diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml new file mode 100644 index 0000000000..6926b0c50d --- /dev/null +++ b/.github/workflows/copilot-setup-steps.yml @@ -0,0 +1,28 @@ +name: Copilot Setup Steps + +# Automatically run the setup steps when they are changed to allow for easy validation, and +# allow manual testing through the repository's "Actions" tab +on: + workflow_dispatch: + push: + paths: + - .github/workflows/copilot-setup-steps.yml + pull_request: + paths: + - .github/workflows/copilot-setup-steps.yml + +jobs: + copilot-setup-steps: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@v5 + - name: Use Node.js + uses: actions/setup-node@v6 + with: + node-version: 20 + - name: Install pnpm + uses: pnpm/action-setup@v4 + - name: Install dependencies + run: pnpm install --frozen-lockfile diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 9fe42390d4..2a19d6fbee 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -83,7 +83,7 @@ jobs: "PUBLIC_CONSOLE_MODE=cloud" "PUBLIC_CONSOLE_FEATURE_FLAGS=" "PUBLIC_APPWRITE_MULTI_REGION=true" - "PUBLIC_CONSOLE_EMAIL_VERIFICATION=false" + "PUBLIC_CONSOLE_EMAIL_VERIFICATION=true" "PUBLIC_CONSOLE_MOCK_AI_SUGGESTIONS=false" "PUBLIC_GROWTH_ENDPOINT=${{ secrets.PUBLIC_GROWTH_ENDPOINT }}" "PUBLIC_STRIPE_KEY=${{ secrets.PUBLIC_STRIPE_KEY_STAGE }}" diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000000..82bcb13c7f --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,104 @@ +# Appwrite Console - Copilot Instructions + +## Repository Overview + +Appwrite Console is the web-based GUI for the Appwrite backend-as-a-service platform. Single-page application built with **Svelte 5 + SvelteKit 2**, **TypeScript** (not strict mode), **Vite 7**, tested with **Vitest + Playwright**. Package manager: **pnpm 10.15.1**, Node 20+. ~1500 files with extensive component-based architecture. + +## Critical Build & Test Commands + +### Setup (REQUIRED before any commands) + +1. **Install pnpm**: `npm install -g corepack && corepack enable && corepack prepare pnpm@10.15.1 --activate` +2. **Create .env**: `cp .env.example .env` (configure `PUBLIC_APPWRITE_ENDPOINT` and `PUBLIC_CONSOLE_MODE`) +3. **Configure network access** (if using GitHub Actions or restricted environments): + - Ensure firewall/proxy allows access to: `pkg.pr.new`, `pkg.vc`, `registry.npmjs.org` + - These domains are required for dependencies: `@appwrite.io/console`, `@appwrite.io/pink-icons-svelte`, `@appwrite.io/pink-svelte` + - In GitHub Actions: Use `pnpm/action-setup@v4` which handles registry configuration + - If network errors persist, check proxy settings: `npm config get proxy` and `npm config get https-proxy` +4. **Install dependencies**: `pnpm install --frozen-lockfile` (if pkg.pr.new/pkg.vc fail due to network restrictions, installation may still succeed with cached versions) + +### Development Commands + +**Standard workflow**: `check` → `lint` → `test` → `build` (before committing) + +- `pnpm run check` - TypeScript/Svelte validation (~30-60s) +- `pnpm run lint` - ESLint check (~10-20s) +- `pnpm run format` - Auto-fix Prettier formatting +- `pnpm run test` - Vitest unit tests with TZ=EST (~10-30s) +- `pnpm run build` - Production build via build.js (~60-120s) +- `pnpm dev` - Dev server on port 3000 +- `pnpm run preview` - Preview build on port 4173 +- `pnpm run e2e` - Playwright tests (needs `pnpm exec playwright install --with-deps chromium` first, ~120s+) + +**CI Pipeline** (`.github/workflows/tests.yml`): audit → install → check → lint → test → build + +## Project Structure + +``` +src/ +├── lib/ # Reusable logic ($lib alias) +│ ├── components/ # Feature components (billing, domains, permissions, etc.) +│ ├── elements/ # Basic UI elements +│ ├── helpers/ # Utility functions (array, date, string, etc.) +│ ├── stores/ # Svelte stores for state +│ ├── sdk/ # Appwrite SDK wrappers +│ └── constants.ts, flags.ts, system.ts +├── routes/ +│ ├── (console)/ # Auth-required routes +│ │ ├── organization-[organization]/ +│ │ └── project-[region]-[project]/ # databases, functions, messaging, storage +│ └── (public)/ # Public routes (login, register, auth callbacks) +├── themes/ # Theme definitions ($themes alias) +└── app.html, hooks.{client,server}.ts, service-worker.ts +``` + +**SvelteKit conventions**: `+page.svelte` (component), `+page.ts` (data loader), `+layout.svelte` (wrapper), `+error.svelte` (errors). Groups like `(console)` organize routes without affecting URLs. Dynamic params: `[param]`. + +## Key Configuration + +**svelte.config.js**: Adapter = static SPA (fallback: index.html), base path `/console`, aliases: `$lib`, `$routes`, `$themes` +**vite.config.ts**: Dev port 3000, Vitest (client=jsdom, server=node), test files: `src/**/*.{test,spec}.{js,ts}` +**tsconfig.json**: Extends `.svelte-kit/tsconfig.json`, **NOT strict mode** (`strict: false`) +**eslint.config.js**: Flat config (ESLint 9+), many rules disabled (see TODOs) +**.prettierrc**: 4 spaces, single quotes, 100 char width, no trailing commas + +## Testing + +**Unit (Vitest)**: Tests in `src/lib/helpers/*.test.ts`, run with `TZ=EST` (timezone matters). Setup mocks SvelteKit (`$app/*`) in `vitest-setup-client.ts`. +**E2E (Playwright)**: Tests in `e2e/journeys/*.spec.ts`, needs build+preview on port 4173, retries 3x, timeout 120s, Chromium only. + +## Common Pitfalls + +1. **Blank page in dev**: Disable ad blockers if seeing "Failed to fetch dynamically imported module" (known SvelteKit issue) +2. **Network errors on install**: + - pkg.pr.new/pkg.vc deps may fail due to firewall/proxy restrictions + - Check access: `curl -I https://pkg.pr.new` and `curl -I https://pkg.vc` + - Configure proxy if needed: `npm config set proxy http://proxy:port` and `npm config set https-proxy http://proxy:port` + - GitHub Actions: Ensure runner has internet access; use `pnpm/action-setup@v4` action + - Local dev: Often safe to continue with cached versions if network fails +3. **OOM on build**: Set `NODE_OPTIONS=--max_old_space_size=8192` (like Dockerfile does) +4. **Test failures**: Always use `pnpm run test` (sets TZ=EST), not `vitest` directly +5. **TS errors not showing**: Run `pnpm run check` explicitly (dev server doesn't always surface them) +6. **Format vs lint conflicts**: Run `pnpm run format` before `pnpm run lint` +7. **E2E timeouts**: Wait 120s for preview server startup, tests auto-retry 3x +8. **Stale build**: Clear `.svelte-kit` if changes not reflected: `rm -rf .svelte-kit && pnpm run build` + +## Code Conventions + +- Imports: Use `$lib`, `$routes`, `$themes` aliases +- Components: PascalCase, in `src/lib/components/[feature]/` +- Helpers: Pure functions in `src/lib/helpers/` +- Types: Inline or `.d.ts`, not `.types.ts` files +- Comments: Minimal, use for TODOs or complex logic +- TypeScript: Not strict mode, `any` tolerated + +## Workflow + +1. Run Appwrite backend locally (see [docs](https://appwrite.io/docs/advanced/self-hosting)) +2. Configure `.env` with backend endpoint +3. `pnpm install --frozen-lockfile` +4. `pnpm dev` (hot reload on port 3000) +5. Before commit: `pnpm run check && pnpm run format && pnpm run lint && pnpm run test && pnpm run build` +6. **Take screenshots**: For any UI changes, capture screenshots and include them in the PR description or comments before finalizing + +**Trust these instructions** - only search if incomplete/incorrect. See CONTRIBUTING.md for PR conventions. Use `--frozen-lockfile` always. Docker builds: multi-stage, final image is nginx serving static files from `/console` path. diff --git a/e2e/steps/free-project.ts b/e2e/steps/free-project.ts index a8a3dadb95..cf0972e478 100644 --- a/e2e/steps/free-project.ts +++ b/e2e/steps/free-project.ts @@ -17,10 +17,22 @@ export async function createFreeProject(page: Page): Promise { await page.waitForURL(/\/organization-[^/]+/); await page.getByRole('button', { name: 'create project' }).first().click(); const dialog = page.locator('dialog[open]'); + await dialog.getByPlaceholder('Project name').fill('test project'); + + let region = 'fra'; // for fallback + const regionPicker = dialog.locator('button[role="combobox"]'); + if (await regionPicker.isVisible()) { + await regionPicker.click(); + await page.getByRole('option', { name: /New York/i }).click(); + + region = 'nyc'; + } + await dialog.getByRole('button', { name: 'create' }).click(); - await page.waitForURL(/\/project-fra-[^/]+/); - expect(page.url()).toContain('/console/project-fra-'); + + await page.waitForURL(new RegExp(`/project-${region}-[^/]+`)); + expect(page.url()).toContain(`/console/project-${region}-`); return getProjectIdFromUrl(page.url()); }); diff --git a/e2e/steps/pro-project.ts b/e2e/steps/pro-project.ts index 94cbb601f8..3f3a7ec1fe 100644 --- a/e2e/steps/pro-project.ts +++ b/e2e/steps/pro-project.ts @@ -50,10 +50,21 @@ export async function createProProject(page: Page): Promise { await page.waitForURL(/\/organization-[^/]+/); await page.getByRole('button', { name: 'create project' }).first().click(); const dialog = page.locator('dialog[open]'); + await dialog.getByPlaceholder('Project name').fill('test project'); + + let region = 'fra'; // for fallback + const regionPicker = dialog.locator('button[role="combobox"]'); + if (await regionPicker.isVisible()) { + await regionPicker.click(); + await page.getByRole('option', { name: /New York/i }).click(); + + region = 'nyc'; + } + await dialog.getByRole('button', { name: 'create' }).click(); - await page.waitForURL(/\/project-fra-[^/]+/); - expect(page.url()).toContain('/console/project-fra-'); + await page.waitForURL(new RegExp(`/project-${region}-[^/]+`)); + expect(page.url()).toContain(`/console/project-${region}-`); return getProjectIdFromUrl(page.url()); }); diff --git a/package.json b/package.json index 3268a42cd6..6ac79cd4e5 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "clean": "rm -rf node_modules && rm -rf .svelte_kit && pnpm i --force", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-check --tsconfig ./tsconfig.json --watch", - "format": "prettier --cache --write .", + "format": "prettier --cache --write --cache .", "lint": "prettier --check . && eslint .", "test": "TZ=EST vitest run", "test:ui": "TZ=EST vitest --ui", @@ -24,9 +24,9 @@ "@ai-sdk/svelte": "^1.1.24", "@appwrite.io/console": "https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@2752", "@appwrite.io/pink-icons": "0.25.0", - "@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@8f82877", + "@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@4472521", "@appwrite.io/pink-legacy": "^1.0.3", - "@appwrite.io/pink-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@8f82877", + "@appwrite.io/pink-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@4472521", "@faker-js/faker": "^9.9.0", "@popperjs/core": "^2.11.8", "@sentry/sveltekit": "^8.55.0", @@ -99,5 +99,5 @@ "svelte-preprocess" ] }, - "packageManager": "pnpm@10.20.0" + "packageManager": "pnpm@10.21.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5b068324ba..b680bc1624 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,7 +10,7 @@ importers: dependencies: '@ai-sdk/svelte': specifier: ^1.1.24 - version: 1.1.24(svelte@5.39.11)(zod@4.1.12) + version: 1.1.24(svelte@5.43.6)(zod@3.24.3) '@appwrite.io/console': specifier: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@2752 version: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@2752 @@ -18,14 +18,14 @@ importers: specifier: 0.25.0 version: 0.25.0 '@appwrite.io/pink-icons-svelte': - specifier: https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@8f82877 - version: https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@8f82877(svelte@5.39.11) + specifier: https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@4472521 + version: https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@4472521(svelte@5.43.6) '@appwrite.io/pink-legacy': specifier: ^1.0.3 version: 1.0.3 '@appwrite.io/pink-svelte': - specifier: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@8f82877 - version: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@8f82877(svelte@5.39.11) + specifier: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@4472521 + version: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@4472521(svelte@5.43.6) '@faker-js/faker': specifier: ^9.9.0 version: 9.9.0 @@ -34,13 +34,13 @@ importers: version: 2.11.8 '@sentry/sveltekit': specifier: ^8.55.0 - version: 8.55.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.37.0)(@sveltejs/kit@2.46.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2)))(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2)))(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2)) + version: 8.55.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.30.0)(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0)))(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0)))(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0)) '@stripe/stripe-js': specifier: ^3.5.0 version: 3.5.0 ai: specifier: ^2.2.37 - version: 2.2.37(react@19.2.0)(solid-js@1.9.9)(svelte@5.39.11)(vue@3.5.22(typescript@5.9.3)) + version: 2.2.37(react@19.2.0)(solid-js@1.9.5)(svelte@5.43.6)(vue@3.5.13(typescript@5.9.3)) analytics: specifier: ^0.8.19 version: 0.8.19(@types/dlv@1.1.5) @@ -49,7 +49,7 @@ importers: version: 4.9.0 dayjs: specifier: ^1.11.18 - version: 1.11.18 + version: 1.11.19 deep-equal: specifier: ^2.2.3 version: 2.2.3 @@ -85,41 +85,41 @@ importers: version: 2.0.1 svelte-confetti: specifier: ^1.4.0 - version: 1.4.0(svelte@5.39.11) + version: 1.4.0(svelte@5.43.6) svelte-reparent: specifier: ^0.0.1 - version: 0.0.1(svelte@5.39.11) + version: 0.0.1(svelte@5.43.6) tippy.js: specifier: ^6.3.7 version: 6.3.7 devDependencies: '@eslint/compat': specifier: ^1.4.0 - version: 1.4.0(eslint@9.37.0(jiti@2.6.1)) + version: 1.4.1(eslint@9.39.1) '@eslint/js': specifier: ^9.37.0 - version: 9.37.0 + version: 9.39.1 '@imagine.dev/web-components': specifier: ^0.0.34 version: 0.0.34(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@melt-ui/pp': specifier: ^0.3.2 - version: 0.3.2(@melt-ui/svelte@0.86.6(svelte@5.39.11))(svelte@5.39.11) + version: 0.3.2(@melt-ui/svelte@0.86.6(svelte@5.43.6))(svelte@5.43.6) '@melt-ui/svelte': specifier: ^0.86.6 - version: 0.86.6(svelte@5.39.11) + version: 0.86.6(svelte@5.43.6) '@playwright/test': specifier: ^1.56.0 - version: 1.56.0 + version: 1.56.1 '@sveltejs/adapter-static': specifier: ^3.0.10 - version: 3.0.10(@sveltejs/kit@2.46.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2)))(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2))) + version: 3.0.10(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0)))(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0))) '@sveltejs/kit': specifier: ^2.46.2 - version: 2.46.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2)))(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2)) + version: 2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0)))(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0)) '@sveltejs/vite-plugin-svelte': specifier: ^5.1.1 - version: 5.1.1(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2)) + version: 5.1.1(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0)) '@testing-library/dom': specifier: ^10.4.1 version: 10.4.1 @@ -128,7 +128,7 @@ importers: version: 6.9.1 '@testing-library/svelte': specifier: ^5.2.8 - version: 5.2.8(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2))(vitest@3.2.4) + version: 5.2.8(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0))(vitest@3.2.4) '@testing-library/user-event': specifier: ^14.6.1 version: 14.6.1(@testing-library/dom@10.4.1) @@ -143,10 +143,10 @@ importers: version: 2.0.8 '@typescript-eslint/eslint-plugin': specifier: ^8.46.0 - version: 8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) + version: 8.46.4(@typescript-eslint/parser@8.46.4(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3) '@typescript-eslint/parser': specifier: ^8.46.0 - version: 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) + version: 8.46.4(eslint@9.39.1)(typescript@5.9.3) '@vitest/ui': specifier: ^3.2.4 version: 3.2.4(vitest@3.2.4) @@ -155,16 +155,16 @@ importers: version: 5.0.2 eslint: specifier: ^9.37.0 - version: 9.37.0(jiti@2.6.1) + version: 9.39.1 eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.37.0(jiti@2.6.1)) + version: 10.1.8(eslint@9.39.1) eslint-plugin-svelte: specifier: ^3.12.4 - version: 3.12.4(eslint@9.37.0(jiti@2.6.1))(svelte@5.39.11) + version: 3.13.0(eslint@9.39.1)(svelte@5.43.6) globals: specifier: ^16.4.0 - version: 16.4.0 + version: 16.5.0 jsdom: specifier: ^26.1.0 version: 26.1.0 @@ -176,19 +176,19 @@ importers: version: 3.6.2 prettier-plugin-svelte: specifier: ^3.4.0 - version: 3.4.0(prettier@3.6.2)(svelte@5.39.11) + version: 3.4.0(prettier@3.6.2)(svelte@5.43.6) sass: specifier: ^1.93.2 - version: 1.93.2 + version: 1.94.0 svelte: specifier: ^5.39.10 - version: 5.39.11 + version: 5.43.6 svelte-check: specifier: ^4.3.2 - version: 4.3.3(picomatch@4.0.3)(svelte@5.39.11)(typescript@5.9.3) + version: 4.3.4(picomatch@4.0.3)(svelte@5.43.6)(typescript@5.9.3) svelte-preprocess: specifier: ^6.0.3 - version: 6.0.3(@babel/core@7.28.4)(postcss-load-config@3.1.4(postcss@8.5.6))(postcss@8.5.6)(sass@1.93.2)(svelte@5.39.11)(typescript@5.9.3) + version: 6.0.3(@babel/core@7.26.10)(postcss-load-config@3.1.4(postcss@8.5.6))(postcss@8.5.6)(sass@1.94.0)(svelte@5.43.6)(typescript@5.9.3) svelte-sequential-preprocessor: specifier: ^2.0.2 version: 2.0.2 @@ -203,18 +203,18 @@ importers: version: 5.9.3 typescript-eslint: specifier: ^8.46.0 - version: 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) + version: 8.46.4(eslint@9.39.1)(typescript@5.9.3) vite: specifier: ^7.1.9 - version: 7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2) + version: 7.2.2(@types/node@22.13.14)(sass@1.94.0) vitest: specifier: ^3.2.4 - version: 3.2.4(@types/debug@4.1.12)(@types/node@24.7.2)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(sass@1.93.2) + version: 3.2.4(@types/node@22.13.14)(@vitest/ui@3.2.4)(jsdom@26.1.0)(sass@1.94.0) packages: - '@adobe/css-tools@4.4.4': - resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==} + '@adobe/css-tools@4.4.2': + resolution: {integrity: sha512-baYZExFpsdkBNuvGKTKWCwKH57HRZLVtycZS05WTQNVOiXVSeAki3nU35zlRbToeMW8aHlJfyS+1C4BOv27q0A==} '@ai-sdk/provider-utils@2.1.13': resolution: {integrity: sha512-kLjqsfOdONr6DGcGEntFYM1niXz1H05vyZNf9OAzK+KKKc64izyP4/q/9HX7W4+6g8hm6BnmKxu8vkr6FSOqDg==} @@ -281,8 +281,8 @@ packages: peerDependencies: svelte: ^4.0.0 - '@appwrite.io/pink-icons-svelte@https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@8f82877': - resolution: {tarball: https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@8f82877} + '@appwrite.io/pink-icons-svelte@https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@4472521': + resolution: {tarball: https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@4472521} version: 2.0.0-RC.1 peerDependencies: svelte: ^4.0.0 @@ -296,45 +296,41 @@ packages: '@appwrite.io/pink-legacy@1.0.3': resolution: {integrity: sha512-GGde5fmPhs+s6/3aFeMPc/kKADG/gTFkYQSy6oBN8pK0y0XNCLrZZgBv+EBbdhwdtqVEWXa0X85Mv9w7jcIlwQ==} - '@appwrite.io/pink-svelte@https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@8f82877': - resolution: {tarball: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@8f82877} + '@appwrite.io/pink-svelte@https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@4472521': + resolution: {tarball: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@4472521} version: 2.0.0-RC.2 peerDependencies: svelte: ^4.0.0 - '@asamuzakjp/css-color@3.2.0': - resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==} + '@asamuzakjp/css-color@3.1.1': + resolution: {integrity: sha512-hpRD68SV2OMcZCsrbdkccTw5FXjNDLo5OuqSHyHZfwweGsDWZwDJ2+gONyNAbazZclobMirACLw0lk8WVxIqxA==} - '@babel/code-frame@7.27.1': - resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + '@babel/code-frame@7.26.2': + resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.28.4': - resolution: {integrity: sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==} + '@babel/compat-data@7.26.8': + resolution: {integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==} engines: {node: '>=6.9.0'} - '@babel/core@7.28.4': - resolution: {integrity: sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==} + '@babel/core@7.26.10': + resolution: {integrity: sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==} engines: {node: '>=6.9.0'} - '@babel/generator@7.28.3': - resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==} + '@babel/generator@7.27.0': + resolution: {integrity: sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.27.2': - resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + '@babel/helper-compilation-targets@7.27.0': + resolution: {integrity: sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==} engines: {node: '>=6.9.0'} - '@babel/helper-globals@7.28.0': - resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + '@babel/helper-module-imports@7.25.9': + resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.27.1': - resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-transforms@7.28.3': - resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} + '@babel/helper-module-transforms@7.26.0': + resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -343,219 +339,213 @@ packages: resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.27.1': - resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.27.1': - resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + '@babel/helper-validator-option@7.25.9': + resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.28.4': - resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} + '@babel/helpers@7.27.0': + resolution: {integrity: sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==} engines: {node: '>=6.9.0'} - '@babel/parser@7.28.4': - resolution: {integrity: sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==} + '@babel/parser@7.28.5': + resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/runtime@7.28.4': - resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} + '@babel/runtime@7.27.0': + resolution: {integrity: sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==} engines: {node: '>=6.9.0'} - '@babel/template@7.27.2': - resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + '@babel/template@7.27.0': + resolution: {integrity: sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.28.4': - resolution: {integrity: sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==} + '@babel/traverse@7.27.0': + resolution: {integrity: sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.4': - resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} + '@babel/types@7.28.5': + resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} engines: {node: '>=6.9.0'} - '@csstools/color-helpers@5.1.0': - resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} + '@csstools/color-helpers@5.0.2': + resolution: {integrity: sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==} engines: {node: '>=18'} - '@csstools/css-calc@2.1.4': - resolution: {integrity: sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==} + '@csstools/css-calc@2.1.2': + resolution: {integrity: sha512-TklMyb3uBB28b5uQdxjReG4L80NxAqgrECqLZFQbyLekwwlcDDS8r3f07DKqeo8C4926Br0gf/ZDe17Zv4wIuw==} engines: {node: '>=18'} peerDependencies: - '@csstools/css-parser-algorithms': ^3.0.5 - '@csstools/css-tokenizer': ^3.0.4 + '@csstools/css-parser-algorithms': ^3.0.4 + '@csstools/css-tokenizer': ^3.0.3 - '@csstools/css-color-parser@3.1.0': - resolution: {integrity: sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==} + '@csstools/css-color-parser@3.0.8': + resolution: {integrity: sha512-pdwotQjCCnRPuNi06jFuP68cykU1f3ZWExLe/8MQ1LOs8Xq+fTkYgd+2V8mWUWMrOn9iS2HftPVaMZDaXzGbhQ==} engines: {node: '>=18'} peerDependencies: - '@csstools/css-parser-algorithms': ^3.0.5 - '@csstools/css-tokenizer': ^3.0.4 + '@csstools/css-parser-algorithms': ^3.0.4 + '@csstools/css-tokenizer': ^3.0.3 - '@csstools/css-parser-algorithms@3.0.5': - resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==} + '@csstools/css-parser-algorithms@3.0.4': + resolution: {integrity: sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==} engines: {node: '>=18'} peerDependencies: - '@csstools/css-tokenizer': ^3.0.4 + '@csstools/css-tokenizer': ^3.0.3 - '@csstools/css-tokenizer@3.0.4': - resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} + '@csstools/css-tokenizer@3.0.3': + resolution: {integrity: sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==} engines: {node: '>=18'} - '@esbuild/aix-ppc64@0.25.10': - resolution: {integrity: sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==} + '@esbuild/aix-ppc64@0.25.1': + resolution: {integrity: sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.25.10': - resolution: {integrity: sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==} + '@esbuild/android-arm64@0.25.1': + resolution: {integrity: sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.25.10': - resolution: {integrity: sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==} + '@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.25.10': - resolution: {integrity: sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==} + '@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.25.10': - resolution: {integrity: sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==} + '@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.25.10': - resolution: {integrity: sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==} + '@esbuild/darwin-x64@0.25.1': + resolution: {integrity: sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.25.10': - resolution: {integrity: sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==} + '@esbuild/freebsd-arm64@0.25.1': + resolution: {integrity: sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.10': - resolution: {integrity: sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==} + '@esbuild/freebsd-x64@0.25.1': + resolution: {integrity: sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.25.10': - resolution: {integrity: sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==} + '@esbuild/linux-arm64@0.25.1': + resolution: {integrity: sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.25.10': - resolution: {integrity: sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==} + '@esbuild/linux-arm@0.25.1': + resolution: {integrity: sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.25.10': - resolution: {integrity: sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==} + '@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.25.10': - resolution: {integrity: sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==} + '@esbuild/linux-loong64@0.25.1': + resolution: {integrity: sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.25.10': - resolution: {integrity: sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==} + '@esbuild/linux-mips64el@0.25.1': + resolution: {integrity: sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.25.10': - resolution: {integrity: sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==} + '@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.25.10': - resolution: {integrity: sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==} + '@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.25.10': - resolution: {integrity: sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==} + '@esbuild/linux-s390x@0.25.1': + resolution: {integrity: sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.25.10': - resolution: {integrity: sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==} + '@esbuild/linux-x64@0.25.1': + resolution: {integrity: sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.10': - resolution: {integrity: sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==} + '@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.25.10': - resolution: {integrity: sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==} + '@esbuild/netbsd-x64@0.25.1': + resolution: {integrity: sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.25.10': - resolution: {integrity: sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==} + '@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.25.10': - resolution: {integrity: sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==} + '@esbuild/openbsd-x64@0.25.1': + resolution: {integrity: sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.25.10': - resolution: {integrity: sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - - '@esbuild/sunos-x64@0.25.10': - resolution: {integrity: sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==} + '@esbuild/sunos-x64@0.25.1': + resolution: {integrity: sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.25.10': - resolution: {integrity: sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==} + '@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.25.10': - resolution: {integrity: sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==} + '@esbuild/win32-ia32@0.25.1': + resolution: {integrity: sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.25.10': - resolution: {integrity: sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==} + '@esbuild/win32-x64@0.25.1': + resolution: {integrity: sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==} engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -570,8 +560,8 @@ packages: resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/compat@1.4.0': - resolution: {integrity: sha512-DEzm5dKeDBPm3r08Ixli/0cmxr8LkRdwxMRUIJBlSCpAwSrvFEJpVBzV+66JhDxiaqKxnRzCXhtiMiczF7Hglg==} + '@eslint/compat@1.4.1': + resolution: {integrity: sha512-cfO82V9zxxGBxcQDr1lfaYB7wykTa0b00mGa36FrJl7iTFd0Z2cHfEYuxcBRP/iNijCsWsEkA+jzT8hGYmv33w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.40 || 9 @@ -579,61 +569,65 @@ packages: eslint: optional: true - '@eslint/config-array@0.21.0': - resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==} + '@eslint/config-array@0.21.1': + resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/config-helpers@0.4.0': - resolution: {integrity: sha512-WUFvV4WoIwW8Bv0KeKCIIEgdSiFOsulyN0xrMu+7z43q/hkOLXjvb5u7UC9jDxvRzcrbEmuZBX5yJZz1741jog==} + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.16.0': - resolution: {integrity: sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==} + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/eslintrc@3.3.1': resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.37.0': - resolution: {integrity: sha512-jaS+NJ+hximswBG6pjNX0uEJZkrT0zwpVi3BA3vX22aFGjJjmgSTSmPpZCRKmoBL5VY/M6p0xsSJx7rk7sy5gg==} + '@eslint/js@9.39.1': + resolution: {integrity: sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/object-schema@2.1.6': - resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/plugin-kit@0.4.0': - resolution: {integrity: sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==} + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@faker-js/faker@9.9.0': resolution: {integrity: sha512-OEl393iCOoo/z8bMezRlJu+GlRGlsKbUAN7jKB6LhnKoqKve5DXRpalbItIIcwnCjs1k/FOPjFzcA6Qn+H+YbA==} engines: {node: '>=18.0.0', npm: '>=9.0.0'} - '@floating-ui/core@1.7.3': - resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} + '@floating-ui/core@1.6.9': + resolution: {integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==} - '@floating-ui/dom@1.7.4': - resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==} + '@floating-ui/dom@1.6.13': + resolution: {integrity: sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==} - '@floating-ui/utils@0.2.10': - resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} + '@floating-ui/utils@0.2.9': + resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} - '@humanfs/node@0.16.7': - resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} + '@humanfs/node@0.16.6': + resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} engines: {node: '>=18.18.0'} '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} - '@humanwhocodes/retry@0.4.3': - resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + '@humanwhocodes/retry@0.3.1': + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} + + '@humanwhocodes/retry@0.4.2': + resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==} engines: {node: '>=18.18'} '@imagine.dev/web-components@0.0.34': @@ -642,11 +636,12 @@ packages: react: 19.1.0 react-dom: 19.1.0 - '@internationalized/date@3.10.0': - resolution: {integrity: sha512-oxDR/NTEJ1k+UFVQElaNIk65E/Z83HK1z1WI3lQyhTtnNg4R5oVXaPzK3jcpKG8UHKDVuDQHzn+wsxSz8RP3aw==} + '@internationalized/date@3.7.0': + resolution: {integrity: sha512-VJ5WS3fcVx0bejE/YHfbDKR/yawZgKqn/if+oEeLqNwBtPzVB06olkfcnojTmEMX+gTpH+FlQ69SHNitJ8/erQ==} - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + '@jridgewell/gen-mapping@0.3.8': + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + engines: {node: '>=6.0.0'} '@jridgewell/remapping@2.3.5': resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} @@ -655,11 +650,18 @@ packages: resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} '@melt-ui/pp@0.3.2': resolution: {integrity: sha512-xKkPvaIAFinklLXcQOpwZ8YSpqAFxykjWf8Y/fSJQwsixV/0rcFs07hJ49hJjPy5vItvw5Qa0uOjzFUbXzBypQ==} @@ -898,8 +900,8 @@ packages: resolution: {integrity: sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==} engines: {node: '>=14'} - '@opentelemetry/semantic-conventions@1.37.0': - resolution: {integrity: sha512-JD6DerIKdJGmRp4jQyX5FlrQjA4tjOw1cvfsPAZXfOOEErMUHjPcPSICS+6WnM0nB0efSFARh0KAZss+bvExOA==} + '@opentelemetry/semantic-conventions@1.30.0': + resolution: {integrity: sha512-4VlGgo32k2EQ2wcCY3vEU28A0O13aOtHz3Xt2/2U5FAh9EfhD6t6DqL5Z6yAnRCntbTFDU4YfbpyzSlHNWycPw==} engines: {node: '>=14'} '@opentelemetry/sql-common@0.40.1': @@ -990,13 +992,13 @@ packages: resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==} engines: {node: '>= 10.0.0'} - '@playwright/test@1.56.0': - resolution: {integrity: sha512-Tzh95Twig7hUwwNe381/K3PggZBZblKUe2wv25oIpzWLr6Z0m4KgV1ZVIjnR6GM9ANEqjZD7XsZEa6JL/7YEgg==} + '@playwright/test@1.56.1': + resolution: {integrity: sha512-vSMYtL/zOcFpvJCW71Q/OEGQb7KYBPAdKh35WNSkaZA75JlAO8ED8UN6GUNTm3drWomcbcqRPFqQbLae8yBTdg==} engines: {node: '>=18'} hasBin: true - '@polka/url@1.0.0-next.29': - resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} + '@polka/url@1.0.0-next.28': + resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==} '@popperjs/core@2.11.8': resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} @@ -1004,113 +1006,103 @@ packages: '@prisma/instrumentation@5.22.0': resolution: {integrity: sha512-LxccF392NN37ISGxIurUljZSh1YWnphO34V5a0+T7FVQG2u9bhAXRTJpgmQ3483woVhkraQZFF7cbRrpbw/F4Q==} - '@rollup/rollup-android-arm-eabi@4.52.4': - resolution: {integrity: sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA==} + '@rollup/rollup-android-arm-eabi@4.46.2': + resolution: {integrity: sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.52.4': - resolution: {integrity: sha512-P9LDQiC5vpgGFgz7GSM6dKPCiqR3XYN1WwJKA4/BUVDjHpYsf3iBEmVz62uyq20NGYbiGPR5cNHI7T1HqxNs2w==} + '@rollup/rollup-android-arm64@4.46.2': + resolution: {integrity: sha512-nTeCWY83kN64oQ5MGz3CgtPx8NSOhC5lWtsjTs+8JAJNLcP3QbLCtDDgUKQc/Ro/frpMq4SHUaHN6AMltcEoLQ==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.52.4': - resolution: {integrity: sha512-QRWSW+bVccAvZF6cbNZBJwAehmvG9NwfWHwMy4GbWi/BQIA/laTIktebT2ipVjNncqE6GLPxOok5hsECgAxGZg==} + '@rollup/rollup-darwin-arm64@4.46.2': + resolution: {integrity: sha512-HV7bW2Fb/F5KPdM/9bApunQh68YVDU8sO8BvcW9OngQVN3HHHkw99wFupuUJfGR9pYLLAjcAOA6iO+evsbBaPQ==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.52.4': - resolution: {integrity: sha512-hZgP05pResAkRJxL1b+7yxCnXPGsXU0fG9Yfd6dUaoGk+FhdPKCJ5L1Sumyxn8kvw8Qi5PvQ8ulenUbRjzeCTw==} + '@rollup/rollup-darwin-x64@4.46.2': + resolution: {integrity: sha512-SSj8TlYV5nJixSsm/y3QXfhspSiLYP11zpfwp6G/YDXctf3Xkdnk4woJIF5VQe0of2OjzTt8EsxnJDCdHd2xMA==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.52.4': - resolution: {integrity: sha512-xmc30VshuBNUd58Xk4TKAEcRZHaXlV+tCxIXELiE9sQuK3kG8ZFgSPi57UBJt8/ogfhAF5Oz4ZSUBN77weM+mQ==} + '@rollup/rollup-freebsd-arm64@4.46.2': + resolution: {integrity: sha512-ZyrsG4TIT9xnOlLsSSi9w/X29tCbK1yegE49RYm3tu3wF1L/B6LVMqnEWyDB26d9Ecx9zrmXCiPmIabVuLmNSg==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.52.4': - resolution: {integrity: sha512-WdSLpZFjOEqNZGmHflxyifolwAiZmDQzuOzIq9L27ButpCVpD7KzTRtEG1I0wMPFyiyUdOO+4t8GvrnBLQSwpw==} + '@rollup/rollup-freebsd-x64@4.46.2': + resolution: {integrity: sha512-pCgHFoOECwVCJ5GFq8+gR8SBKnMO+xe5UEqbemxBpCKYQddRQMgomv1104RnLSg7nNvgKy05sLsY51+OVRyiVw==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.52.4': - resolution: {integrity: sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ==} + '@rollup/rollup-linux-arm-gnueabihf@4.46.2': + resolution: {integrity: sha512-EtP8aquZ0xQg0ETFcxUbU71MZlHaw9MChwrQzatiE8U/bvi5uv/oChExXC4mWhjiqK7azGJBqU0tt5H123SzVA==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.52.4': - resolution: {integrity: sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q==} + '@rollup/rollup-linux-arm-musleabihf@4.46.2': + resolution: {integrity: sha512-qO7F7U3u1nfxYRPM8HqFtLd+raev2K137dsV08q/LRKRLEc7RsiDWihUnrINdsWQxPR9jqZ8DIIZ1zJJAm5PjQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.52.4': - resolution: {integrity: sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg==} + '@rollup/rollup-linux-arm64-gnu@4.46.2': + resolution: {integrity: sha512-3dRaqLfcOXYsfvw5xMrxAk9Lb1f395gkoBYzSFcc/scgRFptRXL9DOaDpMiehf9CO8ZDRJW2z45b6fpU5nwjng==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.52.4': - resolution: {integrity: sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g==} + '@rollup/rollup-linux-arm64-musl@4.46.2': + resolution: {integrity: sha512-fhHFTutA7SM+IrR6lIfiHskxmpmPTJUXpWIsBXpeEwNgZzZZSg/q4i6FU4J8qOGyJ0TR+wXBwx/L7Ho9z0+uDg==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loong64-gnu@4.52.4': - resolution: {integrity: sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ==} + '@rollup/rollup-linux-loongarch64-gnu@4.46.2': + resolution: {integrity: sha512-i7wfGFXu8x4+FRqPymzjD+Hyav8l95UIZ773j7J7zRYc3Xsxy2wIn4x+llpunexXe6laaO72iEjeeGyUFmjKeA==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.52.4': - resolution: {integrity: sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g==} + '@rollup/rollup-linux-ppc64-gnu@4.46.2': + resolution: {integrity: sha512-B/l0dFcHVUnqcGZWKcWBSV2PF01YUt0Rvlurci5P+neqY/yMKchGU8ullZvIv5e8Y1C6wOn+U03mrDylP5q9Yw==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.52.4': - resolution: {integrity: sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg==} + '@rollup/rollup-linux-riscv64-gnu@4.46.2': + resolution: {integrity: sha512-32k4ENb5ygtkMwPMucAb8MtV8olkPT03oiTxJbgkJa7lJ7dZMr0GCFJlyvy+K8iq7F/iuOr41ZdUHaOiqyR3iQ==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.52.4': - resolution: {integrity: sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA==} + '@rollup/rollup-linux-riscv64-musl@4.46.2': + resolution: {integrity: sha512-t5B2loThlFEauloaQkZg9gxV05BYeITLvLkWOkRXogP4qHXLkWSbSHKM9S6H1schf/0YGP/qNKtiISlxvfmmZw==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.52.4': - resolution: {integrity: sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA==} + '@rollup/rollup-linux-s390x-gnu@4.46.2': + resolution: {integrity: sha512-YKjekwTEKgbB7n17gmODSmJVUIvj8CX7q5442/CK80L8nqOUbMtf8b01QkG3jOqyr1rotrAnW6B/qiHwfcuWQA==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.52.4': - resolution: {integrity: sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg==} + '@rollup/rollup-linux-x64-gnu@4.46.2': + resolution: {integrity: sha512-Jj5a9RUoe5ra+MEyERkDKLwTXVu6s3aACP51nkfnK9wJTraCC8IMe3snOfALkrjTYd2G1ViE1hICj0fZ7ALBPA==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.52.4': - resolution: {integrity: sha512-dtBZYjDmCQ9hW+WgEkaffvRRCKm767wWhxsFW3Lw86VXz/uJRuD438/XvbZT//B96Vs8oTA8Q4A0AfHbrxP9zw==} + '@rollup/rollup-linux-x64-musl@4.46.2': + resolution: {integrity: sha512-7kX69DIrBeD7yNp4A5b81izs8BqoZkCIaxQaOpumcJ1S/kmqNFjPhDu1LHeVXv0SexfHQv5cqHsxLOjETuqDuA==} cpu: [x64] os: [linux] - '@rollup/rollup-openharmony-arm64@4.52.4': - resolution: {integrity: sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA==} - cpu: [arm64] - os: [openharmony] - - '@rollup/rollup-win32-arm64-msvc@4.52.4': - resolution: {integrity: sha512-8GKr640PdFNXwzIE0IrkMWUNUomILLkfeHjXBi/nUvFlpZP+FA8BKGKpacjW6OUUHaNI6sUURxR2U2g78FOHWQ==} + '@rollup/rollup-win32-arm64-msvc@4.46.2': + resolution: {integrity: sha512-wiJWMIpeaak/jsbaq2HMh/rzZxHVW1rU6coyeNNpMwk5isiPjSTx0a4YLSlYDwBH/WBvLz+EtsNqQScZTLJy3g==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.52.4': - resolution: {integrity: sha512-AIy/jdJ7WtJ/F6EcfOb2GjR9UweO0n43jNObQMb6oGxkYTfLcnN7vYYpG+CN3lLxrQkzWnMOoNSHTW54pgbVxw==} + '@rollup/rollup-win32-ia32-msvc@4.46.2': + resolution: {integrity: sha512-gBgaUDESVzMgWZhcyjfs9QFK16D8K6QZpwAaVNJxYDLHWayOta4ZMjGm/vsAEy3hvlS2GosVFlBlP9/Wb85DqQ==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.52.4': - resolution: {integrity: sha512-UF9KfsH9yEam0UjTwAgdK0anlQ7c8/pWPU2yVjyWcF1I1thABt6WXE47cI71pGiZ8wGvxohBoLnxM04L/wj8mQ==} - cpu: [x64] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.52.4': - resolution: {integrity: sha512-bf9PtUa0u8IXDVxzRToFQKsNCRz9qLYfR/MpECxl4mRoWYjAeFjgxj1XdZr2M/GNVpT05p+LgQOHopYDlUu6/w==} + '@rollup/rollup-win32-x64-msvc@4.46.2': + resolution: {integrity: sha512-CvUo2ixeIQGtF6WvuB87XWqPQkoFAFqW+HUo/WzHwuHDvIwZCtjdWXoYCcr06iKGydiqTclC4jU/TNObC/xKZg==} cpu: [x64] os: [win32] @@ -1142,55 +1134,55 @@ packages: resolution: {integrity: sha512-1esQdgSUCww9XAntO4pr7uAM5cfGhLsgTK9MEwAKNfvpMYJi9NUTYa3A7AZmdA8V6107Lo4OD7peIPrDRbaDCg==} engines: {node: '>= 14'} - '@sentry/cli-darwin@2.56.1': - resolution: {integrity: sha512-zfhT8MrvB5x/xRdIVGwg+sG0Cx3i0G6RH2zCrdQ/moWn8TfkwsM0O1k/AxpwbpcRfAHCkVb04CU/yKciKwg2KA==} + '@sentry/cli-darwin@2.43.0': + resolution: {integrity: sha512-0MYvRHJowXOMNY5W6XF4p9GQNH3LuQ+IHAQwVbZOsfwnEv8e20rf9BiPPzmJ9sIjZSWYR4yIqm6dBp6ABJFbGQ==} engines: {node: '>=10'} os: [darwin] - '@sentry/cli-linux-arm64@2.56.1': - resolution: {integrity: sha512-AypXIwZvOMJb9RgjI/98hTAd06FcOjqjIm6G9IR0OI4pJCOcaAXz9NKXdJqxpZd7phSMJnD+Bx/8iYOUPeY73A==} + '@sentry/cli-linux-arm64@2.43.0': + resolution: {integrity: sha512-7URSaNjbEJQZyYJ33XK3pVKl6PU2oO9ETF6R/4Cz2FmU3fecACLKVldv7+OuNl9aspLZ62mnPMDvT732/Fp2Ug==} engines: {node: '>=10'} cpu: [arm64] - os: [linux, freebsd, android] + os: [linux, freebsd] - '@sentry/cli-linux-arm@2.56.1': - resolution: {integrity: sha512-fNB/Ng11HrkGOSEIDg+fc3zfTCV7q6kJddp6ndK3QlYFsCffRSnclaX1SMp+mqxdWkHqe1kkp85OY8G/x5uAWw==} + '@sentry/cli-linux-arm@2.43.0': + resolution: {integrity: sha512-c2Fwb6HrFL1nbaGV4uRhHC1wEJPR+wfpKN5y06PgSNNbd10YrECAB3tqBHXC8CEmhuDyFR+ORGZ7VbswfCWEEQ==} engines: {node: '>=10'} cpu: [arm] - os: [linux, freebsd, android] + os: [linux, freebsd] - '@sentry/cli-linux-i686@2.56.1': - resolution: {integrity: sha512-vnH+WJEsUq7Lf7xc9udzE/M4hoDXXsniFFYr/7BvdnXtCQlNNaWFMXHbEDYAql3baIlHkWoG8cEHWuB/YKyniw==} + '@sentry/cli-linux-i686@2.43.0': + resolution: {integrity: sha512-bFo/tpMZeMJ275HPGmAENREchnBxhALOOpZAphSyalUu3pGZ+EETEtlSLrKyVNJo26Dye5W7GlrYUV9+rkyCtg==} engines: {node: '>=10'} cpu: [x86, ia32] - os: [linux, freebsd, android] + os: [linux, freebsd] - '@sentry/cli-linux-x64@2.56.1': - resolution: {integrity: sha512-3/BlKe5Vdnia36MeovghHJD8lbcum5TFIxLp+PSfH2sVb09+5Jo0L95oRTI2JkD8Fs+QNssvTqTxJj5eIo/n+A==} + '@sentry/cli-linux-x64@2.43.0': + resolution: {integrity: sha512-EbAmKXUNU/Ii4pNGVRCepU6ks1M43wStMKx3pibrUTllrrCwqYKyPxRRdoFYySHkduwCxnoKZcLEg9vWZ3qS6A==} engines: {node: '>=10'} cpu: [x64] - os: [linux, freebsd, android] + os: [linux, freebsd] - '@sentry/cli-win32-arm64@2.56.1': - resolution: {integrity: sha512-Gg8RV7CV7Tz4fiR1EN1Af5AVhJsnEXiZvfvfQXI4lp51MKAhcxZIMtEfg9HaWsn3Dm/wgwYBinyeywfWbTXYDg==} + '@sentry/cli-win32-arm64@2.43.0': + resolution: {integrity: sha512-KmJRCdQQGLSErJvrcGcN+yWo68m+5OdluhyJHsVYMOQknwu8YMOWLm12EIa+4t4GclDvwg5xcxLccCuiWMJUZw==} engines: {node: '>=10'} cpu: [arm64] os: [win32] - '@sentry/cli-win32-i686@2.56.1': - resolution: {integrity: sha512-6u6a060yC3i76Ze1apqgWr5luQSyhuD5ND84eWfh/UbddsEa42UHjoVHOiBwmpZqf/hvNZAtzLnE4NCvU4zOMg==} + '@sentry/cli-win32-i686@2.43.0': + resolution: {integrity: sha512-ZWxZdOyZX7NJ/CTskzg+dJ2xTpobFLXVNMOMq0HiwdhqXP2zYYJzKnIt3mHNJYA40zYFODGSgxIamodjpB8BuA==} engines: {node: '>=10'} cpu: [x86, ia32] os: [win32] - '@sentry/cli-win32-x64@2.56.1': - resolution: {integrity: sha512-11cdflajBrDWlRZqI9MOu7ok2vnPzFjKmbU3YvBYWQapNE+HHAsWdsRL/u/P1RmU62vj7Y42iSUcj6x1SNrdPw==} + '@sentry/cli-win32-x64@2.43.0': + resolution: {integrity: sha512-S/IRQYAziEnjpyROhnqzTqShDq3m8jcevXx+q5f49uQnFbfYcTgS1sdrEPqqao/K2boOWbffxYtTkvBiB/piQQ==} engines: {node: '>=10'} cpu: [x64] os: [win32] - '@sentry/cli@2.56.1': - resolution: {integrity: sha512-VDAIg+gmjNtJS5VUZQMDSK9RaKC9hYQi3PoXpNa+owNfQNk60bCi8z8jkbWRcKbNGn3V51WqvrQAqLoNAdPc9w==} + '@sentry/cli@2.43.0': + resolution: {integrity: sha512-gBE3bkx+PBJxopTrzIJLX4xHe5S0w87q5frIveWKDZ5ulVIU6YWnVumay0y07RIEweUEj3IYva1qH6HG2abfiA==} engines: {node: '>= 10'} hasBin: true @@ -1261,8 +1253,8 @@ packages: resolution: {integrity: sha512-pKS3wZnJoL1iTyGBXAvCwduNNeghJHY6QSRSNNvpYnrrQrLZ6Owsazjyynu0e0ObRgks0i7Rv+pe2M7/MBTZpQ==} engines: {node: '>=12.16'} - '@sveltejs/acorn-typescript@1.0.6': - resolution: {integrity: sha512-4awhxtMh4cx9blePWl10HRHj8Iivtqj+2QdDCSMDzxG+XKa9+VCNupQuCuvzEhYPzZSrX+0gC+0lHA/0fFKKQQ==} + '@sveltejs/acorn-typescript@1.0.5': + resolution: {integrity: sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ==} peerDependencies: acorn: ^8.9.0 @@ -1271,8 +1263,8 @@ packages: peerDependencies: '@sveltejs/kit': ^2.0.0 - '@sveltejs/kit@2.46.4': - resolution: {integrity: sha512-J1fd80WokLzIm6EAV7z7C2+/C02qVAX645LZomARARTRJkbbJSY1Jln3wtBZYibUB8c9/5Z6xqLAV39VdbtWCQ==} + '@sveltejs/kit@2.48.4': + resolution: {integrity: sha512-TGFX1pZUt9qqY20Cv5NyYvy0iLWHf2jXi8s+eCGsig7jQMdwZWKUFMR6TbvFNhfDSUpc1sH/Y5EHv20g3HHA3g==} engines: {node: '>=18.13'} hasBin: true peerDependencies: @@ -1299,8 +1291,8 @@ packages: svelte: ^5.0.0 vite: ^6.0.0 - '@swc/helpers@0.5.17': - resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} + '@swc/helpers@0.5.15': + resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} '@tanstack/svelte-virtual@3.13.12': resolution: {integrity: sha512-SsOinCktvpMFbdSW61X6jeUNaJvD1tmt30AFVSLe1FQxGxjdPkZo0gAsoVPqM9FFZqidvvXQ4gpadDaTz/yGxA==} @@ -1349,9 +1341,6 @@ packages: '@types/cookie@0.6.0': resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} - '@types/debug@4.1.12': - resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} - '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} @@ -1361,6 +1350,9 @@ packages: '@types/dlv@1.1.5': resolution: {integrity: sha512-JHOWNfiWepAhfwlSw17kiWrWrk6od2dEQgHltJw9AS0JPFoLZJBge5+Dnil2NfdjAvJ/+vGSX60/BRW20PpUXw==} + '@types/estree@1.0.7': + resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} + '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} @@ -1373,14 +1365,11 @@ packages: '@types/mdast@4.0.4': resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} - '@types/ms@2.1.0': - resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - '@types/mysql@2.15.26': resolution: {integrity: sha512-DSLCOXhkvfS5WNNPbfn2KdICAmk8lLc+/PNvnPnF7gOdMZCxopXduqv0OQ13y/yA/zXTSikZZqVgybUxOEg6YQ==} - '@types/node@24.7.2': - resolution: {integrity: sha512-/NbVmcGTP+lj5oa4yiYxxeBjRivKQ5Ns1eSZeB99ExsEQ6rX5XYU1Zy/gGxY/ilqtD4Etx9mKyrPxZRetiahhA==} + '@types/node@22.13.14': + resolution: {integrity: sha512-Zs/Ollc1SJ8nKUAgc7ivOEdIBM8JAKgrqqUYi2J997JuKO7/tpQC+WCetQ1sypiKCQWHdvdg9wBNpUPEWZae7w==} '@types/pg-pool@2.0.6': resolution: {integrity: sha512-TaAUE5rq2VQYxab5Ts7WZhKNmuN78Q6PiFonTDdpbx8a1H0M1vhy3rhiMjl+e2iHmogyMw7jZF4FrE6eJUy5HQ==} @@ -1394,8 +1383,8 @@ packages: '@types/prop-types@15.7.15': resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} - '@types/react@18.3.26': - resolution: {integrity: sha512-RFA/bURkcKzx/X9oumPG9Vp3D3JUgus/d0b67KB0t5S/raciymilkOa66olh78MUI92QLbEJevO7rvqU/kjwKA==} + '@types/react@18.3.23': + resolution: {integrity: sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==} '@types/remarkable@2.0.8': resolution: {integrity: sha512-eKXqPZfpQl1kOADjdKchHrp2gwn9qMnGXhH/AtZe0UrklzhGJkawJo/Y/D0AlWcdWoWamFNIum8+/nkAISQVGg==} @@ -1409,63 +1398,63 @@ packages: '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} - '@typescript-eslint/eslint-plugin@8.46.0': - resolution: {integrity: sha512-hA8gxBq4ukonVXPy0OKhiaUh/68D0E88GSmtC1iAEnGaieuDi38LhS7jdCHRLi6ErJBNDGCzvh5EnzdPwUc0DA==} + '@typescript-eslint/eslint-plugin@8.46.4': + resolution: {integrity: sha512-R48VhmTJqplNyDxCyqqVkFSZIx1qX6PzwqgcXn1olLrzxcSBDlOsbtcnQuQhNtnNiJ4Xe5gREI1foajYaYU2Vg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.46.0 + '@typescript-eslint/parser': ^8.46.4 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.46.0': - resolution: {integrity: sha512-n1H6IcDhmmUEG7TNVSspGmiHHutt7iVKtZwRppD7e04wha5MrkV1h3pti9xQLcCMt6YWsncpoT0HMjkH1FNwWQ==} + '@typescript-eslint/parser@8.46.4': + resolution: {integrity: sha512-tK3GPFWbirvNgsNKto+UmB/cRtn6TZfyw0D6IKrW55n6Vbs7KJoZtI//kpTKzE/DUmmnAFD8/Ca46s7Obs92/w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.46.0': - resolution: {integrity: sha512-OEhec0mH+U5Je2NZOeK1AbVCdm0ChyapAyTeXVIYTPXDJ3F07+cu87PPXcGoYqZ7M9YJVvFnfpGg1UmCIqM+QQ==} + '@typescript-eslint/project-service@8.46.4': + resolution: {integrity: sha512-nPiRSKuvtTN+no/2N1kt2tUh/HoFzeEgOm9fQ6XQk4/ApGqjx0zFIIaLJ6wooR1HIoozvj2j6vTi/1fgAz7UYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.46.0': - resolution: {integrity: sha512-lWETPa9XGcBes4jqAMYD9fW0j4n6hrPtTJwWDmtqgFO/4HF4jmdH/Q6wggTw5qIT5TXjKzbt7GsZUBnWoO3dqw==} + '@typescript-eslint/scope-manager@8.46.4': + resolution: {integrity: sha512-tMDbLGXb1wC+McN1M6QeDx7P7c0UWO5z9CXqp7J8E+xGcJuUuevWKxuG8j41FoweS3+L41SkyKKkia16jpX7CA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.46.0': - resolution: {integrity: sha512-WrYXKGAHY836/N7zoK/kzi6p8tXFhasHh8ocFL9VZSAkvH956gfeRfcnhs3xzRy8qQ/dq3q44v1jvQieMFg2cw==} + '@typescript-eslint/tsconfig-utils@8.46.4': + resolution: {integrity: sha512-+/XqaZPIAk6Cjg7NWgSGe27X4zMGqrFqZ8atJsX3CWxH/jACqWnrWI68h7nHQld0y+k9eTTjb9r+KU4twLoo9A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.46.0': - resolution: {integrity: sha512-hy+lvYV1lZpVs2jRaEYvgCblZxUoJiPyCemwbQZ+NGulWkQRy0HRPYAoef/CNSzaLt+MLvMptZsHXHlkEilaeg==} + '@typescript-eslint/type-utils@8.46.4': + resolution: {integrity: sha512-V4QC8h3fdT5Wro6vANk6eojqfbv5bpwHuMsBcJUJkqs2z5XnYhJzyz9Y02eUmF9u3PgXEUiOt4w4KHR3P+z0PQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.46.0': - resolution: {integrity: sha512-bHGGJyVjSE4dJJIO5yyEWt/cHyNwga/zXGJbJJ8TiO01aVREK6gCTu3L+5wrkb1FbDkQ+TKjMNe9R/QQQP9+rA==} + '@typescript-eslint/types@8.46.4': + resolution: {integrity: sha512-USjyxm3gQEePdUwJBFjjGNG18xY9A2grDVGuk7/9AkjIF1L+ZrVnwR5VAU5JXtUnBL/Nwt3H31KlRDaksnM7/w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.46.0': - resolution: {integrity: sha512-ekDCUfVpAKWJbRfm8T1YRrCot1KFxZn21oV76v5Fj4tr7ELyk84OS+ouvYdcDAwZL89WpEkEj2DKQ+qg//+ucg==} + '@typescript-eslint/typescript-estree@8.46.4': + resolution: {integrity: sha512-7oV2qEOr1d4NWNmpXLR35LvCfOkTNymY9oyW+lUHkmCno7aOmIf/hMaydnJBUTBMRCOGZh8YjkFOc8dadEoNGA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.46.0': - resolution: {integrity: sha512-nD6yGWPj1xiOm4Gk0k6hLSZz2XkNXhuYmyIrOWcHoPuAhjT9i5bAG+xbWPgFeNR8HPHHtpNKdYUXJl/D3x7f5g==} + '@typescript-eslint/utils@8.46.4': + resolution: {integrity: sha512-AbSv11fklGXV6T28dp2Me04Uw90R2iJ30g2bgLz529Koehrmkbs1r7paFqr1vPCZi7hHwYxYtxfyQMRC8QaVSg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.46.0': - resolution: {integrity: sha512-FrvMpAK+hTbFy7vH5j1+tMYHMSKLE6RzluFJlkFNKD0p9YsUT75JlBSmr5so3QRzvMwU5/bIEdeNrxm8du8l3Q==} + '@typescript-eslint/visitor-keys@8.46.4': + resolution: {integrity: sha512-/++5CYLQqsO9HFGLI7APrxBJYo+5OCMpViuhV8q5/Qa3o5mMrF//eQHks+PXcsAVaLdn817fMuS7zqoXNNZGaw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ungap/structured-clone@1.3.0': @@ -1505,34 +1494,34 @@ packages: '@vitest/utils@3.2.4': resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} - '@vue/compiler-core@3.5.22': - resolution: {integrity: sha512-jQ0pFPmZwTEiRNSb+i9Ow/I/cHv2tXYqsnHKKyCQ08irI2kdF5qmYedmF8si8mA7zepUFmJ2hqzS8CQmNOWOkQ==} + '@vue/compiler-core@3.5.13': + resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} - '@vue/compiler-dom@3.5.22': - resolution: {integrity: sha512-W8RknzUM1BLkypvdz10OVsGxnMAuSIZs9Wdx1vzA3mL5fNMN15rhrSCLiTm6blWeACwUwizzPVqGJgOGBEN/hA==} + '@vue/compiler-dom@3.5.13': + resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==} - '@vue/compiler-sfc@3.5.22': - resolution: {integrity: sha512-tbTR1zKGce4Lj+JLzFXDq36K4vcSZbJ1RBu8FxcDv1IGRz//Dh2EBqksyGVypz3kXpshIfWKGOCcqpSbyGWRJQ==} + '@vue/compiler-sfc@3.5.13': + resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==} - '@vue/compiler-ssr@3.5.22': - resolution: {integrity: sha512-GdgyLvg4R+7T8Nk2Mlighx7XGxq/fJf9jaVofc3IL0EPesTE86cP/8DD1lT3h1JeZr2ySBvyqKQJgbS54IX1Ww==} + '@vue/compiler-ssr@3.5.13': + resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==} - '@vue/reactivity@3.5.22': - resolution: {integrity: sha512-f2Wux4v/Z2pqc9+4SmgZC1p73Z53fyD90NFWXiX9AKVnVBEvLFOWCEgJD3GdGnlxPZt01PSlfmLqbLYzY/Fw4A==} + '@vue/reactivity@3.5.13': + resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==} - '@vue/runtime-core@3.5.22': - resolution: {integrity: sha512-EHo4W/eiYeAzRTN5PCextDUZ0dMs9I8mQ2Fy+OkzvRPUYQEyK9yAjbasrMCXbLNhF7P0OUyivLjIy0yc6VrLJQ==} + '@vue/runtime-core@3.5.13': + resolution: {integrity: sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==} - '@vue/runtime-dom@3.5.22': - resolution: {integrity: sha512-Av60jsryAkI023PlN7LsqrfPvwfxOd2yAwtReCjeuugTJTkgrksYJJstg1e12qle0NarkfhfFu1ox2D+cQotww==} + '@vue/runtime-dom@3.5.13': + resolution: {integrity: sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==} - '@vue/server-renderer@3.5.22': - resolution: {integrity: sha512-gXjo+ao0oHYTSswF+a3KRHZ1WszxIqO7u6XwNHqcqb9JfyIL/pbWrrh/xLv7jeDqla9u+LK7yfZKHih1e1RKAQ==} + '@vue/server-renderer@3.5.13': + resolution: {integrity: sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==} peerDependencies: - vue: 3.5.22 + vue: 3.5.13 - '@vue/shared@3.5.22': - resolution: {integrity: sha512-F4yc6palwq3TT0u+FYf0Ns4Tfl9GRFURDN2gWG7L1ecIaS/4fCIuFOjMTnCyjsu/OK6vaDKLCrGAa+KvvH+h4w==} + '@vue/shared@3.5.13': + resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} acorn-import-attributes@1.9.5: resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} @@ -1553,8 +1542,8 @@ packages: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} - agent-base@7.1.4: - resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + agent-base@7.1.3: + resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} engines: {node: '>= 14'} ai@2.2.37: @@ -1644,26 +1633,22 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - baseline-browser-mapping@2.8.16: - resolution: {integrity: sha512-OMu3BGQ4E7P1ErFsIPpbJh0qvDudM/UuJeHgkAvfWe+0HFJCXh+t/l8L6fVLR55RI/UbKrVLnAXZSVwd9ysWYw==} - hasBin: true - binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} - brace-expansion@1.1.12: - resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - brace-expansion@2.0.2: - resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.26.3: - resolution: {integrity: sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w==} + browserslist@4.24.4: + resolution: {integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -1687,15 +1672,15 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - caniuse-lite@1.0.30001750: - resolution: {integrity: sha512-cuom0g5sdX6rw00qOoLNSFCJ9/mYIsuSOA+yzpDw8eopiFqcVwQvZHqov0vmEighRxX++cfC0Vg1G+1Iy/mSpQ==} + caniuse-lite@1.0.30001707: + resolution: {integrity: sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==} ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} - chai@5.3.3: - resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} - engines: {node: '>=18'} + chai@5.2.0: + resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} + engines: {node: '>=12'} chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} @@ -1733,19 +1718,19 @@ packages: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} - color-convert@3.1.2: - resolution: {integrity: sha512-UNqkvCDXstVck3kdowtOTWROIJQwafjOfXSmddoDrXo4cewMKmusCeF22Q24zvjR8nwWib/3S/dfyzPItPEiJg==} + color-convert@3.1.0: + resolution: {integrity: sha512-TVoqAq8ZDIpK5lsQY874DDnu65CSsc9vzq0wLpNQ6UMBq81GSZocVazPiBbYGzngzBOIRahpkTzCLVe2at4MfA==} engines: {node: '>=14.6'} color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - color-name@2.0.2: - resolution: {integrity: sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==} + color-name@2.0.0: + resolution: {integrity: sha512-SbtvAMWvASO5TE2QP07jHBMXKafgdZz8Vrsrn96fiL+O92/FN/PLARzUW5sKt013fjAprK2d2iCn2hk2Xb5oow==} engines: {node: '>=12.20'} - color-string@2.1.2: - resolution: {integrity: sha512-RxmjYxbWemV9gKu4zPgiZagUxbH3RQpEIO77XoSSX0ivgABDZ+h8Zuash/EMFLTI4N9QgFPOJ6JQpPZKFxa+dA==} + color-string@2.0.1: + resolution: {integrity: sha512-5z9FbYTZPAo8iKsNEqRNv+OlpBbDcoE+SY9GjLfDUHEfcNNV7tS9eSAlFHEaub/r5tBL9LtskAeq1l9SaoZ5tQ==} engines: {node: '>=18'} color@5.0.2: @@ -1789,8 +1774,8 @@ packages: engines: {node: '>=4'} hasBin: true - cssstyle@4.6.0: - resolution: {integrity: sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==} + cssstyle@4.3.0: + resolution: {integrity: sha512-6r0NiY0xizYqfBvWp1G7WXJ06/bZyrk7Dc6PHql82C/pKGUTKu4yAX4Y8JPamb1ob9nBKuxWzCGTRuGwU3yxJQ==} engines: {node: '>=18'} csstype@3.1.3: @@ -1927,11 +1912,20 @@ packages: resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} engines: {node: '>=18'} - dayjs@1.11.18: - resolution: {integrity: sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==} + dayjs@1.11.19: + resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==} + + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true - debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + debug@4.4.1: + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -1939,8 +1933,8 @@ packages: supports-color: optional: true - decimal.js@10.6.0: - resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + decimal.js@10.5.0: + resolution: {integrity: sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==} deep-eql@5.0.2: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} @@ -1977,10 +1971,6 @@ packages: engines: {node: '>=0.10'} hasBin: true - detect-libc@2.1.2: - resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} - engines: {node: '>=8'} - devalue@5.3.2: resolution: {integrity: sha512-UDsjUbpQn9kvm68slnrs+mfxwFkIflOhkanmyabZ8zOYk8SMEIbJ3TK+88g70hSIeytu4y18f0z/hYHMTrXIWw==} @@ -1996,8 +1986,8 @@ packages: dom-accessibility-api@0.6.3: resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} - dotenv@16.6.1: - resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + dotenv@16.4.7: + resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} engines: {node: '>=12'} dunder-proto@1.0.1: @@ -2007,8 +1997,8 @@ packages: echarts@5.6.0: resolution: {integrity: sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA==} - electron-to-chromium@1.5.234: - resolution: {integrity: sha512-RXfEp2x+VRYn8jbKfQlRImzoJU01kyDvVPBmG39eU2iuRVhuS6vQNocB8J0/8GrIMLnPzgz4eW6WiRnJkTuNWg==} + electron-to-chromium@1.5.128: + resolution: {integrity: sha512-bo1A4HH/NS522Ws0QNFIzyPcyUUNV/yyy70Ho1xqfGYzPUme2F/xr4tlEOuM6/A538U1vDA7a4XfCd1CKRegKQ==} emoji-regex-xs@1.0.0: resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==} @@ -2017,10 +2007,6 @@ packages: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} - entities@6.0.1: - resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} - engines: {node: '>=0.12'} - es-define-property@1.0.1: resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} engines: {node: '>= 0.4'} @@ -2039,8 +2025,8 @@ packages: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} - esbuild@0.25.10: - resolution: {integrity: sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==} + esbuild@0.25.1: + resolution: {integrity: sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==} engines: {node: '>=18'} hasBin: true @@ -2058,8 +2044,8 @@ packages: peerDependencies: eslint: '>=7.0.0' - eslint-plugin-svelte@3.12.4: - resolution: {integrity: sha512-hD7wPe+vrPgx3U2X2b/wyTMtWobm660PygMGKrWWYTc9lvtY8DpNFDaU2CJQn1szLjGbn/aJ3g8WiXuKakrEkw==} + eslint-plugin-svelte@3.13.0: + resolution: {integrity: sha512-2ohCCQJJTNbIpQCSDSTWj+FN0OVfPmSO03lmSNT7ytqMaWF6kpT86LdzDqtm4sh7TVPl/OEWJ/d7R87bXP2Vjg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.1 || ^9.0.0 @@ -2080,8 +2066,8 @@ packages: resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.37.0: - resolution: {integrity: sha512-XyLmROnACWqSxiGYArdef1fItQd47weqB7iwtfr9JHwRrqIXZdcFMvvEcL9xHCmL0SNsOvF0c42lWyM1U5dgig==} + eslint@9.39.1: + resolution: {integrity: sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -2106,8 +2092,8 @@ packages: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} - esrap@2.1.0: - resolution: {integrity: sha512-yzmPNpl7TBbMRC5Lj2JlJZNPml0tzqoqP5B1JXycNUwtqma9AKCO0M2wHrdgsHcy1WRW7S9rJknAMtByg3usgA==} + esrap@2.1.2: + resolution: {integrity: sha512-DgvlIQeowRNyvLPWW4PT7Gu13WznY288Du086E751mwwbsgr29ytBiYeLzAGIo0qk3Ujob0SDk8TiSaM5WQzNg==} esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} @@ -2131,8 +2117,8 @@ packages: resolution: {integrity: sha512-9jgfSCa3dmEme2ES3mPByGXfgZ87VbP97tng1G2nWwWx6bV2nYxm2AWCrbQjXToSe+yYlqaZNtxffR9IeQr95g==} engines: {node: '>=14.18'} - eventsource-parser@3.0.6: - resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} + eventsource-parser@3.0.0: + resolution: {integrity: sha512-T1C0XCUimhxVQzW4zFipdx0SficT651NnkR0ZSH3yQwh+mFMdLfgjABVi4YtMTtaL4s168593DaoaRLMqryavA==} engines: {node: '>=18.0.0'} expect-type@1.2.2: @@ -2155,6 +2141,14 @@ packages: fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + fdir@6.4.6: + resolution: {integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -2186,8 +2180,8 @@ packages: flatted@3.3.3: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - focus-trap@7.6.5: - resolution: {integrity: sha512-7Ke1jyybbbPZyZXFxEftUtxFGLMpE2n6A+z//m4CRDlj0hW+o3iYSmh8nFlYMurOiJVDmJRilUQtJr08KfIxlg==} + focus-trap@7.6.4: + resolution: {integrity: sha512-xx560wGBk7seZ6y933idtjJQc1l+ck+pI3sKvhKozdBV1dRZoKhkW5xoCaFv9tQiX5RH1xfSxjuNu6g+lmN/gw==} for-each@0.3.5: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} @@ -2246,12 +2240,16 @@ packages: resolution: {integrity: sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==} engines: {node: '>=16 || 14 >=14.17'} + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} - globals@16.4.0: - resolution: {integrity: sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==} + globals@16.5.0: + resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==} engines: {node: '>=18'} globalyzer@0.1.0: @@ -2334,15 +2332,15 @@ packages: resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} engines: {node: '>= 4'} - immutable@5.1.3: - resolution: {integrity: sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==} + immutable@5.1.1: + resolution: {integrity: sha512-3jatXi9ObIsPGr3N5hGw/vWWcTkq6hUYhpQz4k0wLC+owqWi/LiugIw9x0EdNZ2yGedKN/HzePiBvaJRXa0Ujg==} import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} - import-in-the-middle@1.15.0: - resolution: {integrity: sha512-bpQy+CrsRmYmoPMAE/0G33iwRqwW4ouqdRg8jgbH3aKuCtOc8lxgmYXg2dMM92CRiGP660EtBcymH/eVUpCSaA==} + import-in-the-middle@1.13.1: + resolution: {integrity: sha512-k2V9wNm9B+ysuelDTHjI9d5KPc4l8zAZTGqj+pcynvWkypZd857ryzN8jNC7Pg2YZXNMJcHRPpaDyCBbNyVRpA==} imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} @@ -2452,10 +2450,6 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - jiti@2.6.1: - resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} - hasBin: true - js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -2511,76 +2505,6 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - lightningcss-android-arm64@1.30.2: - resolution: {integrity: sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [android] - - lightningcss-darwin-arm64@1.30.2: - resolution: {integrity: sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [darwin] - - lightningcss-darwin-x64@1.30.2: - resolution: {integrity: sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [darwin] - - lightningcss-freebsd-x64@1.30.2: - resolution: {integrity: sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [freebsd] - - lightningcss-linux-arm-gnueabihf@1.30.2: - resolution: {integrity: sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==} - engines: {node: '>= 12.0.0'} - cpu: [arm] - os: [linux] - - lightningcss-linux-arm64-gnu@1.30.2: - resolution: {integrity: sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - - lightningcss-linux-arm64-musl@1.30.2: - resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - - lightningcss-linux-x64-gnu@1.30.2: - resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - - lightningcss-linux-x64-musl@1.30.2: - resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - - lightningcss-win32-arm64-msvc@1.30.2: - resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [win32] - - lightningcss-win32-x64-msvc@1.30.2: - resolution: {integrity: sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [win32] - - lightningcss@1.30.2: - resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==} - engines: {node: '>= 12.0.0'} - lilconfig@2.1.0: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} engines: {node: '>=10'} @@ -2595,8 +2519,8 @@ packages: lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - loupe@3.2.1: - resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + loupe@3.1.4: + resolution: {integrity: sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg==} lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} @@ -2604,16 +2528,19 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - luxon@3.7.2: - resolution: {integrity: sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==} + luxon@3.6.0: + resolution: {integrity: sha512-WE7p0p7W1xji9qxkLYsvcIxZyfP48GuFrWIBQZIsbjCyf65dG1rv4n83HcOyEyhvzxJCrUoObCRNFgRNIQ5KNA==} engines: {node: '>=12'} lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true - magic-string@0.30.19: - resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} magic-string@0.30.7: resolution: {integrity: sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==} @@ -2685,8 +2612,8 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} - module-details-from-path@1.0.4: - resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==} + module-details-from-path@1.0.3: + resolution: {integrity: sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==} mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} @@ -2732,15 +2659,15 @@ packages: encoding: optional: true - node-releases@2.0.23: - resolution: {integrity: sha512-cCmFDMSm26S6tQSDpBCg/NR8NENrVPhAJSf+XbxBG4rPFaaonlEoE9wHQmun+cls499TQGSb7ZyPBRlzgKfpeg==} + node-releases@2.0.19: + resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} - nwsapi@2.2.22: - resolution: {integrity: sha512-ujSMe1OWVn55euT1ihwCI1ZcAaAU3nxUiDwfDQldc51ZXaB9m2AyOn6/jh1BLe2t/G8xd6uKG1UBF2aZJeg2SQ==} + nwsapi@2.2.20: + resolution: {integrity: sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==} object-inspect@1.13.4: resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} @@ -2777,8 +2704,8 @@ packages: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} - parse5@7.3.0: - resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + parse5@7.2.1: + resolution: {integrity: sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==} path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} @@ -2798,8 +2725,8 @@ packages: pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - pathval@2.0.1: - resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} engines: {node: '>= 14.16'} periscopic@3.1.0: @@ -2809,8 +2736,8 @@ packages: resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} engines: {node: '>=4.0.0'} - pg-protocol@1.10.3: - resolution: {integrity: sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==} + pg-protocol@1.8.0: + resolution: {integrity: sha512-jvuYlEkL03NRvOoyoRktBK7+qU5kOvlAwvmrH8sr3wbLrOdVWsRxQfz8mMy9sZFsqJ1hEWNfdWKI4SAmoL+j7g==} pg-types@2.2.0: resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} @@ -2823,6 +2750,10 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + picomatch@4.0.3: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} @@ -2831,13 +2762,13 @@ packages: resolution: {integrity: sha512-hMhneYm3GCPyQon88SZrVJx+LlqhM1kZFQbuAgXPoh/Az2YvO1B6bitT9qlhpiTdJlsT5lsr3gPmzoVjb5CDXA==} engines: {node: '>=10'} - playwright-core@1.56.0: - resolution: {integrity: sha512-1SXl7pMfemAMSDn5rkPeZljxOCYAmQnYLBTExuh6E8USHXGSX3dx6lYZN/xPpTz1vimXmPA9CDnILvmJaB8aSQ==} + playwright-core@1.56.1: + resolution: {integrity: sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==} engines: {node: '>=18'} hasBin: true - playwright@1.56.0: - resolution: {integrity: sha512-X5Q1b8lOdWIE4KAoHpW3SE8HvUB+ZZsUoN64ZhjnN8dOb1UpujxBtENGiZFE+9F/yhzJwYa+ca3u43FeLbboHA==} + playwright@1.56.1: + resolution: {integrity: sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw==} engines: {node: '>=18'} hasBin: true @@ -2968,6 +2899,9 @@ packages: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + regex-recursion@5.1.1: resolution: {integrity: sha512-ae7SBCbzVNrIjgSbh7wMznPcQel1DNlDtzensnFxpiNpXt1U2ju/bHugH422r+4LAVS1FpW1YCwilmnNsjum9w==} @@ -3006,8 +2940,8 @@ packages: robust-predicates@3.0.2: resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} - rollup@4.52.4: - resolution: {integrity: sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ==} + rollup@4.46.2: + resolution: {integrity: sha512-WMmLFI+Boh6xbop+OAGo9cQ3OgX9MIg7xOQjn+pTCwOkk+FNDAeAemXkJ3HzDJrVXleLOFVa1ipuc1AmEx1Dwg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -3031,8 +2965,8 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - sass@1.93.2: - resolution: {integrity: sha512-t+YPtOQHpGW1QWsh1CHQ5cPIr9lbbGZLZnbihP/D/qZj/yuV68m8qarcV17nvkOX81BCrvzAlq2klCQFZghyTg==} + sass@1.94.0: + resolution: {integrity: sha512-Dqh7SiYcaFtdv5Wvku6QgS5IGPm281L+ZtVD1U2FJa7Q0EFRlq8Z3sjYtz6gYObsYThUOz9ArwFqPZx+1azILQ==} engines: {node: '>=14.0.0'} hasBin: true @@ -3050,8 +2984,8 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.7.3: - resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} + semver@7.7.1: + resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} engines: {node: '>=10'} hasBin: true @@ -3109,12 +3043,12 @@ packages: siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - sirv@3.0.2: - resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} + sirv@3.0.1: + resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==} engines: {node: '>=18'} - solid-js@1.9.9: - resolution: {integrity: sha512-A0ZBPJQldAeGCTW0YRYJmt7RCeh5rbFfPZ2aOttgYnctHE7HgKeHCBB/PVc2P7eOfmNXqMFFFoYYdm3S4dcbkA==} + solid-js@1.9.5: + resolution: {integrity: sha512-ogI3DaFcyn6UhYhrgcyRAMbu/buBJitYQASZz5WzfQVPP10RD2AbCoRZ517psnezrasyCbWzIxZ6kVqet768xw==} solid-swr-store@0.10.7: resolution: {integrity: sha512-A6d68aJmRP471aWqKKPE2tpgOiR5fH4qXQNfKIec+Vap+MGQm3tvXlT8n0I8UgJSlNAsSAUuw2VTviH2h3Vv5g==} @@ -3167,8 +3101,8 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - strip-literal@3.1.0: - resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} + strip-literal@3.0.0: + resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==} style-value-types@5.1.2: resolution: {integrity: sha512-Vs9fNreYF9j6W2VvuDTP7kepALi7sk0xtk2Tu8Yxi9UoajJdEVpNpCov0HsLTqXvNGKX+Uv09pkozVITi1jf3Q==} @@ -3181,8 +3115,8 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - svelte-check@4.3.3: - resolution: {integrity: sha512-RYP0bEwenDXzfv0P1sKAwjZSlaRyqBn0Fz1TVni58lqyEiqgwztTpmodJrGzP6ZT2aHl4MbTvWP6gbmQ3FOnBg==} + svelte-check@4.3.4: + resolution: {integrity: sha512-DVWvxhBrDsd+0hHWKfjP99lsSXASeOhHJYyuKOFYJcP7ThfSCKgjVarE8XfuMWpS5JV3AlDf+iK1YGGo2TACdw==} engines: {node: '>= 18.0.0'} hasBin: true peerDependencies: @@ -3194,9 +3128,9 @@ packages: peerDependencies: svelte: ^4.0.0 - svelte-eslint-parser@1.3.3: - resolution: {integrity: sha512-oTrDR8Z7Wnguut7QH3YKh7JR19xv1seB/bz4dxU5J/86eJtZOU4eh0/jZq4dy6tAlz/KROxnkRQspv5ZEt7t+Q==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + svelte-eslint-parser@1.4.0: + resolution: {integrity: sha512-fjPzOfipR5S7gQ/JvI9r2H8y9gMGXO3JtmrylHLLyahEMquXI0lrebcjT+9/hNgDej0H7abTyox5HpHmW1PSWA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0, pnpm: 10.18.3} peerDependencies: svelte: ^3.37.0 || ^4.0.0 || ^5.0.0 peerDependenciesMeta: @@ -3259,12 +3193,12 @@ packages: peerDependencies: svelte: ^3.0.0 || ^4.0.0 || ^5.0.0-next.1 - svelte@4.2.20: - resolution: {integrity: sha512-eeEgGc2DtiUil5ANdtd8vPwt9AgaMdnuUFnPft9F5oMvU/FHu5IHFic+p1dR/UOB7XU2mX2yHW+NcTch4DCh5Q==} + svelte@4.2.19: + resolution: {integrity: sha512-IY1rnGr6izd10B0A8LqsBfmlT5OILVuZ7XsI0vdGPEvuonFV7NYEUK4dAkm9Zg2q0Um92kYjTpS1CAP3Nh/KWw==} engines: {node: '>=16'} - svelte@5.39.11: - resolution: {integrity: sha512-8MxWVm2+3YwrFbPaxOlT1bbMi6OTenrAgks6soZfiaS8Fptk4EVyRIFhJc3RpO264EeSNwgjWAdki0ufg4zkGw==} + svelte@5.43.6: + resolution: {integrity: sha512-RnyO9VXI85Bmsf4b8AuQFBKFYL3LKUl+ZrifOjvlrQoboAROj5IITVLK1yOXBjwUWUn2BI5cfmurktgCzuZ5QA==} engines: {node: '>=18'} swr-store@0.10.6: @@ -3305,6 +3239,10 @@ packages: tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + tinyglobby@0.2.14: + resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} + engines: {node: '>=12.0.0'} + tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} @@ -3317,21 +3255,21 @@ packages: resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} engines: {node: '>=14.0.0'} - tinyspy@4.0.4: - resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==} + tinyspy@4.0.3: + resolution: {integrity: sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==} engines: {node: '>=14.0.0'} tippy.js@6.3.7: resolution: {integrity: sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==} - tldts-core@6.1.86: - resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} + tldts-core@6.1.85: + resolution: {integrity: sha512-DTjUVvxckL1fIoPSb3KE7ISNtkWSawZdpfxGxwiIrZoO6EbHVDXXUIlIuWympPaeS+BLGyggozX/HTMsRAdsoA==} tldts-core@7.0.17: resolution: {integrity: sha512-DieYoGrP78PWKsrXr8MZwtQ7GLCUeLxihtjC1jZsW1DnvSMdKPitJSe8OSYDM2u5H6g3kWJZpePqkp43TfLh0g==} - tldts@6.1.86: - resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} + tldts@6.1.85: + resolution: {integrity: sha512-gBdZ1RjCSevRPFix/hpaUWeak2/RNUZB4/8frF1r5uYMHjFptkiT0JXIebWvgI/0ZHXvxaUDDJshiA0j6GdL3w==} hasBin: true tldts@7.0.17: @@ -3353,8 +3291,8 @@ packages: tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - tr46@5.1.1: - resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==} + tr46@5.1.0: + resolution: {integrity: sha512-IUWnUK7ADYR5Sl1fZlO1INDUhVhatWl7BtJWsIhwJ0UAK7ilzzIa8uIqOO/aYVWHZPJkKbEL+362wrzoeRF7bw==} engines: {node: '>=18'} trim-lines@3.0.1: @@ -3382,8 +3320,8 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - typescript-eslint@8.46.0: - resolution: {integrity: sha512-6+ZrB6y2bT2DX3K+Qd9vn7OFOJR+xSLDj+Aw/N3zBwUt27uTw2sw2TE2+UcY1RiyBZkaGbTkVg9SSdPNUG6aUw==} + typescript-eslint@8.46.4: + resolution: {integrity: sha512-KALyxkpYV5Ix7UhvjTwJXZv76VWsHG+NjNlt/z+a17SOQSiOcBdUXdbJdyXi7RPxrBFECtFOiPwUJQusJuCqrg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -3394,11 +3332,11 @@ packages: engines: {node: '>=14.17'} hasBin: true - undici-types@7.14.0: - resolution: {integrity: sha512-QQiYxHuyZ9gQUIrmPo3IA+hUl4KYk8uSA7cHrcKd/l3p1OTpZcM0Tbp9x7FAtXdAYhlasd60ncPpgu6ihG6TOA==} + undici-types@6.20.0: + resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} - unist-util-is@6.0.1: - resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + unist-util-is@6.0.0: + resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} unist-util-position@5.0.0: resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} @@ -3406,8 +3344,8 @@ packages: unist-util-stringify-position@4.0.0: resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} - unist-util-visit-parents@6.0.2: - resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + unist-util-visit-parents@6.0.1: + resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} unist-util-visit@5.0.0: resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} @@ -3424,8 +3362,8 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - use-sync-external-store@1.6.0: - resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + use-sync-external-store@1.5.0: + resolution: {integrity: sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -3443,8 +3381,8 @@ packages: engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true - vite@7.1.9: - resolution: {integrity: sha512-4nVGliEpxmhCL8DslSAUdxlB6+SMrhB0a1v5ijlh1xB1nEPuy1mxaHxysVucLHuWryAxLWg6a5ei+U4TLn/rFg==} + vite@7.2.2: + resolution: {integrity: sha512-BxAKBWmIbrDgrokdGZH1IgkIk/5mMHDreLDmCJ0qpyJaAteP8NvMhkwr/ZCQNqNH97bw/dANTE9PDzqwJghfMQ==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -3483,10 +3421,10 @@ packages: yaml: optional: true - vitefu@1.1.1: - resolution: {integrity: sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==} + vitefu@1.0.6: + resolution: {integrity: sha512-+Rex1GlappUyNN6UfwbVZne/9cYC4+R2XDk9xkNXBKMw6HQagdX9PgZ8V2v1WUSK1wfBLp7qbI1+XSNIlB1xmA==} peerDependencies: - vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0 + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 peerDependenciesMeta: vite: optional: true @@ -3519,8 +3457,8 @@ packages: jsdom: optional: true - vue@3.5.22: - resolution: {integrity: sha512-toaZjQ3a/G/mYaLSbV+QsQhIdMo9x5rrqIpYRObsJ6T/J+RyCSFwN2LHNVH9v8uIcljDNa3QzPVdv3Y6b9hAJQ==} + vue@3.5.13: + resolution: {integrity: sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==} peerDependencies: typescript: '*' peerDependenciesMeta: @@ -3538,8 +3476,8 @@ packages: resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} engines: {node: '>=12'} - webpack-sources@3.3.3: - resolution: {integrity: sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==} + webpack-sources@3.2.3: + resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} engines: {node: '>=10.13.0'} webpack-virtual-modules@0.5.0: @@ -3586,8 +3524,8 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} - ws@8.18.3: - resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} + ws@8.18.1: + resolution: {integrity: sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -3620,16 +3558,16 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - zimmerframe@1.1.4: - resolution: {integrity: sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==} + zimmerframe@1.1.2: + resolution: {integrity: sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==} - zod-to-json-schema@3.24.6: - resolution: {integrity: sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==} + zod-to-json-schema@3.24.5: + resolution: {integrity: sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==} peerDependencies: zod: ^3.24.1 - zod@4.1.12: - resolution: {integrity: sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==} + zod@3.24.3: + resolution: {integrity: sha512-HhY1oqzWCQWuUqvBFnsyrtZRhyPeR7SUGv+C4+MsisMuVfSPx8HpwWqH8tRahSlt6M3PiFAcoeFhZAqIXTxoSg==} zrender@5.6.1: resolution: {integrity: sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag==} @@ -3639,42 +3577,42 @@ packages: snapshots: - '@adobe/css-tools@4.4.4': {} + '@adobe/css-tools@4.4.2': {} - '@ai-sdk/provider-utils@2.1.13(zod@4.1.12)': + '@ai-sdk/provider-utils@2.1.13(zod@3.24.3)': dependencies: '@ai-sdk/provider': 1.0.11 - eventsource-parser: 3.0.6 + eventsource-parser: 3.0.0 nanoid: 3.3.11 secure-json-parse: 2.7.0 optionalDependencies: - zod: 4.1.12 + zod: 3.24.3 '@ai-sdk/provider@1.0.11': dependencies: json-schema: 0.4.0 - '@ai-sdk/svelte@1.1.24(svelte@5.39.11)(zod@4.1.12)': + '@ai-sdk/svelte@1.1.24(svelte@5.43.6)(zod@3.24.3)': dependencies: - '@ai-sdk/provider-utils': 2.1.13(zod@4.1.12) - '@ai-sdk/ui-utils': 1.1.19(zod@4.1.12) + '@ai-sdk/provider-utils': 2.1.13(zod@3.24.3) + '@ai-sdk/ui-utils': 1.1.19(zod@3.24.3) optionalDependencies: - svelte: 5.39.11 + svelte: 5.43.6 transitivePeerDependencies: - zod - '@ai-sdk/ui-utils@1.1.19(zod@4.1.12)': + '@ai-sdk/ui-utils@1.1.19(zod@3.24.3)': dependencies: '@ai-sdk/provider': 1.0.11 - '@ai-sdk/provider-utils': 2.1.13(zod@4.1.12) - zod-to-json-schema: 3.24.6(zod@4.1.12) + '@ai-sdk/provider-utils': 2.1.13(zod@3.24.3) + zod-to-json-schema: 3.24.5(zod@3.24.3) optionalDependencies: - zod: 4.1.12 + zod: 3.24.3 '@ampproject/remapping@2.3.0': dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 '@analytics/cookie-utils@0.2.14': dependencies: @@ -3712,13 +3650,13 @@ snapshots: '@appwrite.io/console@https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@2752': {} - '@appwrite.io/pink-icons-svelte@2.0.0-RC.1(svelte@5.39.11)': + '@appwrite.io/pink-icons-svelte@2.0.0-RC.1(svelte@5.43.6)': dependencies: - svelte: 5.39.11 + svelte: 5.43.6 - '@appwrite.io/pink-icons-svelte@https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@8f82877(svelte@5.39.11)': + '@appwrite.io/pink-icons-svelte@https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@4472521(svelte@5.43.6)': dependencies: - svelte: 5.39.11 + svelte: 5.43.6 '@appwrite.io/pink-icons@0.25.0': {} @@ -3729,263 +3667,260 @@ snapshots: '@appwrite.io/pink-icons': 1.0.0 the-new-css-reset: 1.11.3 - '@appwrite.io/pink-svelte@https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@8f82877(svelte@5.39.11)': + '@appwrite.io/pink-svelte@https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@4472521(svelte@5.43.6)': dependencies: - '@appwrite.io/pink-icons-svelte': 2.0.0-RC.1(svelte@5.39.11) - '@floating-ui/dom': 1.7.4 - '@melt-ui/pp': 0.3.2(@melt-ui/svelte@0.86.6(svelte@5.39.11))(svelte@5.39.11) - '@melt-ui/svelte': 0.86.6(svelte@5.39.11) - '@tanstack/svelte-virtual': 3.13.12(svelte@5.39.11) + '@appwrite.io/pink-icons-svelte': 2.0.0-RC.1(svelte@5.43.6) + '@floating-ui/dom': 1.6.13 + '@melt-ui/pp': 0.3.2(@melt-ui/svelte@0.86.6(svelte@5.43.6))(svelte@5.43.6) + '@melt-ui/svelte': 0.86.6(svelte@5.43.6) + '@tanstack/svelte-virtual': 3.13.12(svelte@5.43.6) ansicolor: 2.0.3 d3: 7.9.0 fuse.js: 7.1.0 pretty-bytes: 6.1.1 shiki: 1.29.2 - svelte: 5.39.11 - svelte-motion: 0.12.2(svelte@5.39.11) - svelte-sonner: 0.3.28(svelte@5.39.11) + svelte: 5.43.6 + svelte-motion: 0.12.2(svelte@5.43.6) + svelte-sonner: 0.3.28(svelte@5.43.6) - '@asamuzakjp/css-color@3.2.0': + '@asamuzakjp/css-color@3.1.1': dependencies: - '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) - '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) - '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) - '@csstools/css-tokenizer': 3.0.4 + '@csstools/css-calc': 2.1.2(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-color-parser': 3.0.8(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 lru-cache: 10.4.3 - '@babel/code-frame@7.27.1': + '@babel/code-frame@7.26.2': dependencies: - '@babel/helper-validator-identifier': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.28.4': {} + '@babel/compat-data@7.26.8': {} - '@babel/core@7.28.4': + '@babel/core@7.26.10': dependencies: - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.3 - '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) - '@babel/helpers': 7.28.4 - '@babel/parser': 7.28.4 - '@babel/template': 7.27.2 - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 - '@jridgewell/remapping': 2.3.5 + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.27.0 + '@babel/helper-compilation-targets': 7.27.0 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.10) + '@babel/helpers': 7.27.0 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.0 + '@babel/traverse': 7.27.0 + '@babel/types': 7.28.5 convert-source-map: 2.0.0 - debug: 4.4.3 + debug: 4.4.1 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/generator@7.28.3': + '@babel/generator@7.27.0': dependencies: - '@babel/parser': 7.28.4 - '@babel/types': 7.28.4 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 jsesc: 3.1.0 - '@babel/helper-compilation-targets@7.27.2': + '@babel/helper-compilation-targets@7.27.0': dependencies: - '@babel/compat-data': 7.28.4 - '@babel/helper-validator-option': 7.27.1 - browserslist: 4.26.3 + '@babel/compat-data': 7.26.8 + '@babel/helper-validator-option': 7.25.9 + browserslist: 4.24.4 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-globals@7.28.0': {} - - '@babel/helper-module-imports@7.27.1': + '@babel/helper-module-imports@7.25.9': dependencies: - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 + '@babel/traverse': 7.27.0 + '@babel/types': 7.28.5 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.4)': + '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.10)': dependencies: - '@babel/core': 7.28.4 - '@babel/helper-module-imports': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.28.4 + '@babel/core': 7.26.10 + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.27.0 transitivePeerDependencies: - supports-color '@babel/helper-string-parser@7.27.1': {} - '@babel/helper-validator-identifier@7.27.1': {} + '@babel/helper-validator-identifier@7.28.5': {} - '@babel/helper-validator-option@7.27.1': {} + '@babel/helper-validator-option@7.25.9': {} - '@babel/helpers@7.28.4': + '@babel/helpers@7.27.0': dependencies: - '@babel/template': 7.27.2 - '@babel/types': 7.28.4 + '@babel/template': 7.27.0 + '@babel/types': 7.28.5 - '@babel/parser@7.28.4': + '@babel/parser@7.28.5': dependencies: - '@babel/types': 7.28.4 + '@babel/types': 7.28.5 - '@babel/runtime@7.28.4': {} + '@babel/runtime@7.27.0': + dependencies: + regenerator-runtime: 0.14.1 - '@babel/template@7.27.2': + '@babel/template@7.27.0': dependencies: - '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.4 - '@babel/types': 7.28.4 + '@babel/code-frame': 7.26.2 + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 - '@babel/traverse@7.28.4': + '@babel/traverse@7.27.0': dependencies: - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.3 - '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.4 - '@babel/template': 7.27.2 - '@babel/types': 7.28.4 - debug: 4.4.3 + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.27.0 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.0 + '@babel/types': 7.28.5 + debug: 4.4.1 + globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/types@7.28.4': + '@babel/types@7.28.5': dependencies: '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 - '@csstools/color-helpers@5.1.0': {} + '@csstools/color-helpers@5.0.2': {} - '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + '@csstools/css-calc@2.1.2(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)': dependencies: - '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) - '@csstools/css-tokenizer': 3.0.4 + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 - '@csstools/css-color-parser@3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + '@csstools/css-color-parser@3.0.8(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)': dependencies: - '@csstools/color-helpers': 5.1.0 - '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) - '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) - '@csstools/css-tokenizer': 3.0.4 + '@csstools/color-helpers': 5.0.2 + '@csstools/css-calc': 2.1.2(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 - '@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4)': + '@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3)': dependencies: - '@csstools/css-tokenizer': 3.0.4 - - '@csstools/css-tokenizer@3.0.4': {} + '@csstools/css-tokenizer': 3.0.3 - '@esbuild/aix-ppc64@0.25.10': - optional: true + '@csstools/css-tokenizer@3.0.3': {} - '@esbuild/android-arm64@0.25.10': + '@esbuild/aix-ppc64@0.25.1': optional: true - '@esbuild/android-arm@0.25.10': + '@esbuild/android-arm64@0.25.1': optional: true - '@esbuild/android-x64@0.25.10': + '@esbuild/android-arm@0.25.1': optional: true - '@esbuild/darwin-arm64@0.25.10': + '@esbuild/android-x64@0.25.1': optional: true - '@esbuild/darwin-x64@0.25.10': + '@esbuild/darwin-arm64@0.25.1': optional: true - '@esbuild/freebsd-arm64@0.25.10': + '@esbuild/darwin-x64@0.25.1': optional: true - '@esbuild/freebsd-x64@0.25.10': + '@esbuild/freebsd-arm64@0.25.1': optional: true - '@esbuild/linux-arm64@0.25.10': + '@esbuild/freebsd-x64@0.25.1': optional: true - '@esbuild/linux-arm@0.25.10': + '@esbuild/linux-arm64@0.25.1': optional: true - '@esbuild/linux-ia32@0.25.10': + '@esbuild/linux-arm@0.25.1': optional: true - '@esbuild/linux-loong64@0.25.10': + '@esbuild/linux-ia32@0.25.1': optional: true - '@esbuild/linux-mips64el@0.25.10': + '@esbuild/linux-loong64@0.25.1': optional: true - '@esbuild/linux-ppc64@0.25.10': + '@esbuild/linux-mips64el@0.25.1': optional: true - '@esbuild/linux-riscv64@0.25.10': + '@esbuild/linux-ppc64@0.25.1': optional: true - '@esbuild/linux-s390x@0.25.10': + '@esbuild/linux-riscv64@0.25.1': optional: true - '@esbuild/linux-x64@0.25.10': + '@esbuild/linux-s390x@0.25.1': optional: true - '@esbuild/netbsd-arm64@0.25.10': + '@esbuild/linux-x64@0.25.1': optional: true - '@esbuild/netbsd-x64@0.25.10': + '@esbuild/netbsd-arm64@0.25.1': optional: true - '@esbuild/openbsd-arm64@0.25.10': + '@esbuild/netbsd-x64@0.25.1': optional: true - '@esbuild/openbsd-x64@0.25.10': + '@esbuild/openbsd-arm64@0.25.1': optional: true - '@esbuild/openharmony-arm64@0.25.10': + '@esbuild/openbsd-x64@0.25.1': optional: true - '@esbuild/sunos-x64@0.25.10': + '@esbuild/sunos-x64@0.25.1': optional: true - '@esbuild/win32-arm64@0.25.10': + '@esbuild/win32-arm64@0.25.1': optional: true - '@esbuild/win32-ia32@0.25.10': + '@esbuild/win32-ia32@0.25.1': optional: true - '@esbuild/win32-x64@0.25.10': + '@esbuild/win32-x64@0.25.1': optional: true - '@eslint-community/eslint-utils@4.9.0(eslint@9.37.0(jiti@2.6.1))': + '@eslint-community/eslint-utils@4.9.0(eslint@9.39.1)': dependencies: - eslint: 9.37.0(jiti@2.6.1) + eslint: 9.39.1 eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} - '@eslint/compat@1.4.0(eslint@9.37.0(jiti@2.6.1))': + '@eslint/compat@1.4.1(eslint@9.39.1)': dependencies: - '@eslint/core': 0.16.0 + '@eslint/core': 0.17.0 optionalDependencies: - eslint: 9.37.0(jiti@2.6.1) + eslint: 9.39.1 - '@eslint/config-array@0.21.0': + '@eslint/config-array@0.21.1': dependencies: - '@eslint/object-schema': 2.1.6 - debug: 4.4.3 + '@eslint/object-schema': 2.1.7 + debug: 4.4.1 minimatch: 3.1.2 transitivePeerDependencies: - supports-color - '@eslint/config-helpers@0.4.0': + '@eslint/config-helpers@0.4.2': dependencies: - '@eslint/core': 0.16.0 + '@eslint/core': 0.17.0 - '@eslint/core@0.16.0': + '@eslint/core@0.17.0': dependencies: '@types/json-schema': 7.0.15 '@eslint/eslintrc@3.3.1': dependencies: ajv: 6.12.6 - debug: 4.4.3 + debug: 4.4.1 espree: 10.4.0 globals: 14.0.0 ignore: 5.3.2 @@ -3996,83 +3931,90 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@9.37.0': {} + '@eslint/js@9.39.1': {} - '@eslint/object-schema@2.1.6': {} + '@eslint/object-schema@2.1.7': {} - '@eslint/plugin-kit@0.4.0': + '@eslint/plugin-kit@0.4.1': dependencies: - '@eslint/core': 0.16.0 + '@eslint/core': 0.17.0 levn: 0.4.1 '@faker-js/faker@9.9.0': {} - '@floating-ui/core@1.7.3': + '@floating-ui/core@1.6.9': dependencies: - '@floating-ui/utils': 0.2.10 + '@floating-ui/utils': 0.2.9 - '@floating-ui/dom@1.7.4': + '@floating-ui/dom@1.6.13': dependencies: - '@floating-ui/core': 1.7.3 - '@floating-ui/utils': 0.2.10 + '@floating-ui/core': 1.6.9 + '@floating-ui/utils': 0.2.9 - '@floating-ui/utils@0.2.10': {} + '@floating-ui/utils@0.2.9': {} '@humanfs/core@0.19.1': {} - '@humanfs/node@0.16.7': + '@humanfs/node@0.16.6': dependencies: '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.4.3 + '@humanwhocodes/retry': 0.3.1 '@humanwhocodes/module-importer@1.0.1': {} - '@humanwhocodes/retry@0.4.3': {} + '@humanwhocodes/retry@0.3.1': {} + + '@humanwhocodes/retry@0.4.2': {} '@imagine.dev/web-components@0.0.34(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: react: 19.2.0 react-dom: 19.2.0(react@19.2.0) - '@internationalized/date@3.10.0': + '@internationalized/date@3.7.0': dependencies: - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.15 - '@jridgewell/gen-mapping@0.3.13': + '@jridgewell/gen-mapping@0.3.8': dependencies: + '@jridgewell/set-array': 1.2.1 '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/trace-mapping': 0.3.25 '@jridgewell/remapping@2.3.5': dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 '@jridgewell/resolve-uri@3.1.2': {} + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + '@jridgewell/sourcemap-codec@1.5.5': {} - '@jridgewell/trace-mapping@0.3.31': + '@jridgewell/trace-mapping@0.3.25': dependencies: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@melt-ui/pp@0.3.2(@melt-ui/svelte@0.86.6(svelte@5.39.11))(svelte@5.39.11)': + '@melt-ui/pp@0.3.2(@melt-ui/svelte@0.86.6(svelte@5.43.6))(svelte@5.43.6)': dependencies: - '@melt-ui/svelte': 0.86.6(svelte@5.39.11) + '@melt-ui/svelte': 0.86.6(svelte@5.43.6) estree-walker: 3.0.3 - magic-string: 0.30.19 - svelte: 5.39.11 + magic-string: 0.30.17 + svelte: 5.43.6 - '@melt-ui/svelte@0.86.6(svelte@5.39.11)': + '@melt-ui/svelte@0.86.6(svelte@5.43.6)': dependencies: - '@floating-ui/core': 1.7.3 - '@floating-ui/dom': 1.7.4 - '@internationalized/date': 3.10.0 + '@floating-ui/core': 1.6.9 + '@floating-ui/dom': 1.6.13 + '@internationalized/date': 3.7.0 dequal: 2.0.3 - focus-trap: 7.6.5 + focus-trap: 7.6.4 nanoid: 5.1.6 - svelte: 5.39.11 + svelte: 5.43.6 '@nodelib/fs.scandir@2.1.5': dependencies: @@ -4114,7 +4056,7 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/semantic-conventions': 1.30.0 transitivePeerDependencies: - supports-color @@ -4123,7 +4065,7 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/semantic-conventions': 1.30.0 '@types/connect': 3.4.36 transitivePeerDependencies: - supports-color @@ -4140,7 +4082,7 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/semantic-conventions': 1.30.0 transitivePeerDependencies: - supports-color @@ -4149,7 +4091,7 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/semantic-conventions': 1.30.0 transitivePeerDependencies: - supports-color @@ -4180,7 +4122,7 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/semantic-conventions': 1.30.0 transitivePeerDependencies: - supports-color @@ -4191,7 +4133,7 @@ snapshots: '@opentelemetry/instrumentation': 0.57.1(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': 1.28.0 forwarded-parse: 2.1.2 - semver: 7.7.3 + semver: 7.7.1 transitivePeerDependencies: - supports-color @@ -4200,7 +4142,7 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) '@opentelemetry/redis-common': 0.36.2 - '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/semantic-conventions': 1.30.0 transitivePeerDependencies: - supports-color @@ -4208,7 +4150,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/semantic-conventions': 1.30.0 transitivePeerDependencies: - supports-color @@ -4216,7 +4158,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/semantic-conventions': 1.30.0 transitivePeerDependencies: - supports-color @@ -4225,7 +4167,7 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/semantic-conventions': 1.30.0 transitivePeerDependencies: - supports-color @@ -4240,7 +4182,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/semantic-conventions': 1.30.0 transitivePeerDependencies: - supports-color @@ -4249,7 +4191,7 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/semantic-conventions': 1.30.0 transitivePeerDependencies: - supports-color @@ -4257,7 +4199,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/semantic-conventions': 1.30.0 '@opentelemetry/sql-common': 0.40.1(@opentelemetry/api@1.9.0) transitivePeerDependencies: - supports-color @@ -4266,7 +4208,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/semantic-conventions': 1.30.0 '@types/mysql': 2.15.26 transitivePeerDependencies: - supports-color @@ -4275,7 +4217,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/semantic-conventions': 1.30.0 transitivePeerDependencies: - supports-color @@ -4296,7 +4238,7 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) '@opentelemetry/redis-common': 0.36.2 - '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/semantic-conventions': 1.30.0 transitivePeerDependencies: - supports-color @@ -4304,7 +4246,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/semantic-conventions': 1.30.0 '@types/tedious': 4.0.14 transitivePeerDependencies: - supports-color @@ -4322,9 +4264,9 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/api-logs': 0.53.0 '@types/shimmer': 1.2.0 - import-in-the-middle: 1.15.0 + import-in-the-middle: 1.13.1 require-in-the-middle: 7.5.2 - semver: 7.7.3 + semver: 7.7.1 shimmer: 1.2.1 transitivePeerDependencies: - supports-color @@ -4334,9 +4276,9 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/api-logs': 0.57.1 '@types/shimmer': 1.2.0 - import-in-the-middle: 1.15.0 + import-in-the-middle: 1.13.1 require-in-the-middle: 7.5.2 - semver: 7.7.3 + semver: 7.7.1 shimmer: 1.2.1 transitivePeerDependencies: - supports-color @@ -4346,9 +4288,9 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/api-logs': 0.57.2 '@types/shimmer': 1.2.0 - import-in-the-middle: 1.15.0 + import-in-the-middle: 1.13.1 require-in-the-middle: 7.5.2 - semver: 7.7.3 + semver: 7.7.1 shimmer: 1.2.1 transitivePeerDependencies: - supports-color @@ -4372,7 +4314,7 @@ snapshots: '@opentelemetry/semantic-conventions@1.28.0': {} - '@opentelemetry/semantic-conventions@1.37.0': {} + '@opentelemetry/semantic-conventions@1.30.0': {} '@opentelemetry/sql-common@0.40.1(@opentelemetry/api@1.9.0)': dependencies: @@ -4440,11 +4382,11 @@ snapshots: '@parcel/watcher-win32-x64': 2.5.1 optional: true - '@playwright/test@1.56.0': + '@playwright/test@1.56.1': dependencies: - playwright: 1.56.0 + playwright: 1.56.1 - '@polka/url@1.0.0-next.29': {} + '@polka/url@1.0.0-next.28': {} '@popperjs/core@2.11.8': {} @@ -4456,70 +4398,64 @@ snapshots: transitivePeerDependencies: - supports-color - '@rollup/rollup-android-arm-eabi@4.52.4': - optional: true - - '@rollup/rollup-android-arm64@4.52.4': - optional: true - - '@rollup/rollup-darwin-arm64@4.52.4': + '@rollup/rollup-android-arm-eabi@4.46.2': optional: true - '@rollup/rollup-darwin-x64@4.52.4': + '@rollup/rollup-android-arm64@4.46.2': optional: true - '@rollup/rollup-freebsd-arm64@4.52.4': + '@rollup/rollup-darwin-arm64@4.46.2': optional: true - '@rollup/rollup-freebsd-x64@4.52.4': + '@rollup/rollup-darwin-x64@4.46.2': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.52.4': + '@rollup/rollup-freebsd-arm64@4.46.2': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.52.4': + '@rollup/rollup-freebsd-x64@4.46.2': optional: true - '@rollup/rollup-linux-arm64-gnu@4.52.4': + '@rollup/rollup-linux-arm-gnueabihf@4.46.2': optional: true - '@rollup/rollup-linux-arm64-musl@4.52.4': + '@rollup/rollup-linux-arm-musleabihf@4.46.2': optional: true - '@rollup/rollup-linux-loong64-gnu@4.52.4': + '@rollup/rollup-linux-arm64-gnu@4.46.2': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.52.4': + '@rollup/rollup-linux-arm64-musl@4.46.2': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.52.4': + '@rollup/rollup-linux-loongarch64-gnu@4.46.2': optional: true - '@rollup/rollup-linux-riscv64-musl@4.52.4': + '@rollup/rollup-linux-ppc64-gnu@4.46.2': optional: true - '@rollup/rollup-linux-s390x-gnu@4.52.4': + '@rollup/rollup-linux-riscv64-gnu@4.46.2': optional: true - '@rollup/rollup-linux-x64-gnu@4.52.4': + '@rollup/rollup-linux-riscv64-musl@4.46.2': optional: true - '@rollup/rollup-linux-x64-musl@4.52.4': + '@rollup/rollup-linux-s390x-gnu@4.46.2': optional: true - '@rollup/rollup-openharmony-arm64@4.52.4': + '@rollup/rollup-linux-x64-gnu@4.46.2': optional: true - '@rollup/rollup-win32-arm64-msvc@4.52.4': + '@rollup/rollup-linux-x64-musl@4.46.2': optional: true - '@rollup/rollup-win32-ia32-msvc@4.52.4': + '@rollup/rollup-win32-arm64-msvc@4.46.2': optional: true - '@rollup/rollup-win32-x64-gnu@4.52.4': + '@rollup/rollup-win32-ia32-msvc@4.46.2': optional: true - '@rollup/rollup-win32-x64-msvc@4.52.4': + '@rollup/rollup-win32-x64-msvc@4.46.2': optional: true '@sentry-internal/browser-utils@8.55.0': @@ -4552,10 +4488,10 @@ snapshots: '@sentry/bundler-plugin-core@2.22.6': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.26.10 '@sentry/babel-plugin-component-annotate': 2.22.6 - '@sentry/cli': 2.56.1 - dotenv: 16.6.1 + '@sentry/cli': 2.43.0 + dotenv: 16.4.7 find-up: 5.0.0 glob: 9.3.5 magic-string: 0.30.8 @@ -4564,31 +4500,31 @@ snapshots: - encoding - supports-color - '@sentry/cli-darwin@2.56.1': + '@sentry/cli-darwin@2.43.0': optional: true - '@sentry/cli-linux-arm64@2.56.1': + '@sentry/cli-linux-arm64@2.43.0': optional: true - '@sentry/cli-linux-arm@2.56.1': + '@sentry/cli-linux-arm@2.43.0': optional: true - '@sentry/cli-linux-i686@2.56.1': + '@sentry/cli-linux-i686@2.43.0': optional: true - '@sentry/cli-linux-x64@2.56.1': + '@sentry/cli-linux-x64@2.43.0': optional: true - '@sentry/cli-win32-arm64@2.56.1': + '@sentry/cli-win32-arm64@2.43.0': optional: true - '@sentry/cli-win32-i686@2.56.1': + '@sentry/cli-win32-i686@2.43.0': optional: true - '@sentry/cli-win32-x64@2.56.1': + '@sentry/cli-win32-x64@2.43.0': optional: true - '@sentry/cli@2.56.1': + '@sentry/cli@2.43.0': dependencies: https-proxy-agent: 5.0.1 node-fetch: 2.7.0 @@ -4596,14 +4532,14 @@ snapshots: proxy-from-env: 1.1.0 which: 2.0.2 optionalDependencies: - '@sentry/cli-darwin': 2.56.1 - '@sentry/cli-linux-arm': 2.56.1 - '@sentry/cli-linux-arm64': 2.56.1 - '@sentry/cli-linux-i686': 2.56.1 - '@sentry/cli-linux-x64': 2.56.1 - '@sentry/cli-win32-arm64': 2.56.1 - '@sentry/cli-win32-i686': 2.56.1 - '@sentry/cli-win32-x64': 2.56.1 + '@sentry/cli-darwin': 2.43.0 + '@sentry/cli-linux-arm': 2.43.0 + '@sentry/cli-linux-arm64': 2.43.0 + '@sentry/cli-linux-i686': 2.43.0 + '@sentry/cli-linux-x64': 2.43.0 + '@sentry/cli-win32-arm64': 2.43.0 + '@sentry/cli-win32-i686': 2.43.0 + '@sentry/cli-win32-x64': 2.43.0 transitivePeerDependencies: - encoding - supports-color @@ -4642,44 +4578,44 @@ snapshots: '@opentelemetry/instrumentation-undici': 0.10.0(@opentelemetry/api@1.9.0) '@opentelemetry/resources': 1.30.1(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-base': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/semantic-conventions': 1.30.0 '@prisma/instrumentation': 5.22.0 '@sentry/core': 8.55.0 - '@sentry/opentelemetry': 8.55.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.37.0) - import-in-the-middle: 1.15.0 + '@sentry/opentelemetry': 8.55.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.30.0) + import-in-the-middle: 1.13.1 transitivePeerDependencies: - supports-color - '@sentry/opentelemetry@8.55.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.37.0)': + '@sentry/opentelemetry@8.55.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.30.0)': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/context-async-hooks': 1.30.1(@opentelemetry/api@1.9.0) '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-base': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/semantic-conventions': 1.30.0 '@sentry/core': 8.55.0 - '@sentry/svelte@8.55.0(svelte@5.39.11)': + '@sentry/svelte@8.55.0(svelte@5.43.6)': dependencies: '@sentry/browser': 8.55.0 '@sentry/core': 8.55.0 - magic-string: 0.30.7 - svelte: 5.39.11 + magic-string: 0.30.21 + svelte: 5.43.6 - '@sentry/sveltekit@8.55.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.37.0)(@sveltejs/kit@2.46.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2)))(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2)))(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2))': + '@sentry/sveltekit@8.55.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.30.0)(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0)))(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0)))(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0))': dependencies: '@sentry/core': 8.55.0 '@sentry/node': 8.55.0 - '@sentry/opentelemetry': 8.55.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.37.0) - '@sentry/svelte': 8.55.0(svelte@5.39.11) + '@sentry/opentelemetry': 8.55.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.30.0) + '@sentry/svelte': 8.55.0(svelte@5.43.6) '@sentry/vite-plugin': 2.22.6 - '@sveltejs/kit': 2.46.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2)))(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2)) + '@sveltejs/kit': 2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0)))(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0)) magic-string: 0.30.7 magicast: 0.2.8 sorcery: 1.0.0 optionalDependencies: - vite: 7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2) + vite: 7.2.2(@types/node@22.13.14)(sass@1.94.0) transitivePeerDependencies: - '@opentelemetry/api' - '@opentelemetry/context-async-hooks' @@ -4738,72 +4674,72 @@ snapshots: '@stripe/stripe-js@3.5.0': {} - '@sveltejs/acorn-typescript@1.0.6(acorn@8.15.0)': + '@sveltejs/acorn-typescript@1.0.5(acorn@8.15.0)': dependencies: acorn: 8.15.0 - '@sveltejs/adapter-static@3.0.10(@sveltejs/kit@2.46.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2)))(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2)))': + '@sveltejs/adapter-static@3.0.10(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0)))(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0)))': dependencies: - '@sveltejs/kit': 2.46.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2)))(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2)) + '@sveltejs/kit': 2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0)))(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0)) - '@sveltejs/kit@2.46.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2)))(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2))': + '@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0)))(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0))': dependencies: '@standard-schema/spec': 1.0.0 - '@sveltejs/acorn-typescript': 1.0.6(acorn@8.15.0) - '@sveltejs/vite-plugin-svelte': 5.1.1(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2)) + '@sveltejs/acorn-typescript': 1.0.5(acorn@8.15.0) + '@sveltejs/vite-plugin-svelte': 5.1.1(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0)) '@types/cookie': 0.6.0 acorn: 8.15.0 cookie: 0.6.0 devalue: 5.3.2 esm-env: 1.2.2 kleur: 4.1.5 - magic-string: 0.30.19 + magic-string: 0.30.21 mrmime: 2.0.1 sade: 1.8.1 set-cookie-parser: 2.7.1 - sirv: 3.0.2 - svelte: 5.39.11 - vite: 7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2) + sirv: 3.0.1 + svelte: 5.43.6 + vite: 7.2.2(@types/node@22.13.14)(sass@1.94.0) optionalDependencies: '@opentelemetry/api': 1.9.0 - '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2)))(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2))': + '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0)))(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0))': dependencies: - '@sveltejs/vite-plugin-svelte': 5.1.1(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2)) - debug: 4.4.3 - svelte: 5.39.11 - vite: 7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2) + '@sveltejs/vite-plugin-svelte': 5.1.1(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0)) + debug: 4.4.1 + svelte: 5.43.6 + vite: 7.2.2(@types/node@22.13.14)(sass@1.94.0) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2))': + '@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2)))(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2)) - debug: 4.4.3 + '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0)))(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0)) + debug: 4.4.1 deepmerge: 4.3.1 kleur: 4.1.5 - magic-string: 0.30.19 - svelte: 5.39.11 - vite: 7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2) - vitefu: 1.1.1(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2)) + magic-string: 0.30.21 + svelte: 5.43.6 + vite: 7.2.2(@types/node@22.13.14)(sass@1.94.0) + vitefu: 1.0.6(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0)) transitivePeerDependencies: - supports-color - '@swc/helpers@0.5.17': + '@swc/helpers@0.5.15': dependencies: tslib: 2.8.1 - '@tanstack/svelte-virtual@3.13.12(svelte@5.39.11)': + '@tanstack/svelte-virtual@3.13.12(svelte@5.43.6)': dependencies: '@tanstack/virtual-core': 3.13.12 - svelte: 5.39.11 + svelte: 5.43.6 '@tanstack/virtual-core@3.13.12': {} '@testing-library/dom@10.4.1': dependencies: - '@babel/code-frame': 7.27.1 - '@babel/runtime': 7.28.4 + '@babel/code-frame': 7.26.2 + '@babel/runtime': 7.27.0 '@types/aria-query': 5.0.4 aria-query: 5.3.0 dom-accessibility-api: 0.5.16 @@ -4813,20 +4749,20 @@ snapshots: '@testing-library/jest-dom@6.9.1': dependencies: - '@adobe/css-tools': 4.4.4 + '@adobe/css-tools': 4.4.2 aria-query: 5.3.2 css.escape: 1.5.1 dom-accessibility-api: 0.6.3 picocolors: 1.1.1 redent: 3.0.0 - '@testing-library/svelte@5.2.8(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2))(vitest@3.2.4)': + '@testing-library/svelte@5.2.8(svelte@5.43.6)(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0))(vitest@3.2.4)': dependencies: '@testing-library/dom': 10.4.1 - svelte: 5.39.11 + svelte: 5.43.6 optionalDependencies: - vite: 7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2) - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.7.2)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(sass@1.93.2) + vite: 7.2.2(@types/node@22.13.14)(sass@1.94.0) + vitest: 3.2.4(@types/node@22.13.14)(@vitest/ui@3.2.4)(jsdom@26.1.0)(sass@1.94.0) '@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1)': dependencies: @@ -4840,21 +4776,18 @@ snapshots: '@types/connect@3.4.36': dependencies: - '@types/node': 24.7.2 + '@types/node': 22.13.14 '@types/cookie@0.6.0': {} - '@types/debug@4.1.12': - dependencies: - '@types/ms': 2.1.0 - optional: true - '@types/deep-eql@4.0.2': {} '@types/deep-equal@1.0.4': {} '@types/dlv@1.1.5': {} + '@types/estree@1.0.7': {} + '@types/estree@1.0.8': {} '@types/hast@3.0.4': @@ -4867,16 +4800,13 @@ snapshots: dependencies: '@types/unist': 3.0.3 - '@types/ms@2.1.0': - optional: true - '@types/mysql@2.15.26': dependencies: - '@types/node': 24.7.2 + '@types/node': 22.13.14 - '@types/node@24.7.2': + '@types/node@22.13.14': dependencies: - undici-types: 7.14.0 + undici-types: 6.20.0 '@types/pg-pool@2.0.6': dependencies: @@ -4884,15 +4814,15 @@ snapshots: '@types/pg@8.6.1': dependencies: - '@types/node': 24.7.2 - pg-protocol: 1.10.3 + '@types/node': 22.13.14 + pg-protocol: 1.8.0 pg-types: 2.2.0 '@types/prismjs@1.26.5': {} '@types/prop-types@15.7.15': {} - '@types/react@18.3.26': + '@types/react@18.3.23': dependencies: '@types/prop-types': 15.7.15 csstype: 3.1.3 @@ -4903,19 +4833,19 @@ snapshots: '@types/tedious@4.0.14': dependencies: - '@types/node': 24.7.2 + '@types/node': 22.13.14 '@types/unist@3.0.3': {} - '@typescript-eslint/eslint-plugin@8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.46.4(@typescript-eslint/parser@8.46.4(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.46.0 - '@typescript-eslint/type-utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.46.0 - eslint: 9.37.0(jiti@2.6.1) + '@typescript-eslint/parser': 8.46.4(eslint@9.39.1)(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.46.4 + '@typescript-eslint/type-utils': 8.46.4(eslint@9.39.1)(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.4(eslint@9.39.1)(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.46.4 + eslint: 9.39.1 graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 @@ -4924,80 +4854,80 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/parser@8.46.4(eslint@9.39.1)(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.46.0 - '@typescript-eslint/types': 8.46.0 - '@typescript-eslint/typescript-estree': 8.46.0(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.46.0 - debug: 4.4.3 - eslint: 9.37.0(jiti@2.6.1) + '@typescript-eslint/scope-manager': 8.46.4 + '@typescript-eslint/types': 8.46.4 + '@typescript-eslint/typescript-estree': 8.46.4(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.46.4 + debug: 4.4.1 + eslint: 9.39.1 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.46.0(typescript@5.9.3)': + '@typescript-eslint/project-service@8.46.4(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.46.0(typescript@5.9.3) - '@typescript-eslint/types': 8.46.0 - debug: 4.4.3 + '@typescript-eslint/tsconfig-utils': 8.46.4(typescript@5.9.3) + '@typescript-eslint/types': 8.46.4 + debug: 4.4.1 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.46.0': + '@typescript-eslint/scope-manager@8.46.4': dependencies: - '@typescript-eslint/types': 8.46.0 - '@typescript-eslint/visitor-keys': 8.46.0 + '@typescript-eslint/types': 8.46.4 + '@typescript-eslint/visitor-keys': 8.46.4 - '@typescript-eslint/tsconfig-utils@8.46.0(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.46.4(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.46.4(eslint@9.39.1)(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.46.0 - '@typescript-eslint/typescript-estree': 8.46.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - debug: 4.4.3 - eslint: 9.37.0(jiti@2.6.1) + '@typescript-eslint/types': 8.46.4 + '@typescript-eslint/typescript-estree': 8.46.4(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.4(eslint@9.39.1)(typescript@5.9.3) + debug: 4.4.1 + eslint: 9.39.1 ts-api-utils: 2.1.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.46.0': {} + '@typescript-eslint/types@8.46.4': {} - '@typescript-eslint/typescript-estree@8.46.0(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.46.4(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.46.0(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.46.0(typescript@5.9.3) - '@typescript-eslint/types': 8.46.0 - '@typescript-eslint/visitor-keys': 8.46.0 - debug: 4.4.3 + '@typescript-eslint/project-service': 8.46.4(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.46.4(typescript@5.9.3) + '@typescript-eslint/types': 8.46.4 + '@typescript-eslint/visitor-keys': 8.46.4 + debug: 4.4.1 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 - semver: 7.7.3 + semver: 7.7.1 ts-api-utils: 2.1.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/utils@8.46.4(eslint@9.39.1)(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0(jiti@2.6.1)) - '@typescript-eslint/scope-manager': 8.46.0 - '@typescript-eslint/types': 8.46.0 - '@typescript-eslint/typescript-estree': 8.46.0(typescript@5.9.3) - eslint: 9.37.0(jiti@2.6.1) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1) + '@typescript-eslint/scope-manager': 8.46.4 + '@typescript-eslint/types': 8.46.4 + '@typescript-eslint/typescript-estree': 8.46.4(typescript@5.9.3) + eslint: 9.39.1 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.46.0': + '@typescript-eslint/visitor-keys@8.46.4': dependencies: - '@typescript-eslint/types': 8.46.0 + '@typescript-eslint/types': 8.46.4 eslint-visitor-keys: 4.2.1 '@ungap/structured-clone@1.3.0': {} @@ -5007,16 +4937,16 @@ snapshots: '@types/chai': 5.2.2 '@vitest/spy': 3.2.4 '@vitest/utils': 3.2.4 - chai: 5.3.3 + chai: 5.2.0 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2))': + '@vitest/mocker@3.2.4(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 - magic-string: 0.30.19 + magic-string: 0.30.21 optionalDependencies: - vite: 7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2) + vite: 7.2.2(@types/node@22.13.14)(sass@1.94.0) '@vitest/pretty-format@3.2.4': dependencies: @@ -5026,17 +4956,17 @@ snapshots: dependencies: '@vitest/utils': 3.2.4 pathe: 2.0.3 - strip-literal: 3.1.0 + strip-literal: 3.0.0 '@vitest/snapshot@3.2.4': dependencies: '@vitest/pretty-format': 3.2.4 - magic-string: 0.30.19 + magic-string: 0.30.21 pathe: 2.0.3 '@vitest/spy@3.2.4': dependencies: - tinyspy: 4.0.4 + tinyspy: 4.0.3 '@vitest/ui@3.2.4(vitest@3.2.4)': dependencies: @@ -5044,70 +4974,70 @@ snapshots: fflate: 0.8.2 flatted: 3.3.3 pathe: 2.0.3 - sirv: 3.0.2 - tinyglobby: 0.2.15 + sirv: 3.0.1 + tinyglobby: 0.2.14 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.7.2)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(sass@1.93.2) + vitest: 3.2.4(@types/node@22.13.14)(@vitest/ui@3.2.4)(jsdom@26.1.0)(sass@1.94.0) '@vitest/utils@3.2.4': dependencies: '@vitest/pretty-format': 3.2.4 - loupe: 3.2.1 + loupe: 3.1.4 tinyrainbow: 2.0.0 - '@vue/compiler-core@3.5.22': + '@vue/compiler-core@3.5.13': dependencies: - '@babel/parser': 7.28.4 - '@vue/shared': 3.5.22 + '@babel/parser': 7.28.5 + '@vue/shared': 3.5.13 entities: 4.5.0 estree-walker: 2.0.2 source-map-js: 1.2.1 - '@vue/compiler-dom@3.5.22': + '@vue/compiler-dom@3.5.13': dependencies: - '@vue/compiler-core': 3.5.22 - '@vue/shared': 3.5.22 + '@vue/compiler-core': 3.5.13 + '@vue/shared': 3.5.13 - '@vue/compiler-sfc@3.5.22': + '@vue/compiler-sfc@3.5.13': dependencies: - '@babel/parser': 7.28.4 - '@vue/compiler-core': 3.5.22 - '@vue/compiler-dom': 3.5.22 - '@vue/compiler-ssr': 3.5.22 - '@vue/shared': 3.5.22 + '@babel/parser': 7.28.5 + '@vue/compiler-core': 3.5.13 + '@vue/compiler-dom': 3.5.13 + '@vue/compiler-ssr': 3.5.13 + '@vue/shared': 3.5.13 estree-walker: 2.0.2 - magic-string: 0.30.19 + magic-string: 0.30.21 postcss: 8.5.6 source-map-js: 1.2.1 - '@vue/compiler-ssr@3.5.22': + '@vue/compiler-ssr@3.5.13': dependencies: - '@vue/compiler-dom': 3.5.22 - '@vue/shared': 3.5.22 + '@vue/compiler-dom': 3.5.13 + '@vue/shared': 3.5.13 - '@vue/reactivity@3.5.22': + '@vue/reactivity@3.5.13': dependencies: - '@vue/shared': 3.5.22 + '@vue/shared': 3.5.13 - '@vue/runtime-core@3.5.22': + '@vue/runtime-core@3.5.13': dependencies: - '@vue/reactivity': 3.5.22 - '@vue/shared': 3.5.22 + '@vue/reactivity': 3.5.13 + '@vue/shared': 3.5.13 - '@vue/runtime-dom@3.5.22': + '@vue/runtime-dom@3.5.13': dependencies: - '@vue/reactivity': 3.5.22 - '@vue/runtime-core': 3.5.22 - '@vue/shared': 3.5.22 + '@vue/reactivity': 3.5.13 + '@vue/runtime-core': 3.5.13 + '@vue/shared': 3.5.13 csstype: 3.1.3 - '@vue/server-renderer@3.5.22(vue@3.5.22(typescript@5.9.3))': + '@vue/server-renderer@3.5.13(vue@3.5.13(typescript@5.9.3))': dependencies: - '@vue/compiler-ssr': 3.5.22 - '@vue/shared': 3.5.22 - vue: 3.5.22(typescript@5.9.3) + '@vue/compiler-ssr': 3.5.13 + '@vue/shared': 3.5.13 + vue: 3.5.13(typescript@5.9.3) - '@vue/shared@3.5.22': {} + '@vue/shared@3.5.13': {} acorn-import-attributes@1.9.5(acorn@8.15.0): dependencies: @@ -5121,26 +5051,26 @@ snapshots: agent-base@6.0.2: dependencies: - debug: 4.4.3 + debug: 4.4.1 transitivePeerDependencies: - supports-color - agent-base@7.1.4: {} + agent-base@7.1.3: {} - ai@2.2.37(react@19.2.0)(solid-js@1.9.9)(svelte@5.39.11)(vue@3.5.22(typescript@5.9.3)): + ai@2.2.37(react@19.2.0)(solid-js@1.9.5)(svelte@5.43.6)(vue@3.5.13(typescript@5.9.3)): dependencies: eventsource-parser: 1.0.0 nanoid: 3.3.6 - solid-swr-store: 0.10.7(solid-js@1.9.9)(swr-store@0.10.6) - sswr: 2.0.0(svelte@5.39.11) + solid-swr-store: 0.10.7(solid-js@1.9.5)(swr-store@0.10.6) + sswr: 2.0.0(svelte@5.43.6) swr: 2.2.0(react@19.2.0) swr-store: 0.10.6 - swrv: 1.0.4(vue@3.5.22(typescript@5.9.3)) + swrv: 1.0.4(vue@3.5.13(typescript@5.9.3)) optionalDependencies: react: 19.2.0 - solid-js: 1.9.9 - svelte: 5.39.11 - vue: 3.5.22(typescript@5.9.3) + solid-js: 1.9.5 + svelte: 5.43.6 + vue: 3.5.13(typescript@5.9.3) ajv@6.12.6: dependencies: @@ -5212,16 +5142,14 @@ snapshots: balanced-match@1.0.2: {} - baseline-browser-mapping@2.8.16: {} - binary-extensions@2.3.0: {} - brace-expansion@1.1.12: + brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - brace-expansion@2.0.2: + brace-expansion@2.0.1: dependencies: balanced-match: 1.0.2 @@ -5229,13 +5157,12 @@ snapshots: dependencies: fill-range: 7.1.1 - browserslist@4.26.3: + browserslist@4.24.4: dependencies: - baseline-browser-mapping: 2.8.16 - caniuse-lite: 1.0.30001750 - electron-to-chromium: 1.5.234 - node-releases: 2.0.23 - update-browserslist-db: 1.1.3(browserslist@4.26.3) + caniuse-lite: 1.0.30001707 + electron-to-chromium: 1.5.128 + node-releases: 2.0.19 + update-browserslist-db: 1.1.3(browserslist@4.24.4) cac@6.7.14: {} @@ -5258,17 +5185,17 @@ snapshots: callsites@3.1.0: {} - caniuse-lite@1.0.30001750: {} + caniuse-lite@1.0.30001707: {} ccount@2.0.1: {} - chai@5.3.3: + chai@5.2.0: dependencies: assertion-error: 2.0.1 check-error: 2.1.1 deep-eql: 5.0.2 - loupe: 3.2.1 - pathval: 2.0.1 + loupe: 3.1.4 + pathval: 2.0.0 chalk@4.1.2: dependencies: @@ -5313,22 +5240,22 @@ snapshots: dependencies: color-name: 1.1.4 - color-convert@3.1.2: + color-convert@3.1.0: dependencies: - color-name: 2.0.2 + color-name: 2.0.0 color-name@1.1.4: {} - color-name@2.0.2: {} + color-name@2.0.0: {} - color-string@2.1.2: + color-string@2.0.1: dependencies: - color-name: 2.0.2 + color-name: 2.0.0 color@5.0.2: dependencies: - color-convert: 3.1.2 - color-string: 2.1.2 + color-convert: 3.1.0 + color-string: 2.0.1 comma-separated-tokens@2.0.3: {} @@ -5342,7 +5269,7 @@ snapshots: cron-parser@4.9.0: dependencies: - luxon: 3.7.2 + luxon: 3.6.0 cross-spawn@7.0.6: dependencies: @@ -5359,9 +5286,9 @@ snapshots: cssesc@3.0.0: {} - cssstyle@4.6.0: + cssstyle@4.3.0: dependencies: - '@asamuzakjp/css-color': 3.2.0 + '@asamuzakjp/css-color': 3.1.1 rrweb-cssom: 0.8.0 csstype@3.1.3: {} @@ -5523,13 +5450,17 @@ snapshots: whatwg-mimetype: 4.0.0 whatwg-url: 14.2.0 - dayjs@1.11.18: {} + dayjs@1.11.19: {} + + debug@4.4.0: + dependencies: + ms: 2.1.3 - debug@4.4.3: + debug@4.4.1: dependencies: ms: 2.1.3 - decimal.js@10.6.0: {} + decimal.js@10.5.0: {} deep-eql@5.0.2: {} @@ -5579,9 +5510,6 @@ snapshots: detect-libc@1.0.3: optional: true - detect-libc@2.1.2: - optional: true - devalue@5.3.2: {} devlop@1.1.0: @@ -5594,7 +5522,7 @@ snapshots: dom-accessibility-api@0.6.3: {} - dotenv@16.6.1: {} + dotenv@16.4.7: {} dunder-proto@1.0.1: dependencies: @@ -5607,14 +5535,12 @@ snapshots: tslib: 2.3.0 zrender: 5.6.1 - electron-to-chromium@1.5.234: {} + electron-to-chromium@1.5.128: {} emoji-regex-xs@1.0.0: {} entities@4.5.0: {} - entities@6.0.1: {} - es-define-property@1.0.1: {} es-errors@1.3.0: {} @@ -5637,58 +5563,57 @@ snapshots: dependencies: es-errors: 1.3.0 - esbuild@0.25.10: + esbuild@0.25.1: optionalDependencies: - '@esbuild/aix-ppc64': 0.25.10 - '@esbuild/android-arm': 0.25.10 - '@esbuild/android-arm64': 0.25.10 - '@esbuild/android-x64': 0.25.10 - '@esbuild/darwin-arm64': 0.25.10 - '@esbuild/darwin-x64': 0.25.10 - '@esbuild/freebsd-arm64': 0.25.10 - '@esbuild/freebsd-x64': 0.25.10 - '@esbuild/linux-arm': 0.25.10 - '@esbuild/linux-arm64': 0.25.10 - '@esbuild/linux-ia32': 0.25.10 - '@esbuild/linux-loong64': 0.25.10 - '@esbuild/linux-mips64el': 0.25.10 - '@esbuild/linux-ppc64': 0.25.10 - '@esbuild/linux-riscv64': 0.25.10 - '@esbuild/linux-s390x': 0.25.10 - '@esbuild/linux-x64': 0.25.10 - '@esbuild/netbsd-arm64': 0.25.10 - '@esbuild/netbsd-x64': 0.25.10 - '@esbuild/openbsd-arm64': 0.25.10 - '@esbuild/openbsd-x64': 0.25.10 - '@esbuild/openharmony-arm64': 0.25.10 - '@esbuild/sunos-x64': 0.25.10 - '@esbuild/win32-arm64': 0.25.10 - '@esbuild/win32-ia32': 0.25.10 - '@esbuild/win32-x64': 0.25.10 + '@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-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.8(eslint@9.37.0(jiti@2.6.1)): + eslint-config-prettier@10.1.8(eslint@9.39.1): dependencies: - eslint: 9.37.0(jiti@2.6.1) + eslint: 9.39.1 - eslint-plugin-svelte@3.12.4(eslint@9.37.0(jiti@2.6.1))(svelte@5.39.11): + eslint-plugin-svelte@3.13.0(eslint@9.39.1)(svelte@5.43.6): dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1) '@jridgewell/sourcemap-codec': 1.5.5 - eslint: 9.37.0(jiti@2.6.1) + eslint: 9.39.1 esutils: 2.0.3 - globals: 16.4.0 + globals: 16.5.0 known-css-properties: 0.37.0 postcss: 8.5.6 postcss-load-config: 3.1.4(postcss@8.5.6) postcss-safe-parser: 7.0.1(postcss@8.5.6) - semver: 7.7.3 - svelte-eslint-parser: 1.3.3(svelte@5.39.11) + semver: 7.7.1 + svelte-eslint-parser: 1.4.0(svelte@5.43.6) optionalDependencies: - svelte: 5.39.11 + svelte: 5.43.6 transitivePeerDependencies: - ts-node @@ -5701,25 +5626,24 @@ snapshots: eslint-visitor-keys@4.2.1: {} - eslint@9.37.0(jiti@2.6.1): + eslint@9.39.1: dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1) '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.21.0 - '@eslint/config-helpers': 0.4.0 - '@eslint/core': 0.16.0 + '@eslint/config-array': 0.21.1 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.37.0 - '@eslint/plugin-kit': 0.4.0 - '@humanfs/node': 0.16.7 + '@eslint/js': 9.39.1 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.4.3 + '@humanwhocodes/retry': 0.4.2 '@types/estree': 1.0.8 - '@types/json-schema': 7.0.15 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.3 + debug: 4.4.1 escape-string-regexp: 4.0.0 eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -5738,8 +5662,6 @@ snapshots: minimatch: 3.1.2 natural-compare: 1.4.0 optionator: 0.9.4 - optionalDependencies: - jiti: 2.6.1 transitivePeerDependencies: - supports-color @@ -5757,7 +5679,7 @@ snapshots: dependencies: estraverse: 5.3.0 - esrap@2.1.0: + esrap@2.1.2: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -5771,13 +5693,13 @@ snapshots: estree-walker@3.0.3: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.7 esutils@2.0.3: {} eventsource-parser@1.0.0: {} - eventsource-parser@3.0.6: {} + eventsource-parser@3.0.0: {} expect-type@1.2.2: {} @@ -5799,6 +5721,14 @@ snapshots: dependencies: reusify: 1.1.0 + fdir@6.4.6(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + + fdir@6.4.6(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + fdir@6.5.0(picomatch@4.0.3): optionalDependencies: picomatch: 4.0.3 @@ -5825,7 +5755,7 @@ snapshots: flatted@3.3.3: {} - focus-trap@7.6.5: + focus-trap@7.6.4: dependencies: tabbable: 6.2.0 @@ -5888,9 +5818,11 @@ snapshots: minipass: 4.2.8 path-scurry: 1.11.1 + globals@11.12.0: {} + globals@14.0.0: {} - globals@16.4.0: {} + globals@16.5.0: {} globalyzer@0.1.0: {} @@ -5946,22 +5878,22 @@ snapshots: http-proxy-agent@7.0.2: dependencies: - agent-base: 7.1.4 - debug: 4.4.3 + agent-base: 7.1.3 + debug: 4.4.0 transitivePeerDependencies: - supports-color https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.4.3 + debug: 4.4.1 transitivePeerDependencies: - supports-color https-proxy-agent@7.0.6: dependencies: - agent-base: 7.1.4 - debug: 4.4.3 + agent-base: 7.1.3 + debug: 4.4.0 transitivePeerDependencies: - supports-color @@ -5975,19 +5907,19 @@ snapshots: ignore@7.0.5: {} - immutable@5.1.3: {} + immutable@5.1.1: {} import-fresh@3.3.1: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 - import-in-the-middle@1.15.0: + import-in-the-middle@1.13.1: dependencies: acorn: 8.15.0 acorn-import-attributes: 1.9.5(acorn@8.15.0) cjs-module-lexer: 1.4.3 - module-details-from-path: 1.0.4 + module-details-from-path: 1.0.3 imurmurhash@0.1.4: {} @@ -6092,9 +6024,6 @@ snapshots: isexe@2.0.0: {} - jiti@2.6.1: - optional: true - js-tokens@4.0.0: {} js-tokens@9.0.1: {} @@ -6105,15 +6034,15 @@ snapshots: jsdom@26.1.0: dependencies: - cssstyle: 4.6.0 + cssstyle: 4.3.0 data-urls: 5.0.0 - decimal.js: 10.6.0 + decimal.js: 10.5.0 html-encoding-sniffer: 4.0.0 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.22 - parse5: 7.3.0 + nwsapi: 2.2.20 + parse5: 7.2.1 rrweb-cssom: 0.8.0 saxes: 6.0.0 symbol-tree: 3.2.4 @@ -6123,7 +6052,7 @@ snapshots: whatwg-encoding: 3.1.1 whatwg-mimetype: 4.0.0 whatwg-url: 14.2.0 - ws: 8.18.3 + ws: 8.18.1 xml-name-validator: 5.0.0 transitivePeerDependencies: - bufferutil @@ -6155,56 +6084,6 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - lightningcss-android-arm64@1.30.2: - optional: true - - lightningcss-darwin-arm64@1.30.2: - optional: true - - lightningcss-darwin-x64@1.30.2: - optional: true - - lightningcss-freebsd-x64@1.30.2: - optional: true - - lightningcss-linux-arm-gnueabihf@1.30.2: - optional: true - - lightningcss-linux-arm64-gnu@1.30.2: - optional: true - - lightningcss-linux-arm64-musl@1.30.2: - optional: true - - lightningcss-linux-x64-gnu@1.30.2: - optional: true - - lightningcss-linux-x64-musl@1.30.2: - optional: true - - lightningcss-win32-arm64-msvc@1.30.2: - optional: true - - lightningcss-win32-x64-msvc@1.30.2: - optional: true - - lightningcss@1.30.2: - dependencies: - detect-libc: 2.1.2 - optionalDependencies: - lightningcss-android-arm64: 1.30.2 - lightningcss-darwin-arm64: 1.30.2 - lightningcss-darwin-x64: 1.30.2 - lightningcss-freebsd-x64: 1.30.2 - lightningcss-linux-arm-gnueabihf: 1.30.2 - lightningcss-linux-arm64-gnu: 1.30.2 - lightningcss-linux-arm64-musl: 1.30.2 - lightningcss-linux-x64-gnu: 1.30.2 - lightningcss-linux-x64-musl: 1.30.2 - lightningcss-win32-arm64-msvc: 1.30.2 - lightningcss-win32-x64-msvc: 1.30.2 - optional: true - lilconfig@2.1.0: {} locate-character@3.0.0: {} @@ -6215,7 +6094,7 @@ snapshots: lodash.merge@4.6.2: {} - loupe@3.2.1: {} + loupe@3.1.4: {} lru-cache@10.4.3: {} @@ -6223,11 +6102,15 @@ snapshots: dependencies: yallist: 3.1.1 - luxon@3.7.2: {} + luxon@3.6.0: {} lz-string@1.5.0: {} - magic-string@0.30.19: + magic-string@0.30.17: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -6241,8 +6124,8 @@ snapshots: magicast@0.2.8: dependencies: - '@babel/parser': 7.28.4 - '@babel/types': 7.28.4 + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 recast: 0.23.11 math-intrinsics@1.1.0: {} @@ -6289,15 +6172,15 @@ snapshots: minimatch@3.1.2: dependencies: - brace-expansion: 1.1.12 + brace-expansion: 1.1.11 minimatch@8.0.4: dependencies: - brace-expansion: 2.0.2 + brace-expansion: 2.0.1 minimatch@9.0.5: dependencies: - brace-expansion: 2.0.2 + brace-expansion: 2.0.1 minimist@1.2.8: {} @@ -6305,7 +6188,7 @@ snapshots: minipass@7.1.2: {} - module-details-from-path@1.0.4: {} + module-details-from-path@1.0.3: {} mri@1.2.0: {} @@ -6330,11 +6213,11 @@ snapshots: dependencies: whatwg-url: 5.0.0 - node-releases@2.0.23: {} + node-releases@2.0.19: {} normalize-path@3.0.0: {} - nwsapi@2.2.22: {} + nwsapi@2.2.20: {} object-inspect@1.13.4: {} @@ -6381,9 +6264,9 @@ snapshots: dependencies: callsites: 3.1.0 - parse5@7.3.0: + parse5@7.2.1: dependencies: - entities: 6.0.1 + entities: 4.5.0 path-exists@4.0.0: {} @@ -6398,7 +6281,7 @@ snapshots: pathe@2.0.3: {} - pathval@2.0.1: {} + pathval@2.0.0: {} periscopic@3.1.0: dependencies: @@ -6408,7 +6291,7 @@ snapshots: pg-int8@1.0.1: {} - pg-protocol@1.10.3: {} + pg-protocol@1.8.0: {} pg-types@2.2.0: dependencies: @@ -6422,15 +6305,17 @@ snapshots: picomatch@2.3.1: {} + picomatch@4.0.2: {} + picomatch@4.0.3: {} plausible-tracker@0.3.9: {} - playwright-core@1.56.0: {} + playwright-core@1.56.1: {} - playwright@1.56.0: + playwright@1.56.1: dependencies: - playwright-core: 1.56.0 + playwright-core: 1.56.1 optionalDependencies: fsevents: 2.3.2 @@ -6481,10 +6366,10 @@ snapshots: prelude-ls@1.2.1: {} - prettier-plugin-svelte@3.4.0(prettier@3.6.2)(svelte@5.39.11): + prettier-plugin-svelte@3.4.0(prettier@3.6.2)(svelte@5.43.6): dependencies: prettier: 3.6.2 - svelte: 5.39.11 + svelte: 5.43.6 prettier@3.6.2: {} @@ -6536,6 +6421,8 @@ snapshots: indent-string: 4.0.0 strip-indent: 3.0.0 + regenerator-runtime@0.14.1: {} + regex-recursion@5.1.1: dependencies: regex: 5.1.1 @@ -6563,8 +6450,8 @@ snapshots: require-in-the-middle@7.5.2: dependencies: - debug: 4.4.3 - module-details-from-path: 1.0.4 + debug: 4.4.1 + module-details-from-path: 1.0.3 resolve: 1.22.10 transitivePeerDependencies: - supports-color @@ -6581,32 +6468,30 @@ snapshots: robust-predicates@3.0.2: {} - rollup@4.52.4: + rollup@4.46.2: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.52.4 - '@rollup/rollup-android-arm64': 4.52.4 - '@rollup/rollup-darwin-arm64': 4.52.4 - '@rollup/rollup-darwin-x64': 4.52.4 - '@rollup/rollup-freebsd-arm64': 4.52.4 - '@rollup/rollup-freebsd-x64': 4.52.4 - '@rollup/rollup-linux-arm-gnueabihf': 4.52.4 - '@rollup/rollup-linux-arm-musleabihf': 4.52.4 - '@rollup/rollup-linux-arm64-gnu': 4.52.4 - '@rollup/rollup-linux-arm64-musl': 4.52.4 - '@rollup/rollup-linux-loong64-gnu': 4.52.4 - '@rollup/rollup-linux-ppc64-gnu': 4.52.4 - '@rollup/rollup-linux-riscv64-gnu': 4.52.4 - '@rollup/rollup-linux-riscv64-musl': 4.52.4 - '@rollup/rollup-linux-s390x-gnu': 4.52.4 - '@rollup/rollup-linux-x64-gnu': 4.52.4 - '@rollup/rollup-linux-x64-musl': 4.52.4 - '@rollup/rollup-openharmony-arm64': 4.52.4 - '@rollup/rollup-win32-arm64-msvc': 4.52.4 - '@rollup/rollup-win32-ia32-msvc': 4.52.4 - '@rollup/rollup-win32-x64-gnu': 4.52.4 - '@rollup/rollup-win32-x64-msvc': 4.52.4 + '@rollup/rollup-android-arm-eabi': 4.46.2 + '@rollup/rollup-android-arm64': 4.46.2 + '@rollup/rollup-darwin-arm64': 4.46.2 + '@rollup/rollup-darwin-x64': 4.46.2 + '@rollup/rollup-freebsd-arm64': 4.46.2 + '@rollup/rollup-freebsd-x64': 4.46.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.46.2 + '@rollup/rollup-linux-arm-musleabihf': 4.46.2 + '@rollup/rollup-linux-arm64-gnu': 4.46.2 + '@rollup/rollup-linux-arm64-musl': 4.46.2 + '@rollup/rollup-linux-loongarch64-gnu': 4.46.2 + '@rollup/rollup-linux-ppc64-gnu': 4.46.2 + '@rollup/rollup-linux-riscv64-gnu': 4.46.2 + '@rollup/rollup-linux-riscv64-musl': 4.46.2 + '@rollup/rollup-linux-s390x-gnu': 4.46.2 + '@rollup/rollup-linux-x64-gnu': 4.46.2 + '@rollup/rollup-linux-x64-musl': 4.46.2 + '@rollup/rollup-win32-arm64-msvc': 4.46.2 + '@rollup/rollup-win32-ia32-msvc': 4.46.2 + '@rollup/rollup-win32-x64-msvc': 4.46.2 fsevents: 2.3.3 rrweb-cssom@0.8.0: {} @@ -6629,10 +6514,10 @@ snapshots: safer-buffer@2.1.2: {} - sass@1.93.2: + sass@1.94.0: dependencies: chokidar: 4.0.3 - immutable: 5.1.3 + immutable: 5.1.1 source-map-js: 1.2.1 optionalDependencies: '@parcel/watcher': 2.5.1 @@ -6647,7 +6532,7 @@ snapshots: semver@6.3.1: {} - semver@7.7.3: {} + semver@7.7.1: {} seroval-plugins@1.3.3(seroval@1.3.2): dependencies: @@ -6722,21 +6607,21 @@ snapshots: siginfo@2.0.0: {} - sirv@3.0.2: + sirv@3.0.1: dependencies: - '@polka/url': 1.0.0-next.29 + '@polka/url': 1.0.0-next.28 mrmime: 2.0.1 totalist: 3.0.1 - solid-js@1.9.9: + solid-js@1.9.5: dependencies: csstype: 3.1.3 seroval: 1.3.2 seroval-plugins: 1.3.3(seroval@1.3.2) - solid-swr-store@0.10.7(solid-js@1.9.9)(swr-store@0.10.6): + solid-swr-store@0.10.7(solid-js@1.9.5)(swr-store@0.10.6): dependencies: - solid-js: 1.9.9 + solid-js: 1.9.5 swr-store: 0.10.6 sorcery@1.0.0: @@ -6753,9 +6638,9 @@ snapshots: sprintf-js@1.0.3: {} - sswr@2.0.0(svelte@5.39.11): + sswr@2.0.0(svelte@5.43.6): dependencies: - svelte: 5.39.11 + svelte: 5.43.6 swrev: 4.0.0 stackback@0.0.2: {} @@ -6778,7 +6663,7 @@ snapshots: strip-json-comments@3.1.1: {} - strip-literal@3.1.0: + strip-literal@3.0.0: dependencies: js-tokens: 9.0.1 @@ -6793,23 +6678,23 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svelte-check@4.3.3(picomatch@4.0.3)(svelte@5.39.11)(typescript@5.9.3): + svelte-check@4.3.4(picomatch@4.0.3)(svelte@5.43.6)(typescript@5.9.3): dependencies: - '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/trace-mapping': 0.3.25 chokidar: 4.0.3 - fdir: 6.5.0(picomatch@4.0.3) + fdir: 6.4.6(picomatch@4.0.3) picocolors: 1.1.1 sade: 1.8.1 - svelte: 5.39.11 + svelte: 5.43.6 typescript: 5.9.3 transitivePeerDependencies: - picomatch - svelte-confetti@1.4.0(svelte@5.39.11): + svelte-confetti@1.4.0(svelte@5.43.6): dependencies: - svelte: 5.39.11 + svelte: 5.43.6 - svelte-eslint-parser@1.3.3(svelte@5.39.11): + svelte-eslint-parser@1.4.0(svelte@5.43.6): dependencies: eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -6818,46 +6703,46 @@ snapshots: postcss-scss: 4.0.9(postcss@8.5.6) postcss-selector-parser: 7.1.0 optionalDependencies: - svelte: 5.39.11 + svelte: 5.43.6 - svelte-motion@0.12.2(svelte@5.39.11): + svelte-motion@0.12.2(svelte@5.43.6): dependencies: - '@types/react': 18.3.26 + '@types/react': 18.3.23 framesync: 6.1.2 popmotion: 11.0.5 style-value-types: 5.1.2 - svelte: 5.39.11 + svelte: 5.43.6 tslib: 2.8.1 - svelte-preprocess@6.0.3(@babel/core@7.28.4)(postcss-load-config@3.1.4(postcss@8.5.6))(postcss@8.5.6)(sass@1.93.2)(svelte@5.39.11)(typescript@5.9.3): + svelte-preprocess@6.0.3(@babel/core@7.26.10)(postcss-load-config@3.1.4(postcss@8.5.6))(postcss@8.5.6)(sass@1.94.0)(svelte@5.43.6)(typescript@5.9.3): dependencies: - svelte: 5.39.11 + svelte: 5.43.6 optionalDependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.26.10 postcss: 8.5.6 postcss-load-config: 3.1.4(postcss@8.5.6) - sass: 1.93.2 + sass: 1.94.0 typescript: 5.9.3 - svelte-reparent@0.0.1(svelte@5.39.11): + svelte-reparent@0.0.1(svelte@5.43.6): dependencies: - svelte: 5.39.11 + svelte: 5.43.6 svelte-sequential-preprocessor@2.0.2: dependencies: - svelte: 4.2.20 + svelte: 4.2.19 tslib: 2.7.0 - svelte-sonner@0.3.28(svelte@5.39.11): + svelte-sonner@0.3.28(svelte@5.43.6): dependencies: - svelte: 5.39.11 + svelte: 5.43.6 - svelte@4.2.20: + svelte@4.2.19: dependencies: '@ampproject/remapping': 2.3.0 '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 - '@types/estree': 1.0.8 + '@jridgewell/trace-mapping': 0.3.25 + '@types/estree': 1.0.7 acorn: 8.15.0 aria-query: 5.3.2 axobject-query: 4.1.0 @@ -6866,25 +6751,25 @@ snapshots: estree-walker: 3.0.3 is-reference: 3.0.3 locate-character: 3.0.0 - magic-string: 0.30.19 + magic-string: 0.30.21 periscopic: 3.1.0 - svelte@5.39.11: + svelte@5.43.6: dependencies: '@jridgewell/remapping': 2.3.5 '@jridgewell/sourcemap-codec': 1.5.5 - '@sveltejs/acorn-typescript': 1.0.6(acorn@8.15.0) + '@sveltejs/acorn-typescript': 1.0.5(acorn@8.15.0) '@types/estree': 1.0.8 acorn: 8.15.0 aria-query: 5.3.2 axobject-query: 4.1.0 clsx: 2.1.1 esm-env: 1.2.2 - esrap: 2.1.0 + esrap: 2.1.2 is-reference: 3.0.3 locate-character: 3.0.0 - magic-string: 0.30.19 - zimmerframe: 1.1.4 + magic-string: 0.30.21 + zimmerframe: 1.1.2 swr-store@0.10.6: dependencies: @@ -6893,13 +6778,13 @@ snapshots: swr@2.2.0(react@19.2.0): dependencies: react: 19.2.0 - use-sync-external-store: 1.6.0(react@19.2.0) + use-sync-external-store: 1.5.0(react@19.2.0) swrev@4.0.0: {} - swrv@1.0.4(vue@3.5.22(typescript@5.9.3)): + swrv@1.0.4(vue@3.5.13(typescript@5.9.3)): dependencies: - vue: 3.5.22(typescript@5.9.3) + vue: 3.5.13(typescript@5.9.3) symbol-tree@3.2.4: {} @@ -6918,6 +6803,11 @@ snapshots: tinyexec@0.3.2: {} + tinyglobby@0.2.14: + dependencies: + fdir: 6.4.6(picomatch@4.0.2) + picomatch: 4.0.2 + tinyglobby@0.2.15: dependencies: fdir: 6.5.0(picomatch@4.0.3) @@ -6927,19 +6817,19 @@ snapshots: tinyrainbow@2.0.0: {} - tinyspy@4.0.4: {} + tinyspy@4.0.3: {} tippy.js@6.3.7: dependencies: '@popperjs/core': 2.11.8 - tldts-core@6.1.86: {} + tldts-core@6.1.85: {} tldts-core@7.0.17: {} - tldts@6.1.86: + tldts@6.1.85: dependencies: - tldts-core: 6.1.86 + tldts-core: 6.1.85 tldts@7.0.17: dependencies: @@ -6953,11 +6843,11 @@ snapshots: tough-cookie@5.1.2: dependencies: - tldts: 6.1.86 + tldts: 6.1.85 tr46@0.0.3: {} - tr46@5.1.1: + tr46@5.1.0: dependencies: punycode: 2.3.1 @@ -6979,22 +6869,22 @@ snapshots: dependencies: prelude-ls: 1.2.1 - typescript-eslint@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3): + typescript-eslint@8.46.4(eslint@9.39.1)(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/parser': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.46.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - eslint: 9.37.0(jiti@2.6.1) + '@typescript-eslint/eslint-plugin': 8.46.4(@typescript-eslint/parser@8.46.4(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3) + '@typescript-eslint/parser': 8.46.4(eslint@9.39.1)(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.46.4(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.4(eslint@9.39.1)(typescript@5.9.3) + eslint: 9.39.1 typescript: 5.9.3 transitivePeerDependencies: - supports-color typescript@5.9.3: {} - undici-types@7.14.0: {} + undici-types@6.20.0: {} - unist-util-is@6.0.1: + unist-util-is@6.0.0: dependencies: '@types/unist': 3.0.3 @@ -7006,27 +6896,27 @@ snapshots: dependencies: '@types/unist': 3.0.3 - unist-util-visit-parents@6.0.2: + unist-util-visit-parents@6.0.1: dependencies: '@types/unist': 3.0.3 - unist-util-is: 6.0.1 + unist-util-is: 6.0.0 unist-util-visit@5.0.0: dependencies: '@types/unist': 3.0.3 - unist-util-is: 6.0.1 - unist-util-visit-parents: 6.0.2 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 unplugin@1.0.1: dependencies: acorn: 8.15.0 chokidar: 3.6.0 - webpack-sources: 3.3.3 + webpack-sources: 3.2.3 webpack-virtual-modules: 0.5.0 - update-browserslist-db@1.1.3(browserslist@4.26.3): + update-browserslist-db@1.1.3(browserslist@4.24.4): dependencies: - browserslist: 4.26.3 + browserslist: 4.24.4 escalade: 3.2.0 picocolors: 1.1.1 @@ -7034,7 +6924,7 @@ snapshots: dependencies: punycode: 2.3.1 - use-sync-external-store@1.6.0(react@19.2.0): + use-sync-external-store@1.5.0(react@19.2.0): dependencies: react: 19.2.0 @@ -7050,13 +6940,13 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite-node@3.2.4(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2): + vite-node@3.2.4(@types/node@22.13.14)(sass@1.94.0): dependencies: cac: 6.7.14 - debug: 4.4.3 + debug: 4.4.1 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2) + vite: 7.2.2(@types/node@22.13.14)(sass@1.94.0) transitivePeerDependencies: - '@types/node' - jiti @@ -7071,53 +6961,50 @@ snapshots: - tsx - yaml - vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2): + vite@7.2.2(@types/node@22.13.14)(sass@1.94.0): dependencies: - esbuild: 0.25.10 + esbuild: 0.25.1 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.52.4 + rollup: 4.46.2 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 24.7.2 + '@types/node': 22.13.14 fsevents: 2.3.3 - jiti: 2.6.1 - lightningcss: 1.30.2 - sass: 1.93.2 + sass: 1.94.0 - vitefu@1.1.1(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2)): + vitefu@1.0.6(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0)): optionalDependencies: - vite: 7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2) + vite: 7.2.2(@types/node@22.13.14)(sass@1.94.0) - vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.7.2)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(sass@1.93.2): + vitest@3.2.4(@types/node@22.13.14)(@vitest/ui@3.2.4)(jsdom@26.1.0)(sass@1.94.0): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2)) + '@vitest/mocker': 3.2.4(vite@7.2.2(@types/node@22.13.14)(sass@1.94.0)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 '@vitest/spy': 3.2.4 '@vitest/utils': 3.2.4 - chai: 5.3.3 - debug: 4.4.3 + chai: 5.2.0 + debug: 4.4.1 expect-type: 1.2.2 - magic-string: 0.30.19 + magic-string: 0.30.17 pathe: 2.0.3 picomatch: 4.0.3 std-env: 3.9.0 tinybench: 2.9.0 tinyexec: 0.3.2 - tinyglobby: 0.2.15 + tinyglobby: 0.2.14 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2) - vite-node: 3.2.4(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2) + vite: 7.2.2(@types/node@22.13.14)(sass@1.94.0) + vite-node: 3.2.4(@types/node@22.13.14)(sass@1.94.0) why-is-node-running: 2.3.0 optionalDependencies: - '@types/debug': 4.1.12 - '@types/node': 24.7.2 + '@types/node': 22.13.14 '@vitest/ui': 3.2.4(vitest@3.2.4) jsdom: 26.1.0 transitivePeerDependencies: @@ -7134,13 +7021,13 @@ snapshots: - tsx - yaml - vue@3.5.22(typescript@5.9.3): + vue@3.5.13(typescript@5.9.3): dependencies: - '@vue/compiler-dom': 3.5.22 - '@vue/compiler-sfc': 3.5.22 - '@vue/runtime-dom': 3.5.22 - '@vue/server-renderer': 3.5.22(vue@3.5.22(typescript@5.9.3)) - '@vue/shared': 3.5.22 + '@vue/compiler-dom': 3.5.13 + '@vue/compiler-sfc': 3.5.13 + '@vue/runtime-dom': 3.5.13 + '@vue/server-renderer': 3.5.13(vue@3.5.13(typescript@5.9.3)) + '@vue/shared': 3.5.13 optionalDependencies: typescript: 5.9.3 @@ -7152,7 +7039,7 @@ snapshots: webidl-conversions@7.0.0: {} - webpack-sources@3.3.3: {} + webpack-sources@3.2.3: {} webpack-virtual-modules@0.5.0: {} @@ -7164,7 +7051,7 @@ snapshots: whatwg-url@14.2.0: dependencies: - tr46: 5.1.1 + tr46: 5.1.0 webidl-conversions: 7.0.0 whatwg-url@5.0.0: @@ -7208,7 +7095,7 @@ snapshots: word-wrap@1.2.5: {} - ws@8.18.3: {} + ws@8.18.1: {} xml-name-validator@5.0.0: {} @@ -7222,13 +7109,13 @@ snapshots: yocto-queue@0.1.0: {} - zimmerframe@1.1.4: {} + zimmerframe@1.1.2: {} - zod-to-json-schema@3.24.6(zod@4.1.12): + zod-to-json-schema@3.24.5(zod@3.24.3): dependencies: - zod: 4.1.12 + zod: 3.24.3 - zod@4.1.12: {} + zod@3.24.3: {} zrender@5.6.1: dependencies: diff --git a/src/app.html b/src/app.html index cfb0176396..b2ecb842c8 100644 --- a/src/app.html +++ b/src/app.html @@ -7,6 +7,30 @@ content="Appwrite is an open-source platform for building applications at any scale, using your preferred programming languages and tools." /> + + + + + + + + + + + + %sveltekit.head% diff --git a/src/lib/commandCenter/searchers/projects.ts b/src/lib/commandCenter/searchers/projects.ts index 1df30a3b77..d9c5c8da03 100644 --- a/src/lib/commandCenter/searchers/projects.ts +++ b/src/lib/commandCenter/searchers/projects.ts @@ -4,22 +4,64 @@ import { sdk } from '$lib/stores/sdk'; import { Query } from '@appwrite.io/console'; import { get } from 'svelte/store'; import type { Searcher } from '../commands'; +import { project } from '$routes/(console)/project-[region]-[project]/store'; import { base } from '$app/paths'; export const projectsSearcher = (async (query: string) => { + const q = query.toLowerCase().trim(); + const keywords = [ + 'endpoint', + 'api key', + 'api-key', + 'apikey', + 'project id', + 'project-id', + 'api end' + ]; + + const wantsCredentials = keywords.some((k) => q.includes(k)); + + if (wantsCredentials) { + const curr = get(project); + if (curr?.$id) { + return [ + { + label: 'Go to Settings', + callback: () => { + goto(`${base}/project-${curr.region}-${curr.$id}/settings`); + }, + group: 'navigation' + } + ]; + } + return []; + } + const { projects } = await sdk.forConsole.projects.list({ queries: [Query.equal('teamId', get(organization).$id), Query.orderDesc('')] }); return projects - .filter((project) => project.name.toLowerCase().includes(query.toLowerCase())) + .filter((project) => { + const searchable = [project.name, project.$id, project.region] + .filter(Boolean) + .join(' ') + .toLowerCase(); + + const words = q.split(/\s+/).filter(Boolean); + return words.every((w) => searchable.includes(w)); + }) .map((project) => { + const href = `${base}/project-${project.region}-${project.$id}`; + + const label = project.name; + return { - label: project.name, + label, callback: () => { - goto(`${base}/project-${project.region}-${project.$id}`); + goto(href); }, group: 'projects' - } as const; + }; }); }) satisfies Searcher; diff --git a/src/lib/components/account/sendVerificationEmailModal.svelte b/src/lib/components/account/sendVerificationEmailModal.svelte index c247bda92f..172c248435 100644 --- a/src/lib/components/account/sendVerificationEmailModal.svelte +++ b/src/lib/components/account/sendVerificationEmailModal.svelte @@ -136,7 +136,8 @@ title="Verify your email address" {onSubmit} dismissible={false} - autoClose={false}> + autoClose={false} + backdrop={false}> diff --git a/src/lib/components/apiEndpoint.svelte b/src/lib/components/apiEndpoint.svelte new file mode 100644 index 0000000000..33e70341d0 --- /dev/null +++ b/src/lib/components/apiEndpoint.svelte @@ -0,0 +1,15 @@ + + + + + + + API endpoint + + + diff --git a/src/lib/components/backupRestoreBox.svelte b/src/lib/components/backupRestoreBox.svelte index 2f660985e0..f1de9d3bab 100644 --- a/src/lib/components/backupRestoreBox.svelte +++ b/src/lib/components/backupRestoreBox.svelte @@ -125,20 +125,18 @@ onMount(() => { // fast path: don't subscribe if org is on a free plan or is self-hosted. - if (isSelfHosted || (isCloud && $organization.billingPlan === BillingPlan.FREE)) return; - - return realtime - .forProject(page.params.region, page.params.project) - .subscribe('console', (response) => { - if (!response.channels.includes(`projects.${getProjectId()}`)) return; - - if ( - response.events.includes('archives.*') || - response.events.includes('restorations.*') - ) { - updateOrAddItem(response.payload); - } - }); + if (isSelfHosted || (isCloud && $organization?.billingPlan === BillingPlan.FREE)) return; + + return realtime.forProject(page.params.region, 'console', (response) => { + if (!response.channels.includes(`projects.${getProjectId()}`)) return; + + if ( + response.events.includes('archives.*') || + response.events.includes('restorations.*') + ) { + updateOrAddItem(response.payload); + } + }); }); diff --git a/src/lib/components/card.svelte b/src/lib/components/card.svelte index fd94436ab9..c21c90ef55 100644 --- a/src/lib/components/card.svelte +++ b/src/lib/components/card.svelte @@ -20,21 +20,23 @@ }; type ButtonProps = { - isButton: true; + isButton: boolean; href?: never; }; type AnchorProps = { href: string; - isButton?: never; + isButton?: boolean; + external?: boolean; }; + let classes = ''; type $$Props = BaseProps & (ButtonProps | AnchorProps | BaseProps) & BaseCardProps; - export let isDashed = false; - export let isButton = false; + export let isDashed: boolean = false; + export let isButton: boolean = false; export let href: string = null; - let classes = ''; + export let external: boolean = false; export { classes as class }; export let style = ''; export let padding: $$Props['padding'] = 'm'; @@ -45,7 +47,15 @@ {#if href} - + diff --git a/src/lib/components/copy.svelte b/src/lib/components/copy.svelte index c178913c76..d9a619e013 100644 --- a/src/lib/components/copy.svelte +++ b/src/lib/components/copy.svelte @@ -57,6 +57,7 @@ disabled={tooltipDisabled} portal={tooltipPortal} delay={tooltipDelay} + maxWidth="500px" placement={tooltipPlacement}> ; @@ -28,7 +35,7 @@ * The structure is as follows - * `{ migrationId: { status: status, table: table } }` */ - const importItems: Writable = writable(new Map()); + let importItems = $state(new Map()); async function showCompletionNotification(database: string, table: string, payload: Payload) { const isSuccess = payload.status === 'completed'; @@ -37,13 +44,9 @@ if (!isSuccess && !isError) return; let errorMessage = 'Import failed. Check your CSV for correct fields and required values.'; - if (isError && Array.isArray(payload.errors)) { - try { - // the `errors` is a list of json encoded string. - errorMessage = JSON.parse(payload.errors[0]).message; - } catch { - // do nothing, fallback to default message. - } + const errors = getErrors(payload); + if (errors) { + errorMessage = extractErrorMessage(errors); } const type = isSuccess ? 'success' : 'error'; @@ -73,7 +76,7 @@ const resourceId = importData.resourceId ?? ''; const [databaseId, tableId] = resourceId.split(':') ?? []; - const current = $importItems.get(importData.$id); + const current = importItems.get(importData.$id); let tableName = current?.table ?? null; if (!tableName && tableId) { @@ -91,30 +94,27 @@ } if (tableId && tableName === null) { - importItems.update((items) => { - const next = new Map(items); - next.delete(importData.$id); - return next; - }); + const next = new Map(importItems); + next.delete(importData.$id); + importItems = next; return; } - importItems.update((items) => { - const existing = items.get(importData.$id); - - const isDone = (s: string) => s === 'completed' || s === 'failed'; - const isInProgress = (s: string) => ['pending', 'processing', 'uploading'].includes(s); + const existing = importItems.get(importData.$id); - const shouldSkip = - (existing && isDone(existing.status) && isInProgress(status)) || - existing?.status === status; + const isDone = (s: string) => s === 'completed' || s === 'failed'; + const isInProgress = (s: string) => ['pending', 'processing', 'uploading'].includes(s); - if (shouldSkip) return items; + const shouldSkip = + (existing && isDone(existing.status) && isInProgress(status)) || + existing?.status === status; - const next = new Map(items); - next.set(importData.$id, { status, table: tableName ?? undefined }); - return next; - }); + if (!shouldSkip) { + const next = new Map(importItems); + const errors = getErrors(importData); + next.set(importData.$id, { status, table: tableName ?? undefined, errors }); + importItems = next; + } if (status === 'completed' || status === 'failed') { await showCompletionNotification(databaseId, tableId, importData); @@ -122,10 +122,27 @@ } function clear() { - importItems.update((items) => { - items.clear(); - return items; - }); + importItems = new Map(); + } + + function getErrors(importData: Payload | Models.Migration): string[] | undefined { + return Array.isArray(importData.errors) ? importData.errors : undefined; + } + + function parseError(error: string): string | CsvImportError { + try { + return JSON.parse(error) as CsvImportError; + } catch { + return error; + } + } + + function extractErrorMessage(errors: string[]): string { + try { + return JSON.parse(errors[0]).message; + } catch { + return 'Import failed. Check your CSV for correct fields and required values.'; + } } function graphSize(status: string): number { @@ -148,8 +165,9 @@ const name = collectionName ? `${collectionName}` : ''; switch (status) { case 'completed': + return `CSV import completed${name ? ` to ${name}` : ''}`; case 'failed': - return `Import to ${name} ${status}`; + return `CSV import failed${name ? ` to ${name}` : ''}`; case 'processing': return `Importing CSV file${name ? ` to ${name}` : ''}`; default: @@ -169,7 +187,7 @@ migrations.migrations.forEach(updateOrAddItem); }); - return sdk.forConsoleIn(page.params.region).client.subscribe('console', (response) => { + return realtime.forConsole(page.params.region, 'console', (response) => { if (!response.channels.includes(`projects.${getProjectId()}`)) return; if (response.events.includes('migrations.*')) { updateOrAddItem(response.payload as Payload); @@ -177,8 +195,18 @@ }); }); - $: isOpen = true; - $: showCsvImportBox = $importItems.size > 0; + let isOpen = $state(true); + let showCsvImportBox = $derived(importItems.size > 0); + + let showDetails = $state(false); + let selectedErrors = $state([]); + let parsedErrors = $state>([]); + + function openDetails(errors: string[] | undefined) { + selectedErrors = errors ?? []; + parsedErrors = selectedErrors.map(parseError); + showDetails = true; + } {#if showCsvImportBox} @@ -187,26 +215,23 @@

- Importing rows ({$importItems.size}) + Importing rows ({importItems.size})

-
- {#each [...$importItems.entries()] as [key, value] (key)} + {#each [...importItems.entries()] as [key, value] (key)}
  • @@ -222,6 +247,25 @@ class:is-danger={value.status === 'failed'} style="--graph-size:{graphSize(value.status)}%">
+ {#if value.status === 'failed'} + + + + There was an import issue. + openDetails(value.errors)} + >View details + + + {/if} @@ -232,6 +276,18 @@ {/if} + + + + + + + + diff --git a/src/lib/components/permissions/row.svelte b/src/lib/components/permissions/row.svelte index 8706f77a7c..c70fd5f66f 100644 --- a/src/lib/components/permissions/row.svelte +++ b/src/lib/components/permissions/row.svelte @@ -1,11 +1,14 @@ @@ -48,70 +154,184 @@ {:else if role === 'any'}
Any
{:else} - - {role} -
- {#key showing} - {#await getData(role)} - - - - {:then data} - {@const isUser = role.startsWith('user')} - {@const isTeam = role.startsWith('team')} - {@const isAnonymous = !data.email && !data.phone && !data.name && isUser} - - - {#if isAnonymous} - - - - {:else if data.name} - - {:else} - - - - {/if} - - {data.name ?? data?.email ?? data?.phone ?? '-'} - + + + + {/if} + + diff --git a/src/lib/components/permissions/team.svelte b/src/lib/components/permissions/team.svelte index 02867a7fd9..6f26a62702 100644 --- a/src/lib/components/permissions/team.svelte +++ b/src/lib/components/permissions/team.svelte @@ -141,7 +141,7 @@
{:else} - + Need a hand? Learn more in our {:else} - + Need a hand? Learn more in our documentation import { Copy } from '.'; import { sdk } from '$lib/stores/sdk'; - import { Layout, Tag } from '@appwrite.io/pink-svelte'; + import { Icon, Tag } from '@appwrite.io/pink-svelte'; + import { IconDuplicate } from '@appwrite.io/pink-icons-svelte'; import { Flag, type Models } from '@appwrite.io/console'; - import { truncateText } from '$lib/components/id.svelte'; import { isValueOfStringEnum } from '$lib/helpers/types'; import { getProjectEndpoint } from '$lib/helpers/project'; @@ -21,28 +21,28 @@ {#if region} - - - - {#if flagSrc} - {region?.name} - {/if} - - - {region?.name} - - + + + + API endpoint + {#if flagSrc} + {region?.name} + {/if} {/if} + + diff --git a/src/lib/components/sidebar.svelte b/src/lib/components/sidebar.svelte index ee9c3dea2b..d3ca1991e8 100644 --- a/src/lib/components/sidebar.svelte +++ b/src/lib/components/sidebar.svelte @@ -12,8 +12,7 @@ Button, Layout, Avatar, - Typography, - Badge + Typography } from '@appwrite.io/pink-svelte'; import { @@ -281,12 +280,6 @@ class:has-text={state === 'open'} class="link-text"> {projectOption.name} - {#if projectOption?.badge} - - {/if} {projectOption.name} diff --git a/src/lib/components/viewSelector.svelte b/src/lib/components/viewSelector.svelte index 7523c6f67e..e20b8ca1fa 100644 --- a/src/lib/components/viewSelector.svelte +++ b/src/lib/components/viewSelector.svelte @@ -21,6 +21,7 @@ hideColumns?: boolean; allowNoColumns?: boolean; showAnyway?: boolean; + disableButton?: boolean; } let { @@ -32,7 +33,8 @@ hideView = false, hideColumns = false, allowNoColumns = false, - showAnyway = false + showAnyway = false, + disableButton = false }: Props = $props(); let showCountBadge = $state(false); @@ -70,7 +72,7 @@ icon={onlyIcon} onclick={toggle} variant="secondary" - disabled={!$columns.length && showAnyway} + disabled={(!$columns.length && showAnyway) || disableButton} class={onlyIcon && !$isSmallViewport ? 'width-fix' : undefined} badge={showCountBadge ? selectedColumnsNumber.toString() : undefined}> diff --git a/src/lib/constants.ts b/src/lib/constants.ts index 8fd03090e7..77061abaf0 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -9,12 +9,14 @@ export const REGION_SYD = 'syd'; export const REGION_NYC = 'nyc'; export const REGION_SFO = 'sfo'; export const REGION_SGP = 'sgp'; +export const REGION_TOR = 'tor'; export const SUBDOMAIN_FRA = 'fra.'; export const SUBDOMAIN_SYD = 'syd.'; export const SUBDOMAIN_NYC = 'nyc.'; export const SUBDOMAIN_SFO = 'sfo.'; export const SUBDOMAIN_SGP = 'sgp.'; +export const SUBDOMAIN_TOR = 'tor.'; export enum Dependencies { FACTORS = 'dependency:factors', diff --git a/src/lib/elements/forms/inputLine.svelte b/src/lib/elements/forms/inputLine.svelte index 3987b3635b..6bfeb0fe2e 100644 --- a/src/lib/elements/forms/inputLine.svelte +++ b/src/lib/elements/forms/inputLine.svelte @@ -14,6 +14,7 @@ onDeletePoint: (index: number) => void; onChangePoint: (pointIndex: number, coordIndex: number, newValue: number) => void; addLineButton?: Snippet; + disabled?: boolean; }; let { @@ -24,7 +25,8 @@ onAddPoint, onDeletePoint, onChangePoint, - addLineButton + addLineButton, + disabled }: Props = $props(); function isDeleteDisabled(index: number) { @@ -40,6 +42,7 @@ {#each values as value, index} - {@render addLineButton?.()} diff --git a/src/lib/elements/forms/inputPoint.svelte b/src/lib/elements/forms/inputPoint.svelte index 4c0b4ce40f..9a3f70183e 100644 --- a/src/lib/elements/forms/inputPoint.svelte +++ b/src/lib/elements/forms/inputPoint.svelte @@ -10,6 +10,7 @@ deletePoints?: boolean; onDeletePoint?: () => void; disableDelete?: boolean; + disabled?: boolean; onChangePoint: (index: number, newValue: number) => void; } @@ -21,7 +22,8 @@ deletePoints = false, disableDelete = false, onDeletePoint, - onChangePoint + onChangePoint, + disabled }: Props = $props(); @@ -38,6 +40,7 @@ placeholder="Enter value" step={0.0001} value={values[index]} + {disabled} on:change={(e) => onChangePoint(index, Number.parseFloat(`${e.detail}`))} /> {/each} {/if} @@ -45,7 +48,7 @@ diff --git a/src/lib/elements/forms/inputPolygon.svelte b/src/lib/elements/forms/inputPolygon.svelte index c2bcbb4db1..766dfa7d1b 100644 --- a/src/lib/elements/forms/inputPolygon.svelte +++ b/src/lib/elements/forms/inputPolygon.svelte @@ -17,6 +17,7 @@ coordIndex: number, newValue: number ) => void; + disabled?: boolean; }; let { @@ -26,7 +27,8 @@ onAddPoint, onAddLine, onDeletePoint, - onChangePoint + onChangePoint, + disabled }: Props = $props(); @@ -34,6 +36,7 @@ {#each values as value, index} onAddPoint(index)} {nullable} diff --git a/src/lib/elements/forms/inputSelect.svelte b/src/lib/elements/forms/inputSelect.svelte index 5f56249ff8..57791bdd74 100644 --- a/src/lib/elements/forms/inputSelect.svelte +++ b/src/lib/elements/forms/inputSelect.svelte @@ -21,16 +21,17 @@ }[]; export let leadingIcon: ComponentType | undefined = undefined; - let element: HTMLSelectElement; let error: string; const handleInvalid = (event: Event) => { event.preventDefault(); + const element = event.target as HTMLInputElement; if (element.validity.valueMissing) { error = 'This field is required'; return; } + error = element.validationMessage; }; @@ -38,12 +39,6 @@ return typeof value === 'boolean' ? true : !!value; }; - $: if (required && !isNotEmpty(value)) { - element?.setCustomValidity('This field is required'); - } else { - element?.setCustomValidity(''); - } - $: if (isNotEmpty(value)) { error = null; } diff --git a/src/lib/elements/link.svelte b/src/lib/elements/link.svelte index 6e75e98a5c..444a94d186 100644 --- a/src/lib/elements/link.svelte +++ b/src/lib/elements/link.svelte @@ -29,6 +29,7 @@ {#if href} {:else} - + {/if} diff --git a/src/lib/helpers/buildTimeout.ts b/src/lib/helpers/buildTimeout.ts new file mode 100644 index 0000000000..3915811c2e --- /dev/null +++ b/src/lib/helpers/buildTimeout.ts @@ -0,0 +1,45 @@ +import type { Models } from '@appwrite.io/console'; + +/** + * Checks if a build has exceeded the maximum build timeout duration + */ +function isBuildTimedOut(createdAt: string, status: string, timeoutSeconds: number): boolean { + if (!['waiting', 'processing', 'building'].includes(status)) { + return false; + } + + if (!timeoutSeconds || timeoutSeconds <= 0) { + return false; + } + + const created = new Date(createdAt); + const elapsedSeconds = Math.floor((Date.now() - created.getTime()) / 1000); + + return elapsedSeconds > timeoutSeconds; +} + +/** + * Gets the effective status for a build, considering timeout + */ +export function getEffectiveBuildStatus( + originalStatus: string, + createdAt: string, + consoleVariables: Models.ConsoleVariables | undefined +): string { + const timeoutSeconds = getBuildTimeoutSeconds(consoleVariables); + if (isBuildTimedOut(createdAt, originalStatus, timeoutSeconds)) { + return 'failed'; + } + return originalStatus; +} + +/** + * Helper to get timeout value from console variables + */ +function getBuildTimeoutSeconds(consoleVariables: Models.ConsoleVariables | undefined): number { + if (!consoleVariables?._APP_COMPUTE_BUILD_TIMEOUT) { + return 0; + } + const timeout = parseInt(String(consoleVariables._APP_COMPUTE_BUILD_TIMEOUT), 10); + return isNaN(timeout) ? 0 : timeout; +} diff --git a/src/lib/helpers/numbers.ts b/src/lib/helpers/numbers.ts index ce1c0a0bbc..a3ad303b51 100644 --- a/src/lib/helpers/numbers.ts +++ b/src/lib/helpers/numbers.ts @@ -18,21 +18,38 @@ export function toDecimals(num: number, decimals: number = 1): number { return parseFloat(num.toFixed(decimals)); } -export function formatNumberWithCommas(number: number): string { +export function formatNumberWithCommas(number: number, min: number = 0): string { if (isNaN(number)) return String(number); const formatter = new Intl.NumberFormat('en'); - return formatter.format(number); + return formatter.format(clampMin(number, min)); } -export function formatCurrency(number: number, locale = 'en-US', currency = 'USD'): string { +export function formatCurrency( + number: number, + locale = 'en-US', + currency = 'USD', + min: number = 0 +): string { if (isNaN(number)) return String(number); const formatter = new Intl.NumberFormat(locale, { style: 'currency', currency }); - return formatter.format(number); + return formatter.format(clampMin(number, min)); } export function isWithinSafeRange(val: number) { return Math.abs(val) < Number.MAX_SAFE_INTEGER; } + +/** + * Clamps a number to a minimum value + * + * @export + * @param {number} value + * @param {number} min + * @returns {number} + */ +export function clampMin(value: number, min: number = 0): number { + return Math.max(min, value || 0); +} diff --git a/src/lib/helpers/string.ts b/src/lib/helpers/string.ts index 91dd9a37cb..6f867f86ce 100644 --- a/src/lib/helpers/string.ts +++ b/src/lib/helpers/string.ts @@ -1,3 +1,5 @@ +import { clampMin } from './numbers'; + /** * Capitalizes the first letter of a string * @@ -45,8 +47,8 @@ const formatter = Intl.NumberFormat('en', { notation: 'compact' }); -export function formatNum(number: number): string { - return formatter.format(number); +export function formatNum(number: number, min: number = 0): string { + return formatter.format(clampMin(number, min)); } /** diff --git a/src/lib/images/promos/db-operators-dark.png b/src/lib/images/promos/db-operators-dark.png new file mode 100644 index 0000000000..559c6fce1c Binary files /dev/null and b/src/lib/images/promos/db-operators-dark.png differ diff --git a/src/lib/images/promos/db-operators-light.png b/src/lib/images/promos/db-operators-light.png new file mode 100644 index 0000000000..a3dd30e70e Binary files /dev/null and b/src/lib/images/promos/db-operators-light.png differ diff --git a/src/lib/images/promos/inversion-queries-dark.png b/src/lib/images/promos/inversion-queries-dark.png deleted file mode 100644 index 2b59c4ee2e..0000000000 Binary files a/src/lib/images/promos/inversion-queries-dark.png and /dev/null differ diff --git a/src/lib/images/promos/inversion-queries-light.png b/src/lib/images/promos/inversion-queries-light.png deleted file mode 100644 index 3063aca3c3..0000000000 Binary files a/src/lib/images/promos/inversion-queries-light.png and /dev/null differ diff --git a/src/lib/images/promos/spatial-columns-api-dark.png b/src/lib/images/promos/spatial-columns-api-dark.png deleted file mode 100644 index 29e52e2598..0000000000 Binary files a/src/lib/images/promos/spatial-columns-api-dark.png and /dev/null differ diff --git a/src/lib/images/promos/spatial-columns-api-light.png b/src/lib/images/promos/spatial-columns-api-light.png deleted file mode 100644 index 345bd1650f..0000000000 Binary files a/src/lib/images/promos/spatial-columns-api-light.png and /dev/null differ diff --git a/src/lib/images/promos/time-helper-queries-dark.png b/src/lib/images/promos/time-helper-queries-dark.png deleted file mode 100644 index 0adf4b2311..0000000000 Binary files a/src/lib/images/promos/time-helper-queries-dark.png and /dev/null differ diff --git a/src/lib/images/promos/time-helper-queries-light.png b/src/lib/images/promos/time-helper-queries-light.png deleted file mode 100644 index 466e6ac9fe..0000000000 Binary files a/src/lib/images/promos/time-helper-queries-light.png and /dev/null differ diff --git a/src/lib/layout/footer.svelte b/src/lib/layout/footer.svelte index 5924101371..9ec6553139 100644 --- a/src/lib/layout/footer.svelte +++ b/src/lib/layout/footer.svelte @@ -140,7 +140,7 @@ {/if} {#if $isSmallViewport} - {#if $version && !isCloud} + {#if $version && isSelfHosted} @@ -158,6 +158,9 @@ {/if} {#if isCloud && resolvedProfile.showGeneralAvailability} + + + {/if} + + {#if hasFilters && $columns?.length} {/if} - - {#if hasDisplaySettings} {/if} diff --git a/src/lib/layout/usageMultiple.svelte b/src/lib/layout/usageMultiple.svelte index 421b0892bf..85f5091ca4 100644 --- a/src/lib/layout/usageMultiple.svelte +++ b/src/lib/layout/usageMultiple.svelte @@ -4,7 +4,7 @@ import { Card, SecondaryTabs, SecondaryTabsItem } from '$lib/components'; import { page } from '$app/state'; import { type Models } from '@appwrite.io/console'; - import { formatNumberWithCommas } from '$lib/helpers/numbers'; + import { formatNumberWithCommas, clampMin } from '$lib/helpers/numbers'; import { Layout, Typography } from '@appwrite.io/pink-svelte'; export let title: string; @@ -41,7 +41,7 @@ {#if count} - {@const totalCount = total.reduce((a, b) => a + b, 0)} + {@const totalCount = clampMin(total.reduce((a, b) => a + b, 0))} {formatNumberWithCommas(totalCount)} diff --git a/src/lib/layout/wizardStep.svelte b/src/lib/layout/wizardStep.svelte index 4b64ae4455..591fb62e8e 100644 --- a/src/lib/layout/wizardStep.svelte +++ b/src/lib/layout/wizardStep.svelte @@ -21,14 +21,21 @@ -
- - {#if $$slots.subtitle} -

- -

- {/if} -
+ {#if $$slots.title || $$slots.subtitle} +
+ {#if $$slots.title} + + {/if} + {#if $$slots.subtitle} +

+ +

+ {/if} +
+ {/if}
@@ -42,4 +49,8 @@ padding-block-end: 0; border-block-end: none; } + + .only-subtitle { + margin-block-end: 0.5rem; + } diff --git a/src/lib/stores/billing.ts b/src/lib/stores/billing.ts index d23fa33469..46134dde33 100644 --- a/src/lib/stores/billing.ts +++ b/src/lib/stores/billing.ts @@ -488,6 +488,9 @@ export async function paymentExpired(org: Organization) { const nots = get(notifications); const expiredNotification = nots.some((n) => n.message === expiredMessage); const expiringNotification = nots.some((n) => n.message === expiringMessage); + const cardExpiry = new Date(payment.expiryYear, payment.expiryMonth, 1); + const nextMonth = new Date(year, month + 1, 1); + const isExpiringNextMonth = cardExpiry.getTime() === nextMonth.getTime(); if (payment.expired && !expiredNotification) { addNotification({ type: 'error', @@ -503,7 +506,7 @@ export async function paymentExpired(org: Organization) { } ] }); - } else if (!expiringNotification && payment.expiryYear <= year && payment.expiryMonth < month) { + } else if (!expiringNotification && !payment.expired && isExpiringNextMonth) { addNotification({ type: 'warning', isHtml: true, diff --git a/src/lib/stores/sdk.ts b/src/lib/stores/sdk.ts index 87f46d2144..daeb7ffba8 100644 --- a/src/lib/stores/sdk.ts +++ b/src/lib/stores/sdk.ts @@ -21,7 +21,8 @@ import { Sites, Tokens, TablesDB, - Domains + Domains, + Realtime } from '@appwrite.io/console'; import { Billing } from '../sdk/billing'; import { Backups } from '../sdk/backups'; @@ -32,14 +33,15 @@ import { REGION_SYD, REGION_SFO, REGION_SGP, + REGION_TOR, SUBDOMAIN_FRA, SUBDOMAIN_NYC, SUBDOMAIN_SFO, SUBDOMAIN_SYD, - SUBDOMAIN_SGP + SUBDOMAIN_SGP, + SUBDOMAIN_TOR } from '$lib/constants'; import { building } from '$app/environment'; -import { getProjectId } from '$lib/helpers/project'; export function getApiEndpoint(region?: string): string { if (building) return ''; @@ -67,6 +69,8 @@ const getSubdomain = (region?: string) => { return SUBDOMAIN_SFO; case REGION_SGP: return SUBDOMAIN_SGP; + case REGION_TOR: + return SUBDOMAIN_TOR; default: return ''; } @@ -90,7 +94,8 @@ function createConsoleSdk(client: Client) { sources: new Sources(client), sites: new Sites(client), domains: new Domains(client), - storage: new Storage(client) + storage: new Storage(client), + realtime: new Realtime(client) }; } @@ -134,12 +139,32 @@ const sdkForProject = { }; export const realtime = { - forProject(region: string, _projectId: string) { + forProject( + region: string, + channels: string | string[], + callback: AppwriteRealtimeResponseEvent + ) { const endpoint = getApiEndpoint(region); if (endpoint !== clientRealtime.config.endpoint) { clientRealtime.setEndpoint(endpoint); } - return clientRealtime; + + // because uses a different client! + const realtime = new Realtime(clientRealtime); + + return createRealtimeSubscription(realtime, channels, callback); + }, + + forConsole( + region: string, + channels: string | string[], + callback: AppwriteRealtimeResponseEvent + ): () => void { + const realtimeInstance = region + ? sdk.forConsoleIn(region).realtime + : sdk.forConsole.realtime; + + return createRealtimeSubscription(realtimeInstance, channels, callback); } }; @@ -169,8 +194,8 @@ export const sdk = { }; export enum RuleType { - DEPLOYMENT = 'deployment', API = 'api', + DEPLOYMENT = 'deployment', REDIRECT = 'redirect' } @@ -184,6 +209,24 @@ export enum RuleTrigger { MANUAL = 'manual' } -export const createAdminClient = () => { - return new Client().setEndpoint(getApiEndpoint()).setMode('admin').setProject(getProjectId()); +export type RealtimeResponse = { + events: string[]; + channels: string[]; + timestamp: string; + payload: unknown; }; + +export type AppwriteRealtimeResponseEvent = (response: RealtimeResponse) => void; + +function createRealtimeSubscription( + realtimeInstance: Realtime, + channels: string | string[], + callback: AppwriteRealtimeResponseEvent +): () => void { + const channelsArray = Array.isArray(channels) ? channels : [channels]; + const subscriptionPromise = realtimeInstance.subscribe(channelsArray, callback); + + return () => { + subscriptionPromise.then((sub) => sub.close()); + }; +} diff --git a/src/lib/stores/sites.ts b/src/lib/stores/sites.ts index fcd3215720..29d8113323 100644 --- a/src/lib/stores/sites.ts +++ b/src/lib/stores/sites.ts @@ -26,6 +26,8 @@ export function getFrameworkIcon(framework: string) { return 'vite'; case framework.toLocaleLowerCase().includes('lynx'): return 'lynx'; + case framework.toLocaleLowerCase().includes('tanstack'): + return 'tanstack'; case framework.toLocaleLowerCase().includes('other'): return 'empty'; diff --git a/src/routes/(console)/bottomAlerts.ts b/src/routes/(console)/bottomAlerts.ts index fbbee52afb..b0316aeac6 100644 --- a/src/routes/(console)/bottomAlerts.ts +++ b/src/routes/(console)/bottomAlerts.ts @@ -1,76 +1,32 @@ import { isCloud } from '$lib/system'; import { isSameDay } from '$lib/helpers/date'; import { type BottomModalAlertItem, showBottomModalAlert } from '$lib/stores/bottom-alerts'; -import SpatialColumnsLight from '$lib/images/promos/spatial-columns-api-light.png'; -import SpatialColumnsDark from '$lib/images/promos/spatial-columns-api-dark.png'; -import InversionQueriesDark from '$lib/images/promos/inversion-queries-dark.png'; -import InversionQueriesLight from '$lib/images/promos/inversion-queries-light.png'; -import TimeHelperQueriesDark from '$lib/images/promos/time-helper-queries-dark.png'; -import TimeHelperQueriesLight from '$lib/images/promos/time-helper-queries-light.png'; +import DbOperatorsDark from '$lib/images/promos/db-operators-dark.png'; +import DbOperatorsLight from '$lib/images/promos/db-operators-light.png'; const listOfPromotions: BottomModalAlertItem[] = []; if (isCloud) { - const spatialColumnsPromo: BottomModalAlertItem = { - id: 'modal:spatial_columns_announcement', + const dbOperatorsPromo: BottomModalAlertItem = { + id: 'modal:db_operators_announcement', src: { - dark: SpatialColumnsDark, - light: SpatialColumnsLight + dark: DbOperatorsDark, + light: DbOperatorsLight }, - title: 'Announcing API for spatial columns', - message: 'Store and query geo data directly in your database.', + title: 'Announcing DB operators', + message: 'Update multiple fields without fetching the entire row.', plan: 'free', importance: 8, scope: 'project', cta: { text: 'Read announcement', - link: () => 'https://appwrite.io/blog/post/announcing-spatial-columns', + link: () => 'https://appwrite.io/blog/post/announcing-db-operators', external: true, hideOnClick: true }, show: true }; - - const inversionQueriesPromo: BottomModalAlertItem = { - id: 'modal:inversion_queries_announcement', - src: { - dark: InversionQueriesDark, - light: InversionQueriesLight - }, - title: 'Announcing inversion queries', - message: 'New NOT operators to exclude data directly in queries.', - plan: 'free', - importance: 8, - scope: 'project', - cta: { - text: 'Read announcement', - link: () => 'https://appwrite.io/blog/post/announcing-inversion-queries', - external: true, - hideOnClick: true - }, - show: true - }; - - const timeHelperQueriesPromo: BottomModalAlertItem = { - id: 'modal:time_helper_queries_announcement', - src: { - dark: TimeHelperQueriesDark, - light: TimeHelperQueriesLight - }, - title: 'Announcing Time helper queries', - message: 'New before/after filters for simpler time-based queries.', - plan: 'free', - importance: 8, - scope: 'project', - cta: { - text: 'Read announcement', - link: () => 'https://appwrite.io/blog/post/announcing-time-helper-queries', - external: true, - hideOnClick: true - }, - show: true - }; - listOfPromotions.push(spatialColumnsPromo, inversionQueriesPromo, timeHelperQueriesPromo); + listOfPromotions.push(dbOperatorsPromo); } export function addBottomModalAlerts() { diff --git a/src/routes/(console)/onboarding/create-project/+page.svelte b/src/routes/(console)/onboarding/create-project/+page.svelte index bea9ef9e84..ec39def9a1 100644 --- a/src/routes/(console)/onboarding/create-project/+page.svelte +++ b/src/routes/(console)/onboarding/create-project/+page.svelte @@ -1,5 +1,6 @@ @@ -9,8 +9,10 @@ import { AvatarInitials, Copy, + type DeleteOperationState, Empty, EmptySearch, + MultiSelectionTable, PaginationWithLimit, SearchQuery } from '$lib/components'; @@ -20,14 +22,7 @@ import type { Models } from '@appwrite.io/console'; import { writable } from 'svelte/store'; import Create from './createUser.svelte'; - import { - Badge, - Icon, - Table, - Layout, - Typography, - FloatingActionBar - } from '@appwrite.io/pink-svelte'; + import { Badge, Icon, Table, Layout, Typography } from '@appwrite.io/pink-svelte'; import { Tag } from '@appwrite.io/pink-svelte'; import { IconDuplicate, IconPlus } from '@appwrite.io/pink-icons-svelte'; import { canWriteUsers } from '$lib/stores/roles'; @@ -37,11 +32,11 @@ import { sdk } from '$lib/stores/sdk'; import { Submit, trackError, trackEvent } from '$lib/actions/analytics'; import { Dependencies } from '$lib/constants'; - import { addNotification } from '$lib/stores/notifications'; import { invalidate } from '$app/navigation'; - import Confirm from '$lib/components/confirm.svelte'; - export let data; + import type { PageProps } from './$types'; + + let { data }: PageProps = $props(); const columns = writable([ { id: '$id', title: 'User ID', type: 'string', width: 200 }, @@ -59,44 +54,25 @@ } ]); - let selectedUsers: string[] = []; - let showDelete = false; - let deleting = false; - async function userCreated(event: CustomEvent>>) { await goto( `${base}/project-${page.params.region}-${page.params.project}/auth/user-${event.detail.$id}` ); } - async function handleDelete() { - showDelete = false; - deleting = true; - - const promises = selectedUsers.map((userId) => - sdk.forProject(page.params.region, page.params.project).users.delete(userId) - ); + async function handleDelete(selectedRows: string[]): Promise { + const promises = selectedRows.map((userId) => { + return sdk.forProject(page.params.region, page.params.project).users.delete({ userId }); + }); try { await Promise.all(promises); - trackEvent(Submit.UserDelete, { - total: selectedUsers.length - }); - addNotification({ - type: 'success', - message: `${selectedUsers.length} user${selectedUsers.length > 1 ? 's' : ''} deleted` - }); - invalidate(Dependencies.USERS); + trackEvent(Submit.UserDelete, { total: selectedRows.length }); } catch (error) { - addNotification({ - type: 'error', - message: error.message - }); trackError(error, Submit.UserDelete); + return error; } finally { - selectedUsers = []; - showDelete = false; - deleting = false; + await invalidate(Dependencies.USERS); } } @@ -116,101 +92,111 @@
{#if data.users.total} - - + onDelete={handleDelete} + allowSelection={$canWriteUsers}> + {#snippet header(root)} {#each $columns as { id, title } (id)} {title} {/each} - - {#each data.users.users as user} - - {#each $columns as { id } (id)} - - {#if id === '$id'} - - - - {user.$id} - - - {:else if id === 'name'} - - {#if user.email || user.phone} - {#if user.name} - - - {user.name} - + {/snippet} + + {#snippet children(root)} + {#each data.users.users as user} + + {#each $columns as { id } (id)} + + {#if id === '$id'} + + + + {user.$id} + + + {:else if id === 'name'} + + {#if user.email || user.phone} + {#if user.name} + + + {user.name} + + {:else} +
+ +
+ {/if} {:else}
-
+ + {user.name} + {/if} +
+ {:else if id === 'identifiers'} + + {user.email && user.phone + ? [user.email, user.phone].join(',') + : user.email || user.phone} + + {:else if id === 'status'} + {#if user.status} + {@const success = + user.emailVerification || user.phoneVerification} + {:else} -
- -
- - {user.name} - + + {/if} + {:else if id === 'labels'} + + {user.labels.join(', ')} + + {:else if id === 'joined'} + + {:else if id === 'lastActivity'} + {#if user.accessedAt} + + {:else} + never {/if} -
- {:else if id === 'identifiers'} - - {user.email && user.phone - ? [user.email, user.phone].join(',') - : user.email || user.phone} - - {:else if id === 'status'} - {#if user.status} - {@const success = - user.emailVerification || user.phoneVerification} - - {:else} - - {/if} - {:else if id === 'labels'} - - {user.labels.join(', ')} - - {:else if id === 'joined'} - - {:else if id === 'lastActivity'} - {#if user.accessedAt} - {:else} - never + {user[id]} {/if} - {:else} - {user[id]} - {/if} -
- {/each} -
- {/each} -
+ + {/each} + + {/each} + {/snippet} + + {#snippet deleteContentNotice()} + This action is irreversible and will permanently remove the selected users and all + their data. + {/snippet} + + secondary + href={`${base}/project-${page.params.region}-${page.params.project}/auth`} + >Clear Search {:else} showCreateUser.set(true)} /> {/if} - - {#if selectedUsers.length > 0} - - - - - {selectedUsers.length > 1 ? 'users' : 'user'} - selected - - - - - - - - {/if} - - - - Are you sure you want to delete {selectedUsers.length} - {selectedUsers.length > 1 ? 'users' : 'user'}? - - - This action is irreversible and will permanently remove the selected users and all their - data. - - diff --git a/src/routes/(console)/project-[region]-[project]/auth/teams/+page.svelte b/src/routes/(console)/project-[region]-[project]/auth/teams/+page.svelte index 3a64c2500d..18b2eb2d9e 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/teams/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/teams/+page.svelte @@ -1,4 +1,4 @@ - @@ -10,7 +10,9 @@ EmptySearch, AvatarInitials, SearchQuery, - PaginationWithLimit + PaginationWithLimit, + type DeleteOperationState, + MultiSelectionTable } from '$lib/components'; import Create from '../createTeam.svelte'; import { goto } from '$app/navigation'; @@ -19,31 +21,16 @@ import type { Models } from '@appwrite.io/console'; import { writable } from 'svelte/store'; import { canWriteTeams } from '$lib/stores/roles'; - import { - Icon, - Layout, - Table, - FloatingActionBar, - Badge, - Typography - } from '@appwrite.io/pink-svelte'; + import { Icon, Layout, Table } from '@appwrite.io/pink-svelte'; import { IconPlus } from '@appwrite.io/pink-icons-svelte'; import DualTimeView from '$lib/components/dualTimeView.svelte'; import { sdk } from '$lib/stores/sdk'; import { Submit, trackError, trackEvent } from '$lib/actions/analytics'; import { Dependencies } from '$lib/constants'; - import { addNotification } from '$lib/stores/notifications'; import { invalidate } from '$app/navigation'; - import Confirm from '$lib/components/confirm.svelte'; - - export let data; - - const region = page.params.region; - const project = page.params.project; + import type { PageProps } from './$types'; - let selectedTeams: string[] = []; - let showDelete = false; - let deleting = false; + let { data }: PageProps = $props(); const columns = writable([ { id: 'name', title: 'Name', type: 'string', width: { min: 200, max: 300 } }, @@ -52,37 +39,24 @@ ]); const teamCreated = async (event: CustomEvent>>) => { - await goto(`${base}/project-${region}-${project}/auth/teams/team-${event.detail.$id}`); + await goto( + `${base}/project-${page.params.region}-${page.params.project}/auth/teams/team-${event.detail.$id}` + ); }; - async function handleDelete() { - showDelete = false; - deleting = true; - - const promises = selectedTeams.map((teamId) => - sdk.forProject(page.params.region, page.params.project).teams.delete(teamId) - ); + async function handleDelete(selectedRows: string[]): Promise { + const promises = selectedRows.map((teamId) => { + return sdk.forProject(page.params.region, page.params.project).teams.delete({ teamId }); + }); try { await Promise.all(promises); - trackEvent(Submit.TeamDelete, { - total: selectedTeams.length - }); - addNotification({ - type: 'success', - message: `${selectedTeams.length} team${selectedTeams.length > 1 ? 's' : ''} deleted` - }); - invalidate(Dependencies.TEAMS); + trackEvent(Submit.TeamDelete, { total: selectedRows.length }); } catch (error) { - addNotification({ - type: 'error', - message: error.message - }); trackError(error, Submit.TeamDelete); + return error; } finally { - selectedTeams = []; - showDelete = false; - deleting = false; + await invalidate(Dependencies.TEAMS); } } @@ -101,54 +75,47 @@
{#if data.teams.total} - - + onDelete={handleDelete} + allowSelection={$canWriteTeams}> + {#snippet header(root)} {#each $columns as { id, title }} {title} {/each} - - {#each data.teams.teams as team (team.$id)} - - {#each $columns as column} - - {#if column.id === 'name'} - - - {team.name} - - {:else if column.id === 'members'} - {team.total} members - {:else if column.id === 'created'} - - {/if} - - {/each} - - {/each} - + {/snippet} + + {#snippet children(root)} + {@const TableRowComponent = $canWriteTeams ? Table.Row.Link : Table.Row.Base} + {#each data.teams.teams as team (team.$id)} + {@const href = $canWriteTeams + ? `${base}/project-${page.params.region}-${page.params.project}/auth/teams/team-${team.$id}` + : undefined} + + {#each $columns as column} + + {#if column.id === 'name'} + + + {team.name} + + {:else if column.id === 'members'} + {team.total} members + {:else if column.id === 'created'} + + {/if} + + {/each} + + {/each} + {/snippet} - {#if selectedTeams.length > 0} - - - - - {selectedTeams.length > 1 ? 'teams' : 'team'} - selected - - - - - - - - {/if} + {#snippet deleteContentNotice()} + This action is irreversible and will permanently remove the selected teams and all + their memberships. + {/snippet} + {:else if data.search} - @@ -172,14 +142,3 @@ - - - - Are you sure you want to delete {selectedTeams.length} - {selectedTeams.length > 1 ? 'teams' : 'team'}? - - - This action is irreversible and will permanently remove the selected teams and all their - memberships. - - diff --git a/src/routes/(console)/project-[region]-[project]/auth/teams/team-[team]/members/+page.svelte b/src/routes/(console)/project-[region]-[project]/auth/teams/team-[team]/members/+page.svelte index 629c5bdda3..98999a3059 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/teams/team-[team]/members/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/teams/team-[team]/members/+page.svelte @@ -1,77 +1,50 @@ @@ -85,71 +58,62 @@ {#if data.memberships.total} - - + {#snippet header(root)} Name Roles Joined - - {#each data.memberships.memberships as membership (membership.$id)} - {@const username = membership.userName ? membership.userName : '-'} - - - - - {username} - - - - {membership.roles} - - - - - - - - - {/each} - + {/snippet} - {#if selectedMemberships.length > 0} - - - - - {selectedMemberships.length > 1 ? 'memberships' : 'membership'} - selected - - - - - - - - {/if} + {#snippet children(root)} + {#each data.memberships.memberships as membership (membership.$id)} + {@const username = membership.userName ? membership.userName : '-'} + + + + + {username} + + + + {membership.roles} + + + + + + + + + {/each} + {/snippet} + + {#snippet deleteContentNotice()} + This action is irreversible and will remove the selected members from this team. + {/snippet} + - + invalidate(Dependencies.MEMBERSHIPS)} /> + invalidate(Dependencies.MEMBERSHIPS)} /> - - - - Are you sure you want to delete {selectedMemberships.length} - {selectedMemberships.length > 1 ? 'memberships' : 'membership'}? - - - This action is irreversible and will remove the selected members from this team. - - diff --git a/src/routes/(console)/project-[region]-[project]/auth/user-[user]/identities/table.svelte b/src/routes/(console)/project-[region]-[project]/auth/user-[user]/identities/table.svelte index 13e55efa8e..5d9e956afc 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/user-[user]/identities/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/user-[user]/identities/table.svelte @@ -1,122 +1,88 @@ - - + + {#snippet header(root)} {#each columns as { id, title }} {title} {/each} - - {#each data.identities.identities as identity (identity.$id)} - - {#each columns as column} - - {#if column.id === '$id'} - {#key columns} - - {identity[column.id]} - - {/key} - {:else if column.id === 'provider'} - {@const provider = oAuthProviders[identity[column.id]]} -
-
- {provider.name} + {/snippet} + + {#snippet children(root)} + {#each data.identities.identities as identity (identity.$id)} + + {#each columns as column} + + {#if column.id === '$id'} + {#key columns} + + {identity[column.id]} + + {/key} + {:else if column.id === 'provider'} + {@const provider = oAuthProviders[identity[column.id]]} +
+
+ {provider.name} +
+ {provider.name}
- {provider.name} -
- {:else if column.type === 'datetime'} - {#if !identity[column.id]} - - + {:else if column.type === 'datetime'} + {#if !identity[column.id]} + - + {:else} + + {/if} {:else} - + {identity[column.id]} {/if} - {:else} - {identity[column.id]} - {/if} - - {/each} - - {/each} - - -{#if selectedIds.length > 0} - - - - - {selectedIds.length > 1 ? 'identities' : 'identity'} - selected - - - - - - - -{/if} - - - - Are you sure you want to delete {selectedIds.length} - {selectedIds.length > 1 ? 'identities' : 'identity'}? - - + + {/each} + + {/each} + {/snippet} + diff --git a/src/routes/(console)/project-[region]-[project]/auth/user-[user]/memberships/+page.svelte b/src/routes/(console)/project-[region]-[project]/auth/user-[user]/memberships/+page.svelte index 0deaed8daf..0c0b5525be 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/user-[user]/memberships/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/user-[user]/memberships/+page.svelte @@ -1,50 +1,36 @@ {#if data.memberships.total} - - + {#snippet header(root)} Name Roles Joined - - {#each data.memberships.memberships as membership} - - - - - {membership.teamName ? membership.teamName : 'n/a'} - - - - {membership.roles} - - - - - - - - - {/each} - + {/snippet} + + {#snippet children(root)} + {#each data.memberships.memberships as membership} + + + + + {membership.teamName ? membership.teamName : 'n/a'} + + + + {membership.roles} + + + + + + + + + {/each} + {/snippet} + + {#snippet deleteContentNotice()} + This action is irreversible and will remove the user from the selected teams. + {/snippet} + {:else} {/if} - - {#if selectedMemberships.length > 0} - - - - - {selectedMemberships.length > 1 ? 'memberships' : 'membership'} - selected - - - - - - - - {/if} - - - - Are you sure you want to delete {selectedMemberships.length} - {selectedMemberships.length > 1 ? 'memberships' : 'membership'}? - - - This action is irreversible and will remove the user from the selected teams. - - diff --git a/src/routes/(console)/project-[region]-[project]/auth/user-[user]/targets/table.svelte b/src/routes/(console)/project-[region]-[project]/auth/user-[user]/targets/table.svelte index 09aa636193..e71859a430 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/user-[user]/targets/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/user-[user]/targets/table.svelte @@ -1,6 +1,5 @@ - - + + {#snippet header(root)} {#each $columns as { id, title }} {title} {/each} - - {#each data.targets.targets as target (target.$id)} - {@const provider = data.providersById[target.providerId]} - - {#each $columns as column} - - {#if column.id === '$id'} - {#key $columns} - - {target[column.id]} - - {/key} - {:else if column.id === 'target'} - {#if target.providerType === MessagingProviderType.Push} - {target.name} + {/snippet} + + {#snippet children(root)} + {#each data.targets.targets as target (target.$id)} + {@const provider = data.providersById[target.providerId]} + + {#each $columns as column} + + {#if column.id === '$id'} + {#key $columns} + + {target[column.id]} + + {/key} + {:else if column.id === 'target'} + {#if target.providerType === MessagingProviderType.Push} + {target.name} + {:else} + {target.identifier} + {/if} + {:else if column.id === 'providerType'} + + {:else if column.id === 'provider'} + {#if provider} + + {/if} + {:else if column.id === '$createdAt'} + {:else} - {target.identifier} - {/if} - {:else if column.id === 'providerType'} - - {:else if column.id === 'provider'} - {#if provider} - + {target[column.id]} {/if} - {:else if column.id === '$createdAt'} - - {:else} - {target[column.id]} - {/if} - - {/each} - - {/each} - - -{#if selectedIds.length > 0} - - - - - {selectedIds.length > 1 ? 'targets' : 'target'} - selected - - - - - - - -{/if} - - - - Are you sure you want to delete {selectedIds.length} - {selectedIds.length > 1 ? 'targets' : 'target'}? - - + + {/each} + + {/each} + {/snippet} + diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/columns.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/columns.svelte new file mode 100644 index 0000000000..69cc26bcbb --- /dev/null +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/columns.svelte @@ -0,0 +1,65 @@ + + + + + + + + + + diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/empty.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/empty.svelte index 09289f76f7..22839e48a1 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/empty.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/empty.svelte @@ -8,12 +8,15 @@ Spreadsheet, Typography, FloatingActionBar, - Popover + Popover, + Badge } from '@appwrite.io/pink-svelte'; - import { IconFingerPrint, IconPlus } from '@appwrite.io/pink-icons-svelte'; + import { IconFingerPrint, IconPlus, IconText } from '@appwrite.io/pink-icons-svelte'; import { isSmallViewport, isTabletViewport } from '$lib/stores/viewport'; import type { Column } from '$lib/helpers/types'; - import { expandTabs } from '../table-[table]/store'; + import { SortButton } from '$lib/components'; + import { expandTabs, columnsOrder, columnsWidth, reorderItems } from '../table-[table]/store'; + import { preferences } from '$lib/stores/preferences'; import SpreadsheetContainer from '../table-[table]/layout/spreadsheet.svelte'; import { onDestroy, onMount, tick } from 'svelte'; import { sdk } from '$lib/stores/sdk'; @@ -38,8 +41,62 @@ import Options from './options.svelte'; import { InputSelect, InputText } from '$lib/elements/forms'; import { isCloud, VARS } from '$lib/system'; + import { fade } from 'svelte/transition'; import IconAINotification from './icon/aiNotification.svelte'; + import type { Models } from '@appwrite.io/console'; + + let { + userColumns = [], + userDataRows = [] + }: { + userColumns?: Column[]; + userDataRows?: Models.Row[]; + } = $props(); + + const tableId = page.params.table; + const minimumUserColumnWidth = 168; + + function getUserColumnWidth( + columnId: string, + defaultWidth: number | { min: number } + ): number | { min: number; max?: number } { + const savedWidth = $columnsWidth?.[columnId]; + if (!savedWidth) return defaultWidth; + return savedWidth.resized; + } + + // apply order & width to user columns + const staticUserColumns = $derived.by(() => { + if (!userColumns.length) return []; + + // apply widths to columns + const columnsWithWidths = userColumns.map((column) => { + const defaultWidth = + typeof column.width === 'object' && 'min' in column.width + ? column.width + : typeof column.width === 'number' + ? column.width + : minimumUserColumnWidth; + + return { + ...column, + width: getUserColumnWidth(column.id, defaultWidth), + custom: false, + resizable: false, + draggable: false + }; + }); + + // apply ordering if preferences exist + if ($columnsOrder && $columnsOrder.length > 0) { + return reorderItems(columnsWithWidths, $columnsOrder); + } + + return columnsWithWidths.filter( + (column) => !['$id', '$createdAt', '$updatedAt', 'actions'].includes(column.id) + ); + }); let resizeObserver: ResizeObserver; let spreadsheetContainer: HTMLElement; @@ -48,21 +105,43 @@ let headerElement: HTMLElement | null = null; let rangeOverlayEl: HTMLDivElement | null = null; let fadeBottomOverlayEl: HTMLDivElement | null = null; + let snowFadeBottomOverlayEl: HTMLDivElement | null = null; - let customColumns = $state< - (SuggestedColumnSchema & { elements?: []; isPlaceholder?: boolean })[] - >(Array.from({ length: 7 }, (_, index) => createPlaceholderColumn(index))); + let customColumns = $state( + Array.from({ length: 7 }, (_, index) => createPlaceholderColumn(index)) + ); let showFloatingBar = $state(true); let hasTransitioned = $state(false); let scrollAnimationFrame: number | null = null; let creatingColumns = $state(false); - const baseColProps = { draggable: false, resizable: false }; + let selectedColumnId = $state(null); + let previousColumnId = $state(null); + let selectedColumnName = $state(null); + + let showHeadTooltip = $state(true); + let isInlineEditing = $state(false); + // let tooltipTopPosition = $state(50); + let triggerColumnId = $state(null); + let hoveredColumnId = $state(null); + + // for deleting a column + undo + let undoTimer: ReturnType | null = $state(null); + let columnBeingDeleted: (SuggestedColumnSchema & { deletedIndex?: number }) | null = + $state(null); + + const baseColProps = { + custom: false, + draggable: false, + resizable: false + }; const NOTIFICATION_AND_MOCK_DELAY = 1250; + const COLUMN_DELETION_UNDO_TIMER_LIMIT = 10000; // 10 seconds const getColumnWidth = (columnKey: string) => Math.max(180, columnKey.length * 8 + 60); + const safeNumericValue = (value: number | undefined) => value !== undefined && isWithinSafeRange(value) ? value : undefined; @@ -85,7 +164,7 @@ const updateOverlayHeight = () => { if (!spreadsheetContainer) return; if (!headerElement || !headerElement.isConnected) { - headerElement = spreadsheetContainer.querySelector('[role="rowheader"]'); + headerElement = spreadsheetContainer?.querySelector('[role="rowheader"]'); } if (!headerElement) return; @@ -106,7 +185,7 @@ const updateOverlayBounds = () => { if (!spreadsheetContainer) return; if (!headerElement || !headerElement.isConnected) { - headerElement = spreadsheetContainer.querySelector('[role="rowheader"]'); + headerElement = spreadsheetContainer?.querySelector('[role="rowheader"]'); } if (!headerElement) return; @@ -136,18 +215,45 @@ const hasRealColumns = customColumns.some((col) => !col.isPlaceholder); if (!hasRealColumns) { - // For placeholders or no columns, position overlay to cover custom columns area - const idCell = getById('$id'); + // for placeholders or no columns, + // position overlay to cover custom columns area + let startCell = getById('$id'); + + if (staticUserColumns.length > 0) { + const lastUserColumn = staticUserColumns[staticUserColumns.length - 1]; + let lastUserCell = getById(lastUserColumn.id); + + // if not found with data-header="true", try without it + if (!lastUserCell) { + lastUserCell = headerElement!.querySelector( + `[role="cell"][data-column-id="${lastUserColumn.id}"]` + ); + } + + if (lastUserCell) { + startCell = lastUserCell; + } + } + const actionsCell = headerElement!.querySelector( '[role="cell"][data-column-id="actions"]' ); - if (idCell && actionsCell) { - const idRect = idCell.getBoundingClientRect(); + if (startCell && actionsCell) { + const startRect = startCell.getBoundingClientRect(); const actionsRect = actionsCell.getBoundingClientRect(); - const left = Math.round(idRect.right - containerRect.left); + let left = Math.round(startRect.right - containerRect.left); const actionsLeft = actionsRect.left - containerRect.left; + // ensure overlay doesn't go over select + const selectionRect = spreadsheetContainer + .querySelector('[data-select="true"]') + ?.getBoundingClientRect(); + if (selectionRect) { + const selectionRight = Math.round(selectionRect.right - containerRect.left); + left = Math.max(left, selectionRight); + } + const width = actionsLeft - left; spreadsheetContainer.style.setProperty('--group-left', `${left - 2}px`); @@ -200,15 +306,35 @@ .querySelector('[data-select="true"]') ?.getBoundingClientRect(); - // Start overlay after selection column if it exists, otherwise after $id + // determine starting point for overlay let startLeft = idRect.right; if (selectionRect && selectionRect.right > idRect.right) { startLeft = selectionRect.right; } + // if userColumns exist, + // start overlay **after** the last userColumn + if (staticUserColumns.length > 0) { + const lastUserColumn = staticUserColumns[staticUserColumns.length - 1]; + const lastUserCell = getById(lastUserColumn.id); + + if (lastUserCell) { + const lastUserRect = lastUserCell.getBoundingClientRect(); + startLeft = lastUserRect.right; + } + } + + if (selectionRect) { + startLeft = Math.max(startLeft, selectionRect.right); + } + const left = Math.round(startLeft - containerRect.left); - // get the actions column and use its left border as the boundary + // use the last visible custom column's right edge as the overlay boundary + const endRect = endCell.getBoundingClientRect(); + const endRight = Math.round(endRect.right - containerRect.left); + + // also get the actions column to ensure we don't exceed it const actionsCell = headerElement!.querySelector( '[role="cell"][data-column-id="actions"]' ); @@ -223,7 +349,9 @@ const actionsRect = actionsCell.getBoundingClientRect(); const actionsLeft = actionsRect.left - containerRect.left; - const width = actionsLeft - left; + // ensure overlay doesn't exceed bounds + const right = Math.min(endRight, actionsLeft); + const width = right - left; // Apply overlay positioning spreadsheetContainer.style.setProperty('--group-left', `${left - 2}px`); @@ -232,40 +360,126 @@ // only for mobile, we can remove if not needed! const scrollToFirstCustomColumn = () => { - if (!$isSmallViewport) return; + if (!staticUserColumns.length && !$isSmallViewport) return; if (!headerElement || !headerElement.isConnected) { - headerElement = spreadsheetContainer.querySelector('[role="rowheader"]'); + headerElement = spreadsheetContainer?.querySelector('[role="rowheader"]'); } if (!headerElement) return; - const firstCustomColumnCell = headerElement.querySelector( - `[role="cell"][data-header="true"][data-column-id="${customColumns[0]?.key}"]` - ); - const directAccessScroller = hScroller ?? findHorizontalScroller(headerElement) ?? // internal spreadsheet root main container! spreadsheetContainer.querySelector('.spreadsheet-container'); - if (firstCustomColumnCell && directAccessScroller) { - const cellRect = firstCustomColumnCell.getBoundingClientRect(); + if (!directAccessScroller) return; + + let targetCell: HTMLElement | null = null; + + if (staticUserColumns.length > 0 && !$isSmallViewport) { + const lastUserColumn = staticUserColumns[staticUserColumns.length - 1]; + targetCell = headerElement.querySelector( + `[role="cell"][data-header="true"][data-column-id="${lastUserColumn.id}"]` + ); + } else { + targetCell = headerElement.querySelector( + `[role="cell"][data-header="true"][data-column-id="${customColumns[0]?.key}"]` + ); + } + + if (targetCell) { + const cellRect = targetCell.getBoundingClientRect(); const scrollerRect = directAccessScroller.getBoundingClientRect(); const scrollLeft = directAccessScroller.scrollLeft + cellRect.left - scrollerRect.left - 40; directAccessScroller.scrollTo({ left: Math.max(0, scrollLeft), - behavior: 'smooth' + behavior: 'instant' }); } }; + function updateColumnHighlight() { + const activeColumnId = selectedColumnId || hoveredColumnId; + if (!spreadsheetContainer || !activeColumnId) return; + + const headerCell = spreadsheetContainer.querySelector( + `[role="rowheader"] [role="cell"][data-column-id="${activeColumnId}"]` + ); + + if (!headerCell) return; + + // calculate position similar to columns-range-overlay logic + if (!headerElement || !headerElement.isConnected) { + headerElement = spreadsheetContainer.querySelector('[role="rowheader"]'); + } + + if (!headerElement) return; + + const containerRect = spreadsheetContainer.getBoundingClientRect(); + const cellRect = headerCell.getBoundingClientRect(); + + const left = Math.round(cellRect.left - containerRect.left); + const width = cellRect.width; + + const isHovered = !selectedColumnId && hoveredColumnId; + const isFirstColumn = activeColumnId === customColumns[0]?.key; + const isLastColumn = activeColumnId === customColumns[customColumns.length - 1]?.key; + + let leftAdjustment = -2; + let widthAdjustment = 2; + if (isHovered && (isFirstColumn || isLastColumn)) { + leftAdjustment = 0; + } + + // get actions boundary to prevent hover overlay over it + const actionsCell = headerElement.querySelector( + '[role="cell"][data-column-id="actions"]' + ); + + let finalWidth = width + widthAdjustment; + + if (isHovered && actionsCell) { + const actionsRect = actionsCell.getBoundingClientRect(); + const actionsLeft = actionsRect.left - containerRect.left; + const overlayRight = left + leftAdjustment + finalWidth; + + const borderWidth = 2; + if (overlayRight + borderWidth > actionsLeft) { + finalWidth = actionsLeft - (left + leftAdjustment) - borderWidth; + } + } + + spreadsheetContainer.style.setProperty('--highlight-left', `${left + leftAdjustment}px`); + spreadsheetContainer.style.setProperty('--highlight-width', `${finalWidth}px`); + + if (isHovered) { + const tooltipElement = + spreadsheetContainer.querySelector('.custom-tooltip'); + const tooltipWidth = tooltipElement ? tooltipElement.offsetWidth : 200; + const defaultOffset = 325; + const smallerOffset = 225; + const viewportWidth = window.innerWidth; + + // check how much space is available to the right of the column + const columnRightEdge = left + leftAdjustment + finalWidth; + const availableSpace = viewportWidth - columnRightEdge; + + // use smaller offset if there isn't enough space for default offset + tooltip + const shouldUseSmallerOffset = availableSpace < defaultOffset + tooltipWidth; + const tooltipOffset = shouldUseSmallerOffset ? smallerOffset : defaultOffset; + + spreadsheetContainer.style.setProperty('--tooltip-offset', `${tooltipOffset}px`); + } + } + const recalcAll = () => { updateOverlayHeight(); updateOverlayBounds(); + updateColumnHighlight(); }; /** @@ -276,6 +490,16 @@ scrollAnimationFrame = requestAnimationFrame(() => { recalcAll(); + + // check if selected column is still visible after scroll + if (selectedColumnId && !isColumnVisible(selectedColumnId)) { + resetSelectedColumn(); + } + + if (hoveredColumnId && !isColumnVisible(hoveredColumnId)) { + hoveredColumnId = null; + } + scrollAnimationFrame = null; }); }; @@ -297,38 +521,41 @@ width: { min: getColumnWidth(col.key) }, icon: columnOption?.icon, draggable: false, - resizable: false + resizable: false, + custom: true }; }); }); - const getRowColumns = (): Column[] => { - const minColumnWidth = 180; + const getRowColumns = (): (Column & { custom: boolean })[] => { + const minColumnWidth = 250; const fixedWidths = { id: minColumnWidth, actions: 40, selection: 40 }; - // calculate base widths and total - const columnsWithBase = customSuggestedColumns.map((col) => ({ - ...col, - baseWidth: Math.max(minColumnWidth, getColumnWidth(col.id)) - })); + const equalWidthColumns = [...staticUserColumns, ...customSuggestedColumns]; - const totalUsed = + const totalBaseWidth = fixedWidths.id + fixedWidths.actions + fixedWidths.selection + - columnsWithBase.reduce((sum, col) => sum + col.baseWidth, 0); + equalWidthColumns.length * minColumnWidth; - // distribute excess space equally across custom columns const viewportWidth = spreadsheetContainer?.clientWidth || - (typeof window !== 'undefined' ? window.innerWidth : totalUsed); + (typeof window !== 'undefined' ? window.innerWidth : totalBaseWidth); + const excessSpace = Math.max(0, viewportWidth - totalBaseWidth); const extraPerColumn = - Math.max(0, viewportWidth - totalUsed) / (columnsWithBase.length || 1); + equalWidthColumns.length > 0 ? excessSpace / equalWidthColumns.length : 0; + const distributedWidth = minColumnWidth + extraPerColumn; - const finalCustomColumns = columnsWithBase.map((col) => ({ + const userColumnsWithWidth = staticUserColumns.map((col) => ({ ...col, - width: { min: col.baseWidth + extraPerColumn } + width: distributedWidth + })); + + const finalCustomColumns = customSuggestedColumns.map((col) => ({ + ...col, + width: { min: distributedWidth } })); return [ @@ -340,6 +567,7 @@ icon: IconFingerPrint, ...baseColProps }, + ...userColumnsWithWidth, ...finalCustomColumns, { id: 'actions', @@ -353,9 +581,14 @@ }; const spreadsheetColumns = $derived(getRowColumns()); - const emptyCells = $derived(($isSmallViewport ? 14 : 17) + (!$expandTabs ? 2 : 0)); + const emptyCells = $derived( + ($isSmallViewport ? 14 : 17) + (!$expandTabs ? 2 : 0) - userDataRows.length + ); onMount(async () => { + columnsOrder.set(preferences.getColumnOrder(tableId)); + columnsWidth.set(preferences.getColumnWidths(tableId)); + if (spreadsheetContainer) { resizeObserver = new ResizeObserver(recalcAll); resizeObserver.observe(spreadsheetContainer); @@ -374,20 +607,22 @@ // these are referenced in // `table-[table]/+page.svelte` $tableColumnSuggestions.table = null; + $tableColumnSuggestions.force = false; $tableColumnSuggestions.enabled = false; } $tableColumnSuggestions.context = null; $tableColumnSuggestions.thinking = false; + + // reset selection! + resetSelectedColumn(); } async function suggestColumns() { $tableColumnSuggestions.thinking = true; - if ($isSmallViewport) { - await tick(); - scrollToFirstCustomColumn(); - } + await tick(); + scrollToFirstCustomColumn(); let suggestedColumns: { total: number; @@ -473,17 +708,22 @@ } } - function onPopoverShowStateChanged(value: boolean) { - showFloatingBar = !value; + async function updateOverlaysForMobile(value: boolean) { if ($isSmallViewport) { setTimeout(() => { - [rangeOverlayEl, fadeBottomOverlayEl].forEach((el) => { + [rangeOverlayEl, fadeBottomOverlayEl, snowFadeBottomOverlayEl].forEach((el) => { if (el) { el.style.opacity = value ? '0' : '1'; } }); }, 0); } + } + + function onPopoverShowStateChanged(value: boolean) { + showFloatingBar = !value; + showHeadTooltip = !value; + updateOverlaysForMobile(value); const currentScrollLeft = hScroller?.scrollLeft || 0; @@ -492,6 +732,9 @@ hScroller.scrollLeft = currentScrollLeft; } }); + + // reset selection! + resetSelectedColumn(); } function updateColumn(columnId: string, updates: Partial) { @@ -515,6 +758,174 @@ return !['$id', '$createdAt', '$updatedAt', 'actions'].includes(id); } + function resetSelectedColumn() { + selectedColumnId = null; + previousColumnId = null; + /*selectedColumnName = null;*/ + } + + // small decor, hides previous cell's right border visibility! + function handlePreviousColumnsBorder(columnId: string, hide: boolean = true) { + const allHeaders = Array.from( + spreadsheetContainer.querySelectorAll( + '[role="rowheader"] [role="cell"][data-column-id]' + ) + ); + + const selectedIndex = allHeaders.findIndex( + (cell) => cell.getAttribute('data-column-id') === columnId + ); + + if (selectedIndex > 0) { + const prevColumnId = allHeaders[selectedIndex - 1].getAttribute('data-column-id'); + if (prevColumnId) { + const previousCells = spreadsheetContainer.querySelectorAll( + `[role="rowheader"] [role="cell"][data-column-id="${prevColumnId}"]` + ); + + previousCells.forEach((cell) => { + if (hide) { + cell.classList.add('hide-border'); + } else { + cell.classList.remove('hide-border'); + } + }); + } + } + } + + function isColumnVisible(columnId: string) { + if (!spreadsheetContainer || !hScroller) return true; + + const columnCell = spreadsheetContainer.querySelector( + `[role="rowheader"] [role="cell"][data-column-id="${columnId}"]` + ); + + if (!columnCell) return false; + + const cellRect = columnCell.getBoundingClientRect(); + const scrollerRect = hScroller.getBoundingClientRect(); + + // stickies have 40px width + const STICKY_COLUMN_WIDTH = 40; + + // calculate available viewport bounds (excluding both 40px sticky columns) + const leftBound = scrollerRect.left + STICKY_COLUMN_WIDTH; // Selection column (40px) + const rightBound = scrollerRect.right - STICKY_COLUMN_WIDTH; // Actions column (40px) + + const safetyMargin = 2; + return ( + cellRect.left >= leftBound - safetyMargin && cellRect.right <= rightBound + safetyMargin + ); + } + + function scrollColumnIntoView(columnId: string) { + if (!spreadsheetContainer || !hScroller) return false; + + const columnCell = spreadsheetContainer.querySelector( + `[role="rowheader"] [role="cell"][data-column-id="${columnId}"]` + ); + + if (!columnCell) return false; + + const cellRect = columnCell.getBoundingClientRect(); + const scrollerRect = hScroller.getBoundingClientRect(); + + // calculate scroll needed to center the column in view + const scrollLeft = + hScroller.scrollLeft + + cellRect.left - + scrollerRect.left - + (scrollerRect.width - cellRect.width) / 2; + + hScroller.scrollTo({ + left: Math.max(0, scrollLeft), + behavior: 'smooth' + }); + + return true; + } + + function deleteColumn(columnId: string) { + if (!columnId) return; + + let columnIndex = -1; + let columnSchema: SuggestedColumnSchema = null; + + for (let index = 0; index < customColumns.length; index++) { + if (customColumns[index].key === columnId) { + columnIndex = index; + columnSchema = customColumns[index]; + break; + } + } + + if (columnIndex === -1 || !columnSchema) { + return; + } + + // remove the column + customColumns.splice(columnIndex, 1); + + // store column with its index for undo + columnBeingDeleted = { ...columnSchema, deletedIndex: columnIndex }; + + // clear any existing timer + if (undoTimer) { + clearTimeout(undoTimer); + } + + // start 10-second undo timer + undoTimer = setTimeout(() => { + undoTimer = null; + selectedColumnId = null; + columnBeingDeleted = null; + selectedColumnName = null; + }, COLUMN_DELETION_UNDO_TIMER_LIMIT); + + // reset selection! + resetSelectedColumn(); + + // see overlay is visible after deletion on mobile! + setTimeout(() => updateOverlaysForMobile(false), 150); + + // recalculate view after deletion + requestAnimationFrame(() => recalcAll()); + } + + function undoDelete() { + if (!columnBeingDeleted) return; + + const { deletedIndex, ...columnData } = columnBeingDeleted; + + // restore column at its original index + if (deletedIndex !== undefined && deletedIndex >= 0) { + customColumns.splice(deletedIndex, 0, columnData); + } else { + // fallback: add at the end if index is missing + customColumns.push(columnData); + } + + // clear undo state + columnBeingDeleted = null; + + // clear timer + if (undoTimer) { + clearTimeout(undoTimer); + undoTimer = null; + } + + // recalculate view after restore + requestAnimationFrame(() => { + recalcAll(); + + tick().then(() => { + selectedColumnId = columnData.key; + selectedColumnName = columnData.key; + }); + }); + } + function showIndexSuggestionsNotification() { // safeguard anyways! if (!isCloud) return; @@ -542,8 +953,20 @@ async function createColumns() { creatingColumns = true; + selectedColumnId = null; + const client = sdk.forProject(page.params.region, page.params.project); + const isAnyEmpty = customColumns.some((col) => !col.key); + if (isAnyEmpty) { + creatingColumns = false; + addNotification({ + type: 'warning', + message: 'Some columns have invalid keys' + }); + return; + } + try { const results = []; @@ -552,7 +975,8 @@ databaseId: page.params.database, tableId: page.params.table, key: column.key, - required: column.required || false + required: column.required || false, + encrypt: 'encrypt' in column ? column.encrypt : undefined }; let columnResult: Columns; @@ -650,6 +1074,8 @@ timeout: NOTIFICATION_AND_MOCK_DELAY }); + resetSuggestionsStore(true); + // show index notification! showIndexSuggestionsNotification(); @@ -664,13 +1090,12 @@ } } - function createPlaceholderColumn( - index: number - ): SuggestedColumnSchema & { elements?: []; isPlaceholder?: boolean } { + function createPlaceholderColumn(index: number): SuggestedColumnSchema { return { key: `column${index + 1}`, type: 'string', required: false, + array: false, default: null, format: null, size: undefined, @@ -681,6 +1106,159 @@ }; } + // scroll to view if needed and select! + function selectColumnWithId(column: Column) { + if (creatingColumns) return; + + const columnId = column.id; + selectedColumnName = column.title; + if (!isColumnVisible(columnId)) { + scrollColumnIntoView(columnId); + setTimeout(() => (selectedColumnId = columnId), 300); + } else { + selectedColumnId = columnId; + } + + columnBeingDeleted = null; + } + + /*function fadeSlide(_: Node, { y = 8, duration = 200 } = {}) { + return { + duration, + css: (time: number) => ` + opacity: ${time}; + transform: translateY(${(1 - time) * y}px); + ` + }; + }*/ + + function columnHoverMouseTracker(event: MouseEvent) { + if (hoveredColumnId && event.target instanceof Element) { + const hoveredButton = event.target.closest('[data-column-hover]'); + const currentColumnId = hoveredButton?.getAttribute('data-column-hover'); + + if (currentColumnId !== hoveredColumnId) { + hoveredColumnId = null; + } + } + } + + $effect(() => { + if (!spreadsheetContainer) return; + + // remove existing hide-border classes + const hiddenCells = spreadsheetContainer.querySelectorAll('[role="cell"].hide-border'); + hiddenCells.forEach((cell) => cell.classList.remove('hide-border')); + + if (!selectedColumnId) return; + + setTimeout(() => { + // hide borders for selected column and previous column + const selectedCells = spreadsheetContainer.querySelectorAll( + `[role="cell"][data-column-id="${selectedColumnId}"]` + ); + + selectedCells.forEach((cell) => cell.classList.add('hide-border')); + + // find and hide previous column's borders (which create the left edge of selected column) + const allHeaders = Array.from( + spreadsheetContainer.querySelectorAll( + '[role="rowheader"] [role="cell"][data-column-id]' + ) + ); + const selectedIndex = allHeaders.findIndex( + (cell) => cell.getAttribute('data-column-id') === selectedColumnId + ); + + if (selectedIndex > 0) { + const prevColumnId = allHeaders[selectedIndex - 1].getAttribute('data-column-id'); + if (prevColumnId) { + const previousCells = spreadsheetContainer.querySelectorAll( + `[role="cell"][data-column-id="${prevColumnId}"]` + ); + previousCells.forEach((cell) => cell.classList.add('hide-border')); + } + } + }, 300); + + // update position + updateColumnHighlight(); + + // track for next selection - + // but only if we had a `real` previous selection + if (previousColumnId !== null) { + previousColumnId = selectedColumnId; + } else { + // fresh after a deselect + // set it for future switches + setTimeout(() => (previousColumnId = selectedColumnId), 25); + } + }); + + // mark suggested column cells so CSS can target them specifically + $effect(() => { + if (!spreadsheetContainer) return; + + // get all custom column IDs + const suggestedColumnIds = customColumns.map((col) => col.key); + const firstSuggestedColumnId = suggestedColumnIds[0]; + + const columnBeforeOverlay = + staticUserColumns.length > 0 + ? staticUserColumns[staticUserColumns.length - 1].id + : '$id'; + + const allCells = spreadsheetContainer.querySelectorAll('[role="cell"][data-column-id]'); + allCells.forEach((cell) => { + const columnId = cell.getAttribute('data-column-id'); + if (columnId && suggestedColumnIds.includes(columnId)) { + cell.setAttribute('data-suggested-column', 'true'); + if (columnId === firstSuggestedColumnId) { + cell.setAttribute('data-first-suggested-column', 'true'); + } else { + cell.removeAttribute('data-first-suggested-column'); + } + } else { + cell.removeAttribute('data-suggested-column'); + cell.removeAttribute('data-first-suggested-column'); + } + + if (columnId === columnBeforeOverlay) { + cell.setAttribute('data-column-before-overlay', 'true'); + } else { + cell.removeAttribute('data-column-before-overlay'); + } + }); + }); + + $effect(() => { + if (!spreadsheetContainer) return; + + const allCells = spreadsheetContainer.querySelectorAll('[role="cell"]'); + allCells.forEach((cell) => { + const resizer = cell.querySelector('.column-resizer-disabled') as HTMLDivElement; + if (resizer) resizer.style.display = ''; + }); + + if (!hoveredColumnId) return; + + // auto-scroll if hovered column is out of bounds + /*if (!isColumnVisible(hoveredColumnId)) { + scrollColumnIntoView(hoveredColumnId); + }*/ + + const hoveredCells = spreadsheetContainer.querySelectorAll( + `[role="cell"][data-column-id="${hoveredColumnId}"]` + ); + + hoveredCells.forEach((cell) => { + const resizer = cell.querySelector('.column-resizer-disabled') as HTMLDivElement; + if (resizer) resizer.style.display = 'none'; + }); + + updateColumnHighlight(); + }); + onDestroy(() => { resizeObserver?.disconnect(); hScroller?.removeEventListener('scroll', recalcAllThrottled); @@ -696,12 +1274,14 @@
0} class:thinking={$tableColumnSuggestions.thinking} class="databases-spreadsheet spreadsheet-container-outer" style:--overlay-icon-color="#fd366e99" - style:--non-overlay-icon-color="--fgcolor-neutral-weak"> + style:--non-overlay-icon-color="--fgcolor-neutral-weak" + onmousemove={columnHoverMouseTracker}>
+ + + {#if selectedColumnId || hoveredColumnId} + {@const activeColumnId = selectedColumnId || hoveredColumnId} + {@const isHovered = !selectedColumnId && hoveredColumnId} + {@const isFirstColumn = activeColumnId === customColumns[0]?.key} + {@const isLastColumn = activeColumnId === customColumns[customColumns.length - 1]?.key} +
+
+ + + {/if}
{}}> + bottomActionClick={() => {}} + let:root> {#each spreadsheetColumns as column, index (index)} {#if column.isAction} - + @@ -736,178 +1345,224 @@ ? '--non-overlay-icon-color' : '--overlay-icon-color'} {@const isColumnInteractable = - isCustomColumn(column.id) && !columnObj.isPlaceholder} - - - {#snippet children(toggle)} - { - // tablet viewport check because context-menu - // can be triggered on long hold clicks as well! - if (isColumnInteractable && !$isTabletViewport) { - toggle(event); - } - }}> - - - {column.title} - - - -
+ + + {column.title} + + + + + + {:else} + { + if (triggerColumnId === column.id) { + triggerColumnId = null; + return true; + } + + return false; + }}> + {#snippet children(toggle)} + { + // tablet viewport check because context-menu + // can be triggered on long hold clicks as well! + if (isColumnInteractable && !$isTabletViewport) { + toggle(event); + } + }}> + + - { - if ( - isColumnInteractable && - !$isTabletViewport - ) { - toggle(event); - } + style:--animation-delay={`${isColumnInteractable ? (index - 1) * 100 : 0}ms`} + title={column.title}> + {column.title} + + + {@render changeColumnTypePopover({ + id: column.id, + columnObj, + iconColor: columnIconColor, + icon: column.icon, + isColumnInteractable, + index + })} + + + + {#if !$isTabletViewport} +
{ + isInlineEditing = true; + showHeadTooltip = false; + resetSelectedColumn(); + handlePreviousColumnsBorder(column.id); + }} + onfocusout={() => { + showHeadTooltip = true; + isInlineEditing = false; + handlePreviousColumnsBorder( + column.id, + false + ); }}> - {#if !columnObj?.isPlaceholder} - - {/if} - -
- -
- - - {#each basicColumnOptions as option} - { - toggle(); - updateColumn(column.id, { - type: option.type, - format: - option.format || null - }); - }}> - - - {option.name} - - - {/each} - - -
- - - - - {#if !$isTabletViewport} -
+ + + {#if columnIcon} + {@render changeColumnTypePopover({ + id: column.id, + columnObj, + iconColor: columnIconColor, + icon: column.icon, + isColumnInteractable, + index + })} + {/if} + + +
+ {/if} +
+
+ {/snippet} + + {#snippet tooltipChildren()} + {#if columnObj} + {@const selectedOption = getColumnOption( + columnObj.type, + columnObj.format + )} + {@const ColumnComponent = selectedOption?.component} + + - - {#if columnIcon} - - {/if} - - -
- {/if} -
- - {/snippet} - - {#snippet tooltipChildren()} - {#if columnObj} - {@const selectedOption = getColumnOption( - columnObj.type, - columnObj.format - )} - {@const ColumnComponent = selectedOption?.component} - - - - - { - const newOption = columnOptions.find( - (opt) => opt.name === e.detail - ); - if (newOption) { - updateColumn(column.id, { - type: newOption.type, - format: newOption.format || null - }); - } - }} - options={basicColumnOptions.map((col) => { - return { - label: col.name, - value: col.name, - leadingIcon: col.icon - }; - })} /> - + pattern="^[A-Za-z0-9][A-Za-z0-9._\-]*$" /> - {#if ColumnComponent} - - {/if} - - {/if} - {/snippet} - + { + const newOption = columnOptions.find( + (opt) => opt.name === e.detail + ); + if (newOption) { + updateColumn(column.id, { + type: newOption.type, + format: newOption.format || null + }); + } + }} + options={basicColumnOptions.map((col) => { + return { + label: col.name, + value: col.name, + leadingIcon: col.icon + }; + })} /> + + + {#if ColumnComponent} + + {/if} + + {/if} + {/snippet} + + {#snippet mobileFooterChildren(toggle)} + { + toggle(event); + deleteColumn(column.id); + }} + style="position: absolute; left: 1rem;" + >Delete + + {/snippet} + + {/if} {/if} {/each} + + {#each userDataRows as row} + + {#each spreadsheetColumns as column} + {@const columnObj = getColumn(column.id)} + {@const interactable = + isCustomColumn(column.id) && columnObj && !columnObj.isPlaceholder} + + {@render rowCellInteractiveButton({ + interactable, + column, + row + })} + + {/each} + + {/each} + + {#each Array.from({ length: emptyCells }) as _} + + {#each spreadsheetColumns as column} + {@const columnObj = getColumn(column.id)} + {@const interactable = + isCustomColumn(column.id) && columnObj && !columnObj.isPlaceholder} + + {@render rowCellInteractiveButton({ + interactable, + column + })} + + {/each} + + {/each}
@@ -917,6 +1572,12 @@ data-collapsed-tabs={!$expandTabs}>
+
+
+ {#if $tableColumnSuggestions.thinking}
@@ -942,13 +1603,85 @@
{:else if customColumns.some((col) => !col.isPlaceholder) && showFloatingBar} + + {@const isUndoDeleteMode = columnBeingDeleted && columnBeingDeleted?.key !== null} + {@const columnName = isUndoDeleteMode ? columnBeingDeleted?.key : selectedColumnName} + {@const hasSelection = selectedColumnId !== null || isUndoDeleteMode} + + {#if !creatingColumns} +
+ + + + + + + {#if isUndoDeleteMode} + was deleted. You can undo this action. + {:else} + is selected + {/if} + + + + + + + {#if !isUndoDeleteMode} + (selectedColumnId = null)}> + Cancel + + + + + {/if} + !col.isPlaceholder).length <= 1} + on:click={() => { + if (isUndoDeleteMode) { + undoDelete(); + } else { + deleteColumn(selectedColumnId); + } + }}> + {#if isUndoDeleteMode} + Undo + {:else} + Delete + {/if} + + + + +
+ {/if} + +
+ class:creating-columns={creatingColumns} + class:has-selection={hasSelection}> - + {#if creatingColumns} {/if} @@ -958,49 +1691,212 @@ color="--fgcolor-neutral-secondary" style="white-space: nowrap"> {creatingColumns - ? 'Creating columns' + ? 'Creating columns...' : $isSmallViewport - ? 'Review and edit suggested columns' - : 'Review and edit suggested columns before applying'} + ? 'Click headers or cells to edit columns' + : 'Click headers or cells to edit columns before applying'} - - { - customColumns = []; - resetSuggestionsStore(); - }} - style="opacity: {creatingColumns ? '0' : '1'}" - >Dismiss - - Apply - - + {#if !creatingColumns} + + { + customColumns = []; + resetSuggestionsStore(); + }} + style="opacity: {creatingColumns ? '0' : '1'}" + >Dismiss + + Apply + + + {/if}
{/if}
+ + +{#snippet rowCellInteractiveButton({ interactable, column, row = null })} + +{/snippet} + +{#snippet changeColumnTypePopover({ id, columnObj, iconColor, icon, isColumnInteractable, index })} + +
+ { + if (isColumnInteractable && !$isTabletViewport) { + toggle(event); + resetSelectedColumn(); + } + }}> + {#if !columnObj?.isPlaceholder} + + {/if} + +
+ +
+ + + {#each basicColumnOptions as option} + { + toggle(); + updateColumn(id, { + type: option.type, + format: option.format || null + }); + }}> + + + {option.name} + + + {/each} + + +
+
+{/snippet} + +{#snippet edgeGradients(side: 'left' | 'right')} + + {@const gradientConfigs = [ + { pos: '20%', color: 'var(--border-pink)', spread: '25%', delay: '0s' }, + { pos: '50%', color: 'var(--border-orange)', spread: '15%', delay: '1s' }, + { pos: '80%', color: 'var(--border-pink)', spread: '25%', delay: '2s' }, + { pos: '35%', color: 'var(--border-pink)', spread: '40%', delay: '0.5s' }, + { pos: '65%', color: 'var(--border-orange)', spread: '40%', delay: '1.5s' } + ]} + {@const xPosition = side === 'left' ? '0%' : '100%'} + +
+ {#each gradientConfigs as grad} +
+
+ {/each} +
+{/snippet} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/icon/ai.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/icon/ai.svelte index 1d51db1688..9fae0e544b 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/icon/ai.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/icon/ai.svelte @@ -71,8 +71,16 @@ border: 1.25px solid rgba(253, 54, 110, 0.12); padding: 5px 0; + min-width: 40px; width: 40px !important; height: 40px !important; + + & svg { + width: 30px; + height: 30px; + flex-shrink: 0; + aspect-ratio: 1/1; + } } :global(.ai-icon-holder.notification) { diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/icon/aiForButton.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/icon/aiForButton.svelte new file mode 100644 index 0000000000..df6de05161 --- /dev/null +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/icon/aiForButton.svelte @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/indexes.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/indexes.svelte index 2f33a1af66..85158b884d 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/indexes.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/indexes.svelte @@ -8,7 +8,7 @@ mockSuggestions, type SuggestedIndexSchema } from './store'; - import { Modal, Confirm } from '$lib/components'; + import { Modal } from '$lib/components'; import SideSheet from '../table-[table]/layout/sidesheet.svelte'; import { isSmallViewport } from '$lib/stores/viewport'; import { IndexType, type Models } from '@appwrite.io/console'; @@ -32,7 +32,6 @@ let creatingIndexes = $state(false); let loadingSuggestions = $state(false); let indexes = $state([]); - let confirmDismiss = $state(false); let columnOptions: Array<{ value: string; label: string; @@ -195,7 +194,6 @@ function dismissIndexes() { indexes = []; - confirmDismiss = false; $showIndexesSuggestions = false; } @@ -354,13 +352,7 @@ text size="s" disabled={loadingSuggestions || creatingIndexes} - on:click={() => { - if (indexes.length > 0 && !creatingIndexes) { - confirmDismiss = true; - } else { - $showIndexesSuggestions = false; - } - }}>Cancel + on:click={() => dismissIndexes()}>Cancel {:else} - +
+ + + + + {headerTooltipText} + + +
{/if}
@@ -56,6 +80,10 @@ showSheet = false; } }}> + {#snippet footer()} + {@render mobileFooterChildren?.(() => (showSheet = false))} + {/snippet} + {@render tooltipChildren(() => (showSheet = false))} {/if} diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/store.ts b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/store.ts index f1792e3911..834bfc7aa2 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/store.ts +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/store.ts @@ -3,6 +3,7 @@ import { IndexType } from '@appwrite.io/console'; import { columnOptions } from '../table-[table]/columns/store'; export type TableColumnSuggestions = { + force: boolean; enabled: boolean; thinking: boolean; context?: string | undefined; @@ -18,11 +19,15 @@ export type SuggestedColumnSchema = { key: string; type: string; required: boolean; + array?: boolean; default?: string | number | boolean | number[] | number[][] | number[][][] | null; size?: number; min?: number; max?: number; format?: string | null; + encrypt?: boolean | null; + elements?: string[]; + isPlaceholder?: boolean; }; export enum IndexOrder { @@ -43,11 +48,14 @@ export const tableColumnSuggestions = writable({ enabled: false, context: null, thinking: false, - table: null + table: null, + force: false }); export const showIndexesSuggestions = writable(false); +export const showColumnsSuggestionsModal = writable(false); + export const mockSuggestions: { total: number; columns: ColumnInput[] } = { total: 7, columns: [ @@ -68,7 +76,7 @@ export const mockSuggestions: { total: number; columns: ColumnInput[] } = { formatOptions: null }, { - name: 'publishedYear', + name: 'year', type: 'integer', size: null, format: null, @@ -79,7 +87,7 @@ export const mockSuggestions: { total: number; columns: ColumnInput[] } = { } }, { - name: 'genre', + name: 'category', type: 'string', size: 64, format: null, @@ -88,7 +96,7 @@ export const mockSuggestions: { total: number; columns: ColumnInput[] } = { default: null }, { - name: 'isbn', + name: 'code', type: 'string', size: 13, required: false, @@ -96,7 +104,7 @@ export const mockSuggestions: { total: number; columns: ColumnInput[] } = { default: null }, { - name: 'language', + name: 'spokenLanguage', type: 'string', size: 32, format: null, @@ -105,7 +113,7 @@ export const mockSuggestions: { total: number; columns: ColumnInput[] } = { default: null }, { - name: 'pageCount', + name: 'count', type: 'integer', required: false, min: 1, @@ -123,6 +131,7 @@ export type ColumnInput = { min?: number; max?: number; format?: string; + elements?: string[]; formatOptions?: { min?: number; max?: number; @@ -134,6 +143,7 @@ export function mapSuggestedColumns(columns: T[]): Sugges key: col.name, type: col.type, required: col.required ?? false, + array: false, default: col.default ?? null, size: col.type === 'string' ? (col.size ?? undefined) : undefined, min: @@ -144,7 +154,8 @@ export function mapSuggestedColumns(columns: T[]): Sugges col.type === 'integer' || col.type === 'double' ? (col.max ?? col.formatOptions?.max ?? undefined) : undefined, - format: col.format ?? null + format: col.format ?? null, + elements: col.elements ?? undefined })); } diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/backups/+page.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/backups/+page.svelte index 6c6a8de18e..99521078d7 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/backups/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/backups/+page.svelte @@ -69,11 +69,11 @@ await sdk .forProject(page.params.region, page.params.project) .backups.createArchive(['databases'], data.database.$id); + await invalidate(Dependencies.BACKUPS); addNotification({ type: 'success', message: 'Database backup has started' }); - invalidate(Dependencies.BACKUPS); trackEvent('click_manual_submit'); showFeedbackNotification(); } catch (error) { @@ -86,7 +86,7 @@ } }; - const trackEvents = (policies) => { + const trackEvents = (policies: UserBackupPolicy[]) => { policies.forEach((policy) => { let actualDay = null; const monthlyBackupFrequency = policy.monthlyBackupFrequency; @@ -139,7 +139,6 @@ ? `Backup policies have been created` : `${totalPolicies[0].label} policy has been created`; - // TODO: html isn't yet supported on Toast. addNotification({ isHtml: true, type: 'success', @@ -148,7 +147,7 @@ trackEvents(totalPolicies); - invalidate(Dependencies.BACKUPS); + await invalidate(Dependencies.BACKUPS); showFeedbackNotification(); } catch (err) { addNotification({ @@ -162,19 +161,14 @@ }; onMount(() => { - return realtime - .forProject(page.params.region, page.params.project) - .subscribe(['project', 'console'], (response) => { - // fast path return. - if (!response.channels.includes(`projects.${getProjectId()}`)) return; - - if ( - response.events.includes('archives.*') || - response.events.includes('policies.*') - ) { - invalidate(Dependencies.BACKUPS); - } - }); + return realtime.forProject(page.params.region, ['project', 'console'], (response) => { + // fast path return. + if (!response.channels.includes(`projects.${getProjectId()}`)) return; + + if (response.events.includes('archives.*') || response.events.includes('policies.*')) { + invalidate(Dependencies.BACKUPS); + } + }); }); diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/backups/table.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/backups/table.svelte index 689afe74f4..d335931601 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/backups/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/backups/table.svelte @@ -1,5 +1,11 @@ - - + + {#snippet header(root)} {#each $columns as column} {column.title} {/each} - + {/snippet} - {#each data.backups.archives as backup, index} - {@const policy = policyDetails(backup.policyId)} - {@const retainedUntil = new Date( - new Date(policy?.$createdAt).getTime() + policy?.retention * 24 * 60 * 60 * 1000 - )} - {@const formattedRetainedUntil = `${retainedUntil.getDate()} ${retainedUntil.toLocaleString('en-US', { month: 'short' })}, ${retainedUntil.getFullYear()} ${retainedUntil.toLocaleTimeString('en-US', { hour12: false })}`} - - - - {cleanBackupName(backup)} - - - - {#if backup.status === 'completed'} - {calculateSize(backup.size)} - {:else} - - - {/if} - - - {@const backupStatus = getBackupStatus(backup)} - - - - - - -
- - - {policy?.name || 'Manual'} - - {policy - ? `Retained until: ${formattedRetainedUntil}` - : `Retained forever`} - -
-
- -
- - - - - {#if backup.status === 'completed'} + {#snippet children(root)} + {#each data.backups.archives as backup, index} + {@const policy = getPolicyDetails(backup.policyId)} + {@const retainedUntil = new Date( + new Date(policy?.$createdAt).getTime() + policy?.retention * 24 * 60 * 60 * 1000 + )} + {@const formattedRetainedUntil = `${retainedUntil.getDate()} ${retainedUntil.toLocaleString('en-US', { month: 'short' })}, ${retainedUntil.getFullYear()} ${retainedUntil.toLocaleTimeString('en-US', { hour12: false })}`} + + + + {getCleanBackupName(backup)} + + + + {#if backup.status === 'completed'} + {calculateSize(backup.size)} + {:else} + - + {/if} + + + {@const backupStatus = getBackupStatus(backup)} + + + + + + +
+ + + {policy?.name || 'Manual'} + + {policy + ? `Retained until: ${formattedRetainedUntil}` + : `Retained forever`} + +
+
+ +
+ + + + + {#if backup.status === 'completed'} + { + toggle(e); + showRestore = true; + selectedBackup = backup; + showDropdown[index] = false; + trackEvent(Click.BackupRestoreClick); + }}> + Restore + + {/if} + { + toggle(e); + copy(backup.$id); + showDropdown[index] = false; + trackEvent(Click.BackupCopyIdClick); + }}> + Copy ID + { toggle(e); - showRestore = true; + showDelete = true; selectedBackup = backup; showDropdown[index] = false; - trackEvent(Click.BackupRestoreClick); + trackEvent(Click.BackupDeleteClick); }}> - Restore + Delete - {/if} - { - toggle(e); - copy(backup.$id); - showDropdown[index] = false; - trackEvent(Click.BackupCopyIdClick); - }}> - Copy ID - - { - toggle(e); - showDelete = true; - selectedBackup = backup; - showDropdown[index] = false; - trackEvent(Click.BackupDeleteClick); - }}> - Delete - - - - -
-
-
- {/each} - - -{#if selectedBackups.length > 0} - - - - - {selectedBackups.length > 1 ? 'backups' : 'backup'} - selected - - - - - - - -{/if} +
+
+
+
+
+
+ {/each} + {/snippet} + + + onSubmit={async () => { + if (!selectedBackup) return; + await deleteBackups([selectedBackup.$id]); + }}> - Are you sure you want to delete - {#if selectedBackups.length} - {selectedBackups.length} {selectedBackups.length > 1 ? 'backups' : 'backup'}? - {:else} - the {cleanBackupName(selectedBackup)} backup? - {/if} -
This action is irreversible. + Are you sure you want to delete the {getCleanBackupName(selectedBackup)} backup?
+ + This action is irreversible.
- {cleanBackupName(selectedBackup)} + {getCleanBackupName(selectedBackup)} @@ -374,6 +382,6 @@ - + diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.svelte index ff1c47ff2b..c1290a726a 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.svelte @@ -20,7 +20,7 @@ @@ -398,7 +473,6 @@ - + {#snippet topEndActions()} + {@const rows = $databaseRowSheetOptions.rows ?? []} + {@const currentIndex = $databaseRowSheetOptions.rowIndex ?? -1} + {@const isFirstRow = currentIndex <= 0} + {@const isLastRow = currentIndex >= rows.length - 1} + + {#if !$isTabletViewport} + {@const shouldFocusPrev = !$databaseRowSheetOptions.autoFocus && !isFirstRow} + {@const shouldFocusNext = + !$databaseRowSheetOptions.autoFocus && isFirstRow && !isLastRow} + +
+ +
+ +
+ +
+ {/if} + {/snippet} + + {#key currentRowId} + + {/key}
+ + + + diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+page.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+page.svelte index df77376faa..bc556e3ed7 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+page.svelte @@ -6,7 +6,7 @@ import { Container } from '$lib/layout'; import { preferences } from '$lib/stores/preferences'; import { canWriteTables, canWriteRows } from '$lib/stores/roles'; - import { Icon, Layout, Divider, Tooltip } from '@appwrite.io/pink-svelte'; + import { Icon, Layout, Divider, Tooltip, Typography, Link } from '@appwrite.io/pink-svelte'; import type { PageData } from './$types'; import { table, @@ -26,16 +26,32 @@ import { addNotification } from '$lib/stores/notifications'; import { Click, Submit, trackError, trackEvent } from '$lib/actions/analytics'; import { isSmallViewport } from '$lib/stores/viewport'; - import { IconChevronDown, IconChevronUp, IconPlus } from '@appwrite.io/pink-icons-svelte'; + import { + IconBookOpen, + IconChevronDown, + IconChevronUp, + IconPlus, + IconViewBoards, + IconRefresh + } from '@appwrite.io/pink-icons-svelte'; import type { Models } from '@appwrite.io/console'; import EmptySheet from './layout/emptySheet.svelte'; import CreateRow from './rows/create.svelte'; import { onDestroy } from 'svelte'; import { isCloud } from '$lib/system'; - import { Empty as SuggestionsEmptySheet, tableColumnSuggestions } from '../(suggestions)'; + import { invalidate } from '$app/navigation'; + import { Dependencies } from '$lib/constants'; + import { + Empty as SuggestionsEmptySheet, + tableColumnSuggestions, + showColumnsSuggestionsModal + } from '../(suggestions)'; + import EmptySheetCards from './layout/emptySheetCards.svelte'; + import IconAI from '../(suggestions)/icon/aiForButton.svelte'; export let data: PageData; + let isRefreshing = false; let showImportCSV = false; // todo: might need a type fix here. @@ -83,6 +99,8 @@ $tableColumnSuggestions.table && $tableColumnSuggestions.table.id === page.params.table; + $: disableButton = canShowSuggestionsSheet; + async function onSelect(file: Models.File, localFile = false) { $isCsvImportInProgress = true; @@ -130,7 +148,8 @@ columns={tableColumns} hideView showAnyway - isCustomTable /> + isCustomTable + {disableButton} />
Columns @@ -141,49 +160,84 @@ onlyIcon query={data.query} columns={filterColumns} - disabled={!(hasColumns && hasValidColumns)} + disabled={!(hasColumns && hasValidColumns) || disableButton} analyticsSource="database_tables" /> Filters - - - {#if !$isSmallViewport} + + + {#if !$isSmallViewport} + - - {/if} + + + + + + Refresh + + {/if} + {#if $isSmallViewport} + {/snippet} + {:else} { + customColumns={createTableColumns($table.columns, selected)}> + {#snippet actions()} + { $showRowCreateSheet.show = true; - } - }, - random: { - onClick: () => { + }} /> + + { $randomDataModalState.show = true; - } - } - }} /> + }} /> + {/snippet} + {/if} {:else if isCloud && canShowSuggestionsSheet} - + {:else} - { + + {#snippet subtitle()} + {#if !isCloud} + + + Need a hand? Learn more in the + + docs. + + + {/if} + {/snippet} + + {#snippet actions()} + {#if isCloud} + + { + $showColumnsSuggestionsModal = true; + }} /> + {/if} + + { $showCreateColumnSheet.show = true; - } - }, - random: { - onClick: () => { + }} /> + + { $randomDataModalState.show = true; - } - } - }} /> + }} /> + + {#if isCloud} + + + {/if} + {/snippet} + {/if}
{/key} @@ -282,4 +380,17 @@ width: 32px !important; height: 32px !important; } + + :global(.rotating) { + animation: rotate 1s linear infinite; + } + + @keyframes rotate { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } + } diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/+page.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/+page.svelte index adc70ad97f..08d9192f4a 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/+page.svelte @@ -23,6 +23,7 @@ type ColumnsWidth, indexes, isCsvImportInProgress, + isWaterfallFromFaker, reorderItems, showCreateIndexSheet } from '../store'; @@ -40,7 +41,8 @@ IconTrash, IconViewList, IconLockClosed, - IconFingerPrint + IconFingerPrint, + IconMail } from '@appwrite.io/pink-icons-svelte'; import { type ComponentProps, onDestroy, onMount } from 'svelte'; import { Click, trackEvent } from '$lib/actions/analytics'; @@ -54,6 +56,9 @@ import { page } from '$app/state'; import { debounce } from '$lib/helpers/debounce'; import type { PageData } from './$types'; + import { realtime } from '$lib/stores/sdk'; + import { invalidate } from '$app/navigation'; + import { Dependencies } from '$lib/constants'; const { data @@ -125,7 +130,7 @@ const columnFormatIcon = { ip: IconLocationMarker, url: IconLink, - email: IconLink, + email: IconMail, enum: IconViewList }; @@ -139,6 +144,16 @@ onMount(() => { columnsOrder = preferences.getColumnOrder(tableId); columnsWidth = preferences.getColumnWidths(tableId + '#columns'); + + return realtime.forProject(page.params.region, ['project', 'console'], async (response) => { + if ( + response.events.includes('databases.*.tables.*.columns.*.delete') || + (response.events.includes('databases.*.tables.*.columns.*.update') && + !$isWaterfallFromFaker) + ) { + await invalidate(Dependencies.TABLE); + } + }); }); function getColumnStatusBadge(status: string): ComponentProps['type'] { @@ -248,6 +263,12 @@ minimumWidth: 300, resizable: true }, + { + id: 'type', + width: 150, + minimumWidth: 150, + resizable: false + }, { id: 'indexed', width: getColumnWidth('indexed', 150), @@ -299,8 +320,8 @@ saveColumnsWidth(resize.detail)}> Column name + Type Indexed Default value @@ -315,6 +337,7 @@ {#each updatedColumnsForSheet as column, index (column.key)} + {@const isId = column.key === '$id'} {@const option = columnOptions.find((option) => option.type === column.type)} {@const isSelectable = column['system'] || column.type === 'relationship' ? 'disabled' : true} @@ -359,8 +382,9 @@ {column.key}{column.array ? '[]' : undefined} {/if}
+ {#if isString(column) && column.encrypt} - + Encrypted {/if} -
- + {#if column.status !== 'available'} + + {@const columnType = column['format'] ? column['format'] : column.type} + {columnType.toLowerCase()} + - {@const isActuallyIndexed = $indexes.some((index) => - index.columns.includes(column.key) - )} + + {@const isActuallyIndexed = + isId || $indexes.some((index) => index.columns.includes(column.key))} - {@const checked = isActuallyIndexed || !!columnIndexMap[column.key]} + + {@const checked = isId || isActuallyIndexed || !!columnIndexMap[column.key]} - {@const _default = - column?.default !== null && column?.default !== undefined - ? column?.default - : null} + {@const _default = column.required + ? '-' + : column?.default !== null && column?.default !== undefined + ? column?.default + : null} {#if _default === null} + {:else if isSpatialType(column)} + {JSON.stringify(_default)} {:else} - {isSpatialType(column) ? JSON.stringify(_default) : _default} + {_default} {/if} @@ -452,8 +478,7 @@ - {:else if column.key !== '$sequence'} - + {:else if !isId} + + + + Expand row + + + + + + + + + + + + {:else} + + {#if columnId === '$createdAt' || columnId === '$updatedAt'} + + {:else if columnId === 'actions'} + { + $databaseRowSheetOptions.autoFocus = true; + onSelectSheetOption(option, null, 'row', row); + }} + onVisibilityChanged={(visible) => { + canShowDatetimePopover = !visible; + }}> + {#snippet children(toggle)} + + + + {/snippet} + + {:else if isRelationship(rowColumn)} + {@const args = getDisplayNamesForTable(row[columnId])} + {#if !isRelationshipToMany(rowColumn)} + {#if row[columnId]} + {@const displayValue = args + .map((arg) => row[columnId]?.[arg]) + .filter(Boolean) + .join(' | ')} + + {#if displayValue} + { + $databaseRelatedRowSheetOptions.tableId = + row[columnId]?.['$tableId']; + $databaseRelatedRowSheetOptions.rows = + row[columnId]?.['$id']; + $databaseRelatedRowSheetOptions.show = true; + }}> + {displayValue} + + {:else} + + {/if} {:else} {/if} {:else} - + {@const itemsNum = row[columnId]?.length} + Items {/if} + {:else if isSpatialType(rowColumn) && row[columnId] !== null} + + {JSON.stringify(row[columnId])} + {:else} - {@const itemsNum = row[columnId]?.length} - Items - {/if} - {:else if isSpatialType(rowColumn) && row[columnId] !== null} - - {JSON.stringify(row[columnId])} - - {:else} - {@const value = row[columnId]} - {@const formatted = formatColumn(row[columnId])} - {@const isEmptyArray = formatted === 'Empty'} - {@const isDatetimeAttribute = rowColumn.type === 'datetime'} - {@const isEncryptedAttribute = - isString(rowColumn) && rowColumn.encrypt} - {#if isDatetimeAttribute} - - Timestamp - {toLocaleDateTime(value, true)} - - {:else if isEncryptedAttribute} - - {:else if formatted.length > 20} - + {@const value = row[columnId]} + {@const formatted = formatColumn(row[columnId])} + {@const isEmptyArray = formatted === 'Empty'} + {@const isDatetimeAttribute = rowColumn.type === 'datetime'} + {@const isEncryptedAttribute = + isString(rowColumn) && rowColumn.encrypt} + {#if isDatetimeAttribute} + + Timestamp + {toLocaleDateTime(value, true)} + + {:else if isEncryptedAttribute} + + {:else if formatted.length > 20} + + + {formatted} + + + {formatted} + + + {:else if formatted === 'null'} + + {:else if isEmptyArray} + + {:else} {formatted} - - {formatted} - - - {:else if formatted === 'null'} - - {:else if isEmptyArray} - - {:else} - - {formatted} - + {/if} {/if} - {/if} - - - {@const isRelatedToMany = isRelationshipToMany(rowColumn)} - {@const hasItems = isRelatedToMany - ? row[columnId]?.length - : false} - - paginatedRows.update(index, row)} - onRevert={(row) => paginatedRows.update(index, row)} - openSideSheet={() => { - close(); /* closes the editor */ - - if (isRelationshipToMany(rowColumn)) { - openSideSheetForRelationsToMany( - row[columnId], - rowColumn - ); - } else { - onSelectSheetOption('update', null, 'row', row); - } - }} /> - - + + + {@const isRelatedToMany = isRelationshipToMany(rowColumn)} + {@const hasItems = isRelatedToMany + ? row[columnId]?.length + : false} + + paginatedRows.update(index, row)} + onRevert={(row) => paginatedRows.update(index, row)} + openSideSheet={() => { + close(); /* closes the editor */ + + if (isRelationshipToMany(rowColumn)) { + openSideSheetForRelationsToMany( + row[columnId], + rowColumn + ); + } else { + $databaseRowSheetOptions.autoFocus = true; + onSelectSheetOption('update', null, 'row', row); + } + }} /> + + + {/if} {/each} {/if} @@ -1039,7 +1160,8 @@ gap="xs" direction="row" alignItems="center" - alignContent="center"> + alignContent="center" + class="footer-input-select-wrapper"> Page $page.data.table as Table); export const columns = derived(page, ($page) => $page.data.table.columns as Columns[]); export const indexes = derived(page, ($page) => $page.data.table.indexes as Models.ColumnIndex[]); +/** + * adding a lot of fake data will trigger the realtime below + * and will keep invalidating the `Dependencies.TABLE` making a lot of API noise! + */ +export const isWaterfallFromFaker = writable(false); + export const tableColumns = writable([]); export const isCsvImportInProgress = writable(false); @@ -64,12 +70,18 @@ export const databaseRowSheetOptions = writable< DatabaseSheetOptions & { row: Models.Row; rowId?: string; + rows: Models.Row[]; + rowIndex?: number; + autoFocus?: boolean; } >({ title: null, show: false, row: null, - rowId: null // for loading from a given id + rowId: null, // for loading from a given id + rows: [], + rowIndex: -1, + autoFocus: true }); export const databaseRelatedRowSheetOptions = writable< diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table.svelte index 28e5c2362b..fa19cde37a 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table.svelte @@ -1,110 +1,85 @@ - - + {onDelete}> + {#snippet header(root)} {#each $tableViewColumns as { id, title }} {title} {/each} - - {#each data.tables.tables as table (table.$id)} - - {#each $tableViewColumns as column} - - {#if column.id === '$id'} - {#key $tableViewColumns} - {table.$id} - {/key} - {:else if column.id === 'name'} - {table.name} - {:else} - - {/if} - - {/each} - - {/each} - + {/snippet} -{#if selectedTables.length > 0} - - - - - {selectedTables.length > 1 ? 'tables' : 'table'} - selected - - - - - - - -{/if} - - - - Are you sure you want to delete {selectedTables.length} - {selectedTables.length > 1 ? 'tables' : 'table'}? - - + {#snippet children(root)} + {#each data.tables.tables as table (table.$id)} + + {#each $tableViewColumns as column} + + {#if column.id === '$id'} + {#key $tableViewColumns} + {table.$id} + {/key} + {:else if column.id === 'name'} + {table.name} + {:else} + + {/if} + + {/each} + + {/each} + {/snippet} + diff --git a/src/routes/(console)/project-[region]-[project]/functions/create-function/manual/+page.svelte b/src/routes/(console)/project-[region]-[project]/functions/create-function/manual/+page.svelte index b74bbf60bd..41ca1680e5 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/create-function/manual/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/create-function/manual/+page.svelte @@ -186,27 +186,24 @@ on:invalid={handleInvalid}> - - + + Drag and drop file here or click to upload - - - + justifyContent="center"> + + + Only .tar.gz files allowed + - Only .tar.gz files allowed - + {#if maxSize > 0} - Max file size: {readableMaxSize.value + readableMaxSize.unit} {/if} diff --git a/src/routes/(console)/project-[region]-[project]/functions/create-function/template-[template]/configuration.svelte b/src/routes/(console)/project-[region]-[project]/functions/create-function/template-[template]/configuration.svelte index 34f815e6e3..cd21e5838d 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/create-function/template-[template]/configuration.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/create-function/template-[template]/configuration.svelte @@ -41,8 +41,8 @@ variables.map((variable) => { if (variable.value === '{apiEndpoint}') { - variable.value = getApiEndpoint(); - variable.placeholder = getApiEndpoint(); + variable.value = getApiEndpoint(page.params.region); + variable.placeholder = getApiEndpoint(page.params.region); } else if (variable.value === '{projectId}') { variable.value = page.params.project; variable.placeholder = page.params.project; diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/(components)/deploymentCard.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/(components)/deploymentCard.svelte index 1add28d37b..2376107203 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/(components)/deploymentCard.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/(components)/deploymentCard.svelte @@ -15,6 +15,8 @@ import { DeploymentSource, DeploymentCreatedBy, DeploymentDomains } from '$lib/components/git'; import { func } from '../store'; import { capitalize } from '$lib/helpers/string'; + import { getEffectiveBuildStatus } from '$lib/helpers/buildTimeout'; + import { regionalConsoleVariables } from '$routes/(console)/project-[region]-[project]/store'; import { isCloud } from '$lib/system'; import { IconInfo } from '@appwrite.io/pink-icons-svelte'; import Link from '$lib/elements/link.svelte'; @@ -36,6 +38,9 @@ footer?: Snippet; } = $props(); + let effectiveStatus = $derived( + getEffectiveBuildStatus(deployment.status, deployment.$createdAt, $regionalConsoleVariables) + ); let totalSize = $derived(humanFileSize(deployment?.totalSize ?? 0)); @@ -122,11 +127,11 @@ - {#if deployment.status === 'failed'} + {#if effectiveStatus === 'failed'} {@render titleSnippet('Status')} - + {:else} diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/(components)/downloadActionMenuItem.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/(components)/downloadActionMenuItem.svelte index b91ee6d6f0..85d45bb275 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/(components)/downloadActionMenuItem.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/(components)/downloadActionMenuItem.svelte @@ -2,7 +2,7 @@ import { page } from '$app/state'; import { SubMenu } from '$lib/components/menu'; import { type Models } from '@appwrite.io/console'; - import { IconDownload } from '@appwrite.io/pink-icons-svelte'; + import { IconDownload, IconChevronRight } from '@appwrite.io/pink-icons-svelte'; import { ActionMenu } from '@appwrite.io/pink-svelte'; import { getOutputDownload, getSourceDownload } from '../store'; @@ -13,7 +13,8 @@ {#if deployment?.status === 'ready' || deployment?.status === 'failed' || deployment?.status === 'building'} - Download + Download diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/(modals)/createCli.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/(modals)/createCli.svelte index 566c89ef00..7161846442 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/(modals)/createCli.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/(modals)/createCli.svelte @@ -55,26 +55,26 @@ function setCodeSnippets() { return { Unix: { - code: `appwrite client --projectId="${page.params.project}" && \\ -appwrite functions createDeployment \\ - --functionId=${functionId} \\ + code: `appwrite client --project-id="${page.params.project}" && \\ +appwrite functions create-deployment \\ + --function-id=${functionId} \\ --code="." \\ --activate=true`, language: 'bash' }, CMD: { - code: `appwrite client --projectId="${page.params.project}" && ^ -appwrite functions createDeployment ^ - --functionId=${functionId} ^ + code: `appwrite client --project-id="${page.params.project}" && ^ +appwrite functions create-deployment ^ + --function-id=${functionId} ^ --code="." ^ --activate`, language: 'CMD' }, PowerShell: { - code: `appwrite client --projectId="${page.params.project}" && , -appwrite functions createDeployment , - --functionId=${functionId} , + code: `appwrite client --project-id="${page.params.project}" && , +appwrite functions create-deployment , + --function-id=${functionId} , --code="." , --activate`, language: 'PowerShell' diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/(modals)/deleteModal.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/(modals)/deleteModal.svelte index a8a5d819e6..e913d705b7 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/(modals)/deleteModal.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/(modals)/deleteModal.svelte @@ -1,5 +1,6 @@ - - - Are you sure you want to delete this deployment? - diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/deployment-[deployment]/+page.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/deployment-[deployment]/+page.svelte index 83247cdb2e..9a9b47b2e2 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/deployment-[deployment]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/deployment-[deployment]/+page.svelte @@ -1,7 +1,7 @@ diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/executions/+page.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/executions/+page.svelte index b3f43680e7..55a275d5bb 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/executions/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/executions/+page.svelte @@ -4,7 +4,7 @@ import { Dependencies } from '$lib/constants'; import { Button } from '$lib/elements/forms'; import { Container, ResponsiveContainerHeader } from '$lib/layout'; - import { sdk } from '$lib/stores/sdk'; + import { realtime } from '$lib/stores/sdk'; import { onMount } from 'svelte'; import { project } from '$routes/(console)/project-[region]-[project]/store'; import { base } from '$app/paths'; @@ -12,11 +12,13 @@ import { IconPlus } from '@appwrite.io/pink-icons-svelte'; import Table from './table.svelte'; import { columns } from './store'; + import type { PageProps } from './$types'; + import { page } from '$app/state'; - export let data; + let { data }: PageProps = $props(); onMount(() => { - return sdk.forConsole.client.subscribe('console', (response) => { + return realtime.forConsole(page.params.region, 'console', (response) => { if (response.events.includes('functions.*.executions.*')) { invalidate(Dependencies.EXECUTIONS); } diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/executions/sheet.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/executions/sheet.svelte index 48a313d489..7cddff0bb2 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/executions/sheet.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/executions/sheet.svelte @@ -1,6 +1,7 @@ - - + + {#snippet header(root)} {#each columns as { id, title }} {title} {/each} - - {#each executions.executions as log (log.$id)} - { - e.stopPropagation(); - open = true; - selectedLogId = log.$id; - }}> - {#each columns as column} - - {#if column.id === '$id'} - {#key column.id} - {log.$id} - {/key} - {:else if column.id === 'deploymentId'} - {log.deploymentId} - {:else if column.id === '$createdAt'} - - {:else if column.id === 'requestPath'} - - {log.requestPath} - - {:else if column.id === 'responseStatusCode'} - - {:else if column.id === 'requestMethod'} - - {log.requestMethod} - - {:else if column.id === 'trigger'} - {capitalize(log.trigger)} - {:else if column.id === 'status'} - {@const status = log.status} - -
- - -
- - {`Scheduled to execute on ${toLocaleDateTime(log.scheduledAt)}`} - -
- {:else if column.id === 'duration'} - {#if ['processing', 'waiting'].includes(log.status)} - - {:else} - {calculateTime(log.duration)} + {/snippet} + + {#snippet children(root)} + {#each executions.executions as log (log.$id)} + { + e.stopPropagation(); + open = true; + selectedLogId = log.$id; + }}> + {#each columns as column} + + {#if column.id === '$id'} + {#key column.id} + {log.$id} + {/key} + {:else if column.id === 'deploymentId'} + {log.deploymentId} + {:else if column.id === '$createdAt'} + + {:else if column.id === 'requestPath'} + + {log.requestPath} + + {:else if column.id === 'responseStatusCode'} + + {:else if column.id === 'requestMethod'} + + {log.requestMethod} + + {:else if column.id === 'trigger'} + {capitalize(log.trigger)} + {:else if column.id === 'status'} + {@const status = log.status} + +
+ + +
+ + {`Scheduled to execute on ${toLocaleDateTime(log.scheduledAt)}`} + +
+ {:else if column.id === 'duration'} + {#if ['processing', 'waiting'].includes(log.status)} + + {:else} + {calculateTime(log.duration)} + {/if} {/if} - {/if} -
- {/each} -
- {/each} -
+ + {/each} + + {/each} + {/snippet} + - -{#if selectedRows.length > 0} - - - - - {selectedRows.length > 1 ? 'executions' : 'execution'} - selected - - - - - - - -{/if} - - -

- Are you sure you want to delete {selectedRows.length} - {selectedRows.length > 1 ? 'executions' : 'execution'}? -

- -

This action is irreversible.

-
diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/table.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/table.svelte index eecafbd5a3..7b46acc096 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/table.svelte @@ -1,5 +1,5 @@ - - + {#snippet header(root)} {#each columns as { id, title }} {title} {/each} - - {#each data.deploymentList.deployments as deployment (deployment.$id)} - - {#each columns as column} - - {#if column.id === '$id'} - {#key column.id} - {deployment.$id} - {/key} - {:else if column.id === 'status'} - {@const status = deployment.status} - - {#if data?.activeDeployment?.$id === deployment?.$id} - - {:else} - - {/if} - {:else if column.id === 'type'} - - {:else if column.id === '$updatedAt'} - - {:else if column.id === 'buildDuration'} - {#if ['waiting'].includes(deployment.status)} - - - {:else if ['processing', 'building'].includes(deployment.status)} - - {:else} - {formatTimeDetailed(deployment.buildDuration)} + {/snippet} + {#snippet children(root)} + {#each data.deploymentList.deployments as deployment (deployment.$id)} + {@const effectiveStatus = getEffectiveBuildStatus( + deployment.status, + deployment.$createdAt, + $regionalConsoleVariables + )} + + {#each columns as column} + + {#if column.id === '$id'} + {#key column.id} + {deployment.$id} + {/key} + {:else if column.id === 'status'} + {#if data?.activeDeployment?.$id === deployment?.$id} + + {:else} + + {/if} + {:else if column.id === 'type'} + + {:else if column.id === '$updatedAt'} + + {:else if column.id === 'buildDuration'} + {#if ['waiting'].includes(effectiveStatus)} + - + {:else if ['processing', 'building'].includes(effectiveStatus)} + + {:else} + {formatTimeDetailed(deployment.buildDuration)} + {/if} + {:else if column.id === 'totalSize'} + {calculateSize(deployment.totalSize)} + {:else if column.id === 'sourceSize'} + {calculateSize(deployment.sourceSize)} + {:else if column.id === 'buildSize'} + {calculateSize(deployment.buildSize)} {/if} - {:else if column.id === 'totalSize'} - {calculateSize(deployment.totalSize)} - {:else if column.id === 'sourceSize'} - {calculateSize(deployment.sourceSize)} - {:else if column.id === 'buildSize'} - {calculateSize(deployment.buildSize)} - {/if} - - {/each} - - - - - - - -
+ + {/each} + + + + + + + +
+ { + selectedDeployment = deployment; + showRedeploy = true; + toggle(); + trackEvent(Click.FunctionsRedeployClick); + }} + style="width: 100%"> + Redeploy + +
+
Source is empty
+
+ {#if deployment.status === 'ready' && deployment.$id !== $func.deploymentId} { selectedDeployment = deployment; - showRedeploy = true; + showActivate = true; toggle(); - trackEvent(Click.FunctionsRedeployClick); - }} - style="width: 100%"> - Redeploy + }}> + Activate -
-
Source is empty
-
- {#if deployment.status === 'ready' && deployment.$id !== $func.deploymentId} - { - selectedDeployment = deployment; - showActivate = true; - toggle(); - }}> - Activate - - {/if} + {/if} - + - {#if deployment.status === 'processing' || deployment.status === 'building' || deployment.status === 'waiting'} - { - selectedDeployment = deployment; - toggle(); + {#if effectiveStatus === 'processing' || effectiveStatus === 'building' || effectiveStatus === 'waiting'} + { + selectedDeployment = deployment; + toggle(); - showCancel = true; - trackEvent(Click.FunctionsDeploymentCancelClick); - }}> - Cancel - - {/if} - {#if deployment.status !== 'building' && deployment.status !== 'processing' && deployment.status !== 'waiting'} - { - selectedDeployment = deployment; - toggle(); + showCancel = true; + trackEvent(Click.FunctionsDeploymentCancelClick); + }}> + Cancel + + {/if} + {#if effectiveStatus !== 'building' && effectiveStatus !== 'processing' && effectiveStatus !== 'waiting'} + { + selectedDeployment = deployment; + toggle(); - showDelete = true; - trackEvent(Click.FunctionsDeploymentDeleteClick); - }}> - Delete - - {/if} -
-
-
-
-
- {/each} -
+ showDelete = true; + trackEvent(Click.FunctionsDeploymentDeleteClick); + }}> + Delete + + {/if} +
+
+ + + + {/each} + {/snippet} + + {#snippet deleteContent(count)} +

+ Are you sure you want to delete {count} + {count > 1 ? 'deployments' : 'deployment'} from your function - + {page.data.function.name}? +

+ {/snippet} + {#if selectedDeployment} - + {/if} - -{#if selectedRows.length > 0} - - - - - {selectedRows.length > 1 ? 'deployments' : 'deployment'} - selected - - - - - - - -{/if} - - -

- Are you sure you want to delete {selectedRows.length} - {selectedRows.length > 1 ? 'deployments' : 'deployment'} from your function - - {$func.name}? -

- -

This action is irreversible.

-
diff --git a/src/routes/(console)/project-[region]-[project]/messaging/+page.svelte b/src/routes/(console)/project-[region]-[project]/messaging/+page.svelte index 991d0ba6ca..b096f25618 100644 --- a/src/routes/(console)/project-[region]-[project]/messaging/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/messaging/+page.svelte @@ -1,7 +1,15 @@ - - - + + {#if when === 'later'} + + + + + {/if} {#if when === 'now'} The message will be sent immediately {:else if !dateTime || isNaN(dateTime.getTime())} The message will be sent later {:else} - The message will be sent at {dateTime.toLocaleString('en', formatOptions)} + The message will be sent on {dateTime.toLocaleDateString('en', dateOptions)} at {dateTime.toLocaleTimeString( + 'en', + timeOptions + )} {/if} diff --git a/src/routes/(console)/project-[region]-[project]/messaging/create-[type]/(type)/email.svelte b/src/routes/(console)/project-[region]-[project]/messaging/create-[type]/(type)/email.svelte index 42d352d8e5..ff7c0c9280 100644 --- a/src/routes/(console)/project-[region]-[project]/messaging/create-[type]/(type)/email.svelte +++ b/src/routes/(console)/project-[region]-[project]/messaging/create-[type]/(type)/email.svelte @@ -133,7 +133,7 @@
-
+
diff --git a/src/routes/(console)/project-[region]-[project]/messaging/create-[type]/(type)/push.svelte b/src/routes/(console)/project-[region]-[project]/messaging/create-[type]/(type)/push.svelte index 415504dae1..727e5e7160 100644 --- a/src/routes/(console)/project-[region]-[project]/messaging/create-[type]/(type)/push.svelte +++ b/src/routes/(console)/project-[region]-[project]/messaging/create-[type]/(type)/push.svelte @@ -187,7 +187,7 @@
-
+
diff --git a/src/routes/(console)/project-[region]-[project]/messaging/create-[type]/(type)/sms.svelte b/src/routes/(console)/project-[region]-[project]/messaging/create-[type]/(type)/sms.svelte index a1f88d7a3c..102c20196c 100644 --- a/src/routes/(console)/project-[region]-[project]/messaging/create-[type]/(type)/sms.svelte +++ b/src/routes/(console)/project-[region]-[project]/messaging/create-[type]/(type)/sms.svelte @@ -115,7 +115,7 @@
-
+
diff --git a/src/routes/(console)/project-[region]-[project]/messaging/createMessageDropdown.svelte b/src/routes/(console)/project-[region]-[project]/messaging/createMessageDropdown.svelte index 49e018a16f..e91f92669d 100644 --- a/src/routes/(console)/project-[region]-[project]/messaging/createMessageDropdown.svelte +++ b/src/routes/(console)/project-[region]-[project]/messaging/createMessageDropdown.svelte @@ -7,7 +7,7 @@ import { page } from '$app/state'; - + + external>documentation. diff --git a/src/routes/(console)/project-[region]-[project]/messaging/provider.svelte b/src/routes/(console)/project-[region]-[project]/messaging/provider.svelte index 425f0d1155..3990feca9a 100644 --- a/src/routes/(console)/project-[region]-[project]/messaging/provider.svelte +++ b/src/routes/(console)/project-[region]-[project]/messaging/provider.svelte @@ -7,6 +7,7 @@ Vonage = 'vonage', Mailgun = 'mailgun', Sendgrid = 'sendgrid', + Resend = 'resend', SMTP = 'smtp', FCM = 'fcm', APNS = 'apns' @@ -31,6 +32,9 @@ case Providers.Mailgun: icon = 'mailgun'; break; + case Providers.Resend: + icon = 'resend'; + break; case Providers.SMTP: icon = 'smtp'; displayName = 'SMTP'; diff --git a/src/routes/(console)/project-[region]-[project]/messaging/providers/+page.svelte b/src/routes/(console)/project-[region]-[project]/messaging/providers/+page.svelte index 85b132238d..cc80b73af9 100644 --- a/src/routes/(console)/project-[region]-[project]/messaging/providers/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/messaging/providers/+page.svelte @@ -1,45 +1,40 @@ - - - - - - - - {#if $canWriteProviders} - - - - {/if} - - + + {#if $canWriteProviders} + + + + {/if} + {#if data.providers.total} @@ -52,11 +47,7 @@ {:else if $hasPageQueries} {:else if data.search && data.search !== 'empty'} - -
- Sorry, we couldn't find '{data.search}' -

There are no providers that match your search.

-
+ - @@ -227,7 +240,9 @@ hasDivider href={`https://appwrite.io/docs/products/messaging/${$provider}`} title="Read the guide in the docs" - icon={IconBookOpen} /> + icon={IconBookOpen} + target="_blank" + rel="noreferrer" /> { $newMemberModal = true; @@ -241,4 +256,9 @@ {#if $newMemberModal} {/if} + + + + + diff --git a/src/routes/(console)/project-[region]-[project]/messaging/providers/createProviderDropdown.svelte b/src/routes/(console)/project-[region]-[project]/messaging/providers/createProviderDropdown.svelte index ea8f548396..b210dc61b8 100644 --- a/src/routes/(console)/project-[region]-[project]/messaging/providers/createProviderDropdown.svelte +++ b/src/routes/(console)/project-[region]-[project]/messaging/providers/createProviderDropdown.svelte @@ -9,7 +9,7 @@ import { ActionMenu, Popover } from '@appwrite.io/pink-svelte'; - + {#each Object.entries(providers) as [type, option]} diff --git a/src/routes/(console)/project-[region]-[project]/messaging/providers/popoverContent.svelte b/src/routes/(console)/project-[region]-[project]/messaging/providers/popoverContent.svelte index 7b9a1e7239..ea0f6e2705 100644 --- a/src/routes/(console)/project-[region]-[project]/messaging/providers/popoverContent.svelte +++ b/src/routes/(console)/project-[region]-[project]/messaging/providers/popoverContent.svelte @@ -1,30 +1,25 @@ -
+ {#each lines as line} -

{@html line}

+

{@html line}

{/each} {#if image} - + + + {/if} -
+ diff --git a/src/routes/(console)/project-[region]-[project]/overview/assets/platform-sdk-dark.png b/src/routes/(console)/project-[region]-[project]/overview/assets/platform-sdk-dark.png new file mode 100644 index 0000000000..e778c55b9e Binary files /dev/null and b/src/routes/(console)/project-[region]-[project]/overview/assets/platform-sdk-dark.png differ diff --git a/src/routes/(console)/project-[region]-[project]/overview/assets/platform-sdk.jpg b/src/routes/(console)/project-[region]-[project]/overview/assets/platform-sdk.jpg new file mode 100644 index 0000000000..b891d6a12c Binary files /dev/null and b/src/routes/(console)/project-[region]-[project]/overview/assets/platform-sdk.jpg differ diff --git a/src/routes/(console)/project-[region]-[project]/overview/header.svelte b/src/routes/(console)/project-[region]-[project]/overview/header.svelte index c9271df9d7..6892c55110 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/header.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/header.svelte @@ -2,7 +2,7 @@ import { page } from '$app/state'; import { Id, RegionEndpoint } from '$lib/components'; import { Cover } from '$lib/layout'; - import { project, projectRegion } from '../store'; + import { projectRegion } from '../store'; import { hasOnboardingDismissed, setHasOnboardingDismissed } from '$lib/helpers/onboarding'; import { goto } from '$app/navigation'; import { Layout, Button, Typography } from '@appwrite.io/pink-svelte'; @@ -11,10 +11,13 @@ import { trackEvent } from '$lib/actions/analytics'; import { resolvedProfile } from '$lib/profiles/index.svelte'; + const region = $derived(page.params.region); + const project = $derived(page.params.project); + function dismissOnboarding() { - setHasOnboardingDismissed($project.$id, $user); + setHasOnboardingDismissed(project, $user); trackEvent('onboarding_hub_platform_dismiss'); - goto(resolvedProfile.getProjectRoute({ region: $project.region, project: $project.$id })); + goto(resolvedProfile.getProjectRoute({ region, project })); } @@ -24,12 +27,14 @@ - {$project?.name} + {page.data.project?.name} - {$project.$id} - + {project} + {#if $projectRegion} + + {/if}
@@ -53,7 +58,7 @@ >Follow a few quick steps to get started with {resolvedProfile.platform}
- {#if !hasOnboardingDismissed($project.$id, $user)} + {#if !hasOnboardingDismissed(project, $user)} Dismiss this page diff --git a/src/routes/(console)/project-[region]-[project]/overview/onboard.svelte b/src/routes/(console)/project-[region]-[project]/overview/onboard.svelte index b2291391f2..c2db43d7b8 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/onboard.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/onboard.svelte @@ -14,12 +14,7 @@ import { app } from '$lib/stores/app'; import AuthPreview from './assets/auth-preview.svg'; import AuthPreviewDark from './assets/auth-preview-dark.svg'; - import { - IconArrowRight, - IconNodeJs, - IconPhp, - IconPython - } from '@appwrite.io/pink-icons-svelte'; + import { IconArrowRight } from '@appwrite.io/pink-icons-svelte'; import DatabaseImgSource from './assets/database.png'; import DatabaseImgSourceDark from './assets/database-dark.png'; import DiscordImgSource from './assets/discord.png'; @@ -31,9 +26,10 @@ import PlatformAndroidImgSourceDark from './assets/platform-android-dark.svg'; import PlatformFlutterImgSource from './assets/platform-flutter.svg'; import PlatformFlutterImgSourceDark from './assets/platform-flutter-dark.svg'; + import PlatformSdkImgSource from './assets/platform-sdk.jpg'; + import PlatformSdkImgSourceDark from './assets/platform-sdk-dark.png'; import { base } from '$app/paths'; import { isSmallViewport } from '$lib/stores/viewport'; - import { AvatarGroup } from '$lib/components'; import type { Models } from '@appwrite.io/console'; import { getPlatformInfo } from '$lib/helpers/platform'; import { Click, trackEvent } from '$lib/actions/analytics'; @@ -41,6 +37,9 @@ import { page } from '$app/state'; import { resolvedProfile } from '$lib/profiles/index.svelte'; + export let pingCount = 0; + export let platforms: Models.Platform[] = []; + function createKey() { trackEvent(Click.KeyCreateClick, { source: 'onboarding' @@ -53,9 +52,6 @@ ); } - export let platforms: Models.Platform[] = []; - export let pingCount = 0; - function openPlatformWizard(type: number, platform?: Models.Platform) { if (platform) { continuePlatform(type, platform.name, platform.key, platform.type); @@ -104,7 +100,9 @@
- + { openPlatformWizard(0, platformMap.get('Web')); @@ -342,17 +340,34 @@ - - Or connect - server side -
- -
-
+ or + + + +
+ + + Create API key + Connect your server or backend to Appwrite + +
+ +
+
+
+
+
+ import { SvgIcon } from '$lib/components'; + + + diff --git a/src/routes/(console)/project-[region]-[project]/overview/platforms/components/index.ts b/src/routes/(console)/project-[region]-[project]/overview/platforms/components/index.ts index 32e9fc210c..ae805a26e5 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/components/index.ts +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/components/index.ts @@ -4,6 +4,7 @@ export { default as JavascriptFrameworkIcon } from './JavascriptFrameworkIcon.sv export { default as NextjsFrameworkIcon } from './NextjsFrameworkIcon.svelte'; export { default as NoFrameworkIcon } from './NoFrameworkIcon.svelte'; export { default as NuxtFrameworkIcon } from './NuxtFrameworkIcon.svelte'; +export { default as TanStackFrameworkIcon } from './TanStackFrameworkIcon.svelte'; export { default as ReactFrameworkIcon } from './ReactFrameworkIcon.svelte'; export { default as SvelteFrameworkIcon } from './SvelteFrameworkIcon.svelte'; export { default as VueFrameworkIcon } from './VueFrameworkIcon.svelte'; diff --git a/src/routes/(console)/project-[region]-[project]/overview/platforms/createAndroid.svelte b/src/routes/(console)/project-[region]-[project]/overview/platforms/createAndroid.svelte index e5aba6c424..9ad7963e11 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/createAndroid.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/createAndroid.svelte @@ -17,7 +17,7 @@ import { Card } from '$lib/components'; import { page } from '$app/state'; import { onMount } from 'svelte'; - import { sdk } from '$lib/stores/sdk'; + import { realtime, sdk } from '$lib/stores/sdk'; import { Submit, trackError, trackEvent } from '$lib/actions/analytics'; import { addNotification } from '$lib/stores/notifications'; import { fade } from 'svelte/transition'; @@ -25,11 +25,15 @@ import OnboardingPlatformCard from './components/OnboardingPlatformCard.svelte'; import { PlatformType } from '@appwrite.io/console'; import { project } from '../../store'; + import { getCorrectTitle, type PlatformProps } from './store'; + + let { isConnectPlatform = false }: PlatformProps = $props(); + + let showExitModal = $state(false); + let isCreatingPlatform = $state(false); + let connectionSuccessful = $state(false); + let isPlatformCreated = $state(isConnectPlatform); - let showExitModal = false; - let isPlatformCreated = false; - let isCreatingPlatform = false; - let connectionSuccessful = false; const projectId = page.params.project; const gitCloneCode = @@ -59,8 +63,10 @@ const val APPWRITE_PUBLIC_ENDPOINT = "${sdk.forProject(page.params.region, page. message: 'Platform created.' }); - invalidate(Dependencies.PROJECT); - invalidate(Dependencies.PLATFORMS); + await Promise.all([ + invalidate(Dependencies.PROJECT), + invalidate(Dependencies.PLATFORMS) + ]); } catch (error) { trackError(error, Submit.PlatformCreate); addNotification({ @@ -77,7 +83,7 @@ const val APPWRITE_PUBLIC_ENDPOINT = "${sdk.forProject(page.params.region, page. } onMount(() => { - const unsubscribe = sdk.forConsole.client.subscribe('console', (response) => { + const unsubscribe = realtime.forConsole(page.params.region, 'console', (response) => { if (response.events.includes(`projects.${projectId}.ping`)) { connectionSuccessful = true; invalidate(Dependencies.ORGANIZATION); @@ -93,7 +99,10 @@ const val APPWRITE_PUBLIC_ENDPOINT = "${sdk.forProject(page.params.region, page. }); - + {#if !isPlatformCreated} diff --git a/src/routes/(console)/project-[region]-[project]/overview/platforms/createApple.svelte b/src/routes/(console)/project-[region]-[project]/overview/platforms/createApple.svelte index d830134974..7c1ae8ee67 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/createApple.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/createApple.svelte @@ -18,7 +18,7 @@ import { Card } from '$lib/components'; import { page } from '$app/state'; import { onMount } from 'svelte'; - import { sdk } from '$lib/stores/sdk'; + import { realtime, sdk } from '$lib/stores/sdk'; import { Submit, trackError, trackEvent } from '$lib/actions/analytics'; import { addNotification } from '$lib/stores/notifications'; import { fade } from 'svelte/transition'; @@ -27,11 +27,15 @@ import { PlatformType } from '@appwrite.io/console'; import { app } from '$lib/stores/app'; import { project } from '../../store'; + import { getCorrectTitle, type PlatformProps } from './store'; + + let { isConnectPlatform = false, platform = PlatformType.Appleios }: PlatformProps = $props(); + + let showExitModal = $state(false); + let isCreatingPlatform = $state(false); + let connectionSuccessful = $state(false); + let isPlatformCreated = $state(isConnectPlatform); - let showExitModal = false; - let isPlatformCreated = false; - let isCreatingPlatform = false; - let connectionSuccessful = false; const projectId = page.params.project; const gitCloneCode = @@ -41,8 +45,6 @@ APPWRITE_PROJECT_NAME: "${$project.name}" APPWRITE_PUBLIC_ENDPOINT: "${sdk.forProject(page.params.region, page.params.project).client.config.endpoint}"`; - export let platform: PlatformType = PlatformType.Appleios; - let platforms: { [key: string]: PlatformType } = { iOS: PlatformType.Appleios, macOS: PlatformType.Applemacos, @@ -70,8 +72,10 @@ APPWRITE_PUBLIC_ENDPOINT: "${sdk.forProject(page.params.region, page.params.proj message: 'Platform created.' }); - invalidate(Dependencies.PROJECT); - invalidate(Dependencies.PLATFORMS); + await Promise.all([ + invalidate(Dependencies.PROJECT), + invalidate(Dependencies.PLATFORMS) + ]); } catch (error) { trackError(error, Submit.PlatformCreate); addNotification({ @@ -88,7 +92,7 @@ APPWRITE_PUBLIC_ENDPOINT: "${sdk.forProject(page.params.region, page.params.proj } onMount(() => { - const unsubscribe = sdk.forConsole.client.subscribe('console', (response) => { + const unsubscribe = realtime.forConsole(page.params.region, 'console', (response) => { if (response.events.includes(`projects.${projectId}.ping`)) { connectionSuccessful = true; invalidate(Dependencies.ORGANIZATION); @@ -104,7 +108,10 @@ APPWRITE_PUBLIC_ENDPOINT: "${sdk.forProject(page.params.region, page.params.proj }); - +
diff --git a/src/routes/(console)/project-[region]-[project]/overview/platforms/createFlutter.svelte b/src/routes/(console)/project-[region]-[project]/overview/platforms/createFlutter.svelte index 096d56e20a..f6ab670f65 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/createFlutter.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/createFlutter.svelte @@ -18,7 +18,7 @@ import { Card } from '$lib/components'; import { page } from '$app/state'; import { onMount } from 'svelte'; - import { sdk } from '$lib/stores/sdk'; + import { realtime, sdk } from '$lib/stores/sdk'; import { Submit, trackError, trackEvent } from '$lib/actions/analytics'; import { addNotification } from '$lib/stores/notifications'; import { fade } from 'svelte/transition'; @@ -27,11 +27,16 @@ import { PlatformType } from '@appwrite.io/console'; import { project } from '../../store'; import { resolvedProfile } from '$lib/profiles/index.svelte'; + import { getCorrectTitle, type PlatformProps } from './store'; + + let { isConnectPlatform = false, platform = PlatformType.Flutterandroid }: PlatformProps = + $props(); + + let showExitModal = $state(false); + let isCreatingPlatform = $state(false); + let connectionSuccessful = $state(false); + let isPlatformCreated = $state(isConnectPlatform); - let showExitModal = false; - let isPlatformCreated = false; - let isCreatingPlatform = false; - let connectionSuccessful = false; const projectId = page.params.project; const gitCloneCode = @@ -43,8 +48,6 @@ static const String appwritePublicEndpoint = '${sdk.forProject(page.params.region, page.params.project).client.config.endpoint}'; }`; - export let platform: PlatformType = PlatformType.Flutterandroid; - let platforms: { [key: string]: PlatformType } = { Android: PlatformType.Flutterandroid, iOS: PlatformType.Flutterios, @@ -135,8 +138,10 @@ message: 'Platform created.' }); - invalidate(Dependencies.PROJECT); - invalidate(Dependencies.PLATFORMS); + await Promise.all([ + invalidate(Dependencies.PROJECT), + invalidate(Dependencies.PLATFORMS) + ]); } catch (error) { trackError(error, Submit.PlatformCreate); addNotification({ @@ -153,7 +158,7 @@ } onMount(() => { - const unsubscribe = sdk.forConsole.client.subscribe('console', (response) => { + const unsubscribe = realtime.forConsole(page.params.region, 'console', (response) => { if (response.events.includes(`projects.${projectId}.ping`)) { connectionSuccessful = true; invalidate(Dependencies.ORGANIZATION); @@ -169,7 +174,10 @@ }); - + diff --git a/src/routes/(console)/project-[region]-[project]/overview/platforms/createReactNative.svelte b/src/routes/(console)/project-[region]-[project]/overview/platforms/createReactNative.svelte index cf03dd98b2..74924c8191 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/createReactNative.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/createReactNative.svelte @@ -18,7 +18,7 @@ import { Card } from '$lib/components'; import { page } from '$app/state'; import { onMount } from 'svelte'; - import { sdk } from '$lib/stores/sdk'; + import { realtime, sdk } from '$lib/stores/sdk'; import { Submit, trackError, trackEvent } from '$lib/actions/analytics'; import { addNotification } from '$lib/stores/notifications'; import { fade } from 'svelte/transition'; @@ -27,11 +27,16 @@ import { PlatformType } from '@appwrite.io/console'; import { project } from '../../store'; import { resolvedProfile } from '$lib/profiles/index.svelte'; + import { getCorrectTitle, type PlatformProps } from './store'; + + let { isConnectPlatform = false, platform = PlatformType.Reactnativeandroid }: PlatformProps = + $props(); + + let showExitModal = $state(false); + let isCreatingPlatform = $state(false); + let connectionSuccessful = $state(false); + let isPlatformCreated = $state(isConnectPlatform); - let showExitModal = false; - let isPlatformCreated = false; - let isCreatingPlatform = false; - let connectionSuccessful = false; const projectId = page.params.project; const gitCloneCode = @@ -41,8 +46,6 @@ EXPO_PUBLIC_APPWRITE_PROJECT_NAME="${$project.name}" EXPO_PUBLIC_APPWRITE_ENDPOINT=${sdk.forProject(page.params.region, page.params.project).client.config.endpoint}`; - export let platform: PlatformType = PlatformType.Reactnativeandroid; - let platforms: { [key: string]: PlatformType } = { Android: PlatformType.Reactnativeandroid, iOS: PlatformType.Reactnativeios @@ -97,8 +100,10 @@ EXPO_PUBLIC_APPWRITE_ENDPOINT=${sdk.forProject(page.params.region, page.params.p message: 'Platform created.' }); - invalidate(Dependencies.PROJECT); - invalidate(Dependencies.PLATFORMS); + await Promise.all([ + invalidate(Dependencies.PROJECT), + invalidate(Dependencies.PLATFORMS) + ]); } catch (error) { trackError(error, Submit.PlatformCreate); addNotification({ @@ -115,7 +120,7 @@ EXPO_PUBLIC_APPWRITE_ENDPOINT=${sdk.forProject(page.params.region, page.params.p } onMount(() => { - const unsubscribe = sdk.forConsole.client.subscribe('console', (response) => { + const unsubscribe = realtime.forConsole(page.params.region, 'console', (response) => { if (response.events.includes(`projects.${projectId}.ping`)) { connectionSuccessful = true; invalidate(Dependencies.ORGANIZATION); @@ -131,7 +136,10 @@ EXPO_PUBLIC_APPWRITE_ENDPOINT=${sdk.forProject(page.params.region, page.params.p }); - + diff --git a/src/routes/(console)/project-[region]-[project]/overview/platforms/createWeb.svelte b/src/routes/(console)/project-[region]-[project]/overview/platforms/createWeb.svelte index 92987eebd9..7189813fbd 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/createWeb.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/createWeb.svelte @@ -20,14 +20,15 @@ IconSvelte, IconReact, IconNuxt, + IconTanstack, IconInfo, IconExternalLink, IconAngular, IconJs } from '@appwrite.io/pink-icons-svelte'; import { page } from '$app/state'; - import { type ComponentType, onMount } from 'svelte'; - import { sdk } from '$lib/stores/sdk'; + import { onMount } from 'svelte'; + import { realtime, sdk } from '$lib/stores/sdk'; import { Submit, trackError, trackEvent } from '$lib/actions/analytics'; import { addNotification } from '$lib/stores/notifications'; import { fade } from 'svelte/transition'; @@ -38,6 +39,7 @@ ReactFrameworkIcon, SvelteFrameworkIcon, NuxtFrameworkIcon, + TanStackFrameworkIcon, NextjsFrameworkIcon, VueFrameworkIcon, NoFrameworkIcon, @@ -47,14 +49,15 @@ import { extendedHostnameRegex } from '$lib/helpers/string'; import { project } from '../../store'; import { resolvedProfile } from '$lib/profiles/index.svelte'; + import { type PlatformProps, type FrameworkType, getCorrectTitle } from './store'; - export let key; + let { key, isConnectPlatform = false, platform = PlatformType.Web }: PlatformProps = $props(); - let showExitModal = false; - let isPlatformCreated = !!key; - let isCreatingPlatform = false; - let connectionSuccessful = false; - let isChangingFramework = false; + let showExitModal = $state(false); + let isCreatingPlatform = $state(false); + let connectionSuccessful = $state(false); + let isChangingFramework = $state(false); + let isPlatformCreated = $state(isConnectPlatform); const projectId = page.params.project; @@ -62,19 +65,9 @@ ${prefix}APPWRITE_PROJECT_NAME = "${$project.name}" ${prefix}APPWRITE_ENDPOINT = "${sdk.forProject(page.params.region, page.params.project).client.config.endpoint}" `; - type FrameworkType = { - key: string; - label: string; - icon: ComponentType; - smallIcon: ComponentType; - portNumber: number; - runCommand: string; - updateConfigCode: string; - }; - export let platform: PlatformType = PlatformType.Flutterandroid; - export let selectedFrameworkKey: string | undefined = key ? key : undefined; - let hostname; - let hostnameError = false; + + let hostname = $state(null); + let hostnameError = $state(false); let frameworks: Array = [ { @@ -139,6 +132,15 @@ ${prefix}APPWRITE_ENDPOINT = "${sdk.forProject(page.params.region, page.params.p appwriteProjectName: '${$project.name}' };` }, + { + key: 'tanstack-start', + label: 'TanStack Start', + icon: TanStackFrameworkIcon, + smallIcon: IconTanstack, + portNumber: 3000, + runCommand: 'npm run dev', + updateConfigCode: updateConfigCode('VITE_') + }, { key: 'js', label: 'JavaScript', @@ -150,11 +152,16 @@ ${prefix}APPWRITE_ENDPOINT = "${sdk.forProject(page.params.region, page.params.p } ]; - $: selectedFramework = frameworks.find((framework) => framework.key === selectedFrameworkKey); - $: selectedFrameworkIcon = selectedFramework ? selectedFramework.icon : NoFrameworkIcon; + const selectedFramework = $derived(frameworks.find((framework) => framework.key === key)); + + const selectedFrameworkIcon = $derived( + selectedFramework ? selectedFramework.icon : NoFrameworkIcon + ); async function createWebPlatform() { - hostnameError = hostname !== '' ? !new RegExp(extendedHostnameRegex).test(hostname) : null; + const hostnameRegex = new RegExp(extendedHostnameRegex); + const finalHostname = hostname?.trim() || 'localhost'; + hostnameError = !hostnameRegex.test(finalHostname); if (hostnameError) { return; @@ -166,8 +173,8 @@ ${prefix}APPWRITE_ENDPOINT = "${sdk.forProject(page.params.region, page.params.p projectId, type: PlatformType.Web, name: `${selectedFramework.label} app`, - key: selectedFrameworkKey, - hostname: hostname === '' ? undefined : hostname + key: key, + hostname: finalHostname }); isPlatformCreated = true; @@ -180,8 +187,10 @@ ${prefix}APPWRITE_ENDPOINT = "${sdk.forProject(page.params.region, page.params.p message: 'Platform created.' }); - invalidate(Dependencies.PROJECT); - invalidate(Dependencies.PLATFORMS); + await Promise.all([ + invalidate(Dependencies.PROJECT), + invalidate(Dependencies.PLATFORMS) + ]); } catch (error) { trackError(error, Submit.PlatformCreate); addNotification({ @@ -198,7 +207,7 @@ ${prefix}APPWRITE_ENDPOINT = "${sdk.forProject(page.params.region, page.params.p } onMount(() => { - const unsubscribe = sdk.forConsole.client.subscribe('console', (response) => { + const unsubscribe = realtime.forConsole(page.params.region, 'console', (response) => { if (response.events.includes(`projects.${projectId}.ping`)) { connectionSuccessful = true; invalidate(Dependencies.ORGANIZATION); @@ -214,7 +223,10 @@ ${prefix}APPWRITE_ENDPOINT = "${sdk.forProject(page.params.region, page.params.p }); - + {#if !isPlatformCreated || isChangingFramework} @@ -225,7 +237,7 @@ ${prefix}APPWRITE_ENDPOINT = "${sdk.forProject(page.params.region, page.params.p
{#each frameworks as framework} @@ -278,6 +291,7 @@ ${prefix}APPWRITE_ENDPOINT = "${sdk.forProject(page.params.region, page.params.p diff --git a/src/routes/(console)/project-[region]-[project]/overview/platforms/store.ts b/src/routes/(console)/project-[region]-[project]/overview/platforms/store.ts new file mode 100644 index 0000000000..d0b7956439 --- /dev/null +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/store.ts @@ -0,0 +1,22 @@ +import type { ComponentType } from 'svelte'; +import { PlatformType } from '@appwrite.io/console'; + +export type PlatformProps = { + key?: string; + platform?: PlatformType; + isConnectPlatform: boolean; +}; + +export type FrameworkType = { + key: string; + label: string; + icon: ComponentType; + smallIcon: ComponentType; + portNumber: number; + runCommand: string; + updateConfigCode: string; +}; + +export function getCorrectTitle(isConnectPlatform: boolean, platform: string) { + return isConnectPlatform ? `Connect your ${platform} app` : `Add ${platform} platform`; +} diff --git a/src/routes/(console)/project-[region]-[project]/settings/migrations/+page.svelte b/src/routes/(console)/project-[region]-[project]/settings/migrations/+page.svelte index a951f77714..3d91781c2a 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/migrations/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/migrations/+page.svelte @@ -39,13 +39,11 @@ let migration: Models.Migration = null; onMount(() => { - return realtime - .forProject(page.params.region, page.params.project) - .subscribe(['project', 'console'], (response) => { - if (response.events.includes('migrations.*')) { - invalidate(Dependencies.MIGRATIONS); - } - }); + return realtime.forProject(page.params.region, ['project', 'console'], (response) => { + if (response.events.includes('migrations.*')) { + invalidate(Dependencies.MIGRATIONS); + } + }); }); $: $registerCommands([ diff --git a/src/routes/(console)/project-[region]-[project]/settings/usage/[[invoice]]/+page.svelte b/src/routes/(console)/project-[region]-[project]/settings/usage/[[invoice]]/+page.svelte index 31fc890179..76d4d5e1e2 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/usage/[[invoice]]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/usage/[[invoice]]/+page.svelte @@ -10,7 +10,7 @@ import { total } from '$lib/layout/usage.svelte'; import { BillingPlan } from '$lib/constants.js'; import { base } from '$app/paths'; - import { formatCurrency, formatNumberWithCommas } from '$lib/helpers/numbers'; + import { formatCurrency, formatNumberWithCommas, clampMin } from '$lib/helpers/numbers'; import { getCountryName } from '$lib/helpers/diallingCodes.js'; import { Accordion, Icon, Layout, Link, Table, Typography } from '@appwrite.io/pink-svelte'; import { IconChartSquareBar } from '@appwrite.io/pink-icons-svelte'; @@ -36,11 +36,11 @@ $: legendData = [ { name: 'Reads', - value: data.usage.databasesReads.reduce((sum, item) => sum + item.value, 0) + value: clampMin(data.usage.databasesReads.reduce((sum, item) => sum + item.value, 0)) }, { name: 'Writes', - value: data.usage.databasesWrites.reduce((sum, item) => sum + item.value, 0) + value: clampMin(data.usage.databasesWrites.reduce((sum, item) => sum + item.value, 0)) } ]; diff --git a/src/routes/(console)/project-[region]-[project]/sites/(components)/deploymentActionMenu.svelte b/src/routes/(console)/project-[region]-[project]/sites/(components)/deploymentActionMenu.svelte index b3d988be73..231611a161 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/(components)/deploymentActionMenu.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/(components)/deploymentActionMenu.svelte @@ -15,6 +15,8 @@ IconXCircle } from '@appwrite.io/pink-icons-svelte'; import { ActionMenu, Icon, Tooltip } from '@appwrite.io/pink-svelte'; + import { getEffectiveBuildStatus } from '$lib/helpers/buildTimeout'; + import { regionalConsoleVariables } from '$routes/(console)/project-[region]-[project]/store'; export let selectedDeployment: Models.Deployment; export let deployment: Models.Deployment; @@ -51,6 +53,11 @@ + {@const effectiveStatus = getEffectiveBuildStatus( + deployment.status, + deployment.$createdAt, + $regionalConsoleVariables + )} {#if !inCard}
@@ -70,7 +77,7 @@
Source is empty
{/if} - {#if deployment?.status === 'ready' && deployment?.$id !== activeDeployment} + {#if effectiveStatus === 'ready' && deployment?.$id !== activeDeployment} { @@ -82,7 +89,7 @@ Activate {/if} - {#if deployment?.status === 'ready' || deployment?.status === 'failed' || deployment?.status === 'building'} + {#if effectiveStatus === 'ready' || effectiveStatus === 'failed' || effectiveStatus === 'building'} @@ -112,7 +119,7 @@ {/if} - {#if deployment?.status === 'processing' || deployment?.status === 'building' || deployment.status === 'waiting'} + {#if effectiveStatus === 'processing' || effectiveStatus === 'building' || effectiveStatus === 'waiting'} {/if} - {#if deployment.status !== 'building' && deployment.status !== 'processing' && deployment?.status !== 'waiting'} + {#if ['ready', 'failed'].includes(deployment.status)} import { capitalize } from '$lib/helpers/string'; import { app } from '$lib/stores/app'; + import { getEffectiveBuildStatus } from '$lib/helpers/buildTimeout'; + import { regionalConsoleVariables } from '$routes/(console)/project-[region]-[project]/store'; import type { Models } from '@appwrite.io/console'; import { Badge, Card, Layout, Logs, Spinner, Typography } from '@appwrite.io/pink-svelte'; import LogsTimer from './logsTimer.svelte'; @@ -38,15 +40,19 @@ emptyCopy?: string; } = $props(); + let effectiveStatus = $derived( + getEffectiveBuildStatus(deployment.status, deployment.$createdAt, $regionalConsoleVariables) + ); + function setCopy() { - if (deployment.status === 'failed') { + if (effectiveStatus === 'failed') { return 'Your deployment has failed.'; - } else if (deployment.status === 'building') { + } else if (effectiveStatus === 'building') { //Do not remove empty space before the string it's an invisible character return 'Preparing for build ... \n'; - } else if (deployment.status === 'waiting') { + } else if (effectiveStatus === 'waiting') { return 'Preparing for build ... \n'; - } else if (deployment.status === 'processing') { + } else if (effectiveStatus === 'processing') { return 'Preparing for build ... \n'; } else { return emptyCopy; @@ -62,16 +68,16 @@ Deployment logs + type={badgeTypeDeployment(effectiveStatus)} /> - + {/if} - {#if ['waiting', 'processing'].includes(deployment.status) || (deployment.status === 'building' && !deployment?.buildLogs?.length)} + {#if ['waiting', 'processing'].includes(effectiveStatus) || (effectiveStatus === 'building' && !deployment?.buildLogs?.length)} Waiting for build to start... diff --git a/src/routes/(console)/project-[region]-[project]/sites/(components)/logsTimer.svelte b/src/routes/(console)/project-[region]-[project]/sites/(components)/logsTimer.svelte index 204ce91ec1..47bc28da3f 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/(components)/logsTimer.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/(components)/logsTimer.svelte @@ -1,16 +1,21 @@ - {#if ['processing', 'building'].includes(status)} + {#if ['processing', 'building'].includes(effectiveStatus)}

diff --git a/src/routes/(console)/project-[region]-[project]/sites/(components)/siteCard.svelte b/src/routes/(console)/project-[region]-[project]/sites/(components)/siteCard.svelte index 95562c0add..78ad644f49 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/(components)/siteCard.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/(components)/siteCard.svelte @@ -23,15 +23,40 @@ import { isCloud } from '$lib/system'; import { sdk } from '$lib/stores/sdk'; import { capitalize } from '$lib/helpers/string'; + import { getEffectiveBuildStatus } from '$lib/helpers/buildTimeout'; + import { regionalConsoleVariables } from '$routes/(console)/project-[region]-[project]/store'; + import { regionalProtocol } from '$routes/(console)/project-[region]-[project]/store'; + import type { Snippet } from 'svelte'; - export let deployment: Models.Deployment; - export let proxyRuleList: Models.ProxyRuleList; - export let hideQRCode = false; - export let variant: 'primary' | 'secondary' = 'primary'; + let { + deployment, + proxyRuleList, + hideQRCode = false, + variant = 'primary', + footer + }: { + deployment: Models.Deployment; + proxyRuleList: Models.ProxyRuleList; + hideQRCode?: boolean; + variant?: 'primary' | 'secondary'; + footer?: Snippet; + } = $props(); - let show = false; + let effectiveStatus = $derived( + getEffectiveBuildStatus(deployment.status, deployment.$createdAt, $regionalConsoleVariables) + ); + let show = $state(false); - $: totalSize = humanFileSize(deployment?.totalSize ?? 0); + const totalSize = $derived(humanFileSize(deployment?.totalSize ?? 0)); + + const sortedDomains = $derived( + proxyRuleList?.rules?.slice()?.sort((a, b) => { + if (a?.trigger === 'manual' && b?.trigger !== 'manual') return -1; + if (a?.trigger !== 'manual' && b?.trigger === 'manual') return 1; + return 0; + }) + ); + const primaryDomain = $derived(sortedDomains?.[0]?.domain); function getScreenshot(theme: string, deployment: Models.Deployment) { if (theme === 'dark') { @@ -51,7 +76,7 @@ fileId, width: 1024, height: 576, - output: ImageFormat.Webp + output: ImageFormat.Avif }); } @@ -59,13 +84,25 @@
- + {#if primaryDomain} + + + + {:else} + + {/if} @@ -81,15 +118,15 @@ - {#if deployment.status === 'failed'} + {#if effectiveStatus === 'failed'} Status + status={effectiveStatus} + label={capitalize(effectiveStatus)} /> {:else} @@ -178,13 +215,13 @@
- {#if $$slots.footer} + {#if footer} - + {@render footer?.()} {/if}
diff --git a/src/routes/(console)/project-[region]-[project]/sites/+page.svelte b/src/routes/(console)/project-[region]-[project]/sites/+page.svelte index 17022e7d74..3c4ee175a9 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/+page.svelte @@ -25,7 +25,8 @@ import { onMount } from 'svelte'; import { invalidate } from '$app/navigation'; import { Dependencies } from '$lib/constants'; - import { sdk } from '$lib/stores/sdk'; + import { realtime } from '$lib/stores/sdk'; + import { page } from '$app/state'; export let data; @@ -49,7 +50,7 @@ $updateCommandGroupRanks({ sites: 1000 }); onMount(() => { - return sdk.forConsole.client.subscribe('console', (response) => { + return realtime.forConsole(page.params.region, 'console', (response) => { if (response.events.includes('sites.*')) { invalidate(Dependencies.SITES); } diff --git a/src/routes/(console)/project-[region]-[project]/sites/create-site/deploying/+page.svelte b/src/routes/(console)/project-[region]-[project]/sites/create-site/deploying/+page.svelte index 08f4f1047d..3cb1005435 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/create-site/deploying/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/create-site/deploying/+page.svelte @@ -1,42 +1,42 @@ diff --git a/src/routes/(console)/project-[region]-[project]/sites/create-site/finish/+page.svelte b/src/routes/(console)/project-[region]-[project]/sites/create-site/finish/+page.svelte index 23e7a2d515..fe788db107 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/create-site/finish/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/create-site/finish/+page.svelte @@ -1,5 +1,5 @@ - +
@@ -83,9 +92,9 @@ deployment={data.deployment} proxyRuleList={data.proxyRuleList} hideQRCode> - + {#snippet footer()} - + {/snippet}
@@ -127,7 +136,7 @@ source: 'sites_create_finish' }); }} - href={`${base}/project-${page.params.region}-${page.params.project}/sites/site-${data.site.$id}/domains`}> + href={`${siteRedirectHref}/domains`}> - +
diff --git a/src/routes/(console)/project-[region]-[project]/sites/create-site/manual/+page.svelte b/src/routes/(console)/project-[region]-[project]/sites/create-site/manual/+page.svelte index 5ecf33c75a..969c417cb5 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/create-site/manual/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/create-site/manual/+page.svelte @@ -175,24 +175,21 @@ on:invalid={handleInvalid}> - - - Drag and drop file here or click to upload - - + + + Drag and drop file here or click to upload; - + justifyContent="center"> + + + Only .tar.gz files allowed + - Only .tar.gz files allowed - + {#if maxSize > 0} { 'React', 'Vue.js', 'Svelte', + 'TanStack Start', 'Lynx', 'Angular', 'Analog', diff --git a/src/routes/(console)/project-[region]-[project]/sites/create-site/templates/template-[template]/configuration.svelte b/src/routes/(console)/project-[region]-[project]/sites/create-site/templates/template-[template]/configuration.svelte index 188476e979..2d38d8d999 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/create-site/templates/template-[template]/configuration.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/create-site/templates/template-[template]/configuration.svelte @@ -41,8 +41,8 @@ variables.map((variable) => { if (variable.value === '{apiEndpoint}') { - variable.value = getApiEndpoint(); - variable.placeholder = getApiEndpoint(); + variable.value = getApiEndpoint(page.params.region); + variable.placeholder = getApiEndpoint(page.params.region); } else if (variable.value === '{projectId}') { variable.value = page.params.project; variable.placeholder = page.params.project; diff --git a/src/routes/(console)/project-[region]-[project]/sites/grid.svelte b/src/routes/(console)/project-[region]-[project]/sites/grid.svelte index 46b68f7cc7..99029389ea 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/grid.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/grid.svelte @@ -38,7 +38,7 @@ fileId, width: 1024, height: 576, - output: ImageFormat.Webp + output: ImageFormat.Avif }); } diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/+page.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/+page.svelte index 97ea0bf4cf..9a3c988170 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/+page.svelte @@ -7,19 +7,21 @@ import { Button } from '$lib/elements/forms'; import InstantRollbackDomain from './instantRollbackModal.svelte'; import { app } from '$lib/stores/app'; - import { sdk } from '$lib/stores/sdk'; + import { realtime } from '$lib/stores/sdk'; import { invalidate } from '$app/navigation'; import { Dependencies } from '$lib/constants'; import { onMount } from 'svelte'; import { page } from '$app/state'; import { base } from '$app/paths'; + import type { PageProps } from './$types'; import { regionalProtocol } from '$routes/(console)/project-[region]-[project]/store'; - export let data; - let showRollback = false; + let { data }: PageProps = $props(); + + let showRollback = $state(false); onMount(() => { - return sdk.forConsole.client.subscribe('console', (response) => { + return realtime.forConsole(page.params.region, 'console', (response) => { if (response.events.includes(`sites.${page.params.site}.deployments.*`)) { invalidate(Dependencies.SITE); } @@ -31,7 +33,7 @@ {#if data?.deployment && data.deployment.status === 'ready'} - + {#snippet footer()} {#if data.proxyRuleList.total} - - - -{/if} - - -

- Are you sure you want to delete {selectedRows.length} - {selectedRows.length > 1 ? 'deployments' : 'deployment'} from your site - - {$site.name}? -

- -

This action is irreversible.

-
diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deploymentsOverview.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deploymentsOverview.svelte index aef59781fc..1816d005cb 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deploymentsOverview.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deploymentsOverview.svelte @@ -11,6 +11,8 @@ import ActivateDeploymentModal from '../activateDeploymentModal.svelte'; import CancelDeploymentModal from './deployments/cancelDeploymentModal.svelte'; import { capitalize } from '$lib/helpers/string'; + import { getEffectiveBuildStatus } from '$lib/helpers/buildTimeout'; + import { regionalConsoleVariables } from '$routes/(console)/project-[region]-[project]/store'; import DeleteDeploymentModal from './deployments/deleteDeploymentModal.svelte'; import DeploymentActionMenu from '../(components)/deploymentActionMenu.svelte'; import { deploymentStatusConverter } from '$lib/stores/git'; @@ -72,12 +74,17 @@ {@const status = deployment.status} + {@const effectiveStatus = getEffectiveBuildStatus( + status, + deployment.$createdAt, + $regionalConsoleVariables + )} {#if activeDeployment?.$id === deployment?.$id} {:else} + status={deploymentStatusConverter(effectiveStatus)} + label={capitalize(effectiveStatus)} /> {/if} diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/logs/+page.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/logs/+page.svelte index c7a97e15d2..3ad6b4645b 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/logs/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/logs/+page.svelte @@ -4,16 +4,17 @@ import { Dependencies } from '$lib/constants'; import { Button } from '$lib/elements/forms'; import { Container, ResponsiveContainerHeader } from '$lib/layout'; - import { sdk } from '$lib/stores/sdk'; + import { realtime } from '$lib/stores/sdk'; import { onMount } from 'svelte'; import Table from './table.svelte'; import { Card, Empty } from '@appwrite.io/pink-svelte'; import { columns } from './store'; + import { page } from '$app/state'; export let data; onMount(() => { - return sdk.forConsole.client.subscribe('console', (response) => { + return realtime.forConsole(page.params.region, 'console', (response) => { if (response.events.includes('sites.*.executions.*')) { invalidate(Dependencies.EXECUTIONS); } diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/logs/table.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/logs/table.svelte index 9d74a095da..da4890035b 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/logs/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/logs/table.svelte @@ -1,137 +1,105 @@ - - + + {#snippet header(root)} {#each filteredColumns as { id, title }} {title} {/each} - - {#each logs.executions as log (log.$id)} - { - e.stopPropagation(); - openSheet = true; - selectedLogId = log.$id; - }}> - {#each filteredColumns as column} - - {#if column.id === '$id'} - {#key column.id} - {log.$id} - {/key} - {:else if column.id === 'deploymentId'} - {log.deploymentId} - {:else if column.id === 'requestMethod'} - - {log.requestMethod} - - {:else if column.id === 'duration'} - {#if ['processing', 'waiting'].includes(log.status)} - - {:else} - {calculateTime(log.duration)} + {/snippet} + + {#snippet children(root)} + {#each logs.executions as log (log.$id)} + { + e.stopPropagation(); + openSheet = true; + selectedLogId = log.$id; + }}> + {#each filteredColumns as column} + + {#if column.id === '$id'} + {#key column.id} + {log.$id} + {/key} + {:else if column.id === 'deploymentId'} + {log.deploymentId} + {:else if column.id === 'requestMethod'} + + {log.requestMethod} + + {:else if column.id === 'duration'} + {#if ['processing', 'waiting'].includes(log.status)} + + {:else} + {calculateTime(log.duration)} + {/if} + {:else if column.id === 'responseStatusCode'} +
+ +
+ {:else if column.id === 'requestPath'} + + {log.requestPath} + + {:else if column.id === '$createdAt'} + {/if} - {:else if column.id === 'responseStatusCode'} -
- -
- {:else if column.id === 'requestPath'} - - {log.requestPath} - - {:else if column.id === '$createdAt'} - - {/if} -
- {/each} -
- {/each} -
+ + {/each} + + {/each} + {/snippet} + - -{#if selectedRows.length > 0} - - - - - {selectedRows.length > 1 ? 'logs' : 'log'} - selected - - - - - - - -{/if} - - -

- Are you sure you want to delete {selectedRows.length} - {selectedRows.length > 1 ? 'logs' : 'log'}? -

- -

This action is irreversible.

-
diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/store.ts b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/store.ts index e66ee97b34..59ff9cb358 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/store.ts +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/store.ts @@ -53,15 +53,28 @@ export const adapterDataList = [ url: 'https://nuxt.com/docs/getting-started/deployment#static-hosting' } }, + { + framework: 'tanstack-start', + ssr: { + desc: 'Ensure $ includes $ plugin.', + code: ['vite.config.js', 'tanstackStart()'], + url: 'https://tanstack.com/start/latest/docs/framework/react/guide/hosting' + }, + static: { + desc: 'Set $ to $ in $.', + code: ['prerender', 'enabled', 'vite.config.js'], + url: 'https://tanstack.com/start/latest/docs/framework/react/guide/static-prerendering' + } + }, { framework: 'nextjs', ssr: { - desc: "Ensure you don't set $ in $ file.", - code: ['output', 'next.config.js'], + desc: 'Set $ in $ file.', + code: ["output: 'standalone'", 'next.config.js'], url: 'https://nextjs.org/docs/pages/building-your-application/deploying' }, static: { - desc: 'Set $ in $ file', + desc: 'Set $ in $ file.', code: ["output: 'export'", 'next.config.js'], url: 'https://nextjs.org/docs/pages/building-your-application/deploying/static-exports' } @@ -69,12 +82,12 @@ export const adapterDataList = [ { framework: 'analog', ssr: { - desc: 'Set $ in $ plugin in $', + desc: 'Set $ in $ plugin in $.', code: ['ssr: true', 'analog', 'vite.config.ts'], url: 'https://analogjs.org/docs/features/server/server-side-rendering' }, static: { - desc: 'Set $ in $ plugin in $', + desc: 'Set $ in $ plugin in $.', code: ['static: true', 'analog', 'vite.config.ts'], url: 'https://analogjs.org/docs/features/server/static-site-generation' } diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateBuildSettings.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateBuildSettings.svelte index 1718ebca7d..0f4cbeef36 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateBuildSettings.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateBuildSettings.svelte @@ -36,21 +36,34 @@ frameworks.find((framework) => framework.key === site.framework) ); let showFallback = $derived(adapter === Adapter.Static); - let hasChanges = $derived( + + let isUntouched = $derived( installCommand === site?.installCommand && buildCommand === site?.buildCommand && outputDirectory === site?.outputDirectory && selectedFramework?.key === site?.framework && - fallback === (site?.fallbackFile || undefined) && - adapter === site?.adapter + (fallback ?? '') === (site?.fallbackFile ?? '') && + (adapter ?? '') === (site?.adapter ?? '') ); let frameworkAdapterData = $derived( selectedFramework.adapters.find((a) => a.key === adapter) ?? selectedFramework.adapters[0] ); + $effect(() => { + if (adapter) { + const data = selectedFramework.adapters.find((a) => a.key === adapter); + if (data) { + installCommand = data.installCommand; + buildCommand = data.buildCommand; + outputDirectory = data.outputDirectory; + fallback = data.fallbackFile; + } + } + }); + $effect(() => { if (selectedFramework?.key !== site.framework) { - //Update adapter + // Update adapter const singleAdapter = selectedFramework?.adapters?.length <= 1; if (singleAdapter) { const hasSSR = selectedFramework?.adapters?.some((a) => a?.key === Adapter.Ssr); @@ -65,11 +78,13 @@ } //Update values - const data = selectedFramework.adapters.find((a) => a.key === adapter); + const data = + selectedFramework.adapters.find((a) => a.key === adapter) ?? + selectedFramework.adapters[0]; installCommand = data.installCommand; buildCommand = data.buildCommand; outputDirectory = data.outputDirectory; - adapter = selectedFramework.adapters[0].key as Adapter; + adapter = data.key as Adapter; fallback = data.fallbackFile; } else { adapter = site.adapter as Adapter; @@ -157,11 +172,11 @@ const data = selectedFramework.adapters.find((a) => a.key === adapter); if (type === 'installCommand') { - installCommand = site?.installCommand ?? data.installCommand; + installCommand = data.installCommand; } else if (type === 'buildCommand') { - buildCommand = site?.buildCommand ?? data.buildCommand; + buildCommand = data.buildCommand; } else if (type === 'outputDirectory') { - outputDirectory = site?.outputDirectory ?? data.outputDirectory; + outputDirectory = data.outputDirectory; } } @@ -216,7 +231,8 @@ {adapterData.ssr.desc} {/if} {#if adapterData?.ssr?.url} - Learn more + Learn more {/if} Learn more + Learn more {/if} @@ -258,7 +278,11 @@ placeholder={frameworkAdapterData?.installCommand || 'Enter install command'} /> -
@@ -269,7 +293,11 @@ bind:value={buildCommand} placeholder={frameworkAdapterData?.buildCommand || 'Enter build command'} /> -
@@ -280,7 +308,12 @@ bind:value={outputDirectory} placeholder={frameworkAdapterData?.outputDirectory || 'Enter output directory'} /> -
@@ -305,7 +338,7 @@ - + diff --git a/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/+page.svelte b/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/+page.svelte index 198daff577..8caf3c05a5 100644 --- a/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/+page.svelte @@ -3,28 +3,25 @@ import { base } from '$app/paths'; import { page } from '$app/state'; import { Submit, trackError, trackEvent } from '$lib/actions/analytics'; - import { Avatar, Empty, EmptySearch, PaginationWithLimit, SearchQuery } from '$lib/components'; + import { + Avatar, + type DeleteOperationState, + Empty, + EmptySearch, + MultiSelectionTable, + PaginationWithLimit, + SearchQuery + } from '$lib/components'; import { Dependencies } from '$lib/constants'; import { Badge } from '@appwrite.io/pink-svelte'; import { Button } from '$lib/elements/forms'; import { calculateSize } from '$lib/helpers/sizeConvertion'; import { Container } from '$lib/layout'; - import type { Models } from '@appwrite.io/console'; - import { addNotification } from '$lib/stores/notifications'; + import { ImageFormat, type Models } from '@appwrite.io/console'; import { uploader } from '$lib/stores/uploader'; import { sdk } from '$lib/stores/sdk.js'; import DeleteFile from './deleteFile.svelte'; - import { bucket } from './store'; - import Confirm from '$lib/components/confirm.svelte'; - import { - Layout, - Table, - Icon, - Popover, - ActionMenu, - FloatingActionBar, - Typography - } from '@appwrite.io/pink-svelte'; + import { Layout, Table, Icon, Popover, ActionMenu } from '@appwrite.io/pink-svelte'; import { onMount } from 'svelte'; import DualTimeView from '$lib/components/dualTimeView.svelte'; import { @@ -34,26 +31,24 @@ IconTrash } from '@appwrite.io/pink-icons-svelte'; import { isSmallViewport } from '$lib/stores/viewport'; + import type { PageProps } from './$types'; - export let data; - - let showDelete = false; - let selectedFile: Models.File = null; - let selectedFiles: string[] = []; - let showBulkDelete = false; - let deleting = false; + const { data }: PageProps = $props(); - const bucketId = page.params.bucket; + let showDelete = $state(false); + let isUploading = $state(false); + let selectedFile: Models.File | null = $state(null); function getPreview(fileId: string) { return ( sdk .forProject(page.params.region, page.params.project) .storage.getFilePreview({ - bucketId, + bucketId: page.params.bucket, fileId, height: 128, - width: 128 + width: 128, + output: ImageFormat.Avif }) .toString() + '&mode=admin' ); @@ -70,42 +65,25 @@ showDelete = true; } - async function handleBulkDelete() { - showBulkDelete = false; - deleting = true; - - const promises = selectedFiles.map((fileId) => - sdk.forProject(page.params.region, page.params.project).storage.deleteFile({ - bucketId, + async function handleBulkDelete(selectedRows: string[]): Promise { + const promises = selectedRows.map((fileId) => { + return sdk.forProject(page.params.region, page.params.project).storage.deleteFile({ + bucketId: page.params.bucket, fileId - }) - ); + }); + }); try { await Promise.all(promises); - trackEvent(Submit.FileDelete, { - total: selectedFiles.length - }); - addNotification({ - type: 'success', - message: `${selectedFiles.length} file${selectedFiles.length > 1 ? 's' : ''} deleted` - }); - invalidate(Dependencies.FILES); + trackEvent(Submit.FileDelete, { total: selectedRows.length }); } catch (error) { - addNotification({ - type: 'error', - message: error.message - }); trackError(error, Submit.FileDelete); + return error; } finally { - selectedFiles = []; - showBulkDelete = false; - deleting = false; + await invalidate(Dependencies.FILES); } } - let isUploading = false; - const beforeunload = (event: BeforeUnloadEvent) => { // legacy browser **may** support showing a custom message. const message = 'An upload is in progress. Are you sure you want to leave?'; @@ -146,10 +124,10 @@
{#if data.files.total} - - + {#snippet header(root)} Filename Type Size Created - - {#each data.files.files as file} - {#if file.chunksTotal / file.chunksUploaded !== 1} - - - - - {file.name} -
- + {/snippet} + + {#snippet children(root)} + {#each data.files.files as file} + {#if file.chunksTotal / file.chunksUploaded !== 1} + + + + + {file.name} +
+ +
+
+
+ {file.mimeType} + + {calculateSize(file.sizeOriginal)} + + + + + +
+ +
+
+
+ {:else} + {@const href = `${base}/project-${page.params.region}-${page.params.project}/storage/bucket-${page.params.bucket}/file-${file.$id}`} + + +
+ + {file.name}
- -
- {file.mimeType} - - {calculateSize(file.sizeOriginal)} - - - - - -
- -
-
- - {:else} - {@const href = `${base}/project-${page.params.region}-${page.params.project}/storage/bucket-${bucketId}/file-${file.$id}`} - - -
- - {file.name} -
-
- {file.mimeType} - - {calculateSize(file.sizeOriginal)} - - - - - - - - - - Update - - + {file.mimeType} + + {calculateSize(file.sizeOriginal)} + + + + + + + + + + Update + + { + e.stopPropagation(); + e.preventDefault(); + selectedFile = file; + showDelete = true; + }}> + Delete + + + + +
+ {/if} + {/each} + {/snippet} + + {#snippet deleteContentNotice()} + This action is irreversible and will permanently remove the selected files. + {/snippet} + + href={`${base}/project-${page.params.region}-${page.params.project}/storage/bucket-${page.params.bucket}`}> Clear Search @@ -267,39 +258,9 @@ allowCreate on:click={() => goto( - `${base}/project-${page.params.region}-${page.params.project}/storage/bucket-${bucketId}/create` + `${base}/project-${page.params.region}-${page.params.project}/storage/bucket-${page.params.bucket}/create` )} /> {/if} - - {#if selectedFiles.length > 0} - - - - - {selectedFiles.length > 1 ? 'files' : 'file'} - selected - - - - - - - - {/if} - - - - Are you sure you want to delete {selectedFiles.length} - {selectedFiles.length > 1 ? 'files' : 'file'} from {$bucket?.name}? - - - This action is irreversible and will permanently remove the selected files. - - diff --git a/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/file-[file]/+page.svelte b/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/file-[file]/+page.svelte index 04f5219a41..a940dc8f6f 100644 --- a/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/file-[file]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/file-[file]/+page.svelte @@ -35,7 +35,7 @@ } from '@appwrite.io/pink-icons-svelte'; import FileTokensCopyUrl from './fileTokensCopyUrl.svelte'; import ManageFileTokenModal, { cleanFormattedDate } from './manageFileToken.svelte'; - import { type Models } from '@appwrite.io/console'; + import { ImageFormat, type Models } from '@appwrite.io/console'; import { isSmallViewport } from '$lib/stores/viewport'; import { Menu } from '$lib/components/menu'; @@ -57,7 +57,8 @@ bucketId: $file.bucketId, fileId, width: 640, - height: 300 + height: 300, + output: ImageFormat.Avif }) .toString() + '&mode=admin'; const getView = (fileId: string) => diff --git a/src/routes/(console)/supportWizard.svelte b/src/routes/(console)/supportWizard.svelte index 902bd8038d..eb25fceef5 100644 --- a/src/routes/(console)/supportWizard.svelte +++ b/src/routes/(console)/supportWizard.svelte @@ -125,11 +125,11 @@ { } finally { redirect(303, resolve('/')); } - } else { - redirect(303, resolve('/')); } + return {}; }; diff --git a/static/icons/dark/color/resend.svg b/static/icons/dark/color/resend.svg new file mode 100644 index 0000000000..0ded97051d --- /dev/null +++ b/static/icons/dark/color/resend.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/icons/dark/color/tanstack.svg b/static/icons/dark/color/tanstack.svg new file mode 100644 index 0000000000..5823a237b5 --- /dev/null +++ b/static/icons/dark/color/tanstack.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/icons/light/color/resend.svg b/static/icons/light/color/resend.svg new file mode 100644 index 0000000000..ad99113691 --- /dev/null +++ b/static/icons/light/color/resend.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/icons/light/color/tanstack.svg b/static/icons/light/color/tanstack.svg new file mode 100644 index 0000000000..76011176f5 --- /dev/null +++ b/static/icons/light/color/tanstack.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/logos/apple-touch-icon-120x120.png b/static/logos/apple-touch-icon-120x120.png new file mode 100644 index 0000000000..b5e9c5ea1e Binary files /dev/null and b/static/logos/apple-touch-icon-120x120.png differ diff --git a/static/logos/apple-touch-icon-152x152.png b/static/logos/apple-touch-icon-152x152.png new file mode 100644 index 0000000000..93a40e457a Binary files /dev/null and b/static/logos/apple-touch-icon-152x152.png differ diff --git a/static/logos/apple-touch-icon-167x167.png b/static/logos/apple-touch-icon-167x167.png new file mode 100644 index 0000000000..9083bef9d3 Binary files /dev/null and b/static/logos/apple-touch-icon-167x167.png differ diff --git a/static/logos/apple-touch-icon-180x180.png b/static/logos/apple-touch-icon-180x180.png new file mode 100644 index 0000000000..8e35bc7239 Binary files /dev/null and b/static/logos/apple-touch-icon-180x180.png differ