diff --git a/.gemini/styleguide.md b/.gemini/styleguide.md new file mode 100644 index 000000000..d0d7048b0 --- /dev/null +++ b/.gemini/styleguide.md @@ -0,0 +1,80 @@ +# パフォーマンス最適化アシスタント + +あなたはパフォーマンス最適化の専門家です。動画配信サービス「AremaTV」のパフォーマンスを最大限に改善することが目標です。 + +## 基本方針 + +1. **不要な処理の削除を最優先**: 通常の開発では行わない「削る」アプローチを積極的に提案してください。 +2. **Lighthouse指標の最適化**: FCP、SI、LCP、TBT、CLS、INPの改善に集中してください。 +3. **レギュレーション遵守**: 機能落ちやデザイン差異を発生させず、E2EテストとVRTが通過する範囲で最適化を行ってください。 + +## 分析と診断 + +1. **コードの問題点を自動検出**: ファイルを開いたら、パフォーマンスに影響する以下の問題を自動的に検出してください。 + + - 不要なライブラリやポリフィル + - 最適化されていない画像読み込み + - 不適切なキャッシュ戦略 + - 非効率なレンダリングパターン + - 過剰なバンドルサイズ + - 非効率なAPI通信 + +2. **パフォーマンス測定の支援**: Lighthouseの測定結果を解析し、改善点を提案してください。 + +## 最適化戦略 + +以下の観点から最適化提案を行ってください: + +### 1. フロントエンド最適化 + +- **バンドルサイズ削減**: 不要なライブラリの削除、コード分割、ツリーシェイキング +- **レンダリング最適化**: React.memo、useMemo、useCallbackの適切な使用 +- **画像最適化**: WebP/AVIF形式の採用、遅延読み込み、サイズ最適化 +- **CSS最適化**: 未使用CSSの削除、クリティカルCSSの抽出 + +### 2. バックエンド最適化 + +- **API効率化**: 不要なデータフェッチの削減、データ集約 +- **キャッシュ戦略**: 適切なCache-Controlヘッダー設定 +- **圧縮最適化**: Brotli/Gzip圧縮の導入、圧縮レベルの調整 +- **SSR最適化**: 必要なページのみSSR、ストリーミングSSRの検討 + +### 3. ネットワーク最適化 + +- **リソースプライオリティ**: 重要なリソースの優先読み込み +- **プリフェッチ/プリロード**: 適切なリソースの事前読み込み +- **HTTP/2, HTTP/3の活用**: 複数リクエストの並列化 + +### 4. Service Worker最適化 + +- **キャッシュ戦略**: Runtime Caching、Precaching +- **オフライン対応**: オフラインファーストアプローチ + +### 5. バンドルサイズ最適化 + +- **バンドルサイズ削減**: 不要なライブラリの削除、コード分割、ツリーシェイキング + +## コミュニケーションスタイル + +1. **具体的な改善提案**: 「〜を削除すべき」ではなく「〜を削除し、〜のように実装すると〜の指標が改善します」と具体的に提案してください。 +2. **数値的な効果予測**: 「この変更でLCPが約X秒改善する可能性があります」のように定量的な効果を示してください。 +3. **トレードオフの説明**: 最適化による副作用やトレードオフを明確に説明してください。 + +## ディレクトリ構成 + +pnpm workspaces を採用しています。 + +- `/workspaces/server` : サーバーの実装です +- `/workspaces/client` : AremaTV Web アプリの実装です +- `/workspaces/schema` : データベースモデルと API リクエスト・レスポンスのインタフェースです +- `/workspaces/configs`: Node.js 関連エコシステムの設定ファイル群です +- `/workspaces/test`: E2E テストと VRT の実行環境です + +## 特別な指示 + +1. **積極的な削減提案**: 「この機能は本当に必要か?」という視点で、大胆な削減提案をしてください。 +2. **ボトルネック優先**: 最も効果の高い改善点から順に取り組むよう誘導してください。 +3. **実験的アプローチ**: 通常の開発では試さない実験的な最適化手法も提案してください。 +4. **レギュレーション遵守の確認**: 提案した最適化がレギュレーションに違反しないか常に確認してください。 + +あなたの役割は、参加者がWeb Speed Hackathonで最高のスコアを獲得できるよう、効率的かつ効果的なパフォーマンス最適化の道筋を示すことです。 diff --git a/.github/workflows/create_heroku_review_app.yaml b/.github/workflows/create_heroku_review_app.yaml index 61605fb65..7e3ade03a 100644 --- a/.github/workflows/create_heroku_review_app.yaml +++ b/.github/workflows/create_heroku_review_app.yaml @@ -7,7 +7,7 @@ jobs: create-review-app: runs-on: ubuntu-latest steps: - - uses: fastruby/manage-heroku-review-app@9fa49f0320460f278c3687bc348dd0cbb18555dc # v1.3 + - uses: kqito/manage-heroku-review-app@55e434ad5ac86f21cf2f7654de1566973fbc7046 with: action: create env: diff --git a/.github/workflows/destroy_heroku_review_app.yaml b/.github/workflows/destroy_heroku_review_app.yaml index b2bf67949..cbcec744a 100644 --- a/.github/workflows/destroy_heroku_review_app.yaml +++ b/.github/workflows/destroy_heroku_review_app.yaml @@ -7,7 +7,7 @@ jobs: destroy-review-app: runs-on: ubuntu-latest steps: - - uses: fastruby/manage-heroku-review-app@9fa49f0320460f278c3687bc348dd0cbb18555dc # v1.3 + - uses: kqito/manage-heroku-review-app@55e434ad5ac86f21cf2f7654de1566973fbc7046 with: action: destroy env: diff --git a/.gitignore b/.gitignore index d7ef94f61..f132cf42b 100644 --- a/.gitignore +++ b/.gitignore @@ -25,7 +25,6 @@ # Icon must end with two \r Icon - # Thumbnails ._* @@ -219,3 +218,7 @@ $RECYCLE.BIN/ # Wireit .wireit + +.react-router/ +build +.wrangler diff --git a/package.json b/package.json index 88d45e67d..e2c658548 100644 --- a/package.json +++ b/package.json @@ -23,9 +23,6 @@ "overrides": { "es-abstract": "~1.23.9", "m3u8-parser>@babel/runtime": "-" - }, - "patchedDependencies": { - "shaka-player": "patches/shaka-player.patch" } }, "wireit": { @@ -40,9 +37,7 @@ ] }, "heroku-build": { - "dependencies": [ - "build" - ] + "command": "echo 'Skipping build'" }, "heroku-cleanup": { "//": "Heroku の buildpacks サイズ削減のため、サーバー起動に必要ないものを削除します", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 576486ce7..63df9d42f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,11 +8,6 @@ overrides: es-abstract: ~1.23.9 m3u8-parser>@babel/runtime: '-' -patchedDependencies: - shaka-player: - hash: ztcamgtqc3a62la4l6p3d6w4ae - path: patches/shaka-player.patch - importers: .: @@ -27,18 +22,15 @@ importers: workspaces/client: dependencies: - '@babel/runtime': - specifier: 7.26.10 - version: 7.26.10 '@better-fetch/fetch': specifier: 1.1.15 version: 1.1.15 '@dhmk/zustand-lens': specifier: 5.0.0 - version: 5.0.0(zustand@5.0.3(@types/react@19.0.1)(immer@10.1.1)(react@19.0.0)(use-sync-external-store@1.4.0(react@19.0.0))) + version: 5.0.0(zustand@5.0.3(@types/react@19.0.1)(react@19.0.0)(use-sync-external-store@1.4.0(react@19.0.0))) '@epic-web/restore-scroll': specifier: 1.1.1 - version: 1.1.1(react-router-dom@7.0.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0) + version: 1.1.1(react-router-dom@7.4.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0) '@ffmpeg/ffmpeg': specifier: 0.12.15 version: 0.12.15 @@ -48,12 +40,15 @@ importers: '@radix-ui/react-slider': specifier: 1.2.3 version: 1.2.3(@types/react-dom@19.0.2(@types/react@19.0.1))(@types/react@19.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@react-router/node': + specifier: 7.4.0 + version: 7.4.0(react-router@7.4.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(typescript@5.7.2) '@standard-schema/spec': specifier: 1.0.0 version: 1.0.0 - '@wsh-2025/client': - specifier: workspace:* - version: 'link:' + '@unocss/reset': + specifier: 66.1.0-beta.6 + version: 66.1.0-beta.6 '@wsh-2025/schema': specifier: workspace:* version: link:../schema @@ -63,24 +58,18 @@ importers: classnames: specifier: 2.5.1 version: 2.5.1 + deepmerge: + specifier: 4.3.1 + version: 4.3.1 final-form: specifier: 4.20.10 version: 4.20.10 - immer: - specifier: 10.1.1 - version: 10.1.1 - lodash: - specifier: 4.17.21 - version: 4.17.21 - luxon: - specifier: 3.5.0 - version: 3.5.0 + isbot: + specifier: ^5 + version: 5.1.25 m3u8-parser: specifier: 7.2.0 version: 7.2.0 - p-min-delay: - specifier: 4.0.2 - version: 4.0.2 react: specifier: 19.0.0 version: 19.0.0 @@ -97,17 +86,11 @@ importers: specifier: 7.2.4 version: 7.2.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) react-router: - specifier: 7.0.2 - version: 7.0.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + specifier: 7.4.0 + version: 7.4.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) react-router-dom: - specifier: 7.0.2 - version: 7.0.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react-use: - specifier: 17.6.0 - version: 17.6.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - setimmediate: - specifier: 1.0.5 - version: 1.0.5 + specifier: 7.4.0 + version: 7.4.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) tiny-invariant: specifier: 1.3.3 version: 1.3.3 @@ -120,34 +103,19 @@ importers: use-sync-external-store: specifier: 1.4.0 version: 1.4.0(react@19.0.0) - valibot: - specifier: 1.0.0-rc.3 - version: 1.0.0-rc.3(typescript@5.7.2) - view-transitions-polyfill: - specifier: 1.0.3 - version: 1.0.3 zod: specifier: 3.24.1 version: 3.24.1 zustand: specifier: 5.0.3 - version: 5.0.3(@types/react@19.0.1)(immer@10.1.1)(react@19.0.0)(use-sync-external-store@1.4.0(react@19.0.0)) - zustand-di: - specifier: 0.0.16 - version: 0.0.16(react@19.0.0)(zustand@5.0.3(@types/react@19.0.1)(immer@10.1.1)(react@19.0.0)(use-sync-external-store@1.4.0(react@19.0.0))) + version: 5.0.3(@types/react@19.0.1)(react@19.0.0)(use-sync-external-store@1.4.0(react@19.0.0)) devDependencies: - '@babel/core': - specifier: 7.26.0 - version: 7.26.0 - '@babel/preset-env': - specifier: 7.26.0 - version: 7.26.0(@babel/core@7.26.0) - '@babel/preset-react': - specifier: 7.25.9 - version: 7.25.9(@babel/core@7.26.0) - '@babel/preset-typescript': - specifier: 7.26.0 - version: 7.26.0(@babel/core@7.26.0) + '@cloudflare/vite-plugin': + specifier: 0.1.15 + version: 0.1.15(@cloudflare/workers-types@4.20250321.0)(vite@6.2.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1))(workerd@1.20250320.0) + '@cloudflare/workers-types': + specifier: 4.20250321.0 + version: 4.20250321.0 '@ffmpeg/core': specifier: 0.12.10 version: 0.12.10 @@ -160,12 +128,9 @@ importers: '@iconify/types': specifier: 2.0.0 version: 2.0.0 - '@types/lodash': - specifier: 4.17.16 - version: 4.17.16 - '@types/luxon': - specifier: 3.4.2 - version: 3.4.2 + '@react-router/dev': + specifier: 7.4.0 + version: 7.4.0(@types/node@22.10.0)(jiti@2.4.2)(react-router@7.4.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(terser@5.36.0)(tsx@4.19.2)(typescript@5.7.2)(vite@6.2.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1))(wrangler@4.4.0(@cloudflare/workers-types@4.20250321.0))(yaml@2.6.1) '@types/m3u8-parser': specifier: 7.2.0 version: 7.2.0 @@ -178,18 +143,15 @@ importers: '@types/wicg-task-scheduling': specifier: 2024.1.0 version: 2024.1.0 - '@unocss/preset-icons': - specifier: 66.1.0-beta.5 - version: 66.1.0-beta.5 + '@unocss/cli': + specifier: latest + version: 66.1.0-beta.6 '@unocss/preset-wind3': - specifier: 66.1.0-beta.5 - version: 66.1.0-beta.5 - '@unocss/reset': - specifier: 66.1.0-beta.5 - version: 66.1.0-beta.5 - '@unocss/runtime': - specifier: 66.1.0-beta.5 - version: 66.1.0-beta.5 + specifier: 66.1.0-beta.6 + version: 66.1.0-beta.6 + '@vitejs/plugin-react': + specifier: 4.3.4 + version: 4.3.4(vite@6.2.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1)) '@wsh-2025/configs': specifier: workspace:* version: link:../configs @@ -199,30 +161,30 @@ importers: babel-loader: specifier: 9.2.1 version: 9.2.1(@babel/core@7.26.0)(webpack@5.96.1) - core-js: - specifier: 3.41.0 - version: 3.41.0 hls.js: specifier: 1.5.17 version: 1.5.17 - shaka-player: - specifier: 4.12.5 - version: 4.12.5(patch_hash=ztcamgtqc3a62la4l6p3d6w4ae) + rollup-plugin-visualizer: + specifier: 5.14.0 + version: 5.14.0(rollup@4.36.0) typescript: specifier: 5.7.2 version: 5.7.2 - video.js: - specifier: 8.21.0 - version: 8.21.0 + unocss: + specifier: 66.1.0-beta.6 + version: 66.1.0-beta.6(vite@6.2.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1)) + vite: + specifier: 6.2.2 + version: 6.2.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1) + vite-tsconfig-paths: + specifier: 5.1.4 + version: 5.1.4(typescript@5.7.2)(vite@6.2.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1)) webpack: specifier: 5.96.1 version: 5.96.1(webpack-cli@5.1.4) - webpack-bundle-analyzer: - specifier: 4.10.2 - version: 4.10.2 webpack-cli: specifier: 5.1.4 - version: 5.1.4(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.1.0)(webpack@5.96.1) + version: 5.1.4(webpack-dev-server@5.1.0)(webpack@5.96.1) webpack-dev-server: specifier: 5.1.0 version: 5.1.0(webpack-cli@5.1.4)(webpack@5.96.1) @@ -240,22 +202,22 @@ importers: version: 2.0.5 eslint: specifier: 9.15.0 - version: 9.15.0 + version: 9.15.0(jiti@2.4.2) eslint-config-prettier: specifier: 9.1.0 - version: 9.1.0(eslint@9.15.0) + version: 9.1.0(eslint@9.15.0(jiti@2.4.2)) eslint-import-resolver-typescript: specifier: 3.6.3 - version: 3.6.3(eslint-plugin-import@2.31.0)(eslint@9.15.0) + version: 3.6.3(eslint-plugin-import@2.31.0)(eslint@9.15.0(jiti@2.4.2)) eslint-plugin-import: specifier: 2.31.0 - version: 2.31.0(eslint-import-resolver-typescript@3.6.3)(eslint@9.15.0) + version: 2.31.0(eslint-import-resolver-typescript@3.6.3)(eslint@9.15.0(jiti@2.4.2)) eslint-plugin-react: specifier: 7.37.4 - version: 7.37.4(eslint@9.15.0) + version: 7.37.4(eslint@9.15.0(jiti@2.4.2)) eslint-plugin-sort: specifier: 4.0.0 - version: 4.0.0(eslint@9.15.0)(typescript@5.7.2) + version: 4.0.0(eslint@9.15.0(jiti@2.4.2))(typescript@5.7.2) globals: specifier: 15.12.0 version: 15.12.0 @@ -276,7 +238,7 @@ importers: version: 5.7.2 typescript-eslint: specifier: 8.16.0 - version: 8.16.0(eslint@9.15.0)(typescript@5.7.2) + version: 8.16.0(eslint@9.15.0(jiti@2.4.2))(typescript@5.7.2) devDependencies: '@types/node': specifier: 22.10.0 @@ -284,24 +246,12 @@ importers: workspaces/schema: dependencies: - '@sinclair/typebox': - specifier: 0.34.30 - version: 0.34.30 - '@sinclair/typemap': - specifier: 0.8.18 - version: 0.8.18(@sinclair/typebox@0.34.30)(valibot@1.0.0-rc.3(typescript@5.7.2))(zod@3.24.1) drizzle-orm: specifier: 0.38.2 - version: 0.38.2(@libsql/client@0.14.0)(@types/react@19.0.1)(react@19.0.0) + version: 0.38.2(@cloudflare/workers-types@4.20250321.0)(@libsql/client@0.14.0)(@types/react@19.0.1)(react@19.0.0) drizzle-zod: specifier: 0.6.0 - version: 0.6.0(drizzle-orm@0.38.2(@libsql/client@0.14.0)(@types/react@19.0.1)(react@19.0.0))(zod@3.24.1) - luxon: - specifier: 3.5.0 - version: 3.5.0 - valibot: - specifier: 1.0.0-rc.3 - version: 1.0.0-rc.3(typescript@5.7.2) + version: 0.6.0(drizzle-orm@0.38.2(@cloudflare/workers-types@4.20250321.0)(@libsql/client@0.14.0)(@types/react@19.0.1)(react@19.0.0))(zod@3.24.1) zod: specifier: 3.24.1 version: 3.24.1 @@ -312,9 +262,6 @@ importers: '@wsh-2025/configs': specifier: workspace:* version: link:../configs - '@wsh-2025/schema': - specifier: workspace:* - version: 'link:' wireit: specifier: 0.14.9 version: 0.14.9 @@ -359,10 +306,10 @@ importers: version: 1.5.3 drizzle-orm: specifier: 0.38.2 - version: 0.38.2(@libsql/client@0.14.0)(@types/react@19.0.1)(react@19.0.0) + version: 0.38.2(@cloudflare/workers-types@4.20250321.0)(@libsql/client@0.14.0)(@types/react@19.0.1)(react@19.0.0) drizzle-seed: specifier: 0.1.3 - version: 0.1.3(drizzle-orm@0.38.2(@libsql/client@0.14.0)(@types/react@19.0.1)(react@19.0.0)) + version: 0.1.3(drizzle-orm@0.38.2(@cloudflare/workers-types@4.20250321.0)(@libsql/client@0.14.0)(@types/react@19.0.1)(react@19.0.0)) fastify: specifier: 5.1.0 version: 5.1.0 @@ -449,21 +396,6 @@ importers: specifier: 4.29.1 version: 4.29.1 - workspaces/test: - devDependencies: - '@playwright/test': - specifier: 1.50.1 - version: 1.50.1 - '@types/node': - specifier: 22.10.0 - version: 22.10.0 - '@wsh-2025/configs': - specifier: workspace:* - version: link:../configs - mockdate: - specifier: 3.0.5 - version: 3.0.5 - packages: '@ampproject/remapping@2.3.0': @@ -488,6 +420,10 @@ packages: resolution: {integrity: sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==} engines: {node: '>=6.9.0'} + '@babel/generator@7.26.10': + resolution: {integrity: sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang==} + engines: {node: '>=6.9.0'} + '@babel/generator@7.26.2': resolution: {integrity: sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==} engines: {node: '>=6.9.0'} @@ -496,31 +432,16 @@ packages: resolution: {integrity: sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==} engines: {node: '>=6.9.0'} - '@babel/helper-builder-binary-assignment-operator-visitor@7.25.9': - resolution: {integrity: sha512-C47lC7LIDCnz0h4vai/tpNOI95tCd5ZT3iBt/DBH5lXKHZsyNQv18yf1wIIg2ntiQNgmAvA+DgZ82iW8Qdym8g==} - engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.25.9': resolution: {integrity: sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==} engines: {node: '>=6.9.0'} - '@babel/helper-create-class-features-plugin@7.25.9': - resolution: {integrity: sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-create-regexp-features-plugin@7.25.9': - resolution: {integrity: sha512-ORPNZ3h6ZRkOyAa/SaHU+XsLZr0UQzRwuDQ0cczIA17nAzZ+85G5cVkOJIj7QavLZGSe8QXUmNFxSZzjcZF9bw==} + '@babel/helper-create-class-features-plugin@7.26.9': + resolution: {integrity: sha512-ubbUqCofvxPRurw5L8WTsCLSkQiVpov4Qx0WMA+jUN+nXBK8ADPlJO1grkFw5CWKC5+sZSOfuGMdX1aI1iT9Sg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-define-polyfill-provider@0.6.3': - resolution: {integrity: sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - '@babel/helper-member-expression-to-functions@7.25.9': resolution: {integrity: sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==} engines: {node: '>=6.9.0'} @@ -543,14 +464,12 @@ packages: resolution: {integrity: sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==} engines: {node: '>=6.9.0'} - '@babel/helper-remap-async-to-generator@7.25.9': - resolution: {integrity: sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==} + '@babel/helper-plugin-utils@7.26.5': + resolution: {integrity: sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==} engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/helper-replace-supers@7.25.9': - resolution: {integrity: sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==} + '@babel/helper-replace-supers@7.26.5': + resolution: {integrity: sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -571,63 +490,22 @@ packages: resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} engines: {node: '>=6.9.0'} - '@babel/helper-wrap-function@7.25.9': - resolution: {integrity: sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==} - engines: {node: '>=6.9.0'} - '@babel/helpers@7.26.0': resolution: {integrity: sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==} engines: {node: '>=6.9.0'} + '@babel/parser@7.26.10': + resolution: {integrity: sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/parser@7.26.2': resolution: {integrity: sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9': - resolution: {integrity: sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.9': - resolution: {integrity: sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.9': - resolution: {integrity: sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.25.9': - resolution: {integrity: sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.13.0 - - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.9': - resolution: {integrity: sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': - resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-import-assertions@7.26.0': - resolution: {integrity: sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-import-attributes@7.26.0': - resolution: {integrity: sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==} + '@babel/plugin-syntax-decorators@7.25.9': + resolution: {integrity: sha512-ryzI0McXUPJnRCvMo4lumIKZUzhYUO/ScI+Mz4YVaTLt04DHNSjEUjKVvbzQjZFLuod/cYEc07mJWhzl6v4DPg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -644,439 +522,204 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-unicode-sets-regex@7.18.6': - resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/plugin-transform-arrow-functions@7.25.9': - resolution: {integrity: sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-async-generator-functions@7.25.9': - resolution: {integrity: sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==} + '@babel/plugin-transform-modules-commonjs@7.26.3': + resolution: {integrity: sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-to-generator@7.25.9': - resolution: {integrity: sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==} + '@babel/plugin-transform-react-jsx-self@7.25.9': + resolution: {integrity: sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoped-functions@7.25.9': - resolution: {integrity: sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==} + '@babel/plugin-transform-react-jsx-source@7.25.9': + resolution: {integrity: sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoping@7.25.9': - resolution: {integrity: sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==} + '@babel/plugin-transform-typescript@7.26.8': + resolution: {integrity: sha512-bME5J9AC8ChwA7aEPJ6zym3w7aObZULHhbNLU0bKUhKsAkylkzUdq+0kdymh9rzi8nlNFl2bmldFBCKNJBUpuw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-class-properties@7.25.9': - resolution: {integrity: sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==} + '@babel/preset-typescript@7.26.0': + resolution: {integrity: sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-class-static-block@7.26.0': - resolution: {integrity: sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==} + '@babel/runtime@7.26.10': + resolution: {integrity: sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==} engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.12.0 - '@babel/plugin-transform-classes@7.25.9': - resolution: {integrity: sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==} + '@babel/template@7.25.9': + resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-computed-properties@7.25.9': - resolution: {integrity: sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==} + '@babel/template@7.26.9': + resolution: {integrity: sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==} engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-destructuring@7.25.9': - resolution: {integrity: sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==} + '@babel/traverse@7.25.9': + resolution: {integrity: sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==} engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-dotall-regex@7.25.9': - resolution: {integrity: sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==} + '@babel/traverse@7.26.10': + resolution: {integrity: sha512-k8NuDrxr0WrPH5Aupqb2LCVURP/S0vBEn5mK6iH+GIYob66U5EtoZvcdudR2jQ4cmTwhEwW1DLB+Yyas9zjF6A==} engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-duplicate-keys@7.25.9': - resolution: {integrity: sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==} + '@babel/types@7.26.0': + resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.9': - resolution: {integrity: sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==} + '@babel/types@7.26.10': + resolution: {integrity: sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==} engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/plugin-transform-dynamic-import@7.25.9': - resolution: {integrity: sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@better-fetch/fetch@1.1.15': + resolution: {integrity: sha512-0Bl8YYj1f8qCTNHeSn5+1DWv2hy7rLBrQ8rS8Y9XYloiwZEfc3k4yspIG0llRxafxqhGCwlGRg+F8q1HZRCMXA==} - '@babel/plugin-transform-exponentiation-operator@7.25.9': - resolution: {integrity: sha512-KRhdhlVk2nObA5AYa7QMgTMTVJdfHprfpAk4DjZVtllqRg9qarilstTKEhpVjyt+Npi8ThRyiV8176Am3CodPA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@cloudflare/kv-asset-handler@0.4.0': + resolution: {integrity: sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA==} + engines: {node: '>=18.0.0'} - '@babel/plugin-transform-export-namespace-from@7.25.9': - resolution: {integrity: sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==} - engines: {node: '>=6.9.0'} + '@cloudflare/unenv-preset@2.3.0': + resolution: {integrity: sha512-AaKYnbFpHaVDZGh3Hjy3oLYd12+LZw9aupAOudYJ+tjekahxcIqlSAr0zK9kPOdtgn10tzaqH7QJFUWcLE+k7g==} peerDependencies: - '@babel/core': ^7.0.0-0 + unenv: 2.0.0-rc.15 + workerd: ^1.20250311.0 + peerDependenciesMeta: + workerd: + optional: true - '@babel/plugin-transform-for-of@7.25.9': - resolution: {integrity: sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==} - engines: {node: '>=6.9.0'} + '@cloudflare/vite-plugin@0.1.15': + resolution: {integrity: sha512-MNSakOz6iAo1Cv7Z45+blbz17gxEt6c7h0rTh1NLfcVPYMWw4qNl4KtfY+fAVrRsRlXBHhs9+9mRne6QNyPJUw==} peerDependencies: - '@babel/core': ^7.0.0-0 + vite: ^6.1.0 - '@babel/plugin-transform-function-name@7.25.9': - resolution: {integrity: sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@cloudflare/workerd-darwin-64@1.20250320.0': + resolution: {integrity: sha512-wS2fcowxgbrKtfahU0Mtt/0XYjnuAjZd+2FsTZ3GDgxlywVTTl8SeApM11cjYo7QNdGh56HEGYMsYojya5sHHQ==} + engines: {node: '>=16'} + cpu: [x64] + os: [darwin] - '@babel/plugin-transform-json-strings@7.25.9': - resolution: {integrity: sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@cloudflare/workerd-darwin-arm64@1.20250320.0': + resolution: {integrity: sha512-QMqFay2buv3pPE+mi30QenX/cmlaB72sXTspk5e4LwEEgsxpoS8BryeIOeo8ScGDyt0NBfOutCRFTTiZLSqyzQ==} + engines: {node: '>=16'} + cpu: [arm64] + os: [darwin] - '@babel/plugin-transform-literals@7.25.9': - resolution: {integrity: sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@cloudflare/workerd-linux-64@1.20250320.0': + resolution: {integrity: sha512-PBkmZdNtSIBRiFUhEMhkDoR5WX0bZWE+nSys0/v6DeFU3Pc6KiH+2VPGqWOLVH85uzL1wWFpAJk9ptsWwTC9Ww==} + engines: {node: '>=16'} + cpu: [x64] + os: [linux] - '@babel/plugin-transform-logical-assignment-operators@7.25.9': - resolution: {integrity: sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@cloudflare/workerd-linux-arm64@1.20250320.0': + resolution: {integrity: sha512-nHSMsNbUwaOJRYuHYK4EcZreOP3FlFqD47FUxGP6k1tjYs4l4z86XJMONbY8vE9WZ9BWPAzZX/xzSalB0DhGIA==} + engines: {node: '>=16'} + cpu: [arm64] + os: [linux] - '@babel/plugin-transform-member-expression-literals@7.25.9': - resolution: {integrity: sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@cloudflare/workerd-windows-64@1.20250320.0': + resolution: {integrity: sha512-Uj5z/PyGqO8xuVCkS19exmQ5yGcC1RbB3nUaf6j5rlft7lBTBkjC+l7NAhEiRxNKaZuT2Lfy+r4vAEPsiotegw==} + engines: {node: '>=16'} + cpu: [x64] + os: [win32] - '@babel/plugin-transform-modules-amd@7.25.9': - resolution: {integrity: sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@cloudflare/workers-types@4.20250321.0': + resolution: {integrity: sha512-jPwtZJC7tVFOwFazuwq96be8haTnY9qik8hJ+oLFi50d9LTWPPrnrNHC4OxZmJTEcPIAy0y1WFZHe8C/b7xFXQ==} - '@babel/plugin-transform-modules-commonjs@7.26.3': - resolution: {integrity: sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} - '@babel/plugin-transform-modules-systemjs@7.25.9': - resolution: {integrity: sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@dhmk/utils@4.4.1': + resolution: {integrity: sha512-5l9xBJvaIQqbLv6vOhhArL6A/UXdATqFUdrQ7MkD3kMwGoEv1cxrSsNUIzRRjW5G1c7Kng6gu0KZf5D6tFbP9g==} - '@babel/plugin-transform-modules-umd@7.25.9': - resolution: {integrity: sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==} - engines: {node: '>=6.9.0'} + '@dhmk/zustand-lens@5.0.0': + resolution: {integrity: sha512-PekoVd6mMpld4kdKKtFrYnVc0j9YqK41zYE35szLfzt/2XGUSUCMYDrKTSGpbExexGLMKB9FBIjvlK399UGoHg==} peerDependencies: - '@babel/core': ^7.0.0-0 + zustand: ^5.0.0 - '@babel/plugin-transform-named-capturing-groups-regex@7.25.9': - resolution: {integrity: sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 + '@discoveryjs/json-ext@0.5.7': + resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} + engines: {node: '>=10.0.0'} - '@babel/plugin-transform-new-target@7.25.9': - resolution: {integrity: sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@drizzle-team/brocli@0.10.2': + resolution: {integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==} - '@babel/plugin-transform-nullish-coalescing-operator@7.25.9': - resolution: {integrity: sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@emnapi/runtime@1.3.1': + resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==} - '@babel/plugin-transform-numeric-separator@7.25.9': - resolution: {integrity: sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==} - engines: {node: '>=6.9.0'} + '@epic-web/restore-scroll@1.1.1': + resolution: {integrity: sha512-eosIzgE9QaQVq+yoLnJxPFfDu7wnU2w1hc8a5FmSCDt8/jXFHQF/kDtM6UH4ueW9XCOzlP8qlOKhl+APLgrkFg==} peerDependencies: - '@babel/core': ^7.0.0-0 + react: '>=18.0.0' + react-router-dom: '>=6.4.0' - '@babel/plugin-transform-object-rest-spread@7.25.9': - resolution: {integrity: sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild-kit/core-utils@3.3.2': + resolution: {integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==} + deprecated: 'Merged into tsx: https://tsx.is' - '@babel/plugin-transform-object-super@7.25.9': - resolution: {integrity: sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild-kit/esm-loader@2.6.5': + resolution: {integrity: sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==} + deprecated: 'Merged into tsx: https://tsx.is' - '@babel/plugin-transform-optional-catch-binding@7.25.9': - resolution: {integrity: sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/aix-ppc64@0.19.12': + resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] - '@babel/plugin-transform-optional-chaining@7.25.9': - resolution: {integrity: sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/aix-ppc64@0.23.1': + resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] - '@babel/plugin-transform-parameters@7.25.9': - resolution: {integrity: sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/aix-ppc64@0.24.2': + resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] - '@babel/plugin-transform-private-methods@7.25.9': - resolution: {integrity: sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/aix-ppc64@0.25.1': + resolution: {integrity: sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] - '@babel/plugin-transform-private-property-in-object@7.25.9': - resolution: {integrity: sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/android-arm64@0.18.20': + resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] - '@babel/plugin-transform-property-literals@7.25.9': - resolution: {integrity: sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/android-arm64@0.19.12': + resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] - '@babel/plugin-transform-react-display-name@7.25.9': - resolution: {integrity: sha512-KJfMlYIUxQB1CJfO3e0+h0ZHWOTLCPP115Awhaz8U0Zpq36Gl/cXlpoyMRnUWlhNUBAzldnCiAZNvCDj7CrKxQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-react-jsx-development@7.25.9': - resolution: {integrity: sha512-9mj6rm7XVYs4mdLIpbZnHOYdpW42uoiBCTVowg7sP1thUOiANgMb4UtpRivR0pp5iL+ocvUv7X4mZgFRpJEzGw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-react-jsx@7.25.9': - resolution: {integrity: sha512-s5XwpQYCqGerXl+Pu6VDL3x0j2d82eiV77UJ8a2mDHAW7j9SWRqQ2y1fNo1Z74CdcYipl5Z41zvjj4Nfzq36rw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-react-pure-annotations@7.25.9': - resolution: {integrity: sha512-KQ/Takk3T8Qzj5TppkS1be588lkbTp5uj7w6a0LeQaTMSckU/wK0oJ/pih+T690tkgI5jfmg2TqDJvd41Sj1Cg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-regenerator@7.25.9': - resolution: {integrity: sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-regexp-modifiers@7.26.0': - resolution: {integrity: sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/plugin-transform-reserved-words@7.25.9': - resolution: {integrity: sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-shorthand-properties@7.25.9': - resolution: {integrity: sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-spread@7.25.9': - resolution: {integrity: sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-sticky-regex@7.25.9': - resolution: {integrity: sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-template-literals@7.25.9': - resolution: {integrity: sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-typeof-symbol@7.25.9': - resolution: {integrity: sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-typescript@7.25.9': - resolution: {integrity: sha512-7PbZQZP50tzv2KGGnhh82GSyMB01yKY9scIjf1a+GfZCtInOWqUH5+1EBU4t9fyR5Oykkkc9vFTs4OHrhHXljQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-unicode-escapes@7.25.9': - resolution: {integrity: sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-unicode-property-regex@7.25.9': - resolution: {integrity: sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-unicode-regex@7.25.9': - resolution: {integrity: sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-unicode-sets-regex@7.25.9': - resolution: {integrity: sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/preset-env@7.26.0': - resolution: {integrity: sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/preset-modules@0.1.6-no-external-plugins': - resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} - peerDependencies: - '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 - - '@babel/preset-react@7.25.9': - resolution: {integrity: sha512-D3to0uSPiWE7rBrdIICCd0tJSIGpLaaGptna2+w7Pft5xMqLpA1sz99DK5TZ1TjGbdQ/VI1eCSZ06dv3lT4JOw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/preset-typescript@7.26.0': - resolution: {integrity: sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/runtime@7.26.10': - resolution: {integrity: sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==} - engines: {node: '>=6.9.0'} - - '@babel/template@7.25.9': - resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} - engines: {node: '>=6.9.0'} - - '@babel/traverse@7.25.9': - resolution: {integrity: sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.26.0': - resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} - engines: {node: '>=6.9.0'} - - '@better-fetch/fetch@1.1.15': - resolution: {integrity: sha512-0Bl8YYj1f8qCTNHeSn5+1DWv2hy7rLBrQ8rS8Y9XYloiwZEfc3k4yspIG0llRxafxqhGCwlGRg+F8q1HZRCMXA==} - - '@dhmk/utils@4.4.1': - resolution: {integrity: sha512-5l9xBJvaIQqbLv6vOhhArL6A/UXdATqFUdrQ7MkD3kMwGoEv1cxrSsNUIzRRjW5G1c7Kng6gu0KZf5D6tFbP9g==} - - '@dhmk/zustand-lens@5.0.0': - resolution: {integrity: sha512-PekoVd6mMpld4kdKKtFrYnVc0j9YqK41zYE35szLfzt/2XGUSUCMYDrKTSGpbExexGLMKB9FBIjvlK399UGoHg==} - peerDependencies: - zustand: ^5.0.0 - - '@discoveryjs/json-ext@0.5.7': - resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} - engines: {node: '>=10.0.0'} - - '@drizzle-team/brocli@0.10.2': - resolution: {integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==} - - '@epic-web/restore-scroll@1.1.1': - resolution: {integrity: sha512-eosIzgE9QaQVq+yoLnJxPFfDu7wnU2w1hc8a5FmSCDt8/jXFHQF/kDtM6UH4ueW9XCOzlP8qlOKhl+APLgrkFg==} - peerDependencies: - react: '>=18.0.0' - react-router-dom: '>=6.4.0' - - '@esbuild-kit/core-utils@3.3.2': - resolution: {integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==} - deprecated: 'Merged into tsx: https://tsx.is' - - '@esbuild-kit/esm-loader@2.6.5': - resolution: {integrity: sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==} - deprecated: 'Merged into tsx: https://tsx.is' - - '@esbuild/aix-ppc64@0.19.12': - resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - - '@esbuild/aix-ppc64@0.23.1': - resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==} + '@esbuild/android-arm64@0.23.1': + resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==} engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.18.20': - resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} - engines: {node: '>=12'} cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.19.12': - resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} - engines: {node: '>=12'} + '@esbuild/android-arm64@0.24.2': + resolution: {integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==} + engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.23.1': - resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==} + '@esbuild/android-arm64@0.25.1': + resolution: {integrity: sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==} engines: {node: '>=18'} cpu: [arm64] os: [android] @@ -1099,6 +742,18 @@ packages: cpu: [arm] os: [android] + '@esbuild/android-arm@0.24.2': + resolution: {integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.25.1': + resolution: {integrity: sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.18.20': resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} engines: {node: '>=12'} @@ -1117,6 +772,18 @@ packages: cpu: [x64] os: [android] + '@esbuild/android-x64@0.24.2': + resolution: {integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.25.1': + resolution: {integrity: sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.18.20': resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} engines: {node: '>=12'} @@ -1135,6 +802,18 @@ packages: cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.24.2': + resolution: {integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.25.1': + resolution: {integrity: sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.18.20': resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} engines: {node: '>=12'} @@ -1153,6 +832,18 @@ packages: cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.24.2': + resolution: {integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.1': + resolution: {integrity: sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.18.20': resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} engines: {node: '>=12'} @@ -1171,6 +862,18 @@ packages: cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.24.2': + resolution: {integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.25.1': + resolution: {integrity: sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.18.20': resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} engines: {node: '>=12'} @@ -1189,6 +892,18 @@ packages: cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.24.2': + resolution: {integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.1': + resolution: {integrity: sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.18.20': resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} engines: {node: '>=12'} @@ -1207,6 +922,18 @@ packages: cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.24.2': + resolution: {integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.25.1': + resolution: {integrity: sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.18.20': resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} engines: {node: '>=12'} @@ -1225,6 +952,18 @@ packages: cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.24.2': + resolution: {integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.25.1': + resolution: {integrity: sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.18.20': resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} engines: {node: '>=12'} @@ -1243,6 +982,18 @@ packages: cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.24.2': + resolution: {integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.25.1': + resolution: {integrity: sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.18.20': resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} engines: {node: '>=12'} @@ -1261,6 +1012,18 @@ packages: cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.24.2': + resolution: {integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.25.1': + resolution: {integrity: sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.18.20': resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} engines: {node: '>=12'} @@ -1279,6 +1042,18 @@ packages: cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.24.2': + resolution: {integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.25.1': + resolution: {integrity: sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.18.20': resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} engines: {node: '>=12'} @@ -1297,6 +1072,18 @@ packages: cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.24.2': + resolution: {integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.25.1': + resolution: {integrity: sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.18.20': resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} engines: {node: '>=12'} @@ -1315,6 +1102,18 @@ packages: cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.24.2': + resolution: {integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.1': + resolution: {integrity: sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.18.20': resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} engines: {node: '>=12'} @@ -1333,7 +1132,19 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.18.20': + '@esbuild/linux-s390x@0.24.2': + resolution: {integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.25.1': + resolution: {integrity: sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.18.20': resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} engines: {node: '>=12'} cpu: [x64] @@ -1351,6 +1162,30 @@ packages: cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.24.2': + resolution: {integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.25.1': + resolution: {integrity: sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.24.2': + resolution: {integrity: sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-arm64@0.25.1': + resolution: {integrity: sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.18.20': resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} engines: {node: '>=12'} @@ -1369,12 +1204,36 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.24.2': + resolution: {integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.1': + resolution: {integrity: sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.23.1': resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.24.2': + resolution: {integrity: sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-arm64@0.25.1': + resolution: {integrity: sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.18.20': resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} engines: {node: '>=12'} @@ -1393,6 +1252,18 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.24.2': + resolution: {integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.1': + resolution: {integrity: sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/sunos-x64@0.18.20': resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} engines: {node: '>=12'} @@ -1411,6 +1282,18 @@ packages: cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.24.2': + resolution: {integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.25.1': + resolution: {integrity: sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.18.20': resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} engines: {node: '>=12'} @@ -1429,6 +1312,18 @@ packages: cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.24.2': + resolution: {integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.25.1': + resolution: {integrity: sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.18.20': resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} engines: {node: '>=12'} @@ -1447,6 +1342,18 @@ packages: cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.24.2': + resolution: {integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.25.1': + resolution: {integrity: sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.18.20': resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} engines: {node: '>=12'} @@ -1465,6 +1372,18 @@ packages: cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.24.2': + resolution: {integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.25.1': + resolution: {integrity: sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.4.1': resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1502,6 +1421,7 @@ packages: '@faker-js/faker@9.2.0': resolution: {integrity: sha512-ulqQu4KMr1/sTFIYvqSdegHT8NIkt66tFAkugGnHA+1WAfEn6hMzNR+svjXGFRVLnapxvej67Z/LwchFrnLBUg==} engines: {node: '>=18.0.0', npm: '>=9.0.0'} + deprecated: Please update to a newer version '@fastify/accept-negotiator@2.0.0': resolution: {integrity: sha512-/Sce/kBzuTxIq5tJh85nVNOq9wKD8s+viIgX0fFMDBdw95gnpf53qmF1oBgJym3cPFliWUuSloVg/1w/rH0FcQ==} @@ -1509,6 +1429,10 @@ packages: '@fastify/ajv-compiler@4.0.1': resolution: {integrity: sha512-DxrBdgsjNLP0YM6W5Hd6/Fmj43S8zMKiFJYgi+Ri3htTGAowPVG/tG1wpnWLMjufEnehRivUCKZ1pLDIoZdTuw==} + '@fastify/busboy@2.1.1': + resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} + engines: {node: '>=14'} + '@fastify/cookie@11.0.2': resolution: {integrity: sha512-GWdwdGlgJxyvNv+QcKiGNevSspMQXncjMZ1J8IvuDQk0jvkzgWWZFNC2En3s+nHndZBGV8IbLwOI/sxCZw/mzA==} @@ -1576,6 +1500,22 @@ packages: '@floating-ui/utils@0.2.9': resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} + '@hattip/adapter-node@0.0.49': + resolution: {integrity: sha512-BE+Y8Q4U0YcH34FZUYU4DssGKOaZLbNL0zK57Z41UZp0m9kS79ZIolBmjjpPhTVpIlRY3Rs+uhXbVXKk7mUcJA==} + + '@hattip/core@0.0.49': + resolution: {integrity: sha512-3/ZJtC17cv8m6Sph8+nw4exUp9yhEf2Shi7HK6AHSUSBtaaQXZ9rJBVxTfZj3PGNOR/P49UBXOym/52WYKFTJQ==} + + '@hattip/headers@0.0.49': + resolution: {integrity: sha512-rrB2lEhTf0+MNVt5WdW184Ky706F1Ze9Aazn/R8c+/FMUYF9yjem2CgXp49csPt3dALsecrnAUOHFiV0LrrHXA==} + + '@hattip/polyfills@0.0.49': + resolution: {integrity: sha512-5g7W5s6Gq+HDxwULGFQ861yAnEx3yd9V8GDwS96HBZ1nM1u93vN+KTuwXvNsV7Z3FJmCrD/pgU8WakvchclYuA==} + + '@hattip/walk@0.0.49': + resolution: {integrity: sha512-AgJgKLooZyQnzMfoFg5Mo/aHM+HGBC9ExpXIjNqGimYTRgNbL/K7X5EM1kR2JY90BNKk9lo6Usq1T/nWFdT7TQ==} + hasBin: true + '@headlessui/react@2.2.0': resolution: {integrity: sha512-RzCEg+LXsuI7mHiSomsu/gBJSjpupm6A1qIZ5sWjd7JhARNlMiSA4kKfJpCKwU9tE+zMRterhhrP74PvfJrpXQ==} engines: {node: '>=10'} @@ -1612,6 +1552,111 @@ packages: '@iconify/utils@2.3.0': resolution: {integrity: sha512-GmQ78prtwYW6EtzXRU1rY+KwOKfz32PD7iJh6Iyqw68GiKuoZ2A6pRtzWONz5VQJbp50mEjXh/7NkumtrAgRKA==} + '@img/sharp-darwin-arm64@0.33.5': + resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.33.5': + resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.0.4': + resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.0.4': + resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.0.4': + resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.0.5': + resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.0.4': + resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.0.4': + resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.33.5': + resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.33.5': + resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-s390x@0.33.5': + resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.33.5': + resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.33.5': + resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.33.5': + resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.33.5': + resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-ia32@0.33.5': + resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.33.5': + resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -1637,6 +1682,9 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@jsonjoy.com/base64@1.1.2': resolution: {integrity: sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==} engines: {node: '>=10.0'} @@ -1655,6 +1703,9 @@ packages: peerDependencies: tslib: '2' + '@kamilkisiela/fast-url-parser@1.1.4': + resolution: {integrity: sha512-gbkePEBupNydxCelHCESvFSFM8XPh1Zs/OAVRW/rKpEqPAl5PbOM90Si8mv9bvnR53uPD2s/FiRxdvSejpRJew==} + '@leichtgewicht/ip-codec@2.0.5': resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==} @@ -1717,6 +1768,9 @@ packages: resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==} hasBin: true + '@mjackson/node-fetch-server@0.2.0': + resolution: {integrity: sha512-EMlH1e30yzmTpGLQjlFmaDAjyOeZhng1/XCd7DExR8PNAnG/G1tyruZxEoUe11ClnwGhGrtsdnyyUx1frSzjng==} + '@neon-rs/load@0.0.4': resolution: {integrity: sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw==} @@ -1736,18 +1790,33 @@ packages: resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} engines: {node: '>=12.4.0'} + '@npmcli/git@4.1.0': + resolution: {integrity: sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@npmcli/package-json@4.0.1': + resolution: {integrity: sha512-lRCEGdHZomFsURroh522YvA/2cVb9oPIJrjHanCJZkiasz1BzcnLr3tBJhlV7S86MBJBuAQ33is2D60YitZL2Q==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@npmcli/promise-spawn@6.0.2': + resolution: {integrity: sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + '@pkgr/core@0.1.1': resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@playwright/test@1.50.1': - resolution: {integrity: sha512-Jii3aBg+CEDpgnuDxEp/h7BimHcUTDlpEtce89xEumlJ5ef2hqepZ+PWp1DDpYC/VO9fmWVI1IlEaoI5fK9FXQ==} - engines: {node: '>=18'} - hasBin: true - '@polka/url@1.0.0-next.28': resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==} + '@quansync/fs@0.1.1': + resolution: {integrity: sha512-sx8J1O/+j2lqs8MvsEz6rs/6UAUpCb4fu7C6EqtMqzbS3CmqLkTDTOMK+DrWukvyUuHzl8DhMjfNJzQDTqfGJg==} + engines: {node: '>=20.18.0'} + '@radix-ui/number@1.1.0': resolution: {integrity: sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==} @@ -1898,6 +1967,34 @@ packages: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + '@react-router/dev@7.4.0': + resolution: {integrity: sha512-z3++B3H6k/GyMoR05CUiy2ney5ZxFWJ8YLyVN8wBU2h4aVscqxxVoX9GyrMvjz81VPtrzf0S2iPTJ758ZVmEIg==} + engines: {node: '>=20.0.0'} + hasBin: true + peerDependencies: + '@react-router/serve': ^7.4.0 + react-router: ^7.4.0 + typescript: ^5.1.0 + vite: ^5.1.0 || ^6.0.0 + wrangler: ^3.28.2 + peerDependenciesMeta: + '@react-router/serve': + optional: true + typescript: + optional: true + wrangler: + optional: true + + '@react-router/node@7.4.0': + resolution: {integrity: sha512-Y+2CXCPmnxcBbdTNGYO7pDusP+1xSlInbFXhsgjsM5WPH+5aDKHKYmDDrOT7fkg0l3b/SkzfwVsJg5XT9qjb/A==} + engines: {node: '>=20.0.0'} + peerDependencies: + react-router: 7.4.0 + typescript: ^5.1.0 + peerDependenciesMeta: + typescript: + optional: true + '@react-stately/utils@3.10.5': resolution: {integrity: sha512-iMQSGcpaecghDIh3mZEpZfoFH3ExBwTtuBEcvZ2XnGzCgQjeYXcMdIUwAfVQLXFTdHUHGF6Gu6/dFrYsCzySBQ==} peerDependencies: @@ -1908,6 +2005,101 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + '@rollup/rollup-android-arm-eabi@4.36.0': + resolution: {integrity: sha512-jgrXjjcEwN6XpZXL0HUeOVGfjXhPyxAbbhD0BlXUB+abTOpbPiN5Wb3kOT7yb+uEtATNYF5x5gIfwutmuBA26w==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.36.0': + resolution: {integrity: sha512-NyfuLvdPdNUfUNeYKUwPwKsE5SXa2J6bCt2LdB/N+AxShnkpiczi3tcLJrm5mA+eqpy0HmaIY9F6XCa32N5yzg==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.36.0': + resolution: {integrity: sha512-JQ1Jk5G4bGrD4pWJQzWsD8I1n1mgPXq33+/vP4sk8j/z/C2siRuxZtaUA7yMTf71TCZTZl/4e1bfzwUmFb3+rw==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.36.0': + resolution: {integrity: sha512-6c6wMZa1lrtiRsbDziCmjE53YbTkxMYhhnWnSW8R/yqsM7a6mSJ3uAVT0t8Y/DGt7gxUWYuFM4bwWk9XCJrFKA==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.36.0': + resolution: {integrity: sha512-KXVsijKeJXOl8QzXTsA+sHVDsFOmMCdBRgFmBb+mfEb/7geR7+C8ypAml4fquUt14ZyVXaw2o1FWhqAfOvA4sg==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.36.0': + resolution: {integrity: sha512-dVeWq1ebbvByI+ndz4IJcD4a09RJgRYmLccwlQ8bPd4olz3Y213uf1iwvc7ZaxNn2ab7bjc08PrtBgMu6nb4pQ==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.36.0': + resolution: {integrity: sha512-bvXVU42mOVcF4le6XSjscdXjqx8okv4n5vmwgzcmtvFdifQ5U4dXFYaCB87namDRKlUL9ybVtLQ9ztnawaSzvg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.36.0': + resolution: {integrity: sha512-JFIQrDJYrxOnyDQGYkqnNBtjDwTgbasdbUiQvcU8JmGDfValfH1lNpng+4FWlhaVIR4KPkeddYjsVVbmJYvDcg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.36.0': + resolution: {integrity: sha512-KqjYVh3oM1bj//5X7k79PSCZ6CvaVzb7Qs7VMWS+SlWB5M8p3FqufLP9VNp4CazJ0CsPDLwVD9r3vX7Ci4J56A==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.36.0': + resolution: {integrity: sha512-QiGnhScND+mAAtfHqeT+cB1S9yFnNQ/EwCg5yE3MzoaZZnIV0RV9O5alJAoJKX/sBONVKeZdMfO8QSaWEygMhw==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loongarch64-gnu@4.36.0': + resolution: {integrity: sha512-1ZPyEDWF8phd4FQtTzMh8FQwqzvIjLsl6/84gzUxnMNFBtExBtpL51H67mV9xipuxl1AEAerRBgBwFNpkw8+Lg==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.36.0': + resolution: {integrity: sha512-VMPMEIUpPFKpPI9GZMhJrtu8rxnp6mJR3ZzQPykq4xc2GmdHj3Q4cA+7avMyegXy4n1v+Qynr9fR88BmyO74tg==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.36.0': + resolution: {integrity: sha512-ttE6ayb/kHwNRJGYLpuAvB7SMtOeQnVXEIpMtAvx3kepFQeowVED0n1K9nAdraHUPJ5hydEMxBpIR7o4nrm8uA==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.36.0': + resolution: {integrity: sha512-4a5gf2jpS0AIe7uBjxDeUMNcFmaRTbNv7NxI5xOCs4lhzsVyGR/0qBXduPnoWf6dGC365saTiwag8hP1imTgag==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.36.0': + resolution: {integrity: sha512-5KtoW8UWmwFKQ96aQL3LlRXX16IMwyzMq/jSSVIIyAANiE1doaQsx/KRyhAvpHlPjPiSU/AYX/8m+lQ9VToxFQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.36.0': + resolution: {integrity: sha512-sycrYZPrv2ag4OCvaN5js+f01eoZ2U+RmT5as8vhxiFz+kxwlHrsxOwKPSA8WyS+Wc6Epid9QeI/IkQ9NkgYyQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.36.0': + resolution: {integrity: sha512-qbqt4N7tokFwwSVlWDsjfoHgviS3n/vZ8LK0h1uLG9TYIRuUTJC88E1xb3LM2iqZ/WTqNQjYrtmtGmrmmawB6A==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.36.0': + resolution: {integrity: sha512-t+RY0JuRamIocMuQcfwYSOkmdX9dtkr1PbhKW42AMvaDQa+jOdpUYysroTF/nuPpAaQMWp7ye+ndlmmthieJrQ==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.36.0': + resolution: {integrity: sha512-aRXd7tRZkWLqGbChgcMMDEHjOKudo1kChb1Jt1IfR8cY/KIpgNviLeJy5FUb9IpSuQj8dU2fAYNMPW/hLKOSTw==} + cpu: [x64] + os: [win32] + '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} @@ -1915,16 +2107,6 @@ packages: resolution: {integrity: sha512-qn8tZzfb1nCIxxfLQfjvIYumuz6YoHJMoWFtCR3dey1lKkY/1obv3NvfAy1WRSztXAQqa/vZUDOXJ1M5LHfMvg==} hasBin: true - '@sinclair/typebox@0.34.30': - resolution: {integrity: sha512-gFB3BiqjDxEoadW0zn+xyMVb7cLxPCoblVn2C/BKpI41WPYi2d6fwHAlynPNZ5O/Q4WEiujdnJzVtvG/Jc2CBQ==} - - '@sinclair/typemap@0.8.18': - resolution: {integrity: sha512-DHv4pnTjMrQFqfMXQDfH8UYcgJxh1pBRCROzhiyGs5lFssyxAXqi+k8V0oI+To+Ut+N1zjqpK90AsnJXtzsKqg==} - peerDependencies: - '@sinclair/typebox': ^0.34.24 - valibot: ^1.0.0-rc.0 - zod: ^3.24.1 - '@standard-schema/spec@1.0.0': resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} @@ -1943,6 +2125,18 @@ packages: '@tsconfig/strictest@2.0.5': resolution: {integrity: sha512-ec4tjL2Rr0pkZ5hww65c+EEPYwxOi4Ryv+0MtjeaSQRJyq322Q27eOQiFbuNgw2hpL4hB1/W/HBGk3VKS43osg==} + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.6.8': + resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.20.6': + resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} + '@types/bcrypt@5.0.2': resolution: {integrity: sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ==} @@ -1988,9 +2182,6 @@ packages: '@types/http-proxy@1.17.15': resolution: {integrity: sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==} - '@types/js-cookie@2.2.7': - resolution: {integrity: sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==} - '@types/jsesc@3.0.3': resolution: {integrity: sha512-YZZ9ZOAiiSVC6KApWd/fTCDTdTOOMiRU4Lq3/VSmXNPse8IvCVOn5kYRRLu900Ub1lTPurVZFI5unEqLDJR7wg==} @@ -2000,9 +2191,6 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - '@types/lodash@4.17.16': - resolution: {integrity: sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==} - '@types/luxon@3.4.2': resolution: {integrity: sha512-TifLZlFudklWlMBfhubvgqTXRzLDI5pCbGa4P8a3wPyUQSW+1xQ5eDsreP9DWHX3tjq1ke96uYG/nwundroWcA==} @@ -2115,58 +2303,108 @@ packages: resolution: {integrity: sha512-pq19gbaMOmFE3CbL0ZB8J8BFCo2ckfHBfaIsaOZgBIF4EoISJIdLX5xRhd0FGB0LlHReNRuzoJoMGpTjq8F2CQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@unocss/core@66.1.0-beta.5': - resolution: {integrity: sha512-1kZzSrB87KKd+xP+vMN7IP03j2UPEykna447aw3UaK5RYTDd/LuVtxoep6gvjN9TJiB4K+Qx0sAtgnfhPpka9Q==} + '@unocss/astro@66.1.0-beta.6': + resolution: {integrity: sha512-LL4DqqMB5D++c5aPZAis1YjzqvwstLVOYwcoXfuA8Ty96/HgCK8XZINpfZUwUND8FqlpFjnqs0NgUm4NkDDexg==} + peerDependencies: + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 + peerDependenciesMeta: + vite: + optional: true - '@unocss/extractor-arbitrary-variants@66.1.0-beta.5': - resolution: {integrity: sha512-GBar8cjd+USjgpKy+fgjJK56DdEMfrq1jfa/Sf4UopkuNIatfn6y5ISLI/6E/V52RYVgD2djL7eT8bPDlCDyqA==} + '@unocss/cli@66.1.0-beta.6': + resolution: {integrity: sha512-HLO04NOfTWjrGtpXxpB41vO8oj/pL+R4Ma/E4pnh4Zzq2e5RDMhyQvgiYSdS6PeIGB5AQDrgmd41EuGHsp23qg==} + engines: {node: '>=14'} + hasBin: true - '@unocss/preset-attributify@66.1.0-beta.5': - resolution: {integrity: sha512-jH9cxgrtJHW57mhqYa5kirD+dxxnyP0IU34cs5Y+9syA2lhLFlURVzg7WyJ9dolajlF//ArDEl87TWPXRnHs+w==} + '@unocss/config@66.1.0-beta.6': + resolution: {integrity: sha512-jLAxHSgMCEhIjCwOwfENtFM3gevU4QDQeaG4VVEYGFJ/oj27JJrl/j6HlUBdhFiR0Q7yf6QFCXlKTP/+put0/Q==} + engines: {node: '>=14'} - '@unocss/preset-icons@66.1.0-beta.5': - resolution: {integrity: sha512-800qE/csJOZaiXRvcyMdBqSnJH2eM2757u8RwNLGHDoxCMpmfjdjfTT+yXv1tJV94XlQfuSmSqpbfBIYQkAEIw==} + '@unocss/core@66.1.0-beta.6': + resolution: {integrity: sha512-TQLxpBZPl6m4HhS6/FMr0Vbn22tGWgbGPyfJyjTSYY/LTug42aIUPnTQnqFSRwGiUnBfp3+oAhG/t/lZ6U74tw==} - '@unocss/preset-mini@66.1.0-beta.5': - resolution: {integrity: sha512-1SJbHE6rPou7bi8h+CKozZeBhYIPHr8lLCE30j66y1Vutgt3FI+Je6qT6m9wX2Iql3r2jJMLaXZ3MMA26PKWEQ==} + '@unocss/extractor-arbitrary-variants@66.1.0-beta.6': + resolution: {integrity: sha512-jUI5Ncppngy8NKv8p9ubUi0FAw6Vcrx7hC7aWaqEFdfA2cDGpR5XHyWJozkT7BbfZs+SnA76b6qwuEtcXwYTAg==} - '@unocss/preset-uno@66.1.0-beta.5': - resolution: {integrity: sha512-EkYHQKhzAcKGw56uZDZux6Sg6hXH7DGPkDGMp5dwY8oLhCAP0TZTw3Jc2FBujEZOa27PO5JLihte0sVMJdHQgg==} + '@unocss/inspector@66.1.0-beta.6': + resolution: {integrity: sha512-YjK017dGMtN8Q067d9n9aCKFXGB8jD13PomKmKOWs3YfmPQE1qQjqQUXH4Zf/jhGMvaB72BHevqctLRHguHfww==} - '@unocss/preset-wind3@66.1.0-beta.5': - resolution: {integrity: sha512-+O+Ts60QRe5tpJ9JQbBdLVQFzqiXE/1J3twQ/S5yQeBWUDOIhaEcF2au6nFgdh0MFjXEBk89Ad93Yew78BoMSQ==} + '@unocss/postcss@66.1.0-beta.6': + resolution: {integrity: sha512-WvpOKr7rPRfb8ttUYpta/WlH/rk0hwZUj59hSW5aMFs/EfaKolIurcSz6UU/yDGBly4T3F+MadqbjSU91iJ8xg==} + engines: {node: '>=14'} - '@unocss/reset@66.1.0-beta.5': - resolution: {integrity: sha512-KMRC280hSTo235FdwAmzobLKYWYWVMpUIUuKmtuOXdDg7mXxSjHPbccDW76iwGtRXl8mTt/gL3stVjHgUsfnBA==} + '@unocss/preset-attributify@66.1.0-beta.6': + resolution: {integrity: sha512-JTSTh7x+DXa1hWe4xCztOeYc0zNpbv0USiHfgM303ZcDr5zNKG4iGAebBqcmAu8CUB+Tq3OJOA4m/dqfkVAAuQ==} - '@unocss/rule-utils@66.1.0-beta.5': - resolution: {integrity: sha512-G757sAnQAMNRUijgOTut8UkbkncSablI6Viwcq2VP4r0Lhi6RFOv/n6AOTWsDgGeUSuWTa/p3zb3NDHY7ztE9g==} - engines: {node: '>=14'} + '@unocss/preset-icons@66.1.0-beta.6': + resolution: {integrity: sha512-zj+PaJ7gSIebtnMnLmzzn9e3tVCO9r2+nOz5v0DWpBfMfpSId4EkXtG3hMllRG8WEH8frZz5qBM3yFuhk8NqqQ==} - '@unocss/runtime@66.1.0-beta.5': - resolution: {integrity: sha512-K+nDn6yIve2Ied/rz2diFdNDkmAX29CfWik7/PqbLHsTEle2hY+CYvPd3mQZRwGVwIJV2jbxt75r0KXZpbBTxQ==} + '@unocss/preset-mini@66.1.0-beta.6': + resolution: {integrity: sha512-MoF32nio5jzKi40VOeOU4k2uZvYUm2GKIxTRZ8C8mb7bFFphoMQD0/Pfr9oWpNC7jl7msuKt8i4xUknK5GAVDQ==} - '@videojs/http-streaming@3.16.2': - resolution: {integrity: sha512-fvt4ko7FknxiT9FnjyNQt6q2px+awrkM+Orv7IB/4gldvj94u4fowGfmNHynnvNTPgPkdxHklGmFLGfclYw8HA==} - engines: {node: '>=8', npm: '>=5'} - peerDependencies: - video.js: ^8.19.0 + '@unocss/preset-tagify@66.1.0-beta.6': + resolution: {integrity: sha512-pym/P+A8CtSp6ek/twe82hW50lsh8miJ7m/oNfU9oHNM/Lo0XQhnIaVvHwefprX+isyKW4KJWBBZ/gX3tbz+9Q==} - '@videojs/vhs-utils@4.1.1': - resolution: {integrity: sha512-5iLX6sR2ownbv4Mtejw6Ax+naosGvoT9kY+gcuHzANyUZZ+4NpeNdKMUhb6ag0acYej1Y7cmr/F2+4PrggMiVA==} - engines: {node: '>=8', npm: '>=5'} + '@unocss/preset-typography@66.1.0-beta.6': + resolution: {integrity: sha512-M6o4oXUMXo6RmclqsnUCXYJCW9cBJYYZcl4M2ofejNkCaqplAwWvc7X7TPvUjcURfwHf+CiXx42DXB0k+FCmlA==} - '@videojs/xhr@2.7.0': - resolution: {integrity: sha512-giab+EVRanChIupZK7gXjHy90y3nncA2phIOyG3Ne5fvpiMJzvqYwiTOnEVW2S4CoYcuKJkomat7bMXA/UoUZQ==} + '@unocss/preset-uno@66.1.0-beta.6': + resolution: {integrity: sha512-zFvQ8sxSGcHoZBkMNngQIdQTFJgoNx5UosydUynLMzs86NFkwd/BAcS2cZBy+buLiuqV1oM2uSyxjLeAqury8g==} - '@webassemblyjs/ast@1.14.1': - resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} + '@unocss/preset-web-fonts@66.1.0-beta.6': + resolution: {integrity: sha512-G9EUBFuFT5sbh1rHsc5oJVHTKK9FMUvtoELaS5HRnxYtr6CR9iepXMNNRb8tmjwx5ewStn7cBKHCGHxnoij3Ew==} - '@webassemblyjs/floating-point-hex-parser@1.13.2': - resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==} + '@unocss/preset-wind3@66.1.0-beta.6': + resolution: {integrity: sha512-AWLf5bT/tjXao5BIdgeDG/XxQoRKvh+G7DQGzJJe4vkOv8QK7QHG8LuqaadEkLTgTY1DaIXshK9d7+E/fFAcFw==} - '@webassemblyjs/helper-api-error@1.13.2': - resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==} + '@unocss/preset-wind4@66.1.0-beta.6': + resolution: {integrity: sha512-8OuBpnPbwId4/6sZe4j52+2shnyY/A3/y7RvhRow2xMgvEPBpJdkGHDDE+igwXF3Bhpd7FZS93NpyMLLX42imA==} + + '@unocss/preset-wind@66.1.0-beta.6': + resolution: {integrity: sha512-1H1YH5OQTGG3mFo54BZELkKWO4iE0UgH4W2+RdnWHEKYIpXImk8JtAkiO5iK0gJafoSQjx592fZ70krQKmNamQ==} + + '@unocss/reset@66.1.0-beta.6': + resolution: {integrity: sha512-HIB+JT1/1LbDChcbYmWAmSNMHMBYMcgubc5W0nIEZbfT4JGF/ZsbFeAhpbau/k/Ny5w5XlBD24CESkYewldgyw==} + + '@unocss/rule-utils@66.1.0-beta.6': + resolution: {integrity: sha512-9RxYUGq96Ro+5XbevFlzKKwtROIv9c6VZbG+i34pMaw8ALFsCj34iGFvBs4ohTf03XkCCyMlr2f2KdFc9cj/Sw==} + engines: {node: '>=14'} + + '@unocss/transformer-attributify-jsx@66.1.0-beta.6': + resolution: {integrity: sha512-Qp9kvq7nRjFRuUfM5zJ1Mz/JxjRNvRReL1m0t9lrgDQl3pc1+7pIxlQSEn0NJHaOQc8CBpLgTDRmwWLOtlB6SQ==} + + '@unocss/transformer-compile-class@66.1.0-beta.6': + resolution: {integrity: sha512-MckRTk6zh9GwjxIhvbckKko4VqESkaYLOLmHK0eVOioEPyV2B8eCqgrMLpYJlrpCIRbZV8ttAGNCiB8MsQgR/w==} + + '@unocss/transformer-directives@66.1.0-beta.6': + resolution: {integrity: sha512-+/U6MV9IiPuCoE2+CKkXbpAlN7X8WembjdtM0jFTXJWJdrb11xI8bMTfGnhohKs94naQL6lEmow/wZVFgIIJug==} + + '@unocss/transformer-variant-group@66.1.0-beta.6': + resolution: {integrity: sha512-Liug/F5nHYBLoUbo+47unrzKjYKxmN7HAw/jjQpzjKGn4bN6ZzCDodY3h6q5e8XsxFIkZlt3JZPZkMKjSf1E0Q==} + + '@unocss/vite@66.1.0-beta.6': + resolution: {integrity: sha512-/3yAxOJm8UFiNOBcuRQELrgQX55fJnb0wBNNSeW1YsE5vLCDNvP0acibDmqyKk2O+Ch9yw8duC60FKIptVzJhQ==} + peerDependencies: + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 + + '@videojs/vhs-utils@4.1.1': + resolution: {integrity: sha512-5iLX6sR2ownbv4Mtejw6Ax+naosGvoT9kY+gcuHzANyUZZ+4NpeNdKMUhb6ag0acYej1Y7cmr/F2+4PrggMiVA==} + engines: {node: '>=8', npm: '>=5'} + + '@vitejs/plugin-react@4.3.4': + resolution: {integrity: sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 + + '@webassemblyjs/ast@1.14.1': + resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} + + '@webassemblyjs/floating-point-hex-parser@1.13.2': + resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==} + + '@webassemblyjs/helper-api-error@1.13.2': + resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==} '@webassemblyjs/helper-buffer@1.14.1': resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==} @@ -2229,12 +2467,13 @@ packages: webpack-dev-server: optional: true - '@xmldom/xmldom@0.8.10': - resolution: {integrity: sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==} - engines: {node: '>=10.0.0'} + '@whatwg-node/fetch@0.9.23': + resolution: {integrity: sha512-7xlqWel9JsmxahJnYVUj/LLxWcnA93DR4c9xlw3U814jWTiYalryiH1qToik1hOxweKKRLi4haXHM5ycRksPBA==} + engines: {node: '>=18.0.0'} - '@xobotyi/scrollbar-width@1.9.5': - resolution: {integrity: sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==} + '@whatwg-node/node-fetch@0.6.0': + resolution: {integrity: sha512-tcZAhrpx6oVlkEsRngeTEEE7I5/QdLjeEz4IlekabGaESP7+Dkm/6a9KcF1KdCBB7mO9PXtBkwCuTCt8+UPg8Q==} + engines: {node: '>=18.0.0'} '@xtuc/ieee754@1.2.0': resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} @@ -2263,8 +2502,8 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn-walk@8.3.4: - resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + acorn-walk@8.3.2: + resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} engines: {node: '>=0.4.0'} acorn@8.14.0: @@ -2272,9 +2511,6 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - aes-decrypter@4.0.2: - resolution: {integrity: sha512-lc+/9s6iJvuaRe5qDlMTpCFjnwpkeOXp8qP3oiZ5jsj1MRg+SBVUmmICrhxHvc8OELSmc+fEyyxAuppY6hrWzw==} - agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} @@ -2342,6 +2578,9 @@ packages: engines: {node: '>=10'} deprecated: This package is no longer supported. + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -2368,10 +2607,6 @@ packages: resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} engines: {node: '>= 0.4'} - array.prototype.flatmap@1.3.2: - resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} - engines: {node: '>= 0.4'} - array.prototype.flatmap@1.3.3: resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} engines: {node: '>= 0.4'} @@ -2388,6 +2623,9 @@ packages: resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} engines: {node: '>= 0.4'} + as-table@1.0.55: + resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} + atomic-sleep@1.0.0: resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} engines: {node: '>=8.0.0'} @@ -2399,6 +2637,9 @@ packages: avvio@9.1.0: resolution: {integrity: sha512-fYASnYi600CsH/j9EQov7lECAniYiBFiiAtBNuZYLA2leLe9qOvZzqYHFjtIj6gD2VMoMLP14834LFWvr4IfDw==} + babel-dead-code-elimination@1.0.9: + resolution: {integrity: sha512-JLIhax/xullfInZjtu13UJjaLHDeTzt3vOeomaSUdO/nAMEL/pWC/laKrSvWylXMnVWyL5bpmG9njqBZlUQOdg==} + babel-loader@9.2.1: resolution: {integrity: sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==} engines: {node: '>= 14.15.0'} @@ -2406,21 +2647,6 @@ packages: '@babel/core': ^7.12.0 webpack: '>=5' - babel-plugin-polyfill-corejs2@0.4.12: - resolution: {integrity: sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - - babel-plugin-polyfill-corejs3@0.10.6: - resolution: {integrity: sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - - babel-plugin-polyfill-regenerator@0.6.3: - resolution: {integrity: sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -2442,6 +2668,9 @@ packages: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} + blake3-wasm@2.1.5: + resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} + body-parser@1.20.3: resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} @@ -2475,10 +2704,18 @@ packages: resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} engines: {node: '>=18'} + busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} @@ -2510,6 +2747,10 @@ packages: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + chownr@2.0.0: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} engines: {node: '>=10'} @@ -2521,6 +2762,10 @@ packages: classnames@2.5.1: resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + clone-deep@4.0.1: resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} engines: {node: '>=6'} @@ -2536,10 +2781,17 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + color-support@1.1.3: resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} hasBin: true + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} @@ -2550,10 +2802,6 @@ packages: commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - commander@7.2.0: - resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} - engines: {node: '>= 10'} - common-path-prefix@3.0.0: resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==} @@ -2578,6 +2826,10 @@ packages: resolution: {integrity: sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==} engines: {node: '>=0.8'} + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + console-control-strings@1.1.0: resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} @@ -2595,6 +2847,10 @@ packages: cookie-signature@1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + cookie@0.5.0: + resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} + engines: {node: '>= 0.6'} + cookie@0.7.1: resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} engines: {node: '>= 0.6'} @@ -2603,15 +2859,6 @@ packages: resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} engines: {node: '>=18'} - copy-to-clipboard@3.3.3: - resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} - - core-js-compat@3.39.0: - resolution: {integrity: sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==} - - core-js@3.41.0: - resolution: {integrity: sha512-SJ4/EHwS36QMJd6h/Rg+GyR4A5xE0FSI3eZ+iBVpfqf1x0eTSg1smWLHrA+2jQThZSh97fmSgFSU8B61nxosxA==} - core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -2619,16 +2866,16 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} - css-in-js-utils@3.1.0: - resolution: {integrity: sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==} - - css-tree@1.1.3: - resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==} - engines: {node: '>=8.0.0'} + css-tree@3.1.0: + resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + data-uri-to-buffer@2.0.2: + resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==} + data-uri-to-buffer@4.0.1: resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} engines: {node: '>= 12'} @@ -2645,9 +2892,6 @@ packages: resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} engines: {node: '>= 0.4'} - debounce@1.2.1: - resolution: {integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==} - debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -2693,6 +2937,10 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + default-browser-id@5.0.0: resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==} engines: {node: '>=18'} @@ -2705,6 +2953,10 @@ packages: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} + define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + define-lazy-prop@3.0.0: resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} engines: {node: '>=12'} @@ -2713,6 +2965,9 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + delegates@1.0.0: resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} @@ -2739,6 +2994,10 @@ packages: resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} engines: {node: '>=8'} + detect-libc@2.0.3: + resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} + engines: {node: '>=8'} + detect-newline@4.0.1: resolution: {integrity: sha512-qE3Veg1YXzGHQhlA6jzebZN2qVf6NX+A7m7qlhCGG30dJixrAQhYOsJjsnBjJkCSmuOPpCk30145fr8FV0bzog==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -2883,9 +3142,6 @@ packages: electron-to-chromium@1.5.65: resolution: {integrity: sha512-PWVzBjghx7/wop6n22vS2MLU8tKGd4Q91aCEGhG/TYmW6PP5OcSXcdnxTe1NNt0T66N8D6jxh4kC8UsdzOGaIw==} - eme-encryption-scheme-polyfill@2.1.6: - resolution: {integrity: sha512-SmQ8UxDkH/8hrjLo6ASo452hIe4dSJzqKmJyrNsvUciEJNxf4z9hewIwF1k/c7A5uRk4GApavPZ6dgqXqfvegw==} - emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -2913,8 +3169,8 @@ packages: engines: {node: '>=4'} hasBin: true - error-stack-parser@2.1.4: - resolution: {integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==} + err-code@2.0.3: + resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} es-abstract@1.23.9: resolution: {integrity: sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==} @@ -2982,6 +3238,16 @@ packages: engines: {node: '>=18'} hasBin: true + esbuild@0.24.2: + resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==} + engines: {node: '>=18'} + hasBin: true + + esbuild@0.25.1: + resolution: {integrity: sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -3118,6 +3384,10 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} + exit-hook@2.2.1: + resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} + engines: {node: '>=6'} + express@4.21.1: resolution: {integrity: sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==} engines: {node: '>= 0.10.0'} @@ -3151,9 +3421,6 @@ packages: resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} engines: {node: '>=6'} - fast-shallow-equal@1.0.0: - resolution: {integrity: sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==} - fast-uri@2.4.0: resolution: {integrity: sha512-ypuAmmMKInk5q7XcepxlnUWDLWv4GFtaJqAzWKqn62IpQ3pejtr5dTVbt3vwqVaMKmkNR55sTT+CqUKIaT21BA==} @@ -3164,9 +3431,6 @@ packages: resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} engines: {node: '>= 4.9.1'} - fastest-stable-stringify@2.0.2: - resolution: {integrity: sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==} - fastify-openapi-glue@4.7.4: resolution: {integrity: sha512-1Jc2gxVHxgQuwGLrpT6+AF25CO3QWd+9R33I1vnpivHLFcbf+NUgXTDivehaLfUjmWwUAAwFrr+Kwm3QRgsVwA==} engines: {node: '>=14.0.0'} @@ -3212,6 +3476,14 @@ packages: picomatch: optional: true + fdir@6.4.3: + resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + fetch-blob@3.2.0: resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} engines: {node: ^12.20 || >= 14.13} @@ -3296,6 +3568,10 @@ packages: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} + fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + fs-minipass@2.1.0: resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} engines: {node: '>= 8'} @@ -3303,11 +3579,6 @@ packages: fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -3332,6 +3603,10 @@ packages: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + get-intrinsic@1.2.4: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} @@ -3344,6 +3619,9 @@ packages: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} + get-source@2.0.12: + resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==} + get-stdin@9.0.0: resolution: {integrity: sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==} engines: {node: '>=12'} @@ -3369,6 +3647,10 @@ packages: glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + glob@11.0.0: resolution: {integrity: sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==} engines: {node: 20 || >=22} @@ -3401,6 +3683,9 @@ packages: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} + globrex@0.1.2: + resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} + gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} @@ -3461,15 +3746,16 @@ packages: hls.js@1.5.17: resolution: {integrity: sha512-wA66nnYFvQa1o4DO/BFgLNRKnBTVXpNeldGRBJ2Y0SvFtdwvFKCbqa9zhHoZLoxHhZ+jYsj3aIBkWQQCPNOhMw==} + hosted-git-info@6.1.3: + resolution: {integrity: sha512-HVJyzUrLIL1c0QmviVh5E8VGyUS7xCFPS6yydaVd1UegW+ibV/CohqTH9MkOLDp5o+rb82DMo77PTuc9F/8GKw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hpack.js@2.1.6: resolution: {integrity: sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==} html-entities@2.5.2: resolution: {integrity: sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==} - html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - htmlescape@1.1.1: resolution: {integrity: sha512-eVcrzgbR4tim7c7soKQKtxa/kQM4TzjnlU83rcZ9bHU6t31ehfV7SktN6McWgwPWg+JYMA/O3qpGxBvFq1z2Jg==} engines: {node: '>=0.10'} @@ -3509,9 +3795,6 @@ packages: resolution: {integrity: sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==} engines: {node: '>=10.18'} - hyphenate-style-name@1.1.0: - resolution: {integrity: sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==} - iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -3527,9 +3810,6 @@ packages: immediate@3.0.6: resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} - immer@10.1.1: - resolution: {integrity: sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==} - import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} @@ -3553,9 +3833,6 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - inline-style-prefixer@7.0.1: - resolution: {integrity: sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw==} - internal-slot@1.1.0: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} @@ -3576,6 +3853,9 @@ packages: resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} engines: {node: '>= 0.4'} + is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + is-async-function@2.0.0: resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} engines: {node: '>= 0.4'} @@ -3611,6 +3891,11 @@ packages: resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} engines: {node: '>= 0.4'} + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + is-docker@3.0.0: resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -3628,9 +3913,6 @@ packages: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} - is-function@1.0.2: - resolution: {integrity: sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==} - is-generator-function@1.0.10: resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} engines: {node: '>= 0.4'} @@ -3684,10 +3966,6 @@ packages: resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} engines: {node: '>= 0.4'} - is-string@1.0.7: - resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} - engines: {node: '>= 0.4'} - is-string@1.1.1: resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} engines: {node: '>= 0.4'} @@ -3712,6 +3990,10 @@ packages: resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==} engines: {node: '>= 0.4'} + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + is-wsl@3.1.0: resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} engines: {node: '>=16'} @@ -3722,6 +4004,10 @@ packages: isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + isbot@5.1.25: + resolution: {integrity: sha512-mqU76fmT7cpGG0JX1EzhCZIC+xovpH6TD2SAK18alonk0RG/RgChpGduJTYzRaq9a0COoFA99M9JVtEUOcScIw==} + engines: {node: '>=18'} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -3736,6 +4022,9 @@ packages: resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} engines: {node: '>= 0.4'} + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + jackspeak@4.0.2: resolution: {integrity: sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==} engines: {node: 20 || >=22} @@ -3744,12 +4033,13 @@ packages: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} + jiti@2.4.2: + resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} + hasBin: true + js-base64@3.7.7: resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==} - js-cookie@2.2.1: - resolution: {integrity: sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==} - js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -3768,6 +4058,10 @@ packages: json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + json-parse-even-better-errors@3.0.2: + resolution: {integrity: sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + json-schema-ref-resolver@1.0.1: resolution: {integrity: sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw==} @@ -3796,6 +4090,9 @@ packages: jsonc-parser@3.3.1: resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + jsx-ast-utils@3.3.5: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} @@ -3822,6 +4119,7 @@ packages: libsql@0.4.7: resolution: {integrity: sha512-T9eIRCs6b0J1SHKYIvD8+KCJMcWZ900iZyxdnSCdqxN12Z1ijzT+jY5nrk72Jw4B0HGzms2NgpryArlJqvc3Lw==} + cpu: [x64, arm64, wasm32] os: [darwin, linux, win32] lie@3.3.0: @@ -3854,9 +4152,6 @@ packages: resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - lodash.debounce@4.0.8: - resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} - lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} @@ -3867,6 +4162,9 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@11.0.2: resolution: {integrity: sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==} engines: {node: 20 || >=22} @@ -3874,6 +4172,10 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lru-cache@7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} + luxon@3.5.0: resolution: {integrity: sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==} engines: {node: '>=12'} @@ -3892,8 +4194,8 @@ packages: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} - mdn-data@2.0.14: - resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} + mdn-data@2.12.2: + resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==} media-typer@0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} @@ -3945,6 +4247,11 @@ packages: min-document@2.19.0: resolution: {integrity: sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==} + miniflare@4.20250320.0: + resolution: {integrity: sha512-dD9gpO/nWaLURbBXctB/FOJEDexPlSbplIApb5Ea3xGuSSh+3Iq/cfbgh3IdgueIGMJb6vvTiOWpiPA5naX6vg==} + engines: {node: '>=18.0.0'} + hasBin: true + minimalistic-assert@1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} @@ -3989,13 +4296,6 @@ packages: mnemonist@0.39.8: resolution: {integrity: sha512-vyWo2K3fjrUw8YeeZ1zF0fy6Mu59RHokURlld8ymdUPjMlD9EC9ov1/YPqTgqRvUN9nTr3Gqfz29LYAmu0PHPQ==} - mockdate@3.0.5: - resolution: {integrity: sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ==} - - mpd-parser@1.3.1: - resolution: {integrity: sha512-1FuyEWI5k2HcmhS1HkKnUAQV7yFPfXPht2DnRRGtoiiAAW+ESTbtEXIDpRkwdU+XyrQuwrIym7UkoPKsZ0SyFw==} - hasBin: true - mrmime@2.0.1: resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} engines: {node: '>=10'} @@ -4010,16 +4310,14 @@ packages: resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==} hasBin: true - mux.js@7.1.0: - resolution: {integrity: sha512-NTxawK/BBELJrYsZThEulyUMDVlLizKdxyAsMuzoCD1eFj97BVaA8D/CvKsKu6FOLYkFojN5CbM9h++ZTZtknA==} - engines: {node: '>=8', npm: '>=5'} + mustache@4.2.0: + resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} hasBin: true - nano-css@5.6.2: - resolution: {integrity: sha512-+6bHaC8dSDGALM1HJjOHVXpuastdu2xFoZlC77Jh4cg+33Zcgm+Gxd+1xsnpZK14eyHObSp82+ll5y3SX75liw==} - peerDependencies: - react: '*' - react-dom: '*' + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -4070,10 +4368,30 @@ packages: engines: {node: '>=6'} hasBin: true + normalize-package-data@5.0.0: + resolution: {integrity: sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} + npm-install-checks@6.3.0: + resolution: {integrity: sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-normalize-package-bin@3.0.1: + resolution: {integrity: sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-package-arg@10.1.0: + resolution: {integrity: sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-pick-manifest@8.0.2: + resolution: {integrity: sha512-1dKY+86/AIiq1tkKVD3l0WI+Gd3vkknVGAggsFeBkTvbhMQ1OND/LKkYv4JtXPKUJ8bOTCyLiqEg2P6QNdK+Gg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + npmlog@5.0.1: resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} deprecated: This package is no longer supported. @@ -4110,10 +4428,6 @@ packages: resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} engines: {node: '>= 0.4'} - object.values@1.2.0: - resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} - engines: {node: '>= 0.4'} - object.values@1.2.1: resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} engines: {node: '>= 0.4'} @@ -4127,6 +4441,9 @@ packages: ofetch@1.4.1: resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==} + ohash@2.0.11: + resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} + on-exit-leak-free@2.1.2: resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} engines: {node: '>=14.0.0'} @@ -4146,13 +4463,13 @@ packages: resolution: {integrity: sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==} engines: {node: '>=18'} + open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + openapi-types@12.1.3: resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} - opener@1.5.2: - resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} - hasBin: true - optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -4185,10 +4502,6 @@ packages: resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - p-min-delay@4.0.2: - resolution: {integrity: sha512-7hJcTq/MGF5pNHbQ2akrpPy1N43YYlB4RPECDSbPRn4xP/dsgP0I6ls7NvSUQ5k88o+CyATMOrQiZ/PK4aQR9w==} - engines: {node: '>=12'} - p-retry@6.2.1: resolution: {integrity: sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==} engines: {node: '>=16.17'} @@ -4233,6 +4546,10 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + path-scurry@2.0.0: resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} engines: {node: 20 || >=22} @@ -4240,12 +4557,18 @@ packages: path-to-regexp@0.1.10: resolution: {integrity: sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==} + path-to-regexp@6.3.0: + resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -4267,10 +4590,6 @@ packages: resolution: {integrity: sha512-xSEmD4pLnV54t0NOUN16yCl7RIB1c5UUOse5HSyEXtBp+FgFQyPeDutc+Q2ZO7/22vImV7VfEjH/1zV2QuqvYw==} hasBin: true - pkcs7@1.0.4: - resolution: {integrity: sha512-afRERtHn54AlwaF2/+LFszyAANTCggGilmcmILUzEjvs3XgFZT+xE6+QWQcAGmu4xajy+Xtj7acLOPdx5/eXWQ==} - hasBin: true - pkg-dir@4.2.0: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} @@ -4285,20 +4604,14 @@ packages: pkg-types@2.1.0: resolution: {integrity: sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==} - playwright-core@1.50.1: - resolution: {integrity: sha512-ra9fsNWayuYumt+NiM069M6OkcRb1FZSK8bgi66AtpFoWkg2+y0bJSNmkFrWhMbEBbVKC/EruAHH3g0zmtwGmQ==} - engines: {node: '>=18'} - hasBin: true - - playwright@1.50.1: - resolution: {integrity: sha512-G8rwsOQJ63XG6BbKj2w5rHeavFjy5zynBA9zsJMMtBoe/Uf757oG12NXz6e6OirF7RCrTVAKFXbLmn1RbL7Qaw==} - engines: {node: '>=18'} - hasBin: true - possible-typed-array-names@1.0.0: resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} engines: {node: '>= 0.4'} + postcss@8.5.3: + resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} + engines: {node: ^10 || ^12 || >=14} + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -4372,11 +4685,23 @@ packages: prettier-plugin-svelte: optional: true + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + prettier@3.4.0: resolution: {integrity: sha512-/OXNZcLyWkfo13ofOW5M7SLh+k5pnIs07owXK2teFpnfaOEcycnSy7HQxldaVX1ZP/7Q8oO1eDuQJNwbomQq5Q==} engines: {node: '>=14'} hasBin: true + printable-characters@1.0.42: + resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} + + proc-log@3.0.0: + resolution: {integrity: sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} @@ -4387,9 +4712,21 @@ packages: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} + promise-inflight@1.0.1: + resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} + peerDependencies: + bluebird: '*' + peerDependenciesMeta: + bluebird: + optional: true + promise-limit@2.7.0: resolution: {integrity: sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw==} + promise-retry@2.0.1: + resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} + engines: {node: '>=10'} + prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} @@ -4458,8 +4795,12 @@ packages: react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - react-router-dom@7.0.2: - resolution: {integrity: sha512-VJOQ+CDWFDGaWdrG12Nl+d7yHtLaurNgAQZVgaIy7/Xd+DojgmYLosFfZdGz1wpxmjJIAkAMVTKWcvkx1oggAw==} + react-refresh@0.14.2: + resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} + engines: {node: '>=0.10.0'} + + react-router-dom@7.4.0: + resolution: {integrity: sha512-VlksBPf3n2bijPvnA7nkTsXxMAKOj+bWp4R9c3i+bnwlSOFAGOkJkKhzy/OsRkWaBMICqcAl1JDzh9ZSOze9CA==} engines: {node: '>=20.0.0'} peerDependencies: react: '>=18' @@ -4475,17 +4816,15 @@ packages: react-dom: optional: true - react-universal-interface@0.6.2: - resolution: {integrity: sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==} - peerDependencies: - react: '*' - tslib: '*' - - react-use@17.6.0: - resolution: {integrity: sha512-OmedEScUMKFfzn1Ir8dBxiLLSOzhKe/dPZwVxcujweSj45aNM7BEGPb9BEVIgVEqEXx6f3/TsXzwIktNgUR02g==} + react-router@7.4.0: + resolution: {integrity: sha512-Y2g5ObjkvX3VFeVt+0CIPuYd9PpgqCslG7ASSIdN73LwA1nNWzcMLaoMRJfP3prZFI92svxFwbn7XkLJ+UPQ6A==} + engines: {node: '>=20.0.0'} peerDependencies: - react: '*' - react-dom: '*' + react: '>=18' + react-dom: '>=18' + peerDependenciesMeta: + react-dom: + optional: true react@19.0.0: resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==} @@ -4502,6 +4841,10 @@ packages: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + real-require@0.2.0: resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} engines: {node: '>= 12.13.0'} @@ -4514,37 +4857,20 @@ packages: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} - regenerate-unicode-properties@10.2.0: - resolution: {integrity: sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==} - engines: {node: '>=4'} - - regenerate@1.4.2: - resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} - regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - regenerator-transform@0.15.2: - resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} - regexp.prototype.flags@1.5.3: resolution: {integrity: sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==} engines: {node: '>= 0.4'} - regexpu-core@6.2.0: - resolution: {integrity: sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==} - engines: {node: '>=4'} - - regjsgen@0.8.0: - resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} - - regjsparser@0.12.0: - resolution: {integrity: sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==} - hasBin: true - rematrix@0.2.2: resolution: {integrity: sha512-agFFS3RzrLXJl5LY5xg/xYyXvUuVAnkhgKO7RaO9J1Ssth6yvbO+PIiV67V59MB5NCdAK2flvGvNT4mdKVniFA==} + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + require-from-string@2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} @@ -4602,8 +4928,23 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true - rtl-css-js@1.16.1: - resolution: {integrity: sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==} + rollup-plugin-visualizer@5.14.0: + resolution: {integrity: sha512-VlDXneTDaKsHIw8yzJAFWtrzguoJ/LnQ+lMpoVfYJ3jJF4Ihe5oYLAqLklIK/35lgUY+1yEzCkHyZ1j4A5w5fA==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + rolldown: 1.x + rollup: 2.x || 3.x || 4.x + peerDependenciesMeta: + rolldown: + optional: true + rollup: + optional: true + + rollup@4.36.0: + resolution: {integrity: sha512-zwATAXNQxUcd40zgtQG0ZafcRK4g004WtEl7kbuhTWPvf07PsfohXl39jVUvPF7jvNAIkKPQ2XrsDlWuxBd++Q==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true run-applescript@7.0.0: resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==} @@ -4651,10 +4992,6 @@ packages: resolution: {integrity: sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==} engines: {node: '>= 12.13.0'} - screenfull@5.2.0: - resolution: {integrity: sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==} - engines: {node: '>=0.10.0'} - secure-json-parse@2.7.0: resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} @@ -4703,10 +5040,6 @@ packages: resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} engines: {node: '>= 0.4'} - set-harmonic-interval@1.0.1: - resolution: {integrity: sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g==} - engines: {node: '>=6.9'} - set-proto@1.0.0: resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} engines: {node: '>= 0.4'} @@ -4720,13 +5053,14 @@ packages: setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - shaka-player@4.12.5: - resolution: {integrity: sha512-jJEkASLivZ0Eqg+sIfBJWCWFDzo2l4rfG1e2y5apqphKbDZaMrSCX0Z/B14epJCfStSAwGqKyuC1D+K3e4xBEg==} - shallow-clone@3.0.1: resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} engines: {node: '>=8'} + sharp@0.33.5: + resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -4765,9 +5099,12 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - sirv@2.0.4: - resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} - engines: {node: '>= 10'} + simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + + sirv@3.0.1: + resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==} + engines: {node: '>=18'} sockjs@0.3.24: resolution: {integrity: sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==} @@ -4782,17 +5119,33 @@ packages: resolution: {integrity: sha512-/HrPQAeeLaa+vbAH/znjuhwUluuiM/zL5XX9kop8UpDgjtyWKt43hGDk2vd/TBdDpzIyzIHVUgmYofzYrAQjew==} hasBin: true + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - source-map@0.5.6: - resolution: {integrity: sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==} - engines: {node: '>=0.10.0'} - source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + source-map@0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-license-ids@3.0.21: + resolution: {integrity: sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==} + spdy-transport@3.0.0: resolution: {integrity: sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==} @@ -4804,17 +5157,8 @@ packages: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} - stack-generator@2.0.10: - resolution: {integrity: sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==} - - stackframe@1.3.4: - resolution: {integrity: sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==} - - stacktrace-gps@3.1.2: - resolution: {integrity: sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ==} - - stacktrace-js@2.0.2: - resolution: {integrity: sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==} + stacktracey@2.1.8: + resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} statuses@1.5.0: resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} @@ -4824,6 +5168,17 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} + stoppable@1.1.0: + resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} + engines: {node: '>=4', npm: '>=6'} + + stream-slice@0.1.2: + resolution: {integrity: sha512-QzQxpoacatkreL6jsxnVb7X5R/pGw9OUv2qWTYWnmLpg4NdN31snPy/f3TdQE1ZUXaThRvj1Zw4/OGg0ZkaLMA==} + + streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -4843,9 +5198,6 @@ packages: resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} engines: {node: '>= 0.4'} - string.prototype.trimend@1.0.8: - resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} - string.prototype.trimend@1.0.9: resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} engines: {node: '>= 0.4'} @@ -4876,9 +5228,6 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - stylis@4.3.6: - resolution: {integrity: sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==} - supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -4936,10 +5285,6 @@ packages: thread-stream@3.1.0: resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} - throttle-debounce@3.0.1: - resolution: {integrity: sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==} - engines: {node: '>=10'} - thunky@1.1.0: resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==} @@ -4953,6 +5298,10 @@ packages: resolution: {integrity: sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==} engines: {node: '>=12.0.0'} + tinyglobby@0.2.12: + resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} + engines: {node: '>=12.0.0'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -4961,9 +5310,6 @@ packages: resolution: {integrity: sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==} engines: {node: '>=12'} - toggle-selection@1.0.6: - resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} - toidentifier@1.0.1: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} @@ -4987,8 +5333,15 @@ packages: peerDependencies: typescript: '>=4.2.0' - ts-easing@0.2.0: - resolution: {integrity: sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==} + tsconfck@3.1.5: + resolution: {integrity: sha512-CLDfGgUp7XPswWnezWwsCRxNmgQjhYq3VXHM0/XIRxhVrKw0M1if9agzryh1QS3nxjCROvV+xWxoJO1YctzzWg==} + engines: {node: ^18 || >=20} + hasBin: true + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true tsconfig-paths@3.15.0: resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} @@ -5054,29 +5407,47 @@ packages: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} + unconfig@7.3.1: + resolution: {integrity: sha512-LH5WL+un92tGAzWS87k7LkAfwpMdm7V0IXG2FxEjZz/QxiIW5J5LkcrKQThj0aRz6+h/lFmKI9EUXmK/T0bcrw==} + undici-types@6.20.0: resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} - unicode-canonical-property-names-ecmascript@2.0.1: - resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==} - engines: {node: '>=4'} + undici@5.29.0: + resolution: {integrity: sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==} + engines: {node: '>=14.0'} - unicode-match-property-ecmascript@2.0.0: - resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} - engines: {node: '>=4'} + undici@6.21.2: + resolution: {integrity: sha512-uROZWze0R0itiAKVPsYhFov9LxrPMHLMEQFszeI2gCN6bnIIZ8twzBCJcN2LJrBBLfrP0t1FW0g+JmKVl8Vk1g==} + engines: {node: '>=18.17'} - unicode-match-property-value-ecmascript@2.2.0: - resolution: {integrity: sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==} - engines: {node: '>=4'} + unenv@2.0.0-rc.15: + resolution: {integrity: sha512-J/rEIZU8w6FOfLNz/hNKsnY+fFHWnu9MH4yRbSZF3xbbGHovcetXPs7sD+9p8L6CeNC//I9bhRYAOsBt2u7/OA==} - unicode-property-aliases-ecmascript@2.1.0: - resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} - engines: {node: '>=4'} + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unocss@66.1.0-beta.6: + resolution: {integrity: sha512-ULv6jB5abJO1ciKreq0xW9WOKnWImK4uvWXmPR1d+JX0CvcHTtgO0HxR+UWToUcuvEFyLjQ1MKvovLMydo6+Lw==} + engines: {node: '>=14'} + peerDependencies: + '@unocss/webpack': 66.1.0-beta.6 + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 + peerDependenciesMeta: + '@unocss/webpack': + optional: true + vite: + optional: true unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} + unplugin-utils@0.2.4: + resolution: {integrity: sha512-8U/MtpkPkkk3Atewj1+RcKIjb5WBimZ/WSLhhR3w6SsIj8XJuKTacSP8g+2JhfSGw0Cb125Y+2zA/IzJZDVbhA==} + engines: {node: '>=18.12.0'} + update-browserslist-db@1.1.1: resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} hasBin: true @@ -5086,6 +5457,9 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + urlpattern-polyfill@10.0.0: + resolution: {integrity: sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==} + use-callback-ref@1.3.3: resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} engines: {node: '>=10'} @@ -5112,35 +5486,82 @@ packages: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true - valibot@1.0.0-rc.3: - resolution: {integrity: sha512-LT0REa7Iqx4QGcaHLiTiTkcmJqJ9QdpOy89HALFFBJgejTS64GQFRIbDF7e4f6pauQbo/myfKGmWXCLhMeM6+g==} + valibot@0.41.0: + resolution: {integrity: sha512-igDBb8CTYr8YTQlOKgaN9nSS0Be7z+WRuaeYqGf3Cjz3aKmSnqEmYnkfVjzIuumGqfHpa3fLIvMEAfhrpqN8ng==} peerDependencies: typescript: '>=5' peerDependenciesMeta: typescript: optional: true + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + + validate-npm-package-name@5.0.1: + resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} - video.js@8.21.0: - resolution: {integrity: sha512-zcwerRb257QAuWfi8NH9yEX7vrGKFthjfcONmOQ4lxFRpDAbAi+u5LAjCjMWqhJda6zEmxkgdDpOMW3Y21QpXA==} + vite-node@3.0.0-beta.2: + resolution: {integrity: sha512-ofTf6cfRdL30Wbl9n/BX81EyIR5s4PReLmSurrxQ+koLaWUNOEo8E0lCM53OJkb8vpa2URM2nSrxZsIFyvY1rg==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true - videojs-contrib-quality-levels@4.1.0: - resolution: {integrity: sha512-TfrXJJg1Bv4t6TOCMEVMwF/CoS8iENYsWNKip8zfhB5kTcegiFYezEA0eHAJPU64ZC8NQbxQgOwAsYU8VXbOWA==} - engines: {node: '>=16', npm: '>=8'} + vite-tsconfig-paths@5.1.4: + resolution: {integrity: sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w==} peerDependencies: - video.js: ^8 - - videojs-font@4.2.0: - resolution: {integrity: sha512-YPq+wiKoGy2/M7ccjmlvwi58z2xsykkkfNMyIg4xb7EZQQNwB71hcSsB3o75CqQV7/y5lXkXhI/rsGAS7jfEmQ==} - - videojs-vtt.js@0.15.5: - resolution: {integrity: sha512-yZbBxvA7QMYn15Lr/ZfhhLPrNpI/RmCSCqgIff57GC2gIrV5YfyzLfLyZMj0NnZSAz8syB4N0nHXpZg9MyrMOQ==} + vite: '*' + peerDependenciesMeta: + vite: + optional: true - view-transitions-polyfill@1.0.3: - resolution: {integrity: sha512-o7tiNKAsuqvL0u4Epo/jrSOx7qy1/KH3ajzHsY0GU4zWIOiiC6Pyczyf6QgJneyFKlu8QdcMeCQocUl94R+fvA==} + vite@6.2.2: + resolution: {integrity: sha512-yW7PeMM+LkDzc7CgJuRLMW2Jz0FxMOsVJ8Lv3gpgW9WLcb9cTW+121UEr1hvmfR7w3SegR5ItvYyzVz1vxNJgQ==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: '>=1.21.0' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vue-flow-layout@0.1.1: + resolution: {integrity: sha512-JdgRRUVrN0Y2GosA0M68DEbKlXMqJ7FQgsK8CjQD2vxvNSqAU6PZEpi4cfcTVtfM2GVOMjHo7GKKLbXxOBqDqA==} + peerDependencies: + vue: ^3.4.37 watchpack@2.4.2: resolution: {integrity: sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==} @@ -5156,11 +5577,6 @@ packages: webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - webpack-bundle-analyzer@4.10.2: - resolution: {integrity: sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==} - engines: {node: '>= 10.13.0'} - hasBin: true - webpack-cli@5.1.4: resolution: {integrity: sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==} engines: {node: '>=14.15.0'} @@ -5250,6 +5666,11 @@ packages: engines: {node: '>= 8'} hasBin: true + which@3.0.1: + resolution: {integrity: sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + wide-align@1.1.5: resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} @@ -5265,6 +5686,21 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + workerd@1.20250320.0: + resolution: {integrity: sha512-XrjREboPo1AZNF3kSEly/H1Ejmpu2Mk/Wzsxprn7MHUmBnQNASFtvQdN0ef0bN+MaNdCWUawpsDLpNWNOyK4FA==} + engines: {node: '>=16'} + hasBin: true + + wrangler@4.4.0: + resolution: {integrity: sha512-VmHBpocMk/GTEER+jJzkQeGNx5i/qJJKoUse5zvKmJOnELG/dhEQBJoaWxllwOfaPhIbnqeXdtrN/B+dfQAsFA==} + engines: {node: '>=18.0.0'} + hasBin: true + peerDependencies: + '@cloudflare/workers-types': ^4.20250320.0 + peerDependenciesMeta: + '@cloudflare/workers-types': + optional: true + wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -5276,18 +5712,6 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - ws@7.5.10: - resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} - engines: {node: '>=8.3.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - ws@8.18.0: resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} engines: {node: '>=10.0.0'} @@ -5300,6 +5724,10 @@ packages: utf-8-validate: optional: true + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} @@ -5311,6 +5739,14 @@ packages: engines: {node: '>= 14'} hasBin: true + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -5319,9 +5755,8 @@ packages: resolution: {integrity: sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==} engines: {node: '>=12.20'} - yoctodelay@1.2.0: - resolution: {integrity: sha512-12y/P9MSig9/5BEhBgylss+fkHiCRZCvYR81eH35NW9uw801cvJt31EAV+WOLcwZRZbLiIQl/hxcdXXXFmGvXg==} - engines: {node: '>=4'} + youch@3.2.3: + resolution: {integrity: sha512-ZBcWz/uzZaQVdCvfV4uk616Bbpf2ee+F/AvuKDR5EwX/Y4v06xWdtMluqTD7+KlZdM93lLm9gMZYo0sKBS0pgw==} zod-openapi@4.2.0: resolution: {integrity: sha512-lnm1e2X5/Ymox5mYxdspy/y52Hb4rPxG1bcwOuHS+YIpxQNEt9s8G4zo34jm0M3+q71TAxgqzcbPLiBXrsfsGA==} @@ -5329,15 +5764,12 @@ packages: peerDependencies: zod: ^3.21.4 + zod@3.22.3: + resolution: {integrity: sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==} + zod@3.24.1: resolution: {integrity: sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==} - zustand-di@0.0.16: - resolution: {integrity: sha512-d0KoomJAgqNPi/HO1SPa9O8cPsPEWLZ3k+1qBpa2GqnyT+7BLWez5/SLIzC3n4WQnFFpZrpNXEbZsjC+ikeJOA==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - zustand: ^4.4.0 || ^5.0.0 - zustand@5.0.3: resolution: {integrity: sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg==} engines: {node: '>=12.20.0'} @@ -5398,6 +5830,14 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/generator@7.26.10': + dependencies: + '@babel/parser': 7.26.10 + '@babel/types': 7.26.10 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.0.2 + '@babel/generator@7.26.2': dependencies: '@babel/parser': 7.26.2 @@ -5410,13 +5850,6 @@ snapshots: dependencies: '@babel/types': 7.26.0 - '@babel/helper-builder-binary-assignment-operator-visitor@7.25.9': - dependencies: - '@babel/traverse': 7.25.9 - '@babel/types': 7.26.0 - transitivePeerDependencies: - - supports-color - '@babel/helper-compilation-targets@7.25.9': dependencies: '@babel/compat-data': 7.26.2 @@ -5425,40 +5858,22 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.25.9(@babel/core@7.26.0)': + '@babel/helper-create-class-features-plugin@7.26.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-annotate-as-pure': 7.25.9 '@babel/helper-member-expression-to-functions': 7.25.9 '@babel/helper-optimise-call-expression': 7.25.9 - '@babel/helper-replace-supers': 7.25.9(@babel/core@7.26.0) + '@babel/helper-replace-supers': 7.26.5(@babel/core@7.26.0) '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.26.10 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/helper-create-regexp-features-plugin@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-annotate-as-pure': 7.25.9 - regexpu-core: 6.2.0 - semver: 6.3.1 - - '@babel/helper-define-polyfill-provider@0.6.3(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-compilation-targets': 7.25.9 - '@babel/helper-plugin-utils': 7.25.9 - debug: 4.3.7 - lodash.debounce: 4.0.8 - resolve: 1.22.8 - transitivePeerDependencies: - - supports-color - '@babel/helper-member-expression-to-functions@7.25.9': dependencies: - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.26.10 '@babel/types': 7.26.0 transitivePeerDependencies: - supports-color @@ -5485,21 +5900,14 @@ snapshots: '@babel/helper-plugin-utils@7.25.9': {} - '@babel/helper-remap-async-to-generator@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-wrap-function': 7.25.9 - '@babel/traverse': 7.25.9 - transitivePeerDependencies: - - supports-color + '@babel/helper-plugin-utils@7.26.5': {} - '@babel/helper-replace-supers@7.25.9(@babel/core@7.26.0)': + '@babel/helper-replace-supers@7.26.5(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-member-expression-to-functions': 7.25.9 '@babel/helper-optimise-call-expression': 7.25.9 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.26.10 transitivePeerDependencies: - supports-color @@ -5516,68 +5924,20 @@ snapshots: '@babel/helper-validator-option@7.25.9': {} - '@babel/helper-wrap-function@7.25.9': + '@babel/helpers@7.26.0': dependencies: '@babel/template': 7.25.9 - '@babel/traverse': 7.25.9 '@babel/types': 7.26.0 - transitivePeerDependencies: - - supports-color - '@babel/helpers@7.26.0': + '@babel/parser@7.26.10': dependencies: - '@babel/template': 7.25.9 - '@babel/types': 7.26.0 + '@babel/types': 7.26.10 '@babel/parser@7.26.2': dependencies: '@babel/types': 7.26.0 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - '@babel/traverse': 7.25.9 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 - '@babel/plugin-transform-optional-chaining': 7.25.9(@babel/core@7.26.0) - transitivePeerDependencies: - - supports-color - - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - '@babel/traverse': 7.25.9 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - - '@babel/plugin-syntax-import-assertions@7.26.0(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-syntax-import-attributes@7.26.0(@babel/core@7.26.0)': + '@babel/plugin-syntax-decorators@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 @@ -5590,467 +5950,34 @@ snapshots: '@babel/plugin-syntax-typescript@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-create-regexp-features-plugin': 7.25.9(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-arrow-functions@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-async-generator-functions@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - '@babel/helper-remap-async-to-generator': 7.25.9(@babel/core@7.26.0) - '@babel/traverse': 7.25.9 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-async-to-generator@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-module-imports': 7.25.9 - '@babel/helper-plugin-utils': 7.25.9 - '@babel/helper-remap-async-to-generator': 7.25.9(@babel/core@7.26.0) - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-block-scoped-functions@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-block-scoping@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-class-properties@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-create-class-features-plugin': 7.25.9(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-class-static-block@7.26.0(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-create-class-features-plugin': 7.25.9(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-classes@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-compilation-targets': 7.25.9 - '@babel/helper-plugin-utils': 7.25.9 - '@babel/helper-replace-supers': 7.25.9(@babel/core@7.26.0) - '@babel/traverse': 7.25.9 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-computed-properties@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - '@babel/template': 7.25.9 - - '@babel/plugin-transform-destructuring@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-dotall-regex@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-create-regexp-features-plugin': 7.25.9(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-duplicate-keys@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-create-regexp-features-plugin': 7.25.9(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-dynamic-import@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-exponentiation-operator@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-builder-binary-assignment-operator-visitor': 7.25.9 - '@babel/helper-plugin-utils': 7.25.9 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-export-namespace-from@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-for-of@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-function-name@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-compilation-targets': 7.25.9 - '@babel/helper-plugin-utils': 7.25.9 - '@babel/traverse': 7.25.9 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-json-strings@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-literals@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-logical-assignment-operators@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-member-expression-literals@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-modules-amd@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 - transitivePeerDependencies: - - supports-color + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-modules-commonjs@7.26.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-modules-systemjs@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 - '@babel/helper-validator-identifier': 7.25.9 - '@babel/traverse': 7.25.9 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-modules-umd@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-named-capturing-groups-regex@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-create-regexp-features-plugin': 7.25.9(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-new-target@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-nullish-coalescing-operator@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-numeric-separator@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-object-rest-spread@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-compilation-targets': 7.25.9 - '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-parameters': 7.25.9(@babel/core@7.26.0) - - '@babel/plugin-transform-object-super@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - '@babel/helper-replace-supers': 7.25.9(@babel/core@7.26.0) - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-optional-catch-binding@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-optional-chaining@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-parameters@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-private-methods@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-create-class-features-plugin': 7.25.9(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-private-property-in-object@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-create-class-features-plugin': 7.25.9(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-property-literals@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-react-display-name@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-react-jsx-development@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/plugin-transform-react-jsx': 7.25.9(@babel/core@7.26.0) - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-module-imports': 7.25.9 - '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.0) - '@babel/types': 7.26.0 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-react-pure-annotations@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-regenerator@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - regenerator-transform: 0.15.2 - - '@babel/plugin-transform-regexp-modifiers@7.26.0(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-create-regexp-features-plugin': 7.25.9(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-reserved-words@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-shorthand-properties@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-spread@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-sticky-regex@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-template-literals@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-typeof-symbol@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-typescript@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-create-class-features-plugin': 7.25.9(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 - '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 - '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.0) - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-unicode-escapes@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-unicode-property-regex@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-create-regexp-features-plugin': 7.25.9(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-unicode-regex@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-create-regexp-features-plugin': 7.25.9(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-transform-unicode-sets-regex@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-create-regexp-features-plugin': 7.25.9(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/preset-env@7.26.0(@babel/core@7.26.0)': - dependencies: - '@babel/compat-data': 7.26.2 - '@babel/core': 7.26.0 - '@babel/helper-compilation-targets': 7.25.9 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) '@babel/helper-plugin-utils': 7.25.9 - '@babel/helper-validator-option': 7.25.9 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.26.0) - '@babel/plugin-syntax-import-assertions': 7.26.0(@babel/core@7.26.0) - '@babel/plugin-syntax-import-attributes': 7.26.0(@babel/core@7.26.0) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.26.0) - '@babel/plugin-transform-arrow-functions': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-async-generator-functions': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-async-to-generator': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-block-scoped-functions': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-block-scoping': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-class-properties': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-class-static-block': 7.26.0(@babel/core@7.26.0) - '@babel/plugin-transform-classes': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-computed-properties': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-destructuring': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-dotall-regex': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-duplicate-keys': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-dynamic-import': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-exponentiation-operator': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-export-namespace-from': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-for-of': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-function-name': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-json-strings': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-literals': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-logical-assignment-operators': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-member-expression-literals': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-modules-amd': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-modules-commonjs': 7.26.3(@babel/core@7.26.0) - '@babel/plugin-transform-modules-systemjs': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-modules-umd': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-named-capturing-groups-regex': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-new-target': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-nullish-coalescing-operator': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-numeric-separator': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-object-rest-spread': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-object-super': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-optional-catch-binding': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-optional-chaining': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-parameters': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-private-methods': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-private-property-in-object': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-property-literals': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-regenerator': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-regexp-modifiers': 7.26.0(@babel/core@7.26.0) - '@babel/plugin-transform-reserved-words': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-shorthand-properties': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-spread': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-sticky-regex': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-template-literals': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-typeof-symbol': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-unicode-escapes': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-unicode-property-regex': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-unicode-regex': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-unicode-sets-regex': 7.25.9(@babel/core@7.26.0) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.26.0) - babel-plugin-polyfill-corejs2: 0.4.12(@babel/core@7.26.0) - babel-plugin-polyfill-corejs3: 0.10.6(@babel/core@7.26.0) - babel-plugin-polyfill-regenerator: 0.6.3(@babel/core@7.26.0) - core-js-compat: 3.39.0 - semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.26.0)': + '@babel/plugin-transform-react-jsx-self@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - '@babel/types': 7.26.0 - esutils: 2.0.3 + '@babel/helper-plugin-utils': 7.26.5 - '@babel/preset-react@7.25.9(@babel/core@7.26.0)': + '@babel/plugin-transform-react-jsx-source@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - '@babel/helper-validator-option': 7.25.9 - '@babel/plugin-transform-react-display-name': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-react-jsx': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-react-jsx-development': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-react-pure-annotations': 7.25.9(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-transform-typescript@7.26.8(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-create-class-features-plugin': 7.26.9(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.26.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 + '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.0) transitivePeerDependencies: - supports-color @@ -6061,7 +5988,7 @@ snapshots: '@babel/helper-validator-option': 7.25.9 '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-modules-commonjs': 7.26.3(@babel/core@7.26.0) - '@babel/plugin-transform-typescript': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-typescript': 7.26.8(@babel/core@7.26.0) transitivePeerDependencies: - supports-color @@ -6075,6 +6002,12 @@ snapshots: '@babel/parser': 7.26.2 '@babel/types': 7.26.0 + '@babel/template@7.26.9': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/parser': 7.26.10 + '@babel/types': 7.26.10 + '@babel/traverse@7.25.9': dependencies: '@babel/code-frame': 7.26.2 @@ -6087,28 +6020,98 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/traverse@7.26.10': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.10 + '@babel/parser': 7.26.10 + '@babel/template': 7.26.9 + '@babel/types': 7.26.10 + debug: 4.4.0 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + '@babel/types@7.26.0': dependencies: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 + '@babel/types@7.26.10': + dependencies: + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + '@better-fetch/fetch@1.1.15': {} + '@cloudflare/kv-asset-handler@0.4.0': + dependencies: + mime: 3.0.0 + + '@cloudflare/unenv-preset@2.3.0(unenv@2.0.0-rc.15)(workerd@1.20250320.0)': + dependencies: + unenv: 2.0.0-rc.15 + optionalDependencies: + workerd: 1.20250320.0 + + '@cloudflare/vite-plugin@0.1.15(@cloudflare/workers-types@4.20250321.0)(vite@6.2.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1))(workerd@1.20250320.0)': + dependencies: + '@cloudflare/unenv-preset': 2.3.0(unenv@2.0.0-rc.15)(workerd@1.20250320.0) + '@hattip/adapter-node': 0.0.49 + miniflare: 4.20250320.0 + picocolors: 1.1.1 + tinyglobby: 0.2.12 + unenv: 2.0.0-rc.15 + vite: 6.2.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1) + wrangler: 4.4.0(@cloudflare/workers-types@4.20250321.0) + ws: 8.18.0 + transitivePeerDependencies: + - '@cloudflare/workers-types' + - bufferutil + - utf-8-validate + - workerd + + '@cloudflare/workerd-darwin-64@1.20250320.0': + optional: true + + '@cloudflare/workerd-darwin-arm64@1.20250320.0': + optional: true + + '@cloudflare/workerd-linux-64@1.20250320.0': + optional: true + + '@cloudflare/workerd-linux-arm64@1.20250320.0': + optional: true + + '@cloudflare/workerd-windows-64@1.20250320.0': + optional: true + + '@cloudflare/workers-types@4.20250321.0': {} + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + '@dhmk/utils@4.4.1': {} - '@dhmk/zustand-lens@5.0.0(zustand@5.0.3(@types/react@19.0.1)(immer@10.1.1)(react@19.0.0)(use-sync-external-store@1.4.0(react@19.0.0)))': + '@dhmk/zustand-lens@5.0.0(zustand@5.0.3(@types/react@19.0.1)(react@19.0.0)(use-sync-external-store@1.4.0(react@19.0.0)))': dependencies: '@dhmk/utils': 4.4.1 - zustand: 5.0.3(@types/react@19.0.1)(immer@10.1.1)(react@19.0.0)(use-sync-external-store@1.4.0(react@19.0.0)) + zustand: 5.0.3(@types/react@19.0.1)(react@19.0.0)(use-sync-external-store@1.4.0(react@19.0.0)) '@discoveryjs/json-ext@0.5.7': {} '@drizzle-team/brocli@0.10.2': {} - '@epic-web/restore-scroll@1.1.1(react-router-dom@7.0.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0)': + '@emnapi/runtime@1.3.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@epic-web/restore-scroll@1.1.1(react-router-dom@7.4.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0)': dependencies: react: 19.0.0 - react-router-dom: 7.0.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + react-router-dom: 7.4.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@esbuild-kit/core-utils@3.3.2': dependencies: @@ -6126,6 +6129,12 @@ snapshots: '@esbuild/aix-ppc64@0.23.1': optional: true + '@esbuild/aix-ppc64@0.24.2': + optional: true + + '@esbuild/aix-ppc64@0.25.1': + optional: true + '@esbuild/android-arm64@0.18.20': optional: true @@ -6135,6 +6144,12 @@ snapshots: '@esbuild/android-arm64@0.23.1': optional: true + '@esbuild/android-arm64@0.24.2': + optional: true + + '@esbuild/android-arm64@0.25.1': + optional: true + '@esbuild/android-arm@0.18.20': optional: true @@ -6144,6 +6159,12 @@ snapshots: '@esbuild/android-arm@0.23.1': optional: true + '@esbuild/android-arm@0.24.2': + optional: true + + '@esbuild/android-arm@0.25.1': + optional: true + '@esbuild/android-x64@0.18.20': optional: true @@ -6153,6 +6174,12 @@ snapshots: '@esbuild/android-x64@0.23.1': optional: true + '@esbuild/android-x64@0.24.2': + optional: true + + '@esbuild/android-x64@0.25.1': + optional: true + '@esbuild/darwin-arm64@0.18.20': optional: true @@ -6162,6 +6189,12 @@ snapshots: '@esbuild/darwin-arm64@0.23.1': optional: true + '@esbuild/darwin-arm64@0.24.2': + optional: true + + '@esbuild/darwin-arm64@0.25.1': + optional: true + '@esbuild/darwin-x64@0.18.20': optional: true @@ -6171,6 +6204,12 @@ snapshots: '@esbuild/darwin-x64@0.23.1': optional: true + '@esbuild/darwin-x64@0.24.2': + optional: true + + '@esbuild/darwin-x64@0.25.1': + optional: true + '@esbuild/freebsd-arm64@0.18.20': optional: true @@ -6180,6 +6219,12 @@ snapshots: '@esbuild/freebsd-arm64@0.23.1': optional: true + '@esbuild/freebsd-arm64@0.24.2': + optional: true + + '@esbuild/freebsd-arm64@0.25.1': + optional: true + '@esbuild/freebsd-x64@0.18.20': optional: true @@ -6189,6 +6234,12 @@ snapshots: '@esbuild/freebsd-x64@0.23.1': optional: true + '@esbuild/freebsd-x64@0.24.2': + optional: true + + '@esbuild/freebsd-x64@0.25.1': + optional: true + '@esbuild/linux-arm64@0.18.20': optional: true @@ -6198,6 +6249,12 @@ snapshots: '@esbuild/linux-arm64@0.23.1': optional: true + '@esbuild/linux-arm64@0.24.2': + optional: true + + '@esbuild/linux-arm64@0.25.1': + optional: true + '@esbuild/linux-arm@0.18.20': optional: true @@ -6207,6 +6264,12 @@ snapshots: '@esbuild/linux-arm@0.23.1': optional: true + '@esbuild/linux-arm@0.24.2': + optional: true + + '@esbuild/linux-arm@0.25.1': + optional: true + '@esbuild/linux-ia32@0.18.20': optional: true @@ -6216,6 +6279,12 @@ snapshots: '@esbuild/linux-ia32@0.23.1': optional: true + '@esbuild/linux-ia32@0.24.2': + optional: true + + '@esbuild/linux-ia32@0.25.1': + optional: true + '@esbuild/linux-loong64@0.18.20': optional: true @@ -6225,6 +6294,12 @@ snapshots: '@esbuild/linux-loong64@0.23.1': optional: true + '@esbuild/linux-loong64@0.24.2': + optional: true + + '@esbuild/linux-loong64@0.25.1': + optional: true + '@esbuild/linux-mips64el@0.18.20': optional: true @@ -6234,6 +6309,12 @@ snapshots: '@esbuild/linux-mips64el@0.23.1': optional: true + '@esbuild/linux-mips64el@0.24.2': + optional: true + + '@esbuild/linux-mips64el@0.25.1': + optional: true + '@esbuild/linux-ppc64@0.18.20': optional: true @@ -6243,6 +6324,12 @@ snapshots: '@esbuild/linux-ppc64@0.23.1': optional: true + '@esbuild/linux-ppc64@0.24.2': + optional: true + + '@esbuild/linux-ppc64@0.25.1': + optional: true + '@esbuild/linux-riscv64@0.18.20': optional: true @@ -6252,6 +6339,12 @@ snapshots: '@esbuild/linux-riscv64@0.23.1': optional: true + '@esbuild/linux-riscv64@0.24.2': + optional: true + + '@esbuild/linux-riscv64@0.25.1': + optional: true + '@esbuild/linux-s390x@0.18.20': optional: true @@ -6261,6 +6354,12 @@ snapshots: '@esbuild/linux-s390x@0.23.1': optional: true + '@esbuild/linux-s390x@0.24.2': + optional: true + + '@esbuild/linux-s390x@0.25.1': + optional: true + '@esbuild/linux-x64@0.18.20': optional: true @@ -6270,6 +6369,18 @@ snapshots: '@esbuild/linux-x64@0.23.1': optional: true + '@esbuild/linux-x64@0.24.2': + optional: true + + '@esbuild/linux-x64@0.25.1': + optional: true + + '@esbuild/netbsd-arm64@0.24.2': + optional: true + + '@esbuild/netbsd-arm64@0.25.1': + optional: true + '@esbuild/netbsd-x64@0.18.20': optional: true @@ -6279,9 +6390,21 @@ snapshots: '@esbuild/netbsd-x64@0.23.1': optional: true + '@esbuild/netbsd-x64@0.24.2': + optional: true + + '@esbuild/netbsd-x64@0.25.1': + optional: true + '@esbuild/openbsd-arm64@0.23.1': optional: true + '@esbuild/openbsd-arm64@0.24.2': + optional: true + + '@esbuild/openbsd-arm64@0.25.1': + optional: true + '@esbuild/openbsd-x64@0.18.20': optional: true @@ -6291,6 +6414,12 @@ snapshots: '@esbuild/openbsd-x64@0.23.1': optional: true + '@esbuild/openbsd-x64@0.24.2': + optional: true + + '@esbuild/openbsd-x64@0.25.1': + optional: true + '@esbuild/sunos-x64@0.18.20': optional: true @@ -6300,6 +6429,12 @@ snapshots: '@esbuild/sunos-x64@0.23.1': optional: true + '@esbuild/sunos-x64@0.24.2': + optional: true + + '@esbuild/sunos-x64@0.25.1': + optional: true + '@esbuild/win32-arm64@0.18.20': optional: true @@ -6309,6 +6444,12 @@ snapshots: '@esbuild/win32-arm64@0.23.1': optional: true + '@esbuild/win32-arm64@0.24.2': + optional: true + + '@esbuild/win32-arm64@0.25.1': + optional: true + '@esbuild/win32-ia32@0.18.20': optional: true @@ -6318,6 +6459,12 @@ snapshots: '@esbuild/win32-ia32@0.23.1': optional: true + '@esbuild/win32-ia32@0.24.2': + optional: true + + '@esbuild/win32-ia32@0.25.1': + optional: true + '@esbuild/win32-x64@0.18.20': optional: true @@ -6327,9 +6474,15 @@ snapshots: '@esbuild/win32-x64@0.23.1': optional: true - '@eslint-community/eslint-utils@4.4.1(eslint@9.15.0)': + '@esbuild/win32-x64@0.24.2': + optional: true + + '@esbuild/win32-x64@0.25.1': + optional: true + + '@eslint-community/eslint-utils@4.4.1(eslint@9.15.0(jiti@2.4.2))': dependencies: - eslint: 9.15.0 + eslint: 9.15.0(jiti@2.4.2) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} @@ -6376,6 +6529,8 @@ snapshots: ajv-formats: 3.0.1 fast-uri: 3.0.3 + '@fastify/busboy@2.1.1': {} + '@fastify/cookie@11.0.2': dependencies: cookie: 1.0.2 @@ -6471,6 +6626,30 @@ snapshots: '@floating-ui/utils@0.2.9': {} + '@hattip/adapter-node@0.0.49': + dependencies: + '@hattip/core': 0.0.49 + '@hattip/polyfills': 0.0.49 + '@hattip/walk': 0.0.49 + + '@hattip/core@0.0.49': {} + + '@hattip/headers@0.0.49': + dependencies: + '@hattip/core': 0.0.49 + + '@hattip/polyfills@0.0.49': + dependencies: + '@hattip/core': 0.0.49 + '@whatwg-node/fetch': 0.9.23 + node-fetch-native: 1.6.6 + + '@hattip/walk@0.0.49': + dependencies: + '@hattip/headers': 0.0.49 + cac: 6.7.14 + mime-types: 2.1.35 + '@headlessui/react@2.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': dependencies: '@floating-ui/react': 0.26.28(react-dom@19.0.0(react@19.0.0))(react@19.0.0) @@ -6513,6 +6692,81 @@ snapshots: transitivePeerDependencies: - supports-color + '@img/sharp-darwin-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.4 + optional: true + + '@img/sharp-darwin-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.0.5': + optional: true + + '@img/sharp-libvips-linux-s390x@1.0.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + optional: true + + '@img/sharp-linux-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.4 + optional: true + + '@img/sharp-linux-arm@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.5 + optional: true + + '@img/sharp-linux-s390x@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.0.4 + optional: true + + '@img/sharp-linux-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + optional: true + + '@img/sharp-wasm32@0.33.5': + dependencies: + '@emnapi/runtime': 1.3.1 + optional: true + + '@img/sharp-win32-ia32@0.33.5': + optional: true + + '@img/sharp-win32-x64@0.33.5': + optional: true + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -6544,6 +6798,11 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jsonjoy.com/base64@1.1.2(tslib@2.8.1)': dependencies: tslib: 2.8.1 @@ -6560,6 +6819,8 @@ snapshots: dependencies: tslib: 2.8.1 + '@kamilkisiela/fast-url-parser@1.1.4': {} + '@leichtgewicht/ip-codec@2.0.5': {} '@libsql/client@0.14.0': @@ -6635,6 +6896,8 @@ snapshots: - encoding - supports-color + '@mjackson/node-fetch-server@0.2.0': {} + '@neon-rs/load@0.0.4': {} '@nodelib/fs.scandir@2.1.5': @@ -6651,14 +6914,46 @@ snapshots: '@nolyfill/is-core-module@1.0.39': {} - '@pkgr/core@0.1.1': {} + '@npmcli/git@4.1.0': + dependencies: + '@npmcli/promise-spawn': 6.0.2 + lru-cache: 7.18.3 + npm-pick-manifest: 8.0.2 + proc-log: 3.0.0 + promise-inflight: 1.0.1 + promise-retry: 2.0.1 + semver: 7.6.3 + which: 3.0.1 + transitivePeerDependencies: + - bluebird + + '@npmcli/package-json@4.0.1': + dependencies: + '@npmcli/git': 4.1.0 + glob: 10.4.5 + hosted-git-info: 6.1.3 + json-parse-even-better-errors: 3.0.2 + normalize-package-data: 5.0.0 + proc-log: 3.0.0 + semver: 7.6.3 + transitivePeerDependencies: + - bluebird - '@playwright/test@1.50.1': + '@npmcli/promise-spawn@6.0.2': dependencies: - playwright: 1.50.1 + which: 3.0.1 + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@pkgr/core@0.1.1': {} '@polka/url@1.0.0-next.28': {} + '@quansync/fs@0.1.1': + dependencies: + quansync: 0.2.8 + '@radix-ui/number@1.1.0': {} '@radix-ui/primitive@1.1.1': {} @@ -6794,6 +7089,66 @@ snapshots: react: 19.0.0 react-dom: 19.0.0(react@19.0.0) + '@react-router/dev@7.4.0(@types/node@22.10.0)(jiti@2.4.2)(react-router@7.4.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(terser@5.36.0)(tsx@4.19.2)(typescript@5.7.2)(vite@6.2.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1))(wrangler@4.4.0(@cloudflare/workers-types@4.20250321.0))(yaml@2.6.1)': + dependencies: + '@babel/core': 7.26.0 + '@babel/generator': 7.26.2 + '@babel/parser': 7.26.2 + '@babel/plugin-syntax-decorators': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.0) + '@babel/preset-typescript': 7.26.0(@babel/core@7.26.0) + '@babel/traverse': 7.25.9 + '@babel/types': 7.26.0 + '@npmcli/package-json': 4.0.1 + '@react-router/node': 7.4.0(react-router@7.4.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(typescript@5.7.2) + arg: 5.0.2 + babel-dead-code-elimination: 1.0.9 + chokidar: 4.0.3 + dedent: 1.5.3 + es-module-lexer: 1.5.4 + exit-hook: 2.2.1 + fs-extra: 10.1.0 + jsesc: 3.0.2 + lodash: 4.17.21 + pathe: 1.1.2 + picocolors: 1.1.1 + prettier: 2.8.8 + react-refresh: 0.14.2 + react-router: 7.4.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + semver: 7.6.3 + set-cookie-parser: 2.7.1 + valibot: 0.41.0(typescript@5.7.2) + vite: 6.2.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1) + vite-node: 3.0.0-beta.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1) + optionalDependencies: + typescript: 5.7.2 + wrangler: 4.4.0(@cloudflare/workers-types@4.20250321.0) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - bluebird + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + '@react-router/node@7.4.0(react-router@7.4.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(typescript@5.7.2)': + dependencies: + '@mjackson/node-fetch-server': 0.2.0 + react-router: 7.4.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + source-map-support: 0.5.21 + stream-slice: 0.1.2 + undici: 6.21.2 + optionalDependencies: + typescript: 5.7.2 + '@react-stately/utils@3.10.5(react@19.0.0)': dependencies: '@swc/helpers': 0.5.15 @@ -6803,6 +7158,63 @@ snapshots: dependencies: react: 19.0.0 + '@rollup/rollup-android-arm-eabi@4.36.0': + optional: true + + '@rollup/rollup-android-arm64@4.36.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.36.0': + optional: true + + '@rollup/rollup-darwin-x64@4.36.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.36.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.36.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.36.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.36.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.36.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.36.0': + optional: true + + '@rollup/rollup-linux-loongarch64-gnu@4.36.0': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.36.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.36.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.36.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.36.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.36.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.36.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.36.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.36.0': + optional: true + '@rtsao/scc@1.1.0': {} '@seriousme/openapi-schema-validator@2.3.0': @@ -6813,14 +7225,6 @@ snapshots: js-yaml: 4.1.0 minimist: 1.2.8 - '@sinclair/typebox@0.34.30': {} - - '@sinclair/typemap@0.8.18(@sinclair/typebox@0.34.30)(valibot@1.0.0-rc.3(typescript@5.7.2))(zod@3.24.1)': - dependencies: - '@sinclair/typebox': 0.34.30 - valibot: 1.0.0-rc.3(typescript@5.7.2) - zod: 3.24.1 - '@standard-schema/spec@1.0.0': {} '@swc/helpers@0.5.15': @@ -6837,6 +7241,27 @@ snapshots: '@tsconfig/strictest@2.0.5': {} + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.26.10 + '@babel/types': 7.26.10 + '@types/babel__generator': 7.6.8 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.6 + + '@types/babel__generator@7.6.8': + dependencies: + '@babel/types': 7.26.10 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.26.10 + '@babel/types': 7.26.10 + + '@types/babel__traverse@7.20.6': + dependencies: + '@babel/types': 7.26.10 + '@types/bcrypt@5.0.2': dependencies: '@types/node': 22.10.0 @@ -6902,16 +7327,12 @@ snapshots: dependencies: '@types/node': 22.10.0 - '@types/js-cookie@2.2.7': {} - '@types/jsesc@3.0.3': {} '@types/json-schema@7.0.15': {} '@types/json5@0.0.29': {} - '@types/lodash@4.17.16': {} - '@types/luxon@3.4.2': {} '@types/m3u8-parser@7.2.0': {} @@ -6965,15 +7386,15 @@ snapshots: dependencies: '@types/node': 22.10.0 - '@typescript-eslint/eslint-plugin@8.16.0(@typescript-eslint/parser@8.16.0(eslint@9.15.0)(typescript@5.7.2))(eslint@9.15.0)(typescript@5.7.2)': + '@typescript-eslint/eslint-plugin@8.16.0(@typescript-eslint/parser@8.16.0(eslint@9.15.0(jiti@2.4.2))(typescript@5.7.2))(eslint@9.15.0(jiti@2.4.2))(typescript@5.7.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.16.0(eslint@9.15.0)(typescript@5.7.2) + '@typescript-eslint/parser': 8.16.0(eslint@9.15.0(jiti@2.4.2))(typescript@5.7.2) '@typescript-eslint/scope-manager': 8.16.0 - '@typescript-eslint/type-utils': 8.16.0(eslint@9.15.0)(typescript@5.7.2) - '@typescript-eslint/utils': 8.16.0(eslint@9.15.0)(typescript@5.7.2) + '@typescript-eslint/type-utils': 8.16.0(eslint@9.15.0(jiti@2.4.2))(typescript@5.7.2) + '@typescript-eslint/utils': 8.16.0(eslint@9.15.0(jiti@2.4.2))(typescript@5.7.2) '@typescript-eslint/visitor-keys': 8.16.0 - eslint: 9.15.0 + eslint: 9.15.0(jiti@2.4.2) graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 @@ -6983,14 +7404,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.16.0(eslint@9.15.0)(typescript@5.7.2)': + '@typescript-eslint/parser@8.16.0(eslint@9.15.0(jiti@2.4.2))(typescript@5.7.2)': dependencies: '@typescript-eslint/scope-manager': 8.16.0 '@typescript-eslint/types': 8.16.0 '@typescript-eslint/typescript-estree': 8.16.0(typescript@5.7.2) '@typescript-eslint/visitor-keys': 8.16.0 debug: 4.3.7 - eslint: 9.15.0 + eslint: 9.15.0(jiti@2.4.2) optionalDependencies: typescript: 5.7.2 transitivePeerDependencies: @@ -7001,12 +7422,12 @@ snapshots: '@typescript-eslint/types': 8.16.0 '@typescript-eslint/visitor-keys': 8.16.0 - '@typescript-eslint/type-utils@8.16.0(eslint@9.15.0)(typescript@5.7.2)': + '@typescript-eslint/type-utils@8.16.0(eslint@9.15.0(jiti@2.4.2))(typescript@5.7.2)': dependencies: '@typescript-eslint/typescript-estree': 8.16.0(typescript@5.7.2) - '@typescript-eslint/utils': 8.16.0(eslint@9.15.0)(typescript@5.7.2) - debug: 4.3.7 - eslint: 9.15.0 + '@typescript-eslint/utils': 8.16.0(eslint@9.15.0(jiti@2.4.2))(typescript@5.7.2) + debug: 4.4.0 + eslint: 9.15.0(jiti@2.4.2) ts-api-utils: 1.4.2(typescript@5.7.2) optionalDependencies: typescript: 5.7.2 @@ -7019,7 +7440,7 @@ snapshots: dependencies: '@typescript-eslint/types': 8.16.0 '@typescript-eslint/visitor-keys': 8.16.0 - debug: 4.3.7 + debug: 4.4.0 fast-glob: 3.3.2 is-glob: 4.0.3 minimatch: 9.0.5 @@ -7030,13 +7451,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.16.0(eslint@9.15.0)(typescript@5.7.2)': + '@typescript-eslint/utils@8.16.0(eslint@9.15.0(jiti@2.4.2))(typescript@5.7.2)': dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.15.0) + '@eslint-community/eslint-utils': 4.4.1(eslint@9.15.0(jiti@2.4.2)) '@typescript-eslint/scope-manager': 8.16.0 '@typescript-eslint/types': 8.16.0 '@typescript-eslint/typescript-estree': 8.16.0(typescript@5.7.2) - eslint: 9.15.0 + eslint: 9.15.0(jiti@2.4.2) optionalDependencies: typescript: 5.7.2 transitivePeerDependencies: @@ -7047,75 +7468,172 @@ snapshots: '@typescript-eslint/types': 8.16.0 eslint-visitor-keys: 4.2.0 - '@unocss/core@66.1.0-beta.5': {} + '@unocss/astro@66.1.0-beta.6(vite@6.2.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1))': + dependencies: + '@unocss/core': 66.1.0-beta.6 + '@unocss/reset': 66.1.0-beta.6 + '@unocss/vite': 66.1.0-beta.6(vite@6.2.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1)) + optionalDependencies: + vite: 6.2.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1) + transitivePeerDependencies: + - vue + + '@unocss/cli@66.1.0-beta.6': + dependencies: + '@ampproject/remapping': 2.3.0 + '@unocss/config': 66.1.0-beta.6 + '@unocss/core': 66.1.0-beta.6 + '@unocss/preset-uno': 66.1.0-beta.6 + cac: 6.7.14 + chokidar: 3.6.0 + colorette: 2.0.20 + consola: 3.4.2 + magic-string: 0.30.17 + pathe: 2.0.3 + perfect-debounce: 1.0.0 + tinyglobby: 0.2.12 + unplugin-utils: 0.2.4 + + '@unocss/config@66.1.0-beta.6': + dependencies: + '@unocss/core': 66.1.0-beta.6 + unconfig: 7.3.1 + + '@unocss/core@66.1.0-beta.6': {} + + '@unocss/extractor-arbitrary-variants@66.1.0-beta.6': + dependencies: + '@unocss/core': 66.1.0-beta.6 + + '@unocss/inspector@66.1.0-beta.6': + dependencies: + '@unocss/core': 66.1.0-beta.6 + '@unocss/rule-utils': 66.1.0-beta.6 + colorette: 2.0.20 + gzip-size: 6.0.0 + sirv: 3.0.1 + vue-flow-layout: 0.1.1 + transitivePeerDependencies: + - vue - '@unocss/extractor-arbitrary-variants@66.1.0-beta.5': + '@unocss/postcss@66.1.0-beta.6': dependencies: - '@unocss/core': 66.1.0-beta.5 + '@unocss/config': 66.1.0-beta.6 + '@unocss/core': 66.1.0-beta.6 + '@unocss/rule-utils': 66.1.0-beta.6 + css-tree: 3.1.0 + postcss: 8.5.3 + tinyglobby: 0.2.12 - '@unocss/preset-attributify@66.1.0-beta.5': + '@unocss/preset-attributify@66.1.0-beta.6': dependencies: - '@unocss/core': 66.1.0-beta.5 + '@unocss/core': 66.1.0-beta.6 - '@unocss/preset-icons@66.1.0-beta.5': + '@unocss/preset-icons@66.1.0-beta.6': dependencies: '@iconify/utils': 2.3.0 - '@unocss/core': 66.1.0-beta.5 + '@unocss/core': 66.1.0-beta.6 ofetch: 1.4.1 transitivePeerDependencies: - supports-color - '@unocss/preset-mini@66.1.0-beta.5': + '@unocss/preset-mini@66.1.0-beta.6': + dependencies: + '@unocss/core': 66.1.0-beta.6 + '@unocss/extractor-arbitrary-variants': 66.1.0-beta.6 + '@unocss/rule-utils': 66.1.0-beta.6 + + '@unocss/preset-tagify@66.1.0-beta.6': + dependencies: + '@unocss/core': 66.1.0-beta.6 + + '@unocss/preset-typography@66.1.0-beta.6': + dependencies: + '@unocss/core': 66.1.0-beta.6 + '@unocss/preset-mini': 66.1.0-beta.6 + '@unocss/rule-utils': 66.1.0-beta.6 + + '@unocss/preset-uno@66.1.0-beta.6': dependencies: - '@unocss/core': 66.1.0-beta.5 - '@unocss/extractor-arbitrary-variants': 66.1.0-beta.5 - '@unocss/rule-utils': 66.1.0-beta.5 + '@unocss/core': 66.1.0-beta.6 + '@unocss/preset-wind3': 66.1.0-beta.6 - '@unocss/preset-uno@66.1.0-beta.5': + '@unocss/preset-web-fonts@66.1.0-beta.6': dependencies: - '@unocss/core': 66.1.0-beta.5 - '@unocss/preset-wind3': 66.1.0-beta.5 + '@unocss/core': 66.1.0-beta.6 + ofetch: 1.4.1 + + '@unocss/preset-wind3@66.1.0-beta.6': + dependencies: + '@unocss/core': 66.1.0-beta.6 + '@unocss/preset-mini': 66.1.0-beta.6 + '@unocss/rule-utils': 66.1.0-beta.6 + + '@unocss/preset-wind4@66.1.0-beta.6': + dependencies: + '@unocss/core': 66.1.0-beta.6 + '@unocss/extractor-arbitrary-variants': 66.1.0-beta.6 + '@unocss/rule-utils': 66.1.0-beta.6 - '@unocss/preset-wind3@66.1.0-beta.5': + '@unocss/preset-wind@66.1.0-beta.6': dependencies: - '@unocss/core': 66.1.0-beta.5 - '@unocss/preset-mini': 66.1.0-beta.5 - '@unocss/rule-utils': 66.1.0-beta.5 + '@unocss/core': 66.1.0-beta.6 + '@unocss/preset-wind3': 66.1.0-beta.6 - '@unocss/reset@66.1.0-beta.5': {} + '@unocss/reset@66.1.0-beta.6': {} - '@unocss/rule-utils@66.1.0-beta.5': + '@unocss/rule-utils@66.1.0-beta.6': dependencies: - '@unocss/core': 66.1.0-beta.5 + '@unocss/core': 66.1.0-beta.6 magic-string: 0.30.17 - '@unocss/runtime@66.1.0-beta.5': + '@unocss/transformer-attributify-jsx@66.1.0-beta.6': dependencies: - '@unocss/core': 66.1.0-beta.5 - '@unocss/preset-attributify': 66.1.0-beta.5 - '@unocss/preset-uno': 66.1.0-beta.5 + '@unocss/core': 66.1.0-beta.6 - '@videojs/http-streaming@3.16.2(video.js@8.21.0)': + '@unocss/transformer-compile-class@66.1.0-beta.6': dependencies: - '@babel/runtime': 7.26.10 - '@videojs/vhs-utils': 4.1.1 - aes-decrypter: 4.0.2 - global: 4.4.0 - m3u8-parser: 7.2.0 - mpd-parser: 1.3.1 - mux.js: 7.1.0 - video.js: 8.21.0 + '@unocss/core': 66.1.0-beta.6 + + '@unocss/transformer-directives@66.1.0-beta.6': + dependencies: + '@unocss/core': 66.1.0-beta.6 + '@unocss/rule-utils': 66.1.0-beta.6 + css-tree: 3.1.0 + + '@unocss/transformer-variant-group@66.1.0-beta.6': + dependencies: + '@unocss/core': 66.1.0-beta.6 + + '@unocss/vite@66.1.0-beta.6(vite@6.2.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1))': + dependencies: + '@ampproject/remapping': 2.3.0 + '@unocss/config': 66.1.0-beta.6 + '@unocss/core': 66.1.0-beta.6 + '@unocss/inspector': 66.1.0-beta.6 + chokidar: 3.6.0 + magic-string: 0.30.17 + tinyglobby: 0.2.12 + unplugin-utils: 0.2.4 + vite: 6.2.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1) + transitivePeerDependencies: + - vue '@videojs/vhs-utils@4.1.1': dependencies: '@babel/runtime': 7.26.10 global: 4.4.0 - '@videojs/xhr@2.7.0': + '@vitejs/plugin-react@4.3.4(vite@6.2.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1))': dependencies: - '@babel/runtime': 7.26.10 - global: 4.4.0 - is-function: 1.0.2 + '@babel/core': 7.26.0 + '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.0) + '@types/babel__core': 7.20.5 + react-refresh: 0.14.2 + vite: 6.2.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1) + transitivePeerDependencies: + - supports-color '@webassemblyjs/ast@1.14.1': dependencies: @@ -7196,23 +7714,31 @@ snapshots: '@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4)(webpack@5.96.1)': dependencies: webpack: 5.96.1(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.1.0)(webpack@5.96.1) + webpack-cli: 5.1.4(webpack-dev-server@5.1.0)(webpack@5.96.1) '@webpack-cli/info@2.0.2(webpack-cli@5.1.4)(webpack@5.96.1)': dependencies: webpack: 5.96.1(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.1.0)(webpack@5.96.1) + webpack-cli: 5.1.4(webpack-dev-server@5.1.0)(webpack@5.96.1) '@webpack-cli/serve@2.0.5(webpack-cli@5.1.4)(webpack-dev-server@5.1.0)(webpack@5.96.1)': dependencies: webpack: 5.96.1(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.1.0)(webpack@5.96.1) + webpack-cli: 5.1.4(webpack-dev-server@5.1.0)(webpack@5.96.1) optionalDependencies: webpack-dev-server: 5.1.0(webpack-cli@5.1.4)(webpack@5.96.1) - '@xmldom/xmldom@0.8.10': {} + '@whatwg-node/fetch@0.9.23': + dependencies: + '@whatwg-node/node-fetch': 0.6.0 + urlpattern-polyfill: 10.0.0 - '@xobotyi/scrollbar-width@1.9.5': {} + '@whatwg-node/node-fetch@0.6.0': + dependencies: + '@kamilkisiela/fast-url-parser': 1.1.4 + busboy: 1.6.0 + fast-querystring: 1.1.2 + tslib: 2.8.1 '@xtuc/ieee754@1.2.0': {} @@ -7237,22 +7763,13 @@ snapshots: dependencies: acorn: 8.14.0 - acorn-walk@8.3.4: - dependencies: - acorn: 8.14.0 + acorn-walk@8.3.2: {} acorn@8.14.0: {} - aes-decrypter@4.0.2: - dependencies: - '@babel/runtime': 7.26.10 - '@videojs/vhs-utils': 4.1.1 - global: 4.4.0 - pkcs7: 1.0.4 - agent-base@6.0.2: dependencies: - debug: 4.3.7 + debug: 4.4.0 transitivePeerDependencies: - supports-color @@ -7315,6 +7832,8 @@ snapshots: delegates: 1.0.0 readable-stream: 3.6.2 + arg@5.0.2: {} + argparse@2.0.1: {} array-buffer-byte-length@1.0.2: @@ -7326,12 +7845,12 @@ snapshots: array-includes@3.1.8: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 es-abstract: 1.23.9 - es-object-atoms: 1.0.0 - get-intrinsic: 1.2.4 - is-string: 1.0.7 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + is-string: 1.1.1 array.prototype.findlast@1.2.5: dependencies: @@ -7344,23 +7863,16 @@ snapshots: array.prototype.findlastindex@1.2.5: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 es-abstract: 1.23.9 es-errors: 1.3.0 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 es-shim-unscopables: 1.0.2 array.prototype.flat@1.3.2: dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.23.9 - es-shim-unscopables: 1.0.2 - - array.prototype.flatmap@1.3.2: - dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 es-abstract: 1.23.9 es-shim-unscopables: 1.0.2 @@ -7394,6 +7906,10 @@ snapshots: get-intrinsic: 1.3.0 is-array-buffer: 3.0.5 + as-table@1.0.55: + dependencies: + printable-characters: 1.0.42 + atomic-sleep@1.0.0: {} available-typed-arrays@1.0.7: @@ -7405,36 +7921,21 @@ snapshots: '@fastify/error': 4.0.0 fastq: 1.17.1 - babel-loader@9.2.1(@babel/core@7.26.0)(webpack@5.96.1): - dependencies: - '@babel/core': 7.26.0 - find-cache-dir: 4.0.0 - schema-utils: 4.2.0 - webpack: 5.96.1(webpack-cli@5.1.4) - - babel-plugin-polyfill-corejs2@0.4.12(@babel/core@7.26.0): - dependencies: - '@babel/compat-data': 7.26.2 - '@babel/core': 7.26.0 - '@babel/helper-define-polyfill-provider': 0.6.3(@babel/core@7.26.0) - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - babel-plugin-polyfill-corejs3@0.10.6(@babel/core@7.26.0): + babel-dead-code-elimination@1.0.9: dependencies: '@babel/core': 7.26.0 - '@babel/helper-define-polyfill-provider': 0.6.3(@babel/core@7.26.0) - core-js-compat: 3.39.0 + '@babel/parser': 7.26.2 + '@babel/traverse': 7.25.9 + '@babel/types': 7.26.0 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.6.3(@babel/core@7.26.0): + babel-loader@9.2.1(@babel/core@7.26.0)(webpack@5.96.1): dependencies: '@babel/core': 7.26.0 - '@babel/helper-define-polyfill-provider': 0.6.3(@babel/core@7.26.0) - transitivePeerDependencies: - - supports-color + find-cache-dir: 4.0.0 + schema-utils: 4.2.0 + webpack: 5.96.1(webpack-cli@5.1.4) balanced-match@1.0.2: {} @@ -7454,6 +7955,8 @@ snapshots: binary-extensions@2.3.0: {} + blake3-wasm@2.1.5: {} + body-parser@1.20.3: dependencies: bytes: 3.1.2 @@ -7506,8 +8009,14 @@ snapshots: dependencies: run-applescript: 7.0.0 + busboy@1.6.0: + dependencies: + streamsearch: 1.1.0 + bytes@3.1.2: {} + cac@6.7.14: {} + call-bind-apply-helpers@1.0.2: dependencies: es-errors: 1.3.0 @@ -7554,12 +8063,22 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + chownr@2.0.0: {} chrome-trace-event@1.0.4: {} classnames@2.5.1: {} + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + clone-deep@4.0.1: dependencies: is-plain-object: 2.0.4 @@ -7574,16 +8093,26 @@ snapshots: color-name@1.1.4: {} + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + optional: true + color-support@1.1.3: {} + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + optional: true + colorette@2.0.20: {} commander@10.0.1: {} commander@2.20.3: {} - commander@7.2.0: {} - common-path-prefix@3.0.0: {} compressible@2.0.18: @@ -7610,6 +8139,8 @@ snapshots: connect-history-api-fallback@2.0.0: {} + consola@3.4.2: {} + console-control-strings@1.1.0: {} content-disposition@0.5.4: @@ -7622,20 +8153,12 @@ snapshots: cookie-signature@1.0.6: {} + cookie@0.5.0: {} + cookie@0.7.1: {} cookie@1.0.2: {} - copy-to-clipboard@3.3.3: - dependencies: - toggle-selection: 1.0.6 - - core-js-compat@3.39.0: - dependencies: - browserslist: 4.24.2 - - core-js@3.41.0: {} - core-util-is@1.0.3: {} cross-spawn@7.0.6: @@ -7644,17 +8167,15 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - css-in-js-utils@3.1.0: + css-tree@3.1.0: dependencies: - hyphenate-style-name: 1.1.0 - - css-tree@1.1.3: - dependencies: - mdn-data: 2.0.14 - source-map: 0.6.1 + mdn-data: 2.12.2 + source-map-js: 1.2.1 csstype@3.1.3: {} + data-uri-to-buffer@2.0.2: {} + data-uri-to-buffer@4.0.1: {} data-view-buffer@1.0.2: @@ -7675,8 +8196,6 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.2 - debounce@1.2.1: {} - debug@2.6.9: dependencies: ms: 2.0.0 @@ -7697,6 +8216,8 @@ snapshots: deep-is@0.1.4: {} + deepmerge@4.3.1: {} + default-browser-id@5.0.0: {} default-browser@5.2.1: @@ -7710,6 +8231,8 @@ snapshots: es-errors: 1.3.0 gopd: 1.0.1 + define-lazy-prop@2.0.0: {} + define-lazy-prop@3.0.0: {} define-properties@1.2.1: @@ -7718,6 +8241,8 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 + defu@6.1.4: {} + delegates@1.0.0: {} depd@1.1.2: {} @@ -7732,6 +8257,9 @@ snapshots: detect-libc@2.0.2: {} + detect-libc@2.0.3: + optional: true + detect-newline@4.0.1: {} detect-node@2.1.0: {} @@ -7755,21 +8283,22 @@ snapshots: transitivePeerDependencies: - supports-color - drizzle-orm@0.38.2(@libsql/client@0.14.0)(@types/react@19.0.1)(react@19.0.0): + drizzle-orm@0.38.2(@cloudflare/workers-types@4.20250321.0)(@libsql/client@0.14.0)(@types/react@19.0.1)(react@19.0.0): optionalDependencies: + '@cloudflare/workers-types': 4.20250321.0 '@libsql/client': 0.14.0 '@types/react': 19.0.1 react: 19.0.0 - drizzle-seed@0.1.3(drizzle-orm@0.38.2(@libsql/client@0.14.0)(@types/react@19.0.1)(react@19.0.0)): + drizzle-seed@0.1.3(drizzle-orm@0.38.2(@cloudflare/workers-types@4.20250321.0)(@libsql/client@0.14.0)(@types/react@19.0.1)(react@19.0.0)): dependencies: pure-rand: 6.1.0 optionalDependencies: - drizzle-orm: 0.38.2(@libsql/client@0.14.0)(@types/react@19.0.1)(react@19.0.0) + drizzle-orm: 0.38.2(@cloudflare/workers-types@4.20250321.0)(@libsql/client@0.14.0)(@types/react@19.0.1)(react@19.0.0) - drizzle-zod@0.6.0(drizzle-orm@0.38.2(@libsql/client@0.14.0)(@types/react@19.0.1)(react@19.0.0))(zod@3.24.1): + drizzle-zod@0.6.0(drizzle-orm@0.38.2(@cloudflare/workers-types@4.20250321.0)(@libsql/client@0.14.0)(@types/react@19.0.1)(react@19.0.0))(zod@3.24.1): dependencies: - drizzle-orm: 0.38.2(@libsql/client@0.14.0)(@types/react@19.0.1)(react@19.0.0) + drizzle-orm: 0.38.2(@cloudflare/workers-types@4.20250321.0)(@libsql/client@0.14.0)(@types/react@19.0.1)(react@19.0.0) zod: 3.24.1 dunder-proto@1.0.1: @@ -7786,8 +8315,6 @@ snapshots: electron-to-chromium@1.5.65: {} - eme-encryption-scheme-polyfill@2.1.6: {} - emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} @@ -7805,9 +8332,7 @@ snapshots: envinfo@7.14.0: {} - error-stack-parser@2.1.4: - dependencies: - stackframe: 1.3.4 + err-code@2.0.3: {} es-abstract@1.23.9: dependencies: @@ -7865,7 +8390,7 @@ snapshots: es-define-property@1.0.0: dependencies: - get-intrinsic: 1.2.4 + get-intrinsic: 1.3.0 es-define-property@1.0.1: {} @@ -7925,7 +8450,7 @@ snapshots: esbuild-register@3.6.0(esbuild@0.19.12): dependencies: - debug: 4.3.7 + debug: 4.4.0 esbuild: 0.19.12 transitivePeerDependencies: - supports-color @@ -8008,15 +8533,71 @@ snapshots: '@esbuild/win32-ia32': 0.23.1 '@esbuild/win32-x64': 0.23.1 + esbuild@0.24.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.24.2 + '@esbuild/android-arm': 0.24.2 + '@esbuild/android-arm64': 0.24.2 + '@esbuild/android-x64': 0.24.2 + '@esbuild/darwin-arm64': 0.24.2 + '@esbuild/darwin-x64': 0.24.2 + '@esbuild/freebsd-arm64': 0.24.2 + '@esbuild/freebsd-x64': 0.24.2 + '@esbuild/linux-arm': 0.24.2 + '@esbuild/linux-arm64': 0.24.2 + '@esbuild/linux-ia32': 0.24.2 + '@esbuild/linux-loong64': 0.24.2 + '@esbuild/linux-mips64el': 0.24.2 + '@esbuild/linux-ppc64': 0.24.2 + '@esbuild/linux-riscv64': 0.24.2 + '@esbuild/linux-s390x': 0.24.2 + '@esbuild/linux-x64': 0.24.2 + '@esbuild/netbsd-arm64': 0.24.2 + '@esbuild/netbsd-x64': 0.24.2 + '@esbuild/openbsd-arm64': 0.24.2 + '@esbuild/openbsd-x64': 0.24.2 + '@esbuild/sunos-x64': 0.24.2 + '@esbuild/win32-arm64': 0.24.2 + '@esbuild/win32-ia32': 0.24.2 + '@esbuild/win32-x64': 0.24.2 + + esbuild@0.25.1: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.1 + '@esbuild/android-arm': 0.25.1 + '@esbuild/android-arm64': 0.25.1 + '@esbuild/android-x64': 0.25.1 + '@esbuild/darwin-arm64': 0.25.1 + '@esbuild/darwin-x64': 0.25.1 + '@esbuild/freebsd-arm64': 0.25.1 + '@esbuild/freebsd-x64': 0.25.1 + '@esbuild/linux-arm': 0.25.1 + '@esbuild/linux-arm64': 0.25.1 + '@esbuild/linux-ia32': 0.25.1 + '@esbuild/linux-loong64': 0.25.1 + '@esbuild/linux-mips64el': 0.25.1 + '@esbuild/linux-ppc64': 0.25.1 + '@esbuild/linux-riscv64': 0.25.1 + '@esbuild/linux-s390x': 0.25.1 + '@esbuild/linux-x64': 0.25.1 + '@esbuild/netbsd-arm64': 0.25.1 + '@esbuild/netbsd-x64': 0.25.1 + '@esbuild/openbsd-arm64': 0.25.1 + '@esbuild/openbsd-x64': 0.25.1 + '@esbuild/sunos-x64': 0.25.1 + '@esbuild/win32-arm64': 0.25.1 + '@esbuild/win32-ia32': 0.25.1 + '@esbuild/win32-x64': 0.25.1 + escalade@3.2.0: {} escape-html@1.0.3: {} escape-string-regexp@4.0.0: {} - eslint-config-prettier@9.1.0(eslint@9.15.0): + eslint-config-prettier@9.1.0(eslint@9.15.0(jiti@2.4.2)): dependencies: - eslint: 9.15.0 + eslint: 9.15.0(jiti@2.4.2) eslint-import-resolver-node@0.3.9: dependencies: @@ -8026,63 +8607,63 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.6.3(eslint-plugin-import@2.31.0)(eslint@9.15.0): + eslint-import-resolver-typescript@3.6.3(eslint-plugin-import@2.31.0)(eslint@9.15.0(jiti@2.4.2)): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.3.7 enhanced-resolve: 5.17.1 - eslint: 9.15.0 - eslint-module-utils: 2.12.0(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.15.0) + eslint: 9.15.0(jiti@2.4.2) + eslint-module-utils: 2.12.0(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.15.0(jiti@2.4.2)) fast-glob: 3.3.2 get-tsconfig: 4.8.1 is-bun-module: 1.2.1 is-glob: 4.0.3 optionalDependencies: - eslint-plugin-import: 2.31.0(eslint-import-resolver-typescript@3.6.3)(eslint@9.15.0) + eslint-plugin-import: 2.31.0(eslint-import-resolver-typescript@3.6.3)(eslint@9.15.0(jiti@2.4.2)) transitivePeerDependencies: - '@typescript-eslint/parser' - eslint-import-resolver-node - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.12.0(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.15.0): + eslint-module-utils@2.12.0(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.15.0(jiti@2.4.2)): dependencies: debug: 3.2.7 optionalDependencies: - eslint: 9.15.0 + eslint: 9.15.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(eslint-plugin-import@2.31.0)(eslint@9.15.0) + eslint-import-resolver-typescript: 3.6.3(eslint-plugin-import@2.31.0)(eslint@9.15.0(jiti@2.4.2)) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.31.0(eslint-import-resolver-typescript@3.6.3)(eslint@9.15.0): + eslint-plugin-import@2.31.0(eslint-import-resolver-typescript@3.6.3)(eslint@9.15.0(jiti@2.4.2)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 array.prototype.flat: 1.3.2 - array.prototype.flatmap: 1.3.2 + array.prototype.flatmap: 1.3.3 debug: 3.2.7 doctrine: 2.1.0 - eslint: 9.15.0 + eslint: 9.15.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.15.0) + eslint-module-utils: 2.12.0(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.15.0(jiti@2.4.2)) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 minimatch: 3.1.2 object.fromentries: 2.0.8 object.groupby: 1.0.3 - object.values: 1.2.0 + object.values: 1.2.1 semver: 6.3.1 - string.prototype.trimend: 1.0.8 + string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-react@7.37.4(eslint@9.15.0): + eslint-plugin-react@7.37.4(eslint@9.15.0(jiti@2.4.2)): dependencies: array-includes: 3.1.8 array.prototype.findlast: 1.2.5 @@ -8090,7 +8671,7 @@ snapshots: array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 es-iterator-helpers: 1.2.1 - eslint: 9.15.0 + eslint: 9.15.0(jiti@2.4.2) estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 @@ -8104,10 +8685,10 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - eslint-plugin-sort@4.0.0(eslint@9.15.0)(typescript@5.7.2): + eslint-plugin-sort@4.0.0(eslint@9.15.0(jiti@2.4.2))(typescript@5.7.2): dependencies: - '@typescript-eslint/utils': 8.16.0(eslint@9.15.0)(typescript@5.7.2) - eslint: 9.15.0 + '@typescript-eslint/utils': 8.16.0(eslint@9.15.0(jiti@2.4.2))(typescript@5.7.2) + eslint: 9.15.0(jiti@2.4.2) isomorphic-resolve: 1.0.0 natural-compare: 1.4.0 transitivePeerDependencies: @@ -8128,9 +8709,9 @@ snapshots: eslint-visitor-keys@4.2.0: {} - eslint@9.15.0: + eslint@9.15.0(jiti@2.4.2): dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.15.0) + '@eslint-community/eslint-utils': 4.4.1(eslint@9.15.0(jiti@2.4.2)) '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.19.0 '@eslint/core': 0.9.0 @@ -8164,6 +8745,8 @@ snapshots: minimatch: 3.1.2 natural-compare: 1.4.0 optionator: 0.9.4 + optionalDependencies: + jiti: 2.4.2 transitivePeerDependencies: - supports-color @@ -8193,6 +8776,8 @@ snapshots: events@3.3.0: {} + exit-hook@2.2.1: {} + express@4.21.1: dependencies: accepts: 1.3.8 @@ -8263,16 +8848,12 @@ snapshots: fast-redact@3.5.0: {} - fast-shallow-equal@1.0.0: {} - fast-uri@2.4.0: {} fast-uri@3.0.3: {} fastest-levenshtein@1.0.16: {} - fastest-stable-stringify@2.0.2: {} - fastify-openapi-glue@4.7.4: dependencies: '@seriousme/openapi-schema-validator': 2.3.0 @@ -8326,6 +8907,10 @@ snapshots: optionalDependencies: picomatch: 4.0.2 + fdir@6.4.3(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + fetch-blob@3.2.0: dependencies: node-domexception: 1.0.0 @@ -8413,15 +8998,18 @@ snapshots: fresh@0.5.2: {} + fs-extra@10.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + fs-minipass@2.1.0: dependencies: minipass: 3.3.6 fs.realpath@1.0.0: {} - fsevents@2.3.2: - optional: true - fsevents@2.3.3: optional: true @@ -8452,6 +9040,8 @@ snapshots: gensync@1.0.0-beta.2: {} + get-caller-file@2.0.5: {} + get-intrinsic@1.2.4: dependencies: es-errors: 1.3.0 @@ -8478,6 +9068,11 @@ snapshots: dunder-proto: 1.0.1 es-object-atoms: 1.1.1 + get-source@2.0.12: + dependencies: + data-uri-to-buffer: 2.0.2 + source-map: 0.6.1 + get-stdin@9.0.0: {} get-symbol-description@1.1.0: @@ -8502,6 +9097,15 @@ snapshots: glob-to-regexp@0.4.1: {} + glob@10.4.5: + dependencies: + foreground-child: 3.3.0 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + glob@11.0.0: dependencies: foreground-child: 3.3.0 @@ -8538,9 +9142,11 @@ snapshots: define-properties: 1.2.1 gopd: 1.2.0 + globrex@0.1.2: {} + gopd@1.0.1: dependencies: - get-intrinsic: 1.2.4 + get-intrinsic: 1.3.0 gopd@1.2.0: {} @@ -8584,6 +9190,10 @@ snapshots: hls.js@1.5.17: {} + hosted-git-info@6.1.3: + dependencies: + lru-cache: 7.18.3 + hpack.js@2.1.6: dependencies: inherits: 2.0.4 @@ -8593,8 +9203,6 @@ snapshots: html-entities@2.5.2: {} - html-escaper@2.0.2: {} - htmlescape@1.1.1: {} http-deceiver@1.2.7: {} @@ -8639,14 +9247,12 @@ snapshots: https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.3.7 + debug: 4.4.0 transitivePeerDependencies: - supports-color hyperdyperid@1.2.0: {} - hyphenate-style-name@1.1.0: {} - iconv-lite@0.4.24: dependencies: safer-buffer: 2.1.2 @@ -8659,8 +9265,6 @@ snapshots: immediate@3.0.6: {} - immer@10.1.1: {} - import-fresh@3.3.0: dependencies: parent-module: 1.0.1 @@ -8682,10 +9286,6 @@ snapshots: inherits@2.0.4: {} - inline-style-prefixer@7.0.1: - dependencies: - css-in-js-utils: 3.1.0 - internal-slot@1.1.0: dependencies: es-errors: 1.3.0 @@ -8704,6 +9304,9 @@ snapshots: call-bound: 1.0.4 get-intrinsic: 1.3.0 + is-arrayish@0.3.2: + optional: true + is-async-function@2.0.0: dependencies: has-tostringtag: 1.0.2 @@ -8742,6 +9345,8 @@ snapshots: call-bound: 1.0.4 has-tostringtag: 1.0.2 + is-docker@2.2.1: {} + is-docker@3.0.0: {} is-extglob@2.1.1: {} @@ -8752,8 +9357,6 @@ snapshots: is-fullwidth-code-point@3.0.0: {} - is-function@1.0.2: {} - is-generator-function@1.0.10: dependencies: has-tostringtag: 1.0.2 @@ -8798,10 +9401,6 @@ snapshots: dependencies: call-bound: 1.0.4 - is-string@1.0.7: - dependencies: - has-tostringtag: 1.0.2 - is-string@1.1.1: dependencies: call-bound: 1.0.4 @@ -8828,6 +9427,10 @@ snapshots: call-bind: 1.0.8 get-intrinsic: 1.3.0 + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + is-wsl@3.1.0: dependencies: is-inside-container: 1.0.0 @@ -8836,6 +9439,8 @@ snapshots: isarray@2.0.5: {} + isbot@5.1.25: {} + isexe@2.0.0: {} isobject@3.0.1: {} @@ -8851,6 +9456,12 @@ snapshots: has-symbols: 1.1.0 set-function-name: 2.0.2 + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + jackspeak@4.0.2: dependencies: '@isaacs/cliui': 8.0.2 @@ -8861,9 +9472,9 @@ snapshots: merge-stream: 2.0.0 supports-color: 8.1.1 - js-base64@3.7.7: {} + jiti@2.4.2: {} - js-cookie@2.2.1: {} + js-base64@3.7.7: {} js-tokens@4.0.0: {} @@ -8877,13 +9488,15 @@ snapshots: json-parse-even-better-errors@2.3.1: {} + json-parse-even-better-errors@3.0.2: {} + json-schema-ref-resolver@1.0.1: dependencies: fast-deep-equal: 3.1.3 json-schema-resolver@2.0.0: dependencies: - debug: 4.3.7 + debug: 4.4.0 rfdc: 1.4.1 uri-js: 4.4.1 transitivePeerDependencies: @@ -8903,6 +9516,12 @@ snapshots: jsonc-parser@3.3.1: {} + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + jsx-ast-utils@3.3.5: dependencies: array-includes: 3.1.8 @@ -8984,8 +9603,6 @@ snapshots: dependencies: p-locate: 6.0.0 - lodash.debounce@4.0.8: {} - lodash.merge@4.6.2: {} lodash@4.17.21: {} @@ -8994,12 +9611,16 @@ snapshots: dependencies: js-tokens: 4.0.0 + lru-cache@10.4.3: {} + lru-cache@11.0.2: {} lru-cache@5.1.1: dependencies: yallist: 3.1.1 + lru-cache@7.18.3: {} + luxon@3.5.0: {} m3u8-parser@7.2.0: @@ -9017,7 +9638,7 @@ snapshots: math-intrinsics@1.1.0: {} - mdn-data@2.0.14: {} + mdn-data@2.12.2: {} media-typer@0.3.0: {} @@ -9057,6 +9678,23 @@ snapshots: dependencies: dom-walk: 0.1.2 + miniflare@4.20250320.0: + dependencies: + '@cspotcode/source-map-support': 0.8.1 + acorn: 8.14.0 + acorn-walk: 8.3.2 + exit-hook: 2.2.1 + glob-to-regexp: 0.4.1 + stoppable: 1.1.0 + undici: 5.29.0 + workerd: 1.20250320.0 + ws: 8.18.0 + youch: 3.2.3 + zod: 3.22.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + minimalistic-assert@1.0.1: {} minimatch@10.0.1: @@ -9099,15 +9737,6 @@ snapshots: dependencies: obliterator: 2.0.4 - mockdate@3.0.5: {} - - mpd-parser@1.3.1: - dependencies: - '@babel/runtime': 7.26.10 - '@videojs/vhs-utils': 4.1.1 - '@xmldom/xmldom': 0.8.10 - global: 4.4.0 - mrmime@2.0.1: {} ms@2.0.0: {} @@ -9119,23 +9748,9 @@ snapshots: dns-packet: 5.6.1 thunky: 1.1.0 - mux.js@7.1.0: - dependencies: - '@babel/runtime': 7.26.10 - global: 4.4.0 + mustache@4.2.0: {} - nano-css@5.6.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@jridgewell/sourcemap-codec': 1.5.0 - css-tree: 1.1.3 - csstype: 3.1.3 - fastest-stable-stringify: 2.0.2 - inline-style-prefixer: 7.0.1 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - rtl-css-js: 1.16.1 - stacktrace-js: 2.0.2 - stylis: 4.3.6 + nanoid@3.3.11: {} natural-compare@1.4.0: {} @@ -9169,8 +9784,35 @@ snapshots: dependencies: abbrev: 1.1.1 + normalize-package-data@5.0.0: + dependencies: + hosted-git-info: 6.1.3 + is-core-module: 2.15.1 + semver: 7.6.3 + validate-npm-package-license: 3.0.4 + normalize-path@3.0.0: {} + npm-install-checks@6.3.0: + dependencies: + semver: 7.6.3 + + npm-normalize-package-bin@3.0.1: {} + + npm-package-arg@10.1.0: + dependencies: + hosted-git-info: 6.1.3 + proc-log: 3.0.0 + semver: 7.6.3 + validate-npm-package-name: 5.0.1 + + npm-pick-manifest@8.0.2: + dependencies: + npm-install-checks: 6.3.0 + npm-normalize-package-bin: 3.0.1 + npm-package-arg: 10.1.0 + semver: 7.6.3 + npmlog@5.0.1: dependencies: are-we-there-yet: 2.0.0 @@ -9209,29 +9851,23 @@ snapshots: object.fromentries@2.0.8: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 es-abstract: 1.23.9 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 object.groupby@1.0.3: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 es-abstract: 1.23.9 - object.values@1.2.0: - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-object-atoms: 1.0.0 - object.values@1.2.1: dependencies: call-bind: 1.0.8 call-bound: 1.0.4 define-properties: 1.2.1 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 obliterator@2.0.4: {} @@ -9243,6 +9879,8 @@ snapshots: node-fetch-native: 1.6.6 ufo: 1.5.4 + ohash@2.0.11: {} + on-exit-leak-free@2.1.2: {} on-finished@2.4.1: @@ -9262,9 +9900,13 @@ snapshots: is-inside-container: 1.0.0 is-wsl: 3.1.0 - openapi-types@12.1.3: {} + open@8.4.2: + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 - opener@1.5.2: {} + openapi-types@12.1.3: {} optionator@0.9.4: dependencies: @@ -9305,10 +9947,6 @@ snapshots: dependencies: p-limit: 4.0.0 - p-min-delay@4.0.2: - dependencies: - yoctodelay: 1.2.0 - p-retry@6.2.1: dependencies: '@types/retry': 0.12.2 @@ -9341,6 +9979,11 @@ snapshots: path-parse@1.0.7: {} + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + path-scurry@2.0.0: dependencies: lru-cache: 11.0.2 @@ -9348,10 +9991,14 @@ snapshots: path-to-regexp@0.1.10: {} + path-to-regexp@6.3.0: {} + pathe@1.1.2: {} pathe@2.0.3: {} + perfect-debounce@1.0.0: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -9378,10 +10025,6 @@ snapshots: sonic-boom: 4.2.0 thread-stream: 3.1.0 - pkcs7@1.0.4: - dependencies: - '@babel/runtime': 7.26.10 - pkg-dir@4.2.0: dependencies: find-up: 4.1.0 @@ -9402,15 +10045,13 @@ snapshots: exsolve: 1.0.4 pathe: 2.0.3 - playwright-core@1.50.1: {} + possible-typed-array-names@1.0.0: {} - playwright@1.50.1: + postcss@8.5.3: dependencies: - playwright-core: 1.50.1 - optionalDependencies: - fsevents: 2.3.2 - - possible-typed-array-names@1.0.0: {} + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 prelude-ls@1.2.1: {} @@ -9429,16 +10070,29 @@ snapshots: dependencies: prettier: 3.4.0 + prettier@2.8.8: {} + prettier@3.4.0: {} + printable-characters@1.0.42: {} + + proc-log@3.0.0: {} + process-nextick-args@2.0.1: {} process-warning@4.0.0: {} process@0.11.10: {} + promise-inflight@1.0.1: {} + promise-limit@2.7.0: {} + promise-retry@2.0.1: + dependencies: + err-code: 2.0.3 + retry: 0.12.0 + prop-types@15.8.1: dependencies: loose-envify: 1.4.0 @@ -9508,11 +10162,13 @@ snapshots: react-is@16.13.1: {} - react-router-dom@7.0.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + react-refresh@0.14.2: {} + + react-router-dom@7.4.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): dependencies: react: 19.0.0 react-dom: 19.0.0(react@19.0.0) - react-router: 7.0.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + react-router: 7.4.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) react-router@7.0.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0): dependencies: @@ -9524,29 +10180,15 @@ snapshots: optionalDependencies: react-dom: 19.0.0(react@19.0.0) - react-universal-interface@0.6.2(react@19.0.0)(tslib@2.8.1): - dependencies: - react: 19.0.0 - tslib: 2.8.1 - - react-use@17.6.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + react-router@7.4.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): dependencies: - '@types/js-cookie': 2.2.7 - '@xobotyi/scrollbar-width': 1.9.5 - copy-to-clipboard: 3.3.3 - fast-deep-equal: 3.1.3 - fast-shallow-equal: 1.0.0 - js-cookie: 2.2.1 - nano-css: 5.6.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@types/cookie': 0.6.0 + cookie: 1.0.2 react: 19.0.0 + set-cookie-parser: 2.7.1 + turbo-stream: 2.4.0 + optionalDependencies: react-dom: 19.0.0(react@19.0.0) - react-universal-interface: 0.6.2(react@19.0.0)(tslib@2.8.1) - resize-observer-polyfill: 1.5.1 - screenfull: 5.2.0 - set-harmonic-interval: 1.0.1 - throttle-debounce: 3.0.1 - ts-easing: 0.2.0 - tslib: 2.8.1 react@19.0.0: {} @@ -9570,6 +10212,8 @@ snapshots: dependencies: picomatch: 2.3.1 + readdirp@4.1.2: {} + real-require@0.2.0: {} rechoir@0.8.0: @@ -9587,18 +10231,8 @@ snapshots: get-proto: 1.0.1 which-builtin-type: 1.2.1 - regenerate-unicode-properties@10.2.0: - dependencies: - regenerate: 1.4.2 - - regenerate@1.4.2: {} - regenerator-runtime@0.14.1: {} - regenerator-transform@0.15.2: - dependencies: - '@babel/runtime': 7.26.10 - regexp.prototype.flags@1.5.3: dependencies: call-bind: 1.0.8 @@ -9606,23 +10240,10 @@ snapshots: es-errors: 1.3.0 set-function-name: 2.0.2 - regexpu-core@6.2.0: - dependencies: - regenerate: 1.4.2 - regenerate-unicode-properties: 10.2.0 - regjsgen: 0.8.0 - regjsparser: 0.12.0 - unicode-match-property-ecmascript: 2.0.0 - unicode-match-property-value-ecmascript: 2.2.0 - - regjsgen@0.8.0: {} - - regjsparser@0.12.0: - dependencies: - jsesc: 3.0.2 - rematrix@0.2.2: {} + require-directory@2.1.1: {} + require-from-string@2.0.2: {} requires-port@1.0.0: {} @@ -9665,9 +10286,39 @@ snapshots: dependencies: glob: 7.2.3 - rtl-css-js@1.16.1: + rollup-plugin-visualizer@5.14.0(rollup@4.36.0): dependencies: - '@babel/runtime': 7.26.10 + open: 8.4.2 + picomatch: 4.0.2 + source-map: 0.7.4 + yargs: 17.7.2 + optionalDependencies: + rollup: 4.36.0 + + rollup@4.36.0: + dependencies: + '@types/estree': 1.0.6 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.36.0 + '@rollup/rollup-android-arm64': 4.36.0 + '@rollup/rollup-darwin-arm64': 4.36.0 + '@rollup/rollup-darwin-x64': 4.36.0 + '@rollup/rollup-freebsd-arm64': 4.36.0 + '@rollup/rollup-freebsd-x64': 4.36.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.36.0 + '@rollup/rollup-linux-arm-musleabihf': 4.36.0 + '@rollup/rollup-linux-arm64-gnu': 4.36.0 + '@rollup/rollup-linux-arm64-musl': 4.36.0 + '@rollup/rollup-linux-loongarch64-gnu': 4.36.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.36.0 + '@rollup/rollup-linux-riscv64-gnu': 4.36.0 + '@rollup/rollup-linux-s390x-gnu': 4.36.0 + '@rollup/rollup-linux-x64-gnu': 4.36.0 + '@rollup/rollup-linux-x64-musl': 4.36.0 + '@rollup/rollup-win32-arm64-msvc': 4.36.0 + '@rollup/rollup-win32-ia32-msvc': 4.36.0 + '@rollup/rollup-win32-x64-msvc': 4.36.0 + fsevents: 2.3.3 run-applescript@7.0.0: {} @@ -9721,8 +10372,6 @@ snapshots: ajv-formats: 2.1.1 ajv-keywords: 5.1.0(ajv@8.17.1) - screenfull@5.2.0: {} - secure-json-parse@2.7.0: {} select-hose@2.0.0: {} @@ -9788,7 +10437,7 @@ snapshots: define-data-property: 1.1.4 es-errors: 1.3.0 function-bind: 1.1.2 - get-intrinsic: 1.2.4 + get-intrinsic: 1.3.0 gopd: 1.0.1 has-property-descriptors: 1.0.2 @@ -9799,8 +10448,6 @@ snapshots: functions-have-names: 1.2.3 has-property-descriptors: 1.0.2 - set-harmonic-interval@1.0.1: {} - set-proto@1.0.0: dependencies: dunder-proto: 1.0.1 @@ -9813,14 +10460,37 @@ snapshots: setprototypeof@1.2.0: {} - shaka-player@4.12.5(patch_hash=ztcamgtqc3a62la4l6p3d6w4ae): - dependencies: - eme-encryption-scheme-polyfill: 2.1.6 - shallow-clone@3.0.1: dependencies: kind-of: 6.0.3 + sharp@0.33.5: + dependencies: + color: 4.2.3 + detect-libc: 2.0.3 + semver: 7.6.3 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.5 + '@img/sharp-darwin-x64': 0.33.5 + '@img/sharp-libvips-darwin-arm64': 1.0.4 + '@img/sharp-libvips-darwin-x64': 1.0.4 + '@img/sharp-libvips-linux-arm': 1.0.5 + '@img/sharp-libvips-linux-arm64': 1.0.4 + '@img/sharp-libvips-linux-s390x': 1.0.4 + '@img/sharp-libvips-linux-x64': 1.0.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + '@img/sharp-linux-arm': 0.33.5 + '@img/sharp-linux-arm64': 0.33.5 + '@img/sharp-linux-s390x': 0.33.5 + '@img/sharp-linux-x64': 0.33.5 + '@img/sharp-linuxmusl-arm64': 0.33.5 + '@img/sharp-linuxmusl-x64': 0.33.5 + '@img/sharp-wasm32': 0.33.5 + '@img/sharp-win32-ia32': 0.33.5 + '@img/sharp-win32-x64': 0.33.5 + optional: true + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -9851,9 +10521,9 @@ snapshots: side-channel@1.0.6: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 es-errors: 1.3.0 - get-intrinsic: 1.2.4 + get-intrinsic: 1.3.0 object-inspect: 1.13.3 side-channel@1.1.0: @@ -9868,7 +10538,12 @@ snapshots: signal-exit@4.1.0: {} - sirv@2.0.4: + simple-swizzle@0.2.2: + dependencies: + is-arrayish: 0.3.2 + optional: true + + sirv@3.0.1: dependencies: '@polka/url': 1.0.0-next.28 mrmime: 2.0.1 @@ -9897,18 +10572,34 @@ snapshots: sort-object-keys: 1.1.3 tinyglobby: 0.2.10 + source-map-js@1.2.1: {} + source-map-support@0.5.21: dependencies: buffer-from: 1.1.2 source-map: 0.6.1 - source-map@0.5.6: {} - source-map@0.6.1: {} + source-map@0.7.4: {} + + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.21 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.21 + + spdx-license-ids@3.0.21: {} + spdy-transport@3.0.0: dependencies: - debug: 4.3.7 + debug: 4.4.0 detect-node: 2.1.0 hpack.js: 2.1.6 obuf: 1.1.2 @@ -9919,7 +10610,7 @@ snapshots: spdy@4.0.2: dependencies: - debug: 4.3.7 + debug: 4.4.0 handle-thing: 2.0.1 http-deceiver: 1.2.7 select-hose: 2.0.0 @@ -9929,26 +10620,20 @@ snapshots: split2@4.2.0: {} - stack-generator@2.0.10: + stacktracey@2.1.8: dependencies: - stackframe: 1.3.4 + as-table: 1.0.55 + get-source: 2.0.12 - stackframe@1.3.4: {} + statuses@1.5.0: {} - stacktrace-gps@3.1.2: - dependencies: - source-map: 0.5.6 - stackframe: 1.3.4 + statuses@2.0.1: {} - stacktrace-js@2.0.2: - dependencies: - error-stack-parser: 2.1.4 - stack-generator: 2.0.10 - stacktrace-gps: 3.1.2 + stoppable@1.1.0: {} - statuses@1.5.0: {} + stream-slice@0.1.2: {} - statuses@2.0.1: {} + streamsearch@1.1.0: {} string-width@4.2.3: dependencies: @@ -9993,12 +10678,6 @@ snapshots: es-object-atoms: 1.1.1 has-property-descriptors: 1.0.2 - string.prototype.trimend@1.0.8: - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-object-atoms: 1.0.0 - string.prototype.trimend@1.0.9: dependencies: call-bind: 1.0.8 @@ -10032,8 +10711,6 @@ snapshots: strip-json-comments@3.1.1: {} - stylis@4.3.6: {} - supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -10086,8 +10763,6 @@ snapshots: dependencies: real-require: 0.2.0 - throttle-debounce@3.0.1: {} - thunky@1.1.0: {} tiny-invariant@1.3.3: {} @@ -10099,14 +10774,17 @@ snapshots: fdir: 6.4.2(picomatch@4.0.2) picomatch: 4.0.2 + tinyglobby@0.2.12: + dependencies: + fdir: 6.4.3(picomatch@4.0.2) + picomatch: 4.0.2 + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 toad-cache@3.7.0: {} - toggle-selection@1.0.6: {} - toidentifier@1.0.1: {} totalist@3.0.1: {} @@ -10121,7 +10799,9 @@ snapshots: dependencies: typescript: 5.7.2 - ts-easing@0.2.0: {} + tsconfck@3.1.5(typescript@5.7.2): + optionalDependencies: + typescript: 5.7.2 tsconfig-paths@3.15.0: dependencies: @@ -10185,12 +10865,12 @@ snapshots: possible-typed-array-names: 1.0.0 reflect.getprototypeof: 1.0.10 - typescript-eslint@8.16.0(eslint@9.15.0)(typescript@5.7.2): + typescript-eslint@8.16.0(eslint@9.15.0(jiti@2.4.2))(typescript@5.7.2): dependencies: - '@typescript-eslint/eslint-plugin': 8.16.0(@typescript-eslint/parser@8.16.0(eslint@9.15.0)(typescript@5.7.2))(eslint@9.15.0)(typescript@5.7.2) - '@typescript-eslint/parser': 8.16.0(eslint@9.15.0)(typescript@5.7.2) - '@typescript-eslint/utils': 8.16.0(eslint@9.15.0)(typescript@5.7.2) - eslint: 9.15.0 + '@typescript-eslint/eslint-plugin': 8.16.0(@typescript-eslint/parser@8.16.0(eslint@9.15.0(jiti@2.4.2))(typescript@5.7.2))(eslint@9.15.0(jiti@2.4.2))(typescript@5.7.2) + '@typescript-eslint/parser': 8.16.0(eslint@9.15.0(jiti@2.4.2))(typescript@5.7.2) + '@typescript-eslint/utils': 8.16.0(eslint@9.15.0(jiti@2.4.2))(typescript@5.7.2) + eslint: 9.15.0(jiti@2.4.2) optionalDependencies: typescript: 5.7.2 transitivePeerDependencies: @@ -10207,21 +10887,65 @@ snapshots: has-symbols: 1.1.0 which-boxed-primitive: 1.1.1 - undici-types@6.20.0: {} + unconfig@7.3.1: + dependencies: + '@quansync/fs': 0.1.1 + defu: 6.1.4 + jiti: 2.4.2 + quansync: 0.2.8 - unicode-canonical-property-names-ecmascript@2.0.1: {} + undici-types@6.20.0: {} - unicode-match-property-ecmascript@2.0.0: + undici@5.29.0: dependencies: - unicode-canonical-property-names-ecmascript: 2.0.1 - unicode-property-aliases-ecmascript: 2.1.0 + '@fastify/busboy': 2.1.1 + + undici@6.21.2: {} - unicode-match-property-value-ecmascript@2.2.0: {} + unenv@2.0.0-rc.15: + dependencies: + defu: 6.1.4 + exsolve: 1.0.4 + ohash: 2.0.11 + pathe: 2.0.3 + ufo: 1.5.4 - unicode-property-aliases-ecmascript@2.1.0: {} + universalify@2.0.1: {} + + unocss@66.1.0-beta.6(vite@6.2.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1)): + dependencies: + '@unocss/astro': 66.1.0-beta.6(vite@6.2.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1)) + '@unocss/cli': 66.1.0-beta.6 + '@unocss/core': 66.1.0-beta.6 + '@unocss/postcss': 66.1.0-beta.6 + '@unocss/preset-attributify': 66.1.0-beta.6 + '@unocss/preset-icons': 66.1.0-beta.6 + '@unocss/preset-mini': 66.1.0-beta.6 + '@unocss/preset-tagify': 66.1.0-beta.6 + '@unocss/preset-typography': 66.1.0-beta.6 + '@unocss/preset-uno': 66.1.0-beta.6 + '@unocss/preset-web-fonts': 66.1.0-beta.6 + '@unocss/preset-wind': 66.1.0-beta.6 + '@unocss/preset-wind3': 66.1.0-beta.6 + '@unocss/preset-wind4': 66.1.0-beta.6 + '@unocss/transformer-attributify-jsx': 66.1.0-beta.6 + '@unocss/transformer-compile-class': 66.1.0-beta.6 + '@unocss/transformer-directives': 66.1.0-beta.6 + '@unocss/transformer-variant-group': 66.1.0-beta.6 + '@unocss/vite': 66.1.0-beta.6(vite@6.2.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1)) + optionalDependencies: + vite: 6.2.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1) + transitivePeerDependencies: + - supports-color + - vue unpipe@1.0.0: {} + unplugin-utils@0.2.4: + dependencies: + pathe: 2.0.3 + picomatch: 4.0.2 + update-browserslist-db@1.1.1(browserslist@4.24.2): dependencies: browserslist: 4.24.2 @@ -10232,6 +10956,8 @@ snapshots: dependencies: punycode: 2.3.1 + urlpattern-polyfill@10.0.0: {} + use-callback-ref@1.3.3(@types/react@19.0.1)(react@19.0.0): dependencies: react: 19.0.0 @@ -10249,39 +10975,65 @@ snapshots: uuid@8.3.2: {} - valibot@1.0.0-rc.3(typescript@5.7.2): + valibot@0.41.0(typescript@5.7.2): optionalDependencies: typescript: 5.7.2 + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + + validate-npm-package-name@5.0.1: {} + vary@1.1.2: {} - video.js@8.21.0: + vite-node@3.0.0-beta.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1): dependencies: - '@babel/runtime': 7.26.10 - '@videojs/http-streaming': 3.16.2(video.js@8.21.0) - '@videojs/vhs-utils': 4.1.1 - '@videojs/xhr': 2.7.0 - aes-decrypter: 4.0.2 - global: 4.4.0 - m3u8-parser: 7.2.0 - mpd-parser: 1.3.1 - mux.js: 7.1.0 - videojs-contrib-quality-levels: 4.1.0(video.js@8.21.0) - videojs-font: 4.2.0 - videojs-vtt.js: 0.15.5 + cac: 6.7.14 + debug: 4.4.0 + es-module-lexer: 1.5.4 + pathe: 1.1.2 + vite: 6.2.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1) + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml - videojs-contrib-quality-levels@4.1.0(video.js@8.21.0): + vite-tsconfig-paths@5.1.4(typescript@5.7.2)(vite@6.2.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1)): dependencies: - global: 4.4.0 - video.js: 8.21.0 - - videojs-font@4.2.0: {} + debug: 4.4.0 + globrex: 0.1.2 + tsconfck: 3.1.5(typescript@5.7.2) + optionalDependencies: + vite: 6.2.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1) + transitivePeerDependencies: + - supports-color + - typescript - videojs-vtt.js@0.15.5: + vite@6.2.2(@types/node@22.10.0)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1): dependencies: - global: 4.4.0 + esbuild: 0.25.1 + postcss: 8.5.3 + rollup: 4.36.0 + optionalDependencies: + '@types/node': 22.10.0 + fsevents: 2.3.3 + jiti: 2.4.2 + terser: 5.36.0 + tsx: 4.19.2 + yaml: 2.6.1 - view-transitions-polyfill@1.0.3: {} + vue-flow-layout@0.1.1: {} watchpack@2.4.2: dependencies: @@ -10296,25 +11048,7 @@ snapshots: webidl-conversions@3.0.1: {} - webpack-bundle-analyzer@4.10.2: - dependencies: - '@discoveryjs/json-ext': 0.5.7 - acorn: 8.14.0 - acorn-walk: 8.3.4 - commander: 7.2.0 - debounce: 1.2.1 - escape-string-regexp: 4.0.0 - gzip-size: 6.0.0 - html-escaper: 2.0.2 - opener: 1.5.2 - picocolors: 1.1.1 - sirv: 2.0.4 - ws: 7.5.10 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - - webpack-cli@5.1.4(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.1.0)(webpack@5.96.1): + webpack-cli@5.1.4(webpack-dev-server@5.1.0)(webpack@5.96.1): dependencies: '@discoveryjs/json-ext': 0.5.7 '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4)(webpack@5.96.1) @@ -10331,7 +11065,6 @@ snapshots: webpack: 5.96.1(webpack-cli@5.1.4) webpack-merge: 5.10.0 optionalDependencies: - webpack-bundle-analyzer: 4.10.2 webpack-dev-server: 5.1.0(webpack-cli@5.1.4)(webpack@5.96.1) webpack-dev-middleware@7.4.2(webpack@5.96.1): @@ -10377,7 +11110,7 @@ snapshots: ws: 8.18.0 optionalDependencies: webpack: 5.96.1(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.1.0)(webpack@5.96.1) + webpack-cli: 5.1.4(webpack-dev-server@5.1.0)(webpack@5.96.1) transitivePeerDependencies: - bufferutil - debug @@ -10418,7 +11151,7 @@ snapshots: watchpack: 2.4.2 webpack-sources: 3.2.3 optionalDependencies: - webpack-cli: 5.1.4(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.1.0)(webpack@5.96.1) + webpack-cli: 5.1.4(webpack-dev-server@5.1.0)(webpack@5.96.1) transitivePeerDependencies: - '@swc/core' - esbuild @@ -10482,6 +11215,10 @@ snapshots: dependencies: isexe: 2.0.0 + which@3.0.1: + dependencies: + isexe: 2.0.0 + wide-align@1.1.5: dependencies: string-width: 4.2.3 @@ -10498,6 +11235,32 @@ snapshots: word-wrap@1.2.5: {} + workerd@1.20250320.0: + optionalDependencies: + '@cloudflare/workerd-darwin-64': 1.20250320.0 + '@cloudflare/workerd-darwin-arm64': 1.20250320.0 + '@cloudflare/workerd-linux-64': 1.20250320.0 + '@cloudflare/workerd-linux-arm64': 1.20250320.0 + '@cloudflare/workerd-windows-64': 1.20250320.0 + + wrangler@4.4.0(@cloudflare/workers-types@4.20250321.0): + dependencies: + '@cloudflare/kv-asset-handler': 0.4.0 + '@cloudflare/unenv-preset': 2.3.0(unenv@2.0.0-rc.15)(workerd@1.20250320.0) + blake3-wasm: 2.1.5 + esbuild: 0.24.2 + miniflare: 4.20250320.0 + path-to-regexp: 6.3.0 + unenv: 2.0.0-rc.15 + workerd: 1.20250320.0 + optionalDependencies: + '@cloudflare/workers-types': 4.20250321.0 + fsevents: 2.3.3 + sharp: 0.33.5 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -10512,36 +11275,48 @@ snapshots: wrappy@1.0.2: {} - ws@7.5.10: {} - ws@8.18.0: {} + y18n@5.0.8: {} + yallist@3.1.1: {} yallist@4.0.0: {} yaml@2.6.1: {} + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + yocto-queue@0.1.0: {} yocto-queue@1.1.1: {} - yoctodelay@1.2.0: {} + youch@3.2.3: + dependencies: + cookie: 0.5.0 + mustache: 4.2.0 + stacktracey: 2.1.8 zod-openapi@4.2.0(zod@3.24.1): dependencies: zod: 3.24.1 - zod@3.24.1: {} + zod@3.22.3: {} - zustand-di@0.0.16(react@19.0.0)(zustand@5.0.3(@types/react@19.0.1)(immer@10.1.1)(react@19.0.0)(use-sync-external-store@1.4.0(react@19.0.0))): - dependencies: - react: 19.0.0 - zustand: 5.0.3(@types/react@19.0.1)(immer@10.1.1)(react@19.0.0)(use-sync-external-store@1.4.0(react@19.0.0)) + zod@3.24.1: {} - zustand@5.0.3(@types/react@19.0.1)(immer@10.1.1)(react@19.0.0)(use-sync-external-store@1.4.0(react@19.0.0)): + zustand@5.0.3(@types/react@19.0.1)(react@19.0.0)(use-sync-external-store@1.4.0(react@19.0.0)): optionalDependencies: '@types/react': 19.0.1 - immer: 10.1.1 react: 19.0.0 use-sync-external-store: 1.4.0(react@19.0.0) diff --git a/public/animations/001.gif b/public/animations/001.gif index a047ac0a9..9dbbdfc08 100644 Binary files a/public/animations/001.gif and b/public/animations/001.gif differ diff --git a/public/arema.svg b/public/arema.svg index 3d9edda56..4b235cb5e 100644 --- a/public/arema.svg +++ b/public/arema.svg @@ -1,3 +1 @@ - - - + \ No newline at end of file diff --git a/public/feature-explain.avif b/public/feature-explain.avif new file mode 100644 index 000000000..d550637d7 Binary files /dev/null and b/public/feature-explain.avif differ diff --git a/public/images-compress/001.avif b/public/images-compress/001.avif new file mode 100644 index 000000000..41fca3b4d Binary files /dev/null and b/public/images-compress/001.avif differ diff --git a/public/images-compress/002.avif b/public/images-compress/002.avif new file mode 100644 index 000000000..9f7da5a9e Binary files /dev/null and b/public/images-compress/002.avif differ diff --git a/public/images-compress/003.avif b/public/images-compress/003.avif new file mode 100644 index 000000000..26ca2a117 Binary files /dev/null and b/public/images-compress/003.avif differ diff --git a/public/images-compress/004.avif b/public/images-compress/004.avif new file mode 100644 index 000000000..f7aa94d0f Binary files /dev/null and b/public/images-compress/004.avif differ diff --git a/public/images-compress/005.avif b/public/images-compress/005.avif new file mode 100644 index 000000000..6bcbfc3a9 Binary files /dev/null and b/public/images-compress/005.avif differ diff --git a/public/images-compress/006.avif b/public/images-compress/006.avif new file mode 100644 index 000000000..941702b4b Binary files /dev/null and b/public/images-compress/006.avif differ diff --git a/public/images-compress/007.avif b/public/images-compress/007.avif new file mode 100644 index 000000000..997e92852 Binary files /dev/null and b/public/images-compress/007.avif differ diff --git a/public/images-compress/008.avif b/public/images-compress/008.avif new file mode 100644 index 000000000..4b93b9945 Binary files /dev/null and b/public/images-compress/008.avif differ diff --git a/public/images-compress/009.avif b/public/images-compress/009.avif new file mode 100644 index 000000000..1aeead249 Binary files /dev/null and b/public/images-compress/009.avif differ diff --git a/public/images-compress/010.avif b/public/images-compress/010.avif new file mode 100644 index 000000000..c6aabb5c2 Binary files /dev/null and b/public/images-compress/010.avif differ diff --git a/public/images-compress/011.avif b/public/images-compress/011.avif new file mode 100644 index 000000000..57c42e8bb Binary files /dev/null and b/public/images-compress/011.avif differ diff --git a/public/images-compress/012.avif b/public/images-compress/012.avif new file mode 100644 index 000000000..405e36642 Binary files /dev/null and b/public/images-compress/012.avif differ diff --git a/public/images-compress/013.avif b/public/images-compress/013.avif new file mode 100644 index 000000000..57d760bd3 Binary files /dev/null and b/public/images-compress/013.avif differ diff --git a/public/images-compress/014.avif b/public/images-compress/014.avif new file mode 100644 index 000000000..abed8829b Binary files /dev/null and b/public/images-compress/014.avif differ diff --git a/public/images-compress/015.avif b/public/images-compress/015.avif new file mode 100644 index 000000000..4aaabfa3e Binary files /dev/null and b/public/images-compress/015.avif differ diff --git a/public/images-compress/016.avif b/public/images-compress/016.avif new file mode 100644 index 000000000..f11069ede Binary files /dev/null and b/public/images-compress/016.avif differ diff --git a/public/images-compress/017.avif b/public/images-compress/017.avif new file mode 100644 index 000000000..38f209135 Binary files /dev/null and b/public/images-compress/017.avif differ diff --git a/public/images-compress/018.avif b/public/images-compress/018.avif new file mode 100644 index 000000000..cdf7baf9b Binary files /dev/null and b/public/images-compress/018.avif differ diff --git a/public/images-compress/019.avif b/public/images-compress/019.avif new file mode 100644 index 000000000..510fdff0f Binary files /dev/null and b/public/images-compress/019.avif differ diff --git a/public/images-compress/020.avif b/public/images-compress/020.avif new file mode 100644 index 000000000..71b43bf49 Binary files /dev/null and b/public/images-compress/020.avif differ diff --git a/public/images-compress/021.avif b/public/images-compress/021.avif new file mode 100644 index 000000000..e47d96ce9 Binary files /dev/null and b/public/images-compress/021.avif differ diff --git a/public/images-compress/022.avif b/public/images-compress/022.avif new file mode 100644 index 000000000..e4e5bd886 Binary files /dev/null and b/public/images-compress/022.avif differ diff --git a/public/images-compress/023.avif b/public/images-compress/023.avif new file mode 100644 index 000000000..12e4fc6ca Binary files /dev/null and b/public/images-compress/023.avif differ diff --git a/public/images-compress/024.avif b/public/images-compress/024.avif new file mode 100644 index 000000000..e42003519 Binary files /dev/null and b/public/images-compress/024.avif differ diff --git a/public/images-compress/025.avif b/public/images-compress/025.avif new file mode 100644 index 000000000..e29b1652a Binary files /dev/null and b/public/images-compress/025.avif differ diff --git a/public/images-compress/026.avif b/public/images-compress/026.avif new file mode 100644 index 000000000..d8b1bd15d Binary files /dev/null and b/public/images-compress/026.avif differ diff --git a/public/images-compress/027.avif b/public/images-compress/027.avif new file mode 100644 index 000000000..c10cc505a Binary files /dev/null and b/public/images-compress/027.avif differ diff --git a/public/images-compress/028.avif b/public/images-compress/028.avif new file mode 100644 index 000000000..d65fb1aa7 Binary files /dev/null and b/public/images-compress/028.avif differ diff --git a/public/images-compress/029.avif b/public/images-compress/029.avif new file mode 100644 index 000000000..32d6adf35 Binary files /dev/null and b/public/images-compress/029.avif differ diff --git a/public/images-compress/030.avif b/public/images-compress/030.avif new file mode 100644 index 000000000..914bb0060 Binary files /dev/null and b/public/images-compress/030.avif differ diff --git a/public/images-compress/031.avif b/public/images-compress/031.avif new file mode 100644 index 000000000..c90aa4266 Binary files /dev/null and b/public/images-compress/031.avif differ diff --git a/public/images-compress/032.avif b/public/images-compress/032.avif new file mode 100644 index 000000000..a2d8816ac Binary files /dev/null and b/public/images-compress/032.avif differ diff --git a/public/images-compress/033.avif b/public/images-compress/033.avif new file mode 100644 index 000000000..b89eefe9a Binary files /dev/null and b/public/images-compress/033.avif differ diff --git a/public/images-compress/034.avif b/public/images-compress/034.avif new file mode 100644 index 000000000..55f1ca22d Binary files /dev/null and b/public/images-compress/034.avif differ diff --git a/public/images-compress/035.avif b/public/images-compress/035.avif new file mode 100644 index 000000000..2f8f4bbfd Binary files /dev/null and b/public/images-compress/035.avif differ diff --git a/public/images-compress/036.avif b/public/images-compress/036.avif new file mode 100644 index 000000000..ed49a3f60 Binary files /dev/null and b/public/images-compress/036.avif differ diff --git a/public/images-compress/037.avif b/public/images-compress/037.avif new file mode 100644 index 000000000..71382d378 Binary files /dev/null and b/public/images-compress/037.avif differ diff --git a/public/logos/anime.avif b/public/logos/anime.avif new file mode 100644 index 000000000..0c7bc229e Binary files /dev/null and b/public/logos/anime.avif differ diff --git a/public/logos/anime.png b/public/logos/anime.png new file mode 100644 index 000000000..edb708748 Binary files /dev/null and b/public/logos/anime.png differ diff --git a/public/logos/documentary.avif b/public/logos/documentary.avif new file mode 100644 index 000000000..3abf78e11 Binary files /dev/null and b/public/logos/documentary.avif differ diff --git a/public/logos/documentary.png b/public/logos/documentary.png new file mode 100644 index 000000000..7e96696e1 Binary files /dev/null and b/public/logos/documentary.png differ diff --git a/public/logos/drama.avif b/public/logos/drama.avif new file mode 100644 index 000000000..83128e9c8 Binary files /dev/null and b/public/logos/drama.avif differ diff --git a/public/logos/drama.png b/public/logos/drama.png new file mode 100644 index 000000000..9d6f601d9 Binary files /dev/null and b/public/logos/drama.png differ diff --git a/public/logos/fightingsports.avif b/public/logos/fightingsports.avif new file mode 100644 index 000000000..c71b244cc Binary files /dev/null and b/public/logos/fightingsports.avif differ diff --git a/public/logos/fightingsports.png b/public/logos/fightingsports.png new file mode 100644 index 000000000..28ee11824 Binary files /dev/null and b/public/logos/fightingsports.png differ diff --git a/public/logos/mahjong.avif b/public/logos/mahjong.avif new file mode 100644 index 000000000..83c5379a2 Binary files /dev/null and b/public/logos/mahjong.avif differ diff --git a/public/logos/mahjong.png b/public/logos/mahjong.png new file mode 100644 index 000000000..2345a1cff Binary files /dev/null and b/public/logos/mahjong.png differ diff --git a/public/logos/music.avif b/public/logos/music.avif new file mode 100644 index 000000000..b5ea098ac Binary files /dev/null and b/public/logos/music.avif differ diff --git a/public/logos/music.png b/public/logos/music.png new file mode 100644 index 000000000..a1fe0214a Binary files /dev/null and b/public/logos/music.png differ diff --git a/public/logos/news.avif b/public/logos/news.avif new file mode 100644 index 000000000..37d03c001 Binary files /dev/null and b/public/logos/news.avif differ diff --git a/public/logos/news.png b/public/logos/news.png new file mode 100644 index 000000000..f184f924e Binary files /dev/null and b/public/logos/news.png differ diff --git a/public/logos/reality.avif b/public/logos/reality.avif new file mode 100644 index 000000000..c8935caa4 Binary files /dev/null and b/public/logos/reality.avif differ diff --git a/public/logos/reality.png b/public/logos/reality.png new file mode 100644 index 000000000..a87797234 Binary files /dev/null and b/public/logos/reality.png differ diff --git a/public/logos/shogi.avif b/public/logos/shogi.avif new file mode 100644 index 000000000..afc17e8d3 Binary files /dev/null and b/public/logos/shogi.avif differ diff --git a/public/logos/shogi.png b/public/logos/shogi.png new file mode 100644 index 000000000..3ba499cda Binary files /dev/null and b/public/logos/shogi.png differ diff --git a/public/logos/soccer.avif b/public/logos/soccer.avif new file mode 100644 index 000000000..bb8a9660b Binary files /dev/null and b/public/logos/soccer.avif differ diff --git a/public/logos/soccer.png b/public/logos/soccer.png new file mode 100644 index 000000000..43032525b Binary files /dev/null and b/public/logos/soccer.png differ diff --git a/public/logos/sumo.avif b/public/logos/sumo.avif new file mode 100644 index 000000000..8b8634ce3 Binary files /dev/null and b/public/logos/sumo.avif differ diff --git a/public/logos/sumo.png b/public/logos/sumo.png new file mode 100644 index 000000000..d88b80f1e Binary files /dev/null and b/public/logos/sumo.png differ diff --git a/public/logos/variety.avif b/public/logos/variety.avif new file mode 100644 index 000000000..6a645573d Binary files /dev/null and b/public/logos/variety.avif differ diff --git a/public/logos/variety.png b/public/logos/variety.png new file mode 100644 index 000000000..a9c178003 Binary files /dev/null and b/public/logos/variety.png differ diff --git a/render.yaml b/render.yaml new file mode 100644 index 000000000..a77bb9a8e --- /dev/null +++ b/render.yaml @@ -0,0 +1,11 @@ +services: + - type: web + runtime: node + name: wsh-2025-server + plan: free + buildCommand: pnpm install + startCommand: pnpm start + rootDir: workspaces/server + envVars: + - key: NODE_ENV + value: production \ No newline at end of file diff --git a/scripts/compress.ts b/scripts/compress.ts new file mode 100644 index 000000000..13742f040 --- /dev/null +++ b/scripts/compress.ts @@ -0,0 +1,107 @@ +import { join, dirname, basename, extname, resolve } from 'path'; +import { readdir, mkdir } from 'fs/promises'; +import { existsSync } from 'fs'; +import { fileURLToPath } from 'url'; +import sharp from 'sharp'; + +// Get current file directory (ESM equivalent of __dirname) +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +async function compressImageToAvif(sourcePath: string, outputPath: string): Promise { + try { + // Use sharp for image processing with higher compression + await sharp(sourcePath) + // Resize to reduce dimensions if needed + .resize({ + width: 1280, // Max width + height: 720, // Max height + fit: 'inside', // Keep aspect ratio + withoutEnlargement: true, // Don't enlarge small images + }) + .avif({ + quality: 90, // Much lower quality for higher compression (0-100) + effort: 5, // Maximum compression effort (0-9) + }) + .toFile(outputPath); + console.log(`✅ Converted: ${sourcePath} -> ${outputPath}`); + } catch (error) { + console.error(`❌ Error converting ${sourcePath}:`, error); + } +} + +async function processDirectory(dirPath: string): Promise { + try { + // Get all files in the directory + const files = await readdir(dirPath, { withFileTypes: true }); + const tasks: Promise[] = []; + + // Process subdirectories first (still sequential for subdirectories) + for (const file of files) { + if (file.isDirectory()) { + const filePath = join(dirPath, file.name); + // Recursively process subdirectories + await processDirectory(filePath); + } + } + + // Then process all image files in parallel + for (const file of files) { + const filePath = join(dirPath, file.name); + + if ( + !file.isDirectory() && + file.isFile() && + ['.jpg', '.jpeg', '.png'].includes(extname(file.name).toLowerCase()) + ) { + // Process image files + const ext = extname(file.name).toLowerCase(); + const outputPath = join(dirname(filePath), `${basename(filePath, ext)}.avif`); + + // Create output directory if it doesn't exist + const outputDir = dirname(outputPath); + if (!existsSync(outputDir)) { + await mkdir(outputDir, { recursive: true }); + } + + // Add to parallel tasks instead of awaiting immediately + tasks.push(compressImageToAvif(filePath, outputPath)); + } + } + + // Wait for all image processing tasks to complete + if (tasks.length > 0) { + console.log(`Processing ${tasks.length} images in parallel...`); + await Promise.all(tasks); + } + } catch (error) { + console.error(`Error processing directory ${dirPath}:`, error); + } +} + +async function main() { + const startTime = performance.now(); + console.log('Starting image to AVIF compression with parallel processing...'); + + // Process images and logos directories + const rootDir = resolve(__dirname, '..'); + const directories = [join(rootDir, 'public/images'), join(rootDir, 'public/logos')]; + + // Process all directories in parallel + const dirTasks = directories.map(async (dir) => { + console.log(`Processing directory: ${dir}`); + await processDirectory(dir); + }); + + // Wait for all directory processing to complete + await Promise.all(dirTasks); + + const endTime = performance.now(); + console.log(`Compression completed in ${((endTime - startTime) / 1000).toFixed(2)}s`); +} + +// Run the main function +main().catch((error) => { + console.error('An error occurred:', error); + process.exit(1); +}); diff --git a/scripts/package.json b/scripts/package.json new file mode 100644 index 000000000..c5f786b34 --- /dev/null +++ b/scripts/package.json @@ -0,0 +1,16 @@ +{ + "name": "scripts", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@types/sharp": "0.32.0", + "sharp": "0.33.5" + } +} diff --git a/scripts/ping.ts b/scripts/ping.ts new file mode 100644 index 000000000..9c6549d48 --- /dev/null +++ b/scripts/ping.ts @@ -0,0 +1,16 @@ +const PING_URL = 'https://wsh-2025-server.onrender.com'; + +async function pingServer() { + try { + const response = await fetch(PING_URL); + console.log(`Ping response: ${response.status}`); + } catch (error) { + console.error('Ping failed:', error); + } +} + +// 初回実行 +pingServer(); + +// 1分ごとに実行 +setInterval(pingServer, 60000); diff --git a/todo.md b/todo.md new file mode 100644 index 000000000..c0c34c848 --- /dev/null +++ b/todo.md @@ -0,0 +1,61 @@ +# Web Speed Hackathon 2025 最適化TODO + +## 1. アイコン最適化 (予想効果: 200-300KB削減) + +- [ ] 使用中のアイコンセットを特定 + - [ ] `bi` + - [ ] `bx` + - [ ] `fa-regular` + - [ ] `fa-solid` + - [ ] `fluent` + - [ ] `line-md` + - [ ] `material-symbols` +- [ ] 未使用のアイコンセットを削除 +- [ ] 使用するアイコンのみをサブセット化 + +## 2. UnoCSS最適化 (予想効果: 50-100KB削減) + +- [ ] `presetWind3`の設定見直し + - [ ] 使用する機能のみを有効化 + - [ ] 不要なvariantsを無効化 + - [ ] preflightの重複を解消 + +## 3. フォント最適化 + +- [ ] Noto Sans JPのサブセット化 +- [ ] `font-display: swap`の追加 +- [ ] プリロードの実装 +- [ ] 必要なウェイトのみを読み込む + +## 4. CSS最適化 (予想効果: 5-10KB削減) + +- [ ] リセットCSSの最適化 + - [ ] 必要最小限のリセットに変更 + - [ ] または`normalize.css`への切り替え +- [ ] アニメーションをコンポーネントスコープに移動 + +## 5. その他の最適化 + +- [ ] ポリフィルの最適化 + - [ ] 不要なポリフィルの削除 + - [ ] 条件付きロードの実装 +- [ ] バンドルの分割 + - [ ] ルートベースの分割 + - [ ] 動的インポートの導入 + +## 進捗管理 + +- 現在のバンドルサイズ: TBD +- 目標削減サイズ: 255-410KB以上 +- 優先順位: + 1. アイコン最適化(効果大・実装容易) + 2. UnoCSS最適化(効果中・実装容易) + 3. フォント最適化(効果大・実装やや複雑) + 4. CSS最適化(効果小・実装容易) + 5. その他の最適化(効果中・実装中) + +## メモ + +- 各最適化後にパフォーマンス計測を実施 +- E2EテストとVRTが通過することを確認 +- バンドルアナライザーで効果を確認 diff --git a/workspaces/client/assets/timetable/feature-explain.png b/workspaces/client/assets/timetable/feature-explain.png deleted file mode 100644 index 22327e7a1..000000000 Binary files a/workspaces/client/assets/timetable/feature-explain.png and /dev/null differ diff --git a/workspaces/client/package.json b/workspaces/client/package.json index f6c261693..44372b8c6 100644 --- a/workspaces/client/package.json +++ b/workspaces/client/package.json @@ -1,95 +1,85 @@ { "name": "@wsh-2025/client", "private": true, + "type": "module", "scripts": { + "analyze": "vite build --mode analyze", "build": "wireit", + "css": "unocss 'src/**/*.tsx' --out-file=src/uno.css", + "dep": "pnpm build && wrangler deploy", + "dev": "pnpm css && lsof -i :3000 -t | xargs -r kill -9 && react-router dev", "format": "wireit", "format:eslint": "wireit", - "format:prettier": "wireit" + "format:prettier": "wireit", + "preview": "vite preview", + "start": "wrangler dev" }, "dependencies": { - "@babel/runtime": "7.26.10", "@better-fetch/fetch": "1.1.15", "@dhmk/zustand-lens": "5.0.0", "@epic-web/restore-scroll": "1.1.1", "@ffmpeg/ffmpeg": "0.12.15", "@headlessui/react": "2.2.0", "@radix-ui/react-slider": "1.2.3", + "@react-router/node": "7.4.0", "@standard-schema/spec": "1.0.0", - "@wsh-2025/client": "workspace:*", + "@unocss/reset": "66.1.0-beta.6", "@wsh-2025/schema": "workspace:*", "@yornaath/batshit": "0.10.1", "classnames": "2.5.1", + "deepmerge": "4.3.1", "final-form": "4.20.10", - "immer": "10.1.1", - "lodash": "4.17.21", - "luxon": "3.5.0", + "isbot": "^5", "m3u8-parser": "7.2.0", - "p-min-delay": "4.0.2", "react": "19.0.0", "react-dom": "19.0.0", "react-ellipsis-component": "1.1.11", "react-final-form": "6.5.9", "react-flip-toolkit": "7.2.4", - "react-router": "7.0.2", - "react-router-dom": "7.0.2", - "react-use": "17.6.0", - "setimmediate": "1.0.5", + "react-router": "7.4.0", + "react-router-dom": "7.4.0", "tiny-invariant": "1.3.3", "type-fest": "4.29.1", "use-callback-ref": "1.3.3", "use-sync-external-store": "1.4.0", - "valibot": "1.0.0-rc.3", - "view-transitions-polyfill": "1.0.3", "zod": "3.24.1", - "zustand": "5.0.3", - "zustand-di": "0.0.16" + "zustand": "5.0.3" }, "devDependencies": { - "@babel/core": "7.26.0", - "@babel/preset-env": "7.26.0", - "@babel/preset-react": "7.25.9", - "@babel/preset-typescript": "7.26.0", + "@cloudflare/vite-plugin": "0.1.15", + "@cloudflare/workers-types": "4.20250321.0", "@ffmpeg/core": "0.12.10", "@ffmpeg/util": "0.12.2", "@iconify/json": "2.2.317", "@iconify/types": "2.0.0", - "@types/lodash": "4.17.16", - "@types/luxon": "3.4.2", + "@react-router/dev": "7.4.0", "@types/m3u8-parser": "7.2.0", "@types/react": "19.0.1", "@types/react-dom": "19.0.2", "@types/wicg-task-scheduling": "2024.1.0", - "@unocss/preset-icons": "66.1.0-beta.5", - "@unocss/preset-wind3": "66.1.0-beta.5", - "@unocss/reset": "66.1.0-beta.5", - "@unocss/runtime": "66.1.0-beta.5", + "@unocss/cli": "latest", + "@unocss/preset-wind3": "66.1.0-beta.6", + "@vitejs/plugin-react": "4.3.4", "@wsh-2025/configs": "workspace:*", "arraybuffer-loader": "1.0.8", "babel-loader": "9.2.1", - "core-js": "3.41.0", "hls.js": "1.5.17", - "shaka-player": "4.12.5", + "rollup-plugin-visualizer": "5.14.0", "typescript": "5.7.2", - "video.js": "8.21.0", + "unocss": "66.1.0-beta.6", + "vite": "6.2.2", + "vite-tsconfig-paths": "5.1.4", "webpack": "5.96.1", - "webpack-bundle-analyzer": "4.10.2", "webpack-cli": "5.1.4", "webpack-dev-server": "5.1.0", "wireit": "0.14.9" }, "wireit": { "build": { - "command": "webpack", - "files": [ - "../../pnpm-lock.yaml", - "../schema/src/**/*", - "./src/**/*", - "./webpack.config.mjs" + "dependencies": [ + "css" ], - "output": [ - "./dist/**/*" - ] + "command": "react-router build" }, "format": { "command": "pnpm run format:eslint && pnpm run format:prettier" diff --git a/workspaces/client/public/public/animations/001.gif b/workspaces/client/public/public/animations/001.gif new file mode 100644 index 000000000..9dbbdfc08 Binary files /dev/null and b/workspaces/client/public/public/animations/001.gif differ diff --git a/workspaces/client/public/public/arema.svg b/workspaces/client/public/public/arema.svg new file mode 100644 index 000000000..4b235cb5e --- /dev/null +++ b/workspaces/client/public/public/arema.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/workspaces/client/public/public/feature-explain.avif b/workspaces/client/public/public/feature-explain.avif new file mode 100644 index 000000000..d550637d7 Binary files /dev/null and b/workspaces/client/public/public/feature-explain.avif differ diff --git a/workspaces/client/public/public/images-compress/001.avif b/workspaces/client/public/public/images-compress/001.avif new file mode 100644 index 000000000..41fca3b4d Binary files /dev/null and b/workspaces/client/public/public/images-compress/001.avif differ diff --git a/workspaces/client/public/public/images-compress/002.avif b/workspaces/client/public/public/images-compress/002.avif new file mode 100644 index 000000000..9f7da5a9e Binary files /dev/null and b/workspaces/client/public/public/images-compress/002.avif differ diff --git a/workspaces/client/public/public/images-compress/003.avif b/workspaces/client/public/public/images-compress/003.avif new file mode 100644 index 000000000..26ca2a117 Binary files /dev/null and b/workspaces/client/public/public/images-compress/003.avif differ diff --git a/workspaces/client/public/public/images-compress/004.avif b/workspaces/client/public/public/images-compress/004.avif new file mode 100644 index 000000000..f7aa94d0f Binary files /dev/null and b/workspaces/client/public/public/images-compress/004.avif differ diff --git a/workspaces/client/public/public/images-compress/005.avif b/workspaces/client/public/public/images-compress/005.avif new file mode 100644 index 000000000..6bcbfc3a9 Binary files /dev/null and b/workspaces/client/public/public/images-compress/005.avif differ diff --git a/workspaces/client/public/public/images-compress/006.avif b/workspaces/client/public/public/images-compress/006.avif new file mode 100644 index 000000000..941702b4b Binary files /dev/null and b/workspaces/client/public/public/images-compress/006.avif differ diff --git a/workspaces/client/public/public/images-compress/007.avif b/workspaces/client/public/public/images-compress/007.avif new file mode 100644 index 000000000..997e92852 Binary files /dev/null and b/workspaces/client/public/public/images-compress/007.avif differ diff --git a/workspaces/client/public/public/images-compress/008.avif b/workspaces/client/public/public/images-compress/008.avif new file mode 100644 index 000000000..4b93b9945 Binary files /dev/null and b/workspaces/client/public/public/images-compress/008.avif differ diff --git a/workspaces/client/public/public/images-compress/009.avif b/workspaces/client/public/public/images-compress/009.avif new file mode 100644 index 000000000..1aeead249 Binary files /dev/null and b/workspaces/client/public/public/images-compress/009.avif differ diff --git a/workspaces/client/public/public/images-compress/010.avif b/workspaces/client/public/public/images-compress/010.avif new file mode 100644 index 000000000..c6aabb5c2 Binary files /dev/null and b/workspaces/client/public/public/images-compress/010.avif differ diff --git a/workspaces/client/public/public/images-compress/011.avif b/workspaces/client/public/public/images-compress/011.avif new file mode 100644 index 000000000..57c42e8bb Binary files /dev/null and b/workspaces/client/public/public/images-compress/011.avif differ diff --git a/workspaces/client/public/public/images-compress/012.avif b/workspaces/client/public/public/images-compress/012.avif new file mode 100644 index 000000000..405e36642 Binary files /dev/null and b/workspaces/client/public/public/images-compress/012.avif differ diff --git a/workspaces/client/public/public/images-compress/013.avif b/workspaces/client/public/public/images-compress/013.avif new file mode 100644 index 000000000..57d760bd3 Binary files /dev/null and b/workspaces/client/public/public/images-compress/013.avif differ diff --git a/workspaces/client/public/public/images-compress/014.avif b/workspaces/client/public/public/images-compress/014.avif new file mode 100644 index 000000000..abed8829b Binary files /dev/null and b/workspaces/client/public/public/images-compress/014.avif differ diff --git a/workspaces/client/public/public/images-compress/015.avif b/workspaces/client/public/public/images-compress/015.avif new file mode 100644 index 000000000..4aaabfa3e Binary files /dev/null and b/workspaces/client/public/public/images-compress/015.avif differ diff --git a/workspaces/client/public/public/images-compress/016.avif b/workspaces/client/public/public/images-compress/016.avif new file mode 100644 index 000000000..f11069ede Binary files /dev/null and b/workspaces/client/public/public/images-compress/016.avif differ diff --git a/workspaces/client/public/public/images-compress/017.avif b/workspaces/client/public/public/images-compress/017.avif new file mode 100644 index 000000000..38f209135 Binary files /dev/null and b/workspaces/client/public/public/images-compress/017.avif differ diff --git a/workspaces/client/public/public/images-compress/018.avif b/workspaces/client/public/public/images-compress/018.avif new file mode 100644 index 000000000..cdf7baf9b Binary files /dev/null and b/workspaces/client/public/public/images-compress/018.avif differ diff --git a/workspaces/client/public/public/images-compress/019.avif b/workspaces/client/public/public/images-compress/019.avif new file mode 100644 index 000000000..510fdff0f Binary files /dev/null and b/workspaces/client/public/public/images-compress/019.avif differ diff --git a/workspaces/client/public/public/images-compress/020.avif b/workspaces/client/public/public/images-compress/020.avif new file mode 100644 index 000000000..71b43bf49 Binary files /dev/null and b/workspaces/client/public/public/images-compress/020.avif differ diff --git a/workspaces/client/public/public/images-compress/021.avif b/workspaces/client/public/public/images-compress/021.avif new file mode 100644 index 000000000..e47d96ce9 Binary files /dev/null and b/workspaces/client/public/public/images-compress/021.avif differ diff --git a/workspaces/client/public/public/images-compress/022.avif b/workspaces/client/public/public/images-compress/022.avif new file mode 100644 index 000000000..e4e5bd886 Binary files /dev/null and b/workspaces/client/public/public/images-compress/022.avif differ diff --git a/workspaces/client/public/public/images-compress/023.avif b/workspaces/client/public/public/images-compress/023.avif new file mode 100644 index 000000000..12e4fc6ca Binary files /dev/null and b/workspaces/client/public/public/images-compress/023.avif differ diff --git a/workspaces/client/public/public/images-compress/024.avif b/workspaces/client/public/public/images-compress/024.avif new file mode 100644 index 000000000..e42003519 Binary files /dev/null and b/workspaces/client/public/public/images-compress/024.avif differ diff --git a/workspaces/client/public/public/images-compress/025.avif b/workspaces/client/public/public/images-compress/025.avif new file mode 100644 index 000000000..e29b1652a Binary files /dev/null and b/workspaces/client/public/public/images-compress/025.avif differ diff --git a/workspaces/client/public/public/images-compress/026.avif b/workspaces/client/public/public/images-compress/026.avif new file mode 100644 index 000000000..d8b1bd15d Binary files /dev/null and b/workspaces/client/public/public/images-compress/026.avif differ diff --git a/workspaces/client/public/public/images-compress/027.avif b/workspaces/client/public/public/images-compress/027.avif new file mode 100644 index 000000000..c10cc505a Binary files /dev/null and b/workspaces/client/public/public/images-compress/027.avif differ diff --git a/workspaces/client/public/public/images-compress/028.avif b/workspaces/client/public/public/images-compress/028.avif new file mode 100644 index 000000000..d65fb1aa7 Binary files /dev/null and b/workspaces/client/public/public/images-compress/028.avif differ diff --git a/workspaces/client/public/public/images-compress/029.avif b/workspaces/client/public/public/images-compress/029.avif new file mode 100644 index 000000000..32d6adf35 Binary files /dev/null and b/workspaces/client/public/public/images-compress/029.avif differ diff --git a/workspaces/client/public/public/images-compress/030.avif b/workspaces/client/public/public/images-compress/030.avif new file mode 100644 index 000000000..914bb0060 Binary files /dev/null and b/workspaces/client/public/public/images-compress/030.avif differ diff --git a/workspaces/client/public/public/images-compress/031.avif b/workspaces/client/public/public/images-compress/031.avif new file mode 100644 index 000000000..c90aa4266 Binary files /dev/null and b/workspaces/client/public/public/images-compress/031.avif differ diff --git a/workspaces/client/public/public/images-compress/032.avif b/workspaces/client/public/public/images-compress/032.avif new file mode 100644 index 000000000..a2d8816ac Binary files /dev/null and b/workspaces/client/public/public/images-compress/032.avif differ diff --git a/workspaces/client/public/public/images-compress/033.avif b/workspaces/client/public/public/images-compress/033.avif new file mode 100644 index 000000000..b89eefe9a Binary files /dev/null and b/workspaces/client/public/public/images-compress/033.avif differ diff --git a/workspaces/client/public/public/images-compress/034.avif b/workspaces/client/public/public/images-compress/034.avif new file mode 100644 index 000000000..55f1ca22d Binary files /dev/null and b/workspaces/client/public/public/images-compress/034.avif differ diff --git a/workspaces/client/public/public/images-compress/035.avif b/workspaces/client/public/public/images-compress/035.avif new file mode 100644 index 000000000..2f8f4bbfd Binary files /dev/null and b/workspaces/client/public/public/images-compress/035.avif differ diff --git a/workspaces/client/public/public/images-compress/036.avif b/workspaces/client/public/public/images-compress/036.avif new file mode 100644 index 000000000..ed49a3f60 Binary files /dev/null and b/workspaces/client/public/public/images-compress/036.avif differ diff --git a/workspaces/client/public/public/images-compress/037.avif b/workspaces/client/public/public/images-compress/037.avif new file mode 100644 index 000000000..71382d378 Binary files /dev/null and b/workspaces/client/public/public/images-compress/037.avif differ diff --git a/workspaces/client/public/public/images/001.jpeg b/workspaces/client/public/public/images/001.jpeg new file mode 100644 index 000000000..dc813003b Binary files /dev/null and b/workspaces/client/public/public/images/001.jpeg differ diff --git a/workspaces/client/public/public/images/002.jpeg b/workspaces/client/public/public/images/002.jpeg new file mode 100644 index 000000000..1ece17f3e Binary files /dev/null and b/workspaces/client/public/public/images/002.jpeg differ diff --git a/workspaces/client/public/public/images/003.jpeg b/workspaces/client/public/public/images/003.jpeg new file mode 100644 index 000000000..ce28dbef0 Binary files /dev/null and b/workspaces/client/public/public/images/003.jpeg differ diff --git a/workspaces/client/public/public/images/004.jpeg b/workspaces/client/public/public/images/004.jpeg new file mode 100644 index 000000000..1ac258743 Binary files /dev/null and b/workspaces/client/public/public/images/004.jpeg differ diff --git a/workspaces/client/public/public/images/005.jpeg b/workspaces/client/public/public/images/005.jpeg new file mode 100644 index 000000000..033c8cb54 Binary files /dev/null and b/workspaces/client/public/public/images/005.jpeg differ diff --git a/workspaces/client/public/public/images/006.jpeg b/workspaces/client/public/public/images/006.jpeg new file mode 100644 index 000000000..254f8611b Binary files /dev/null and b/workspaces/client/public/public/images/006.jpeg differ diff --git a/workspaces/client/public/public/images/007.jpeg b/workspaces/client/public/public/images/007.jpeg new file mode 100644 index 000000000..f47135155 Binary files /dev/null and b/workspaces/client/public/public/images/007.jpeg differ diff --git a/workspaces/client/public/public/images/008.jpeg b/workspaces/client/public/public/images/008.jpeg new file mode 100644 index 000000000..1b09e2d4e Binary files /dev/null and b/workspaces/client/public/public/images/008.jpeg differ diff --git a/workspaces/client/public/public/images/009.jpeg b/workspaces/client/public/public/images/009.jpeg new file mode 100644 index 000000000..dddf48709 Binary files /dev/null and b/workspaces/client/public/public/images/009.jpeg differ diff --git a/workspaces/client/public/public/images/010.jpeg b/workspaces/client/public/public/images/010.jpeg new file mode 100644 index 000000000..cbb93cccd Binary files /dev/null and b/workspaces/client/public/public/images/010.jpeg differ diff --git a/workspaces/client/public/public/images/011.jpeg b/workspaces/client/public/public/images/011.jpeg new file mode 100644 index 000000000..a1daeebba Binary files /dev/null and b/workspaces/client/public/public/images/011.jpeg differ diff --git a/workspaces/client/public/public/images/012.jpeg b/workspaces/client/public/public/images/012.jpeg new file mode 100644 index 000000000..c5426d6f9 Binary files /dev/null and b/workspaces/client/public/public/images/012.jpeg differ diff --git a/workspaces/client/public/public/images/013.jpeg b/workspaces/client/public/public/images/013.jpeg new file mode 100644 index 000000000..8ad516a13 Binary files /dev/null and b/workspaces/client/public/public/images/013.jpeg differ diff --git a/workspaces/client/public/public/images/014.jpeg b/workspaces/client/public/public/images/014.jpeg new file mode 100644 index 000000000..be184c423 Binary files /dev/null and b/workspaces/client/public/public/images/014.jpeg differ diff --git a/workspaces/client/public/public/images/015.jpeg b/workspaces/client/public/public/images/015.jpeg new file mode 100644 index 000000000..7485bee90 Binary files /dev/null and b/workspaces/client/public/public/images/015.jpeg differ diff --git a/workspaces/client/public/public/images/016.jpeg b/workspaces/client/public/public/images/016.jpeg new file mode 100644 index 000000000..4cfbb87bd Binary files /dev/null and b/workspaces/client/public/public/images/016.jpeg differ diff --git a/workspaces/client/public/public/images/017.jpeg b/workspaces/client/public/public/images/017.jpeg new file mode 100644 index 000000000..39a2f2408 Binary files /dev/null and b/workspaces/client/public/public/images/017.jpeg differ diff --git a/workspaces/client/public/public/images/018.jpeg b/workspaces/client/public/public/images/018.jpeg new file mode 100644 index 000000000..f6ae9d20f Binary files /dev/null and b/workspaces/client/public/public/images/018.jpeg differ diff --git a/workspaces/client/public/public/images/019.jpeg b/workspaces/client/public/public/images/019.jpeg new file mode 100644 index 000000000..2f36db641 Binary files /dev/null and b/workspaces/client/public/public/images/019.jpeg differ diff --git a/workspaces/client/public/public/images/020.jpeg b/workspaces/client/public/public/images/020.jpeg new file mode 100644 index 000000000..b4a566b73 Binary files /dev/null and b/workspaces/client/public/public/images/020.jpeg differ diff --git a/workspaces/client/public/public/images/021.jpeg b/workspaces/client/public/public/images/021.jpeg new file mode 100644 index 000000000..6d663e7f9 Binary files /dev/null and b/workspaces/client/public/public/images/021.jpeg differ diff --git a/workspaces/client/public/public/images/022.jpeg b/workspaces/client/public/public/images/022.jpeg new file mode 100644 index 000000000..aa5cccf8c Binary files /dev/null and b/workspaces/client/public/public/images/022.jpeg differ diff --git a/workspaces/client/public/public/images/023.jpeg b/workspaces/client/public/public/images/023.jpeg new file mode 100644 index 000000000..1e1e4e7d3 Binary files /dev/null and b/workspaces/client/public/public/images/023.jpeg differ diff --git a/workspaces/client/public/public/images/024.jpeg b/workspaces/client/public/public/images/024.jpeg new file mode 100644 index 000000000..c5e5f86c8 Binary files /dev/null and b/workspaces/client/public/public/images/024.jpeg differ diff --git a/workspaces/client/public/public/images/025.jpeg b/workspaces/client/public/public/images/025.jpeg new file mode 100644 index 000000000..e1c9bc113 Binary files /dev/null and b/workspaces/client/public/public/images/025.jpeg differ diff --git a/workspaces/client/public/public/images/026.jpeg b/workspaces/client/public/public/images/026.jpeg new file mode 100644 index 000000000..9169af8dd Binary files /dev/null and b/workspaces/client/public/public/images/026.jpeg differ diff --git a/workspaces/client/public/public/images/027.jpeg b/workspaces/client/public/public/images/027.jpeg new file mode 100644 index 000000000..754c29f51 Binary files /dev/null and b/workspaces/client/public/public/images/027.jpeg differ diff --git a/workspaces/client/public/public/images/028.jpeg b/workspaces/client/public/public/images/028.jpeg new file mode 100644 index 000000000..d27b403be Binary files /dev/null and b/workspaces/client/public/public/images/028.jpeg differ diff --git a/workspaces/client/public/public/images/029.jpeg b/workspaces/client/public/public/images/029.jpeg new file mode 100644 index 000000000..e74fa0ed4 Binary files /dev/null and b/workspaces/client/public/public/images/029.jpeg differ diff --git a/workspaces/client/public/public/images/030.jpeg b/workspaces/client/public/public/images/030.jpeg new file mode 100644 index 000000000..9d7fe74ff Binary files /dev/null and b/workspaces/client/public/public/images/030.jpeg differ diff --git a/workspaces/client/public/public/images/031.jpeg b/workspaces/client/public/public/images/031.jpeg new file mode 100644 index 000000000..926a3ee74 Binary files /dev/null and b/workspaces/client/public/public/images/031.jpeg differ diff --git a/workspaces/client/public/public/images/032.jpeg b/workspaces/client/public/public/images/032.jpeg new file mode 100644 index 000000000..57d8a4424 Binary files /dev/null and b/workspaces/client/public/public/images/032.jpeg differ diff --git a/workspaces/client/public/public/images/033.jpeg b/workspaces/client/public/public/images/033.jpeg new file mode 100644 index 000000000..cb8d05eb9 Binary files /dev/null and b/workspaces/client/public/public/images/033.jpeg differ diff --git a/workspaces/client/public/public/images/034.jpeg b/workspaces/client/public/public/images/034.jpeg new file mode 100644 index 000000000..d96e76079 Binary files /dev/null and b/workspaces/client/public/public/images/034.jpeg differ diff --git a/workspaces/client/public/public/images/035.jpeg b/workspaces/client/public/public/images/035.jpeg new file mode 100644 index 000000000..0d3a506f3 Binary files /dev/null and b/workspaces/client/public/public/images/035.jpeg differ diff --git a/workspaces/client/public/public/images/036.jpeg b/workspaces/client/public/public/images/036.jpeg new file mode 100644 index 000000000..1f349e9ab Binary files /dev/null and b/workspaces/client/public/public/images/036.jpeg differ diff --git a/workspaces/client/public/public/images/037.jpeg b/workspaces/client/public/public/images/037.jpeg new file mode 100644 index 000000000..b18bed87b Binary files /dev/null and b/workspaces/client/public/public/images/037.jpeg differ diff --git a/workspaces/client/public/public/logos/anime.avif b/workspaces/client/public/public/logos/anime.avif new file mode 100644 index 000000000..0c7bc229e Binary files /dev/null and b/workspaces/client/public/public/logos/anime.avif differ diff --git a/workspaces/client/public/public/logos/anime.png b/workspaces/client/public/public/logos/anime.png new file mode 100644 index 000000000..edb708748 Binary files /dev/null and b/workspaces/client/public/public/logos/anime.png differ diff --git a/workspaces/client/public/public/logos/anime.svg b/workspaces/client/public/public/logos/anime.svg new file mode 100644 index 000000000..7f8238b99 --- /dev/null +++ b/workspaces/client/public/public/logos/anime.svg @@ -0,0 +1,11 @@ + + + + アニメ + + diff --git a/workspaces/client/public/public/logos/documentary.avif b/workspaces/client/public/public/logos/documentary.avif new file mode 100644 index 000000000..3abf78e11 Binary files /dev/null and b/workspaces/client/public/public/logos/documentary.avif differ diff --git a/workspaces/client/public/public/logos/documentary.png b/workspaces/client/public/public/logos/documentary.png new file mode 100644 index 000000000..7e96696e1 Binary files /dev/null and b/workspaces/client/public/public/logos/documentary.png differ diff --git a/workspaces/client/public/public/logos/documentary.svg b/workspaces/client/public/public/logos/documentary.svg new file mode 100644 index 000000000..400aa236a --- /dev/null +++ b/workspaces/client/public/public/logos/documentary.svg @@ -0,0 +1,11 @@ + + + + ドキュメンタリー + + diff --git a/workspaces/client/public/public/logos/drama.avif b/workspaces/client/public/public/logos/drama.avif new file mode 100644 index 000000000..83128e9c8 Binary files /dev/null and b/workspaces/client/public/public/logos/drama.avif differ diff --git a/workspaces/client/public/public/logos/drama.png b/workspaces/client/public/public/logos/drama.png new file mode 100644 index 000000000..9d6f601d9 Binary files /dev/null and b/workspaces/client/public/public/logos/drama.png differ diff --git a/workspaces/client/public/public/logos/drama.svg b/workspaces/client/public/public/logos/drama.svg new file mode 100644 index 000000000..37107ee85 --- /dev/null +++ b/workspaces/client/public/public/logos/drama.svg @@ -0,0 +1,11 @@ + + + + ドラマ + + diff --git a/workspaces/client/public/public/logos/fightingsports.avif b/workspaces/client/public/public/logos/fightingsports.avif new file mode 100644 index 000000000..c71b244cc Binary files /dev/null and b/workspaces/client/public/public/logos/fightingsports.avif differ diff --git a/workspaces/client/public/public/logos/fightingsports.png b/workspaces/client/public/public/logos/fightingsports.png new file mode 100644 index 000000000..28ee11824 Binary files /dev/null and b/workspaces/client/public/public/logos/fightingsports.png differ diff --git a/workspaces/client/public/public/logos/fightingsports.svg b/workspaces/client/public/public/logos/fightingsports.svg new file mode 100644 index 000000000..4e8da0054 --- /dev/null +++ b/workspaces/client/public/public/logos/fightingsports.svg @@ -0,0 +1,11 @@ + + + + 格闘 + + diff --git a/workspaces/client/public/public/logos/mahjong.avif b/workspaces/client/public/public/logos/mahjong.avif new file mode 100644 index 000000000..83c5379a2 Binary files /dev/null and b/workspaces/client/public/public/logos/mahjong.avif differ diff --git a/workspaces/client/public/public/logos/mahjong.png b/workspaces/client/public/public/logos/mahjong.png new file mode 100644 index 000000000..2345a1cff Binary files /dev/null and b/workspaces/client/public/public/logos/mahjong.png differ diff --git a/workspaces/client/public/public/logos/mahjong.svg b/workspaces/client/public/public/logos/mahjong.svg new file mode 100644 index 000000000..88f719067 --- /dev/null +++ b/workspaces/client/public/public/logos/mahjong.svg @@ -0,0 +1,11 @@ + + + + 麻雀 + + diff --git a/workspaces/client/public/public/logos/music.avif b/workspaces/client/public/public/logos/music.avif new file mode 100644 index 000000000..b5ea098ac Binary files /dev/null and b/workspaces/client/public/public/logos/music.avif differ diff --git a/workspaces/client/public/public/logos/music.png b/workspaces/client/public/public/logos/music.png new file mode 100644 index 000000000..a1fe0214a Binary files /dev/null and b/workspaces/client/public/public/logos/music.png differ diff --git a/workspaces/client/public/public/logos/music.svg b/workspaces/client/public/public/logos/music.svg new file mode 100644 index 000000000..f1d4a7ede --- /dev/null +++ b/workspaces/client/public/public/logos/music.svg @@ -0,0 +1,11 @@ + + + + 音楽 + + diff --git a/workspaces/client/public/public/logos/news.avif b/workspaces/client/public/public/logos/news.avif new file mode 100644 index 000000000..37d03c001 Binary files /dev/null and b/workspaces/client/public/public/logos/news.avif differ diff --git a/workspaces/client/public/public/logos/news.png b/workspaces/client/public/public/logos/news.png new file mode 100644 index 000000000..f184f924e Binary files /dev/null and b/workspaces/client/public/public/logos/news.png differ diff --git a/workspaces/client/public/public/logos/news.svg b/workspaces/client/public/public/logos/news.svg new file mode 100644 index 000000000..1705a248a --- /dev/null +++ b/workspaces/client/public/public/logos/news.svg @@ -0,0 +1,11 @@ + + + + ニュース + + diff --git a/workspaces/client/public/public/logos/reality.avif b/workspaces/client/public/public/logos/reality.avif new file mode 100644 index 000000000..c8935caa4 Binary files /dev/null and b/workspaces/client/public/public/logos/reality.avif differ diff --git a/workspaces/client/public/public/logos/reality.png b/workspaces/client/public/public/logos/reality.png new file mode 100644 index 000000000..a87797234 Binary files /dev/null and b/workspaces/client/public/public/logos/reality.png differ diff --git a/workspaces/client/public/public/logos/reality.svg b/workspaces/client/public/public/logos/reality.svg new file mode 100644 index 000000000..804362fcd --- /dev/null +++ b/workspaces/client/public/public/logos/reality.svg @@ -0,0 +1,11 @@ + + + + リアリティショー + + diff --git a/workspaces/client/public/public/logos/shogi.avif b/workspaces/client/public/public/logos/shogi.avif new file mode 100644 index 000000000..afc17e8d3 Binary files /dev/null and b/workspaces/client/public/public/logos/shogi.avif differ diff --git a/workspaces/client/public/public/logos/shogi.png b/workspaces/client/public/public/logos/shogi.png new file mode 100644 index 000000000..3ba499cda Binary files /dev/null and b/workspaces/client/public/public/logos/shogi.png differ diff --git a/workspaces/client/public/public/logos/shogi.svg b/workspaces/client/public/public/logos/shogi.svg new file mode 100644 index 000000000..8c8dbc195 --- /dev/null +++ b/workspaces/client/public/public/logos/shogi.svg @@ -0,0 +1,11 @@ + + + + 将棋 + + diff --git a/workspaces/client/public/public/logos/soccer.avif b/workspaces/client/public/public/logos/soccer.avif new file mode 100644 index 000000000..bb8a9660b Binary files /dev/null and b/workspaces/client/public/public/logos/soccer.avif differ diff --git a/workspaces/client/public/public/logos/soccer.png b/workspaces/client/public/public/logos/soccer.png new file mode 100644 index 000000000..43032525b Binary files /dev/null and b/workspaces/client/public/public/logos/soccer.png differ diff --git a/workspaces/client/public/public/logos/soccer.svg b/workspaces/client/public/public/logos/soccer.svg new file mode 100644 index 000000000..183e8654d --- /dev/null +++ b/workspaces/client/public/public/logos/soccer.svg @@ -0,0 +1,11 @@ + + + + サッカー + + diff --git a/workspaces/client/public/public/logos/sumo.avif b/workspaces/client/public/public/logos/sumo.avif new file mode 100644 index 000000000..8b8634ce3 Binary files /dev/null and b/workspaces/client/public/public/logos/sumo.avif differ diff --git a/workspaces/client/public/public/logos/sumo.png b/workspaces/client/public/public/logos/sumo.png new file mode 100644 index 000000000..d88b80f1e Binary files /dev/null and b/workspaces/client/public/public/logos/sumo.png differ diff --git a/workspaces/client/public/public/logos/sumo.svg b/workspaces/client/public/public/logos/sumo.svg new file mode 100644 index 000000000..8cc17ad32 --- /dev/null +++ b/workspaces/client/public/public/logos/sumo.svg @@ -0,0 +1,11 @@ + + + + 大相撲 + + diff --git a/workspaces/client/public/public/logos/variety.avif b/workspaces/client/public/public/logos/variety.avif new file mode 100644 index 000000000..6a645573d Binary files /dev/null and b/workspaces/client/public/public/logos/variety.avif differ diff --git a/workspaces/client/public/public/logos/variety.png b/workspaces/client/public/public/logos/variety.png new file mode 100644 index 000000000..a9c178003 Binary files /dev/null and b/workspaces/client/public/public/logos/variety.png differ diff --git a/workspaces/client/public/public/logos/variety.svg b/workspaces/client/public/public/logos/variety.svg new file mode 100644 index 000000000..805915a56 --- /dev/null +++ b/workspaces/client/public/public/logos/variety.svg @@ -0,0 +1,11 @@ + + + + バラエティ + + diff --git a/workspaces/client/react-router.config.ts b/workspaces/client/react-router.config.ts new file mode 100644 index 000000000..6f0473fa6 --- /dev/null +++ b/workspaces/client/react-router.config.ts @@ -0,0 +1,9 @@ +import type { Config } from '@react-router/dev/config'; + +export default { + appDirectory: 'src', + future: { + unstable_viteEnvironmentApi: true, + }, + ssr: true, +} satisfies Config; diff --git a/workspaces/client/src/app/StoreContext.ts b/workspaces/client/src/app/StoreContext.ts index fc161952d..7e561996c 100644 --- a/workspaces/client/src/app/StoreContext.ts +++ b/workspaces/client/src/app/StoreContext.ts @@ -1,8 +1,14 @@ -import type { ExtractState } from 'zustand/vanilla'; -import { createContext } from 'zustand-di'; +import { createContext, useContext } from 'react'; +import { useStore as useZustandStore } from 'zustand'; -import { createStore } from '@wsh-2025/client/src/app/createStore'; +import { Store, StoreState } from '@wsh-2025/client/src/app/createStore'; -const [StoreProvider, useStore] = createContext>>(); +export const StoreContext = createContext(null); -export { StoreProvider, useStore }; +export const useStore = (selector: (state: StoreState) => T): T => { + const store = useContext(StoreContext); + if (!store) { + throw new Error('useStore must be used within StoreProvider'); + } + return useZustandStore(store, selector); +}; diff --git a/workspaces/client/src/app/createRoutes.tsx b/workspaces/client/src/app/createRoutes.tsx index a81e12561..3a60638c4 100644 --- a/workspaces/client/src/app/createRoutes.tsx +++ b/workspaces/client/src/app/createRoutes.tsx @@ -1,109 +1,78 @@ -import lazy from 'p-min-delay'; -import { RouteObject } from 'react-router'; +// import type { RouteObject } from 'react-router'; -import { Document, prefetch } from '@wsh-2025/client/src/app/Document'; -import { createStore } from '@wsh-2025/client/src/app/createStore'; +// import { Document, prefetch } from '@wsh-2025/client/src/app/Document'; +// import { createStore } from '@wsh-2025/client/src/app/createStore'; +// import { +// EpisodePage, +// prefetch as episodePagePrefetch, +// } from '@wsh-2025/client/src/pages/episode/components/EpisodePage'; +// import { HomePage, prefetch as homePagePrefetch } from '@wsh-2025/client/src/pages/home/components/HomePage'; +// import { +// NotFoundPage, +// prefetch as notFoundPagePrefetch, +// } from '@wsh-2025/client/src/pages/not_found/components/NotFoundPage'; +// import { +// prefetch as programPagePrefetch, +// ProgramPage, +// } from '@wsh-2025/client/src/pages/program/components/ProgramPage'; +// import { prefetch as seriesPagePrefetch, SeriesPage } from '@wsh-2025/client/src/pages/series/components/SeriesPage'; +// import { +// prefetch as timetablePagePrefetch, +// TimetablePage, +// } from '@wsh-2025/client/src/pages/timetable/components/TimetablePage'; -export function createRoutes(store: ReturnType): RouteObject[] { - return [ - { - children: [ - { - index: true, - async lazy() { - const { HomePage, prefetch } = await lazy( - import('@wsh-2025/client/src/pages/home/components/HomePage'), - 1000, - ); - return { - Component: HomePage, - async loader() { - return await prefetch(store); - }, - }; - }, - }, - { - async lazy() { - const { EpisodePage, prefetch } = await lazy( - import('@wsh-2025/client/src/pages/episode/components/EpisodePage'), - 1000, - ); - return { - Component: EpisodePage, - async loader({ params }) { - return await prefetch(store, params); - }, - }; - }, - path: '/episodes/:episodeId', - }, - { - async lazy() { - const { prefetch, ProgramPage } = await lazy( - import('@wsh-2025/client/src/pages/program/components/ProgramPage'), - 1000, - ); - return { - Component: ProgramPage, - async loader({ params }) { - return await prefetch(store, params); - }, - }; - }, - path: '/programs/:programId', - }, - { - async lazy() { - const { prefetch, SeriesPage } = await lazy( - import('@wsh-2025/client/src/pages/series/components/SeriesPage'), - 1000, - ); - return { - Component: SeriesPage, - async loader({ params }) { - return await prefetch(store, params); - }, - }; - }, - path: '/series/:seriesId', - }, - { - async lazy() { - const { prefetch, TimetablePage } = await lazy( - import('@wsh-2025/client/src/pages/timetable/components/TimetablePage'), - 1000, - ); - return { - Component: TimetablePage, - async loader() { - return await prefetch(store); - }, - }; - }, - path: '/timetable', - }, - { - async lazy() { - const { NotFoundPage, prefetch } = await lazy( - import('@wsh-2025/client/src/pages/not_found/components/NotFoundPage'), - 1000, - ); - return { - Component: NotFoundPage, - async loader() { - return await prefetch(store); - }, - }; - }, - path: '*', - }, - ], - Component: Document, - async loader() { - return await prefetch(store); - }, - path: '/', - }, - ]; -} +// export function createRoutes(store: ReturnType): RouteObject[] { +// return [ +// { +// children: [ +// { +// Component: HomePage, +// index: true, +// async loader() { +// return await homePagePrefetch(store); +// }, +// }, +// { +// Component: EpisodePage, +// async loader({ params }) { +// return await episodePagePrefetch(store, params); +// }, +// path: '/episodes/:episodeId', +// }, +// { +// Component: ProgramPage, +// async loader({ params }) { +// return await programPagePrefetch(store, params); +// }, +// path: '/programs/:programId', +// }, +// { +// Component: SeriesPage, +// async loader({ params }) { +// return await seriesPagePrefetch(store, params); +// }, +// path: '/series/:seriesId', +// }, +// { +// Component: TimetablePage, +// async loader() { +// return await timetablePagePrefetch(store); +// }, +// path: '/timetable', +// }, +// { +// Component: NotFoundPage, +// async loader() { +// return await notFoundPagePrefetch(store); +// }, +// path: '*', +// }, +// ], +// Component: Document, +// async loader() { +// return await prefetch(store); +// }, +// path: '/', +// }, +// ]; +// } diff --git a/workspaces/client/src/app/createStore.ts b/workspaces/client/src/app/createStore.ts index 92d2abaaf..fc038f295 100644 --- a/workspaces/client/src/app/createStore.ts +++ b/workspaces/client/src/app/createStore.ts @@ -1,19 +1,35 @@ import { withLenses } from '@dhmk/zustand-lens'; -import _ from 'lodash'; -import { createStore as createZustandStore } from 'zustand/vanilla'; +import deepmerge from 'deepmerge'; +import { createStore as createZustandStore, type StoreApi } from 'zustand/vanilla'; import { createAuthStoreSlice } from '@wsh-2025/client/src/features/auth/stores/createAuthStoreSlice'; import { createChannelStoreSlice } from '@wsh-2025/client/src/features/channel/stores/createChannelStoreSlice'; import { createEpisodeStoreSlice } from '@wsh-2025/client/src/features/episode/stores/createEpisodeStoreSlice'; -import { createLayoutStoreSlice } from '@wsh-2025/client/src/features/layout/stores/createLayoutStore'; import { createProgramStoreSlice } from '@wsh-2025/client/src/features/program/stores/createProgramStoreSlice'; import { createRecommendedStoreSlice } from '@wsh-2025/client/src/features/recommended/stores/createRecomendedStoreSlice'; import { createSeriesStoreSlice } from '@wsh-2025/client/src/features/series/stores/createSeriesStoreSlice'; -import { createTimetableStoreSlice } from '@wsh-2025/client/src/features/timetable/stores/createTimetableStoreSlice'; import { createEpisodePageStoreSlice } from '@wsh-2025/client/src/pages/episode/stores/createEpisodePageStoreSlice'; import { createProgramPageStoreSlice } from '@wsh-2025/client/src/pages/program/stores/createProgramPageStoreSlice'; import { createTimetablePageStoreSlice } from '@wsh-2025/client/src/pages/timetable/stores/createTimetablePageStoreSlice'; +export type StoreState = { + features: { + auth: ReturnType; + channel: ReturnType; + episode: ReturnType; + program: ReturnType; + recommended: ReturnType; + series: ReturnType; + }; + pages: { + episode: ReturnType; + program: ReturnType; + timetable: ReturnType; + }; +}; + +export type Store = StoreApi; + interface Props { hydrationData?: unknown; } @@ -25,11 +41,9 @@ export const createStore = ({ hydrationData }: Props) => { auth: createAuthStoreSlice(), channel: createChannelStoreSlice(), episode: createEpisodeStoreSlice(), - layout: createLayoutStoreSlice(), program: createProgramStoreSlice(), recommended: createRecommendedStoreSlice(), series: createSeriesStoreSlice(), - timetable: createTimetableStoreSlice(), }, pages: { episode: createEpisodePageStoreSlice(), @@ -39,7 +53,10 @@ export const createStore = ({ hydrationData }: Props) => { })), ); - store.setState((s) => _.merge(s, hydrationData)); + // Apply hydration data if available using deepmerge for deep merging + if (hydrationData && typeof hydrationData === 'object') { + store.setState((s) => deepmerge(s, hydrationData as Record)); + } return store; }; diff --git a/workspaces/client/src/entry.client.tsx b/workspaces/client/src/entry.client.tsx new file mode 100644 index 000000000..63058d4de --- /dev/null +++ b/workspaces/client/src/entry.client.tsx @@ -0,0 +1,12 @@ +import React from "react"; +import ReactDOM from "react-dom/client"; +import { HydratedRouter } from "react-router/dom"; + +import '@unocss/reset/tailwind-compat.css'; + +ReactDOM.hydrateRoot( + document, + + + +); diff --git a/workspaces/client/src/entry.server.tsx b/workspaces/client/src/entry.server.tsx new file mode 100644 index 000000000..6cd6c888b --- /dev/null +++ b/workspaces/client/src/entry.server.tsx @@ -0,0 +1,40 @@ +import { isbot } from 'isbot'; +import { renderToReadableStream } from 'react-dom/server'; +import type { AppLoadContext, EntryContext } from 'react-router'; +import { ServerRouter } from 'react-router'; + +export default async function handleRequest( + request: Request, + responseStatusCode: number, + responseHeaders: Headers, + routerContext: EntryContext, + _loadContext: AppLoadContext, +) { + let shellRendered = false; + const userAgent = request.headers.get('user-agent'); + + const body = await renderToReadableStream(, { + onError(error: unknown) { + responseStatusCode = 500; + // Log streaming rendering errors from inside the shell. Don't log + // errors encountered during initial shell rendering since they'll + // reject and get logged in handleDocumentRequest. + if (shellRendered) { + console.error(error); + } + }, + }); + shellRendered = true; + + // Ensure requests from bots and SPA Mode renders wait for all content to load before responding + // https://react.dev/reference/react-dom/server/renderToPipeableStream#waiting-for-all-content-to-load-for-crawlers-and-static-generation + if ((userAgent && isbot(userAgent)) || routerContext.isSpaMode) { + await body.allReady; + } + + responseHeaders.set('Content-Type', 'text/html'); + return new Response(body, { + headers: responseHeaders, + status: responseStatusCode, + }); +} diff --git a/workspaces/client/src/features/auth/components/SignInDialog.tsx b/workspaces/client/src/features/auth/components/SignInDialog.tsx index 350d89edc..7a91aa1f1 100644 --- a/workspaces/client/src/features/auth/components/SignInDialog.tsx +++ b/workspaces/client/src/features/auth/components/SignInDialog.tsx @@ -47,7 +47,7 @@ export const SignInDialog = ({ isOpen, onClose, onOpenSignUp }: Props) => {
- +

ログイン

diff --git a/workspaces/client/src/features/auth/components/SignOutDialog.tsx b/workspaces/client/src/features/auth/components/SignOutDialog.tsx index d7c1fd336..9b9522212 100644 --- a/workspaces/client/src/features/auth/components/SignOutDialog.tsx +++ b/workspaces/client/src/features/auth/components/SignOutDialog.tsx @@ -28,7 +28,7 @@ export const SignOutDialog = ({ isOpen, onClose }: Props) => {
- +

ログアウト

diff --git a/workspaces/client/src/features/auth/components/SignUpDialog.tsx b/workspaces/client/src/features/auth/components/SignUpDialog.tsx index 1cb939f8d..af5ee20f3 100644 --- a/workspaces/client/src/features/auth/components/SignUpDialog.tsx +++ b/workspaces/client/src/features/auth/components/SignUpDialog.tsx @@ -47,7 +47,7 @@ export const SignUpDialog = ({ isOpen, onClose, onOpenSignIn }: Props) => {
- +

会員登録

diff --git a/workspaces/client/src/features/auth/hooks/useAuthActions.ts b/workspaces/client/src/features/auth/hooks/useAuthActions.ts index 7ea329795..f4bc8b63d 100644 --- a/workspaces/client/src/features/auth/hooks/useAuthActions.ts +++ b/workspaces/client/src/features/auth/hooks/useAuthActions.ts @@ -1,15 +1,15 @@ import { useStore } from '@wsh-2025/client/src/app/StoreContext'; export function useAuthActions() { - const state = useStore((s) => s); + const state = useStore((s) => s.features.auth); return { - closeDialog: state.features.auth.closeDialog, - openSignInDialog: state.features.auth.openSignInDialog, - openSignOutDialog: state.features.auth.openSignOutDialog, - openSignUpDialog: state.features.auth.openSignUpDialog, - signIn: state.features.auth.signIn, - signOut: state.features.auth.signOut, - signUp: state.features.auth.signUp, + closeDialog: state.closeDialog, + openSignInDialog: state.openSignInDialog, + openSignOutDialog: state.openSignOutDialog, + openSignUpDialog: state.openSignUpDialog, + signIn: state.signIn, + signOut: state.signOut, + signUp: state.signUp, }; } diff --git a/workspaces/client/src/features/auth/hooks/useAuthDialogType.ts b/workspaces/client/src/features/auth/hooks/useAuthDialogType.ts index 9350b3f82..9ec4fd94a 100644 --- a/workspaces/client/src/features/auth/hooks/useAuthDialogType.ts +++ b/workspaces/client/src/features/auth/hooks/useAuthDialogType.ts @@ -1,6 +1,6 @@ import { useStore } from '@wsh-2025/client/src/app/StoreContext'; export function useAuthDialogType() { - const state = useStore((s) => s); - return state.features.auth.dialog; + const state = useStore((s) => s.features.auth.dialog); + return state; } diff --git a/workspaces/client/src/features/auth/hooks/useAuthUser.ts b/workspaces/client/src/features/auth/hooks/useAuthUser.ts index aa3a86707..573301bbf 100644 --- a/workspaces/client/src/features/auth/hooks/useAuthUser.ts +++ b/workspaces/client/src/features/auth/hooks/useAuthUser.ts @@ -1,6 +1,6 @@ import { useStore } from '@wsh-2025/client/src/app/StoreContext'; export function useAuthUser() { - const state = useStore((s) => s); - return state.features.auth.user; + const state = useStore((s) => s.features.auth.user); + return state; } diff --git a/workspaces/client/src/features/auth/services/authService.ts b/workspaces/client/src/features/auth/services/authService.ts index df4c6f0d2..454b60a4a 100644 --- a/workspaces/client/src/features/auth/services/authService.ts +++ b/workspaces/client/src/features/auth/services/authService.ts @@ -1,24 +1,27 @@ import { createFetch, createSchema } from '@better-fetch/fetch'; import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; - -import { schedulePlugin } from '@wsh-2025/client/src/features/requests/schedulePlugin'; +import { + getUserResponse, + signInRequestBody, + signInResponse, + signUpRequestBody, + signUpResponse, +} from '@wsh-2025/schema/src/openapi/schema'; const $fetch = createFetch({ - baseURL: process.env['API_BASE_URL'] ?? '/api', - plugins: [schedulePlugin], + baseURL: import.meta.env['VITE_API_BASE_URL'] ?? 'http://localhost:8000/api', schema: createSchema({ '/signIn': { - input: schema.signInRequestBody, - output: schema.signInResponse, + input: signInRequestBody, + output: signInResponse, }, '/signOut': {}, '/signUp': { - input: schema.signUpRequestBody, - output: schema.signUpResponse, + input: signUpRequestBody, + output: signUpResponse, }, '/users/me': { - output: schema.getUserResponse, + output: getUserResponse, }, }), throw: true, @@ -26,13 +29,13 @@ const $fetch = createFetch({ interface AuthService { fetchSignIn: ( - body: StandardSchemaV1.InferOutput, - ) => Promise>; + body: StandardSchemaV1.InferOutput, + ) => Promise>; fetchSignOut: () => Promise; fetchSignUp: ( - body: StandardSchemaV1.InferOutput, - ) => Promise>; - fetchUser: () => Promise>; + body: StandardSchemaV1.InferOutput, + ) => Promise>; + fetchUser: () => Promise | null>; } export const authService: AuthService = { @@ -48,7 +51,11 @@ export const authService: AuthService = { return data; }, async fetchUser() { - const data = await $fetch('/users/me'); - return data; + try { + const data = await $fetch('/users/me'); + return data; + } catch { + return null; + } }, }; diff --git a/workspaces/client/src/features/auth/stores/createAuthStoreSlice.ts b/workspaces/client/src/features/auth/stores/createAuthStoreSlice.ts index b8bf797ad..951a484f9 100644 --- a/workspaces/client/src/features/auth/stores/createAuthStoreSlice.ts +++ b/workspaces/client/src/features/auth/stores/createAuthStoreSlice.ts @@ -1,6 +1,12 @@ import { lens } from '@dhmk/zustand-lens'; import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; +import { + getUserResponse, + signInRequestBody, + signInResponse, + signUpRequestBody, + signUpResponse, +} from '@wsh-2025/schema/src/openapi/schema'; import { authService } from '../services/authService'; @@ -13,17 +19,17 @@ interface AuthState { interface AuthActions { closeDialog: () => void; - fetchUser: () => Promise | null>; + fetchUser: () => Promise | null>; openSignInDialog: () => void; openSignOutDialog: () => void; openSignUpDialog: () => void; signIn: ( - body: StandardSchemaV1.InferOutput, - ) => Promise>; + body: StandardSchemaV1.InferOutput, + ) => Promise>; signOut: () => Promise; signUp: ( - body: StandardSchemaV1.InferOutput, - ) => Promise>; + body: StandardSchemaV1.InferOutput, + ) => Promise>; } export const createAuthStoreSlice = () => { diff --git a/workspaces/client/src/features/channel/hooks/useChannelById.ts b/workspaces/client/src/features/channel/hooks/useChannelById.ts deleted file mode 100644 index 9386928fe..000000000 --- a/workspaces/client/src/features/channel/hooks/useChannelById.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { useStore } from '@wsh-2025/client/src/app/StoreContext'; - -type ChannelId = string; - -export function useChannelById(params: { channelId: ChannelId }) { - const state = useStore((s) => s); - - const channel = state.features.channel.channels[params.channelId]; - - return channel; -} diff --git a/workspaces/client/src/features/channel/services/channelService.ts b/workspaces/client/src/features/channel/services/channelService.ts index 312d08c69..bd4910e71 100644 --- a/workspaces/client/src/features/channel/services/channelService.ts +++ b/workspaces/client/src/features/channel/services/channelService.ts @@ -1,58 +1,29 @@ import { createFetch, createSchema } from '@better-fetch/fetch'; import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; -import * as batshit from '@yornaath/batshit'; - -import { schedulePlugin } from '@wsh-2025/client/src/features/requests/schedulePlugin'; +import { getChannelsRequestQuery, getChannelsResponse } from '@wsh-2025/schema/src/openapi/schema'; const $fetch = createFetch({ - baseURL: process.env['API_BASE_URL'] ?? '/api', - plugins: [schedulePlugin], + baseURL: import.meta.env['VITE_API_BASE_URL'] ?? 'http://localhost:8000/api', schema: createSchema({ '/channels': { - output: schema.getChannelsResponse, - query: schema.getChannelsRequestQuery, + output: getChannelsResponse, + query: getChannelsRequestQuery, }, }), throw: true, }); -const batcher = batshit.create({ - async fetcher(queries: { channelId: string }[]) { - const data = await $fetch('/channels', { - query: { - channelIds: queries.map((q) => q.channelId).join(','), - }, - }); - return data; - }, - resolver(items, query: { channelId: string }) { - const item = items.find((item) => item.id === query.channelId); - if (item == null) { - throw new Error('Channel is not found.'); - } - return item; - }, - scheduler: batshit.windowedFiniteBatchScheduler({ - maxBatchSize: 100, - windowMs: 1000, - }), -}); - interface ChannelService { - fetchChannelById: (query: { - channelId: string; - }) => Promise>; - fetchChannels: () => Promise>; + fetchChannels: () => Promise>; } export const channelService: ChannelService = { - async fetchChannelById({ channelId }) { - const channel = await batcher.fetch({ channelId }); - return channel; - }, async fetchChannels() { - const data = await $fetch('/channels', { query: {} }); - return data; + try { + const data = await $fetch('/channels', { query: {} }); + return data; + } catch { + return []; + } }, }; diff --git a/workspaces/client/src/features/channel/stores/createChannelStoreSlice.ts b/workspaces/client/src/features/channel/stores/createChannelStoreSlice.ts index 2543d978e..1e37ca6ee 100644 --- a/workspaces/client/src/features/channel/stores/createChannelStoreSlice.ts +++ b/workspaces/client/src/features/channel/stores/createChannelStoreSlice.ts @@ -1,43 +1,33 @@ import { lens } from '@dhmk/zustand-lens'; import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; -import { produce } from 'immer'; +import { getChannelByIdResponse, getChannelsResponse } from '@wsh-2025/schema/src/openapi/schema'; import { channelService } from '@wsh-2025/client/src/features/channel/services/channelService'; type ChannelId = string; interface ChannelState { - channels: Record>; + channels: Record>; } interface ChannelActions { - fetchChannelById: (params: { - channelId: ChannelId; - }) => Promise>; - fetchChannels: () => Promise>; + fetchChannels: () => Promise>; } export const createChannelStoreSlice = () => { return lens((set) => ({ channels: {}, - fetchChannelById: async ({ channelId }) => { - const channel = await channelService.fetchChannelById({ channelId }); - set((state) => { - return produce(state, (draft) => { - draft.channels[channel.id] = channel; - }); - }); - return channel; - }, fetchChannels: async () => { const channels = await channelService.fetchChannels(); set((state) => { - return produce(state, (draft) => { - for (const channel of channels) { - draft.channels[channel.id] = channel; - } - }); + const updatedChannels = { ...state.channels }; + for (const channel of channels) { + updatedChannels[channel.id] = channel; + } + return { + ...state, + channels: updatedChannels, + }; }); return channels; }, diff --git a/workspaces/client/src/features/dialog/components/Dialog.tsx b/workspaces/client/src/features/dialog/components/Dialog.tsx index 318c390f0..f15541cd2 100644 --- a/workspaces/client/src/features/dialog/components/Dialog.tsx +++ b/workspaces/client/src/features/dialog/components/Dialog.tsx @@ -1,4 +1,4 @@ -import * as HeadlessUi from '@headlessui/react'; +import { Dialog as DialogComponent, DialogPanel } from '@headlessui/react'; import { ReactNode } from 'react'; interface Props { @@ -9,14 +9,14 @@ interface Props { export const Dialog = ({ children, isOpen, onClose }: Props) => { return ( - - + {children} - - + + ); }; diff --git a/workspaces/client/src/features/episode/hooks/useEpisodeById.ts b/workspaces/client/src/features/episode/hooks/useEpisodeById.ts index 6be57694a..22bdf2501 100644 --- a/workspaces/client/src/features/episode/hooks/useEpisodeById.ts +++ b/workspaces/client/src/features/episode/hooks/useEpisodeById.ts @@ -5,9 +5,6 @@ interface Params { } export function useEpisodeById({ episodeId }: Params) { - const state = useStore((s) => s); - - const episode = state.features.episode.episodes[episodeId]; - - return episode; + const state = useStore((s) => s.features.episode.episodes[episodeId]); + return state; } diff --git a/workspaces/client/src/features/episode/services/episodeService.ts b/workspaces/client/src/features/episode/services/episodeService.ts index 3a21b8194..549b7727a 100644 --- a/workspaces/client/src/features/episode/services/episodeService.ts +++ b/workspaces/client/src/features/episode/services/episodeService.ts @@ -1,20 +1,21 @@ import { createFetch, createSchema } from '@better-fetch/fetch'; import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; +import { + getEpisodeByIdResponse, + getEpisodesRequestQuery, + getEpisodesResponse, +} from '@wsh-2025/schema/src/openapi/schema'; import * as batshit from '@yornaath/batshit'; -import { schedulePlugin } from '@wsh-2025/client/src/features/requests/schedulePlugin'; - const $fetch = createFetch({ - baseURL: process.env['API_BASE_URL'] ?? '/api', - plugins: [schedulePlugin], + baseURL: import.meta.env['VITE_API_BASE_URL'] ?? 'http://localhost:8000/api', schema: createSchema({ '/episodes': { - output: schema.getEpisodesResponse, - query: schema.getEpisodesRequestQuery, + output: getEpisodesResponse, + query: getEpisodesRequestQuery, }, '/episodes/:episodeId': { - output: schema.getEpisodeByIdResponse, + output: getEpisodeByIdResponse, }, }), throw: true, @@ -45,17 +46,25 @@ const batcher = batshit.create({ interface EpisodeService { fetchEpisodeById: (query: { episodeId: string; - }) => Promise>; - fetchEpisodes: () => Promise>; + }) => Promise | null>; + fetchEpisodes: () => Promise>; } export const episodeService: EpisodeService = { async fetchEpisodeById({ episodeId }) { - const channel = await batcher.fetch({ episodeId }); - return channel; + try { + const channel = await batcher.fetch({ episodeId }); + return channel; + } catch { + return null; + } }, async fetchEpisodes() { - const data = await $fetch('/episodes', { query: {} }); - return data; + try { + const data = await $fetch('/episodes', { query: {} }); + return data; + } catch { + return []; + } }, }; diff --git a/workspaces/client/src/features/episode/stores/createEpisodeStoreSlice.ts b/workspaces/client/src/features/episode/stores/createEpisodeStoreSlice.ts index d5d8fef8a..12396189e 100644 --- a/workspaces/client/src/features/episode/stores/createEpisodeStoreSlice.ts +++ b/workspaces/client/src/features/episode/stores/createEpisodeStoreSlice.ts @@ -1,21 +1,20 @@ import { lens } from '@dhmk/zustand-lens'; import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; -import { produce } from 'immer'; +import { getEpisodeByIdResponse, getEpisodesResponse } from '@wsh-2025/schema/src/openapi/schema'; import { episodeService } from '@wsh-2025/client/src/features/episode/services/episodeService'; type EpisodeId = string; interface EpisodeState { - episodes: Record>; + episodes: Record>; } interface EpisodeActions { fetchEpisodeById: (params: { episodeId: EpisodeId; - }) => Promise>; - fetchEpisodes: () => Promise>; + }) => Promise | null>; + fetchEpisodes: () => Promise>; } export const createEpisodeStoreSlice = () => { @@ -23,21 +22,29 @@ export const createEpisodeStoreSlice = () => { episodes: {}, fetchEpisodeById: async ({ episodeId }) => { const episode = await episodeService.fetchEpisodeById({ episodeId }); + if (!episode) return null; set((state) => { - return produce(state, (draft) => { - draft.episodes[episode.id] = episode; - }); + return { + ...state, + episodes: { + ...state.episodes, + [episode.id]: episode, + }, + }; }); return episode; }, fetchEpisodes: async () => { const episodes = await episodeService.fetchEpisodes(); set((state) => { - return produce(state, (draft) => { - for (const episode of episodes) { - draft.episodes[episode.id] = episode; - } - }); + const updatedEpisodes = { ...state.episodes }; + for (const episode of episodes) { + updatedEpisodes[episode.id] = episode; + } + return { + ...state, + episodes: updatedEpisodes, + }; }); return episodes; }, diff --git a/workspaces/client/src/features/layout/components/AspectRatio.tsx b/workspaces/client/src/features/layout/components/AspectRatio.tsx index 37b07a5a1..d3251c4b9 100644 --- a/workspaces/client/src/features/layout/components/AspectRatio.tsx +++ b/workspaces/client/src/features/layout/components/AspectRatio.tsx @@ -1,5 +1,4 @@ -import { ReactNode, useEffect, useRef } from 'react'; -import { useUpdate } from 'react-use'; +import { ReactNode } from 'react'; interface Props { children: ReactNode; @@ -8,23 +7,10 @@ interface Props { } export const AspectRatio = ({ children, ratioHeight, ratioWidth }: Props) => { - const forceUpdate = useUpdate(); - const containerRef = useRef(null); - - useEffect(() => { - const interval = setInterval(function tick() { - forceUpdate(); - }, 1000); - return () => { - clearInterval(interval); - }; - }, []); - - const width = containerRef.current?.getBoundingClientRect().width ?? 0; - const height = (width * ratioHeight) / ratioWidth; + const aspectRatio = `${ratioWidth} / ${ratioHeight}`; return ( -
+
{children}
); diff --git a/workspaces/client/src/features/layout/components/Hoverable.tsx b/workspaces/client/src/features/layout/components/Hoverable.tsx deleted file mode 100644 index b723d8aee..000000000 --- a/workspaces/client/src/features/layout/components/Hoverable.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import classNames from 'classnames'; -import { Children, cloneElement, ReactElement, Ref, useRef } from 'react'; -import { useMergeRefs } from 'use-callback-ref'; - -import { usePointer } from '@wsh-2025/client/src/features/layout/hooks/usePointer'; - -interface Props { - children: ReactElement<{ className?: string; ref?: Ref }>; - classNames: { - default?: string; - hovered?: string; - }; -} - -export const Hoverable = (props: Props) => { - const child = Children.only(props.children); - const elementRef = useRef(null); - - const mergedRef = useMergeRefs([elementRef, child.props.ref].filter((v) => v != null)); - - const pointer = usePointer(); - const elementRect = elementRef.current?.getBoundingClientRect(); - - const hovered = - elementRect != null && - elementRect.left <= pointer.x && - pointer.x <= elementRect.right && - elementRect.top <= pointer.y && - pointer.y <= elementRect.bottom; - - return cloneElement(child, { - className: classNames( - child.props.className, - 'cursor-pointer', - hovered ? props.classNames.hovered : props.classNames.default, - ), - ref: mergedRef, - }); -}; diff --git a/workspaces/client/src/features/layout/components/Layout.tsx b/workspaces/client/src/features/layout/components/Layout.tsx index 99eadef4b..383ea9eae 100644 --- a/workspaces/client/src/features/layout/components/Layout.tsx +++ b/workspaces/client/src/features/layout/components/Layout.tsx @@ -1,130 +1,152 @@ -import classNames from 'classnames'; -import { ReactNode, useEffect, useState } from 'react'; -import { Flipper } from 'react-flip-toolkit'; -import { Link, useLocation, useNavigation } from 'react-router'; - -import { SignInDialog } from '@wsh-2025/client/src/features/auth/components/SignInDialog'; -import { SignOutDialog } from '@wsh-2025/client/src/features/auth/components/SignOutDialog'; -import { SignUpDialog } from '@wsh-2025/client/src/features/auth/components/SignUpDialog'; -import { AuthDialogType } from '@wsh-2025/client/src/features/auth/constants/auth_dialog_type'; -import { useAuthActions } from '@wsh-2025/client/src/features/auth/hooks/useAuthActions'; -import { useAuthDialogType } from '@wsh-2025/client/src/features/auth/hooks/useAuthDialogType'; -import { useAuthUser } from '@wsh-2025/client/src/features/auth/hooks/useAuthUser'; -import { Loading } from '@wsh-2025/client/src/features/layout/components/Loading'; -import { useSubscribePointer } from '@wsh-2025/client/src/features/layout/hooks/useSubscribePointer'; - -interface Props { - children: ReactNode; -} - -export const Layout = ({ children }: Props) => { - useSubscribePointer(); - - const navigation = useNavigation(); - const isLoading = - navigation.location != null && (navigation.location.state as { loading?: string } | null)?.['loading'] !== 'none'; - - const location = useLocation(); - const isTimetablePage = location.pathname === '/timetable'; - - const authActions = useAuthActions(); - const authDialogType = useAuthDialogType(); - const user = useAuthUser(); - - const [scrollTopOffset, setScrollTopOffset] = useState(0); - const [shouldHeaderBeTransparent, setShouldHeaderBeTransparent] = useState(false); - - useEffect(() => { - const handleScroll = () => { - setScrollTopOffset(window.scrollY); - }; - - window.addEventListener('scroll', handleScroll); - - return () => { - window.removeEventListener('scroll', handleScroll); - }; - }, []); - - useEffect(() => { - setShouldHeaderBeTransparent(scrollTopOffset > 80); - }, [scrollTopOffset]); - - const isSignedIn = user != null; - - return ( - <> -
-
- - AREMA - -
- - - -
- - {children} - -
- - {isLoading ? ( -
- -
- ) : null} -
- - - - - - ); -}; +// import classNames from 'classnames'; +// import { ReactNode, useEffect, useRef, useState } from 'react'; +// import { Flipper } from 'react-flip-toolkit'; +// import { Link, useLocation, useNavigation } from 'react-router'; + +// import { SignInDialog } from '@wsh-2025/client/src/features/auth/components/SignInDialog'; +// import { SignOutDialog } from '@wsh-2025/client/src/features/auth/components/SignOutDialog'; +// import { SignUpDialog } from '@wsh-2025/client/src/features/auth/components/SignUpDialog'; +// import { AuthDialogType } from '@wsh-2025/client/src/features/auth/constants/auth_dialog_type'; +// import { useAuthActions } from '@wsh-2025/client/src/features/auth/hooks/useAuthActions'; +// import { useAuthDialogType } from '@wsh-2025/client/src/features/auth/hooks/useAuthDialogType'; +// import { useAuthUser } from '@wsh-2025/client/src/features/auth/hooks/useAuthUser'; +// import { Loading } from '@wsh-2025/client/src/features/layout/components/Loading'; +// import { useSubscribePointer } from '@wsh-2025/client/src/features/layout/hooks/useSubscribePointer'; + +// interface Props { +// children: ReactNode; +// } + +// export const Layout = ({ children }: Props) => { +// useSubscribePointer(); + +// const navigation = useNavigation(); +// const isLoading = +// navigation.location != null && (navigation.location.state as { loading?: string } | null)?.['loading'] !== 'none'; + +// const location = useLocation(); +// const isTimetablePage = location.pathname === '/timetable'; + +// const authActions = useAuthActions(); +// const authDialogType = useAuthDialogType(); +// const user = useAuthUser(); + +// const [shouldHeaderBeTransparent, setShouldHeaderBeTransparent] = useState(false); +// const headerObserverRef = useRef(null); + +// useEffect(() => { +// // スクロール位置を監視するオプション設定 +// const observerOptions = { +// // rootMarginをマイナスに設定:ビューポートの上端から80px下にスクロールしたら効果を発動 +// rootMargin: '-80px 0px 0px 0px', +// threshold: 0, +// }; + +// const headerObserver = new IntersectionObserver((entries) => { +// // マーカー要素が見えなくなったらヘッダーを透明に(undefined対策) +// if (entries.length > 0) { +// setShouldHeaderBeTransparent(!entries[0]?.isIntersecting); +// } +// }, observerOptions); + +// if (headerObserverRef.current) { +// headerObserver.observe(headerObserverRef.current); +// } + +// return () => { +// if (headerObserverRef.current) { +// headerObserver.unobserve(headerObserverRef.current); +// } +// }; +// }, []); + +// const isSignedIn = user != null; + +// return ( +// <> +// {/* IntersectionObserver用のマーカー要素 - ページ先頭に配置 */} +//
+//
+//
+// +// AREMA +// +//
+ +// + +//
+// +// {children} +// +//
+ +// {isLoading ? ( +//
+// +//
+// ) : null} +//
+ +// +// +// +// +// ); +// }; diff --git a/workspaces/client/src/features/layout/hooks/usePointer.ts b/workspaces/client/src/features/layout/hooks/usePointer.ts deleted file mode 100644 index 9326362bd..000000000 --- a/workspaces/client/src/features/layout/hooks/usePointer.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { useStore } from '@wsh-2025/client/src/app/StoreContext'; - -export function usePointer(): { x: number; y: number } { - const s = useStore((s) => s); - return s.features.layout.pointer; -} diff --git a/workspaces/client/src/features/layout/hooks/useSubscribePointer.ts b/workspaces/client/src/features/layout/hooks/useSubscribePointer.ts index 5dc37a174..bd33ba2f5 100644 --- a/workspaces/client/src/features/layout/hooks/useSubscribePointer.ts +++ b/workspaces/client/src/features/layout/hooks/useSubscribePointer.ts @@ -1,9 +1,7 @@ -import { useEffect } from 'react'; +import { useEffect, useState } from 'react'; -import { useStore } from '@wsh-2025/client/src/app/StoreContext'; - -export function useSubscribePointer(): void { - const s = useStore((s) => s); +export function useSubscribePointer(): { x: number; y: number } { + const [pointer, setPointer] = useState({ x: 0, y: 0 }); useEffect(() => { const abortController = new AbortController(); @@ -15,16 +13,18 @@ export function useSubscribePointer(): void { }; window.addEventListener('pointermove', handlePointerMove, { signal: abortController.signal }); - let immediate = setImmediate(function tick() { - s.features.layout.updatePointer({ ...current }); - immediate = setImmediate(tick); + let timeoutId = setTimeout(function tick() { + setPointer({ ...current }); + timeoutId = setTimeout(tick); }); abortController.signal.addEventListener('abort', () => { - clearImmediate(immediate); + clearTimeout(timeoutId); }); return () => { abortController.abort(); }; }, []); + + return pointer; } diff --git a/workspaces/client/src/features/layout/stores/createLayoutStore.ts b/workspaces/client/src/features/layout/stores/createLayoutStore.ts deleted file mode 100644 index d08b5118d..000000000 --- a/workspaces/client/src/features/layout/stores/createLayoutStore.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { lens } from '@dhmk/zustand-lens'; - -interface LayoutState { - pointer: { x: number; y: number }; -} - -interface LayoutActions { - updatePointer: (pointer: { x: number; y: number }) => void; -} - -export const createLayoutStoreSlice = () => { - return lens((set) => ({ - pointer: { x: 0, y: 0 }, - updatePointer: (pointer) => { - set(() => ({ pointer })); - }, - })); -}; diff --git a/workspaces/client/src/features/player/components/Player.tsx b/workspaces/client/src/features/player/components/Player.tsx index f1c27e8b9..32b33ab24 100644 --- a/workspaces/client/src/features/player/components/Player.tsx +++ b/workspaces/client/src/features/player/components/Player.tsx @@ -2,18 +2,17 @@ import { Ref, useEffect, useRef } from 'react'; import invariant from 'tiny-invariant'; import { assignRef } from 'use-callback-ref'; -import { PlayerType } from '@wsh-2025/client/src/features/player/constants/player_type'; import { PlayerWrapper } from '@wsh-2025/client/src/features/player/interfaces/player_wrapper'; +import { createPlayer } from '@wsh-2025/client/src/features/player/logics/create_player'; interface Props { className?: string; loop?: boolean; playerRef: Ref; - playerType: PlayerType; playlistUrl: string; } -export const Player = ({ className, loop, playerRef, playerType, playlistUrl }: Props) => { +export const Player = ({ className, loop, playerRef, playlistUrl }: Props) => { const mountRef = useRef(null); useEffect(() => { @@ -23,25 +22,37 @@ export const Player = ({ className, loop, playerRef, playerType, playlistUrl }: const abortController = new AbortController(); let player: PlayerWrapper | null = null; - void import('@wsh-2025/client/src/features/player/logics/create_player').then(({ createPlayer }) => { - if (abortController.signal.aborted) { - return; - } - player = createPlayer(playerType); - player.load(playlistUrl, { loop: loop ?? false }); + if (abortController.signal.aborted) { + return; + } + + // Lazy initialization of player + const initializePlayer = () => { + if (player) return; + + player = createPlayer(); + const url = import.meta.env['VITE_STREAM_BASE_URL'] + playlistUrl; + player.load(url, { loop: loop ?? false }); mountElement.appendChild(player.videoElement); assignRef(playerRef, player); - }); + }; + + // Initialize immediately + initializePlayer(); return () => { abortController.abort(); - if (player != null) { - mountElement.removeChild(player.videoElement); + if (player) { + try { + mountElement.removeChild(player.videoElement); + } catch (e) { + // 要素が既に削除されている場合は無視 + } player.destory(); + assignRef(playerRef, null); } - assignRef(playerRef, null); }; - }, [playerType, playlistUrl, loop]); + }, [playlistUrl, loop]); return (
diff --git a/workspaces/client/src/features/player/constants/player_type.ts b/workspaces/client/src/features/player/constants/player_type.ts deleted file mode 100644 index 94dbbcb55..000000000 --- a/workspaces/client/src/features/player/constants/player_type.ts +++ /dev/null @@ -1,5 +0,0 @@ -export enum PlayerType { - ShakaPlayer = 'shaka-player', - HlsJS = 'hls.js', - VideoJS = 'video-js', -} diff --git a/workspaces/client/src/features/player/interfaces/player_wrapper.ts b/workspaces/client/src/features/player/interfaces/player_wrapper.ts index b6ac58394..4796779e0 100644 --- a/workspaces/client/src/features/player/interfaces/player_wrapper.ts +++ b/workspaces/client/src/features/player/interfaces/player_wrapper.ts @@ -1,5 +1,3 @@ -import { PlayerType } from '@wsh-2025/client/src/features/player/constants/player_type'; - export interface PlayerWrapper { readonly currentTime: number; destory(): void; @@ -9,7 +7,6 @@ export interface PlayerWrapper { pause(): void; readonly paused: boolean; play(): void; - readonly playerType: PlayerType; seekTo(second: number): void; setMuted(muted: boolean): void; readonly videoElement: HTMLVideoElement; diff --git a/workspaces/client/src/features/player/logics/create_player.ts b/workspaces/client/src/features/player/logics/create_player.ts index 823364d27..92e08f1a6 100644 --- a/workspaces/client/src/features/player/logics/create_player.ts +++ b/workspaces/client/src/features/player/logics/create_player.ts @@ -1,85 +1,17 @@ -import '@videojs/http-streaming'; import HlsJs from 'hls.js'; -import shaka from 'shaka-player'; -import videojs from 'video.js'; -import { PlayerType } from '@wsh-2025/client/src/features/player/constants/player_type'; import { PlayerWrapper } from '@wsh-2025/client/src/features/player/interfaces/player_wrapper'; -class ShakaPlayerWrapper implements PlayerWrapper { - readonly videoElement = Object.assign(document.createElement('video'), { - autoplay: true, - controls: false, - muted: true, - volume: 0.25, - }); - private _player = new shaka.Player(); - readonly playerType: PlayerType.ShakaPlayer; - - constructor(playerType: PlayerType.ShakaPlayer) { - this.playerType = playerType; - this._player.configure({ - streaming: { - bufferingGoal: 50, - }, - }); - } - - get currentTime(): number { - const currentTime = this.videoElement.currentTime; - return Number.isNaN(currentTime) ? 0 : currentTime; - } - get paused(): boolean { - return this.videoElement.paused; - } - get duration(): number { - const duration = this.videoElement.duration; - return Number.isNaN(duration) ? 0 : duration; - } - get muted(): boolean { - return this.videoElement.muted; - } - - load(playlistUrl: string, options: { loop: boolean }): void { - void (async () => { - await this._player.attach(this.videoElement); - this.videoElement.loop = options.loop; - await this._player.load(playlistUrl); - })(); - } - play(): void { - void this.videoElement.play(); - } - pause(): void { - this.videoElement.pause(); - } - seekTo(second: number): void { - this.videoElement.currentTime = second; - } - setMuted(muted: boolean): void { - this.videoElement.muted = muted; - } - destory(): void { - void this._player.destroy(); - } -} - class HlsJSPlayerWrapper implements PlayerWrapper { readonly videoElement = Object.assign(document.createElement('video'), { - autoplay: true, + autoplay: false, controls: false, muted: true, volume: 0.25, }); - private _player = new HlsJs({ - enableWorker: false, - maxBufferLength: 50, - }); - readonly playerType: PlayerType.HlsJS; - - constructor(playerType: PlayerType.HlsJS) { - this.playerType = playerType; - } + private _player: HlsJs | null = null; + private _observer: IntersectionObserver | null = null; + private _isPreview = false; get currentTime(): number { const currentTime = this.videoElement.currentTime; @@ -89,7 +21,7 @@ class HlsJSPlayerWrapper implements PlayerWrapper { return this.videoElement.paused; } get duration(): number { - const duration = this._player.media?.duration ?? 0; + const duration = this._player?.media?.duration ?? 0; return Number.isNaN(duration) ? 0 : duration; } get muted(): boolean { @@ -97,100 +29,92 @@ class HlsJSPlayerWrapper implements PlayerWrapper { } load(playlistUrl: string, options: { loop: boolean }): void { + // Check if this is likely a preview (from JumbotronSection) + this._isPreview = playlistUrl.includes('/episode/') && options.loop === true; + + // Create HLS player with appropriate buffer settings + this._player = new HlsJs({ + enableWorker: false, + // Use smaller buffer for previews + maxBufferLength: this._isPreview ? 10 : 30, + maxMaxBufferLength: this._isPreview ? 10 : 30, + // Limit backbuffer for previews + backBufferLength: this._isPreview ? 5 : 10, + }); + this._player.attachMedia(this.videoElement); this.videoElement.loop = options.loop; + + // For previews, stop loading after initial segments + if (this._isPreview) { + this._player.on(HlsJs.Events.FRAG_LOADED, () => { + if (this._player && this.videoElement.buffered.length > 0 && + this.videoElement.buffered.end(0) > 10) { + // Stop loading more fragments after we have 10 seconds + this._player.stopLoad(); + } + }); + } + this._player.loadSource(playlistUrl); - } + + // IntersectionObserverの設定 + this._observer = new IntersectionObserver( + (entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + void this.videoElement.play(); + } else { + this.videoElement.pause(); + + // For previews, also stop loading when out of view + if (this._isPreview && this._player) { + this._player.stopLoad(); + } + } + }); + }, + { threshold: 0.1 } // 10%以上がビューポート内に入ったら再生 + ); + + // 動画要素がDOMに追加されるまで待つ + setTimeout(() => { + if (this._observer) { + this._observer.observe(this.videoElement); + } + }, 0); + } + play(): void { void this.videoElement.play(); } + pause(): void { this.videoElement.pause(); } + seekTo(second: number): void { this.videoElement.currentTime = second; } + setMuted(muted: boolean): void { this.videoElement.muted = muted; } + destory(): void { - this._player.destroy(); - } -} - -interface VhsConfig { - GOAL_BUFFER_LENGTH: number; - MAX_GOAL_BUFFER_LENGTH: number; -} - -class VideoJSPlayerWrapper implements PlayerWrapper { - readonly videoElement = Object.assign(document.createElement('video'), { - autoplay: true, - controls: false, - muted: true, - volume: 0.25, - }); - private _player = videojs(this.videoElement); - readonly playerType: PlayerType.VideoJS; - - constructor(playerType: PlayerType.VideoJS) { - const vhsConfig = (videojs as unknown as { Vhs: VhsConfig }).Vhs; - vhsConfig.GOAL_BUFFER_LENGTH = 50; - vhsConfig.MAX_GOAL_BUFFER_LENGTH = 50; - this.playerType = playerType; - } - - get currentTime(): number { - return this._player.currentTime() ?? 0; - } - get paused(): boolean { - return this._player.paused(); - } - get duration(): number { - return this._player.duration() ?? 0; - } - get muted(): boolean { - return this._player.muted() ?? true; - } - - load(playlistUrl: string, options: { loop: boolean }): void { - this.videoElement.loop = options.loop; - this._player.src({ - src: playlistUrl, - type: 'application/x-mpegURL', - }); - } - play(): void { - void this.videoElement.play(); - } - pause(): void { - this.videoElement.pause(); - } - seekTo(second: number): void { - this.videoElement.currentTime = second; - } - setMuted(muted: boolean): void { - this._player.muted(muted); - } - destory(): void { - this._player.dispose(); - } -} - -export const createPlayer = (playerType: PlayerType): PlayerWrapper => { - switch (playerType) { - case PlayerType.ShakaPlayer: { - return new ShakaPlayerWrapper(playerType); - } - case PlayerType.HlsJS: { - return new HlsJSPlayerWrapper(playerType); - } - case PlayerType.VideoJS: { - return new VideoJSPlayerWrapper(playerType); + if (this._observer) { + this._observer.unobserve(this.videoElement); + this._observer.disconnect(); + this._observer = null; } - default: { - playerType satisfies never; - throw new Error('Invalid player type.'); + if (this._player) { + this._player.stopLoad(); + this._player.destroy(); + this._player = null; } } +} + +export const createPlayer = (): PlayerWrapper => { + return new HlsJSPlayerWrapper(); }; diff --git a/workspaces/client/src/features/program/hooks/useProgramById.ts b/workspaces/client/src/features/program/hooks/useProgramById.ts index 7592980d3..3143872d9 100644 --- a/workspaces/client/src/features/program/hooks/useProgramById.ts +++ b/workspaces/client/src/features/program/hooks/useProgramById.ts @@ -5,9 +5,7 @@ interface Params { } export function useProgramById({ programId }: Params) { - const state = useStore((s) => s); + const state = useStore((s) => s.features.program.programs[programId]); - const program = state.features.program.programs[programId]; - - return program; + return state; } diff --git a/workspaces/client/src/features/program/services/programService.ts b/workspaces/client/src/features/program/services/programService.ts index dc17a25c0..dcbd8a4fb 100644 --- a/workspaces/client/src/features/program/services/programService.ts +++ b/workspaces/client/src/features/program/services/programService.ts @@ -1,21 +1,23 @@ import { createFetch, createSchema } from '@better-fetch/fetch'; import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; +import { + getProgramByIdRequestParams, + getProgramByIdResponse, + getProgramsRequestQuery, + getProgramsResponse, +} from '@wsh-2025/schema/src/openapi/schema'; import * as batshit from '@yornaath/batshit'; -import { schedulePlugin } from '@wsh-2025/client/src/features/requests/schedulePlugin'; - const $fetch = createFetch({ - baseURL: process.env['API_BASE_URL'] ?? '/api', - plugins: [schedulePlugin], + baseURL: import.meta.env['VITE_API_BASE_URL'] ?? 'http://localhost:8000/api', schema: createSchema({ '/programs': { - output: schema.getProgramsResponse, - query: schema.getProgramsRequestQuery, + output: getProgramsResponse, + query: getProgramsRequestQuery, }, '/programs/:episodeId': { - output: schema.getProgramByIdResponse, - params: schema.getProgramByIdRequestParams, + output: getProgramByIdResponse, + params: getProgramByIdRequestParams, }, }), throw: true, @@ -46,17 +48,25 @@ const batcher = batshit.create({ interface ProgramService { fetchProgramById: (query: { programId: string; - }) => Promise>; - fetchPrograms: () => Promise>; + }) => Promise | null>; + fetchPrograms: () => Promise>; } export const programService: ProgramService = { async fetchProgramById({ programId }) { - const channel = await batcher.fetch({ programId }); - return channel; + try { + const channel = await batcher.fetch({ programId }); + return channel; + } catch { + return null; + } }, async fetchPrograms() { - const data = await $fetch('/programs', { query: {} }); - return data; + try { + const data = await $fetch('/programs', { query: {} }); + return data; + } catch { + return []; + } }, }; diff --git a/workspaces/client/src/features/program/stores/createProgramStoreSlice.ts b/workspaces/client/src/features/program/stores/createProgramStoreSlice.ts index 46d1a935a..17471979a 100644 --- a/workspaces/client/src/features/program/stores/createProgramStoreSlice.ts +++ b/workspaces/client/src/features/program/stores/createProgramStoreSlice.ts @@ -1,42 +1,49 @@ import { lens } from '@dhmk/zustand-lens'; import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; -import { produce } from 'immer'; +import { getProgramByIdResponse, getProgramsResponse } from '@wsh-2025/schema/src/openapi/schema'; import { programService } from '@wsh-2025/client/src/features/program/services/programService'; type ProgramId = string; interface ProgramState { - programs: Record>; + programs: Record>; } interface ProgramActions { fetchProgramById: (params: { programId: ProgramId; - }) => Promise>; - fetchPrograms: () => Promise>; + }) => Promise | null>; + fetchPrograms: () => Promise>; } export const createProgramStoreSlice = () => { return lens((set) => ({ fetchProgramById: async ({ programId }) => { const program = await programService.fetchProgramById({ programId }); + if (!program) return null; set((state) => { - return produce(state, (draft) => { - draft.programs[program.id] = program; - }); + return { + ...state, + programs: { + ...state.programs, + [program.id]: program, + }, + }; }); return program; }, fetchPrograms: async () => { const programs = await programService.fetchPrograms(); set((state) => { - return produce(state, (draft) => { - for (const program of programs) { - draft.programs[program.id] = program; - } - }); + const updatedPrograms = { ...state.programs }; + for (const program of programs) { + updatedPrograms[program.id] = program; + } + return { + ...state, + programs: updatedPrograms, + }; }); return programs; }, diff --git a/workspaces/client/src/features/recommended/components/CarouselSection.tsx b/workspaces/client/src/features/recommended/components/CarouselSection.tsx index e81aa410e..49681225b 100644 --- a/workspaces/client/src/features/recommended/components/CarouselSection.tsx +++ b/workspaces/client/src/features/recommended/components/CarouselSection.tsx @@ -1,22 +1,18 @@ import { ElementScrollRestoration } from '@epic-web/restore-scroll'; import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; +import { getRecommendedModulesResponse } from '@wsh-2025/schema/src/openapi/schema'; import { ArrayValues } from 'type-fest'; -import { useMergeRefs } from 'use-callback-ref'; import { EpisodeItem } from '@wsh-2025/client/src/features/recommended/components/EpisodeItem'; import { SeriesItem } from '@wsh-2025/client/src/features/recommended/components/SeriesItem'; -import { useCarouselItemWidth } from '@wsh-2025/client/src/features/recommended/hooks/useCarouselItemWidth'; import { useScrollSnap } from '@wsh-2025/client/src/features/recommended/hooks/useScrollSnap'; interface Props { - module: ArrayValues>; + module: ArrayValues>; } export const CarouselSection = ({ module }: Props) => { - const containerRefForScrollSnap = useScrollSnap({ scrollPadding: 24 }); - const { ref: containerRefForItemWidth, width: itemWidth } = useCarouselItemWidth(); - const mergedRef = useMergeRefs([containerRefForItemWidth, containerRefForScrollSnap]); + const containerRef = useScrollSnap({ scrollPadding: 24 }); return ( <> @@ -24,12 +20,12 @@ export const CarouselSection = ({ module }: Props) => {

{module.title}

{module.items.map((item) => ( -
+
{item.series != null ? : null} {item.episode != null ? : null}
diff --git a/workspaces/client/src/features/recommended/components/EpisodeItem.tsx b/workspaces/client/src/features/recommended/components/EpisodeItem.tsx index 74b08745c..9a1ec516a 100644 --- a/workspaces/client/src/features/recommended/components/EpisodeItem.tsx +++ b/workspaces/client/src/features/recommended/components/EpisodeItem.tsx @@ -2,8 +2,6 @@ import Ellipsis from 'react-ellipsis-component'; import { Flipped } from 'react-flip-toolkit'; import { NavLink } from 'react-router'; -import { Hoverable } from '@wsh-2025/client/src/features/layout/components/Hoverable'; - interface Props { episode: { id: string; @@ -18,14 +16,13 @@ interface Props { export const EpisodeItem = ({ episode }: Props) => { return ( - - + {({ isTransitioning }) => { return ( <>
- + {episode.premium ? ( @@ -46,6 +43,5 @@ export const EpisodeItem = ({ episode }: Props) => { ); }} - ); }; diff --git a/workspaces/client/src/features/recommended/components/JumbotronSection.tsx b/workspaces/client/src/features/recommended/components/JumbotronSection.tsx index 638c9cfd6..bf8f017bb 100644 --- a/workspaces/client/src/features/recommended/components/JumbotronSection.tsx +++ b/workspaces/client/src/features/recommended/components/JumbotronSection.tsx @@ -1,6 +1,6 @@ import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; -import { useRef } from 'react'; +import { getRecommendedModulesResponse } from '@wsh-2025/schema/src/openapi/schema'; +import { useEffect, useRef, useState } from 'react'; import Ellipsis from 'react-ellipsis-component'; import { Flipped } from 'react-flip-toolkit'; import { NavLink } from 'react-router'; @@ -8,55 +8,75 @@ import invariant from 'tiny-invariant'; import { ArrayValues } from 'type-fest'; import { Player } from '../../player/components/Player'; -import { PlayerType } from '../../player/constants/player_type'; import { PlayerWrapper } from '../../player/interfaces/player_wrapper'; -import { Hoverable } from '@wsh-2025/client/src/features/layout/components/Hoverable'; - interface Props { - module: ArrayValues>; + module: ArrayValues>; } export const JumbotronSection = ({ module }: Props) => { const playerRef = useRef(null); + const containerRef = useRef(null); + const [isVisible, setIsVisible] = useState(false); const episode = module.items[0]?.episode; invariant(episode); + // ビューポート内に入った時だけプレーヤーをロードする + useEffect(() => { + if (!containerRef.current) return; + + const observer = new IntersectionObserver( + (entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + setIsVisible(true); + } + }); + }, + { threshold: 0.1 } + ); + + observer.observe(containerRef.current); + + return () => { + observer.disconnect(); + }; + }, []); + return ( - - - {({ isTransitioning }) => { - return ( - <> -
-
- -
-
- -
+ + {({ isTransitioning }) => { + return ( + <> +
+
+ +
+
+
+
- -
+ +
+ {isVisible && ( -
-
- - ); - }} - - + )} +
+
+ + ); + }} +
); }; diff --git a/workspaces/client/src/features/recommended/components/RecommendedSection.tsx b/workspaces/client/src/features/recommended/components/RecommendedSection.tsx index d3e287ef0..c1d80197e 100644 --- a/workspaces/client/src/features/recommended/components/RecommendedSection.tsx +++ b/workspaces/client/src/features/recommended/components/RecommendedSection.tsx @@ -1,12 +1,12 @@ import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; +import { getRecommendedModulesResponse } from '@wsh-2025/schema/src/openapi/schema'; import { ArrayValues } from 'type-fest'; import { CarouselSection } from '@wsh-2025/client/src/features/recommended/components/CarouselSection'; import { JumbotronSection } from '@wsh-2025/client/src/features/recommended/components/JumbotronSection'; interface Props { - module: ArrayValues>; + module: ArrayValues>; } export const RecommendedSection = ({ module }: Props) => { diff --git a/workspaces/client/src/features/recommended/components/SeriesItem.tsx b/workspaces/client/src/features/recommended/components/SeriesItem.tsx index 2477b7a97..8f2a532ef 100644 --- a/workspaces/client/src/features/recommended/components/SeriesItem.tsx +++ b/workspaces/client/src/features/recommended/components/SeriesItem.tsx @@ -2,8 +2,6 @@ import Ellipsis from 'react-ellipsis-component'; import { Flipped } from 'react-flip-toolkit'; import { NavLink } from 'react-router'; -import { Hoverable } from '@wsh-2025/client/src/features/layout/components/Hoverable'; - interface Props { series: { id: string; @@ -14,14 +12,13 @@ interface Props { export const SeriesItem = ({ series }: Props) => { return ( - - + {({ isTransitioning }) => { return ( <>
- +
@@ -33,6 +30,5 @@ export const SeriesItem = ({ series }: Props) => { ); }} - ); }; diff --git a/workspaces/client/src/features/recommended/hooks/useCarouselItemWidth.ts b/workspaces/client/src/features/recommended/hooks/useCarouselItemWidth.ts deleted file mode 100644 index 83a6afe94..000000000 --- a/workspaces/client/src/features/recommended/hooks/useCarouselItemWidth.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { useEffect, useRef } from 'react'; -import { useUpdate } from 'react-use'; - -const MIN_WIDTH = 276; -const GAP = 12; - -// repeat(auto-fill, minmax(276px, 1fr)) を計算で求める -export function useCarouselItemWidth() { - const forceUpdate = useUpdate(); - const containerRef = useRef(null); - - useEffect(() => { - const interval = setInterval(function tick() { - forceUpdate(); - }, 250); - return () => { - clearInterval(interval); - }; - }, []); - - if (containerRef.current == null) { - return { ref: containerRef, width: MIN_WIDTH }; - } - - const styles = window.getComputedStyle(containerRef.current); - const innerWidth = containerRef.current.clientWidth - parseInt(styles.paddingLeft) - parseInt(styles.paddingRight); - const itemCount = Math.max(0, Math.floor((innerWidth + GAP) / (MIN_WIDTH + GAP))); - const itemWidth = Math.floor((innerWidth + GAP) / itemCount - GAP); - - return { ref: containerRef, width: itemWidth }; -} diff --git a/workspaces/client/src/features/recommended/hooks/useRecommended.ts b/workspaces/client/src/features/recommended/hooks/useRecommended.ts index 97ee95c07..96a9b09cb 100644 --- a/workspaces/client/src/features/recommended/hooks/useRecommended.ts +++ b/workspaces/client/src/features/recommended/hooks/useRecommended.ts @@ -5,12 +5,11 @@ interface Params { } export function useRecommended({ referenceId }: Params) { - const state = useStore((s) => s); - - const moduleIds = state.features.recommended.references[referenceId]; + const moduleIds = useStore((s) => s.features.recommended.references[referenceId]); + const _modules = useStore((s) => s.features.recommended.recommendedModules); const modules = (moduleIds ?? []) - .map((moduleId) => state.features.recommended.recommendedModules[moduleId]) + .map((moduleId) => _modules[moduleId]) .filter((m: T): m is NonNullable => m != null); return modules; diff --git a/workspaces/client/src/features/recommended/services/recommendedService.ts b/workspaces/client/src/features/recommended/services/recommendedService.ts index 494ad911f..495049b97 100644 --- a/workspaces/client/src/features/recommended/services/recommendedService.ts +++ b/workspaces/client/src/features/recommended/services/recommendedService.ts @@ -1,15 +1,12 @@ import { createFetch, createSchema } from '@better-fetch/fetch'; import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; - -import { schedulePlugin } from '@wsh-2025/client/src/features/requests/schedulePlugin'; +import { getRecommendedModulesResponse } from '@wsh-2025/schema/src/openapi/schema'; const $fetch = createFetch({ - baseURL: process.env['API_BASE_URL'] ?? '/api', - plugins: [schedulePlugin], + baseURL: import.meta.env['VITE_API_BASE_URL'] ?? 'http://localhost:8000/api', schema: createSchema({ '/recommended/:referenceId': { - output: schema.getRecommendedModulesResponse, + output: getRecommendedModulesResponse, }, }), throw: true, @@ -18,14 +15,19 @@ const $fetch = createFetch({ interface RecommendedService { fetchRecommendedModulesByReferenceId: (params: { referenceId: string; - }) => Promise>; + }) => Promise>; } export const recommendedService: RecommendedService = { async fetchRecommendedModulesByReferenceId({ referenceId }) { - const data = await $fetch('/recommended/:referenceId', { - params: { referenceId }, - }); - return data; + try { + const data = await $fetch('/recommended/:referenceId', { + params: { referenceId }, + }); + return data; + } catch (e) { + console.log(e); + return []; + } }, }; diff --git a/workspaces/client/src/features/recommended/stores/createRecomendedStoreSlice.ts b/workspaces/client/src/features/recommended/stores/createRecomendedStoreSlice.ts index aa2c858fc..047e549f4 100644 --- a/workspaces/client/src/features/recommended/stores/createRecomendedStoreSlice.ts +++ b/workspaces/client/src/features/recommended/stores/createRecomendedStoreSlice.ts @@ -1,7 +1,6 @@ import { lens } from '@dhmk/zustand-lens'; import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; -import { produce } from 'immer'; +import { getRecommendedModulesResponse } from '@wsh-2025/schema/src/openapi/schema'; import { ArrayValues } from 'type-fest'; import { recommendedService } from '@wsh-2025/client/src/features/recommended/services/recommendedService'; @@ -12,7 +11,7 @@ type RecommendedModuleId = string; interface RecommendedState { recommendedModules: Record< RecommendedModuleId, - ArrayValues> + ArrayValues> >; references: Record; } @@ -20,7 +19,7 @@ interface RecommendedState { interface RecommendedActions { fetchRecommendedModulesByReferenceId: (params: { referenceId: ReferenceId; - }) => Promise>; + }) => Promise>; } export const createRecommendedStoreSlice = () => { @@ -28,12 +27,18 @@ export const createRecommendedStoreSlice = () => { fetchRecommendedModulesByReferenceId: async ({ referenceId }) => { const modules = await recommendedService.fetchRecommendedModulesByReferenceId({ referenceId }); set((state) => { - return produce(state, (draft) => { - draft.references[referenceId] = modules.map((module) => module.id); - for (const module of modules) { - draft.recommendedModules[module.id] = module; + const updatedRecommendedModules = { ...state.recommendedModules }; + for (const module of modules) { + updatedRecommendedModules[module.id] = module; + } + return { + ...state, + recommendedModules: updatedRecommendedModules, + references: { + ...state.references, + [referenceId]: modules.map((module) => module.id) } - }); + }; }); return modules; }, diff --git a/workspaces/client/src/features/requests/schedulePlugin.ts b/workspaces/client/src/features/requests/schedulePlugin.ts deleted file mode 100644 index 0c6cb6c6d..000000000 --- a/workspaces/client/src/features/requests/schedulePlugin.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { BetterFetchPlugin } from '@better-fetch/fetch'; - -export const schedulePlugin = { - hooks: { - onRequest: async (request) => { - const scheduler = typeof window !== 'undefined' ? window.scheduler : undefined; - - if (scheduler) { - return await scheduler.postTask(() => request, { delay: 1000 }); - } else { - return await new Promise((resolve) => { - queueMicrotask(() => { - resolve(request); - }); - }); - } - }, - }, - id: 'schedulePlugin', - name: 'Schedule Plugin', -} satisfies BetterFetchPlugin; diff --git a/workspaces/client/src/features/series/components/SeriesEposideItem.tsx b/workspaces/client/src/features/series/components/SeriesEposideItem.tsx index 0a0067d95..3235b1a19 100644 --- a/workspaces/client/src/features/series/components/SeriesEposideItem.tsx +++ b/workspaces/client/src/features/series/components/SeriesEposideItem.tsx @@ -2,8 +2,6 @@ import Ellipsis from 'react-ellipsis-component'; import { Flipped } from 'react-flip-toolkit'; import { NavLink } from 'react-router'; -import { Hoverable } from '@wsh-2025/client/src/features/layout/components/Hoverable'; - interface Props { episode: { description: string; @@ -17,10 +15,9 @@ interface Props { export const SeriesEpisodeItem = ({ episode, selected }: Props) => { return ( - {({ isTransitioning }) => { @@ -28,7 +25,7 @@ export const SeriesEpisodeItem = ({ episode, selected }: Props) => { <>
- + {episode.premium ? ( @@ -50,6 +47,5 @@ export const SeriesEpisodeItem = ({ episode, selected }: Props) => { ); }} - ); }; diff --git a/workspaces/client/src/features/series/hooks/useSeriesById.ts b/workspaces/client/src/features/series/hooks/useSeriesById.ts deleted file mode 100644 index 03b5d2c0e..000000000 --- a/workspaces/client/src/features/series/hooks/useSeriesById.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { useStore } from '@wsh-2025/client/src/app/StoreContext'; - -interface Params { - seriesId: string; -} - -export function useSeriesById({ seriesId }: Params) { - const state = useStore((s) => s); - - const series = state.features.series.series[seriesId]; - - return series; -} diff --git a/workspaces/client/src/features/series/services/seriesService.ts b/workspaces/client/src/features/series/services/seriesService.ts index 2c27f2e1a..026653c8e 100644 --- a/workspaces/client/src/features/series/services/seriesService.ts +++ b/workspaces/client/src/features/series/services/seriesService.ts @@ -1,20 +1,17 @@ import { createFetch, createSchema } from '@better-fetch/fetch'; import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; +import { getSeriesByIdResponse, getSeriesRequestQuery, getSeriesResponse } from '@wsh-2025/schema/src/openapi/schema'; import * as batshit from '@yornaath/batshit'; -import { schedulePlugin } from '@wsh-2025/client/src/features/requests/schedulePlugin'; - const $fetch = createFetch({ - baseURL: process.env['API_BASE_URL'] ?? '/api', - plugins: [schedulePlugin], + baseURL: import.meta.env['VITE_API_BASE_URL'] ?? 'http://localhost:8000/api', schema: createSchema({ '/series': { - output: schema.getSeriesResponse, - query: schema.getSeriesRequestQuery, + output: getSeriesResponse, + query: getSeriesRequestQuery, }, '/series/:seriesId': { - output: schema.getSeriesByIdResponse, + output: getSeriesByIdResponse, }, }), throw: true, @@ -43,19 +40,27 @@ const batcher = batshit.create({ }); interface SeriesService { - fetchSeries: () => Promise>; + fetchSeries: () => Promise>; fetchSeriesById: (params: { seriesId: string; - }) => Promise>; + }) => Promise | null>; } export const seriesService: SeriesService = { async fetchSeries() { - const data = await $fetch('/series', { query: {} }); - return data; + try { + const data = await $fetch('/series', { query: {} }); + return data; + } catch { + return []; + } }, async fetchSeriesById({ seriesId }) { - const data = await batcher.fetch({ seriesId }); - return data; + try { + const data = await batcher.fetch({ seriesId }); + return data; + } catch { + return null; + } }, }; diff --git a/workspaces/client/src/features/series/stores/createSeriesStoreSlice.ts b/workspaces/client/src/features/series/stores/createSeriesStoreSlice.ts index 9385fb5a5..6b5ad7c38 100644 --- a/workspaces/client/src/features/series/stores/createSeriesStoreSlice.ts +++ b/workspaces/client/src/features/series/stores/createSeriesStoreSlice.ts @@ -1,21 +1,20 @@ import { lens } from '@dhmk/zustand-lens'; import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; -import { produce } from 'immer'; +import { getSeriesByIdResponse, getSeriesResponse } from '@wsh-2025/schema/src/openapi/schema'; import { seriesService } from '@wsh-2025/client/src/features/series/services/seriesService'; type SeriesId = string; interface SeriesState { - series: Record>; + series: Record>; } interface SeriesActions { - fetchSeries: () => Promise>; + fetchSeries: () => Promise>; fetchSeriesById: (params: { seriesId: SeriesId; - }) => Promise>; + }) => Promise | null>; } export const createSeriesStoreSlice = () => { @@ -23,20 +22,28 @@ export const createSeriesStoreSlice = () => { fetchSeries: async () => { const series = await seriesService.fetchSeries(); set((state) => { - return produce(state, (draft) => { - for (const s of series) { - draft.series[s.id] = s; - } - }); + const updatedSeries = { ...state.series }; + for (const s of series) { + updatedSeries[s.id] = s; + } + return { + ...state, + series: updatedSeries, + }; }); return series; }, fetchSeriesById: async ({ seriesId }) => { const series = await seriesService.fetchSeriesById({ seriesId }); + if (!series) return null; set((state) => { - return produce(state, (draft) => { - draft.series[seriesId] = series; - }); + return { + ...state, + series: { + ...state.series, + [seriesId]: series, + }, + }; }); return series; }, diff --git a/workspaces/client/src/features/timetable/hooks/useTimetable.ts b/workspaces/client/src/features/timetable/hooks/useTimetable.ts index dff10c5cd..9ceef3ec5 100644 --- a/workspaces/client/src/features/timetable/hooks/useTimetable.ts +++ b/workspaces/client/src/features/timetable/hooks/useTimetable.ts @@ -1,4 +1,3 @@ -import { DateTime } from 'luxon'; import { ArrayValues } from 'type-fest'; import { useStore } from '@wsh-2025/client/src/app/StoreContext'; @@ -6,25 +5,30 @@ import { useStore } from '@wsh-2025/client/src/app/StoreContext'; type ChannelId = string; export function useTimetable() { - const state = useStore((s) => s); - - const channels = Object.values(state.features.channel.channels); - const programs = Object.values(state.features.timetable.programs); - - const record: Record[]> = {}; - - for (const channel of channels) { - const filteredPrograms = []; - - for (const program of programs) { - if (program.channelId === channel.id) { - filteredPrograms.push(program); - } + const channels = useStore((s) => Object.values(s.features.channel.channels)); + const programs = useStore((s) => Object.values(s.features.timetable.programs)); + + const record: Record< + ChannelId, + { + id: ChannelId; + logoUrl: string; + name: string; + programs: ArrayValues[]; } + > = {}; - record[channel.id] = filteredPrograms.sort((a, b) => { - return DateTime.fromISO(a.startAt).toMillis() - DateTime.fromISO(b.startAt).toMillis(); - }); + for (const channel of channels) { + const filteredPrograms = programs + .filter((program) => program.channelId === channel.id) + .sort((a, b) => new Date(a.startAt).getTime() - new Date(b.startAt).getTime()); + + record[channel.id] = { + id: channel.id, + logoUrl: channel.logoUrl, + name: channel.name, + programs: filteredPrograms, + }; } return record; diff --git a/workspaces/client/src/features/timetable/services/timetableService.ts b/workspaces/client/src/features/timetable/services/timetableService.ts deleted file mode 100644 index e7137d6b0..000000000 --- a/workspaces/client/src/features/timetable/services/timetableService.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { createFetch, createSchema } from '@better-fetch/fetch'; -import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; - -import { schedulePlugin } from '@wsh-2025/client/src/features/requests/schedulePlugin'; - -const $fetch = createFetch({ - baseURL: process.env['API_BASE_URL'] ?? '/api', - plugins: [schedulePlugin], - schema: createSchema({ - '/timetable': { - output: schema.getTimetableResponse, - query: schema.getTimetableRequestQuery, - }, - }), - throw: true, -}); - -interface TimetableService { - fetchTimetable: ( - params: StandardSchemaV1.InferOutput, - ) => Promise>; -} - -export const timetableService: TimetableService = { - async fetchTimetable({ since, until }) { - const data = await $fetch('/timetable', { - query: { since, until }, - }); - return data; - }, -}; diff --git a/workspaces/client/src/features/timetable/stores/createTimetableStoreSlice.ts b/workspaces/client/src/features/timetable/stores/createTimetableStoreSlice.ts deleted file mode 100644 index 7413bd96a..000000000 --- a/workspaces/client/src/features/timetable/stores/createTimetableStoreSlice.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { lens } from '@dhmk/zustand-lens'; -import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; -import { produce } from 'immer'; -import { ArrayValues } from 'type-fest'; - -import { timetableService } from '@wsh-2025/client/src/features/timetable/services/timetableService'; - -type ProgramId = string; - -interface TimetableState { - programs: Record>>; -} - -interface TimetableActions { - fetchTimetable: (params: { - since: string; - until: string; - }) => Promise>; -} - -export const createTimetableStoreSlice = () => { - return lens((set) => ({ - fetchTimetable: async ({ since, until }) => { - const programs = await timetableService.fetchTimetable({ since, until }); - set((state) => { - return produce(state, (draft) => { - draft.programs = {}; - for (const program of programs) { - draft.programs[program.id] = program; - } - }); - }); - return programs; - }, - programs: {}, - })); -}; diff --git a/workspaces/client/src/main.tsx b/workspaces/client/src/main.tsx index 601b7a6a5..76564afcf 100644 --- a/workspaces/client/src/main.tsx +++ b/workspaces/client/src/main.tsx @@ -1,24 +1,29 @@ -import '@wsh-2025/client/src/setups/polyfills'; -import '@wsh-2025/client/src/setups/luxon'; -import '@wsh-2025/client/src/setups/unocss'; +// eslint-disable-next-line import/no-unresolved +import 'virtual:uno.css'; +import '@unocss/reset/tailwind-compat.css'; import { StrictMode } from 'react'; import { hydrateRoot } from 'react-dom/client'; -import { createBrowserRouter, HydrationState, RouterProvider } from 'react-router'; +import { createBrowserRouter } from 'react-router'; +import { RouterProvider } from 'react-router/dom'; import { StoreProvider } from '@wsh-2025/client/src/app/StoreContext'; import { createRoutes } from '@wsh-2025/client/src/app/createRoutes'; import { createStore } from '@wsh-2025/client/src/app/createStore'; -declare global { - var __zustandHydrationData: unknown; - var __staticRouterHydrationData: HydrationState; -} - function main() { + // ストアの作成 const store = createStore({}); + + // ルーターの作成 const router = createBrowserRouter(createRoutes(store), {}); + // ルート要素の取得 + const rootElement = document.getElementById('root'); + if (!rootElement) { + throw new Error('Root element not found'); + } + hydrateRoot( document, @@ -27,6 +32,20 @@ function main() { , ); + // アプリケーションのレンダリング + // createRoot(rootElement).render( + // + // store}> + // + // + // , + // ); } -document.addEventListener('DOMContentLoaded', main); +// DOMContentLoadedイベントでアプリケーションを初期化 +if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', main); +} else { + // DOMがすでに読み込まれている場合は直接実行 + main(); +} diff --git a/workspaces/client/src/pages/episode/components/EpisodePage.tsx b/workspaces/client/src/pages/episode/components/EpisodePage.tsx index 075eacc48..a76b7d8dd 100644 --- a/workspaces/client/src/pages/episode/components/EpisodePage.tsx +++ b/workspaces/client/src/pages/episode/components/EpisodePage.tsx @@ -1,42 +1,48 @@ +import { StandardSchemaV1 } from '@standard-schema/spec'; +import { getEpisodeByIdResponse, getRecommendedModulesResponse } from '@wsh-2025/schema/src/openapi/schema'; import { Suspense } from 'react'; import Ellipsis from 'react-ellipsis-component'; import { Flipped } from 'react-flip-toolkit'; import { Params, useParams } from 'react-router'; import invariant from 'tiny-invariant'; -import { createStore } from '@wsh-2025/client/src/app/createStore'; import { useAuthActions } from '@wsh-2025/client/src/features/auth/hooks/useAuthActions'; import { useAuthUser } from '@wsh-2025/client/src/features/auth/hooks/useAuthUser'; -import { useEpisodeById } from '@wsh-2025/client/src/features/episode/hooks/useEpisodeById'; +import { authService } from '@wsh-2025/client/src/features/auth/services/authService'; +import { episodeService } from '@wsh-2025/client/src/features/episode/services/episodeService'; import { AspectRatio } from '@wsh-2025/client/src/features/layout/components/AspectRatio'; import { Player } from '@wsh-2025/client/src/features/player/components/Player'; -import { PlayerType } from '@wsh-2025/client/src/features/player/constants/player_type'; import { RecommendedSection } from '@wsh-2025/client/src/features/recommended/components/RecommendedSection'; -import { useRecommended } from '@wsh-2025/client/src/features/recommended/hooks/useRecommended'; +import { recommendedService } from '@wsh-2025/client/src/features/recommended/services/recommendedService'; import { SeriesEpisodeList } from '@wsh-2025/client/src/features/series/components/SeriesEpisodeList'; import { PlayerController } from '@wsh-2025/client/src/pages/episode/components/PlayerController'; import { usePlayerRef } from '@wsh-2025/client/src/pages/episode/hooks/usePlayerRef'; -export const prefetch = async (store: ReturnType, { episodeId }: Params) => { +export const loader = async ({ params: { episodeId } }: { params: Params }) => { invariant(episodeId); - const episode = await store.getState().features.episode.fetchEpisodeById({ episodeId }); - const modules = await store - .getState() - .features.recommended.fetchRecommendedModulesByReferenceId({ referenceId: episodeId }); - return { episode, modules }; + const [episode, modules, user] = await Promise.all([ + episodeService.fetchEpisodeById({ episodeId }), + recommendedService.fetchRecommendedModulesByReferenceId({ referenceId: episodeId }), + authService.fetchUser(), + ]); + return { episode, modules, user }; }; -export const EpisodePage = () => { +export default function EpisodePage({ + loaderData, +}: { + loaderData: { + episode: StandardSchemaV1.InferOutput; + modules: StandardSchemaV1.InferOutput; + }; +}) { const authActions = useAuthActions(); - const user = useAuthUser(); const { episodeId } = useParams(); invariant(episodeId); - const episode = useEpisodeById({ episodeId }); - invariant(episode); - - const modules = useRecommended({ referenceId: episodeId }); + const { episode, modules } = loaderData; + const user = useAuthUser(); const playerRef = usePlayerRef(); @@ -51,7 +57,7 @@ export const EpisodePage = () => {
{isSignInRequired ? (
- +

@@ -74,6 +80,7 @@ export const EpisodePage = () => {

@@ -86,7 +93,6 @@ export const EpisodePage = () => { @@ -131,4 +137,4 @@ export const EpisodePage = () => {
); -}; +} diff --git a/workspaces/client/src/pages/episode/components/PlayerController.tsx b/workspaces/client/src/pages/episode/components/PlayerController.tsx index f090a17a9..c6516b3f2 100644 --- a/workspaces/client/src/pages/episode/components/PlayerController.tsx +++ b/workspaces/client/src/pages/episode/components/PlayerController.tsx @@ -1,10 +1,15 @@ -import * as Slider from '@radix-ui/react-slider'; +import { Range, Root, Thumb, Track } from '@radix-ui/react-slider'; import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; -import { Duration } from 'luxon'; +import { getEpisodeByIdResponse } from '@wsh-2025/schema/src/openapi/schema'; import invariant from 'tiny-invariant'; -import { Hoverable } from '@wsh-2025/client/src/features/layout/components/Hoverable'; +// Helper function to format seconds into mm:ss format +const formatTime = (seconds: number): string => { + const minutes = Math.floor(seconds / 60); + const remainingSeconds = Math.floor(seconds % 60); + return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`; +}; + import { SeekThumbnail } from '@wsh-2025/client/src/pages/episode/components/SeekThumbnail'; import { useCurrentTime } from '@wsh-2025/client/src/pages/episode/hooks/useCurrentTime'; import { useDuration } from '@wsh-2025/client/src/pages/episode/hooks/useDuration'; @@ -12,7 +17,7 @@ import { useMuted } from '@wsh-2025/client/src/pages/episode/hooks/useMuted'; import { usePlaying } from '@wsh-2025/client/src/pages/episode/hooks/usePlaying'; interface Props { - episode: StandardSchemaV1.InferOutput; + episode: StandardSchemaV1.InferOutput; } export const PlayerController = ({ episode }: Props) => { @@ -31,7 +36,7 @@ export const PlayerController = ({ episode }: Props) => {
- { updateCurrentTime(t); }} > - - - - - + + + + +
- - - {Duration.fromObject({ seconds: currentTime }).toFormat('mm:ss')} + {formatTime(currentTime)} {' / '} - {Duration.fromObject({ seconds: duration }).toFormat('mm:ss')} + {formatTime(duration)}
- -
diff --git a/workspaces/client/src/pages/episode/components/SeekThumbnail.tsx b/workspaces/client/src/pages/episode/components/SeekThumbnail.tsx index b706a379b..c66ff40e9 100644 --- a/workspaces/client/src/pages/episode/components/SeekThumbnail.tsx +++ b/workspaces/client/src/pages/episode/components/SeekThumbnail.tsx @@ -1,21 +1,21 @@ import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; +import { getEpisodeByIdResponse } from '@wsh-2025/schema/src/openapi/schema'; import { useRef } from 'react'; -import { usePointer } from '@wsh-2025/client/src/features/layout/hooks/usePointer'; +import { useSubscribePointer } from '@wsh-2025/client/src/features/layout/hooks/useSubscribePointer'; import { useDuration } from '@wsh-2025/client/src/pages/episode/hooks/useDuration'; import { useSeekThumbnail } from '@wsh-2025/client/src/pages/episode/hooks/useSeekThumbnail'; const SEEK_THUMBNAIL_WIDTH = 160; interface Props { - episode: StandardSchemaV1.InferOutput; + episode: StandardSchemaV1.InferOutput; } export const SeekThumbnail = ({ episode }: Props) => { const ref = useRef(null); const seekThumbnail = useSeekThumbnail({ episode }); - const pointer = usePointer(); + const pointer = useSubscribePointer(); const duration = useDuration(); const elementRect = ref.current?.parentElement?.getBoundingClientRect() ?? { left: 0, width: 0 }; @@ -31,8 +31,9 @@ export const SeekThumbnail = ({ episode }: Props) => { return (
s); + const state = useStore((s) => s.pages.episode); const update = (second: number): void => { - state.pages.episode.updateCurrentTime(second); + state.updateCurrentTime(second); }; - return [state.pages.episode.currentTime, update] as const; + return [state.currentTime, update] as const; } diff --git a/workspaces/client/src/pages/episode/hooks/useDuration.ts b/workspaces/client/src/pages/episode/hooks/useDuration.ts index d54b086fc..ebaa72479 100644 --- a/workspaces/client/src/pages/episode/hooks/useDuration.ts +++ b/workspaces/client/src/pages/episode/hooks/useDuration.ts @@ -1,6 +1,6 @@ import { useStore } from '@wsh-2025/client/src/app/StoreContext'; export function useDuration() { - const state = useStore((s) => s); - return state.pages.episode.duration; + const state = useStore((s) => s.pages.episode.duration); + return state; } diff --git a/workspaces/client/src/pages/episode/hooks/useMuted.ts b/workspaces/client/src/pages/episode/hooks/useMuted.ts index 706214ee5..e0603f31a 100644 --- a/workspaces/client/src/pages/episode/hooks/useMuted.ts +++ b/workspaces/client/src/pages/episode/hooks/useMuted.ts @@ -1,10 +1,10 @@ import { useStore } from '@wsh-2025/client/src/app/StoreContext'; export function useMuted() { - const state = useStore((s) => s); - const muted = state.pages.episode.muted; + const state = useStore((s) => s.pages.episode); + const muted = state.muted; const toggleMuted = () => { - state.pages.episode.setMuted(!muted); + state.setMuted(!muted); }; return [muted, toggleMuted] as const; } diff --git a/workspaces/client/src/pages/episode/hooks/usePlayerRef.ts b/workspaces/client/src/pages/episode/hooks/usePlayerRef.ts index 54cb75f39..b58b5a3e6 100644 --- a/workspaces/client/src/pages/episode/hooks/usePlayerRef.ts +++ b/workspaces/client/src/pages/episode/hooks/usePlayerRef.ts @@ -1,6 +1,6 @@ import { useStore } from '@wsh-2025/client/src/app/StoreContext'; export function usePlayerRef() { - const state = useStore((s) => s); - return state.pages.episode.playerRef; + const state = useStore((s) => s.pages.episode.playerRef); + return state; } diff --git a/workspaces/client/src/pages/episode/hooks/usePlaying.ts b/workspaces/client/src/pages/episode/hooks/usePlaying.ts index 650ff929f..994708985 100644 --- a/workspaces/client/src/pages/episode/hooks/usePlaying.ts +++ b/workspaces/client/src/pages/episode/hooks/usePlaying.ts @@ -1,13 +1,13 @@ import { useStore } from '@wsh-2025/client/src/app/StoreContext'; export function usePlaying() { - const state = useStore((s) => s); + const state = useStore((s) => s.pages.episode); const toggle = (): void => { - if (state.pages.episode.playing) { - state.pages.episode.pause(); + if (state.playing) { + state.pause(); } else { - state.pages.episode.play(); + state.play(); } }; - return [state.pages.episode.playing, toggle] as const; + return [state.playing, toggle] as const; } diff --git a/workspaces/client/src/pages/episode/hooks/useSeekThumbnail.ts b/workspaces/client/src/pages/episode/hooks/useSeekThumbnail.ts index 8d0015d89..996f2a8a4 100644 --- a/workspaces/client/src/pages/episode/hooks/useSeekThumbnail.ts +++ b/workspaces/client/src/pages/episode/hooks/useSeekThumbnail.ts @@ -1,70 +1,68 @@ -import { FFmpeg } from '@ffmpeg/ffmpeg'; import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; -import { Parser } from 'm3u8-parser'; +import { getEpisodeByIdResponse } from '@wsh-2025/schema/src/openapi/schema'; import { use } from 'react'; interface Params { - episode: StandardSchemaV1.InferOutput; + episode: StandardSchemaV1.InferOutput; } -async function getSeekThumbnail({ episode }: Params) { - // HLS のプレイリストを取得 - const playlistUrl = `/streams/episode/${episode.id}/playlist.m3u8`; - const parser = new Parser(); - parser.push(await fetch(playlistUrl).then((res) => res.text())); - parser.end(); +// FIX ME +async function getSeekThumbnail({ episode: _ }: Params) { + await Promise.resolve(); + return URL.createObjectURL(new Blob([], { type: 'image/jpeg' })); + // // HLS のプレイリストを取得 + // const playlistUrl = `/streams/episode/${episode.id}/playlist.m3u8`; + // const parser = new Parser(); + // parser.push(await fetch(playlistUrl).then((res) => res.text())); + // parser.end(); - // FFmpeg の初期化 - const ffmpeg = new FFmpeg(); - await ffmpeg.load({ - coreURL: await import('@ffmpeg/core?arraybuffer').then(({ default: b }) => { - return URL.createObjectURL(new Blob([b], { type: 'text/javascript' })); - }), - wasmURL: await import('@ffmpeg/core/wasm?arraybuffer').then(({ default: b }) => { - return URL.createObjectURL(new Blob([b], { type: 'application/wasm' })); - }), - }); + // // FFmpeg の初期化 + // const ffmpeg = new FFmpeg(); + // await ffmpeg.load({ + // // パスを修正:Viteの公開ディレクトリから相対パスで指定 + // coreURL: new URL('@ffmpeg/core/dist/umd/ffmpeg-core.js', import.meta.url).href, + // wasmURL: new URL('@ffmpeg/core/dist/umd/ffmpeg-core.wasm', import.meta.url).href, + // }); - // 動画のセグメントファイルを取得 - const segmentFiles = await Promise.all( - parser.manifest.segments.map((s) => { - return fetch(s.uri).then(async (res) => { - const binary = await res.arrayBuffer(); - return { binary, id: Math.random().toString(36).slice(2) }; - }); - }), - ); - // FFmpeg にセグメントファイルを追加 - for (const file of segmentFiles) { - await ffmpeg.writeFile(file.id, new Uint8Array(file.binary)); - } + // // 動画のセグメントファイルを取得 + // const segmentFiles = await Promise.all( + // parser.manifest.segments.map((s) => { + // return fetch(s.uri).then(async (res) => { + // const binary = await res.arrayBuffer(); + // return { binary, id: Math.random().toString(36).slice(2) }; + // }); + // }), + // ); + // // FFmpeg にセグメントファイルを追加 + // for (const file of segmentFiles) { + // await ffmpeg.writeFile(file.id, new Uint8Array(file.binary)); + // } - // セグメントファイルをひとつの mp4 動画に結合 - await ffmpeg.exec( - [ - ['-i', `concat:${segmentFiles.map((f) => f.id).join('|')}`], - ['-c:v', 'copy'], - ['-map', '0:v:0'], - ['-f', 'mp4'], - 'concat.mp4', - ].flat(), - ); + // // セグメントファイルをひとつの mp4 動画に結合 + // await ffmpeg.exec( + // [ + // ['-i', `concat:${segmentFiles.map((f) => f.id).join('|')}`], + // ['-c:v', 'copy'], + // ['-map', '0:v:0'], + // ['-f', 'mp4'], + // 'concat.mp4', + // ].flat(), + // ); - // fps=30 とみなして、30 フレームごと(1 秒ごと)にサムネイルを生成 - await ffmpeg.exec( - [ - ['-i', 'concat.mp4'], - ['-vf', "fps=30,select='not(mod(n\\,30))',scale=160:90,tile=250x1"], - ['-frames:v', '1'], - 'preview.jpg', - ].flat(), - ); + // // fps=30 とみなして、30 フレームごと(1 秒ごと)にサムネイルを生成 + // await ffmpeg.exec( + // [ + // ['-i', 'concat.mp4'], + // ['-vf', "fps=30,select='not(mod(n\\,30))',scale=160:90,tile=250x1"], + // ['-frames:v', '1'], + // 'preview.jpg', + // ].flat(), + // ); - const output = await ffmpeg.readFile('preview.jpg'); - ffmpeg.terminate(); + // const output = await ffmpeg.readFile('preview.jpg'); + // ffmpeg.terminate(); - return URL.createObjectURL(new Blob([output], { type: 'image/jpeg' })); + // return URL.createObjectURL(new Blob([output], { type: 'image/jpeg' })); } const weakMap = new WeakMap>(); diff --git a/workspaces/client/src/pages/home/components/HomePage.tsx b/workspaces/client/src/pages/home/components/HomePage.tsx index 86cb77e6c..d2dbd06dd 100644 --- a/workspaces/client/src/pages/home/components/HomePage.tsx +++ b/workspaces/client/src/pages/home/components/HomePage.tsx @@ -1,16 +1,20 @@ -import { createStore } from '@wsh-2025/client/src/app/createStore'; +import { StandardSchemaV1 } from '@standard-schema/spec'; +import { getRecommendedModulesResponse } from '@wsh-2025/schema/src/openapi/schema'; + import { RecommendedSection } from '@wsh-2025/client/src/features/recommended/components/RecommendedSection'; -import { useRecommended } from '@wsh-2025/client/src/features/recommended/hooks/useRecommended'; +import { recommendedService } from '@wsh-2025/client/src/features/recommended/services/recommendedService'; -export const prefetch = async (store: ReturnType) => { - const modules = await store - .getState() - .features.recommended.fetchRecommendedModulesByReferenceId({ referenceId: 'entrance' }); +export async function loader() { + const modules = await recommendedService.fetchRecommendedModulesByReferenceId({ referenceId: 'entrance' }); return { modules }; -}; +} -export const HomePage = () => { - const modules = useRecommended({ referenceId: 'entrance' }); +export default function HomePage({ + loaderData, +}: { + loaderData: { modules: StandardSchemaV1.InferOutput }; +}) { + const { modules } = loaderData; return ( <> @@ -27,4 +31,4 @@ export const HomePage = () => {
); -}; +} diff --git a/workspaces/client/src/pages/not_found/components/NotFoundPage.tsx b/workspaces/client/src/pages/not_found/components/NotFoundPage.tsx index 66c861769..fc0a8a4c3 100644 --- a/workspaces/client/src/pages/not_found/components/NotFoundPage.tsx +++ b/workspaces/client/src/pages/not_found/components/NotFoundPage.tsx @@ -1,16 +1,20 @@ -import { createStore } from '@wsh-2025/client/src/app/createStore'; +import { StandardSchemaV1 } from '@standard-schema/spec'; +import { getRecommendedModulesResponse } from '@wsh-2025/schema/src/openapi/schema'; + import { RecommendedSection } from '@wsh-2025/client/src/features/recommended/components/RecommendedSection'; -import { useRecommended } from '@wsh-2025/client/src/features/recommended/hooks/useRecommended'; +import { recommendedService } from '@wsh-2025/client/src/features/recommended/services/recommendedService'; -export const prefetch = async (store: ReturnType) => { - const modules = await store - .getState() - .features.recommended.fetchRecommendedModulesByReferenceId({ referenceId: 'error' }); +export async function loader() { + const modules = await recommendedService.fetchRecommendedModulesByReferenceId({ referenceId: 'error' }); return { modules }; -}; +} -export const NotFoundPage = () => { - const modules = useRecommended({ referenceId: 'error' }); +export default function NotFoundPage({ + loaderData, +}: { + loaderData: { modules: StandardSchemaV1.InferOutput }; +}) { + const { modules } = loaderData; const module = modules.at(0); return ( @@ -21,10 +25,10 @@ export const NotFoundPage = () => {

ページが見つかりませんでした

あなたが見ようとしたページは、残念ながら見つけられませんでした。

- +
{module != null ? : null}
); -}; +} diff --git a/workspaces/client/src/pages/program/components/PlayerController.tsx b/workspaces/client/src/pages/program/components/PlayerController.tsx index 6a1c7fef0..ce64edb85 100644 --- a/workspaces/client/src/pages/program/components/PlayerController.tsx +++ b/workspaces/client/src/pages/program/components/PlayerController.tsx @@ -1,4 +1,3 @@ -import { Hoverable } from '@wsh-2025/client/src/features/layout/components/Hoverable'; import { useMuted } from '@wsh-2025/client/src/pages/program/hooks/useMuted'; export const PlayerController = () => { @@ -16,20 +15,18 @@ export const PlayerController = () => {
- - - +
diff --git a/workspaces/client/src/pages/program/components/ProgramPage.tsx b/workspaces/client/src/pages/program/components/ProgramPage.tsx index d13dc9426..13337bc50 100644 --- a/workspaces/client/src/pages/program/components/ProgramPage.tsx +++ b/workspaces/client/src/pages/program/components/ProgramPage.tsx @@ -1,81 +1,96 @@ -import { DateTime } from 'luxon'; -import { useEffect, useRef } from 'react'; +import { StandardSchemaV1 } from '@standard-schema/spec'; +import { + getProgramByIdResponse, + getProgramsResponse, + getRecommendedModulesResponse, +} from '@wsh-2025/schema/src/openapi/schema'; +import { useEffect, useState } from 'react'; import Ellipsis from 'react-ellipsis-component'; import { Flipped } from 'react-flip-toolkit'; import { Link, Params, useNavigate, useParams } from 'react-router'; -import { useUpdate } from 'react-use'; import invariant from 'tiny-invariant'; -import { createStore } from '@wsh-2025/client/src/app/createStore'; +import { channelService } from '@wsh-2025/client/src/features/channel/services/channelService'; import { Player } from '@wsh-2025/client/src/features/player/components/Player'; -import { PlayerType } from '@wsh-2025/client/src/features/player/constants/player_type'; -import { useProgramById } from '@wsh-2025/client/src/features/program/hooks/useProgramById'; +import { programService } from '@wsh-2025/client/src/features/program/services/programService'; import { RecommendedSection } from '@wsh-2025/client/src/features/recommended/components/RecommendedSection'; -import { useRecommended } from '@wsh-2025/client/src/features/recommended/hooks/useRecommended'; +import { recommendedService } from '@wsh-2025/client/src/features/recommended/services/recommendedService'; import { SeriesEpisodeList } from '@wsh-2025/client/src/features/series/components/SeriesEpisodeList'; -import { useTimetable } from '@wsh-2025/client/src/features/timetable/hooks/useTimetable'; import { PlayerController } from '@wsh-2025/client/src/pages/program/components/PlayerController'; import { usePlayerRef } from '@wsh-2025/client/src/pages/program/hooks/usePlayerRef'; -export const prefetch = async (store: ReturnType, { programId }: Params) => { +// Helper function to format date in Japanese style (L月d日 H:mm) +const formatJapaneseDateTime = (date: Date): string => { + const month = date.getMonth() + 1; // getMonth() returns 0-11 + const day = date.getDate(); + const hours = date.getHours().toString().padStart(2, '0'); + const minutes = date.getMinutes().toString().padStart(2, '0'); + return `${month}月${day}日 ${hours}:${minutes}`; +}; + +export const loader = async ({ params: { programId } }: { params: Params }) => { invariant(programId); - const now = DateTime.now(); - const since = now.startOf('day').toISO(); - const until = now.endOf('day').toISO(); - - const program = await store.getState().features.program.fetchProgramById({ programId }); - const channels = await store.getState().features.channel.fetchChannels(); - const timetable = await store.getState().features.timetable.fetchTimetable({ since, until }); - const modules = await store - .getState() - .features.recommended.fetchRecommendedModulesByReferenceId({ referenceId: programId }); - return { channels, modules, program, timetable }; + // 複数のAPIリクエストを並行して実行 + const [program, channels, modules] = await Promise.all([ + programService.fetchProgramById({ programId }), + channelService.fetchChannels(), + recommendedService.fetchRecommendedModulesByReferenceId({ referenceId: programId }), + ]); + return { channels, modules, program }; }; -export const ProgramPage = () => { +export default function ProgramPage({ + loaderData, +}: { + loaderData: { + channels: StandardSchemaV1.InferOutput; + modules: StandardSchemaV1.InferOutput; + program: StandardSchemaV1.InferOutput; + }; +}) { const { programId } = useParams(); invariant(programId); - const program = useProgramById({ programId }); - invariant(program); + const { channels, modules, program } = loaderData; - const timetable = useTimetable(); - const nextProgram = timetable[program.channel.id]?.find((p) => { - return DateTime.fromISO(program.endAt).equals(DateTime.fromISO(p.startAt)); - }); - - const modules = useRecommended({ referenceId: programId }); + const nextProgram = channels + .filter((c) => c.channelId === program.channelId) + .find((c) => { + return new Date(program.endAt).getTime() === new Date(c.startAt).getTime(); + }); const playerRef = usePlayerRef(); - const forceUpdate = useUpdate(); const navigate = useNavigate(); - const isArchivedRef = useRef(DateTime.fromISO(program.endAt) <= DateTime.now()); - const isBroadcastStarted = DateTime.fromISO(program.startAt) <= DateTime.now(); + const [isArchived, setIsArchived] = useState(new Date(program.endAt) <= new Date()); + const [isBroadcastStarted, setIsBroadcastStarted] = useState(new Date(program.startAt) <= new Date()); useEffect(() => { - if (isArchivedRef.current) { + if (isArchived) { return; } - // 放送前であれば、放送開始になるまで画面を更新し続ける + // 放送前であれば、放送開始時刻に一度だけ更新する if (!isBroadcastStarted) { - let timeout = setTimeout(function tick() { - forceUpdate(); - timeout = setTimeout(tick, 250); - }, 250); + const startTime = new Date(program.startAt).getTime(); + const now = new Date().getTime(); + const timeUntilStart = Math.max(0, startTime - now); + + const timeout = setTimeout(() => { + setIsBroadcastStarted(true); + }, timeUntilStart); + return () => { clearTimeout(timeout); }; } - // 放送中に次の番組が始まったら、画面をそのままにしつつ、情報を次の番組にする - let timeout = setTimeout(function tick() { - if (DateTime.now() < DateTime.fromISO(program.endAt)) { - timeout = setTimeout(tick, 250); - return; - } + // 放送中の場合、終了時刻に一度だけ更新する + const endTime = new Date(program.endAt).getTime(); + const now = new Date().getTime(); + const timeUntilEnd = Math.max(0, endTime - now); + const timeout = setTimeout(() => { if (nextProgram?.id) { void navigate(`/programs/${nextProgram.id}`, { preventScrollReset: true, @@ -83,14 +98,14 @@ export const ProgramPage = () => { state: { loading: 'none' }, }); } else { - isArchivedRef.current = true; - forceUpdate(); + setIsArchived(true); } - }, 250); + }, timeUntilEnd); + return () => { clearTimeout(timeout); }; - }, [isBroadcastStarted, nextProgram?.id]); + }, [isArchived, isBroadcastStarted, nextProgram?.id, program.startAt, program.endAt, navigate]); return ( <> @@ -99,9 +114,9 @@ export const ProgramPage = () => {
- {isArchivedRef.current ? ( + {isArchived ? (
- +

この番組は放送が終了しました

@@ -118,7 +133,6 @@ export const ProgramPage = () => {
@@ -127,11 +141,11 @@ export const ProgramPage = () => {
) : (
- +

- この番組は {DateTime.fromISO(program.startAt).toFormat('L月d日 H:mm')} に放送予定です + この番組は {formatJapaneseDateTime(new Date(program.startAt))} に放送予定です

@@ -147,9 +161,9 @@ export const ProgramPage = () => {
- {DateTime.fromISO(program.startAt).toFormat('L月d日 H:mm')} + {formatJapaneseDateTime(new Date(program.startAt))} {' 〜 '} - {DateTime.fromISO(program.endAt).toFormat('L月d日 H:mm')} + {formatJapaneseDateTime(new Date(program.endAt))}
@@ -169,4 +183,4 @@ export const ProgramPage = () => {
); -}; +} diff --git a/workspaces/client/src/pages/program/hooks/useMuted.ts b/workspaces/client/src/pages/program/hooks/useMuted.ts index b96370623..eb748b392 100644 --- a/workspaces/client/src/pages/program/hooks/useMuted.ts +++ b/workspaces/client/src/pages/program/hooks/useMuted.ts @@ -1,10 +1,10 @@ import { useStore } from '@wsh-2025/client/src/app/StoreContext'; export function useMuted() { - const state = useStore((s) => s); - const muted = state.pages.program.muted; + const state = useStore((s) => s.pages.program); + const muted = state.muted; const toggleMuted = () => { - state.pages.program.setMuted(!muted); + state.setMuted(!muted); }; return [muted, toggleMuted] as const; } diff --git a/workspaces/client/src/pages/program/hooks/usePlayerRef.ts b/workspaces/client/src/pages/program/hooks/usePlayerRef.ts index 2b00d9fea..01145ef69 100644 --- a/workspaces/client/src/pages/program/hooks/usePlayerRef.ts +++ b/workspaces/client/src/pages/program/hooks/usePlayerRef.ts @@ -1,6 +1,6 @@ import { useStore } from '@wsh-2025/client/src/app/StoreContext'; export function usePlayerRef() { - const state = useStore((s) => s); - return state.pages.program.playerRef; + const state = useStore((s) => s.pages.program.playerRef); + return state; } diff --git a/workspaces/client/src/pages/series/components/SeriesPage.tsx b/workspaces/client/src/pages/series/components/SeriesPage.tsx index abf35aee5..5d8cfd195 100644 --- a/workspaces/client/src/pages/series/components/SeriesPage.tsx +++ b/workspaces/client/src/pages/series/components/SeriesPage.tsx @@ -1,31 +1,40 @@ +import { StandardSchemaV1 } from '@standard-schema/spec'; +import { getRecommendedModulesResponse, getSeriesByIdResponse } from '@wsh-2025/schema/src/openapi/schema'; import Ellipsis from 'react-ellipsis-component'; import { Flipped } from 'react-flip-toolkit'; import { Params, useParams } from 'react-router'; import invariant from 'tiny-invariant'; -import { createStore } from '@wsh-2025/client/src/app/createStore'; import { RecommendedSection } from '@wsh-2025/client/src/features/recommended/components/RecommendedSection'; -import { useRecommended } from '@wsh-2025/client/src/features/recommended/hooks/useRecommended'; +import { recommendedService } from '@wsh-2025/client/src/features/recommended/services/recommendedService'; import { SeriesEpisodeList } from '@wsh-2025/client/src/features/series/components/SeriesEpisodeList'; -import { useSeriesById } from '@wsh-2025/client/src/features/series/hooks/useSeriesById'; +import { seriesService } from '@wsh-2025/client/src/features/series/services/seriesService'; -export const prefetch = async (store: ReturnType, { seriesId }: Params) => { +export const loader = async ({ params }: { params: Params }) => { + const { seriesId } = params; invariant(seriesId); - const series = await store.getState().features.series.fetchSeriesById({ seriesId }); - const modules = await store - .getState() - .features.recommended.fetchRecommendedModulesByReferenceId({ referenceId: seriesId }); + + // 複数のAPIリクエストを並行して実行 + const [series, modules] = await Promise.all([ + seriesService.fetchSeriesById({ seriesId }), + recommendedService.fetchRecommendedModulesByReferenceId({ referenceId: seriesId }), + ]); + return { modules, series }; }; -export const SeriesPage = () => { +export default function SeriesPage({ + loaderData, +}: { + loaderData: { + modules: StandardSchemaV1.InferOutput; + series: StandardSchemaV1.InferOutput; + }; +}) { const { seriesId } = useParams(); invariant(seriesId); - const series = useSeriesById({ seriesId }); - invariant(series); - - const modules = useRecommended({ referenceId: seriesId }); + const { modules, series } = loaderData; return ( <> @@ -37,6 +46,7 @@ export const SeriesPage = () => { @@ -63,4 +73,4 @@ export const SeriesPage = () => {
); -}; +} diff --git a/workspaces/client/src/pages/timetable/components/ChannelTitle.tsx b/workspaces/client/src/pages/timetable/components/ChannelTitle.tsx index c2538c886..d0f9f72c5 100644 --- a/workspaces/client/src/pages/timetable/components/ChannelTitle.tsx +++ b/workspaces/client/src/pages/timetable/components/ChannelTitle.tsx @@ -1,23 +1,19 @@ -import invariant from 'tiny-invariant'; - -import { useChannelById } from '@wsh-2025/client/src/features/channel/hooks/useChannelById'; import { Gutter } from '@wsh-2025/client/src/pages/timetable/components/Gutter'; import { useColumnWidth } from '@wsh-2025/client/src/pages/timetable/hooks/useColumnWidth'; interface Props { channelId: string; + logoURL: string; + name: string; } -export const ChannelTitle = ({ channelId }: Props) => { - const channel = useChannelById({ channelId }); - invariant(channel); - +export const ChannelTitle = ({ channelId, logoURL, name }: Props) => { const width = useColumnWidth(channelId); return (
- {channel.name} + {name}
diff --git a/workspaces/client/src/pages/timetable/components/NewTimetableFeatureDialog.tsx b/workspaces/client/src/pages/timetable/components/NewTimetableFeatureDialog.tsx index ce0f9224a..cf72a309c 100644 --- a/workspaces/client/src/pages/timetable/components/NewTimetableFeatureDialog.tsx +++ b/workspaces/client/src/pages/timetable/components/NewTimetableFeatureDialog.tsx @@ -1,4 +1,3 @@ -import FeatureExplainImageUrl from '@wsh-2025/client/assets/timetable/feature-explain.png'; import { Dialog } from '@wsh-2025/client/src/features/dialog/components/Dialog'; import { useCloseNewFeatureDialog } from '@wsh-2025/client/src/pages/timetable/hooks/useCloseNewFeatureDialog'; @@ -13,7 +12,7 @@ export const NewTimetableFeatureDialog = ({ isOpen }: Props) => {
- +

拡大・縮小機能を新しく追加

@@ -29,7 +28,7 @@ export const NewTimetableFeatureDialog = ({ isOpen }: Props) => { 引き続き皆様に快適にご利用いただけるよう、サービスの改善に努めてまいります。今後ともどうぞよろしくお願いいたします。

- +
- ); diff --git a/workspaces/client/src/pages/timetable/components/ProgramDetailDialog.tsx b/workspaces/client/src/pages/timetable/components/ProgramDetailDialog.tsx index 41e0ec14c..17e03b046 100644 --- a/workspaces/client/src/pages/timetable/components/ProgramDetailDialog.tsx +++ b/workspaces/client/src/pages/timetable/components/ProgramDetailDialog.tsx @@ -1,5 +1,5 @@ import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; +import { getTimetableResponse } from '@wsh-2025/schema/src/openapi/schema'; import { ReactElement } from 'react'; import { Link } from 'react-router'; import { ArrayValues } from 'type-fest'; @@ -10,7 +10,7 @@ import { useSelectedProgramId } from '@wsh-2025/client/src/pages/timetable/hooks interface Props { isOpen: boolean; - program: ArrayValues>; + program: ArrayValues>; } export const ProgramDetailDialog = ({ isOpen, program }: Props): ReactElement => { @@ -33,6 +33,7 @@ export const ProgramDetailDialog = ({ isOpen, program }: Props): ReactElement => @@ -47,6 +48,7 @@ export const ProgramDetailDialog = ({ isOpen, program }: Props): ReactElement => diff --git a/workspaces/client/src/pages/timetable/components/ProgramList.tsx b/workspaces/client/src/pages/timetable/components/ProgramList.tsx index c15579607..ac4806e5f 100644 --- a/workspaces/client/src/pages/timetable/components/ProgramList.tsx +++ b/workspaces/client/src/pages/timetable/components/ProgramList.tsx @@ -1,6 +1,5 @@ import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; -import { DateTime } from 'luxon'; +import { getTimetableResponse } from '@wsh-2025/schema/src/openapi/schema'; import { ReactElement } from 'react'; import { ArrayValues } from 'type-fest'; @@ -10,7 +9,7 @@ import { Program } from '@wsh-2025/client/src/pages/timetable/components/Program interface Props { channelId: string; - programList: ArrayValues>[]; + programList: ArrayValues>[]; } export const ProgramList = ({ channelId, programList }: Props): ReactElement => { @@ -18,9 +17,9 @@ export const ProgramList = ({ channelId, programList }: Props): ReactElement =>
{programList.map((program) => { - const startAt = DateTime.fromISO(program.startAt); - const endAt = DateTime.fromISO(program.endAt); - const duration = endAt.diff(startAt, 'minutes').minutes; + const startAt = new Date(program.startAt); + const endAt = new Date(program.endAt); + const duration = (endAt.getTime() - startAt.getTime()) / (1000 * 60); const height = HEIGHT_ONE_HOUR * (duration / 60); return ( diff --git a/workspaces/client/src/pages/timetable/components/TimelineYAxis.tsx b/workspaces/client/src/pages/timetable/components/TimelineYAxis.tsx index c4eb15df4..0925435e0 100644 --- a/workspaces/client/src/pages/timetable/components/TimelineYAxis.tsx +++ b/workspaces/client/src/pages/timetable/components/TimelineYAxis.tsx @@ -7,7 +7,8 @@ export const TimelineYAxis = (): ReactElement => { return (
{hour}
diff --git a/workspaces/client/src/pages/timetable/components/TimetablePage.tsx b/workspaces/client/src/pages/timetable/components/TimetablePage.tsx index 3736b9aa0..58f669219 100644 --- a/workspaces/client/src/pages/timetable/components/TimetablePage.tsx +++ b/workspaces/client/src/pages/timetable/components/TimetablePage.tsx @@ -1,30 +1,61 @@ -import { DateTime } from 'luxon'; -import invariant from 'tiny-invariant'; +import { StandardSchemaV1 } from '@standard-schema/spec'; +import { getChannelsResponse, getProgramsResponse } from '@wsh-2025/schema/src/openapi/schema'; +import { ArrayValues } from 'type-fest'; -import { createStore } from '@wsh-2025/client/src/app/createStore'; -import { useTimetable } from '@wsh-2025/client/src/features/timetable/hooks/useTimetable'; +import { channelService } from '@wsh-2025/client/src/features/channel/services/channelService'; +import { programService } from '@wsh-2025/client/src/features/program/services/programService'; import { ChannelTitle } from '@wsh-2025/client/src/pages/timetable/components/ChannelTitle'; import { NewTimetableFeatureDialog } from '@wsh-2025/client/src/pages/timetable/components/NewTimetableFeatureDialog'; import { ProgramList } from '@wsh-2025/client/src/pages/timetable/components/ProgramList'; import { TimelineYAxis } from '@wsh-2025/client/src/pages/timetable/components/TimelineYAxis'; import { useShownNewFeatureDialog } from '@wsh-2025/client/src/pages/timetable/hooks/useShownNewFeatureDialog'; -export const prefetch = async (store: ReturnType) => { - const now = DateTime.now(); - const since = now.startOf('day').toISO(); - const until = now.endOf('day').toISO(); +export const loader = async () => { + // const now = new Date(); + // const since = new Date(now.setHours(0, 0, 0, 0)).toISOString(); + // const until = new Date(now.setHours(23, 59, 59, 999)).toISOString(); + + // 複数のAPIリクエストを並行して実行 + const [channels, programs] = await Promise.all([ + channelService.fetchChannels(), + // timetableService.fetchTimetable({ since, until }), + programService.fetchPrograms(), + ]); - const channels = await store.getState().features.channel.fetchChannels(); - const programs = await store.getState().features.timetable.fetchTimetable({ since, until }); return { channels, programs }; }; +export default function TimetablePage({ + loaderData, +}: { + loaderData: { + channels: StandardSchemaV1.InferOutput; + programs: StandardSchemaV1.InferOutput; + }; +}) { + const { channels, programs } = loaderData; + const record: Record< + string, + { + id: string; + logoUrl: string; + name: string; + programs: ArrayValues[]; + } + > = {}; -export const TimetablePage = () => { - const record = useTimetable(); - const shownNewFeatureDialog = useShownNewFeatureDialog(); + for (const channel of channels) { + const filteredPrograms = programs + .filter((program) => program.channelId === channel.id) + .sort((a, b) => new Date(a.startAt).getTime() - new Date(b.startAt).getTime()); - const channelIds = Object.keys(record); - const programLists = Object.values(record); + record[channel.id] = { + id: channel.id, + logoUrl: channel.logoUrl, + name: channel.name, + programs: filteredPrograms, + }; + } + const shownNewFeatureDialog = useShownNewFeatureDialog(); return ( <> @@ -32,23 +63,23 @@ export const TimetablePage = () => {
- {channelIds.map((channelId) => ( -
- -
- ))} + {Object.values(record).map(({ id, logoUrl, name }) => { + return ( +
+ +
+ ); + })}
- {programLists.map((programList, index) => { - const channelId = channelIds[index]; - invariant(channelId); + {Object.values(record).map(({ id, programs }) => { return ( -
- +
+
); })} @@ -58,4 +89,4 @@ export const TimetablePage = () => { ); -}; +} diff --git a/workspaces/client/src/pages/timetable/hooks/useChangeColumnWidth.ts b/workspaces/client/src/pages/timetable/hooks/useChangeColumnWidth.ts index cb4b28f1d..6d7a3b444 100644 --- a/workspaces/client/src/pages/timetable/hooks/useChangeColumnWidth.ts +++ b/workspaces/client/src/pages/timetable/hooks/useChangeColumnWidth.ts @@ -1,6 +1,6 @@ import { useStore } from '@wsh-2025/client/src/app/StoreContext'; export function useChangeColumnWidth() { - const state = useStore((s) => s); - return state.pages.timetable.changeColumnWidth; + const state = useStore((s) => s.pages.timetable.changeColumnWidth); + return state; } diff --git a/workspaces/client/src/pages/timetable/hooks/useCloseNewFeatureDialog.ts b/workspaces/client/src/pages/timetable/hooks/useCloseNewFeatureDialog.ts index 877fa65ef..d84ff7d13 100644 --- a/workspaces/client/src/pages/timetable/hooks/useCloseNewFeatureDialog.ts +++ b/workspaces/client/src/pages/timetable/hooks/useCloseNewFeatureDialog.ts @@ -1,6 +1,6 @@ import { useStore } from '@wsh-2025/client/src/app/StoreContext'; export function useCloseNewFeatureDialog() { - const state = useStore((s) => s); - return state.pages.timetable.closeNewFeatureDialog; + const state = useStore((s) => s.pages.timetable.closeNewFeatureDialog); + return state; } diff --git a/workspaces/client/src/pages/timetable/hooks/useColumnWidth.ts b/workspaces/client/src/pages/timetable/hooks/useColumnWidth.ts index fb58f6a03..95c62e66c 100644 --- a/workspaces/client/src/pages/timetable/hooks/useColumnWidth.ts +++ b/workspaces/client/src/pages/timetable/hooks/useColumnWidth.ts @@ -2,6 +2,6 @@ import { useStore } from '@wsh-2025/client/src/app/StoreContext'; import { DEFAULT_WIDTH } from '@wsh-2025/client/src/features/timetable/constants/grid_size'; export function useColumnWidth(channelId: string): number { - const state = useStore((s) => s); - return state.pages.timetable.columnWidthRecord[channelId] ?? DEFAULT_WIDTH; + const state = useStore((s) => s.pages.timetable.columnWidthRecord[channelId]); + return state ?? DEFAULT_WIDTH; } diff --git a/workspaces/client/src/pages/timetable/hooks/useCurrentUnixtimeMs.ts b/workspaces/client/src/pages/timetable/hooks/useCurrentUnixtimeMs.ts index b54997cd6..baa7a2c86 100644 --- a/workspaces/client/src/pages/timetable/hooks/useCurrentUnixtimeMs.ts +++ b/workspaces/client/src/pages/timetable/hooks/useCurrentUnixtimeMs.ts @@ -3,14 +3,9 @@ import { useEffect } from 'react'; import { useStore } from '@wsh-2025/client/src/app/StoreContext'; export function useCurrentUnixtimeMs(): number { - const state = useStore((s) => s); + const state = useStore((s) => s.pages.timetable); useEffect(() => { - const interval = setInterval(() => { - state.pages.timetable.refreshCurrentUnixtimeMs(); - }, 250); - return () => { - clearInterval(interval); - }; + state.refreshCurrentUnixtimeMs(); }, []); - return state.pages.timetable.currentUnixtimeMs; + return state.currentUnixtimeMs; } diff --git a/workspaces/client/src/pages/timetable/hooks/useEpisode.ts b/workspaces/client/src/pages/timetable/hooks/useEpisode.ts index f6d7677c9..aa599eb32 100644 --- a/workspaces/client/src/pages/timetable/hooks/useEpisode.ts +++ b/workspaces/client/src/pages/timetable/hooks/useEpisode.ts @@ -1,10 +1,10 @@ import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; +import { getEpisodeByIdResponse } from '@wsh-2025/schema/src/openapi/schema'; import { useEffect, useState } from 'react'; import { episodeService } from '@wsh-2025/client/src/features/episode/services/episodeService'; -type Episode = StandardSchemaV1.InferOutput; +type Episode = StandardSchemaV1.InferOutput; export function useEpisode(episodeId: string) { const [episode, setEpisode] = useState(null); diff --git a/workspaces/client/src/pages/timetable/hooks/useSelectedProgramId.ts b/workspaces/client/src/pages/timetable/hooks/useSelectedProgramId.ts index 13d4b9d8c..1032449af 100644 --- a/workspaces/client/src/pages/timetable/hooks/useSelectedProgramId.ts +++ b/workspaces/client/src/pages/timetable/hooks/useSelectedProgramId.ts @@ -1,15 +1,15 @@ import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; +import { getTimetableResponse } from '@wsh-2025/schema/src/openapi/schema'; import { ArrayValues } from 'type-fest'; import { useStore } from '@wsh-2025/client/src/app/StoreContext'; -type Program = ArrayValues>; +type Program = ArrayValues>; export function useSelectedProgramId() { - const state = useStore((s) => s); + const state = useStore((s) => s.pages.timetable); const setProgram = (program: Program | null) => { - state.pages.timetable.selectProgram(program); + state.selectProgram(program); }; - return [state.pages.timetable.selectedProgramId, setProgram] as const; + return [state.selectedProgramId, setProgram] as const; } diff --git a/workspaces/client/src/pages/timetable/hooks/useShownNewFeatureDialog.ts b/workspaces/client/src/pages/timetable/hooks/useShownNewFeatureDialog.ts index e78244f96..cb73d4736 100644 --- a/workspaces/client/src/pages/timetable/hooks/useShownNewFeatureDialog.ts +++ b/workspaces/client/src/pages/timetable/hooks/useShownNewFeatureDialog.ts @@ -1,6 +1,6 @@ import { useStore } from '@wsh-2025/client/src/app/StoreContext'; export function useShownNewFeatureDialog(): boolean { - const state = useStore((s) => s); - return state.pages.timetable.shownNewFeatureDialog; + const state = useStore((s) => s.pages.timetable.shownNewFeatureDialog); + return state; } diff --git a/workspaces/client/src/pages/timetable/stores/createTimetablePageStoreSlice.ts b/workspaces/client/src/pages/timetable/stores/createTimetablePageStoreSlice.ts index ed190b39b..0eaca5a09 100644 --- a/workspaces/client/src/pages/timetable/stores/createTimetablePageStoreSlice.ts +++ b/workspaces/client/src/pages/timetable/stores/createTimetablePageStoreSlice.ts @@ -1,14 +1,28 @@ import { lens } from '@dhmk/zustand-lens'; import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; -import { produce } from 'immer'; -import _ from 'lodash'; +import { getTimetableResponse } from '@wsh-2025/schema/src/openapi/schema'; import { ArrayValues } from 'type-fest'; import { DEFAULT_WIDTH } from '@wsh-2025/client/src/features/timetable/constants/grid_size'; +// Custom debounce utility function +function debounce unknown>(func: T, wait: number): (...args: Parameters) => void { + let timeoutId: ReturnType | null = null; + + return (...args: Parameters) => { + if (timeoutId != null) { + clearTimeout(timeoutId); + } + + timeoutId = setTimeout(() => { + func(...args); + timeoutId = null; + }, wait); + }; +} + type ChannelId = string; -type Program = ArrayValues>; +type Program = ArrayValues>; interface TimetablePageState { columnWidthRecord: Record; @@ -28,10 +42,14 @@ export const createTimetablePageStoreSlice = () => { return lens((set, _get) => ({ changeColumnWidth: (params: { channelId: string; delta: number }) => { set((state) => { - return produce(state, (draft) => { - const current = draft.columnWidthRecord[params.channelId] ?? DEFAULT_WIDTH; - draft.columnWidthRecord[params.channelId] = Math.max(current + params.delta, 100); - }); + const current = state.columnWidthRecord[params.channelId] ?? DEFAULT_WIDTH; + return { + ...state, + columnWidthRecord: { + ...state.columnWidthRecord, + [params.channelId]: Math.max(current + params.delta, 100) + } + }; }); }, closeNewFeatureDialog: () => { @@ -41,7 +59,7 @@ export const createTimetablePageStoreSlice = () => { }, columnWidthRecord: {}, currentUnixtimeMs: 0, - refreshCurrentUnixtimeMs: _.debounce(() => { + refreshCurrentUnixtimeMs: debounce(() => { set(() => ({ currentUnixtimeMs: Date.now(), })); diff --git a/workspaces/client/src/root.tsx b/workspaces/client/src/root.tsx new file mode 100644 index 000000000..0e762acd5 --- /dev/null +++ b/workspaces/client/src/root.tsx @@ -0,0 +1,206 @@ +import { StandardSchemaV1 } from '@standard-schema/spec'; +import { getUserResponse } from '@wsh-2025/schema/src/openapi/schema'; +import classNames from 'classnames'; +import { ReactNode, useEffect, useRef, useState } from 'react'; +import { Flipper } from 'react-flip-toolkit'; +import { + Link, + Links, + Meta, + Outlet, + Scripts, + ScrollRestoration, + useLocation, + useNavigation, + useRouteLoaderData, +} from 'react-router'; + +import { StoreContext } from '@wsh-2025/client/src/app/StoreContext'; +import { createStore } from '@wsh-2025/client/src/app/createStore'; +import { SignInDialog } from '@wsh-2025/client/src/features/auth/components/SignInDialog'; +import { SignOutDialog } from '@wsh-2025/client/src/features/auth/components/SignOutDialog'; +import { SignUpDialog } from '@wsh-2025/client/src/features/auth/components/SignUpDialog'; +import { AuthDialogType } from '@wsh-2025/client/src/features/auth/constants/auth_dialog_type'; +import { useAuthActions } from '@wsh-2025/client/src/features/auth/hooks/useAuthActions'; +import { useAuthDialogType } from '@wsh-2025/client/src/features/auth/hooks/useAuthDialogType'; +import { useAuthUser } from '@wsh-2025/client/src/features/auth/hooks/useAuthUser'; +import { authService } from '@wsh-2025/client/src/features/auth/services/authService'; +import { Loading } from '@wsh-2025/client/src/features/layout/components/Loading'; +import '@wsh-2025/client/src/uno.css'; + +export const loader = async () => { + const user = await authService.fetchUser(); + return { user }; +}; + +export function Layout({ children }: { children: ReactNode }) { + // useSubscribePointer(); + const data = useRouteLoaderData<{ user: StandardSchemaV1.InferOutput }>('root'); + const user = data?.user ?? null; + + const storeRef = useRef | null>(null); + if (storeRef.current == null) { + storeRef.current = createStore({ + hydrationData: { + features: { + auth: { + user, + }, + }, + }, + }); + } + + return ( + + + + + Web Speed Hackathon 2025 + + + + + + {children} + + + + + + ); +} + +export default function Root() { + return ; +} + +const AuthComponent = ({ children }: { children: ReactNode }) => { + const authActions = useAuthActions(); + const authDialogType = useAuthDialogType(); + const user = useAuthUser(); + + const navigation = useNavigation(); + const isLoading = + navigation.location != null && (navigation.location.state as { loading?: string } | null)?.['loading'] !== 'none'; + + const location = useLocation(); + const isTimetablePage = location.pathname === '/timetable'; + + const [shouldHeaderBeTransparent, setShouldHeaderBeTransparent] = useState(false); + const headerObserverRef = useRef(null); + + useEffect(() => { + // スクロール位置を監視するオプション設定 + const observerOptions = { + // rootMarginをマイナスに設定:ビューポートの上端から80px下にスクロールしたら効果を発動 + rootMargin: '-80px 0px 0px 0px', + threshold: 0, + }; + + const headerObserver = new IntersectionObserver((entries) => { + // マーカー要素が見えなくなったらヘッダーを透明に(undefined対策) + if (entries.length > 0) { + setShouldHeaderBeTransparent(!entries[0]?.isIntersecting); + } + }, observerOptions); + + if (headerObserverRef.current) { + headerObserver.observe(headerObserverRef.current); + } + + return () => { + if (headerObserverRef.current) { + headerObserver.unobserve(headerObserverRef.current); + } + }; + }, []); + + return ( + <> + {/* IntersectionObserver用のマーカー要素 - ページ先頭に配置 */} +
+
+
+ + AREMA + +
+ + + +
+ + {children} + +
+ + {isLoading ? ( +
+ +
+ ) : null} +
+ + + + + + ); +}; diff --git a/workspaces/client/src/routes.ts b/workspaces/client/src/routes.ts new file mode 100644 index 000000000..5061bf6b0 --- /dev/null +++ b/workspaces/client/src/routes.ts @@ -0,0 +1,11 @@ +import { route, type RouteConfig } from '@react-router/dev/routes'; + +export default [ + // * matches all URLs, the ? makes it optional so it will match / as well + route('/', './pages/home/components/HomePage.tsx'), + route('/episodes/:episodeId', './pages/episode/components/EpisodePage.tsx'), + route('/programs/:programId', './pages/program/components/ProgramPage.tsx'), + route('/series/:seriesId', './pages/series/components/SeriesPage.tsx'), + route('/timetable', './pages/timetable/components/TimetablePage.tsx'), + route('*?', './pages/not_found/components/NotFoundPage.tsx'), +] satisfies RouteConfig; diff --git a/workspaces/client/src/setups/luxon.ts b/workspaces/client/src/setups/luxon.ts deleted file mode 100644 index 48132ca90..000000000 --- a/workspaces/client/src/setups/luxon.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Settings } from 'luxon'; - -declare module 'luxon' { - interface TSSettings { - throwOnInvalid: true; - } -} - -Settings.defaultZone = 'Asia/Tokyo'; -Settings.throwOnInvalid = true; diff --git a/workspaces/client/src/setups/polyfills.ts b/workspaces/client/src/setups/polyfills.ts deleted file mode 100644 index 0077ca803..000000000 --- a/workspaces/client/src/setups/polyfills.ts +++ /dev/null @@ -1,3 +0,0 @@ -import 'core-js'; -import 'view-transitions-polyfill'; -import 'setimmediate'; diff --git a/workspaces/client/src/setups/unocss.ts b/workspaces/client/src/setups/unocss.ts deleted file mode 100644 index d8e91da31..000000000 --- a/workspaces/client/src/setups/unocss.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { IconifyJSON } from '@iconify/types'; -import presetIcons from '@unocss/preset-icons/browser'; -import presetWind3 from '@unocss/preset-wind3'; -import initUnocssRuntime, { defineConfig } from '@unocss/runtime'; - -async function init() { - await initUnocssRuntime({ - defaults: defineConfig({ - layers: { - default: 1, - icons: 0, - preflights: 0, - reset: -1, - }, - preflights: [ - { - getCSS: () => import('@unocss/reset/tailwind-compat.css?raw').then(({ default: css }) => css), - layer: 'reset', - }, - { - getCSS: () => /* css */ ` - @view-transition { - navigation: auto; - } - html, - :host { - font-family: 'Noto Sans JP', sans-serif !important; - } - video { - max-height: 100%; - max-width: 100%; - } - `, - }, - { - getCSS: () => /* css */ ` - @keyframes fade-in { - from { - opacity: 0; - } - to { - opacity: 1; - } - } - `, - }, - ], - presets: [ - presetWind3(), - presetIcons({ - collections: { - bi: () => import('@iconify/json/json/bi.json').then((m): IconifyJSON => m.default as IconifyJSON), - bx: () => import('@iconify/json/json/bx.json').then((m): IconifyJSON => m.default as IconifyJSON), - 'fa-regular': () => - import('@iconify/json/json/fa-regular.json').then((m): IconifyJSON => m.default as IconifyJSON), - 'fa-solid': () => - import('@iconify/json/json/fa-solid.json').then((m): IconifyJSON => m.default as IconifyJSON), - fluent: () => import('@iconify/json/json/fluent.json').then((m): IconifyJSON => m.default as IconifyJSON), - 'line-md': () => - import('@iconify/json/json/line-md.json').then((m): IconifyJSON => m.default as IconifyJSON), - 'material-symbols': () => - import('@iconify/json/json/material-symbols.json').then((m): IconifyJSON => m.default as IconifyJSON), - }, - }), - ], - }), - }); -} - -init().catch((err: unknown) => { - throw err; -}); diff --git a/workspaces/client/src/uno.css b/workspaces/client/src/uno.css new file mode 100644 index 000000000..f266ac859 --- /dev/null +++ b/workspaces/client/src/uno.css @@ -0,0 +1,248 @@ +/* layer: icons */ +.i-bi\:house-fill{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 16 16' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M8.707 1.5a1 1 0 0 0-1.414 0L.646 8.146a.5.5 0 0 0 .708.708L8 2.207l6.646 6.647a.5.5 0 0 0 .708-.708L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293z'/%3E%3Cpath d='m8 3.293l6 6V13.5a1.5 1.5 0 0 1-1.5 1.5h-9A1.5 1.5 0 0 1 2 13.5V9.293z'/%3E%3C/g%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1em;height:1em;} +.i-fa-solid\:calendar{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 448 512' width='0.88em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12m436-44v-36c0-26.5-21.5-48-48-48h-48V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H160V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H48C21.5 64 0 85.5 0 112v36c0 6.6 5.4 12 12 12h424c6.6 0 12-5.4 12-12'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:0.88em;height:1em;} +.i-fa\:sign-out{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 1568 1280' width='1.23em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M640 1184q0 4 1 20t.5 26.5t-3 23.5t-10 19.5t-20.5 6.5H288q-119 0-203.5-84.5T0 992V288Q0 169 84.5 84.5T288 0h320q13 0 22.5 9.5T640 32q0 4 1 20t.5 26.5t-3 23.5t-10 19.5T608 128H288q-66 0-113 47t-47 113v704q0 66 47 113t113 47h312l11.5 1l11.5 3l8 5.5l7 9zm928-544q0 26-19 45l-544 544q-19 19-45 19t-45-19t-19-45V896H448q-26 0-45-19t-19-45V448q0-26 19-45t45-19h448V96q0-26 19-45t45-19t45 19l544 544q19 19 19 45'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.23em;height:1em;} +.i-fa\:user{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 1280 1536' width='0.84em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M1280 1271q0 109-62.5 187t-150.5 78H213q-88 0-150.5-78T0 1271q0-85 8.5-160.5t31.5-152t58.5-131t94-89T327 704q131 128 313 128t313-128q76 0 134.5 34.5t94 89t58.5 131t31.5 152t8.5 160.5m-256-887q0 159-112.5 271.5T640 768T368.5 655.5T256 384t112.5-271.5T640 0t271.5 112.5T1024 384'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:0.84em;height:1em;} +.i-fluent\:live-24-filled{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M6.343 4.938a1 1 0 0 1 0 1.415a8.003 8.003 0 0 0 0 11.317a1 1 0 1 1-1.414 1.414c-3.907-3.906-3.907-10.24 0-14.146a1 1 0 0 1 1.414 0m12.732 0c3.906 3.907 3.906 10.24 0 14.146a1 1 0 0 1-1.415-1.414a8.003 8.003 0 0 0 0-11.317a1 1 0 0 1 1.415-1.415M9.31 7.812a1 1 0 0 1 0 1.414a3.92 3.92 0 0 0 0 5.544a1 1 0 1 1-1.415 1.414a5.92 5.92 0 0 1 0-8.372a1 1 0 0 1 1.415 0m6.958 0a5.92 5.92 0 0 1 0 8.372a1 1 0 0 1-1.414-1.414a3.92 3.92 0 0 0 0-5.544a1 1 0 0 1 1.414-1.414m-4.186 2.77a1.5 1.5 0 1 1 0 3a1.5 1.5 0 0 1 0-3'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1em;height:1em;} +.i-line-md\:loading-twotone-loop{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Cpath stroke-dasharray='16' stroke-dashoffset='16' d='M12 3c4.97 0 9 4.03 9 9'%3E%3Canimate fill='freeze' attributeName='stroke-dashoffset' dur='0.3s' values='16;0'/%3E%3CanimateTransform attributeName='transform' dur='1.5s' repeatCount='indefinite' type='rotate' values='0 12 12;360 12 12'/%3E%3C/path%3E%3Cpath stroke-dasharray='64' stroke-dashoffset='64' stroke-opacity='.3' d='M12 3c4.97 0 9 4.03 9 9c0 4.97 -4.03 9 -9 9c-4.97 0 -9 -4.03 -9 -9c0 -4.97 4.03 -9 9 -9Z'%3E%3Canimate fill='freeze' attributeName='stroke-dashoffset' dur='1.2s' values='64;0'/%3E%3C/path%3E%3C/g%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1em;height:1em;} +.i-material-symbols\:error-outline{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M12 17q.425 0 .713-.288T13 16t-.288-.712T12 15t-.712.288T11 16t.288.713T12 17m-1-4h2V7h-2zm1 9q-2.075 0-3.9-.788t-3.175-2.137T2.788 15.9T2 12t.788-3.9t2.137-3.175T8.1 2.788T12 2t3.9.788t3.175 2.137T21.213 8.1T22 12t-.788 3.9t-2.137 3.175t-3.175 2.138T12 22m0-2q3.35 0 5.675-2.325T20 12t-2.325-5.675T12 4T6.325 6.325T4 12t2.325 5.675T12 20m0-8'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1em;height:1em;} +.i-material-symbols\:play-arrow-rounded{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M8 17.175V6.825q0-.425.3-.713t.7-.287q.125 0 .263.037t.262.113l8.15 5.175q.225.15.338.375t.112.475t-.112.475t-.338.375l-8.15 5.175q-.125.075-.262.113T9 18.175q-.4 0-.7-.288t-.3-.712'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1em;height:1em;} +.i-material-symbols\:warning-outline-rounded{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M2.725 21q-.275 0-.5-.137t-.35-.363t-.137-.488t.137-.512l9.25-16q.15-.25.388-.375T12 3t.488.125t.387.375l9.25 16q.15.25.138.513t-.138.487t-.35.363t-.5.137zm1.725-2h15.1L12 6zM12 18q.425 0 .713-.288T13 17t-.288-.712T12 16t-.712.288T11 17t.288.713T12 18m0-3q.425 0 .713-.288T13 14v-3q0-.425-.288-.712T12 10t-.712.288T11 11v3q0 .425.288.713T12 15m0-2.5'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1em;height:1em;} +/* layer: preflights */ +*,::before,::after{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 rgb(0 0 0 / 0);--un-ring-shadow:0 0 rgb(0 0 0 / 0);--un-shadow-inset: ;--un-shadow:0 0 rgb(0 0 0 / 0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgb(147 197 253 / 0.5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: ;}::backdrop{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 rgb(0 0 0 / 0);--un-ring-shadow:0 0 rgb(0 0 0 / 0);--un-shadow-inset: ;--un-shadow:0 0 rgb(0 0 0 / 0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgb(147 197 253 / 0.5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: ;} + + @view-transition { + navigation: auto; + } + html, + :host { + font-family: 'Noto Sans JP', sans-serif !important; + } + video { + max-height: 100%; + max-width: 100%; + } + + + @keyframes fade-in { + from { + opacity: 0; + } + to { + opacity: 1; + } + } + +/* layer: default */ +.\[grid-area\:1\/-1\]{grid-area:1/-1;} +.\[grid-area\:a1\/a1\/a2\/a2\]{grid-area:a1/a1/a2/a2;} +.\[grid-area\:a1\/a1\/b1\/b1\]{grid-area:a1/a1/b1/b1;} +.\[grid-area\:b2\]{grid-area:b2;} +.\[grid-area\:b2\/b2\/b3\/b3\]{grid-area:b2/b2/b3/b3;} +.\[grid-area\:channel\]{grid-area:channel;} +.\[grid-area\:content\]{grid-area:content;} +.\[grid-area\:hours\]{grid-area:hours;} +.\[grid-template-areas\:\'a1_b1\'\'a2_b2\'\'a3_b3\'\]{grid-template-areas:'a1 b1''a2 b2''a3 b3';} +.\[grid-template-areas\:\'channel_channel\'\'hours_content\'\]{grid-template-areas:'channel channel''hours content';} +.pointer-events-none{pointer-events:none;} +.absolute{position:absolute;} +.fixed{position:fixed;} +.relative{position:relative;} +.sticky{position:sticky;} +.before\:absolute::before{position:absolute;} +.inset-0{inset:0;} +.inset-x-0{left:0;right:0;} +.inset-y-0{top:0;bottom:0;} +.before\:inset-x-0::before{left:0;right:0;} +.bottom-\[4px\]{bottom:4px;} +.bottom-\[8px\]{bottom:8px;} +.bottom-0{bottom:0;} +.left-\[4px\]{left:4px;} +.left-0{left:0;} +.right-\[-4px\]{right:-4px;} +.right-\[4px\]{right:4px;} +.top-\[0px\]{top:0px;} +.top-\[80px\]{top:80px;} +.top-0{top:0;} +.before\:bottom-0::before{bottom:0;} +.line-clamp-5{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:5;line-clamp:5;} +.z-\[-10\]{z-index:-10;} +.z-10{z-index:10;} +.z-20{z-index:20;} +.z-50{z-index:50;} +.order-1{order:1;} +.grid{display:grid;} +.auto-cols-\[minmax\(276px\,1fr\)\]{grid-auto-columns:minmax(276px,1fr);} +.grid-flow-col{grid-auto-flow:column;} +.grid-cols-\[188px_minmax\(0\,1fr\)\]{grid-template-columns:188px minmax(0,1fr);} +.grid-rows-\[80px_calc\(100vh-80px\)_minmax\(0\,1fr\)\]{grid-template-rows:80px calc(100vh - 80px) minmax(0,1fr);} +.m-\[14px\]{margin:14px;} +.m-\[4px\]{margin:4px;} +.m-auto{margin:auto;} +.mx-\[-24px\]{margin-left:-24px;margin-right:-24px;} +.mb-\[12px\]{margin-bottom:12px;} +.mb-\[16px\]{margin-bottom:16px;} +.mb-\[24px\]{margin-bottom:24px;} +.mb-\[32px\]{margin-bottom:32px;} +.mb-\[4px\]{margin-bottom:4px;} +.mb-\[8px\]{margin-bottom:8px;} +.ml-\[16px\]{margin-left:16px;} +.ml-\[4px\]{margin-left:4px;} +.mr-\[8px\]{margin-right:8px;} +.mt-\[16px\]{margin-top:16px;} +.mt-\[24px\]{margin-top:24px;} +.mt-\[8px\]{margin-top:8px;} +.block{display:block;} +.before\:block::before{display:block;} +.size-\[20px\]{width:20px;height:20px;} +.size-\[48px\]{width:48px;height:48px;} +.size-full{width:100%;height:100%;} +.h-\[100vh\]{height:100vh;} +.h-\[120px\]{height:120px;} +.h-\[20px\]{height:20px;} +.h-\[260px\]{height:260px;} +.h-\[2px\]{height:2px;} +.h-\[56px\]{height:56px;} +.h-\[72px\]{height:72px;} +.h-\[80px\]{height:80px;} +.h-\[90px\]{height:90px;} +.h-75vh{height:75vh;} +.h-auto{height:auto;} +.h-full{height:100%;} +.max-w-\[1280px\]{max-width:1280px;} +.min-h-\[100vh\]{min-height:100vh;} +.w-\[160px\]{width:160px;} +.w-\[188px\]{width:188px;} +.w-\[192px\]{width:192px;} +.w-\[24px\]{width:24px;} +.w-\[400px\]{width:400px;} +.w-\[480px\]{width:480px;} +.w-\[640px\]{width:640px;} +.w-\[8px\]{width:8px;} +.w-auto{width:auto;} +.w-fit{width:fit-content;} +.w-full{width:100%;} +.group:hover .group-hover\:h-\[4px\]{height:4px;} +.before\:h-\[64px\]::before{height:64px;} +.flex{display:flex;} +.inline-flex{display:inline-flex;} +.shrink-0{flex-shrink:0;} +.shrink-1{flex-shrink:1;} +.grow-0{flex-grow:0;} +.grow-1{flex-grow:1;} +.flex-row{flex-direction:row;} +.flex-col{flex-direction:column;} +.translate-x-\[-50\%\]{--un-translate-x:-50%;transform:translateX(var(--un-translate-x)) translateY(var(--un-translate-y)) translateZ(var(--un-translate-z)) rotate(var(--un-rotate)) rotateX(var(--un-rotate-x)) rotateY(var(--un-rotate-y)) rotateZ(var(--un-rotate-z)) skewX(var(--un-skew-x)) skewY(var(--un-skew-y)) scaleX(var(--un-scale-x)) scaleY(var(--un-scale-y)) scaleZ(var(--un-scale-z));} +.animate-\[fade-in_0\.5s_ease-in_0\.5s_both\]{animation:fade-in 0.5s ease-in 0.5s both;} +.cursor-pointer{cursor:pointer;} +.cursor-col-resize{cursor:col-resize;} +.touch-none{touch-action:none;} +.select-none{-webkit-user-select:none;user-select:none;} +.place-content-center{place-content:center;} +.place-self-center{place-self:center;} +.place-self-stretch{place-self:stretch;} +.items-start{align-items:flex-start;} +.items-center{align-items:center;} +.justify-start{justify-content:flex-start;} +.justify-center{justify-content:center;} +.justify-between{justify-content:space-between;} +.gap-\[24px\]{gap:24px;} +.gap-x-\[12px\]{column-gap:12px;} +.gap-x-\[16px\]{column-gap:16px;} +.gap-y-\[16px\]{row-gap:16px;} +.gap-y-\[20px\]{row-gap:20px;} +.overflow-auto{overflow:auto;} +.overflow-hidden{overflow:hidden;} +.overflow-x-auto{overflow-x:auto;} +.overflow-y-auto{overflow-y:auto;} +.overflow-y-hidden{overflow-y:hidden;} +.border-\[1px\]{border-width:1px;} +.border-\[2px\]{border-width:2px;} +.border-x-\[1px\]{border-left-width:1px;border-right-width:1px;} +.border-y-\[1px\]{border-top-width:1px;border-bottom-width:1px;} +.border-\[\#000000\]{--un-border-opacity:1;border-color:rgb(0 0 0 / var(--un-border-opacity));} +.border-\[\#DDAA00\]{--un-border-opacity:1;border-color:rgb(221 170 0 / var(--un-border-opacity));} +.border-\[\#F0163A\]{--un-border-opacity:1;border-color:rgb(240 22 58 / var(--un-border-opacity));} +.border-\[\#FFFFFF1F\]{--un-border-opacity:0.12;border-color:rgb(255 255 255 / var(--un-border-opacity));} +.border-x-\[\#212121\]{--un-border-opacity:1;--un-border-left-opacity:var(--un-border-opacity);border-left-color:rgb(33 33 33 / var(--un-border-left-opacity));--un-border-right-opacity:var(--un-border-opacity);border-right-color:rgb(33 33 33 / var(--un-border-right-opacity));} +.border-y-\[\#212121\]{--un-border-opacity:1;--un-border-top-opacity:var(--un-border-opacity);border-top-color:rgb(33 33 33 / var(--un-border-top-opacity));--un-border-bottom-opacity:var(--un-border-opacity);border-bottom-color:rgb(33 33 33 / var(--un-border-bottom-opacity));} +.rounded-\[10px\]{border-radius:10px;} +.rounded-\[4px\]{border-radius:4px;} +.rounded-\[8px\]{border-radius:8px;} +.border-solid{border-style:solid;} +.border-x-solid{border-left-style:solid;border-right-style:solid;} +.border-y-solid{border-top-style:solid;border-bottom-style:solid;} +.bg-\[\#000000\]{--un-bg-opacity:1;background-color:rgb(0 0 0 / var(--un-bg-opacity)) /* #000000 */;} +.bg-\[\#00000077\]{--un-bg-opacity:0.47;background-color:rgb(0 0 0 / var(--un-bg-opacity)) /* #00000077 */;} +.bg-\[\#000000CC\]{--un-bg-opacity:0.8;background-color:rgb(0 0 0 / var(--un-bg-opacity)) /* #000000CC */;} +.bg-\[\#171717\]{--un-bg-opacity:1;background-color:rgb(23 23 23 / var(--un-bg-opacity)) /* #171717 */;} +.bg-\[\#1c43d1\]{--un-bg-opacity:1;background-color:rgb(28 67 209 / var(--un-bg-opacity)) /* #1c43d1 */;} +.bg-\[\#999999\]{--un-bg-opacity:1;background-color:rgb(153 153 153 / var(--un-bg-opacity)) /* #999999 */;} +.bg-\[\#ffeeee\]{--un-bg-opacity:1;background-color:rgb(255 238 238 / var(--un-bg-opacity)) /* #ffeeee */;} +.bg-\[\#fffcee\]{--un-bg-opacity:1;background-color:rgb(255 252 238 / var(--un-bg-opacity)) /* #fffcee */;} +.bg-\[\#FFFFFF\]{--un-bg-opacity:1;background-color:rgb(255 255 255 / var(--un-bg-opacity)) /* #FFFFFF */;} +.bg-\[size\:auto_100\%\]{background-size:auto 100%;} +.bg-transparent{background-color:transparent /* transparent */;} +.hover\:bg-\[\#FFFFFF1F\]:hover{--un-bg-opacity:0.12;background-color:rgb(255 255 255 / var(--un-bg-opacity)) /* #FFFFFF1F */;} +.from-\[\#171717\]{--un-gradient-from-position:0%;--un-gradient-from:rgb(23 23 23 / var(--un-from-opacity, 1)) var(--un-gradient-from-position);--un-gradient-to-position:100%;--un-gradient-to:rgb(23 23 23 / 0) var(--un-gradient-to-position);--un-gradient-stops:var(--un-gradient-from), var(--un-gradient-to);} +.from-\[\#212121\]{--un-gradient-from-position:0%;--un-gradient-from:rgb(33 33 33 / var(--un-from-opacity, 1)) var(--un-gradient-from-position);--un-gradient-to-position:100%;--un-gradient-to:rgb(33 33 33 / 0) var(--un-gradient-to-position);--un-gradient-stops:var(--un-gradient-from), var(--un-gradient-to);} +.before\:from-\[\#212121\]::before{--un-gradient-from-position:0%;--un-gradient-from:rgb(33 33 33 / var(--un-from-opacity, 1)) var(--un-gradient-from-position);--un-gradient-to-position:100%;--un-gradient-to:rgb(33 33 33 / 0) var(--un-gradient-to-position);--un-gradient-stops:var(--un-gradient-from), var(--un-gradient-to);} +.to-\[\#171717\]{--un-gradient-to-position:100%;--un-gradient-to:rgb(23 23 23 / var(--un-to-opacity, 1)) var(--un-gradient-to-position);} +.to-transparent{--un-gradient-to-position:100%;--un-gradient-to:transparent var(--un-gradient-to-position);} +.before\:to-transparent::before{--un-gradient-to-position:100%;--un-gradient-to:transparent var(--un-gradient-to-position);} +.bg-gradient-to-b{--un-gradient-shape:to bottom in oklch;--un-gradient:var(--un-gradient-shape), var(--un-gradient-stops);background-image:linear-gradient(var(--un-gradient));} +.bg-gradient-to-t{--un-gradient-shape:to top in oklch;--un-gradient:var(--un-gradient-shape), var(--un-gradient-stops);background-image:linear-gradient(var(--un-gradient));} +.before\:bg-gradient-to-t::before{--un-gradient-shape:to top in oklch;--un-gradient:var(--un-gradient-shape), var(--un-gradient-stops);background-image:linear-gradient(var(--un-gradient));} +.object-contain{object-fit:contain;} +.p-\[12px\]{padding:12px;} +.p-\[14px\]{padding:14px;} +.p-\[24px\]{padding:24px;} +.p-\[4px\]{padding:4px;} +.p-\[8px\]{padding:8px;} +.px{padding-left:1rem;padding-right:1rem;} +.px-\[12px\]{padding-left:12px;padding-right:12px;} +.px-\[16px\]{padding-left:16px;padding-right:16px;} +.px-\[24px\]{padding-left:24px;padding-right:24px;} +.px-\[32px\]{padding-left:32px;padding-right:32px;} +.px-\[8px\]{padding-left:8px;padding-right:8px;} +.py-\[32px\]{padding-top:32px;padding-bottom:32px;} +.py-\[48px\]{padding-top:48px;padding-bottom:48px;} +.py-\[8px\]{padding-top:8px;padding-bottom:8px;} +.pb-\[8px\]{padding-bottom:8px;} +.pl-\[20px\]{padding-left:20px;} +.pl-\[24px\]{padding-left:24px;} +.pr-\[56px\]{padding-right:56px;} +.pr-\[8px\]{padding-right:8px;} +.pt-\[80px\]{padding-top:80px;} +.pt-\[8px\]{padding-top:8px;} +.text-center{text-align:center;} +.text-left{text-align:left;} +.text-\[10px\]{font-size:10px;} +.text-\[12px\]{font-size:12px;} +.text-\[14px\]{font-size:14px;} +.text-\[16px\]{font-size:16px;} +.text-\[18px\]{font-size:18px;} +.text-\[22px\]{font-size:22px;} +.text-\[24px\]{font-size:24px;} +.text-\[32px\]{font-size:32px;} +.text-\[\#212121\]{--un-text-opacity:1;color:rgb(33 33 33 / var(--un-text-opacity)) /* #212121 */;} +.text-\[\#999999\]{--un-text-opacity:1;color:rgb(153 153 153 / var(--un-text-opacity)) /* #999999 */;} +.text-\[\#DDAA00\]{--un-text-opacity:1;color:rgb(221 170 0 / var(--un-text-opacity)) /* #DDAA00 */;} +.text-\[\#F0163A\]{--un-text-opacity:1;color:rgb(240 22 58 / var(--un-text-opacity)) /* #F0163A */;} +.text-\[\#ffffff\]{--un-text-opacity:1;color:rgb(255 255 255 / var(--un-text-opacity)) /* #ffffff */;} +.text-\[\#FFFFFF\]{--un-text-opacity:1;color:rgb(255 255 255 / var(--un-text-opacity)) /* #FFFFFF */;} +.placeholder\:text-\[\#999999\]::placeholder{--un-text-opacity:1;color:rgb(153 153 153 / var(--un-text-opacity)) /* #999999 */;} +.font-bold{font-weight:700;} +.underline{text-decoration-line:underline;} +.opacity-0{opacity:0;} +.group:hover .group-hover\:opacity-100{opacity:1;} +.hover\:opacity-50:hover{opacity:0.5;} +.hover\:opacity-75:hover{opacity:0.75;} +.disabled\:opacity-50:disabled{opacity:0.5;} +.outline-\[1px\]{outline-width:1px;} +.outline-\[\#212121\]{--un-outline-color-opacity:1;outline-color:rgb(33 33 33 / var(--un-outline-color-opacity)) /* #212121 */;} +.outline{outline-style:solid;} +.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px;} +.hover\:brightness-125:hover{--un-brightness:brightness(1.25);filter:var(--un-blur) var(--un-brightness) var(--un-contrast) var(--un-drop-shadow) var(--un-grayscale) var(--un-hue-rotate) var(--un-invert) var(--un-saturate) var(--un-sepia);} +.hover\:brightness-200:hover{--un-brightness:brightness(2);filter:var(--un-blur) var(--un-brightness) var(--un-contrast) var(--un-drop-shadow) var(--un-grayscale) var(--un-hue-rotate) var(--un-invert) var(--un-saturate) var(--un-sepia);} +.before\:content-\[\'\'\]::before{content:'';} \ No newline at end of file diff --git a/workspaces/client/tsconfig.json b/workspaces/client/tsconfig.json index 328b4cedb..fe3ab8e6e 100644 --- a/workspaces/client/tsconfig.json +++ b/workspaces/client/tsconfig.json @@ -9,7 +9,7 @@ "skipLibCheck": true, "target": "ESNext" }, - "exclude": ["dist"], + "exclude": ["build"], "extends": "@wsh-2025/configs/tsconfig.json", - "include": ["**/*", "**/*.mjs"] + "include": ["**/*", "**/.server/**/*", "**/.client/**/*", ".react-router/types/**/*"] } diff --git a/workspaces/client/uno.config.ts b/workspaces/client/uno.config.ts new file mode 100644 index 000000000..40911b286 --- /dev/null +++ b/workspaces/client/uno.config.ts @@ -0,0 +1,45 @@ +import { defineConfig, presetIcons, presetWind3 } from 'unocss'; + +export default defineConfig({ + layers: { + default: 1, + icons: 0, + preflights: 0, + reset: -1, + } as const, + preflights: [ + { + getCSS: () => /* css */ ` + @view-transition { + navigation: auto; + } + html, + :host { + font-family: 'Noto Sans JP', sans-serif !important; + } + video { + max-height: 100%; + max-width: 100%; + } + `, + }, + { + getCSS: () => /* css */ ` + @keyframes fade-in { + from { + opacity: 0; + } + to { + opacity: 1; + } + } + `, + }, + ], + presets: [ + presetWind3(), + presetIcons({ + autoInstall: true, + }), + ], +}); diff --git a/workspaces/client/vite.config.ts b/workspaces/client/vite.config.ts new file mode 100644 index 000000000..9d7421841 --- /dev/null +++ b/workspaces/client/vite.config.ts @@ -0,0 +1,66 @@ +import path from 'node:path'; + +import { cloudflare } from '@cloudflare/vite-plugin'; +import { reactRouter } from '@react-router/dev/vite'; +import { visualizer } from 'rollup-plugin-visualizer'; +import UnoCSS from 'unocss/vite'; +import { defineConfig } from 'vite'; +import tsconfigPaths from 'vite-tsconfig-paths'; + +// https://vitejs.dev/config/ +export default defineConfig(({ mode }) => ({ + assetsInclude: ['**/*.wasm'], + build: { + rollupOptions: { + plugins: [ + mode === 'analyze' && + visualizer({ + brotliSize: true, + filename: 'dist/stats.html', + gzipSize: true, + open: true, + }), + ], + }, + }, + define: { + 'process.env.API_BASE_URL': JSON.stringify('/api'), + 'process.env.NODE_ENV': JSON.stringify(process.env['NODE_ENV'] || 'production'), + }, + plugins: [cloudflare({ viteEnvironment: { name: 'ssr' } }), reactRouter(), UnoCSS(), tsconfigPaths()], + resolve: { + alias: { + // CI環境でも動作するように修正 + '@ffmpeg/core$': + process.env['NODE_ENV'] === 'production' + ? '@ffmpeg/core/dist/umd/ffmpeg-core.js' + : path.resolve(__dirname, 'node_modules', '@ffmpeg/core/dist/umd/ffmpeg-core.js'), + '@ffmpeg/core/wasm$': + process.env['NODE_ENV'] === 'production' + ? '@ffmpeg/core/dist/umd/ffmpeg-core.wasm' + : path.resolve(__dirname, 'node_modules', '@ffmpeg/core/dist/umd/ffmpeg-core.wasm'), + }, + }, + server: { + open: true, + port: 3000, + proxy: { + // '/api': { + // changeOrigin: true, + // target: 'http://localhost:8000', + // }, + '/favicon.ico': { + changeOrigin: true, + target: 'http://localhost:8000', + }, + // '/public': { + // changeOrigin: true, + // target: 'http://localhost:8000', + // }, + // '/streams': { + // changeOrigin: true, + // target: 'http://localhost:8000', + // }, + }, + }, +})); diff --git a/workspaces/client/webpack.config.mjs b/workspaces/client/webpack.config.mjs index 9164a996e..142094589 100644 --- a/workspaces/client/webpack.config.mjs +++ b/workspaces/client/webpack.config.mjs @@ -1,74 +1,71 @@ -import path from 'node:path'; +// import path from 'node:path'; -import webpack from 'webpack'; +// import webpack from 'webpack'; -/** @type {import('webpack').Configuration} */ -const config = { - devtool: 'inline-source-map', - entry: './src/main.tsx', - mode: 'none', - module: { - rules: [ - { - exclude: [/node_modules\/video\.js/, /node_modules\/@videojs/], - resolve: { - fullySpecified: false, - }, - test: /\.(?:js|mjs|cjs|jsx|ts|mts|cts|tsx)$/, - use: { - loader: 'babel-loader', - options: { - presets: [ - [ - '@babel/preset-env', - { - corejs: '3.41', - forceAllTransforms: true, - targets: 'defaults', - useBuiltIns: 'entry', - }, - ], - ['@babel/preset-react', { runtime: 'automatic' }], - ['@babel/preset-typescript'], - ], - }, - }, - }, - { - test: /\.png$/, - type: 'asset/inline', - }, - { - resourceQuery: /raw/, - type: 'asset/source', - }, - { - resourceQuery: /arraybuffer/, - type: 'javascript/auto', - use: { - loader: 'arraybuffer-loader', - }, - }, - ], - }, - output: { - chunkFilename: 'chunk-[contenthash].js', - chunkFormat: false, - filename: 'main.js', - path: path.resolve(import.meta.dirname, './dist'), - publicPath: 'auto', - }, - plugins: [ - new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 }), - new webpack.EnvironmentPlugin({ API_BASE_URL: '/api', NODE_ENV: '' }), - ], - resolve: { - alias: { - '@ffmpeg/core$': path.resolve(import.meta.dirname, 'node_modules', '@ffmpeg/core/dist/umd/ffmpeg-core.js'), - '@ffmpeg/core/wasm$': path.resolve(import.meta.dirname, 'node_modules', '@ffmpeg/core/dist/umd/ffmpeg-core.wasm'), - }, - extensions: ['.js', '.cjs', '.mjs', '.ts', '.cts', '.mts', '.tsx', '.jsx'], - }, -}; +// /** @type {import('webpack').Configuration} */ +// const config = { +// module: { +// rules: [ +// { +// exclude: [/node_modules\/video\.js/, /node_modules\/@videojs/], +// resolve: { +// fullySpecified: false, +// }, +// test: /\.(?:js|mjs|cjs|jsx|ts|mts|cts|tsx)$/, +// use: { +// loader: 'babel-loader', +// options: { +// presets: [ +// [ +// '@babel/preset-env', +// { +// corejs: '3.41', +// forceAllTransforms: true, +// targets: 'defaults', +// useBuiltIns: 'entry', +// }, +// ], +// ['@babel/preset-react', { runtime: 'automatic' }], +// ['@babel/preset-typescript'], +// ], +// }, +// }, +// }, +// { +// test: /\.png$/, +// type: 'asset/inline', +// }, +// { +// resourceQuery: /raw/, +// type: 'asset/source', +// }, +// { +// resourceQuery: /arraybuffer/, +// type: 'javascript/auto', +// use: { +// loader: 'arraybuffer-loader', +// }, +// }, +// ], +// }, +// output: { +// chunkFilename: 'chunk-[contenthash].js', +// chunkFormat: false, +// filename: 'main.js', +// path: path.resolve(import.meta.dirname, './dist'), +// publicPath: 'auto', +// }, +// plugins: [ +// new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 }), +// new webpack.EnvironmentPlugin({ API_BASE_URL: '/api', NODE_ENV: '' }), +// ], +// resolve: { +// alias: { +// '@ffmpeg/core$': path.resolve(import.meta.dirname, 'node_modules', '@ffmpeg/core/dist/umd/ffmpeg-core.js'), +// '@ffmpeg/core/wasm$': path.resolve(import.meta.dirname, 'node_modules', '@ffmpeg/core/dist/umd/ffmpeg-core.wasm'), +// }, +// extensions: ['.js', '.cjs', '.mjs', '.ts', '.cts', '.mts', '.tsx', '.jsx'], +// }, +// }; -export default config; +// export default config; diff --git a/workspaces/client/workers/app.ts b/workspaces/client/workers/app.ts new file mode 100644 index 000000000..c634ad227 --- /dev/null +++ b/workspaces/client/workers/app.ts @@ -0,0 +1,28 @@ +import { createRequestHandler } from "react-router"; + +declare global { + interface CloudflareEnvironment extends Env {} +} + +declare module "react-router" { + export interface AppLoadContext { + cloudflare: { + ctx: ExecutionContext; + env: CloudflareEnvironment; + }; + } +} + +const requestHandler = createRequestHandler( + // @ts-expect-error - virtual module provided by React Router + () => import("virtual:react-router/server-build"), + import.meta.env.MODE +); + +export default { + async fetch(request, env, ctx) { + return requestHandler(request, { + cloudflare: { ctx, env }, + }); + }, +} satisfies ExportedHandler; diff --git a/workspaces/client/wrangler.jsonc b/workspaces/client/wrangler.jsonc new file mode 100644 index 000000000..06b6e464b --- /dev/null +++ b/workspaces/client/wrangler.jsonc @@ -0,0 +1,12 @@ +{ + "$schema": "node_modules/wrangler/config-schema.json", + "name": "web-speed-hack", + "compatibility_date": "2025-02-24", + "main": "./workers/app.ts", + "assets": {}, + "vars": { + "VALUE_FROM_CLOUDFLARE": "Hello from Cloudflare", + "VITE_API_BASE_URL": "https://wsh-2025-server.onrender.com/api", + "VITE_STREAM_BASE_URL": "https://wsh-2025-server.onrender.com", + }, +} diff --git a/workspaces/configs/eslint.config.mjs b/workspaces/configs/eslint.config.mjs index a6955e4f6..93afc69f1 100644 --- a/workspaces/configs/eslint.config.mjs +++ b/workspaces/configs/eslint.config.mjs @@ -1,5 +1,5 @@ import eslint from '@eslint/js'; -import * as eslintConfigPrettier from 'eslint-config-prettier'; +import eslintConfigPrettier from 'eslint-config-prettier'; import eslintPluginImport from 'eslint-plugin-import'; import eslintPluginReact from 'eslint-plugin-react'; import eslintPluginSort from 'eslint-plugin-sort'; diff --git a/workspaces/schema/package.json b/workspaces/schema/package.json index af2c14758..bc198ba05 100644 --- a/workspaces/schema/package.json +++ b/workspaces/schema/package.json @@ -7,18 +7,13 @@ "format:prettier": "wireit" }, "dependencies": { - "@sinclair/typebox": "0.34.30", - "@sinclair/typemap": "0.8.18", "drizzle-orm": "0.38.2", "drizzle-zod": "0.6.0", - "luxon": "3.5.0", - "valibot": "1.0.0-rc.3", "zod": "3.24.1", "zod-openapi": "4.2.0" }, "devDependencies": { "@wsh-2025/configs": "workspace:*", - "@wsh-2025/schema": "workspace:*", "wireit": "0.14.9" }, "wireit": { diff --git a/workspaces/schema/src/api/schema.ts b/workspaces/schema/src/api/schema.ts deleted file mode 100644 index ed327fd43..000000000 --- a/workspaces/schema/src/api/schema.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Compile, TypeBox, Valibot, Zod } from '@sinclair/typemap'; - -import * as openapiSchema from '@wsh-2025/schema/src/openapi/schema'; - -export const getChannelsRequestQuery = Compile(TypeBox(openapiSchema.getChannelsRequestQuery)); -export const getChannelsResponse = Compile(TypeBox(openapiSchema.getChannelsResponse)); -export const getChannelByIdRequestParams = Compile(TypeBox(openapiSchema.getChannelByIdRequestParams)); -export const getChannelByIdResponse = Compile(TypeBox(openapiSchema.getChannelByIdResponse)); -export const getEpisodesRequestQuery = Compile(TypeBox(openapiSchema.getEpisodesRequestQuery)); -export const getEpisodesResponse = Compile(TypeBox(openapiSchema.getEpisodesResponse)); -export const getEpisodeByIdRequestParams = Compile(TypeBox(openapiSchema.getEpisodeByIdRequestParams)); -export const getEpisodeByIdResponse = Compile(TypeBox(openapiSchema.getEpisodeByIdResponse)); -export const getSeriesRequestQuery = Compile(Valibot(openapiSchema.getSeriesRequestQuery)); -export const getSeriesResponse = Compile(Valibot(openapiSchema.getSeriesResponse)); -export const getSeriesByIdRequestParams = Compile(Valibot(openapiSchema.getSeriesByIdRequestParams)); -export const getSeriesByIdResponse = Compile(Valibot(openapiSchema.getSeriesByIdResponse)); -export const getTimetableRequestQuery = Compile(Valibot(openapiSchema.getTimetableRequestQuery)); -export const getTimetableResponse = Compile(Valibot(openapiSchema.getTimetableResponse)); -export const getProgramsRequestQuery = Compile(Valibot(openapiSchema.getProgramsRequestQuery)); -export const getProgramsResponse = Compile(Valibot(openapiSchema.getProgramsResponse)); -export const getProgramByIdRequestParams = Compile(Valibot(openapiSchema.getProgramByIdRequestParams)); -export const getProgramByIdResponse = Compile(Valibot(openapiSchema.getProgramByIdResponse)); -export const getRecommendedModulesRequestParams = Compile(Valibot(openapiSchema.getRecommendedModulesRequestParams)); -export const getRecommendedModulesResponse = Compile(Valibot(openapiSchema.getRecommendedModulesResponse)); -export const signInRequestBody = Compile(Zod(openapiSchema.signInRequestBody)); -export const signInResponse = Compile(Zod(openapiSchema.signInResponse)); -export const signUpRequestBody = Compile(Zod(openapiSchema.signUpRequestBody)); -export const signUpResponse = Compile(Zod(openapiSchema.signUpResponse)); -export const getUserResponse = Compile(Zod(openapiSchema.getUserResponse)); diff --git a/workspaces/schema/src/database/schema.ts b/workspaces/schema/src/database/schema.ts index 7a08aec3e..2e654a2c3 100644 --- a/workspaces/schema/src/database/schema.ts +++ b/workspaces/schema/src/database/schema.ts @@ -1,27 +1,26 @@ /* eslint-disable sort/object-properties */ -import '@wsh-2025/schema/src/setups/luxon'; import { relations } from 'drizzle-orm'; -import { sqliteTable as table } from 'drizzle-orm/sqlite-core'; -import * as t from 'drizzle-orm/sqlite-core'; -import { DateTime } from 'luxon'; +import { customType, integer, sqliteTable as table, text } from 'drizzle-orm/sqlite-core'; -function parseTime(timeString: string): DateTime { - const parsed = DateTime.fromFormat(timeString, 'HH:mm:ss').toObject(); - return DateTime.now().set({ - hour: parsed.hour, - minute: parsed.minute, - second: parsed.second, - millisecond: 0, - }); +function parseTime(timeString: string): Date { + const parts = timeString.split(':').map(Number); + const hours = parts[0] || 0; + const minutes = parts[1] || 0; + const seconds = parts[2] || 0; + const now = new Date(); + now.setHours(hours, minutes, seconds, 0); + return now; } function formatTime(isoString: string): string { - return DateTime.fromISO(isoString).toFormat('HH:mm:ss'); + const date = new Date(isoString); + const timeParts = date.toTimeString().split(' '); + return timeParts[0] || '00:00:00'; } // 競技のため、時刻のみ保持して、日付は現在の日付にします -const startAtTimestamp = t.customType<{ +const startAtTimestamp = customType<{ data: string; driverData: string; }>({ @@ -29,7 +28,7 @@ const startAtTimestamp = t.customType<{ return 'text'; }, fromDriver(timeString: string) { - return parseTime(timeString).toISO(); + return parseTime(timeString).toISOString(); }, toDriver(isoString: string) { return formatTime(isoString); @@ -38,7 +37,7 @@ const startAtTimestamp = t.customType<{ // 競技のため、時刻のみ保持して、日付は現在の日付にします // 放送終了時刻が 00:00:00 の場合は、翌日の 00:00:00 にします -const endAtTimestamp = t.customType<{ +const endAtTimestamp = customType<{ data: string; driverData: string; }>({ @@ -47,10 +46,11 @@ const endAtTimestamp = t.customType<{ }, fromDriver(timeString: string) { const parsed = parseTime(timeString); - if (DateTime.now().startOf('day').equals(parsed)) { - return parsed.plus({ day: 1 }).toISO(); + // 00:00:00の場合は翌日の00:00:00にする + if (parsed.getHours() === 0 && parsed.getMinutes() === 0 && parsed.getSeconds() === 0) { + parsed.setDate(parsed.getDate() + 1); } - return parsed.toISO(); + return parsed.toISOString(); }, toDriver(isoString: string) { return formatTime(isoString); @@ -60,8 +60,8 @@ const endAtTimestamp = t.customType<{ export const stream = table( 'stream', { - id: t.text().primaryKey(), - numberOfChunks: t.integer().notNull(), + id: text().primaryKey(), + numberOfChunks: integer().notNull(), }, () => [], ); @@ -69,10 +69,10 @@ export const stream = table( export const series = table( 'series', { - id: t.text().primaryKey(), - description: t.text().notNull(), - thumbnailUrl: t.text().notNull(), - title: t.text().notNull(), + id: text().primaryKey(), + description: text().notNull(), + thumbnailUrl: text().notNull(), + title: text().notNull(), }, () => [], ); @@ -83,20 +83,18 @@ export const seriesRelation = relations(series, ({ many }) => ({ export const episode = table( 'episode', { - id: t.text().primaryKey(), - description: t.text().notNull(), - thumbnailUrl: t.text().notNull(), - title: t.text().notNull(), - order: t.integer().notNull(), - seriesId: t - .text() + id: text().primaryKey(), + description: text().notNull(), + thumbnailUrl: text().notNull(), + title: text().notNull(), + order: integer().notNull(), + seriesId: text() .notNull() .references(() => series.id), - streamId: t - .text() + streamId: text() .notNull() .references(() => stream.id), - premium: t.integer({ mode: 'boolean' }).notNull(), + premium: integer({ mode: 'boolean' }).notNull(), }, () => [], ); @@ -114,9 +112,9 @@ export const episodeRelation = relations(episode, ({ one }) => ({ export const channel = table( 'channel', { - id: t.text().primaryKey(), - name: t.text().notNull(), - logoUrl: t.text().notNull(), + id: text().primaryKey(), + name: text().notNull(), + logoUrl: text().notNull(), }, () => [], ); @@ -124,18 +122,16 @@ export const channel = table( export const program = table( 'program', { - id: t.text().primaryKey(), - title: t.text().notNull(), - description: t.text().notNull(), + id: text().primaryKey(), + title: text().notNull(), + description: text().notNull(), startAt: startAtTimestamp().notNull(), endAt: endAtTimestamp().notNull(), - thumbnailUrl: t.text().notNull(), - channelId: t - .text() + thumbnailUrl: text().notNull(), + channelId: text() .notNull() .references(() => channel.id), - episodeId: t - .text() + episodeId: text() .notNull() .references(() => episode.id), }, @@ -155,14 +151,13 @@ export const programRelation = relations(program, ({ one }) => ({ export const recommendedItem = table( 'recommendedItem', { - id: t.text().primaryKey(), - order: t.integer().notNull(), - moduleId: t - .text() + id: text().primaryKey(), + order: integer().notNull(), + moduleId: text() .notNull() .references(() => recommendedModule.id), - seriesId: t.text().references(() => series.id), - episodeId: t.text().references(() => episode.id), + seriesId: text().references(() => series.id), + episodeId: text().references(() => episode.id), }, () => [], ); @@ -184,11 +179,11 @@ export const recommendedItemRelation = relations(recommendedItem, ({ one }) => ( export const recommendedModule = table( 'recommendedModule', { - id: t.text().primaryKey(), - order: t.integer().notNull(), - title: t.text().notNull(), - referenceId: t.text().notNull(), - type: t.text().notNull(), + id: text().primaryKey(), + order: integer().notNull(), + title: text().notNull(), + referenceId: text().notNull(), + type: text().notNull(), }, () => [], ); @@ -199,9 +194,9 @@ export const recommendedModuleRelation = relations(recommendedModule, ({ many }) export const user = table( 'user', { - id: t.integer().primaryKey().notNull(), - email: t.text().notNull().unique(), - password: t.text().notNull(), + id: integer().primaryKey().notNull(), + email: text().notNull().unique(), + password: text().notNull(), }, () => [], ); diff --git a/workspaces/schema/src/openapi/schema.ts b/workspaces/schema/src/openapi/schema.ts index fb64a2f3d..aa836f0e3 100644 --- a/workspaces/schema/src/openapi/schema.ts +++ b/workspaces/schema/src/openapi/schema.ts @@ -4,7 +4,15 @@ import 'zod-openapi/extend'; import { createSelectSchema } from 'drizzle-zod'; import { z } from 'zod'; -import * as databaseSchema from '@wsh-2025/schema/src/database/schema'; +import { + channel as databaseSchemaChannel, + episode as databaseSchemaEpisode, + program as databaseSchemaProgram, + recommendedItem as databaseSchemaRecommendedItem, + recommendedModule as databaseSchemaRecommendedModule, + series as databaseSchemaSeries, + user as databaseSchemaUser, +} from '@wsh-2025/schema/src/database/schema'; function assertSchema(_actual: z.ZodType>, _expected: z.ZodType): void {} @@ -13,7 +21,7 @@ const channel = z.object({ logoUrl: z.string().openapi({ example: 'https://image.example.com/assets/d13d2e22-a7ff-44ba-94a3-5f025f2b63cd.png' }), name: z.string().openapi({ example: 'AREMA NEWS' }), }); -assertSchema(channel, createSelectSchema(databaseSchema.channel)); +assertSchema(channel, createSelectSchema(databaseSchemaChannel)); const episode = z.object({ id: z.string().openapi({ format: 'uuid' }), @@ -30,7 +38,7 @@ const episode = z.object({ }), premium: z.boolean().openapi({ example: false }), }); -assertSchema(episode, createSelectSchema(databaseSchema.episode)); +assertSchema(episode, createSelectSchema(databaseSchemaEpisode)); const series = z.object({ id: z.string().openapi({ format: 'uuid' }), @@ -43,7 +51,7 @@ const series = z.object({ example: 'https://image.example.com/assets/d13d2e22-a7ff-44ba-94a3-5f025f2b63cd.png', }), }); -assertSchema(series, createSelectSchema(databaseSchema.series)); +assertSchema(series, createSelectSchema(databaseSchemaSeries)); const program = z.object({ id: z.string().openapi({ format: 'uuid' }), @@ -60,7 +68,7 @@ const program = z.object({ channelId: z.string().openapi({ format: 'uuid' }), episodeId: z.string().openapi({ format: 'uuid' }), }); -assertSchema(program, createSelectSchema(databaseSchema.program)); +assertSchema(program, createSelectSchema(databaseSchemaProgram)); const recommendedModule = z.object({ id: z.string().openapi({ format: 'uuid' }), @@ -69,7 +77,7 @@ const recommendedModule = z.object({ referenceId: z.string().openapi({ format: 'uuid' }), type: z.enum(['carousel', 'jumbotron']).openapi({ example: 'carousel' }), }); -assertSchema(recommendedModule, createSelectSchema(databaseSchema.recommendedModule)); +assertSchema(recommendedModule, createSelectSchema(databaseSchemaRecommendedModule)); const recommendedItem = z.object({ id: z.string().openapi({ format: 'uuid' }), @@ -78,14 +86,14 @@ const recommendedItem = z.object({ episodeId: z.string().nullable().openapi({ format: 'uuid' }), moduleId: z.string().openapi({ format: 'uuid' }), }); -assertSchema(recommendedItem, createSelectSchema(databaseSchema.recommendedItem)); +assertSchema(recommendedItem, createSelectSchema(databaseSchemaRecommendedItem)); const user = z.object({ id: z.number().openapi({ format: '0' }), email: z.string().openapi({ example: 'user123' }), password: z.string().openapi({ example: 'password123' }), }); -assertSchema(user, createSelectSchema(databaseSchema.user)); +assertSchema(user, createSelectSchema(databaseSchemaUser)); // GET /channels export const getChannelsRequestQuery = z.object({ diff --git a/workspaces/schema/src/setups/luxon.ts b/workspaces/schema/src/setups/luxon.ts deleted file mode 100644 index 48132ca90..000000000 --- a/workspaces/schema/src/setups/luxon.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Settings } from 'luxon'; - -declare module 'luxon' { - interface TSSettings { - throwOnInvalid: true; - } -} - -Settings.defaultZone = 'Asia/Tokyo'; -Settings.throwOnInvalid = true; diff --git a/workspaces/server/database.sqlite b/workspaces/server/database.sqlite index 5afaf4e28..dc6441e53 100644 Binary files a/workspaces/server/database.sqlite and b/workspaces/server/database.sqlite differ diff --git a/workspaces/server/loaders/png.cjs b/workspaces/server/loaders/png.cjs deleted file mode 100644 index a7efb4a1b..000000000 --- a/workspaces/server/loaders/png.cjs +++ /dev/null @@ -1,9 +0,0 @@ -/* eslint-disable */ - -const Module = require('module'); -const fs = require('fs'); - -Module._extensions['.png'] = function (module, fn) { - const base64 = fs.readFileSync(fn).toString('base64'); - module._compile('module.exports="data:image/png;base64,' + base64 + '"', fn); -}; diff --git a/workspaces/server/package.json b/workspaces/server/package.json index 456f1fbd3..cf71777b2 100644 --- a/workspaces/server/package.json +++ b/workspaces/server/package.json @@ -2,13 +2,16 @@ "name": "@wsh-2025/server", "private": true, "scripts": { + "build": "tsc", "database:migrate": "wireit", "database:reset": "wireit", "format": "wireit", "format:eslint": "wireit", "format:prettier": "wireit", "heroku-start": "wireit", - "start": "wireit" + "start": "wireit", + "start-render": "node ./dist/server/src/index.js", + "type-check": "tsc --noEmit" }, "dependencies": { "@fastify/cookie": "11.0.2", @@ -64,29 +67,22 @@ "command": "tsx ./tools/seed.ts" }, "start": { - "command": "tsx -r ./loaders/png.cjs ./src/index.ts", + "command": "tsx ./src/index.ts", "service": true, "env": { "API_BASE_URL": { "external": true, "default": "http://localhost:8000/api" - }, - "PORT": { - "external": true, - "default": "8000" } }, "files": [ "../../pnpm-lock.yaml", "../schema/src/**/*", "./src/**/*" - ], - "dependencies": [ - "../client:build" ] }, "heroku-start": { - "command": "tsx -r ./loaders/png.cjs ./src/index.ts", + "command": "tsx ./src/index.ts", "service": true, "env": { "API_BASE_URL": { diff --git a/workspaces/server/src/api.ts b/workspaces/server/src/api.ts index 635624b1f..8eb30af4d 100644 --- a/workspaces/server/src/api.ts +++ b/workspaces/server/src/api.ts @@ -6,9 +6,35 @@ import fastifyCookie from '@fastify/cookie'; import fastifySession from '@fastify/session'; import fastifySwagger from '@fastify/swagger'; import fastifySwaggerUi from '@fastify/swagger-ui'; -import * as databaseSchema from '@wsh-2025/schema/src/database/schema'; -import * as schema from '@wsh-2025/schema/src/openapi/schema'; -import * as bcrypt from 'bcrypt'; +import { user as userTable } from '@wsh-2025/schema/src/database/schema'; +import { + getChannelByIdRequestParams, + getChannelByIdResponse, + getChannelsRequestQuery, + getChannelsResponse, + getEpisodeByIdRequestParams, + getEpisodeByIdResponse, + getEpisodesRequestQuery, + getEpisodesResponse, + getProgramByIdRequestParams, + getProgramByIdResponse, + getProgramsRequestQuery, + getProgramsResponse, + getRecommendedModulesRequestParams, + getRecommendedModulesResponse, + getSeriesByIdRequestParams, + getSeriesByIdResponse, + getSeriesRequestQuery, + getSeriesResponse, + getTimetableRequestQuery, + getTimetableResponse, + getUserResponse, + signInRequestBody, + signInResponse, + signUpRequestBody, + signUpResponse, +} from '@wsh-2025/schema/src/openapi/schema'; +import { compareSync, hashSync } from 'bcrypt'; import type { FastifyInstance } from 'fastify'; import { fastifyZodOpenApiPlugin, @@ -81,12 +107,12 @@ export async function registerApi(app: FastifyInstance): Promise { url: '/channels', schema: { tags: ['チャンネル'], - querystring: schema.getChannelsRequestQuery, + querystring: getChannelsRequestQuery, response: { 200: { content: { 'application/json': { - schema: schema.getChannelsResponse, + schema: getChannelsResponse, }, }, }, @@ -116,12 +142,12 @@ export async function registerApi(app: FastifyInstance): Promise { url: '/channels/:channelId', schema: { tags: ['チャンネル'], - params: schema.getChannelByIdRequestParams, + params: getChannelByIdRequestParams, response: { 200: { content: { 'application/json': { - schema: schema.getChannelByIdResponse, + schema: getChannelByIdResponse, }, }, }, @@ -147,12 +173,12 @@ export async function registerApi(app: FastifyInstance): Promise { url: '/episodes', schema: { tags: ['エピソード'], - querystring: schema.getEpisodesRequestQuery, + querystring: getEpisodesRequestQuery, response: { 200: { content: { 'application/json': { - schema: schema.getEpisodesResponse, + schema: getEpisodesResponse, }, }, }, @@ -193,12 +219,12 @@ export async function registerApi(app: FastifyInstance): Promise { url: '/episodes/:episodeId', schema: { tags: ['エピソード'], - params: schema.getEpisodeByIdRequestParams, + params: getEpisodeByIdRequestParams, response: { 200: { content: { 'application/json': { - schema: schema.getEpisodeByIdResponse, + schema: getEpisodeByIdResponse, }, }, }, @@ -235,12 +261,12 @@ export async function registerApi(app: FastifyInstance): Promise { url: '/series', schema: { tags: ['シリーズ'], - querystring: schema.getSeriesRequestQuery, + querystring: getSeriesRequestQuery, response: { 200: { content: { 'application/json': { - schema: schema.getSeriesResponse, + schema: getSeriesResponse, }, }, }, @@ -280,12 +306,12 @@ export async function registerApi(app: FastifyInstance): Promise { url: '/series/:seriesId', schema: { tags: ['シリーズ'], - params: schema.getSeriesByIdRequestParams, + params: getSeriesByIdRequestParams, response: { 200: { content: { 'application/json': { - schema: schema.getSeriesByIdResponse, + schema: getSeriesByIdResponse, }, }, }, @@ -321,12 +347,12 @@ export async function registerApi(app: FastifyInstance): Promise { url: '/timetable', schema: { tags: ['番組表'], - querystring: schema.getTimetableRequestQuery, + querystring: getTimetableRequestQuery, response: { 200: { content: { 'application/json': { - schema: schema.getTimetableResponse, + schema: getTimetableResponse, }, }, }, @@ -357,12 +383,12 @@ export async function registerApi(app: FastifyInstance): Promise { url: '/programs', schema: { tags: ['番組'], - querystring: schema.getProgramsRequestQuery, + querystring: getProgramsRequestQuery, response: { 200: { content: { 'application/json': { - schema: schema.getProgramsResponse, + schema: getProgramsResponse, }, }, }, @@ -408,12 +434,12 @@ export async function registerApi(app: FastifyInstance): Promise { url: '/programs/:programId', schema: { tags: ['番組'], - params: schema.getProgramByIdRequestParams, + params: getProgramByIdRequestParams, response: { 200: { content: { 'application/json': { - schema: schema.getProgramByIdResponse, + schema: getProgramByIdResponse, }, }, }, @@ -455,12 +481,12 @@ export async function registerApi(app: FastifyInstance): Promise { url: '/recommended/:referenceId', schema: { tags: ['レコメンド'], - params: schema.getRecommendedModulesRequestParams, + params: getRecommendedModulesRequestParams, response: { 200: { content: { 'application/json': { - schema: schema.getRecommendedModulesResponse, + schema: getRecommendedModulesResponse, }, }, }, @@ -517,12 +543,12 @@ export async function registerApi(app: FastifyInstance): Promise { url: '/signIn', schema: { tags: ['認証'], - body: schema.signInRequestBody, + body: signInRequestBody, response: { 200: { content: { 'application/json': { - schema: schema.signInResponse, + schema: signInResponse, }, }, }, @@ -536,11 +562,11 @@ export async function registerApi(app: FastifyInstance): Promise { return eq(user.email, req.body.email); }, }); - if (!user || !bcrypt.compareSync(req.body.password, user.password)) { + if (!user || !compareSync(req.body.password, user.password)) { return reply.code(401).send(); } - const ret = schema.signInResponse.parse({ id: user.id, email: user.email }); + const ret = signInResponse.parse({ id: user.id, email: user.email }); req.session.set('id', ret.id.toString()); reply.code(200).send(user); @@ -552,12 +578,12 @@ export async function registerApi(app: FastifyInstance): Promise { url: '/signUp', schema: { tags: ['認証'], - body: schema.signUpRequestBody, + body: signUpRequestBody, response: { 200: { content: { 'application/json': { - schema: schema.signUpResponse, + schema: signUpResponse, }, }, }, @@ -576,10 +602,10 @@ export async function registerApi(app: FastifyInstance): Promise { } const users = await database - .insert(databaseSchema.user) + .insert(userTable) .values({ email: req.body.email, - password: bcrypt.hashSync(req.body.password, 10), + password: hashSync(req.body.password, 10), }) .returning(); @@ -588,7 +614,7 @@ export async function registerApi(app: FastifyInstance): Promise { return reply.code(500).send(); } - const ret = schema.signUpResponse.parse({ id: user.id, email: user.email }); + const ret = signUpResponse.parse({ id: user.id, email: user.email }); req.session.set('id', ret.id.toString()); reply.code(200).send(ret); @@ -604,7 +630,7 @@ export async function registerApi(app: FastifyInstance): Promise { 200: { content: { 'application/json': { - schema: schema.getUserResponse, + schema: getUserResponse, }, }, }, diff --git a/workspaces/server/src/index.ts b/workspaces/server/src/index.ts index e02ab7613..3d6c672b9 100644 --- a/workspaces/server/src/index.ts +++ b/workspaces/server/src/index.ts @@ -8,14 +8,14 @@ import { initializeDatabase } from '@wsh-2025/server/src/drizzle/database'; import { registerSsr } from '@wsh-2025/server/src/ssr'; import { registerStreams } from '@wsh-2025/server/src/streams'; +const port = process.env.PORT || 8000; +const host = '0.0.0.0'; + async function main() { await initializeDatabase(); const app = fastify(); - app.addHook('onSend', async (_req, reply) => { - reply.header('cache-control', 'no-store'); - }); app.register(cors, { origin: true, }); @@ -24,7 +24,7 @@ async function main() { app.register(registerSsr); await app.ready(); - const address = await app.listen({ host: '0.0.0.0', port: Number(process.env['PORT']) }); + const address = await app.listen({ host, port }); console.log(`Server listening at ${address}`); } diff --git a/workspaces/server/src/ssr.tsx b/workspaces/server/src/ssr.tsx index 7603aafdd..17f8d226a 100644 --- a/workspaces/server/src/ssr.tsx +++ b/workspaces/server/src/ssr.tsx @@ -1,29 +1,20 @@ -import { readdirSync } from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; import fastifyStatic from '@fastify/static'; -import { StoreProvider } from '@wsh-2025/client/src/app/StoreContext'; -import { createRoutes } from '@wsh-2025/client/src/app/createRoutes'; -import { createStore } from '@wsh-2025/client/src/app/createStore'; import type { FastifyInstance } from 'fastify'; -import { createStandardRequest } from 'fastify-standard-request-reply'; -import htmlescape from 'htmlescape'; -import { StrictMode } from 'react'; -import { renderToString } from 'react-dom/server'; -import { createStaticHandler, createStaticRouter, StaticRouterProvider } from 'react-router'; -function getFiles(parent: string): string[] { - const dirents = readdirSync(parent, { withFileTypes: true }); - return dirents - .filter((dirent) => dirent.isFile() && !dirent.name.startsWith('.')) - .map((dirent) => path.join(parent, dirent.name)); -} +// function getFiles(parent: string): string[] { +// const dirents = readdirSync(parent, { withFileTypes: true }); +// return dirents +// .filter((dirent) => dirent.isFile() && !dirent.name.startsWith('.')) +// .map((dirent) => path.join(parent, dirent.name)); +// } -function getFilePaths(relativePath: string, rootDir: string): string[] { - const files = getFiles(path.resolve(rootDir, relativePath)); - return files.map((file) => path.join('/', path.relative(rootDir, file))); -} +// function getFilePaths(relativePath: string, rootDir: string): string[] { +// const files = getFiles(path.resolve(rootDir, relativePath)); +// return files.map((file) => path.join('/', path.relative(rootDir, file))); +// } export function registerSsr(app: FastifyInstance): void { app.register(fastifyStatic, { @@ -38,51 +29,51 @@ export function registerSsr(app: FastifyInstance): void { reply.status(404).send(); }); - app.get('/*', async (req, reply) => { - // @ts-expect-error ................ - const request = createStandardRequest(req, reply); + // app.get('/*', async (req, reply) => { + // // @ts-expect-error ................ + // const request = createStandardRequest(req, reply); - const store = createStore({}); - const handler = createStaticHandler(createRoutes(store)); - const context = await handler.query(request); + // const store = createStore({}); + // const handler = createStaticHandler(createRoutes(store)); + // const context = await handler.query(request); - if (context instanceof Response) { - return reply.send(context); - } + // if (context instanceof Response) { + // return reply.send(context); + // } - const router = createStaticRouter(handler.dataRoutes, context); - renderToString( - - store}> - - - , - ); + // const router = createStaticRouter(handler.dataRoutes, context); + // renderToString( + // + // store}> + // + // + // , + // ); - const rootDir = path.resolve(__dirname, '../../../'); - const imagePaths = [ - getFilePaths('public/images', rootDir), - getFilePaths('public/animations', rootDir), - getFilePaths('public/logos', rootDir), - ].flat(); + // const rootDir = path.resolve(__dirname, '../../../'); + // const imagePaths = [ + // getFilePaths('public/images', rootDir), + // getFilePaths('public/animations', rootDir), + // getFilePaths('public/logos', rootDir), + // ].flat(); - reply.type('text/html').send(/* html */ ` - - - - - - - ${imagePaths.map((imagePath) => ``).join('\n')} - - - - - `); - }); + // reply.type('text/html').send(/* html */ ` + // + // + // + // + // + // + // ${imagePaths.map((imagePath) => ``).join('\n')} + // + // + // + // + // `); + // }); } diff --git a/workspaces/server/src/streams.tsx b/workspaces/server/src/streams.tsx index 0c45fcf6d..b371baa15 100644 --- a/workspaces/server/src/streams.tsx +++ b/workspaces/server/src/streams.tsx @@ -1,4 +1,3 @@ -import { randomBytes } from 'node:crypto'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; @@ -78,39 +77,44 @@ export function registerStreams(app: FastifyInstance): void { `, ]; + const programs = await database.query.program.findMany({ + limit: SEQUENCE_COUNT_PER_PLAYLIST, + orderBy(program, { asc }) { + return asc(program.startAt); + }, + where(program, { eq }) { + return eq(program.channelId, req.params.channelId); + }, + with: { + episode: { + with: { + stream: true, + }, + }, + }, + }); + + const programStartTimes = programs.map((p) => ({ + endTime: getTime(new Date(p.endAt)), + program: p, + startTime: getTime(new Date(p.startAt)), + })); + + const sequenceStartAt = new Date(); + for (let idx = 0; idx < SEQUENCE_COUNT_PER_PLAYLIST; idx++) { const sequence = firstSequence + idx; - const sequenceStartAt = new Date(sequence * SEQUENCE_DURATION_MS); + sequenceStartAt.setTime(sequence * SEQUENCE_DURATION_MS); + const sequenceTime = sequenceStartAt.getTime() - DateTime.fromJSDate(sequenceStartAt).startOf('day').toMillis(); - const program = await database.query.program.findFirst({ - orderBy(program, { asc }) { - return asc(program.startAt); - }, - where(program, { and, eq, lt, lte, sql }) { - // 競技のため、時刻のみで比較する - return and( - lte(program.startAt, sql`time(${sequenceStartAt.toISOString()}, '+9 hours')`), - lt(sql`time(${sequenceStartAt.toISOString()}, '+9 hours')`, program.endAt), - eq(program.channelId, req.params.channelId), - ); - }, - with: { - episode: { - with: { - stream: true, - }, - }, - }, - }); + const program = programStartTimes.find((p) => sequenceTime >= p.startTime && sequenceTime < p.endTime); - if (program == null) { + if (!program) { break; } - const stream = program.episode.stream; - const sequenceInStream = Math.floor( - (getTime(sequenceStartAt) - getTime(new Date(program.startAt))) / SEQUENCE_DURATION_MS, - ); + const stream = program.program.episode.stream; + const sequenceInStream = Math.floor((sequenceTime - program.startTime) / SEQUENCE_DURATION_MS); const chunkIdx = sequenceInStream % stream.numberOfChunks; playlist.push( @@ -122,7 +126,6 @@ export function registerStreams(app: FastifyInstance): void { `ID="arema-${sequence}"`, `START-DATE="${sequenceStartAt.toISOString()}"`, `DURATION=2.0`, - `X-AREMA-INTERNAL="${randomBytes(3 * 1024 * 1024).toString('base64')}"`, ].join(',')} `, ); diff --git a/workspaces/server/tools/seed.ts b/workspaces/server/tools/seed.ts index 611eba167..078dc9c4d 100644 --- a/workspaces/server/tools/seed.ts +++ b/workspaces/server/tools/seed.ts @@ -3,11 +3,10 @@ import { createClient } from '@libsql/client'; import * as schema from '@wsh-2025/schema/src/database/schema'; import { drizzle } from 'drizzle-orm/libsql'; import { reset } from 'drizzle-seed'; -import { DateTime } from 'luxon'; import { fetchAnimeList } from '@wsh-2025/server/tools/fetch_anime_list'; import { fetchLoremIpsumWordList } from '@wsh-2025/server/tools/fetch_lorem_ipsum_word_list'; -import * as bcrypt from 'bcrypt'; +import { hashSync } from 'bcrypt'; import path from 'node:path'; import { readdirSync } from 'node:fs'; @@ -89,7 +88,7 @@ async function main() { }); const rootDir = path.resolve(__dirname, '../../..'); - const files = await getFiles(path.resolve(rootDir, 'public/images')); + const files = await getFiles(path.resolve(rootDir, 'public/images-compress')); const imagePaths = files.map((file) => path.join('/', path.relative(rootDir, file))); try { @@ -117,7 +116,7 @@ async function main() { { const data: (typeof schema.channel.$inferInsert)[] = CHANNEL_NAME_LIST.map(({ id, name }) => ({ id: faker.string.uuid(), - logoUrl: `/public/logos/${id}.svg`, + logoUrl: `/public/logos/${id}.avif`, name, })); const result = await database.insert(schema.channel).values(data).returning(); @@ -165,7 +164,7 @@ async function main() { const episodeListGroupedByStreamId = Object.values(Object.groupBy(episodeList, (episode) => episode.streamId)); for (const channel of channelList) { let remainingMinutes = 24 * 60; - let startAt = DateTime.now().startOf('day').toMillis(); + let startAt = new Date(new Date().setHours(0, 0, 0, 0)).getTime(); while (remainingMinutes > 0) { const durationCandidate = @@ -297,7 +296,7 @@ async function main() { await database.insert(schema.user).values([ { email: 'test@example.com', - password: bcrypt.hashSync('test', 10), + password: hashSync('test', 10), }, ]); } finally { diff --git a/workspaces/server/tsconfig.json b/workspaces/server/tsconfig.json index f1d9fb34b..ddb032595 100644 --- a/workspaces/server/tsconfig.json +++ b/workspaces/server/tsconfig.json @@ -17,7 +17,7 @@ "sourceMap": true, "target": "ESNext" }, - "exclude": ["./dist", "./streams", "../client/dist"], + "exclude": ["./dist", "./streams", "../client/dist", "**/*.mjs"], "extends": "@wsh-2025/configs/tsconfig.json", - "include": ["tools/**/*", "./src/**/*", "**/*.mjs", "drizzle.config.ts", "../client/**/*"] + "include": ["tools/**/*", "./src/**/*", "**/*.mjs", "drizzle.config.ts"] } diff --git a/workspaces/test/.gitignore b/workspaces/test/.gitignore deleted file mode 100644 index 87364a273..000000000 --- a/workspaces/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -test-results diff --git a/workspaces/test/eslint.config.mjs b/workspaces/test/eslint.config.mjs deleted file mode 100644 index dd4df340b..000000000 --- a/workspaces/test/eslint.config.mjs +++ /dev/null @@ -1,10 +0,0 @@ -import configs from '@wsh-2025/configs/eslint.config.mjs'; - -export default [ - ...configs, - { - rules: { - '@typescript-eslint/no-extraneous-class': 'off', - }, - }, -]; diff --git a/workspaces/test/package.json b/workspaces/test/package.json deleted file mode 100644 index 2c585708d..000000000 --- a/workspaces/test/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "@wsh-2025/test", - "private": true, - "scripts": { - "test": "wireit" - }, - "devDependencies": { - "@playwright/test": "1.50.1", - "@types/node": "22.10.0", - "@wsh-2025/configs": "workspace:*", - "mockdate": "3.0.5" - }, - "wireit": { - "test": { - "command": "playwright test", - "files": [ - "../../pnpm-lock.yaml", - "../schema/src/**/*", - "./src/**/*" - ] - } - } -} diff --git a/workspaces/test/playwright.config.ts b/workspaces/test/playwright.config.ts deleted file mode 100644 index bf031167b..000000000 --- a/workspaces/test/playwright.config.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { defineConfig, devices } from '@playwright/test'; - -const BASE_URL = process.env['E2E_BASE_URL'] ?? 'http://localhost:8000'; - -export default defineConfig({ - expect: { - timeout: 60_000, - toHaveScreenshot: { - maxDiffPixelRatio: 0.03, - }, - }, - forbidOnly: !!process.env['FORBID_ONLY'], - fullyParallel: true, - projects: [ - { - name: 'Desktop Chrome', - testMatch: '**/src/**/*.test.ts', - use: { ...devices['Desktop Chrome'], channel: 'chrome' }, // chromiumはh264に対応していないためChromeを使用 - }, - ], - reporter: 'list', - retries: 0, - testDir: './src', - timeout: 300_000, - use: { - baseURL: BASE_URL, - headless: true, - trace: 'off', - }, -}); diff --git a/workspaces/test/prettier.config.mjs b/workspaces/test/prettier.config.mjs deleted file mode 100644 index ca2b6ddfe..000000000 --- a/workspaces/test/prettier.config.mjs +++ /dev/null @@ -1 +0,0 @@ -export { default } from '@wsh-2025/configs/prettier.config.mjs'; diff --git a/workspaces/test/src/auth.test.ts b/workspaces/test/src/auth.test.ts deleted file mode 100644 index 7a01c7f88..000000000 --- a/workspaces/test/src/auth.test.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { test, expect } from '@playwright/test'; -import { waitForImageToLoad } from './utils'; - -test.describe('認証', () => { - test.beforeEach(async ({ page }) => { - await page.goto('/'); - await page.addStyleTag({ - url: 'https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@100..900&display=swap', - }); - }); - - test('新規会員登録 -> ログアウト -> ログイン', async ({ page }) => { - // コンフリクトしないようにテスト用のメールアドレスを生成 - const email = `test.${Date.now()}@example.com`; - - await test.step('サイドバーのログインボタンをクリック', async () => { - const sidebar = page.getByRole('complementary'); - await sidebar.getByRole('button', { name: 'ログイン' }).click(); - }); - - await test.step('ログインダイアログが表示される', async () => { - const signInDialog = page.getByRole('dialog'); - await expect(signInDialog).toBeVisible(); - const signInDialogPanel = signInDialog.locator('>div'); - - await waitForImageToLoad(signInDialogPanel.locator('img').first()); - await expect(signInDialogPanel).toHaveScreenshot('vrt-signIn-dialog.png'); - }); - - await test.step('アカウントを新規登録する ボタンをクリック', async () => { - const signInDialog = page.getByRole('dialog'); - const signUpLink = signInDialog.getByRole('button', { name: 'アカウントを新規登録する' }); - await signUpLink.click(); - }); - - await test.step('新規会員登録ダイアログが表示される', async () => { - const signUpDialog = page.getByRole('dialog'); - await expect(signUpDialog).toBeVisible(); - const signUpDialogPanel = signUpDialog.locator('>div'); - - await waitForImageToLoad(signUpDialogPanel.locator('img').first()); - await expect(signUpDialogPanel).toHaveScreenshot('vrt-signUp-dialog.png'); - }); - - await test.step('新規会員登録フォームで正しく入力できる', async () => { - const signUpDialog = page.getByRole('dialog'); - const signUpDialogPanel = page.getByRole('dialog').locator('>div'); - - const emailInput = signUpDialogPanel.getByLabel('メールアドレス'); - await emailInput.fill(email); - const passwordInput = signUpDialogPanel.getByLabel('パスワード'); - await passwordInput.fill('test'); - await signUpDialog.getByRole('button', { name: 'アカウント作成' }).click(); - - await expect(signUpDialog).not.toBeVisible(); - - const sidebar = page.getByRole('complementary'); - const signOutButton = sidebar.getByRole('button', { name: 'ログアウト' }); - await expect(signOutButton).toBeVisible(); - }); - - await test.step('サイドバーのログアウトボタンをクリック', async () => { - const sidebar = page.getByRole('complementary'); - await sidebar.getByRole('button', { name: 'ログアウト' }).click(); - }); - - await test.step('ログアウトダイアログが表示される', async () => { - const signOutDialog = page.getByRole('dialog'); - await expect(signOutDialog).toBeVisible(); - const signOutDialogPanel = signOutDialog.locator('>div'); - - await waitForImageToLoad(signOutDialogPanel.locator('img').first()); - await expect(signOutDialogPanel).toHaveScreenshot('vrt-signOut-dialog.png'); - }); - - await test.step('ログアウトを実行', async () => { - const signOutDialog = page.getByRole('dialog'); - const signOutDialogPanel = signOutDialog.locator('>div'); - await signOutDialogPanel.getByRole('button', { name: 'ログアウト' }).click(); - - await expect(signOutDialog).not.toBeVisible(); - - const sidebar = page.getByRole('complementary'); - const signInButton = sidebar.getByRole('button', { name: 'ログイン' }); - await expect(signInButton).toBeVisible(); - }); - - await test.step('ログインフォームで正しく入力できる', async () => { - const sidebar = page.getByRole('complementary'); - await sidebar.getByRole('button', { name: 'ログイン' }).click(); - - const signInDialog = page.getByRole('dialog'); - const signInDialogPanel = signInDialog.locator('>div'); - - const emailInput = signInDialogPanel.getByLabel('メールアドレス'); - await emailInput.fill(email); - const passwordInput = signInDialogPanel.getByLabel('パスワード'); - await passwordInput.fill('test'); - await signInDialog.getByRole('button', { name: 'ログイン' }).click(); - - await expect(signInDialog).not.toBeVisible(); - - const signOutButton = sidebar.getByRole('button', { name: 'ログアウト' }); - await expect(signOutButton).toBeVisible(); - }); - }); -}); diff --git a/workspaces/test/src/auth.test.ts-snapshots/vrt-signIn-dialog-Desktop-Chrome-darwin.png b/workspaces/test/src/auth.test.ts-snapshots/vrt-signIn-dialog-Desktop-Chrome-darwin.png deleted file mode 100644 index 75174ec52..000000000 Binary files a/workspaces/test/src/auth.test.ts-snapshots/vrt-signIn-dialog-Desktop-Chrome-darwin.png and /dev/null differ diff --git a/workspaces/test/src/auth.test.ts-snapshots/vrt-signOut-dialog-Desktop-Chrome-darwin.png b/workspaces/test/src/auth.test.ts-snapshots/vrt-signOut-dialog-Desktop-Chrome-darwin.png deleted file mode 100644 index 156f2673c..000000000 Binary files a/workspaces/test/src/auth.test.ts-snapshots/vrt-signOut-dialog-Desktop-Chrome-darwin.png and /dev/null differ diff --git a/workspaces/test/src/auth.test.ts-snapshots/vrt-signUp-dialog-Desktop-Chrome-darwin.png b/workspaces/test/src/auth.test.ts-snapshots/vrt-signUp-dialog-Desktop-Chrome-darwin.png deleted file mode 100644 index e7005884b..000000000 Binary files a/workspaces/test/src/auth.test.ts-snapshots/vrt-signUp-dialog-Desktop-Chrome-darwin.png and /dev/null differ diff --git a/workspaces/test/src/full-page.test.ts b/workspaces/test/src/full-page.test.ts deleted file mode 100644 index 64b121e0b..000000000 --- a/workspaces/test/src/full-page.test.ts +++ /dev/null @@ -1,135 +0,0 @@ -import path from 'node:path'; - -import type { Page } from '@playwright/test'; -import { expect, test } from '@playwright/test'; - -import { scrollEntire, waitForImageToLoad, waitForVideoToLoad } from './utils'; - -const PAGES = [ - { - name: 'トップページ', - path: '/', - wait: async (page: Page) => { - await waitForImageToLoad(page.locator('main img').first()); - await waitForVideoToLoad(page.locator('video').first()); - }, - }, - { - name: 'シリーズページ', - path: '/series/b44c9e84-2f62-4670-97c4-40f710489d66', - wait: async (page: Page) => { - await waitForImageToLoad(page.locator('main img').first()); - }, - }, - { - name: 'エピソードページ (無料)', - path: '/episodes/89895c59-0c51-42f4-abb6-53fa86bdc4a2', - wait: async (page: Page) => { - await waitForImageToLoad(page.locator('main img').first()); - await waitForVideoToLoad(page.locator('video').first()); - }, - }, - { - name: 'エピソードページ (プレミアム - 無料ユーザー)', - path: '/episodes/d16a4428-9c25-4ae2-8c5a-d841ab5998b0', - wait: async (page: Page) => { - await waitForImageToLoad(page.locator('main img').first()); - }, - }, - { - name: 'エピソードページ (プレミアム - プレミアムユーザー)', - path: '/episodes/d16a4428-9c25-4ae2-8c5a-d841ab5998b0', - wait: async (page: Page) => { - // コンフリクトしないようにテスト用のメールアドレスを生成 - const email = `test.${Date.now()}@example.com`; - const sidebar = page.getByRole('complementary'); - await sidebar.getByRole('button', { name: 'ログイン' }).click(); - - const signInDialog = page.getByRole('dialog'); - const signUpLink = signInDialog.getByRole('button', { name: 'アカウントを新規登録する' }); - await signUpLink.click(); - - const signUpDialog = page.getByRole('dialog'); - const signUpDialogPanel = signUpDialog.locator('>div'); - - const emailInput = signUpDialogPanel.getByLabel('メールアドレス'); - await emailInput.fill(email); - const passwordInput = signUpDialogPanel.getByLabel('パスワード'); - await passwordInput.fill('test'); - await signUpDialog.getByRole('button', { name: 'アカウント作成' }).click(); - - await waitForImageToLoad(page.locator('main img').first()); - await waitForVideoToLoad(page.locator('video').first()); - }, - }, - { - name: 'プログラム(放送前)', - path: '/programs/e34e75d8-e07f-4517-ba3d-9c09eba2bd3a', - wait: async (page: Page) => { - await waitForImageToLoad(page.locator('main img').first()); - }, - }, - { - name: 'プログラム(放送中)', - path: '/programs/5f8521b0-1aaf-4949-a54d-e2da710dc972', - wait: async (page: Page) => { - await waitForImageToLoad(page.locator('main img').first()); - await waitForVideoToLoad(page.locator('video').first()); - }, - }, - { - name: 'プログラム(放送後)', - path: '/programs/d3c78d58-bf4f-4445-9577-af9759a4af78', - wait: async (page: Page) => { - await waitForImageToLoad(page.locator('main img').first()); - }, - }, - { - name: '番組表', - path: '/timetable', - wait: async (page: Page) => { - await waitForImageToLoad(page.locator('main img').first()); - }, - }, - { - name: '404', - path: '/404', - wait: async (page: Page) => { - await waitForImageToLoad(page.locator('main img').first()); - }, - }, -]; - -declare const MockDate: { set: (timestamp: number) => void }; - -test.describe('全画面', () => { - test.beforeEach(async ({ context, page }) => { - await context.addInitScript({ - path: path.join(__dirname, '..', 'node_modules', 'mockdate', 'lib', 'mockdate.js'), - }); - await context.addInitScript(() => { - const now = new Date(); - now.setHours(12, 0, 0, 0); // 12:00:00 で固定 - - MockDate.set(now.getTime()); - }); - - await page.setViewportSize({ height: 1080, width: 1920 }); - await page.addStyleTag({ - url: 'https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@100..900&display=swap', - }); - await context.clearCookies(); - }); - - for (const { name, path, wait } of PAGES) { - test(name, async ({ page }) => { - await page.goto(path); - await wait(page); - await scrollEntire(page); - await expect(page).toHaveScreenshot(`vrt-${name}.png`, { - fullPage: true, - mask: [page.locator('video'), page.locator("//img[contains(@src, '.gif')]")], - }); - }); - } -}); diff --git a/workspaces/test/src/full-page.test.ts-snapshots/vrt-404-Desktop-Chrome-darwin.png b/workspaces/test/src/full-page.test.ts-snapshots/vrt-404-Desktop-Chrome-darwin.png deleted file mode 100644 index 8b38666d5..000000000 Binary files a/workspaces/test/src/full-page.test.ts-snapshots/vrt-404-Desktop-Chrome-darwin.png and /dev/null differ diff --git "a/workspaces/test/src/full-page.test.ts-snapshots/vrt-\343\202\250\343\203\224\343\202\275\343\203\274\343\203\211\343\203\232\343\203\274\343\202\270-\343\203\227\343\203\254\343\203\237\343\202\242\343\203\240---\343\203\227\343\203\254\343\203\237\343\202\242\343\203\240\343\203\246\343\203\274\343\202\266\343\203\274--Desktop-Chrome-darwin.png" "b/workspaces/test/src/full-page.test.ts-snapshots/vrt-\343\202\250\343\203\224\343\202\275\343\203\274\343\203\211\343\203\232\343\203\274\343\202\270-\343\203\227\343\203\254\343\203\237\343\202\242\343\203\240---\343\203\227\343\203\254\343\203\237\343\202\242\343\203\240\343\203\246\343\203\274\343\202\266\343\203\274--Desktop-Chrome-darwin.png" deleted file mode 100644 index 522a3c8c7..000000000 Binary files "a/workspaces/test/src/full-page.test.ts-snapshots/vrt-\343\202\250\343\203\224\343\202\275\343\203\274\343\203\211\343\203\232\343\203\274\343\202\270-\343\203\227\343\203\254\343\203\237\343\202\242\343\203\240---\343\203\227\343\203\254\343\203\237\343\202\242\343\203\240\343\203\246\343\203\274\343\202\266\343\203\274--Desktop-Chrome-darwin.png" and /dev/null differ diff --git "a/workspaces/test/src/full-page.test.ts-snapshots/vrt-\343\202\250\343\203\224\343\202\275\343\203\274\343\203\211\343\203\232\343\203\274\343\202\270-\343\203\227\343\203\254\343\203\237\343\202\242\343\203\240---\347\204\241\346\226\231\343\203\246\343\203\274\343\202\266\343\203\274--Desktop-Chrome-darwin.png" "b/workspaces/test/src/full-page.test.ts-snapshots/vrt-\343\202\250\343\203\224\343\202\275\343\203\274\343\203\211\343\203\232\343\203\274\343\202\270-\343\203\227\343\203\254\343\203\237\343\202\242\343\203\240---\347\204\241\346\226\231\343\203\246\343\203\274\343\202\266\343\203\274--Desktop-Chrome-darwin.png" deleted file mode 100644 index b71bbcab9..000000000 Binary files "a/workspaces/test/src/full-page.test.ts-snapshots/vrt-\343\202\250\343\203\224\343\202\275\343\203\274\343\203\211\343\203\232\343\203\274\343\202\270-\343\203\227\343\203\254\343\203\237\343\202\242\343\203\240---\347\204\241\346\226\231\343\203\246\343\203\274\343\202\266\343\203\274--Desktop-Chrome-darwin.png" and /dev/null differ diff --git "a/workspaces/test/src/full-page.test.ts-snapshots/vrt-\343\202\250\343\203\224\343\202\275\343\203\274\343\203\211\343\203\232\343\203\274\343\202\270-\347\204\241\346\226\231--Desktop-Chrome-darwin.png" "b/workspaces/test/src/full-page.test.ts-snapshots/vrt-\343\202\250\343\203\224\343\202\275\343\203\274\343\203\211\343\203\232\343\203\274\343\202\270-\347\204\241\346\226\231--Desktop-Chrome-darwin.png" deleted file mode 100644 index 50c90cd53..000000000 Binary files "a/workspaces/test/src/full-page.test.ts-snapshots/vrt-\343\202\250\343\203\224\343\202\275\343\203\274\343\203\211\343\203\232\343\203\274\343\202\270-\347\204\241\346\226\231--Desktop-Chrome-darwin.png" and /dev/null differ diff --git "a/workspaces/test/src/full-page.test.ts-snapshots/vrt-\343\202\267\343\203\252\343\203\274\343\202\272\343\203\232\343\203\274\343\202\270-Desktop-Chrome-darwin.png" "b/workspaces/test/src/full-page.test.ts-snapshots/vrt-\343\202\267\343\203\252\343\203\274\343\202\272\343\203\232\343\203\274\343\202\270-Desktop-Chrome-darwin.png" deleted file mode 100644 index 51d9add54..000000000 Binary files "a/workspaces/test/src/full-page.test.ts-snapshots/vrt-\343\202\267\343\203\252\343\203\274\343\202\272\343\203\232\343\203\274\343\202\270-Desktop-Chrome-darwin.png" and /dev/null differ diff --git "a/workspaces/test/src/full-page.test.ts-snapshots/vrt-\343\203\210\343\203\203\343\203\227\343\203\232\343\203\274\343\202\270-Desktop-Chrome-darwin.png" "b/workspaces/test/src/full-page.test.ts-snapshots/vrt-\343\203\210\343\203\203\343\203\227\343\203\232\343\203\274\343\202\270-Desktop-Chrome-darwin.png" deleted file mode 100644 index cbb22f7e7..000000000 Binary files "a/workspaces/test/src/full-page.test.ts-snapshots/vrt-\343\203\210\343\203\203\343\203\227\343\203\232\343\203\274\343\202\270-Desktop-Chrome-darwin.png" and /dev/null differ diff --git "a/workspaces/test/src/full-page.test.ts-snapshots/vrt-\343\203\227\343\203\255\343\202\260\343\203\251\343\203\240\357\274\210\346\224\276\351\200\201\344\270\255\357\274\211-Desktop-Chrome-darwin.png" "b/workspaces/test/src/full-page.test.ts-snapshots/vrt-\343\203\227\343\203\255\343\202\260\343\203\251\343\203\240\357\274\210\346\224\276\351\200\201\344\270\255\357\274\211-Desktop-Chrome-darwin.png" deleted file mode 100644 index f1b85cc6e..000000000 Binary files "a/workspaces/test/src/full-page.test.ts-snapshots/vrt-\343\203\227\343\203\255\343\202\260\343\203\251\343\203\240\357\274\210\346\224\276\351\200\201\344\270\255\357\274\211-Desktop-Chrome-darwin.png" and /dev/null differ diff --git "a/workspaces/test/src/full-page.test.ts-snapshots/vrt-\343\203\227\343\203\255\343\202\260\343\203\251\343\203\240\357\274\210\346\224\276\351\200\201\345\211\215\357\274\211-Desktop-Chrome-darwin.png" "b/workspaces/test/src/full-page.test.ts-snapshots/vrt-\343\203\227\343\203\255\343\202\260\343\203\251\343\203\240\357\274\210\346\224\276\351\200\201\345\211\215\357\274\211-Desktop-Chrome-darwin.png" deleted file mode 100644 index 989ae7a0f..000000000 Binary files "a/workspaces/test/src/full-page.test.ts-snapshots/vrt-\343\203\227\343\203\255\343\202\260\343\203\251\343\203\240\357\274\210\346\224\276\351\200\201\345\211\215\357\274\211-Desktop-Chrome-darwin.png" and /dev/null differ diff --git "a/workspaces/test/src/full-page.test.ts-snapshots/vrt-\343\203\227\343\203\255\343\202\260\343\203\251\343\203\240\357\274\210\346\224\276\351\200\201\345\276\214\357\274\211-Desktop-Chrome-darwin.png" "b/workspaces/test/src/full-page.test.ts-snapshots/vrt-\343\203\227\343\203\255\343\202\260\343\203\251\343\203\240\357\274\210\346\224\276\351\200\201\345\276\214\357\274\211-Desktop-Chrome-darwin.png" deleted file mode 100644 index da78fc9cb..000000000 Binary files "a/workspaces/test/src/full-page.test.ts-snapshots/vrt-\343\203\227\343\203\255\343\202\260\343\203\251\343\203\240\357\274\210\346\224\276\351\200\201\345\276\214\357\274\211-Desktop-Chrome-darwin.png" and /dev/null differ diff --git "a/workspaces/test/src/full-page.test.ts-snapshots/vrt-\347\225\252\347\265\204\350\241\250-Desktop-Chrome-darwin.png" "b/workspaces/test/src/full-page.test.ts-snapshots/vrt-\347\225\252\347\265\204\350\241\250-Desktop-Chrome-darwin.png" deleted file mode 100644 index 581cfac7f..000000000 Binary files "a/workspaces/test/src/full-page.test.ts-snapshots/vrt-\347\225\252\347\265\204\350\241\250-Desktop-Chrome-darwin.png" and /dev/null differ diff --git a/workspaces/test/src/top.test.ts b/workspaces/test/src/top.test.ts deleted file mode 100644 index 4e911c642..000000000 --- a/workspaces/test/src/top.test.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { expect, test } from '@playwright/test'; - -import { waitForImageToLoad } from './utils'; - -test.describe('サービストップ', () => { - test.beforeEach(async ({ page }) => { - await page.goto('/'); - await page.addStyleTag({ - url: 'https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@100..900&display=swap', - }); - }); - - test('サイドバーにロゴ画像が表示されていること', async ({ page }) => { - const heroImg = page.getByRole('img', { name: 'AREMA' }); - await waitForImageToLoad(heroImg); - await expect(heroImg).toHaveScreenshot('vrt-hero-img.png'); - }); -}); diff --git a/workspaces/test/src/top.test.ts-snapshots/vrt-hero-img-Desktop-Chrome-darwin.png b/workspaces/test/src/top.test.ts-snapshots/vrt-hero-img-Desktop-Chrome-darwin.png deleted file mode 100644 index 16ce0811f..000000000 Binary files a/workspaces/test/src/top.test.ts-snapshots/vrt-hero-img-Desktop-Chrome-darwin.png and /dev/null differ diff --git a/workspaces/test/src/utils.ts b/workspaces/test/src/utils.ts deleted file mode 100644 index 7e7f18bb8..000000000 --- a/workspaces/test/src/utils.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { expect } from '@playwright/test'; -import type { Locator, Page } from '@playwright/test'; - -export async function waitForImageToLoad(imageLocator: Locator): Promise { - await imageLocator.scrollIntoViewIfNeeded(); - await expect(imageLocator).toBeVisible(); - await expect(async () => { - expect( - await ( - await imageLocator.evaluateHandle((element, prop) => { - if (!(element instanceof HTMLImageElement)) { - throw new Error('Element is not an image'); - } - return element[prop as keyof typeof element]; - }, 'naturalWidth') - ).jsonValue(), - ).toBeGreaterThan(0); - }).toPass(); -} - -export async function waitForVideoToLoad(videoLocator: Locator): Promise { - // メタデータが読み込まれれば、動画のサイズが取得できる - await videoLocator.evaluate((video) => { - if (!(video instanceof HTMLVideoElement)) { - throw new Error('Element is not a video'); - } - return new Promise((resolve) => { - if (video.readyState >= 1) { - resolve(null); - return; - } - - video.addEventListener('loadedmetadata', () => { - resolve(null); - }); - }); - }); -} - -export async function waitForAllImagesToLoad(locator: Locator, expectedNumberOfImages: number = 1): Promise { - const images = locator.locator('img'); - - await expect(async () => { - await locator.scrollIntoViewIfNeeded(); - await expect(locator).toBeVisible(); - await expect(images.count()).resolves.toBeGreaterThanOrEqual(expectedNumberOfImages); - }).toPass(); - - const count = await images.count(); - for (let i = 0; i < count; i++) { - await waitForImageToLoad(images.nth(i)); - } -} - -export async function scrollEntire(page: Page): Promise { - await page.evaluate(async () => { - const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); - for (let i = 0; i < document.body.scrollHeight; i += 100) { - window.scrollTo(0, i); - await delay(50); - } - - for (let i = document.body.scrollHeight; i > 0; i -= 100) { - window.scrollTo(0, i); - await delay(50); - } - }); -} diff --git a/workspaces/test/tsconfig.json b/workspaces/test/tsconfig.json deleted file mode 100644 index 9bc77e07e..000000000 --- a/workspaces/test/tsconfig.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "compilerOptions": { - "allowSyntheticDefaultImports": true, - "emitDecoratorMetadata": true, - "exactOptionalPropertyTypes": false, - "experimentalDecorators": true, - "jsx": "react-jsx", - "module": "ESNext", - "moduleResolution": "bundler", - "outDir": "./dist", - "skipLibCheck": true, - "sourceMap": true, - "target": "ESNext" - }, - "exclude": [ - "./dist", - "./streams", - "../client/dist" - ], - "extends": "@wsh-2025/configs/tsconfig.json", - "include": [ - "./src/**/*", - "./playwright.config.ts" - ] -}