diff --git a/.claude/skills/frontend-dev-guidelines/resources/forms-and-modals.md b/.claude/skills/frontend-dev-guidelines/resources/forms-and-modals.md index c442834f4c..0ed2704d52 100644 --- a/.claude/skills/frontend-dev-guidelines/resources/forms-and-modals.md +++ b/.claude/skills/frontend-dev-guidelines/resources/forms-and-modals.md @@ -93,13 +93,13 @@ import { getFieldErrors, handleSubmit } from '@app-builder/utils/form'; ### Form Components -| Component | Props | Purpose | -|-----------|-------|---------| -| `FormInput` | `type`, `name`, `defaultValue`, `onChange`, `onBlur`, `valid` | Text/number input with error border | -| `FormLabel` | `name`, `valid` | Label linked to input via `htmlFor` | -| `FormErrorOrDescription` | `errors?`, `description?` | Shows errors or help text | -| `FormTextArea` | Same as FormInput | Multi-line input | -| `FormError` | `field`, `asString?`, `translations?` | Translates Zod error codes to i18n | +| Component | Props | Purpose | +| ------------------------ | ------------------------------------------------------------- | ----------------------------------- | +| `FormInput` | `type`, `name`, `defaultValue`, `onChange`, `onBlur`, `valid` | Text/number input with error border | +| `FormLabel` | `name`, `valid` | Label linked to input via `htmlFor` | +| `FormErrorOrDescription` | `errors?`, `description?` | Shows errors or help text | +| `FormTextArea` | Same as FormInput | Multi-line input | +| `FormError` | `field`, `asString?`, `translations?` | Translates Zod error codes to i18n | ### Number Fields @@ -161,14 +161,14 @@ export function DeleteConfirmModal({ onDelete }: { onDelete: () => void }) { ### Modal Components -| Component | Purpose | -|-----------|---------| -| `Modal.Root` | Root state manager. Props: `open`, `onOpenChange` | -| `Modal.Trigger` | Opens the modal. Use `asChild` to wrap custom trigger | -| `Modal.Content` | Dialog container. Props: `size` (`small`/`medium`/`large`/`xlarge`) | -| `Modal.Title` | Dialog title (required for accessibility) | -| `Modal.Close` | Closes on click. Use `asChild` to wrap custom button | -| `Modal.Footer` | Standard buttons in the footer, asClosed for the buttons that close the modal, with optional icon and isLoading state | +| Component | Purpose | +| --------------- | --------------------------------------------------------------------------------------------------------------------- | +| `Modal.Root` | Root state manager. Props: `open`, `onOpenChange` | +| `Modal.Trigger` | Opens the modal. Use `asChild` to wrap custom trigger | +| `Modal.Content` | Dialog container. Props: `size` (`small`/`medium`/`large`/`xlarge`) | +| `Modal.Title` | Dialog title (required for accessibility) | +| `Modal.Close` | Closes on click. Use `asChild` to wrap custom button | +| `Modal.Footer` | Standard buttons in the footer, asClosed for the buttons that close the modal, with optional icon and isLoading state | ### Modal with Form @@ -196,7 +196,7 @@ Wrap `
` around `Modal.Title`, content, and `Modal.Footer`: Right-side sliding panel for detail views. Import from app-builder components. ```typescript -import { Panel } from '@app-builder/components/Panel'; +import { Panel } from 'ui-design-system'; import { useTranslation } from 'react-i18next'; export function DetailPanel({ open, onOpenChange }: { open: boolean; onOpenChange: (open: boolean) => void }) { @@ -225,11 +225,10 @@ export function DetailPanel({ open, onOpenChange }: { open: boolean; onOpenChang ### Panel Sizes -| Size | Max Width | -|------|-----------| -| small | 'max-w-[calc(100vw_/_3)]' | -| medium | 'max-w-[50vw]' | -| large | 'max-w-[calc(100vw_*_(2_/_3))]' | - +| Size | Max Width | +| ------ | ------------------------------- | +| small | 'max-w-[calc(100vw_/_3)]' | +| medium | 'max-w-[50vw]' | +| large | 'max-w-[calc(100vw_*_(2_/_3))]' | Features: slide animation, focus trapping, Escape to close, portal rendering. diff --git a/.dockerignore b/.dockerignore index c8c4196b31..7486ef0775 100644 --- a/.dockerignore +++ b/.dockerignore @@ -14,7 +14,6 @@ node_modules # Build outputs -packages/app-builder/build **/.output **/.nitro **/build diff --git a/.github/workflows/build_and_deploy.yaml b/.github/workflows/build_and_deploy.yaml index a43afa68f9..0d7018a642 100644 --- a/.github/workflows/build_and_deploy.yaml +++ b/.github/workflows/build_and_deploy.yaml @@ -3,6 +3,11 @@ name: Reusable build and deploy job on: workflow_call: inputs: + app: + type: string + description: "Application to build and deploy (app-builder or backoffice)" + required: true + default: "app-builder" environment: type: string description: "Github environment to use" @@ -33,7 +38,7 @@ jobs: environment: ${{ inputs.environment }} env: VERSION: ${{ inputs.version }} - IMAGE: europe-west1-docker.pkg.dev/marble-infra/marble/marble-frontend:${{ inputs.version }} + IMAGE: europe-west1-docker.pkg.dev/marble-infra/marble/${{ inputs.app }}:${{ inputs.version }} SERVICE_ACCOUNT: marble-frontend-cloud-run@${{ vars.GCP_PROJECT_ID }}.iam.gserviceaccount.com steps: - name: Checkout @@ -71,9 +76,9 @@ jobs: with: context: . push: true - target: app-builder + target: ${{ inputs.app }} tags: ${{ env.IMAGE }} - file: ./Dockerfile + file: ${{ inputs.dockerfile }} build-args: | SENTRY_PROJECT=marble-frontend SENTRY_RELEASE=${{ inputs.SENTRY_RELEASE }} @@ -89,7 +94,7 @@ jobs: - name: Deploy server run: | - gcloud run deploy marble-frontend \ + gcloud run deploy ${{ inputs.app }} \ --quiet \ --region="europe-west1" \ --image="$IMAGE" diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index 1e52f48746..484c696fb9 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -60,3 +60,6 @@ jobs: - name: Build app-builder run: bun run -F app-builder build + + - name: Build backoffice + run: bun run -F backoffice build diff --git a/.github/workflows/main_push.yaml b/.github/workflows/main_push.yaml index 8e294d09e1..2cd7335462 100644 --- a/.github/workflows/main_push.yaml +++ b/.github/workflows/main_push.yaml @@ -16,15 +16,34 @@ jobs: actions: read uses: ./.github/workflows/check.yaml - build_and_deploy: + build_and_deploy_app_builder: needs: check permissions: contents: read actions: read - id-token: 'write' # needed for using open id token to authenticate with GCP + id-token: "write" # needed for using open id token to authenticate with GCP uses: ./.github/workflows/build_and_deploy.yaml with: - environment: 'staging' + app: "app-builder" + dockerfile: ./Dockerfile + environment: "staging" + version: latest + SENTRY_RELEASE: ${{ github.sha }} + secrets: + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + SEGMENT_WRITE_KEY_OPENSOURCE: ${{ secrets.SEGMENT_WRITE_KEY_OPENSOURCE }} + + build_and_deploy_backoffice: + needs: check + permissions: + contents: read + actions: read + id-token: "write" # needed for using open id token to authenticate with GCP + uses: ./.github/workflows/build_and_deploy.yaml + with: + app: "backoffice" + dockerfile: ./Dockerfile.backoffice + environment: "staging" version: latest SENTRY_RELEASE: ${{ github.sha }} secrets: diff --git a/.github/workflows/tags_push.yaml b/.github/workflows/tags_push.yaml index 5db28ced69..23f869a0a4 100644 --- a/.github/workflows/tags_push.yaml +++ b/.github/workflows/tags_push.yaml @@ -17,7 +17,7 @@ jobs: actions: read uses: ./.github/workflows/check.yaml - build_and_deploy: + build_and_deploy_app_builder: needs: check permissions: contents: read @@ -25,6 +25,25 @@ jobs: id-token: "write" # needed for using open id token to authenticate with GCP uses: ./.github/workflows/build_and_deploy.yaml with: + app: "app-builder" + dockerfile: ./Dockerfile + environment: "production" + version: ${{ github.ref_name }} + SENTRY_RELEASE: ${{ github.ref_name }} + secrets: + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + SEGMENT_WRITE_KEY_OPENSOURCE: ${{ secrets.SEGMENT_WRITE_KEY_OPENSOURCE }} + + build_and_deploy_backoffice: + needs: check + permissions: + contents: read + actions: read + id-token: "write" # needed for using open id token to authenticate with GCP + uses: ./.github/workflows/build_and_deploy.yaml + with: + app: "backoffice" + dockerfile: ./Dockerfile.backoffice environment: "production" version: ${{ github.ref_name }} SENTRY_RELEASE: ${{ github.ref_name }} diff --git a/Dockerfile b/Dockerfile index 8d4fe8b29a..952649176c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,6 +7,7 @@ WORKDIR /usr/src/app # Copy only workspace manifests to maximize install cache hits COPY package.json bun.lock ./ COPY packages/app-builder/package.json ./packages/app-builder/ +COPY packages/backoffice/package.json ./packages/backoffice/ COPY packages/shared/package.json ./packages/shared/ COPY packages/marble-api/package.json ./packages/marble-api/ COPY packages/typescript-utils/package.json ./packages/typescript-utils/ @@ -68,9 +69,13 @@ RUN --mount=type=secret,id=SENTRY_AUTH_TOKEN \ if [ -f /run/secrets/SENTRY_AUTH_TOKEN ]; then export SENTRY_AUTH_TOKEN=$(cat /run/secrets/SENTRY_AUTH_TOKEN); fi; \ bun run -F app-builder build +RUN bun run -F backoffice build + # Collect build artifacts and dependencies for runtime RUN mkdir -p /prod/app-builder && \ - cp -R packages/app-builder/.output /prod/app-builder/.output + cp -R packages/app-builder/.output /prod/app-builder/.output && \ + mkdir -p /prod/backoffice && \ + cp -R packages/backoffice/.output /prod/backoffice/.output # ---- Production Dependencies stage ---- FROM ${BUN_IMAGE} AS deps-prod @@ -79,6 +84,7 @@ WORKDIR /usr/src/app # Copy only workspace manifests to maximize install cache hits COPY package.json bun.lock ./ COPY packages/app-builder/package.json ./packages/app-builder/ +COPY packages/backoffice/package.json ./packages/backoffice/ COPY packages/shared/package.json ./packages/shared/ COPY packages/marble-api/package.json ./packages/marble-api/ COPY packages/typescript-utils/package.json ./packages/typescript-utils/ @@ -119,3 +125,23 @@ COPY --from=deps-prod /usr/src/app/node_modules ./node_modules EXPOSE $PORT CMD [".output/server/index.mjs"] + +# ---- Runtime stage (backoffice) ---- +FROM ${BUN_IMAGE} AS backoffice +WORKDIR /prod/backoffice + +ENV NODE_ENV=production +ARG PORT=8080 +ENV PORT=${PORT:-8080} + +ARG APP_VERSION +ENV APP_VERSION=$APP_VERSION + +# Copy build output +COPY --from=build /prod/backoffice/.output ./.output + +# Copy ONLY production dependencies +COPY --from=deps-prod /usr/src/app/node_modules ./node_modules + +EXPOSE $PORT +CMD ["bun", ".output/server/index.mjs"] diff --git a/Dockerfile.backoffice b/Dockerfile.backoffice new file mode 100644 index 0000000000..111aa10e70 --- /dev/null +++ b/Dockerfile.backoffice @@ -0,0 +1,85 @@ +ARG BUN_IMAGE=oven/bun:1.3 +ARG RUNTIME_IMAGE=oven/bun:1.3-distroless +# ---- Dependencies stage ---- +FROM ${BUN_IMAGE} AS deps-dev +WORKDIR /usr/src/app + +# Copy only workspace manifests to maximize install cache hits +COPY package.json bun.lock ./ +COPY packages/app-builder/package.json ./packages/app-builder/ +COPY packages/backoffice/package.json ./packages/backoffice/ +COPY packages/shared/package.json ./packages/shared/ +COPY packages/marble-api/package.json ./packages/marble-api/ +COPY packages/typescript-utils/package.json ./packages/typescript-utils/ +COPY packages/ui-design-system/package.json ./packages/ui-design-system/ +COPY packages/ui-icons/package.json ./packages/ui-icons/ +COPY packages/tailwind-preset/package.json ./packages/tailwind-preset/ +COPY packages/tests/package.json ./packages/tests/ + +# Install WITH dev dependencies (needed for build stage) +RUN --mount=type=cache,target=/root/.bun \ + bun ci + +# ---- Build stage ---- (uses dev deps from above) +FROM ${BUN_IMAGE} AS build +WORKDIR /usr/src/app + +# Copy full source AFTER deps to leverage layer caching +COPY . . +# Reuse cached node_modules from deps stage (root + workspace-local) +COPY --from=deps-dev /usr/src/app/node_modules ./node_modules +COPY --from=deps-dev /usr/src/app/packages/backoffice/node_modules ./packages/backoffice/node_modules + +# Build-time configuration +ARG SENTRY_ORG +ENV SENTRY_ORG=$SENTRY_ORG +ARG SENTRY_PROJECT +ENV SENTRY_PROJECT=$SENTRY_PROJECT +ARG SENTRY_RELEASE +ENV SENTRY_RELEASE=$SENTRY_RELEASE + +RUN bun run -F backoffice build + +# Collect build artifacts and dependencies for runtime +RUN mkdir -p /prod/backoffice && \ + cp -R packages/backoffice/.output /prod/backoffice/.output + +# ---- Production Dependencies stage ---- +FROM ${BUN_IMAGE} AS deps-prod +WORKDIR /usr/src/app + +# Copy only workspace manifests to maximize install cache hits +COPY package.json bun.lock ./ +COPY packages/app-builder/package.json ./packages/app-builder/ +COPY packages/backoffice/package.json ./packages/backoffice/ +COPY packages/shared/package.json ./packages/shared/ +COPY packages/marble-api/package.json ./packages/marble-api/ +COPY packages/typescript-utils/package.json ./packages/typescript-utils/ +COPY packages/ui-design-system/package.json ./packages/ui-design-system/ +COPY packages/ui-icons/package.json ./packages/ui-icons/ +COPY packages/tailwind-preset/package.json ./packages/tailwind-preset/ +COPY packages/tests/package.json ./packages/tests/ + +# Install ONLY production dependencies +RUN --mount=type=cache,target=/root/.bun \ + bun install --production --frozen-lockfile + +# ---- Runtime stage (backoffice) ---- +FROM ${RUNTIME_IMAGE} AS backoffice +WORKDIR /prod/backoffice + +ENV NODE_ENV=production +ARG PORT=8080 +ENV PORT=${PORT:-8080} + +ARG APP_VERSION +ENV APP_VERSION=$APP_VERSION + +# Copy build output +COPY --from=build /prod/backoffice/.output ./.output + +# Copy ONLY production dependencies +COPY --from=deps-prod /usr/src/app/node_modules ./node_modules + +EXPOSE $PORT +CMD [".output/server/index.mjs"] diff --git a/biome.json b/biome.json index e74e58d464..c95242d2c2 100644 --- a/biome.json +++ b/biome.json @@ -21,7 +21,7 @@ "!**/coverage", "!**/public", "!packages/marble-api/src/generated", - "!packages/app-builder/src/routeTree.gen.ts", + "!packages/*/src/routeTree.gen.ts", "!packages-licenses.json" ] }, diff --git a/bun.lock b/bun.lock index 422301e09b..5d7dada581 100644 --- a/bun.lock +++ b/bun.lock @@ -5,6 +5,8 @@ "": { "name": "marble-front", "dependencies": { + "react": "18.3.1", + "react-dom": "18.3.1", "tailwindcss-grid-areas": "^0.1.1", }, "devDependencies": { @@ -106,12 +108,12 @@ "tailwindcss-radix": "^4.0.2", "temporal-polyfill": "^1.0.2", "tiny-invariant": "^1.3.3", - "ts-pattern": "^5.6.2", + "ts-pattern": "^5.9.0", "typescript-utils": "workspace:*", "ui-design-system": "workspace:*", "ui-icons": "workspace:*", "uuid": "^14.0.0", - "zod": "^4.1.8", + "zod": "^4.1.11", "zustand": "^5.0.14", }, "devDependencies": { @@ -137,6 +139,59 @@ "vitest": "4.1.10", }, }, + "packages/backoffice": { + "name": "backoffice", + "dependencies": { + "@marble/shared": "workspace:*", + "@sentry/tanstackstart-react": "^10.52.0", + "@t3-oss/env-core": "^0.13.8", + "@tailwindcss/vite": "^4.2.4", + "@tanstack/react-devtools": "^0.10.5", + "@tanstack/react-form": "^1.29.3", + "@tanstack/react-query": "^5.99.2", + "@tanstack/react-query-devtools": "^5.84.2", + "@tanstack/react-router": "1.170.16", + "@tanstack/react-router-devtools": "1.167.0", + "@tanstack/react-router-ssr-query": "1.167.1", + "@tanstack/react-start": "1.168.26", + "@tanstack/router-plugin": "1.168.18", + "@trpc/client": "^11.4.3", + "@trpc/server": "^11.4.3", + "@trpc/tanstack-react-query": "^11.4.3", + "firebase": "^12.13.0", + "lucide-react": "^0.544.0", + "marble-api": "workspace:*", + "nitro": "^3.0.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-dropzone-esm": "^15.2.0", + "react-error-boundary": "^6.0.0", + "react-hot-toast": "^2.5.2", + "remeda": "^2.38.0", + "sharpstate": "^0.0.13", + "superjson": "^2.2.6", + "tailwindcss": "4.3.2", + "ts-pattern": "^5.9.0", + "ui-design-system": "workspace:*", + "ui-icons": "workspace:*", + "vite-tsconfig-paths": "^6.1.1", + "zod": "^4.1.11", + }, + "devDependencies": { + "@tanstack/devtools-vite": "^0.6.0", + "@testing-library/dom": "^10.4.0", + "@testing-library/react": "16.3.2", + "@types/node": "25.6.2", + "@types/react": "18.3.24", + "@types/react-dom": "^18.3.5", + "@vitejs/plugin-react": "^5.0.4", + "babel-plugin-react-compiler": "^1.0.0", + "jsdom": "29.1.1", + "vite": "^7.3.6", + "vitest": "4.1.8", + "web-vitals": "^5.1.0", + }, + }, "packages/marble-api": { "name": "marble-api", "version": "1.0.0", @@ -173,8 +228,8 @@ "vite": "^7.3.6", }, "peerDependencies": { - "react": "18.3.1", - "react-dom": "18.3.1", + "react": "^18.3.1", + "react-dom": "^18.3.1", }, }, "packages/tailwind-preset": { @@ -226,6 +281,7 @@ "@radix-ui/react-scroll-area": "^1.2.18", "@radix-ui/react-select": "^2.3.7", "@radix-ui/react-separator": "^1.1.15", + "@radix-ui/react-slot": "^1.3.3", "@radix-ui/react-switch": "^1.3.7", "@radix-ui/react-tabs": "^1.1.21", "@radix-ui/react-toggle-group": "^1.1.19", @@ -286,12 +342,12 @@ "@types/react": "18.3.24", "@types/svg-sprite": "^0.0.39", "ora": "^8.2.0", - "react": "18.3.1", + "react": "^18.3.1", "svg-sprite": "^2.0.4", "tsx": "^4.22.4", }, "peerDependencies": { - "react": "18.3.1", + "react": "^18.3.1", }, }, }, @@ -300,6 +356,8 @@ "cross-spawn": "^7.0.5", "glob": "10.5.0", "minimatch": "9.0.7", + "react": "18.3.1", + "react-dom": "18.3.1", "vite": "^7.3.6", }, "packages": { @@ -331,7 +389,7 @@ "@asamuzakjp/nwsapi": ["@asamuzakjp/nwsapi@2.3.9", "", {}, "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q=="], - "@babel/code-frame": ["@babel/code-frame@7.29.7", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw=="], + "@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="], "@babel/compat-data": ["@babel/compat-data@7.29.7", "", {}, "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg=="], @@ -483,93 +541,93 @@ "@fastify/busboy": ["@fastify/busboy@2.1.1", "", {}, "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA=="], - "@firebase/ai": ["@firebase/ai@2.14.0", "", { "dependencies": { "@firebase/app-check-interop-types": "0.3.4", "@firebase/component": "0.7.4", "@firebase/logger": "0.5.1", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-types": "0.x" } }, "sha512-TYEQqCQUTyVHuG/HVi9vau6F9kvEaS49o/hmdn/yUuN6ZXQkwIml2nNJTIBfjNl/r9LOxwUNILgcOY16nxObug=="], + "@firebase/ai": ["@firebase/ai@2.15.0", "", { "dependencies": { "@firebase/app-check-interop-types": "0.3.5", "@firebase/component": "0.7.5", "@firebase/logger": "0.5.2", "@firebase/util": "1.15.3", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-types": "0.x" } }, "sha512-Aj7TbFdAIWZdkX8JfdDStERpR35g6WNs+7XhNPtFLFOizUotj6k4N/D8HJkR45165HhnMJBe4hjOeeaxnnn56Q=="], - "@firebase/analytics": ["@firebase/analytics@0.10.23", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/installations": "0.6.23", "@firebase/logger": "0.5.1", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-34ALWXzWA6PTRUA5hipZmsm1RKzeecw5J1+qTCXsiMzwLqONC+GuTIQSdmm91MmTAEA+wG1Q5t0IFahcYQOqAA=="], + "@firebase/analytics": ["@firebase/analytics@0.10.24", "", { "dependencies": { "@firebase/component": "0.7.5", "@firebase/installations": "0.6.24", "@firebase/logger": "0.5.2", "@firebase/util": "1.15.3", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-OfIAcIIwoqXjBzS+DnUQpOZ7i3ePaNFg83KPpDWjBZUKJmqMwzzAtLJqmKZOkQnW8im6vFR6f2I3M/9hxVd+QA=="], - "@firebase/analytics-compat": ["@firebase/analytics-compat@0.2.29", "", { "dependencies": { "@firebase/analytics": "0.10.23", "@firebase/analytics-types": "0.8.4", "@firebase/component": "0.7.4", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-allztvCvCUlItZzD97TiRAtGoFJzR1FQFmLxbaLc6PvgscqD9cl5NdKPTtka6keShVYXvCZJpzWcRoH4TME8rw=="], + "@firebase/analytics-compat": ["@firebase/analytics-compat@0.2.30", "", { "dependencies": { "@firebase/analytics": "0.10.24", "@firebase/analytics-types": "0.8.5", "@firebase/component": "0.7.5", "@firebase/util": "1.15.3", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-uVZEKlLaW4AHAhv8zoN9cTmveX6v86AVqcJ4LCaRCMTChTH8/NsjbisTq1lpBfWCLWS1spqwSHB4vol/YSCdMA=="], - "@firebase/analytics-types": ["@firebase/analytics-types@0.8.4", "", {}, "sha512-zQ+XTgkwH6CY/eUSHJRP7e4LxM30RCxlCmob5sy2axs25GE3Ny0XdgpDscMTHHQIGqWkxPXad4w2Mw9sCgT8zQ=="], + "@firebase/analytics-types": ["@firebase/analytics-types@0.8.5", "", {}, "sha512-kdnooE7Bis2jEnsqcerRwn/UQpH5D3uvHpku7OdUM9TJN3omlu6iYtbyAQ6XkAJRgJtO0aNf9OOkW8J6D59oCA=="], - "@firebase/app": ["@firebase/app@0.16.0", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/logger": "0.5.1", "@firebase/util": "1.15.2", "idb": "7.1.1", "tslib": "^2.1.0" } }, "sha512-G+ZGEyVP8YTb3ay6A+XpcYgFH3sTESHcnHU/EyTktodqhz2BHkLq+QEP7IVwjiMX0cxYwpVKip0/wC0KZcn9vQ=="], + "@firebase/app": ["@firebase/app@0.16.1", "", { "dependencies": { "@firebase/component": "0.7.5", "@firebase/logger": "0.5.2", "@firebase/util": "1.15.3", "idb": "7.1.1", "tslib": "^2.1.0" } }, "sha512-tjUEorFyKrurH7PbLWv9zDHRuU4mLefgD/yY38D584ziorIRlQz/PVjx4c/SCGyCuUlmyzt72mK+Lh+COAywNQ=="], - "@firebase/app-check": ["@firebase/app-check@0.13.0", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/logger": "0.5.1", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-AbMttBKazQvGVXBZhQdVAdPzRhwHyJAY3Ghu5y2C7IZKIDIppzNYz0shTZ1mP4FBJa+28BuC4t+5h1Q6pT3Asg=="], + "@firebase/app-check": ["@firebase/app-check@0.13.1", "", { "dependencies": { "@firebase/component": "0.7.5", "@firebase/logger": "0.5.2", "@firebase/util": "1.15.3", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-l8y3dmnhodXks/APAwx4tWqRl3tk8b9874KF1FJyKg1DIU+kMD0l52iz7S9/MW+eK8k6cjJg0G0iJ5KQAsQpow=="], - "@firebase/app-check-compat": ["@firebase/app-check-compat@0.4.6", "", { "dependencies": { "@firebase/app-check": "0.13.0", "@firebase/app-check-types": "0.5.4", "@firebase/component": "0.7.4", "@firebase/logger": "0.5.1", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-2pzNEZEkX84jSqy6TH6FI1HSLA1lc7kakRUybBbKjg9YhIttPlW/XX3N9CDtChji2PTTPWVPZiWhB10exHfA+A=="], + "@firebase/app-check-compat": ["@firebase/app-check-compat@0.4.7", "", { "dependencies": { "@firebase/app-check": "0.13.1", "@firebase/app-check-types": "0.5.5", "@firebase/component": "0.7.5", "@firebase/logger": "0.5.2", "@firebase/util": "1.15.3", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-fBb/xSMyIKv1nDmccfzz3IAGBzx/cQOxmZai66rJzifb1hMMkztf824Xx7LhpTUe7HNUbXwY90IvJ66fi8q6yg=="], - "@firebase/app-check-interop-types": ["@firebase/app-check-interop-types@0.3.4", "", {}, "sha512-zz3i6e13B8BfWiLy8MABtTh8aGIACgKbf9UVnyHcWs+yQzJXgQcl8A46b0zfaiJHdQ+niF0ouAfcpuf+3LMPQg=="], + "@firebase/app-check-interop-types": ["@firebase/app-check-interop-types@0.3.5", "", {}, "sha512-qId34pVZ2CXTmtu4ofW5leiI93DvnOvIcr/5GT7MZPw5WXAi6nZoU+g9cNRgl7K90UJSbK0cXxten4meYMPyZg=="], - "@firebase/app-check-types": ["@firebase/app-check-types@0.5.4", "", {}, "sha512-xV7JsIyzVr15aA7f3Pi0rB9gdBuVubs89FGA8VkRYA4g0l78poADgdfrScgf7NndSg9mm7cR7PJyY0+t22KaGw=="], + "@firebase/app-check-types": ["@firebase/app-check-types@0.5.5", "", {}, "sha512-+DF4gzFrlwGFyky38o4T/YN/r51l70yCtJ2HTkwmRj8FCMwPjm4hLH4fQbj6BUvzkiFqliBkitFsRpf1/YZkWA=="], - "@firebase/app-compat": ["@firebase/app-compat@0.5.16", "", { "dependencies": { "@firebase/app": "0.16.0", "@firebase/component": "0.7.4", "@firebase/logger": "0.5.1", "@firebase/util": "1.15.2", "tslib": "^2.1.0" } }, "sha512-shQq37O8qELDzvsVwYPlDXwD1zlcrZ0m2bpBF5ov2HSbY8x+AHsnL5TtJ2e1JAfkQN05qHao1AfabS69PN6GiA=="], + "@firebase/app-compat": ["@firebase/app-compat@0.5.17", "", { "dependencies": { "@firebase/app": "0.16.1", "@firebase/component": "0.7.5", "@firebase/logger": "0.5.2", "@firebase/util": "1.15.3", "tslib": "^2.1.0" } }, "sha512-5GdJWobqs6jbNYOnaQiSa4Ng8gnFerhqr7nY+v5jlnT7o9QbEeIZRLPQpnLe0TxYSWfRV2lAMbyR0kbXeIos9Q=="], - "@firebase/app-types": ["@firebase/app-types@0.9.5", "", { "dependencies": { "@firebase/logger": "0.5.1" } }, "sha512-YevqTjvo7Iujsa9Dwowmd6dSoElhzmD63ZSrq6bzjvQ6POjYgNjOFHLmNIgJs48eNO093NCERibuFnxbfOvU7A=="], + "@firebase/app-types": ["@firebase/app-types@0.9.6", "", { "dependencies": { "@firebase/logger": "0.5.2" } }, "sha512-yPLahy7Esfu2w/yme3msVK4xTkDXQqq6szfQn8yVOQpCKiT5GVFjqNpLbuz6NkX0WuTwUidkmPewW3r4xkvpeg=="], - "@firebase/auth": ["@firebase/auth@1.13.4", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/logger": "0.5.1", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@react-native-async-storage/async-storage": "^2.2.0 || ^3.0.0" }, "optionalPeers": ["@react-native-async-storage/async-storage"] }, "sha512-s+NS1aV0DDyyfoIMeSz53HXnVTv7ufJjJfrP63XyaWHweJ5vOoxKWrTm5tO7S7PDqvyOa/Wi3oP0dgAo6JTMMA=="], + "@firebase/auth": ["@firebase/auth@1.13.5", "", { "dependencies": { "@firebase/component": "0.7.5", "@firebase/logger": "0.5.2", "@firebase/util": "1.15.3", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@react-native-async-storage/async-storage": "^2.2.0 || ^3.0.0" }, "optionalPeers": ["@react-native-async-storage/async-storage"] }, "sha512-1AXoBJqBVD8WL8FZYo3S2GmJF9YUoom6Y6ngMxOSkzzhW5sT83pLchb6TGFgxes91dfXx8s/VYc5VrLDNqpLog=="], - "@firebase/auth-compat": ["@firebase/auth-compat@0.6.9", "", { "dependencies": { "@firebase/auth": "1.13.4", "@firebase/auth-types": "0.13.1", "@firebase/component": "0.7.4", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-/hHeTBmQ61+N5J1RECls+WfskZTY78JXr7aO5EMOfUpqJvDqvoS+568k0rp6Ss/4UWwBjadILs+H+SGy1zCS3A=="], + "@firebase/auth-compat": ["@firebase/auth-compat@0.6.10", "", { "dependencies": { "@firebase/auth": "1.13.5", "@firebase/auth-types": "0.13.2", "@firebase/component": "0.7.5", "@firebase/util": "1.15.3", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-Bvklg2nL7BrBFCAqdsleW8fse9Jh0fARqJPlJmA40uermfWx1bJiO7dnKyZN3J39d2TFVd4VJXtg3i6Wg92/YQ=="], - "@firebase/auth-interop-types": ["@firebase/auth-interop-types@0.2.5", "", {}, "sha512-1Li/YuBDBAXcKv7BzY4U28gontUmAaw53sYiqbaVOMCFb2lFKK/c3CGMUWqtwe7+TXrl3poWnTCL5umYBg85Eg=="], + "@firebase/auth-interop-types": ["@firebase/auth-interop-types@0.2.6", "", {}, "sha512-FgwZqDrBqgK0BHI70QTv1v/5wmuDF9f8fsJFvKSxoRlK2PPfSQtZAk2jhXu4pe9BZzFi/e4UYusU/bEQHdf6Qg=="], - "@firebase/auth-types": ["@firebase/auth-types@0.13.1", "", { "peerDependencies": { "@firebase/app-types": "0.x", "@firebase/util": "1.x" } }, "sha512-0c1Mnid0uMDfGJHeUS4zfvBa4/CedJXotGy/n/NZJnBjwiJawt0ZYU+wH2VAVLiRCEfG2ncCkAX3yd1/2nrB7g=="], + "@firebase/auth-types": ["@firebase/auth-types@0.13.2", "", { "peerDependencies": { "@firebase/app-types": "0.x", "@firebase/util": "1.x" } }, "sha512-OU+miuoSxIWYN7GT291d2ylVJBL3k/OePo7/JDSoQtkFQoEiGBc4AHuMjj/seqFIsHrqnjrAfRCk4pfufoJolQ=="], - "@firebase/component": ["@firebase/component@0.7.4", "", { "dependencies": { "@firebase/util": "1.15.2", "tslib": "^2.1.0" } }, "sha512-tLpOaaCol9ugUIYp2R3CbWPPA8Ajg/papX/XHEy8U52b/QXH3BbX8tTJX9aShDCjp+9sMAxMLD94i7lresdugQ=="], + "@firebase/component": ["@firebase/component@0.7.5", "", { "dependencies": { "@firebase/util": "1.15.3", "tslib": "^2.1.0" } }, "sha512-vuFDcL91Q+2ZuBJkyOh86T4q0B4ffNTDjc/A38tybO56odQABxRTFLTIowCWqAKeIcgo37GowWMVgFF73gD8Qw=="], - "@firebase/data-connect": ["@firebase/data-connect@0.7.3", "", { "dependencies": { "@firebase/auth-interop-types": "0.2.5", "@firebase/component": "0.7.4", "@firebase/logger": "0.5.1", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-nHBFk3Ntl+NZCRIUG2d5j7I69P0otjyQ/duhVKLbw4+5cNke/F6RK1pdE5Jnf831/QOTs2Bd00LlxlZ+jNsb9w=="], + "@firebase/data-connect": ["@firebase/data-connect@0.7.4", "", { "dependencies": { "@firebase/auth-interop-types": "0.2.6", "@firebase/component": "0.7.5", "@firebase/logger": "0.5.2", "@firebase/util": "1.15.3", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-su1aGWlzhxb+xtggCUSsufJn1FDa06SBDK71y+fpQ+g2zMhMExik6FUv/odkKzOF/xfWVjabCbWBcjJY3MceDA=="], - "@firebase/database": ["@firebase/database@1.1.4", "", { "dependencies": { "@firebase/app-check-interop-types": "0.3.4", "@firebase/auth-interop-types": "0.2.5", "@firebase/component": "0.7.4", "@firebase/logger": "0.5.1", "@firebase/util": "1.15.2", "faye-websocket": "0.11.4", "tslib": "^2.1.0" } }, "sha512-D+j4+8uhGtNd1tVD+X+c8JrC4ppStGJKyujSQt2NPwdN26QcCk0BeIxue+UqspHkHiFHyQOimwlzjLewGq6S+A=="], + "@firebase/database": ["@firebase/database@1.1.5", "", { "dependencies": { "@firebase/app-check-interop-types": "0.3.5", "@firebase/auth-interop-types": "0.2.6", "@firebase/component": "0.7.5", "@firebase/logger": "0.5.2", "@firebase/util": "1.15.3", "faye-websocket": "0.11.4", "tslib": "^2.1.0" } }, "sha512-/JGpvszLoNXNgzilRXocigGfFF4hbcPA9wN1i1kjJx6oKkXgkHteZYl3lQs1lJX3ETDf6bv7zI15lPMVUp4sAQ=="], - "@firebase/database-compat": ["@firebase/database-compat@2.1.6", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/database": "1.1.4", "@firebase/database-types": "1.0.21", "@firebase/logger": "0.5.1", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" }, "optionalPeers": ["@firebase/app", "@firebase/app-compat"] }, "sha512-mu7S/75UIajB1A5M9Vfojk69LttW55uABp9nHEtWrV/mIaSEwvoaIe9GySsEzS2EKFK5/3f5okcAuUbihhYeJg=="], + "@firebase/database-compat": ["@firebase/database-compat@2.1.7", "", { "dependencies": { "@firebase/component": "0.7.5", "@firebase/database": "1.1.5", "@firebase/database-types": "1.0.22", "@firebase/logger": "0.5.2", "@firebase/util": "1.15.3", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" }, "optionalPeers": ["@firebase/app", "@firebase/app-compat"] }, "sha512-lBq9sJm8MnJINKJnkAKSOj2MbC66xGoSVCcGkPtstl+lkoKEBtD46qHLbuDgW/WbLPoKVm17RIN8BxHj+Z2F2w=="], - "@firebase/database-types": ["@firebase/database-types@1.0.21", "", { "dependencies": { "@firebase/app-types": "0.9.5", "@firebase/util": "1.15.2" } }, "sha512-SX1jUqhttKgg/m9dYRTvqU9QvucBooziWfA986r4cpsbi4zlsvewe424j3Vpduwd6DG1MSAMfBVT2VqA61FnkA=="], + "@firebase/database-types": ["@firebase/database-types@1.0.22", "", { "dependencies": { "@firebase/app-types": "0.9.6", "@firebase/util": "1.15.3" } }, "sha512-YAZNXsjY9EQQ+pKw/3ax8n5FgolHC7Qew7EY5RceYdl0R2ZP+kCv1O0DkKlcceue8uQCOreHCNN7PWVFpY1Nug=="], - "@firebase/firestore": ["@firebase/firestore@4.17.0", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/logger": "0.5.1", "@firebase/util": "1.15.2", "@firebase/webchannel-wrapper": "1.0.6", "@grpc/grpc-js": "~1.9.0", "@grpc/proto-loader": "^0.7.8", "re2js": "^2.8.3", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-P9tof6pyO1bnLlMWbux+5O7WFJqlb7OTPMKxxOiXKYiQl7mxykAvxr1BFCgWeEXUU7DZxQncyJ040B0IhFVZCg=="], + "@firebase/firestore": ["@firebase/firestore@4.17.1", "", { "dependencies": { "@firebase/component": "0.7.5", "@firebase/logger": "0.5.2", "@firebase/util": "1.15.3", "@firebase/webchannel-wrapper": "1.0.7", "@grpc/grpc-js": "~1.9.0", "@grpc/proto-loader": "^0.7.8", "re2js": "^2.8.3", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-8lqPNf2w10CtYG+tayVjZO1pSyQpnhztQRudeD109VtXDzNbASTaYdO43sj5PMsDcWq0aOYY3RmJOUlXu9++jw=="], - "@firebase/firestore-compat": ["@firebase/firestore-compat@0.4.12", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/firestore": "4.17.0", "@firebase/firestore-types": "3.0.4", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-k2uX81Ao/S0jnFcWGPOQpKK1cPlJHvD9WIqh/RE1XBDP2yg5zhE4rHhSg1rtB11k39q3nKon9XLNDDrPjGclag=="], + "@firebase/firestore-compat": ["@firebase/firestore-compat@0.4.13", "", { "dependencies": { "@firebase/component": "0.7.5", "@firebase/firestore": "4.17.1", "@firebase/firestore-types": "3.0.5", "@firebase/util": "1.15.3", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-l9dCewxMzzLOIhcwTjERCKxrWOn1kZ9JvwOQq9zZNq4I/Nbvb/B9njT230V61uvQ9qZ3/qpUG758D8DDTEFXnw=="], - "@firebase/firestore-types": ["@firebase/firestore-types@3.0.4", "", { "peerDependencies": { "@firebase/app-types": "0.x", "@firebase/util": "1.x" } }, "sha512-jGn+JSS4X9zZsrfu7Yw66v5YRdOLD1oyQh4USR0xWl4CUqV/DA6bNIXRPpxH/cUl3iVTNiP6MN7g+EL42A4qfA=="], + "@firebase/firestore-types": ["@firebase/firestore-types@3.0.5", "", { "peerDependencies": { "@firebase/app-types": "0.x", "@firebase/util": "1.x" } }, "sha512-dbdMAQkMd5dwWc48eupz/Y6/E9ruat3+gY5lhVKscvvT/HnDBEEMzJW38zdKhgdnglZHGk2vUsJMOHAphMHGMA=="], - "@firebase/functions": ["@firebase/functions@0.13.6", "", { "dependencies": { "@firebase/app-check-interop-types": "0.3.4", "@firebase/auth-interop-types": "0.2.5", "@firebase/component": "0.7.4", "@firebase/messaging-interop-types": "0.2.5", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-9obLnzeQUivK5lmtGFOU2ucQ38BjTp+jpPtbfFp/mDsdVCvEpRqdWNvMMQ6aQwR4vcVc/utsvngm5BRkXbc7ZA=="], + "@firebase/functions": ["@firebase/functions@0.14.0", "", { "dependencies": { "@firebase/app-check-interop-types": "0.3.5", "@firebase/auth-interop-types": "0.2.6", "@firebase/component": "0.7.5", "@firebase/messaging-interop-types": "0.2.6", "@firebase/util": "1.15.3", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-DhuYFr0eMhp+s/PNEk6SiMsYkc00+XVOUeKbrl8MOzQNZI3SKQpqoDR1d+keNDAutwmHRWTUAdXBoVPD+xxVUw=="], - "@firebase/functions-compat": ["@firebase/functions-compat@0.4.6", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/functions": "0.13.6", "@firebase/functions-types": "0.6.4", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-dj9sOet+FIU91jeU4A3vGJoXHty7NqkSfjRLCwLgJXPDk1m72KFuxD3nlFgw/yXx/Fr7UjqzbxZ0LrIOdpx7+w=="], + "@firebase/functions-compat": ["@firebase/functions-compat@0.5.0", "", { "dependencies": { "@firebase/component": "0.7.5", "@firebase/functions": "0.14.0", "@firebase/functions-types": "0.6.5", "@firebase/util": "1.15.3", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-T3BDIToESZUHt7438wyKYMkRjKg3m1xAIux5fVpNvTRQlDOFLukWniQWBDhJ2znpU9kxMTR6+e31TVo8P15PZw=="], - "@firebase/functions-types": ["@firebase/functions-types@0.6.4", "", {}, "sha512-zV6kgqtduR4rUAdC/ilS7kmb93XD7bEZoJDlVBZqlOw2uGGGCNBQBuleww2rr0Ulr3L9o2TDjumEt68/l1f9DQ=="], + "@firebase/functions-types": ["@firebase/functions-types@0.6.5", "", {}, "sha512-Zc0pURjthHXzSj54ZivCkzKDSV1r/wIpnmHdhq82q2yFFPVoncG/ZJjnVMiANvQfeww/QnElhzODpfwUucVwdA=="], - "@firebase/installations": ["@firebase/installations@0.6.23", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/util": "1.15.2", "idb": "7.1.1", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-MBkbcQfd+3qHjW+slsH4s7jH5qTdGlYpwqmxEZ7QcIpgDxu1SKyU0f+mCZhCt1BCacLNiOWF5L0R06N0LtlfMg=="], + "@firebase/installations": ["@firebase/installations@0.6.24", "", { "dependencies": { "@firebase/component": "0.7.5", "@firebase/util": "1.15.3", "idb": "7.1.1", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-Ui52ey8wHoWqkBbXRKJEKYWylI0JZogZmoLS+o8Anh1bxWtK27ZYjLla1UJAAdC5DCKLJ2qAp0VpJOjg8VOX1g=="], - "@firebase/installations-compat": ["@firebase/installations-compat@0.2.23", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/installations": "0.6.23", "@firebase/installations-types": "0.5.4", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-isaXmjb9roM83eVeXAe+ZRNKYNsSo2s0aNM+cy04AAGEyVL/d8Aa11GwEXovRFeYjl9+1yRAOxRDTOukZRwTxA=="], + "@firebase/installations-compat": ["@firebase/installations-compat@0.2.24", "", { "dependencies": { "@firebase/component": "0.7.5", "@firebase/installations": "0.6.24", "@firebase/installations-types": "0.5.5", "@firebase/util": "1.15.3", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-8M5nlcWwYt881x83COP2odq5vgf+NgwJh+RMd4LRSv8JI1pxwDfgrDJOERrjTgfC9J5Z0vnQX4b1pdN914e0Zw=="], - "@firebase/installations-types": ["@firebase/installations-types@0.5.4", "", { "peerDependencies": { "@firebase/app-types": "0.x" } }, "sha512-U2eFapdHwjb43Vx9o+Pmj4dFfvcHEK1IirEFLqMtWrTHvmdrS3gBpBD1kmJk/9HjsOtoHZxJ2Paoe79e+L1ZPg=="], + "@firebase/installations-types": ["@firebase/installations-types@0.5.5", "", { "peerDependencies": { "@firebase/app-types": "0.x" } }, "sha512-e9UYcju3puDl1vdrcKIi5dExzHLameOT/Tc61Q48PYwxtsM1NzZh/ikGbdBQTsbRgg0EMZqdPr0/m5ODUBobrg=="], - "@firebase/logger": ["@firebase/logger@0.5.1", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-vZKLsqE1ABOy8OjQiE7cUTFn4gvaqlk88yp8N94Pk/sDpq61YqZGqmVFZTvOyflTwuYFcWirBdYGoJgbDaXKYQ=="], + "@firebase/logger": ["@firebase/logger@0.5.2", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-J2VO4NFTc0xQFrxV1B/lm5balicm9cwuX2acR9Yn41fN8KgUeQFo+VJV222IqW2FPSXKDu9uo5WdQFWf9TPbYg=="], - "@firebase/messaging": ["@firebase/messaging@0.13.1", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/installations": "0.6.23", "@firebase/messaging-interop-types": "0.2.5", "@firebase/util": "1.15.2", "idb": "7.1.1", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-kL8fdjbNBI7hprlXJrUjktDWosrpT4JtfwXtVVevImPF/rBRAsC+LS/jIs+kgQVuotnvMhaBCgAFipBoY9YU9g=="], + "@firebase/messaging": ["@firebase/messaging@0.13.2", "", { "dependencies": { "@firebase/component": "0.7.5", "@firebase/installations": "0.6.24", "@firebase/messaging-interop-types": "0.2.6", "@firebase/util": "1.15.3", "idb": "7.1.1", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-KcZoqUu2ih4sLH91dW9tmyHjCR0IQyNzSLZunX5uq7cLeImXb4uO2I0wq5FACduO2I+FoTeWa2BtUv7Jpowqdw=="], - "@firebase/messaging-compat": ["@firebase/messaging-compat@0.2.28", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/messaging": "0.13.1", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-/AmMqHRnSQhPsdeED3ocs+s30/tpFvZDiiwIYY2uXFRvLujo1fnbPOeCFoe4Y+dRy1LCSjpvJf+dy5ZTsxi1yg=="], + "@firebase/messaging-compat": ["@firebase/messaging-compat@0.2.29", "", { "dependencies": { "@firebase/component": "0.7.5", "@firebase/messaging": "0.13.2", "@firebase/util": "1.15.3", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-8Twe4CeYvAx8AzjBxyyQFKzinaMGGt13hPQBqaARQ2QZjagrEaqSVBe+Zy6F4L/vT8DV168yRgRu7W/RK7p+4w=="], - "@firebase/messaging-interop-types": ["@firebase/messaging-interop-types@0.2.5", "", {}, "sha512-tUEKnaAP2Y/MNIqgnriPpV6e5l13Vs/+p2yrd6NGlncPJT9O3a8muYZtdnWe+IJ4fgKLHJVC79n/asxk/N5Msw=="], + "@firebase/messaging-interop-types": ["@firebase/messaging-interop-types@0.2.6", "", {}, "sha512-MVzvkKe2V4H2dHu5oOxRfeKQcfTwWmCgnzsC4V1q3ixun5iiL8riCZ2qI35rDhCL4glPGiu0jHxDbpVNuTKfow=="], - "@firebase/performance": ["@firebase/performance@0.7.13", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/installations": "0.6.23", "@firebase/logger": "0.5.1", "@firebase/util": "1.15.2", "tslib": "^2.1.0", "web-vitals": "^4.2.4" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-1u6fuXP9cj0s+lkTFAspr/ttfPebPbEdpx+5Wdr4mPZbp8qH2KCMxOddEAR1ZMRa5GI0E7hDYSnolEmbqOFOAg=="], + "@firebase/performance": ["@firebase/performance@0.7.14", "", { "dependencies": { "@firebase/component": "0.7.5", "@firebase/installations": "0.6.24", "@firebase/logger": "0.5.2", "@firebase/util": "1.15.3", "tslib": "^2.1.0", "web-vitals": "^4.2.4" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-9PH1XEZVHErxGdbXluvGz4Uyjw4W955H8v7Mv9rHIybRrg5F2Ac2tvf5+mSf5EtnxWNmxrD2WLnvMFaZP4sMrQ=="], - "@firebase/performance-compat": ["@firebase/performance-compat@0.2.26", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/logger": "0.5.1", "@firebase/performance": "0.7.13", "@firebase/performance-types": "0.2.4", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-jgoocXLN6ao26xWQ8pzosmzQ33uLzGBJQPNK0NTbVy1XvIHr5pfgBf9hWLOxsWe+R7sJq5bjD+8ybXprmt61mA=="], + "@firebase/performance-compat": ["@firebase/performance-compat@0.2.27", "", { "dependencies": { "@firebase/component": "0.7.5", "@firebase/logger": "0.5.2", "@firebase/performance": "0.7.14", "@firebase/performance-types": "0.2.5", "@firebase/util": "1.15.3", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-O/ozTf/EbChN94Pk7bd1eUC0PAC36726AwsaiJyC0bZzSBWfLGSWASGPH5pebUWXQPJtGxIJYRkkbX5l0Qa+Hw=="], - "@firebase/performance-types": ["@firebase/performance-types@0.2.4", "", {}, "sha512-kJSEk7b0uhpcPRyL4SQ/GPujLqk52XNKcXlnsKDbWGAb9vugcLvOU3u6zfEdwd+d8hWJb5S5ZizV1JFFI0nkKg=="], + "@firebase/performance-types": ["@firebase/performance-types@0.2.5", "", {}, "sha512-PRzOgB+/M+6AKlEkY8a9xy5Ff5SfZPIh4iShXhn2WAcL/euSbK7bdLqWysHduunNJhGFsXa22Ag3ixqL6rQtYg=="], - "@firebase/remote-config": ["@firebase/remote-config@0.9.1", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/installations": "0.6.23", "@firebase/logger": "0.5.1", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-nzQUSJnk1zAZEl2Q5O3I7Z61cYLK5JI4H6wyyOiHkVZ+bmgy1YXNNMptNbVjixMQ/eCzgA6nZRaC+1eBcJGUFA=="], + "@firebase/remote-config": ["@firebase/remote-config@0.9.2", "", { "dependencies": { "@firebase/component": "0.7.5", "@firebase/installations": "0.6.24", "@firebase/logger": "0.5.2", "@firebase/util": "1.15.3", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-Rii93DkXjM+RE/ytHdYa7EIiQLJbdBr+W8EEiqd/vbLCOC+1FdkDuRiumJBp6t3yewHGbdqbpjB3fk3z0cZ+8g=="], - "@firebase/remote-config-compat": ["@firebase/remote-config-compat@0.2.28", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/logger": "0.5.1", "@firebase/remote-config": "0.9.1", "@firebase/remote-config-types": "0.5.1", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-kEO9Gn6fbmVj7eNUtZ6d59mLgUDUD0qo7aCicGOWNfuRWTaUv3CF9DMYychO61zaEQ3cfA+CEny4V1E8A1gRGA=="], + "@firebase/remote-config-compat": ["@firebase/remote-config-compat@0.2.29", "", { "dependencies": { "@firebase/component": "0.7.5", "@firebase/logger": "0.5.2", "@firebase/remote-config": "0.9.2", "@firebase/remote-config-types": "0.5.2", "@firebase/util": "1.15.3", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-mY7JtTISK6F4g4T0x3kVepr5cp0NXL7f5yjIUXXGaTrg4qUlFBWRbENaHaqZ78dwmNcLm24h/yPsOVRlDXEXhA=="], - "@firebase/remote-config-types": ["@firebase/remote-config-types@0.5.1", "", {}, "sha512-cX/1LT6KQwkXzck2eSzeKnuvXZCyr8qaPpDcikoJs7jmI+oBOXixpDLeDtWj1U6GNMkIoXrEDNoyT2Ypcyp5/A=="], + "@firebase/remote-config-types": ["@firebase/remote-config-types@0.5.2", "", {}, "sha512-i8k1omVfoAnaT1ZPv2FFjxMZrATYsO/GnFgHEj5+7fAJLzi8wLnGGv1WK06oEAD6ltrWXSO1HzeNyajn/NjMWw=="], - "@firebase/storage": ["@firebase/storage@0.14.4", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-jfzEWZb3Fpsq3FwAB2ifoc8mcSh935qXdDou3TpyjDWa45hhNcZUv8/w28/10njByhfK7snbakKN30nwnzQ3/w=="], + "@firebase/storage": ["@firebase/storage@0.14.5", "", { "dependencies": { "@firebase/component": "0.7.5", "@firebase/util": "1.15.3", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-r2tozN/BlEewLi70tJNUQPzWwbex9GM7NgXZsamHKQrjKEfcR0i4jGgHBKAKA4hbwiPE9eNMb3hcxWnDpeJZwg=="], - "@firebase/storage-compat": ["@firebase/storage-compat@0.4.4", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/storage": "0.14.4", "@firebase/storage-types": "0.8.4", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-qSRgCB9f2R/nCp8t/8OC101cIFBFeUazlRInOMdzbnLzvrQBzEfx19SrR4pvdj/0+M+P/y8AK/a2s+3EB+B1Pw=="], + "@firebase/storage-compat": ["@firebase/storage-compat@0.4.5", "", { "dependencies": { "@firebase/component": "0.7.5", "@firebase/storage": "0.14.5", "@firebase/storage-types": "0.8.5", "@firebase/util": "1.15.3", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-vO0tFPxXbKDKdlTu8tYT08S9t9ezUTJYEdLCULpWxWq2aq6zojwN1QmAB+1a50AI/g47GlWUJn1XPncm/PDZsw=="], - "@firebase/storage-types": ["@firebase/storage-types@0.8.4", "", { "peerDependencies": { "@firebase/app-types": "0.x", "@firebase/util": "1.x" } }, "sha512-BT7cwxJOx8SWwlQfrlC+bD/Sk3Cw+1odCi8UZNFNWTVZoPsBnA5W+mqtZzVnvsdJpXCFGSGQ7R7vOR6dtM/BRA=="], + "@firebase/storage-types": ["@firebase/storage-types@0.8.5", "", { "peerDependencies": { "@firebase/app-types": "0.x", "@firebase/util": "1.x" } }, "sha512-GEDs5P+rNUfNcS+wxIdOLAHficife2YXtvTJnyi3ssrX11AAtBg+nDUdbYh8vuBzWehVQZPmztGUUnud4L+4yg=="], - "@firebase/util": ["@firebase/util@1.15.2", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-974pWIZVLDMc5GW5YAsj8y0XxULxIy/sPUy7tsxmWbF93KRIyh9xpuHlh0zDL+shUcf5nHDjFOg9YLiQ763eiA=="], + "@firebase/util": ["@firebase/util@1.15.3", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-c/z/gaIlaaLZEuGbE6sLUuJ61tskg1JghvhcNQzW948ASBinbVBBRnZTC4b4yt4LaEtJQkYlyzqLHcutFwEIvA=="], - "@firebase/webchannel-wrapper": ["@firebase/webchannel-wrapper@1.0.6", "", {}, "sha512-Vr/Mqu79dMwGRAyGbJ4uN4+BtXB3/mRTdzetD1daWNeG8QaWuzhhbG77GltO5c0yYmYls8i250iX73624GJd7Q=="], + "@firebase/webchannel-wrapper": ["@firebase/webchannel-wrapper@1.0.7", "", {}, "sha512-phBFwieDLvkZGYN9CE9ZFNEIoBVksprzsnCzQejCmCHtgwCXReeuRpoEGN9C4EbhONztv8NRV1tau6Rb9pONwQ=="], "@floating-ui/core": ["@floating-ui/core@1.8.0", "", { "dependencies": { "@floating-ui/utils": "^0.2.12" } }, "sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ=="], @@ -623,7 +681,7 @@ "@maplibre/maplibre-gl-style-spec": ["@maplibre/maplibre-gl-style-spec@19.3.3", "", { "dependencies": { "@mapbox/jsonlint-lines-primitives": "~2.0.2", "@mapbox/unitbezier": "^0.0.1", "json-stringify-pretty-compact": "^3.0.0", "minimist": "^1.2.8", "rw": "^1.3.3", "sort-object": "^3.0.3" }, "bin": { "gl-style-format": "dist/gl-style-format.mjs", "gl-style-migrate": "dist/gl-style-migrate.mjs", "gl-style-validate": "dist/gl-style-validate.mjs" } }, "sha512-cOZZOVhDSulgK0meTsTkmNXb1ahVvmTmWmfx9gRBwc6hq98wS9JP35ESIoNq3xqEan+UN+gn8187Z6E4NKhLsw=="], - "@maplibre/mlt": ["@maplibre/mlt@1.1.12", "", { "dependencies": { "@mapbox/point-geometry": "^1.1.0" } }, "sha512-ZeK5w2TTeHOajcLaEQs1KZXw2V9wIKo1PmThlxlsHoXsQsYlBqLJzPOd6tJHRtGTChUY3DPPmjXRArYVvAbmZw=="], + "@maplibre/mlt": ["@maplibre/mlt@1.2.0", "", { "dependencies": { "@mapbox/point-geometry": "^1.1.0" } }, "sha512-g45M8gEI4sMO3X9ib4K7n3ZKFf0qQOL+NMkHCnEK51lOrYFHiEssOuZncx1+miIgi1IEE2NcbRMcq8RBkL+QHA=="], "@maplibre/vt-pbf": ["@maplibre/vt-pbf@4.3.2", "", { "dependencies": { "@mapbox/point-geometry": "^1.1.0", "@types/geojson": "^7946.0.16", "pbf": "^5.1.0" } }, "sha512-j6p0AdjvAR19Z3XaCysle7A4ZSo08tYOzxD0Y9NQylwPAkwJJeYub5b2eVucdeDh7erhv69DahoLOevDRERRUw=="], @@ -763,43 +821,43 @@ "@oxc-project/types": ["@oxc-project/types@0.127.0", "", {}, "sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ=="], - "@oxc-resolver/binding-android-arm-eabi": ["@oxc-resolver/binding-android-arm-eabi@11.24.2", "", { "os": "android", "cpu": "arm" }, "sha512-y09e0L0SRI2OA2tUIrjBgoV3eH5hvUKXNkJqXmNo5V2WxIjyC7I7aJfRLMEVpA8yi95f90gFDvO0VMgrDw+vwA=="], + "@oxc-resolver/binding-android-arm-eabi": ["@oxc-resolver/binding-android-arm-eabi@11.21.2", "", { "os": "android", "cpu": "arm" }, "sha512-xQoCRv+gKax9KTdwdaQNnAFOai8neay7g3jExDIORzhbrejwGSJaZNTdOJHR5ziLg2joMxOCMOFMo4zuxza2uQ=="], - "@oxc-resolver/binding-android-arm64": ["@oxc-resolver/binding-android-arm64@11.24.2", "", { "os": "android", "cpu": "arm64" }, "sha512-cl4icWaZFnLdg8m6qtnh5rBMuGbxc/ptStFHLeCNwr+2cZjkjNwQu/jYRS0CHlnPecOJMpuS5M6/BH+0J/YkEg=="], + "@oxc-resolver/binding-android-arm64": ["@oxc-resolver/binding-android-arm64@11.21.2", "", { "os": "android", "cpu": "arm64" }, "sha512-HF5oiE2L05yInPYCFD/4uxSrEZW4SuIfn99Y6L1xnJnzl066JR+MJs2rIdstw8A2MPlAKH+13dpFPNycjqzvGg=="], - "@oxc-resolver/binding-darwin-arm64": ["@oxc-resolver/binding-darwin-arm64@11.24.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-At29QEMF6HajbQvgY8K6OXnHD1x9rad74xBEfmCB6ZqCGsdq75aK7tOYcTbOanMy8qdIBrfL3SMr3p/lfSlb9w=="], + "@oxc-resolver/binding-darwin-arm64": ["@oxc-resolver/binding-darwin-arm64@11.21.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-UX4u49CVCAD8QZNELaW8eMGgMAGwFWYEPbvNsh+3r/gs4NX3KfpiACMVwRQT0EuH3uat9hM5Zl+Ppm9pJD8tgg=="], - "@oxc-resolver/binding-darwin-x64": ["@oxc-resolver/binding-darwin-x64@11.24.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-A5Kqr1EUj4oIL5CF4WRssq/o5P0Y11cwoFouMRmQ7YnC/A8V93nv1nb7aSU8HwcgmXropjLNkVTl4MN87cu28Q=="], + "@oxc-resolver/binding-darwin-x64": ["@oxc-resolver/binding-darwin-x64@11.21.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-J9xPx7YBkrRmJ+xl561ztnMWEc1aOyjEIxBiGX1dVb3u7bGSnfObfcZk+Pd+uM0HZAPNsQ1xvD8j52A/uOSqNQ=="], - "@oxc-resolver/binding-freebsd-x64": ["@oxc-resolver/binding-freebsd-x64@11.24.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-R5xkRBRRz7ceH/P5Jrc6G7FmdUdgpLYyESFAUDVTNQ9K0sGPxcp4ljiwEwEqsvNcQ4sYbMRrWcHHBCu7ksAJVw=="], + "@oxc-resolver/binding-freebsd-x64": ["@oxc-resolver/binding-freebsd-x64@11.21.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-fRlt7OvSaQkWj6+EDTVxawVxOlqJB2QSnBfkeCyK4RTvsGctbw3BiH2Tb7DzMs7bikc4BRBpvWP5zF9K8b54Zg=="], - "@oxc-resolver/binding-linux-arm-gnueabihf": ["@oxc-resolver/binding-linux-arm-gnueabihf@11.24.2", "", { "os": "linux", "cpu": "arm" }, "sha512-k/RuYL4L/R58IBn3wT5ma3Wh4k62bp1eYCFRWCmMsasUOqL+H6sW0VGFadEzKWXFFlz+2uIMoeMk9ySSZJHgbg=="], + "@oxc-resolver/binding-linux-arm-gnueabihf": ["@oxc-resolver/binding-linux-arm-gnueabihf@11.21.2", "", { "os": "linux", "cpu": "arm" }, "sha512-gK+vPUcPQITkGwBKpZGrcDHSlU6eDGl7AQacxS2CEKAZIBHWkOVFeJwLZ4tYnA1acJqRM5lt7yYwPCVqGHIJ7A=="], - "@oxc-resolver/binding-linux-arm-musleabihf": ["@oxc-resolver/binding-linux-arm-musleabihf@11.24.2", "", { "os": "linux", "cpu": "arm" }, "sha512-bnHAak3ujYfH5pKk4NieFNbvYvernfoQDgwLddbZ3OtMYrem87/qjlA+u+aKG0oZcqSLGCful/6/CEA+aeAgaA=="], + "@oxc-resolver/binding-linux-arm-musleabihf": ["@oxc-resolver/binding-linux-arm-musleabihf@11.21.2", "", { "os": "linux", "cpu": "arm" }, "sha512-L/Rgas7SrOKy/z7IH+HxSFRqVO4PuLDKLEGKvnhoCBBq3UJ0YzGBou3qMzaAGgkJwsIvX2pBF+7ojzfUhLiZxQ=="], - "@oxc-resolver/binding-linux-arm64-gnu": ["@oxc-resolver/binding-linux-arm64-gnu@11.24.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-vDT3KHgzYp47gmtNOqL2VNhCyl5Zv643eyxm//A68J8DeUGXrvD1pZFiaT4jSfe+RInfnn1R2yVHye4enx6RnA=="], + "@oxc-resolver/binding-linux-arm64-gnu": ["@oxc-resolver/binding-linux-arm64-gnu@11.21.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-CUEYvlX1Fk7E9kUMzuswru1J9HLxMwnpDeQGjQuI4ZH+iNCoa2X9T+pvyzrbsgl7WnIeTFTlNlHsRfVdf5g9/g=="], - "@oxc-resolver/binding-linux-arm64-musl": ["@oxc-resolver/binding-linux-arm64-musl@11.24.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-+kMlQvbzfyEYtu5FcjE4p+ttBLpKW4d/AsAsuE69BxV6V4twZJeIQZFfD8gh/wqglY0MkPSezWXQH0jBV13MUw=="], + "@oxc-resolver/binding-linux-arm64-musl": ["@oxc-resolver/binding-linux-arm64-musl@11.21.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-ViN1ZibQyxwC67GpoP33oo+S9UyUnkog13vzQb9+v9bCNvrVzJuk0MRdacjtv/9xfRMVF/eqHFyl8YOeykI10Q=="], - "@oxc-resolver/binding-linux-ppc64-gnu": ["@oxc-resolver/binding-linux-ppc64-gnu@11.24.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-shjfMhmZ3gq9fv/w7bi3PnZlgOPG+2QAOFf0BJF0EgBSIGZ6PMLN2zbGEblTUYB/NKVDRyYhE2ff3dJ1QqNPkA=="], + "@oxc-resolver/binding-linux-ppc64-gnu": ["@oxc-resolver/binding-linux-ppc64-gnu@11.21.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-CU1sCqWnhGqYD5I1HedHk5pujrn7ssDkNB/AEQd/pd3D/EojVSgJUlpbafwIbyhia3PgIfkvdFpRPWSALzVumA=="], - "@oxc-resolver/binding-linux-riscv64-gnu": ["@oxc-resolver/binding-linux-riscv64-gnu@11.24.2", "", { "os": "linux", "cpu": "none" }, "sha512-zGelwFR5oRo+b69k8Lrzun86DyUHzfKN6cnjbR9l7Z7NIRznOE/2ZvPa1IUKqAL2PzAXOdwkfVqNvO1H2RlpAw=="], + "@oxc-resolver/binding-linux-riscv64-gnu": ["@oxc-resolver/binding-linux-riscv64-gnu@11.21.2", "", { "os": "linux", "cpu": "none" }, "sha512-jWVyZtIHca4Gb96x7dag+y69vlei7ffjrsveLkmf2ZhqEAz6ZSBnY1GWvgZUaZlwZP62A3xD092BW97Q5VGc+g=="], - "@oxc-resolver/binding-linux-riscv64-musl": ["@oxc-resolver/binding-linux-riscv64-musl@11.24.2", "", { "os": "linux", "cpu": "none" }, "sha512-qxZ1SWCXJY0eyhAlP6Lmo9F2Nrtx7EkYj9oCgL8apDPCwXwCEDA2U697bbT81JIc2IrVjxO4KX6WU2N+oN9Z4w=="], + "@oxc-resolver/binding-linux-riscv64-musl": ["@oxc-resolver/binding-linux-riscv64-musl@11.21.2", "", { "os": "linux", "cpu": "none" }, "sha512-LF29obFqNgBUgDX7rmUK7M4D0JQG5LxhYzn3xXmECcHU9aQAdWG7NiY052qybtesEdwHQXKNTWYQ7mTsybNvWg=="], - "@oxc-resolver/binding-linux-s390x-gnu": ["@oxc-resolver/binding-linux-s390x-gnu@11.24.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-sGCecF3cx2DFlH4t/z7ApnOnXqN48p5p5mlHDEnHTAukQa2P+qMVE4CwyWE9W+q/m3QJ7kKfGrIjax31f44oFQ=="], + "@oxc-resolver/binding-linux-s390x-gnu": ["@oxc-resolver/binding-linux-s390x-gnu@11.21.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-+NYcm+cCHBbtdQQ3A4phQTSuVRYnNHz7wrl9XRAPEovcdoqi0mb1K5ZOl+jN54ZD+q1zz3V0vltbFJmzecJKmw=="], - "@oxc-resolver/binding-linux-x64-gnu": ["@oxc-resolver/binding-linux-x64-gnu@11.24.2", "", { "os": "linux", "cpu": "x64" }, "sha512-k/VlMMcSzMlahb3/fENM4rTlsJ0s3fFROA0KXPBmKggqmTSaE383sl8F3KCOXPLmVsYfW6hCitMhXCEtNeZxxg=="], + "@oxc-resolver/binding-linux-x64-gnu": ["@oxc-resolver/binding-linux-x64-gnu@11.21.2", "", { "os": "linux", "cpu": "x64" }, "sha512-UQqZDdG2r2HhAOsZEgufkIWHPQ886IUyuJQkoZByvzhW8j51R4UNzGBJFkTiTnLhQnggwJRdJgFWK4uY6ZVIMw=="], - "@oxc-resolver/binding-linux-x64-musl": ["@oxc-resolver/binding-linux-x64-musl@11.24.2", "", { "os": "linux", "cpu": "x64" }, "sha512-8hbnZyNi97b/8wapYaIF9+t9GmZKBW2vunaOc3h9HGJptH7b7XpvZqOTBSm/MpTjr7H497BlgOaSfLUdhmy2bw=="], + "@oxc-resolver/binding-linux-x64-musl": ["@oxc-resolver/binding-linux-x64-musl@11.21.2", "", { "os": "linux", "cpu": "x64" }, "sha512-3Q9PMRjalWkT6NZ4jfujuqTCFwoWErg3y3BnOgb544B8IMw4PktiwWOigMfOHNRLMghZeJ7hpfpZf4CP7rV7Og=="], - "@oxc-resolver/binding-openharmony-arm64": ["@oxc-resolver/binding-openharmony-arm64@11.24.2", "", { "os": "none", "cpu": "arm64" }, "sha512-MvyGik3a6pVgZ0t/kWlbmFxFLmXQJwgLsY2eYFHLpy0wGwRbfzeIGgDwQ3kXqE30z+kSXennRkCrT7TUvkptNg=="], + "@oxc-resolver/binding-openharmony-arm64": ["@oxc-resolver/binding-openharmony-arm64@11.21.2", "", { "os": "none", "cpu": "arm64" }, "sha512-Eljeq3ndtyKhM+Es8LITi4Zl2htzuRZcrPMF3kMCsrILztvU6AjZ3FuEhHHKobPUB9rMpzLpJP5bDqXI7r+iog=="], - "@oxc-resolver/binding-wasm32-wasi": ["@oxc-resolver/binding-wasm32-wasi@11.24.2", "", { "dependencies": { "@emnapi/core": "1.11.2", "@emnapi/runtime": "1.11.2", "@napi-rs/wasm-runtime": "^1.1.6" }, "cpu": "none" }, "sha512-vHcssMPwO08RTvj/c0iOBz90attxyG3wQJ0dTcyEQK43LRpcdLWZlV5feBhv6Isn6ahbQIzHbCgfa81+RiML0Q=="], + "@oxc-resolver/binding-wasm32-wasi": ["@oxc-resolver/binding-wasm32-wasi@11.21.2", "", { "dependencies": { "@emnapi/core": "1.11.0", "@emnapi/runtime": "1.11.0", "@napi-rs/wasm-runtime": "^1.1.5" }, "cpu": "none" }, "sha512-HGDbNsIywqc4LxU38+CTJNnB/6BF7rheWOJ259b4eE0aEnelYblC8x+1tEd63bp31fYne63RQz9Jb4yVnC7Yig=="], - "@oxc-resolver/binding-win32-arm64-msvc": ["@oxc-resolver/binding-win32-arm64-msvc@11.24.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-uokJqro2iBqkFvJdKQLP7d8/BUmFwESQFVmIJUQKj1Xn1a/LysJoe1vmeECLF5b3jsV8CAL5sEMJXX6SdK9Nhg=="], + "@oxc-resolver/binding-win32-arm64-msvc": ["@oxc-resolver/binding-win32-arm64-msvc@11.21.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-iWx25CBEgH49iE9q5coEGI/jb1jl5kkCY9z6U5Og67xCkQ/WFMDc2J5U78+AE91SUxM2NqSLhJC8/PLfWnImww=="], - "@oxc-resolver/binding-win32-x64-msvc": ["@oxc-resolver/binding-win32-x64-msvc@11.24.2", "", { "os": "win32", "cpu": "x64" }, "sha512-UqGPmo56KDfLlfXFAFIrNflHT8tFxWGEivWg3Zeyp4Uy2NlKN1FGPr6/BxcLGG3+kZ6Wp14g5Uj+n71boqZfiw=="], + "@oxc-resolver/binding-win32-x64-msvc": ["@oxc-resolver/binding-win32-x64-msvc@11.21.2", "", { "os": "win32", "cpu": "x64" }, "sha512-VPoCAhKvCQTlG7vxqaBXcmuvbh77BfnGXj8g0pbvVXpm1F/R8rDVwqIWcEbMzrI1JvJlm8v7T9uMVQb6UctMRg=="], "@pinojs/redact": ["@pinojs/redact@0.4.0", "", {}, "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg=="], @@ -1095,26 +1153,28 @@ "@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - "@storybook/addon-docs": ["@storybook/addon-docs@10.5.9", "", { "dependencies": { "@mdx-js/react": "^3.0.0", "@storybook/csf-plugin": "10.5.9", "@storybook/icons": "^2.0.2", "@storybook/react-dom-shim": "10.5.9", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "ts-dedent": "^2.0.0" }, "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "storybook": "^10.5.9" }, "optionalPeers": ["@types/react"] }, "sha512-8sFsMkZYrrdqCLdV+hnwTwDF7RaBsBPRwl4wfc8ve9Q/7Yhi5REe/Xjvd8x1yn6fBPPw9tnID9dx6Agdnr81fw=="], + "@storybook/addon-docs": ["@storybook/addon-docs@10.5.10", "", { "dependencies": { "@mdx-js/react": "^3.0.0", "@storybook/csf-plugin": "10.5.10", "@storybook/icons": "^2.0.2", "@storybook/react-dom-shim": "10.5.10", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "ts-dedent": "^2.0.0" }, "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "storybook": "^10.5.10" }, "optionalPeers": ["@types/react"] }, "sha512-06JoK3/a7FWI/6GzuidJP9iHp1/Vejboe6lzS1jW+d8ItpecriBt+oXh1VNmUM7i7PjI6pZnet+j51QnLyeOoQ=="], - "@storybook/addon-links": ["@storybook/addon-links@10.5.9", "", { "dependencies": { "@storybook/global": "^5.0.0" }, "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "storybook": "^10.5.9" }, "optionalPeers": ["@types/react", "react"] }, "sha512-ZDbPl6ia6hqjoV+CpQU3DjkXpc0TxUq6+y/rFD8w21dJMdqNWzY8zajHC8r4CfTWANjM1pGPUYisWtTKi1MxZw=="], + "@storybook/addon-links": ["@storybook/addon-links@10.5.10", "", { "dependencies": { "@storybook/global": "^5.0.0" }, "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "storybook": "^10.5.10" }, "optionalPeers": ["@types/react", "react"] }, "sha512-wZQX26vSKEBuQB+EKHuAoeDh0XiUDrN2GMX2lhhj2KpJ/di4OyXFaHXspXOXWkjNtyMTRd0QkCHQqKx4LY3E6w=="], - "@storybook/builder-vite": ["@storybook/builder-vite@10.5.9", "", { "dependencies": { "@storybook/csf-plugin": "10.5.9", "ts-dedent": "^2.0.0" }, "peerDependencies": { "storybook": "^10.5.9", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-Zg4JbGQiHFPGlFJ9HM+XPgzKmU/RFPCymhohVRJhBBYfmgaQgz0flWWzscseCDpl638MNd8/r/H+nwuoBgSYDg=="], + "@storybook/builder-vite": ["@storybook/builder-vite@10.5.10", "", { "dependencies": { "@storybook/csf-plugin": "10.5.10", "ts-dedent": "^2.0.0" }, "peerDependencies": { "storybook": "^10.5.10", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-O4GgIP0tKLRueom3EmU3OaBUHKjNYj+jkOvmTIkn3PYTiWVkCuHqSKEs4ADvRyaQuLH+peHhFe4JtkNC9KbtrQ=="], - "@storybook/csf-plugin": ["@storybook/csf-plugin@10.5.9", "", { "dependencies": { "unplugin": "^2.3.5" }, "peerDependencies": { "esbuild": "*", "rollup": "*", "storybook": "^10.5.9", "vite": "*", "webpack": "*" }, "optionalPeers": ["esbuild", "rollup", "vite", "webpack"] }, "sha512-4H5QIHQVtQYCuL43GCRLGjNQhZpQg9gL03ja0DV80kO2Dn9LEt6ol87bSnSjn4VDgcAXtgTzXFvRLknfVgAAqg=="], + "@storybook/csf-plugin": ["@storybook/csf-plugin@10.5.10", "", { "dependencies": { "unplugin": "^2.3.5" }, "peerDependencies": { "esbuild": "*", "rollup": "*", "storybook": "^10.5.10", "vite": "*", "webpack": "*" }, "optionalPeers": ["esbuild", "rollup", "vite", "webpack"] }, "sha512-TaCLBrqVEr767+w58QDotDUiCTuE5cyRJuRcDlsKQyUIyGBv+lYD3lu8wBiVCYxgIjB/gu9HmqiC+0yx1rHzaw=="], "@storybook/global": ["@storybook/global@5.0.0", "", {}, "sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ=="], "@storybook/icons": ["@storybook/icons@2.1.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Fxh9vYpX9bQqFeHRiY8h2ApeRGDzRSMLwJwNZ/AIRqnyOKHxRKL+yFe+ctEkVJmuptRE9u1Hrn8ZZNHyfDKKNg=="], - "@storybook/react": ["@storybook/react@10.5.9", "", { "dependencies": { "@storybook/global": "^5.0.0", "@storybook/react-dom-shim": "10.5.9", "react-docgen": "^8.0.2", "react-docgen-typescript": "^2.2.2" }, "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "@types/react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "storybook": "^10.5.9", "typescript": ">= 4.9.x" }, "optionalPeers": ["@types/react", "@types/react-dom", "typescript"] }, "sha512-kApGOuNT26NkpioTsr1iT/Q2c44tA7OIsNUSyFqtT7W8k3fRn/jQWfrDegYxty0WG0wxdNMZq2ndRfOOF8HaHw=="], + "@storybook/react": ["@storybook/react@10.5.10", "", { "dependencies": { "@storybook/global": "^5.0.0", "@storybook/react-dom-shim": "10.5.10", "react-docgen": "^8.0.2", "react-docgen-typescript": "^2.2.2" }, "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "@types/react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "storybook": "^10.5.10", "typescript": ">= 4.9.x" }, "optionalPeers": ["@types/react", "@types/react-dom", "typescript"] }, "sha512-4MBV5e1SXIMfPynLHzr+Mp0dwGv/FW1bklWAsS4ynBOAbC98W9p/I9vqBnUctsvE3BJkhzHQQyPwMHL5tTcHVA=="], - "@storybook/react-dom-shim": ["@storybook/react-dom-shim@10.5.9", "", { "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "@types/react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "storybook": "^10.5.9" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-7qZD6CSa64p1m/zX9tG4ALcEHlEk0Bx+5++4RL3MFlRCgCFfAomXsCHTzF0RyF8cI4vl+hS7Y0ryjQchVs6UQA=="], + "@storybook/react-dom-shim": ["@storybook/react-dom-shim@10.5.10", "", { "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "@types/react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "storybook": "^10.5.10" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-rbu62ILo/VE3iXKmu+kWXFpD1H1Lwi0f19q/x7JnDsD2dxKS9w5znLEqPIq2qxpzi/wjjIb2iUP1cRG1d/9W5A=="], - "@storybook/react-vite": ["@storybook/react-vite@10.5.9", "", { "dependencies": { "@joshwooding/vite-plugin-react-docgen-typescript": "^0.7.0", "@rollup/pluginutils": "^5.0.2", "@storybook/builder-vite": "10.5.9", "@storybook/react": "10.5.9", "empathic": "^2.0.0", "magic-string": "^0.30.0", "react-docgen": "^8.0.2", "resolve": "^1.22.8", "tsconfig-paths": "^4.2.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "storybook": "^10.5.9", "typescript": ">= 4.9.x", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["typescript"] }, "sha512-mDI+UssrOEP8IwgBsefLG+gqW1gZbZEPbpH5PoHK/P1WPi8BfrLEqrFi9H9wmMkal/Vh8SmL1awgOi0ir3XwcQ=="], + "@storybook/react-vite": ["@storybook/react-vite@10.5.10", "", { "dependencies": { "@joshwooding/vite-plugin-react-docgen-typescript": "^0.7.0", "@rollup/pluginutils": "^5.0.2", "@storybook/builder-vite": "10.5.10", "@storybook/react": "10.5.10", "empathic": "^2.0.0", "magic-string": "^0.30.0", "react-docgen": "^8.0.2", "resolve": "^1.22.8", "tsconfig-paths": "^4.2.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "storybook": "^10.5.10", "typescript": ">= 4.9.x", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["typescript"] }, "sha512-xOztxefUnqKeuyvcnjspqmlDnER4cExL+liltrpdXLPJVqfFNr9lgM49FyEPajzsUVG9W/vHJWjbaQGGu1UsYQ=="], "@swan-io/boxed": ["@swan-io/boxed@3.2.1", "", { "peerDependencies": { "typescript": ">=5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-MQqSpe09PdjDjTR4HCPpUxO9XsacNguCkce1C2wm1eIb6ycWXQoV+biYvLEuI/LiMqB31KySdgY2YFwrVucLCw=="], + "@t3-oss/env-core": ["@t3-oss/env-core@0.13.11", "", { "peerDependencies": { "arktype": "^2.1.0", "typescript": ">=5.0.0", "valibot": "^1.0.0-beta.7 || ^1.0.0", "zod": "^3.24.0 || ^4.0.0" }, "optionalPeers": ["arktype", "typescript", "valibot", "zod"] }, "sha512-sM7GYY+KL7H/Hl0BE0inWfk3nRHZOLhmVn7sHGxaZt9FAR6KqREXAE+6TqKfiavfXmpRxO/OZ2QgKRd+oiBYRQ=="], + "@tabby_ai/hijri-converter": ["@tabby_ai/hijri-converter@1.0.5", "", {}, "sha512-r5bClKrcIusDoo049dSL8CawnHR6mRdDwhlQuIgZRNty68q0x8k3Lf1BtPAMxRf/GgnHBnIO4ujd3+GQdLWzxQ=="], "@tailwindcss/aspect-ratio": ["@tailwindcss/aspect-ratio@0.4.0", "", { "peerDependencies": { "tailwindcss": ">=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1" } }, "sha512-WJu0I4PpqNPuutpaA9zDUq2JXR+lorZ7PbLcKNLmb6GL9/HLfC7w3CRsMhJF4BbYd/lkY6CfXOvkYpuGnZfkpQ=="], @@ -1157,7 +1217,7 @@ "@tailwindcss/vite": ["@tailwindcss/vite@4.3.3", "", { "dependencies": { "@tailwindcss/node": "4.3.3", "@tailwindcss/oxide": "4.3.3", "tailwindcss": "4.3.3" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7 || ^8" } }, "sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw=="], - "@tanstack/devtools": ["@tanstack/devtools@0.14.0", "", { "dependencies": { "@neodrag/solid": "3.0.0-next.11", "@solid-primitives/event-listener": "^2.4.3", "@solid-primitives/keyboard": "^1.3.3", "@solid-primitives/resize-observer": "^2.1.3", "@tanstack/devtools-client": "0.0.8", "@tanstack/devtools-event-bus": "0.4.2", "@tanstack/devtools-ui": "0.7.0", "clsx": "^2.1.1", "goober": "^2.1.16", "solid-js": "^1.9.9" }, "bin": { "intent": "./bin/intent.js" } }, "sha512-tN0SEi1BVaJYtkZbgYpvLsInjwNRAZkR3r6slSvz9Jm+bfkhcdjuOSrZp0cAwOGwdnauHZ1mYgtfe2AfC/V1NQ=="], + "@tanstack/devtools": ["@tanstack/devtools@0.14.2", "", { "dependencies": { "@neodrag/core": "3.0.0-next.11", "@neodrag/solid": "3.0.0-next.11", "@solid-primitives/event-listener": "^2.4.3", "@solid-primitives/keyboard": "^1.3.3", "@solid-primitives/resize-observer": "^2.1.3", "@tanstack/devtools-client": "0.0.8", "@tanstack/devtools-event-bus": "0.4.3", "@tanstack/devtools-ui": "0.7.1", "clsx": "^2.1.1", "goober": "^2.1.16", "solid-js": "^1.9.9" }, "bin": { "intent": "./bin/intent.js" } }, "sha512-8FVVmDU+x3iEwrl5rtbIhud8gwp9eSXPlhs36SCV59yAtXmheFFvLqLAUXpfIU79sZVBg3LLTy2VlTIXaWbaBw=="], "@tanstack/devtools-client": ["@tanstack/devtools-client@0.0.6", "", { "dependencies": { "@tanstack/devtools-event-client": "^0.4.1" } }, "sha512-f85ZJXJnDIFOoykG/BFIixuAevJovCvJF391LPs6YjBAPhGYC50NWlx1y4iF/UmK5/cCMx+/JqI5SBOz7FanQQ=="], @@ -1165,7 +1225,7 @@ "@tanstack/devtools-event-client": ["@tanstack/devtools-event-client@0.4.4", "", { "bin": { "intent": "./bin/intent.js" } }, "sha512-6T5Yop/793YI+H+5J8Hsyj4kCih9sl4t3ElLgKioW5hk3ocn+ZdSJ94tT7vL7uabxSugWYBZlOTMPzEw2puvQw=="], - "@tanstack/devtools-ui": ["@tanstack/devtools-ui@0.7.0", "", { "dependencies": { "clsx": "^2.1.1", "dayjs": "^1.11.19", "goober": "^2.1.16", "solid-js": "^1.9.9" } }, "sha512-px/a+JgRSVHDj/hID1cwfsIi+ly5l7t3Yw7fLw4G556HXCNgDri36fupt9h7oBeEKntpsx3ep/XtZn51rrCv2g=="], + "@tanstack/devtools-ui": ["@tanstack/devtools-ui@0.7.1", "", { "dependencies": { "clsx": "^2.1.1", "dayjs": "^1.11.19", "goober": "^2.1.16", "solid-js": "^1.9.9" } }, "sha512-3xQ/ezZ2qVNszhjpCN2N3jn7uHc2J1PMgcyjHzH4XZBt9xAQyMMcPNoR2cd7rzReyxWoJpZUWiDBmOJiCtLj9A=="], "@tanstack/devtools-utils": ["@tanstack/devtools-utils@0.4.0", "", { "peerDependencies": { "@types/react": ">=17.0.0", "preact": ">=10.0.0", "react": ">=17.0.0", "solid-js": ">=1.9.7", "vue": ">=3.2.0" }, "optionalPeers": ["@types/react", "preact", "react", "solid-js", "vue"], "bin": { "intent": "bin/intent.js" } }, "sha512-KsGzYhA8L/fCNgyyMyoUy+TKtx+DjNbzWwqH6wXL48Llzo7kvV9RynYJlaO8Qkzwm+NdHXSgsljQNjQ3CKPpZA=="], @@ -1183,7 +1243,7 @@ "@tanstack/query-devtools": ["@tanstack/query-devtools@5.101.4", "", {}, "sha512-z5IPHnDX3aUWeTWlRKLyooBQekaCAw4xRpZqPQ390RiWTDBcTynjpPT221BArw0u2+pnQMdGvPQI9YNNubBcmA=="], - "@tanstack/react-devtools": ["@tanstack/react-devtools@0.10.10", "", { "dependencies": { "@tanstack/devtools": "0.14.0" }, "peerDependencies": { "@types/react": ">=16.8", "@types/react-dom": ">=16.8", "react": ">=16.8", "react-dom": ">=16.8" } }, "sha512-hYH34MSVbajs1pUc22ftSapyKQp2gOh0w34a7ouYOdIcbXD6YPckSR2YpAWGq1rrs6N0l/rvV6LM/G1pgN5ARg=="], + "@tanstack/react-devtools": ["@tanstack/react-devtools@0.10.12", "", { "dependencies": { "@tanstack/devtools": "0.14.2" }, "peerDependencies": { "@types/react": ">=16.8", "@types/react-dom": ">=16.8", "react": ">=16.8", "react-dom": ">=16.8" } }, "sha512-dgoz7TFm97Izo/D34z91PD0h+ufk+eBmoN9OgRHJlj/c7Ol5xpIP7bqLBNByjgt5paRE2eSu5AQHV92Ul+G6iw=="], "@tanstack/react-form": ["@tanstack/react-form@1.33.5", "", { "dependencies": { "@tanstack/form-core": "1.33.5", "@tanstack/react-store": "^0.11.0" }, "peerDependencies": { "react": "^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-LlRB28qJwO/QCGaHvWnbdh4haBgTFiZVmzA2uzxSBS3YA7/IqrQ6HOBK70CkFQ+DbflZ7NawsmSln13h5iIdTA=="], @@ -1217,9 +1277,9 @@ "@tanstack/router-devtools-core": ["@tanstack/router-devtools-core@1.168.0", "", { "dependencies": { "clsx": "^2.1.1", "goober": "^2.1.16" }, "peerDependencies": { "@tanstack/router-core": "^1.170.0", "csstype": "^3.0.10" }, "optionalPeers": ["csstype"] }, "sha512-wQoQhlBK7nlZgqzaqdYXKWNTpdHdsaREdaPhFZVH0/Ador+F+eM3/NF2i3f2LPeS0GgKraZUQXe1Q/1+KHyEYg=="], - "@tanstack/router-generator": ["@tanstack/router-generator@1.167.21", "", { "dependencies": { "@babel/types": "^7.28.5", "@tanstack/router-core": "1.171.15", "@tanstack/router-utils": "1.162.2", "@tanstack/virtual-file-routes": "1.162.0", "jiti": "^2.7.0", "magic-string": "^0.30.21", "prettier": "^3.5.0", "zod": "^4.4.3" } }, "sha512-m3oXZyienj8owialdyoZ0txHQrnEx/Ra+D9kWtar5fC2cWZr5Pvxl86VY2mX5RRLC5QLKLeRGT1x4HV95wHVDQ=="], + "@tanstack/router-generator": ["@tanstack/router-generator@1.167.17", "", { "dependencies": { "@babel/types": "^7.28.5", "@tanstack/router-core": "1.171.13", "@tanstack/router-utils": "1.162.2", "@tanstack/virtual-file-routes": "1.162.0", "jiti": "^2.7.0", "magic-string": "^0.30.21", "prettier": "^3.5.0", "zod": "^4.4.3" } }, "sha512-xtB9tB2Ws0tWR6Pi7nc3Qk9IYgoh1mQCKWjHqIl9tf6BNUpKoqniJoPAQ4+LGrK8FeZYU0o0p/qlZEyj9FAulA=="], - "@tanstack/router-plugin": ["@tanstack/router-plugin@1.168.23", "", { "dependencies": { "@babel/core": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "@tanstack/router-core": "1.171.15", "@tanstack/router-generator": "1.167.21", "@tanstack/router-utils": "1.162.2", "chokidar": "^5.0.0", "unplugin": "^3.0.0", "zod": "^4.4.3" }, "peerDependencies": { "@rsbuild/core": ">=1.0.2 || ^2.0.0", "@tanstack/react-router": "^1.170.18", "vite": ">=5.0.0 || >=6.0.0 || >=7.0.0 || >=8.0.0", "vite-plugin-solid": "^2.11.10 || ^3.0.0-0", "webpack": ">=5.92.0" }, "optionalPeers": ["@rsbuild/core", "@tanstack/react-router", "vite", "vite-plugin-solid", "webpack"] }, "sha512-0+PIcvnaAimFwjoEIeV3h7LKjzC8zNnp7pH2UamdKwQ9QlY99WU9V0Xl0zbM0i9hrUa/mKgWPDAzELmPUu5fMA=="], + "@tanstack/router-plugin": ["@tanstack/router-plugin@1.168.18", "", { "dependencies": { "@babel/core": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "@tanstack/router-core": "1.171.13", "@tanstack/router-generator": "1.167.17", "@tanstack/router-utils": "1.162.2", "chokidar": "^5.0.0", "unplugin": "^3.0.0", "zod": "^4.4.3" }, "peerDependencies": { "@rsbuild/core": ">=1.0.2 || ^2.0.0", "@tanstack/react-router": "^1.170.15", "vite": ">=5.0.0 || >=6.0.0 || >=7.0.0 || >=8.0.0", "vite-plugin-solid": "^2.11.10 || ^3.0.0-0", "webpack": ">=5.92.0" }, "optionalPeers": ["@rsbuild/core", "@tanstack/react-router", "vite", "vite-plugin-solid", "webpack"] }, "sha512-MofS28/axfnfnhOD2RSgJEaU882aX5RsAzhGz5Vc4XhAmvCjy919u9JrNs4QsTWFbTD1P7IJ8WFlFVsrg0pStg=="], "@tanstack/router-ssr-query-core": ["@tanstack/router-ssr-query-core@1.169.1", "", { "peerDependencies": { "@tanstack/query-core": ">=5.90.0", "@tanstack/router-core": ">=1.127.0" } }, "sha512-rngux8s/3mPQzcjLYDLkNU31coYVyCgrVTfpdwqUdY5jIEHqGTXrO73DTkPR1PppwYUeVhmNCgl8TctRcnupjg=="], @@ -1251,6 +1311,12 @@ "@testing-library/user-event": ["@testing-library/user-event@14.6.5", "", { "peerDependencies": { "@testing-library/dom": ">=7.21.4" } }, "sha512-FhqjldLTpteueBaKflhNFlMT3+PM0O5fiBUivht6b9CZ1eesJyy7+g3Jr7XwJzt/Hip3ZG5hWwK1MX1FuDiE4w=="], + "@trpc/client": ["@trpc/client@11.18.0", "", { "peerDependencies": { "@trpc/server": "11.18.0", "typescript": ">=5.7.2" }, "bin": { "intent": "bin/intent.js" } }, "sha512-wOqeg3Fvl25V1ZisQhUD3K8G60ZJDlSGJNSyeXrLH24xAo5w6GSR2Kzb1cSNY9Y+IQ2YZvYGZstBU+V/ulo/ow=="], + + "@trpc/server": ["@trpc/server@11.18.0", "", { "peerDependencies": { "typescript": ">=5.7.2" }, "bin": { "intent": "bin/intent.js" } }, "sha512-JAvXOuNTxgXjIDfQaOvDq1j66LMNfDJUH1IU7Slfn8EvRv2EkH6ehu3A7zpYhjO0syHHiYg77v2lG2JFJgvw7Q=="], + + "@trpc/tanstack-react-query": ["@trpc/tanstack-react-query@11.18.0", "", { "peerDependencies": { "@tanstack/react-query": "^5.80.3", "@trpc/client": "11.18.0", "@trpc/server": "11.18.0", "react": ">=18.2.0", "typescript": ">=5.7.2" }, "bin": { "intent": "bin/intent.js" } }, "sha512-dm5xIlN0SEzJAbQ34EHdb1Kgd/zWZ63ZMviQEw3WCWCIPz8MjLKAhquncPcn+YxFUJa+Qi4qatdGFymmM4HmAQ=="], + "@tybys/wasm-util": ["@tybys/wasm-util@0.10.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg=="], "@types/aria-query": ["@types/aria-query@5.0.4", "", {}, "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw=="], @@ -1327,7 +1393,7 @@ "@types/resolve": ["@types/resolve@1.20.6", "", {}, "sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ=="], - "@types/ssh2": ["@types/ssh2@0.5.52", "", { "dependencies": { "@types/node": "*", "@types/ssh2-streams": "*" } }, "sha512-lbLLlXxdCZOSJMCInKH2+9V/77ET2J6NPQHpFI0kda61Dd1KglJs+fPQBchizmzYSOJBgdTajhPqBO1xxLywvg=="], + "@types/ssh2": ["@types/ssh2@1.15.5", "", { "dependencies": { "@types/node": "^18.11.18" } }, "sha512-N1ASjp/nXH3ovBHddRJpli4ozpk6UdDYIX4RJWFa9L1YKnzdhTlVmiGHm4DZnj/jLbqZpes4aeR30EFGQtvhQQ=="], "@types/ssh2-streams": ["@types/ssh2-streams@0.1.13", "", { "dependencies": { "@types/node": "*" } }, "sha512-faHyY3brO9oLEA0QlcO8N2wT7R0+1sHWZvQ+y3rMLwdY1ZyS1z0W3t65j9PqT4HmQ6ALzNe7RZlNuCNE0wBSWA=="], @@ -1435,6 +1501,10 @@ "babel-dead-code-elimination": ["babel-dead-code-elimination@1.0.12", "", { "dependencies": { "@babel/core": "^7.23.7", "@babel/parser": "^7.23.6", "@babel/traverse": "^7.23.7", "@babel/types": "^7.23.6" } }, "sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig=="], + "babel-plugin-react-compiler": ["babel-plugin-react-compiler@1.0.0", "", { "dependencies": { "@babel/types": "^7.26.0" } }, "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw=="], + + "backoffice": ["backoffice@workspace:packages/backoffice"], + "balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], "bare-events": ["bare-events@2.9.1", "", { "peerDependencies": { "bare-abort-controller": "*" }, "optionalPeers": ["bare-abort-controller"] }, "sha512-Z0oHEHAFDZkffN8Qc39zNZjQlMDkPJRyyyZieU1VH7u8c5S+qHZ2S8ixdKIAxEjfHO7FJxXmJWgteOghVanIsg=="], @@ -1449,7 +1519,7 @@ "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], - "baseline-browser-mapping": ["baseline-browser-mapping@2.11.15", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-FwMjJJ7HnyZpWe+oWxegG0fezZyBZUagI5LZEoO3GCbtbKNwRfMH9Ue5d5v01PNePBy1QSfPSDTTeVL0Hb9EzA=="], + "baseline-browser-mapping": ["baseline-browser-mapping@2.11.16", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-H/bNPUFHewJHyCTdjn1n3Pit5+2GmWT6mmeHImPX+8MA9NA6b67jO4gYmi4jTbCJb2otq34KMZnovndDPqJwhQ=="], "bcrypt-pbkdf": ["bcrypt-pbkdf@1.0.2", "", { "dependencies": { "tweetnacl": "^0.14.3" } }, "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w=="], @@ -1503,7 +1573,7 @@ "check-error": ["check-error@2.1.3", "", {}, "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA=="], - "chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], + "chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], "chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="], @@ -1551,7 +1621,7 @@ "cookie-es": ["cookie-es@2.0.1", "", {}, "sha512-aVf4A4hI2w70LnF7GG+7xDQUkliwiXWXFvTjkip4+b64ygDQ2sJPRSKFDHbxn8o0xu9QzPkMuuiWIXyFSE2slA=="], - "copy-anything": ["copy-anything@4.0.5", "", { "dependencies": { "is-what": "^5.2.0" } }, "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA=="], + "copy-anything": ["copy-anything@4.1.0", "", {}, "sha512-ufbM3smX/Jbnpk5wcQjzd1MgBpzmqfNETUAyZNrGwU9foRlyHoGzMMBBCRzEhQLBjZfFDE1W2ufPXX2vdWkV8Q=="], "core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="], @@ -1567,7 +1637,7 @@ "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], - "crossws": ["crossws@0.4.10", "", { "peerDependencies": { "srvx": ">=0.11.5" }, "optionalPeers": ["srvx"] }, "sha512-pz3oubH/dt12KjqsUB0IuXW4nwRDQ583iDsP4555Cpdqx0NoU7pGlWBcayyFI8f/l/idRpgjMEfwuOxSWJYlIA=="], + "crossws": ["crossws@0.4.12", "", { "peerDependencies": { "srvx": ">=0.11.5" }, "optionalPeers": ["srvx"] }, "sha512-aypfsr6t0uNvkqaZc6zvBfXzC6pLI0/sIulpkV6RwCVtZqG5ebBzv4weImKK0VNCj91Wl9F5j7p5WU4MNrybng=="], "css-box-model": ["css-box-model@1.2.1", "", { "dependencies": { "tiny-invariant": "^1.0.6" } }, "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw=="], @@ -1709,7 +1779,7 @@ "eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="], - "electron-to-chromium": ["electron-to-chromium@1.5.409", "", {}, "sha512-ChI4N44d0B4A6C8prnNjMOaGgE59fUyEVYcRYm2XEXIjMbbvF5i9UL1cblDbpGqiU0uS8FE8UcKxqZqTXdmzbQ=="], + "electron-to-chromium": ["electron-to-chromium@1.5.411", "", {}, "sha512-gglkxzokjHfawpGxq75XdBV2/l3BAPzrsMs70qgaZdTW5rpV1tC4MdgJVP9fN126bODA4ZJQkn1wryEzJyQXIg=="], "embla-carousel": ["embla-carousel@8.6.0", "", {}, "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA=="], @@ -1789,7 +1859,7 @@ "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="], - "firebase": ["firebase@12.17.1", "", { "dependencies": { "@firebase/ai": "2.14.0", "@firebase/analytics": "0.10.23", "@firebase/analytics-compat": "0.2.29", "@firebase/app": "0.16.0", "@firebase/app-check": "0.13.0", "@firebase/app-check-compat": "0.4.6", "@firebase/app-compat": "0.5.16", "@firebase/app-types": "0.9.5", "@firebase/auth": "1.13.4", "@firebase/auth-compat": "0.6.9", "@firebase/data-connect": "0.7.3", "@firebase/database": "1.1.4", "@firebase/database-compat": "2.1.6", "@firebase/firestore": "4.17.0", "@firebase/firestore-compat": "0.4.12", "@firebase/functions": "0.13.6", "@firebase/functions-compat": "0.4.6", "@firebase/installations": "0.6.23", "@firebase/installations-compat": "0.2.23", "@firebase/messaging": "0.13.1", "@firebase/messaging-compat": "0.2.28", "@firebase/performance": "0.7.13", "@firebase/performance-compat": "0.2.26", "@firebase/remote-config": "0.9.1", "@firebase/remote-config-compat": "0.2.28", "@firebase/storage": "0.14.4", "@firebase/storage-compat": "0.4.4", "@firebase/util": "1.15.2" } }, "sha512-dhp41ye9jMQvhx5FwjMkf/hjDHJApl7gXmvzOZGvP0M7c/GZGUnQ4qvsvlOBkF0Pa7wAwHMdcpL0ON2pXCQ4Sw=="], + "firebase": ["firebase@12.18.0", "", { "dependencies": { "@firebase/ai": "2.15.0", "@firebase/analytics": "0.10.24", "@firebase/analytics-compat": "0.2.30", "@firebase/app": "0.16.1", "@firebase/app-check": "0.13.1", "@firebase/app-check-compat": "0.4.7", "@firebase/app-compat": "0.5.17", "@firebase/app-types": "0.9.6", "@firebase/auth": "1.13.5", "@firebase/auth-compat": "0.6.10", "@firebase/data-connect": "0.7.4", "@firebase/database": "1.1.5", "@firebase/database-compat": "2.1.7", "@firebase/firestore": "4.17.1", "@firebase/firestore-compat": "0.4.13", "@firebase/functions": "0.14.0", "@firebase/functions-compat": "0.5.0", "@firebase/installations": "0.6.24", "@firebase/installations-compat": "0.2.24", "@firebase/messaging": "0.13.2", "@firebase/messaging-compat": "0.2.29", "@firebase/performance": "0.7.14", "@firebase/performance-compat": "0.2.27", "@firebase/remote-config": "0.9.2", "@firebase/remote-config-compat": "0.2.29", "@firebase/storage": "0.14.5", "@firebase/storage-compat": "0.4.5", "@firebase/util": "1.15.3" } }, "sha512-XaL6tlE5Xd20ZDhckqOMIw+JJTET+wTdeZPxQ7ihc42oxRb7kWUyn/j1LO5V9dH1xq8Rv5R71Pv1fBCdIkt9Rw=="], "first-match": ["first-match@0.0.1", "", {}, "sha512-VvKbnaxrC0polTFDC+teKPTdl2mn6B/KUW+WB3C9RzKDeNwbzfLdnUz3FxC+tnjvus6bI0jWrWicQyVIPdS37A=="], @@ -1859,7 +1929,7 @@ "https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="], - "i18next": ["i18next@26.3.6", "", { "peerDependencies": { "typescript": "^5 || ^6 || ^7" }, "optionalPeers": ["typescript"] }, "sha512-Bu5Z2nAXgfVyM8xvW3jk9EKRIuX37PudsrBViThNFx7CR7aaYTpP01cxNB/E4c4UUzTDiAZRstEhsRfPOL/8xA=="], + "i18next": ["i18next@26.4.0", "", { "peerDependencies": { "typescript": "^5 || ^6 || ^7" }, "optionalPeers": ["typescript"] }, "sha512-rsmK5bFqsD1AetSFSIa43wtNR4WpvvH4p0tLEsTxkC7QTrfdFm06nbQ95bh8Og4wwaCnUEcm9DVYL2cgxitiQg=="], "i18next-browser-languagedetector": ["i18next-browser-languagedetector@8.2.1", "", { "dependencies": { "@babel/runtime": "^7.23.2" } }, "sha512-bZg8+4bdmaOiApD7N7BPT9W8MLZG+nPTOFlLiJiT8uzKXFjhxw4v2ierCXOwB5sFDMtuA5G4kgYZ0AznZxQ/cw=="], @@ -1909,8 +1979,6 @@ "is-unicode-supported": ["is-unicode-supported@2.1.0", "", {}, "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ=="], - "is-what": ["is-what@5.5.0", "", {}, "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw=="], - "is-wsl": ["is-wsl@3.1.1", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw=="], "isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="], @@ -2037,6 +2105,8 @@ "lru-cache": ["lru-cache@11.5.2", "", {}, "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g=="], + "lucide-react": ["lucide-react@0.544.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-t5tS44bqd825zAW45UQxpG2CvcC4urOwn2TrwSH8u+MjeE+1NnWl6QqeQ/6NdjMqdOygyiT9p3Ev0p1NJykxjw=="], + "lz-string": ["lz-string@1.5.0", "", { "bin": { "lz-string": "bin/bin.js" } }, "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ=="], "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], @@ -2145,7 +2215,7 @@ "oxc-parser": ["oxc-parser@0.127.0", "", { "dependencies": { "@oxc-project/types": "^0.127.0" }, "optionalDependencies": { "@oxc-parser/binding-android-arm-eabi": "0.127.0", "@oxc-parser/binding-android-arm64": "0.127.0", "@oxc-parser/binding-darwin-arm64": "0.127.0", "@oxc-parser/binding-darwin-x64": "0.127.0", "@oxc-parser/binding-freebsd-x64": "0.127.0", "@oxc-parser/binding-linux-arm-gnueabihf": "0.127.0", "@oxc-parser/binding-linux-arm-musleabihf": "0.127.0", "@oxc-parser/binding-linux-arm64-gnu": "0.127.0", "@oxc-parser/binding-linux-arm64-musl": "0.127.0", "@oxc-parser/binding-linux-ppc64-gnu": "0.127.0", "@oxc-parser/binding-linux-riscv64-gnu": "0.127.0", "@oxc-parser/binding-linux-riscv64-musl": "0.127.0", "@oxc-parser/binding-linux-s390x-gnu": "0.127.0", "@oxc-parser/binding-linux-x64-gnu": "0.127.0", "@oxc-parser/binding-linux-x64-musl": "0.127.0", "@oxc-parser/binding-openharmony-arm64": "0.127.0", "@oxc-parser/binding-wasm32-wasi": "0.127.0", "@oxc-parser/binding-win32-arm64-msvc": "0.127.0", "@oxc-parser/binding-win32-ia32-msvc": "0.127.0", "@oxc-parser/binding-win32-x64-msvc": "0.127.0" } }, "sha512-bkgD4qHlN7WxLdX8bLXdaU54TtQtAIg/ZBAfm0aje/mo3MRDo3P0hZSgr4U7O3xfX+fQmR5AP04JS/TGcZLcFA=="], - "oxc-resolver": ["oxc-resolver@11.24.2", "", { "optionalDependencies": { "@oxc-resolver/binding-android-arm-eabi": "11.24.2", "@oxc-resolver/binding-android-arm64": "11.24.2", "@oxc-resolver/binding-darwin-arm64": "11.24.2", "@oxc-resolver/binding-darwin-x64": "11.24.2", "@oxc-resolver/binding-freebsd-x64": "11.24.2", "@oxc-resolver/binding-linux-arm-gnueabihf": "11.24.2", "@oxc-resolver/binding-linux-arm-musleabihf": "11.24.2", "@oxc-resolver/binding-linux-arm64-gnu": "11.24.2", "@oxc-resolver/binding-linux-arm64-musl": "11.24.2", "@oxc-resolver/binding-linux-ppc64-gnu": "11.24.2", "@oxc-resolver/binding-linux-riscv64-gnu": "11.24.2", "@oxc-resolver/binding-linux-riscv64-musl": "11.24.2", "@oxc-resolver/binding-linux-s390x-gnu": "11.24.2", "@oxc-resolver/binding-linux-x64-gnu": "11.24.2", "@oxc-resolver/binding-linux-x64-musl": "11.24.2", "@oxc-resolver/binding-openharmony-arm64": "11.24.2", "@oxc-resolver/binding-wasm32-wasi": "11.24.2", "@oxc-resolver/binding-win32-arm64-msvc": "11.24.2", "@oxc-resolver/binding-win32-x64-msvc": "11.24.2" } }, "sha512-FY91FiDBj7ls5MsFS9jN3tjz2o0/zsdSsymlakySaBwVJZorHhkWyICLZMKxlu1R9vYo+sd3z1jwb4J8x7bNDw=="], + "oxc-resolver": ["oxc-resolver@11.21.2", "", { "optionalDependencies": { "@oxc-resolver/binding-android-arm-eabi": "11.21.2", "@oxc-resolver/binding-android-arm64": "11.21.2", "@oxc-resolver/binding-darwin-arm64": "11.21.2", "@oxc-resolver/binding-darwin-x64": "11.21.2", "@oxc-resolver/binding-freebsd-x64": "11.21.2", "@oxc-resolver/binding-linux-arm-gnueabihf": "11.21.2", "@oxc-resolver/binding-linux-arm-musleabihf": "11.21.2", "@oxc-resolver/binding-linux-arm64-gnu": "11.21.2", "@oxc-resolver/binding-linux-arm64-musl": "11.21.2", "@oxc-resolver/binding-linux-ppc64-gnu": "11.21.2", "@oxc-resolver/binding-linux-riscv64-gnu": "11.21.2", "@oxc-resolver/binding-linux-riscv64-musl": "11.21.2", "@oxc-resolver/binding-linux-s390x-gnu": "11.21.2", "@oxc-resolver/binding-linux-x64-gnu": "11.21.2", "@oxc-resolver/binding-linux-x64-musl": "11.21.2", "@oxc-resolver/binding-openharmony-arm64": "11.21.2", "@oxc-resolver/binding-wasm32-wasi": "11.21.2", "@oxc-resolver/binding-win32-arm64-msvc": "11.21.2", "@oxc-resolver/binding-win32-x64-msvc": "11.21.2" } }, "sha512-w5tLwYN3Zo24w5EeWJjJWZOwhYqTtC8PS2B1tIt7BZUuqTIcU07sQValbDw+rq7+AuAGzOHklgK+ifsy4lpXfw=="], "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], @@ -2191,8 +2261,6 @@ "picomatch": ["picomatch@4.0.5", "", {}, "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A=="], - "pify": ["pify@2.3.0", "", {}, "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="], - "pino": ["pino@10.3.1", "", { "dependencies": { "@pinojs/redact": "^0.4.0", "atomic-sleep": "^1.0.0", "on-exit-leak-free": "^2.1.0", "pino-abstract-transport": "^3.0.0", "pino-std-serializers": "^7.0.0", "process-warning": "^5.0.0", "quick-format-unescaped": "^4.0.3", "real-require": "^0.2.0", "safe-stable-stringify": "^2.3.1", "sonic-boom": "^4.0.1", "thread-stream": "^4.0.0" }, "bin": { "pino": "bin.js" } }, "sha512-r34yH/GlQpKZbU1BvFFqOjhISRo1MNx1tWYsYvmj6KIRHSPMT2+yHOEb1SG6NMvRoHRF0a07kCOox/9yakl1vg=="], "pino-abstract-transport": ["pino-abstract-transport@3.0.0", "", { "dependencies": { "split2": "^4.0.0" } }, "sha512-wlfUczU+n7Hy/Ha5j9a/gZNy7We5+cXp8YL+X+PG8S0KXxw7n/JXA3c46Y0zQznIJ83URJiwy7Lh56WLokNuxg=="], @@ -2289,9 +2357,11 @@ "react-dropzone-esm": ["react-dropzone-esm@15.2.0", "", { "dependencies": { "prop-types": "^15.8.1" }, "peerDependencies": { "react": ">= 16.8 || 18.0.0" } }, "sha512-pPwR8xWVL+tFLnbAb8KVH5f6Vtl397tck8dINkZ1cPMxHWH+l9dFmIgRWgbh7V7jbjIcuKXCsVrXbhQz68+dVA=="], + "react-error-boundary": ["react-error-boundary@6.1.3", "", { "peerDependencies": { "@types/react": "^18.0.0 || ^19.0.0", "react": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-GnSKpCohFi2nQmJCWwP8O8wub7zexlePvpsejvQr35vS5RTouS1+utTNOmyc540yw5vyOXnSL1rBWsCQDmkyUA=="], + "react-hot-toast": ["react-hot-toast@2.6.0", "", { "dependencies": { "csstype": "^3.1.3", "goober": "^2.1.16" }, "peerDependencies": { "react": ">=16", "react-dom": ">=16" } }, "sha512-bH+2EBMZ4sdyou/DPrfgIouFpcRLCJ+HoCA32UoAYHn6T3Ur5yfcDCeSr5mwldl6pFOsiocmrXMuoCJ1vV8bWg=="], - "react-i18next": ["react-i18next@17.0.11", "", { "dependencies": { "@babel/runtime": "^7.29.2", "html-parse-stringify": "^4.0.1", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "i18next": ">= 26.2.0", "react": ">= 16.8.0", "typescript": "^5 || ^6 || ^7" }, "optionalPeers": ["typescript"] }, "sha512-cDtkXgxjuFTWUH6V+aQn1Ve5vDiUztCNPWW5GtSHDccsgRXO1nE6QFWCEmc1KAutrb3OUv87wFShJL5RhUwPXg=="], + "react-i18next": ["react-i18next@17.0.12", "", { "dependencies": { "@babel/runtime": "^7.29.7", "html-parse-stringify": "^4.0.1", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "i18next": ">= 26.2.0", "react": ">= 16.8.0", "typescript": "^5 || ^6 || ^7" }, "optionalPeers": ["typescript"] }, "sha512-lFWPEGkxQ6RhusdUkysFBD58VHfSSzvHBzqMgN0SvfVpdQGfwtNkStTqdy08/sJd7s807qqutgx93fRpD0DJ3Q=="], "react-is": ["react-is@17.0.2", "", {}, "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="], @@ -2307,13 +2377,13 @@ "react-virtualized-auto-sizer": ["react-virtualized-auto-sizer@1.0.26", "", { "peerDependencies": { "react": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-CblNyiNVw2o+hsa5/49NH2ogGxZ+t+3aweRvNSq7TVjDIlwk7ir4lencEg5HxHeSzwNarSkNkiu0qJSOXtxm5A=="], - "read-cache": ["read-cache@1.0.0", "", { "dependencies": { "pify": "^2.3.0" } }, "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="], + "read-cache": ["read-cache@1.0.2", "", {}, "sha512-/peqiBB/n07gQGLsWaHho3WfvUyRscw0gYTsEFMhrIe/nWLkYaf5SbKYjGYqtRV3aPwykJgF2VEMo1ac4bnsGA=="], "readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="], "readdir-glob": ["readdir-glob@1.1.3", "", { "dependencies": { "minimatch": "^5.1.0" } }, "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA=="], - "readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], + "readdirp": ["readdirp@5.1.1", "", {}, "sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA=="], "real-require": ["real-require@0.2.0", "", {}, "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg=="], @@ -2455,7 +2525,7 @@ "stdin-discarder": ["stdin-discarder@0.2.2", "", {}, "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ=="], - "storybook": ["storybook@10.5.9", "", { "dependencies": { "@storybook/global": "^5.0.0", "@storybook/icons": "^2.0.2", "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "6.9.1", "@testing-library/user-event": "^14.6.1", "@vitest/expect": "3.2.4", "@vitest/spy": "3.2.4", "@webcontainer/env": "^1.1.1", "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0 || ^0.28.0", "jsonc-parser": "^3.3.1", "open": "^10.2.0", "oxc-parser": "^0.127.0", "oxc-resolver": "^11.19.1", "recast": "^0.23.5", "semver": "^7.7.3", "use-sync-external-store": "^1.5.0", "ws": "^8.21.1" }, "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "prettier": "^2 || ^3", "vite-plus": "^0.1.15 || ^0.2.0" }, "optionalPeers": ["@types/react", "prettier", "vite-plus"], "bin": "./dist/bin/dispatcher.js" }, "sha512-UfdMKSjEhIKr8LbqYyIE5r7vT/drL/PxN75YaouJ+UG0FssEy6cf49OdTF3kstAqVMHskc+zEqyRoiQHZXHwgA=="], + "storybook": ["storybook@10.5.10", "", { "dependencies": { "@storybook/global": "^5.0.0", "@storybook/icons": "^2.0.2", "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "6.9.1", "@testing-library/user-event": "^14.6.1", "@vitest/expect": "3.2.4", "@vitest/spy": "3.2.4", "@webcontainer/env": "^1.1.1", "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0 || ^0.28.0", "jsonc-parser": "^3.3.1", "open": "^10.2.0", "oxc-parser": "^0.127.0", "oxc-resolver": "11.21.2", "recast": "^0.23.5", "semver": "^7.7.3", "use-sync-external-store": "^1.5.0", "ws": "^8.21.1" }, "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "prettier": "^2 || ^3", "vite-plus": "^0.1.15 || ^0.2.0" }, "optionalPeers": ["@types/react", "prettier", "vite-plus"], "bin": "./dist/bin/dispatcher.js" }, "sha512-Rz8k9ejFHsi7lbtJTaxZlhCUz4GkbJIKEoKDjXeLfr/ZhXip73E6keKxW0KH8iGeKiCqHAbJCV4YIQrxTOLiig=="], "streamx": ["streamx@2.28.0", "", { "dependencies": { "events-universal": "^1.0.0", "fast-fifo": "^1.3.2", "text-decoder": "^1.1.0" } }, "sha512-1Yowhzjf0ivGMrTIkY9hav5TxobO9qIVqUE41fiCGMGgc3CLlf4MY+9AHmZqBWgDTue0fY9zWjYFVyf6Diuobw=="], @@ -2601,7 +2671,7 @@ "union-value": ["union-value@1.0.1", "", { "dependencies": { "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", "set-value": "^2.0.1" } }, "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg=="], - "unplugin": ["unplugin@2.3.11", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "acorn": "^8.15.0", "picomatch": "^4.0.3", "webpack-virtual-modules": "^0.6.2" } }, "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww=="], + "unplugin": ["unplugin@3.3.0", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "picomatch": "^4.0.4", "webpack-virtual-modules": "^0.6.2" }, "peerDependencies": { "@farmfe/core": "*", "@rspack/core": "*", "bun-types-no-globals": "*", "esbuild": "*", "rolldown": "*", "rollup": "*", "unloader": "*", "vite": "*", "webpack": "*" }, "optionalPeers": ["@farmfe/core", "@rspack/core", "bun-types-no-globals", "esbuild", "rolldown", "rollup", "unloader", "vite", "webpack"] }, "sha512-qa66K+crbfyE6JK10GjvbJeRrOsuC/JpbnHctfyp/i4oBTxWOzJfRZyDiOk1PtErMFRu8JhsU/wPvOdBNWe5Rg=="], "unstorage": ["unstorage@2.0.0-alpha.3", "", { "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6.0.3 || ^7.0.0", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1.0.1", "aws4fetch": "^1.0.20", "chokidar": "^4.0.3", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "lru-cache": "^11.2.2", "mongodb": "^6.20.0", "ofetch": "^1.4.1", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "chokidar", "db0", "idb-keyval", "ioredis", "lru-cache", "mongodb", "ofetch", "uploadthing"] }, "sha512-BeoqISVh8jxqnPseHH7/92twe2VkQztrudXg8RFZVbXb4ckkFdpLk1LnNvsUndDltyodBMVxgI6V7JcbJYt2VQ=="], @@ -2617,7 +2687,7 @@ "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], - "uuid": ["uuid@14.0.1", "", { "bin": { "uuid": "dist-node/bin/uuid" } }, "sha512-6ZxzVpzDXDa3bJWaHilVayA+BH/1zmxCJoVgvmqJnid/gPoKHxUrS/aC/T6LGQtNHT+XHG9fXPJB4d+IrU30Ew=="], + "uuid": ["uuid@14.0.2", "", { "bin": { "uuid": "dist-node/bin/uuid" } }, "sha512-xZe/16rV4aa+HGSOCiY2YeLT1OybRLrrkL/Rqaq7p7GMVXjFh+6wN4oMYgjFmnSnhY8t6Xpdl2l9qmnHYuMHwQ=="], "vinyl": ["vinyl@2.2.1", "", { "dependencies": { "clone": "^2.1.1", "clone-buffer": "^1.0.0", "clone-stats": "^1.0.0", "cloneable-readable": "^1.0.0", "remove-trailing-separator": "^1.0.1", "replace-ext": "^1.0.0" } }, "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw=="], @@ -2631,7 +2701,7 @@ "w3c-xmlserializer": ["w3c-xmlserializer@5.0.0", "", { "dependencies": { "xml-name-validator": "^5.0.0" } }, "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA=="], - "web-vitals": ["web-vitals@4.2.4", "", {}, "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw=="], + "web-vitals": ["web-vitals@5.3.0", "", {}, "sha512-q6LWsLatGYZp5VGBIOvbTj6JBV2nOmC8KvWztXBmwJcfFAzhwKwbOxhUH306XY3CcaZDUlSmSuNPBsCn0bFu+g=="], "webidl-conversions": ["webidl-conversions@8.0.1", "", {}, "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ=="], @@ -2705,12 +2775,20 @@ "@babel/code-frame/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], + "@babel/core/@babel/code-frame": ["@babel/code-frame@7.29.7", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw=="], + "@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], "@babel/helper-compilation-targets/lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], "@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + "@babel/template/@babel/code-frame": ["@babel/code-frame@7.29.7", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw=="], + + "@babel/traverse/@babel/code-frame": ["@babel/code-frame@7.29.7", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw=="], + + "@firebase/performance/web-vitals": ["web-vitals@4.2.4", "", {}, "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw=="], + "@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="], "@isaacs/cliui/wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="], @@ -2721,14 +2799,16 @@ "@oslojs/jwt/@oslojs/encoding": ["@oslojs/encoding@0.4.1", "", {}, "sha512-hkjo6MuIK/kQR5CrGNdAPZhS01ZCXuWDRJ187zh6qqF2+yMHZpD9fAYpX8q2bOO6Ryhl3XpCT6kUX76N8hhm4Q=="], - "@oxc-resolver/binding-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.11.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" } }, "sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA=="], + "@oxc-resolver/binding-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.11.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" } }, "sha512-l9Oo58x0HOP5znGzVhYW9U3e5wVuA4LAZU2AGezTmkhO1CgQRFDhDg4nneHsu/t3WniXg9QrG2nIXL/ZS8ln8Q=="], - "@oxc-resolver/binding-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.11.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA=="], + "@oxc-resolver/binding-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.11.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-55coeOFKHv1ywEcUXJtWU5f+Jr/W5tZDvZig8DLKSwUN1JpROQ4rk/SNOQiFWmaR/VKF4zuFyW1B8JduOSv6Pg=="], "@rollup/pluginutils/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], "@segment/analytics.js-video-plugins/unfetch": ["unfetch@3.1.2", "", {}, "sha512-L0qrK7ZeAudGiKYw6nzFjnJ2D5WHblUBwmHIqtPS6oKUd+Hcpk7/hKsSmcHsTlpd1TbTNsiRBUKRq3bHLNIqIw=="], + "@storybook/csf-plugin/unplugin": ["unplugin@2.3.11", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "acorn": "^8.15.0", "picomatch": "^4.0.3", "webpack-virtual-modules": "^0.6.2" } }, "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww=="], + "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.11.3", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.3", "tslib": "^2.4.0" }, "bundled": true }, "sha512-zLpS5asjEb7lq8jYLq37N6XKaE41DIexlY1rF/z4/tIl3wo13Sqm28fRyfIsKZD+NZ8mM5RoKkpW/rBcuoSZSg=="], "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.11.3", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA=="], @@ -2743,7 +2823,7 @@ "@tanstack/devtools/@tanstack/devtools-client": ["@tanstack/devtools-client@0.0.8", "", { "dependencies": { "@tanstack/devtools-event-client": "^0.5.0" } }, "sha512-cG3iZkGWCwN330bLBKa8+9r4Of2AXNoz2zUqcsy/4XsD3105ghVBx78cGyvJj9fSclNomPxoqAnDGXXhg1WLvA=="], - "@tanstack/devtools/@tanstack/devtools-event-bus": ["@tanstack/devtools-event-bus@0.4.2", "", { "dependencies": { "ws": "^8.18.3" } }, "sha512-2LHzhwBFlKHCcklsQrGe8TeyjHd4XAF8nuCO6wHmva5fePUkJUULbu6CsCNAlGlCi0KkEsMXZSvRdR4HgMq4yA=="], + "@tanstack/devtools/@tanstack/devtools-event-bus": ["@tanstack/devtools-event-bus@0.4.3", "", { "dependencies": { "ws": "^8.18.3" } }, "sha512-NeegBt5/n2E5q4DbrXHqECBq42+kDi6JBOp8/+RNqkIE+P4hJpbM36kGyjnGQFMWOoku31qhMyX9/48VuTTdmg=="], "@tanstack/form-devtools/@tanstack/devtools-ui": ["@tanstack/devtools-ui@0.5.3", "", { "dependencies": { "clsx": "^2.1.1", "dayjs": "^1.11.19", "goober": "^2.1.16", "solid-js": "^1.9.9" } }, "sha512-iJjwWtdXhUGpeHyyW9+3NhXhmlVFhh3v3UBNKCouykG9UFXEtneVVNXgSRpd70DeYJFmvKOY19LafKRI5/cM7A=="], @@ -2751,20 +2831,22 @@ "@tanstack/router-core/cookie-es": ["cookie-es@3.1.1", "", {}, "sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg=="], - "@tanstack/router-plugin/chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], + "@tanstack/router-generator/@tanstack/router-core": ["@tanstack/router-core@1.171.13", "", { "dependencies": { "@tanstack/history": "1.162.0", "cookie-es": "^3.0.0", "seroval": "^1.5.4", "seroval-plugins": "^1.5.4" } }, "sha512-+NOwEj1kO/6IGmpHRIZHasYxYWpyBQGNIZAST9aNrk9Q3YlU9SgqVnl1pbLa9qAKfeNdXQIRve0RQb/0kyDeDA=="], - "@tanstack/router-plugin/unplugin": ["unplugin@3.3.0", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "picomatch": "^4.0.4", "webpack-virtual-modules": "^0.6.2" }, "peerDependencies": { "@farmfe/core": "*", "@rspack/core": "*", "bun-types-no-globals": "*", "esbuild": "*", "rolldown": "*", "rollup": "*", "unloader": "*", "vite": "*", "webpack": "*" }, "optionalPeers": ["@farmfe/core", "@rspack/core", "bun-types-no-globals", "esbuild", "rolldown", "rollup", "unloader", "vite", "webpack"] }, "sha512-qa66K+crbfyE6JK10GjvbJeRrOsuC/JpbnHctfyp/i4oBTxWOzJfRZyDiOk1PtErMFRu8JhsU/wPvOdBNWe5Rg=="], + "@tanstack/router-plugin/@tanstack/router-core": ["@tanstack/router-core@1.171.13", "", { "dependencies": { "@tanstack/history": "1.162.0", "cookie-es": "^3.0.0", "seroval": "^1.5.4", "seroval-plugins": "^1.5.4" } }, "sha512-+NOwEj1kO/6IGmpHRIZHasYxYWpyBQGNIZAST9aNrk9Q3YlU9SgqVnl1pbLa9qAKfeNdXQIRve0RQb/0kyDeDA=="], - "@tanstack/start-plugin-core/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="], + "@tanstack/start-plugin-core/@tanstack/router-generator": ["@tanstack/router-generator@1.167.21", "", { "dependencies": { "@babel/types": "^7.28.5", "@tanstack/router-core": "1.171.15", "@tanstack/router-utils": "1.162.2", "@tanstack/virtual-file-routes": "1.162.0", "jiti": "^2.7.0", "magic-string": "^0.30.21", "prettier": "^3.5.0", "zod": "^4.4.3" } }, "sha512-m3oXZyienj8owialdyoZ0txHQrnEx/Ra+D9kWtar5fC2cWZr5Pvxl86VY2mX5RRLC5QLKLeRGT1x4HV95wHVDQ=="], + + "@tanstack/start-plugin-core/@tanstack/router-plugin": ["@tanstack/router-plugin@1.168.23", "", { "dependencies": { "@babel/core": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "@tanstack/router-core": "1.171.15", "@tanstack/router-generator": "1.167.21", "@tanstack/router-utils": "1.162.2", "chokidar": "^5.0.0", "unplugin": "^3.0.0", "zod": "^4.4.3" }, "peerDependencies": { "@rsbuild/core": ">=1.0.2 || ^2.0.0", "@tanstack/react-router": "^1.170.18", "vite": ">=5.0.0 || >=6.0.0 || >=7.0.0 || >=8.0.0", "vite-plugin-solid": "^2.11.10 || ^3.0.0-0", "webpack": ">=5.92.0" }, "optionalPeers": ["@rsbuild/core", "@tanstack/react-router", "vite", "vite-plugin-solid", "webpack"] }, "sha512-0+PIcvnaAimFwjoEIeV3h7LKjzC8zNnp7pH2UamdKwQ9QlY99WU9V0Xl0zbM0i9hrUa/mKgWPDAzELmPUu5fMA=="], "@tanstack/start-plugin-core/lightningcss": ["lightningcss@1.33.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.33.0", "lightningcss-darwin-arm64": "1.33.0", "lightningcss-darwin-x64": "1.33.0", "lightningcss-freebsd-x64": "1.33.0", "lightningcss-linux-arm-gnueabihf": "1.33.0", "lightningcss-linux-arm64-gnu": "1.33.0", "lightningcss-linux-arm64-musl": "1.33.0", "lightningcss-linux-x64-gnu": "1.33.0", "lightningcss-linux-x64-musl": "1.33.0", "lightningcss-win32-arm64-msvc": "1.33.0", "lightningcss-win32-x64-msvc": "1.33.0" } }, "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA=="], "@tanstack/start-plugin-core/srvx": ["srvx@0.11.22", "", { "bin": { "srvx": "bin/srvx.mjs" } }, "sha512-LqZxxBDMKuMAZzFzJnDCkFOrs9MZQZr0LvHiO/SuSZVdQaXD7xQ5UWTUxheJrQPve1qk9MG2B/yttUvJxw8egQ=="], - "@testing-library/jest-dom/aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="], - "@testing-library/jest-dom/dom-accessibility-api": ["dom-accessibility-api@0.6.3", "", {}, "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w=="], + "@types/ssh2/@types/node": ["@types/node@18.19.130", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg=="], + "@vitejs/plugin-react/react-refresh": ["react-refresh@0.14.2", "", {}, "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA=="], "@xyflow/react/zustand": ["zustand@4.5.7", "", { "dependencies": { "use-sync-external-store": "^1.2.2" }, "peerDependencies": { "@types/react": ">=16.8", "immer": ">=9.0.6", "react": ">=16.8" }, "optionalPeers": ["@types/react", "immer", "react"] }, "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw=="], @@ -2775,13 +2857,19 @@ "app-builder/@vitejs/plugin-react": ["@vitejs/plugin-react@5.2.0", "", { "dependencies": { "@babel/core": "^7.29.0", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-rc.3", "@types/babel__core": "^7.20.5", "react-refresh": "^0.18.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw=="], - "bl/buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="], + "backoffice/@tanstack/react-router": ["@tanstack/react-router@1.170.16", "", { "dependencies": { "@tanstack/history": "1.162.0", "@tanstack/react-store": "^0.9.3", "@tanstack/router-core": "1.171.13", "isbot": "^5.1.22" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-w6eq1IJklujs1tESazaK/FxH0+H2l8vm/QPuu1cD3oRW/ubgKneQpd7b64ti/8gUyEimzimJQZDmJr6YHfP5+g=="], - "bl/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], + "backoffice/@tanstack/react-start": ["@tanstack/react-start@1.168.26", "", { "dependencies": { "@tanstack/react-router": "1.170.16", "@tanstack/react-start-client": "1.168.14", "@tanstack/react-start-rsc": "0.1.25", "@tanstack/react-start-server": "1.167.20", "@tanstack/router-utils": "1.162.2", "@tanstack/start-client-core": "1.170.12", "@tanstack/start-plugin-core": "1.171.18", "@tanstack/start-server-core": "1.169.15", "pathe": "^2.0.3" }, "peerDependencies": { "@rsbuild/core": "^2.0.0", "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0", "vite": ">=7.0.0" }, "optionalPeers": ["@rsbuild/core", "vite"] }, "sha512-ZzNecqKWC0p2643/kIcFUdsMrXZ8A4dXm4Yfe9zV/Y0u14MtSkh/Sk76RQYIU5S84VyDyKhHo0Ffh8HQbLdvFw=="], + + "backoffice/@vitejs/plugin-react": ["@vitejs/plugin-react@5.2.0", "", { "dependencies": { "@babel/core": "^7.29.0", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-rc.3", "@types/babel__core": "^7.20.5", "react-refresh": "^0.18.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw=="], + + "backoffice/tailwindcss": ["tailwindcss@4.3.2", "", {}, "sha512-WtctNNSH8A9jlMIqxzuYumOHU5uGZyRv0Q5svQl+oEPy5w84YpBxdb7MdqyiSPQge5jTJ6zFQLq0PFygdccSBA=="], + + "backoffice/vitest": ["vitest@4.1.8", "", { "dependencies": { "@vitest/expect": "4.1.8", "@vitest/mocker": "4.1.8", "@vitest/pretty-format": "4.1.8", "@vitest/runner": "4.1.8", "@vitest/snapshot": "4.1.8", "@vitest/spy": "4.1.8", "@vitest/utils": "4.1.8", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", "obug": "^2.1.1", "pathe": "^2.0.3", "picomatch": "^4.0.3", "std-env": "^4.0.0-rc.1", "tinybench": "^2.9.0", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tinyrainbow": "^3.1.0", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", "@vitest/browser-playwright": "4.1.8", "@vitest/browser-preview": "4.1.8", "@vitest/browser-webdriverio": "4.1.8", "@vitest/coverage-istanbul": "4.1.8", "@vitest/coverage-v8": "4.1.8", "@vitest/ui": "4.1.8", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@opentelemetry/api", "@types/node", "@vitest/browser-playwright", "@vitest/browser-preview", "@vitest/browser-webdriverio", "@vitest/coverage-istanbul", "@vitest/coverage-v8", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-flY6ScbCIt9HThs+C5HS7jvGOB560DJtk/Z15IQROTA6zEy49Nh8T/dofWTQL+n3vswqn87sbJNiuqw1SDp5Ig=="], - "chokidar/fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="], + "bl/buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="], - "chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + "bl/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], "cliui/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], @@ -2851,28 +2939,24 @@ "react-docgen/strip-indent": ["strip-indent@4.1.1", "", {}, "sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA=="], - "readdirp/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], - "recast/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], "restore-cursor/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], - "rollup/fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="], - "solid-js/seroval": ["seroval@1.5.6", "", {}, "sha512-rVQVWjjSvlINzaQPZH5JFqsqEsIWdTxY3iJZCnTL/5gQbXIRooVZKI60tVCkOVfzcRPejboxO2t0P89dg5mQaA=="], "solid-js/seroval-plugins": ["seroval-plugins@1.5.6", "", { "peerDependencies": { "seroval": "^1.0" } }, "sha512-HXuLAX2pu/UByPpaeo/TaMfvMIi+1QqIoPJYCcAtU8QkVNwgR6MPlGuCQTErV1JwraaMbYaWVIBX7mppzGLATQ=="], "split-string/extend-shallow": ["extend-shallow@3.0.2", "", { "dependencies": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" } }, "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q=="], + "ssh-remote-port-forward/@types/ssh2": ["@types/ssh2@0.5.52", "", { "dependencies": { "@types/node": "*", "@types/ssh2-streams": "*" } }, "sha512-lbLLlXxdCZOSJMCInKH2+9V/77ET2J6NPQHpFI0kda61Dd1KglJs+fPQBchizmzYSOJBgdTajhPqBO1xxLywvg=="], + "storybook/@testing-library/jest-dom": ["@testing-library/jest-dom@6.9.1", "", { "dependencies": { "@adobe/css-tools": "^4.4.0", "aria-query": "^5.0.0", "css.escape": "^1.5.1", "dom-accessibility-api": "^0.6.3", "picocolors": "^1.1.1", "redent": "^3.0.0" } }, "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA=="], "storybook/@vitest/expect": ["@vitest/expect@3.2.4", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/spy": "3.2.4", "@vitest/utils": "3.2.4", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" } }, "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig=="], "storybook/@vitest/spy": ["@vitest/spy@3.2.4", "", { "dependencies": { "tinyspy": "^4.0.3" } }, "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw=="], - "storybook/esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="], - "string-width-cjs/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], "string-width-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], @@ -2921,6 +3005,12 @@ "@apidevtools/swagger-cli/yargs/yargs-parser": ["yargs-parser@18.1.3", "", { "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" } }, "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ=="], + "@babel/core/@babel/code-frame/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], + + "@babel/template/@babel/code-frame/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], + + "@babel/traverse/@babel/code-frame/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], + "@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], "@isaacs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], @@ -2931,9 +3021,9 @@ "@tanstack/react-router/@tanstack/react-store/@tanstack/store": ["@tanstack/store@0.9.3", "", {}, "sha512-8reSzl/qGWGGVKhBoxXPMWzATSbZLZFWhwBAFO9NAyp0TxzfBP0mIrGb8CP8KrQTmvzXlR/vFPPUrHTLBGyFyw=="], - "@tanstack/router-plugin/chokidar/readdirp": ["readdirp@5.1.1", "", {}, "sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA=="], + "@tanstack/router-generator/@tanstack/router-core/cookie-es": ["cookie-es@3.1.1", "", {}, "sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg=="], - "@tanstack/start-plugin-core/@babel/code-frame/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], + "@tanstack/router-plugin/@tanstack/router-core/cookie-es": ["cookie-es@3.1.1", "", {}, "sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg=="], "@tanstack/start-plugin-core/lightningcss/lightningcss-android-arm64": ["lightningcss-android-arm64@1.33.0", "", { "os": "android", "cpu": "arm64" }, "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg=="], @@ -2957,6 +3047,38 @@ "@tanstack/start-plugin-core/lightningcss/lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.33.0", "", { "os": "win32", "cpu": "x64" }, "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA=="], + "@types/ssh2/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + + "backoffice/@tanstack/react-router/@tanstack/react-store": ["@tanstack/react-store@0.9.3", "", { "dependencies": { "@tanstack/store": "0.9.3", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-y2iHd/N9OkoQbFJLUX1T9vbc2O9tjH0pQRgTcx1/Nz4IlwLvkgpuglXUx+mXt0g5ZDFrEeDnONPqkbfxXJKwRg=="], + + "backoffice/@tanstack/react-router/@tanstack/router-core": ["@tanstack/router-core@1.171.13", "", { "dependencies": { "@tanstack/history": "1.162.0", "cookie-es": "^3.0.0", "seroval": "^1.5.4", "seroval-plugins": "^1.5.4" } }, "sha512-+NOwEj1kO/6IGmpHRIZHasYxYWpyBQGNIZAST9aNrk9Q3YlU9SgqVnl1pbLa9qAKfeNdXQIRve0RQb/0kyDeDA=="], + + "backoffice/@tanstack/react-start/@tanstack/react-start-client": ["@tanstack/react-start-client@1.168.14", "", { "dependencies": { "@tanstack/react-router": "1.170.16", "@tanstack/router-core": "1.171.13", "@tanstack/start-client-core": "1.170.12" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-oaz43fdOhBWfOPsdLkp3IejwYEXRyeaZ4CYexOPZx3eVXzm4LLozvNkkkBE9aje1sM5MVC2Yo6+cyv2HdVzkHQ=="], + + "backoffice/@tanstack/react-start/@tanstack/react-start-rsc": ["@tanstack/react-start-rsc@0.1.25", "", { "dependencies": { "@tanstack/react-router": "1.170.16", "@tanstack/router-core": "1.171.13", "@tanstack/router-utils": "1.162.2", "@tanstack/start-client-core": "1.170.12", "@tanstack/start-fn-stubs": "1.162.0", "@tanstack/start-plugin-core": "1.171.18", "@tanstack/start-server-core": "1.169.15", "@tanstack/start-storage-context": "1.167.15", "pathe": "^2.0.3" }, "peerDependencies": { "@rspack/core": ">=2.0.0-0", "@vitejs/plugin-rsc": ">=0.5.20", "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0", "react-server-dom-rspack": ">=0.0.2" }, "optionalPeers": ["@rspack/core", "@vitejs/plugin-rsc", "react-server-dom-rspack"] }, "sha512-Rwm6cjcS148y2XAebr8jyrwU0SqsRSkW4/CuXesoHg+G3IOnVRHV0HOylJfnznUTVuH1nVhfQRPI5uWPJaw2TA=="], + + "backoffice/@tanstack/react-start/@tanstack/react-start-server": ["@tanstack/react-start-server@1.167.20", "", { "dependencies": { "@tanstack/react-router": "1.170.16", "@tanstack/router-core": "1.171.13", "@tanstack/start-server-core": "1.169.15" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-hg9xVI6yNDu+6NCalKz1h3Ea18HZEUu35i/ZMJz1WadwqcArLMp41nM1GNhOAtGIdpycrp9tT7ccqc9zuRMRpQ=="], + + "backoffice/@tanstack/react-start/@tanstack/start-client-core": ["@tanstack/start-client-core@1.170.12", "", { "dependencies": { "@tanstack/router-core": "1.171.13", "@tanstack/start-fn-stubs": "1.162.0", "@tanstack/start-storage-context": "1.167.15", "seroval": "^1.5.4" } }, "sha512-gwtZRMPUIAxmDV2AIQUhC0kSW262SV7BkHXEgy5B1woHQdrdsELuGOdJwdweLxrjyefORxk+9MYGqDY0Cxn0bw=="], + + "backoffice/@tanstack/react-start/@tanstack/start-plugin-core": ["@tanstack/start-plugin-core@1.171.18", "", { "dependencies": { "@babel/code-frame": "7.27.1", "@babel/core": "^7.28.5", "@babel/types": "^7.28.5", "@tanstack/router-core": "1.171.13", "@tanstack/router-generator": "1.167.17", "@tanstack/router-plugin": "1.168.18", "@tanstack/router-utils": "1.162.2", "@tanstack/start-server-core": "1.169.15", "exsolve": "^1.0.7", "lightningcss": "^1.32.0", "pathe": "^2.0.3", "picomatch": "^4.0.3", "seroval": "^1.5.4", "source-map": "^0.7.6", "srvx": "^0.11.9", "tinyglobby": "^0.2.15", "ufo": "^1.5.4", "vitefu": "^1.1.1", "xmlbuilder2": "^4.0.3", "zod": "^4.4.3" }, "peerDependencies": { "@rsbuild/core": "^2.0.0", "vite": ">=7.0.0" }, "optionalPeers": ["@rsbuild/core", "vite"] }, "sha512-weuOOjRD03BiKcF9NYKL5QADEQOp3yGHb0qIsOX42ENz5XUE4in2fXcVYHjSwwpzs+XGhWIFLp5J385pOVPuZQ=="], + + "backoffice/@tanstack/react-start/@tanstack/start-server-core": ["@tanstack/start-server-core@1.169.15", "", { "dependencies": { "@tanstack/history": "1.162.0", "@tanstack/router-core": "1.171.13", "@tanstack/start-client-core": "1.170.12", "@tanstack/start-storage-context": "1.167.15", "fetchdts": "^0.1.6", "h3-v2": "npm:h3@2.0.1-rc.20", "seroval": "^1.5.4" } }, "sha512-V8ie2G2Ecb3Nklk8/QuKzulxb+tDUqgz6rjJe8Isdp4iKVXZu/TscItkUP/4Q5Bu7W4gUy3P25O6soC1oW1SXQ=="], + + "backoffice/vitest/@vitest/expect": ["@vitest/expect@4.1.8", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", "@vitest/spy": "4.1.8", "@vitest/utils": "4.1.8", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" } }, "sha512-h3nDO677RDLEGlBxyQ5CW8RlMThSKSRLUePLOx09gNIWRL40edgA1GCZSZgf1W55MFAG6/Sw14KeaAnqv0NKdQ=="], + + "backoffice/vitest/@vitest/mocker": ["@vitest/mocker@4.1.8", "", { "dependencies": { "@vitest/spy": "4.1.8", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["msw", "vite"] }, "sha512-LEiN/xe4OSIbKe9HQIp5OC24agGD9J5CnmMgsLohVVoOPWL9a2sBoR6VBx43jQZb7Kr1l4RCuyCJzcAa0+dojw=="], + + "backoffice/vitest/@vitest/pretty-format": ["@vitest/pretty-format@4.1.8", "", { "dependencies": { "tinyrainbow": "^3.1.0" } }, "sha512-9GasEBxpZ1VYIpqHf/0+YGg121uSNwCKOJqIrTwWP/TB7DmFCiaBpNl3aPZzoLWfWkuqhbH8vJIVobZkvdo2cA=="], + + "backoffice/vitest/@vitest/runner": ["@vitest/runner@4.1.8", "", { "dependencies": { "@vitest/utils": "4.1.8", "pathe": "^2.0.3" } }, "sha512-EmVxeBAfMJvycdjd6Hm+RbFBbA9fKvo0Kx37hNpBYoYeavH3RNsBXWDooR1mgD52dCrxIIuP7UotpfiwOikvcg=="], + + "backoffice/vitest/@vitest/snapshot": ["@vitest/snapshot@4.1.8", "", { "dependencies": { "@vitest/pretty-format": "4.1.8", "@vitest/utils": "4.1.8", "magic-string": "^0.30.21", "pathe": "^2.0.3" } }, "sha512-acfZboRmAIf05DEKcBQy33VXojFJjtUdLyo7oOmV9kebb2xdU01UknNiPuPZoJZQyO7DF0gZdTGTpeAzET9QPQ=="], + + "backoffice/vitest/@vitest/spy": ["@vitest/spy@4.1.8", "", {}, "sha512-6EevtBp6OZOPF7bmz36HrGMeP3txgVSrgebWxHOafDXGkhIzfXK14f8KF6MuFfgXXUeHxmpD3BQxkV00/3s5mA=="], + + "backoffice/vitest/@vitest/utils": ["@vitest/utils@4.1.8", "", { "dependencies": { "@vitest/pretty-format": "4.1.8", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" } }, "sha512-uOJamYALNhfJ6iolExyQM40yIQwDqYnkKtQ5VCiSe17E33H0aQ/u+1GlRuz4LZBk6Mm3sg90G9hEbmEt37C1Zg=="], + "cliui/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], "cloneable-readable/readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], @@ -3043,8 +3165,6 @@ "split-string/extend-shallow/is-extendable": ["is-extendable@1.0.1", "", { "dependencies": { "is-plain-object": "^2.0.4" } }, "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA=="], - "storybook/@testing-library/jest-dom/aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="], - "storybook/@testing-library/jest-dom/dom-accessibility-api": ["dom-accessibility-api@0.6.3", "", {}, "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w=="], "storybook/@vitest/expect/@vitest/utils": ["@vitest/utils@3.2.4", "", { "dependencies": { "@vitest/pretty-format": "3.2.4", "loupe": "^3.1.4", "tinyrainbow": "^2.0.0" } }, "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA=="], @@ -3053,90 +3173,106 @@ "storybook/@vitest/expect/tinyrainbow": ["tinyrainbow@2.0.0", "", {}, "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw=="], - "storybook/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="], + "svgo/css-tree/mdn-data": ["mdn-data@2.0.14", "", {}, "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow=="], + + "svgo/css-tree/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], + + "wrap-ansi-cjs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + + "wrap-ansi/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + + "yargs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], - "storybook/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="], + "yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "storybook/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="], + "@apidevtools/swagger-cli/@apidevtools/swagger-parser/@apidevtools/json-schema-ref-parser/js-yaml": ["js-yaml@4.3.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ=="], - "storybook/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="], + "@apidevtools/swagger-cli/yargs/cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "storybook/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="], + "@apidevtools/swagger-cli/yargs/cliui/wrap-ansi": ["wrap-ansi@6.2.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA=="], - "storybook/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="], + "@apidevtools/swagger-cli/yargs/find-up/locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="], - "storybook/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="], + "@apidevtools/swagger-cli/yargs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], - "storybook/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="], + "@apidevtools/swagger-cli/yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "storybook/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="], + "backoffice/@tanstack/react-router/@tanstack/react-store/@tanstack/store": ["@tanstack/store@0.9.3", "", {}, "sha512-8reSzl/qGWGGVKhBoxXPMWzATSbZLZFWhwBAFO9NAyp0TxzfBP0mIrGb8CP8KrQTmvzXlR/vFPPUrHTLBGyFyw=="], - "storybook/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="], + "backoffice/@tanstack/react-router/@tanstack/router-core/cookie-es": ["cookie-es@3.1.1", "", {}, "sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg=="], - "storybook/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="], + "backoffice/@tanstack/react-start/@tanstack/react-start-client/@tanstack/router-core": ["@tanstack/router-core@1.171.13", "", { "dependencies": { "@tanstack/history": "1.162.0", "cookie-es": "^3.0.0", "seroval": "^1.5.4", "seroval-plugins": "^1.5.4" } }, "sha512-+NOwEj1kO/6IGmpHRIZHasYxYWpyBQGNIZAST9aNrk9Q3YlU9SgqVnl1pbLa9qAKfeNdXQIRve0RQb/0kyDeDA=="], - "storybook/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="], + "backoffice/@tanstack/react-start/@tanstack/react-start-rsc/@tanstack/router-core": ["@tanstack/router-core@1.171.13", "", { "dependencies": { "@tanstack/history": "1.162.0", "cookie-es": "^3.0.0", "seroval": "^1.5.4", "seroval-plugins": "^1.5.4" } }, "sha512-+NOwEj1kO/6IGmpHRIZHasYxYWpyBQGNIZAST9aNrk9Q3YlU9SgqVnl1pbLa9qAKfeNdXQIRve0RQb/0kyDeDA=="], - "storybook/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="], + "backoffice/@tanstack/react-start/@tanstack/react-start-rsc/@tanstack/start-storage-context": ["@tanstack/start-storage-context@1.167.15", "", { "dependencies": { "@tanstack/router-core": "1.171.13" } }, "sha512-Jy0q4vdG6pv76N92+X+ag3fuOV2zINQagYyMN1/es7tPI1vzpKECIU8AqHqzI6ahkwaph7XDvmfUkiLJ3i4LOA=="], - "storybook/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="], + "backoffice/@tanstack/react-start/@tanstack/react-start-server/@tanstack/router-core": ["@tanstack/router-core@1.171.13", "", { "dependencies": { "@tanstack/history": "1.162.0", "cookie-es": "^3.0.0", "seroval": "^1.5.4", "seroval-plugins": "^1.5.4" } }, "sha512-+NOwEj1kO/6IGmpHRIZHasYxYWpyBQGNIZAST9aNrk9Q3YlU9SgqVnl1pbLa9qAKfeNdXQIRve0RQb/0kyDeDA=="], - "storybook/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="], + "backoffice/@tanstack/react-start/@tanstack/start-client-core/@tanstack/router-core": ["@tanstack/router-core@1.171.13", "", { "dependencies": { "@tanstack/history": "1.162.0", "cookie-es": "^3.0.0", "seroval": "^1.5.4", "seroval-plugins": "^1.5.4" } }, "sha512-+NOwEj1kO/6IGmpHRIZHasYxYWpyBQGNIZAST9aNrk9Q3YlU9SgqVnl1pbLa9qAKfeNdXQIRve0RQb/0kyDeDA=="], - "storybook/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="], + "backoffice/@tanstack/react-start/@tanstack/start-client-core/@tanstack/start-storage-context": ["@tanstack/start-storage-context@1.167.15", "", { "dependencies": { "@tanstack/router-core": "1.171.13" } }, "sha512-Jy0q4vdG6pv76N92+X+ag3fuOV2zINQagYyMN1/es7tPI1vzpKECIU8AqHqzI6ahkwaph7XDvmfUkiLJ3i4LOA=="], - "storybook/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="], + "backoffice/@tanstack/react-start/@tanstack/start-plugin-core/@tanstack/router-core": ["@tanstack/router-core@1.171.13", "", { "dependencies": { "@tanstack/history": "1.162.0", "cookie-es": "^3.0.0", "seroval": "^1.5.4", "seroval-plugins": "^1.5.4" } }, "sha512-+NOwEj1kO/6IGmpHRIZHasYxYWpyBQGNIZAST9aNrk9Q3YlU9SgqVnl1pbLa9qAKfeNdXQIRve0RQb/0kyDeDA=="], - "storybook/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg=="], + "backoffice/@tanstack/react-start/@tanstack/start-plugin-core/lightningcss": ["lightningcss@1.33.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.33.0", "lightningcss-darwin-arm64": "1.33.0", "lightningcss-darwin-x64": "1.33.0", "lightningcss-freebsd-x64": "1.33.0", "lightningcss-linux-arm-gnueabihf": "1.33.0", "lightningcss-linux-arm64-gnu": "1.33.0", "lightningcss-linux-arm64-musl": "1.33.0", "lightningcss-linux-x64-gnu": "1.33.0", "lightningcss-linux-x64-musl": "1.33.0", "lightningcss-win32-arm64-msvc": "1.33.0", "lightningcss-win32-x64-msvc": "1.33.0" } }, "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA=="], - "storybook/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="], + "backoffice/@tanstack/react-start/@tanstack/start-plugin-core/srvx": ["srvx@0.11.22", "", { "bin": { "srvx": "bin/srvx.mjs" } }, "sha512-LqZxxBDMKuMAZzFzJnDCkFOrs9MZQZr0LvHiO/SuSZVdQaXD7xQ5UWTUxheJrQPve1qk9MG2B/yttUvJxw8egQ=="], - "storybook/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.12", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A=="], + "backoffice/@tanstack/react-start/@tanstack/start-server-core/@tanstack/router-core": ["@tanstack/router-core@1.171.13", "", { "dependencies": { "@tanstack/history": "1.162.0", "cookie-es": "^3.0.0", "seroval": "^1.5.4", "seroval-plugins": "^1.5.4" } }, "sha512-+NOwEj1kO/6IGmpHRIZHasYxYWpyBQGNIZAST9aNrk9Q3YlU9SgqVnl1pbLa9qAKfeNdXQIRve0RQb/0kyDeDA=="], - "storybook/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="], + "backoffice/@tanstack/react-start/@tanstack/start-server-core/@tanstack/start-storage-context": ["@tanstack/start-storage-context@1.167.15", "", { "dependencies": { "@tanstack/router-core": "1.171.13" } }, "sha512-Jy0q4vdG6pv76N92+X+ag3fuOV2zINQagYyMN1/es7tPI1vzpKECIU8AqHqzI6ahkwaph7XDvmfUkiLJ3i4LOA=="], - "storybook/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg=="], + "dockerode/tar-fs/tar-stream/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], - "storybook/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="], + "marble-api/tailwind-preset/tailwindcss/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], - "storybook/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="], + "storybook/@vitest/expect/@vitest/utils/@vitest/pretty-format": ["@vitest/pretty-format@3.2.4", "", { "dependencies": { "tinyrainbow": "^2.0.0" } }, "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA=="], - "storybook/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="], + "@apidevtools/swagger-cli/yargs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], - "storybook/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="], + "@apidevtools/swagger-cli/yargs/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="], - "svgo/css-tree/mdn-data": ["mdn-data@2.0.14", "", {}, "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow=="], + "backoffice/@tanstack/react-start/@tanstack/react-start-client/@tanstack/router-core/cookie-es": ["cookie-es@3.1.1", "", {}, "sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg=="], - "svgo/css-tree/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], + "backoffice/@tanstack/react-start/@tanstack/react-start-rsc/@tanstack/router-core/cookie-es": ["cookie-es@3.1.1", "", {}, "sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg=="], - "wrap-ansi-cjs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + "backoffice/@tanstack/react-start/@tanstack/react-start-server/@tanstack/router-core/cookie-es": ["cookie-es@3.1.1", "", {}, "sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg=="], - "wrap-ansi/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + "backoffice/@tanstack/react-start/@tanstack/start-client-core/@tanstack/router-core/cookie-es": ["cookie-es@3.1.1", "", {}, "sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg=="], - "yargs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + "backoffice/@tanstack/react-start/@tanstack/start-plugin-core/@tanstack/router-core/cookie-es": ["cookie-es@3.1.1", "", {}, "sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg=="], - "yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + "backoffice/@tanstack/react-start/@tanstack/start-plugin-core/lightningcss/lightningcss-android-arm64": ["lightningcss-android-arm64@1.33.0", "", { "os": "android", "cpu": "arm64" }, "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg=="], - "@apidevtools/swagger-cli/@apidevtools/swagger-parser/@apidevtools/json-schema-ref-parser/js-yaml": ["js-yaml@4.3.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ=="], + "backoffice/@tanstack/react-start/@tanstack/start-plugin-core/lightningcss/lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.33.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg=="], - "@apidevtools/swagger-cli/yargs/cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + "backoffice/@tanstack/react-start/@tanstack/start-plugin-core/lightningcss/lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.33.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ=="], - "@apidevtools/swagger-cli/yargs/cliui/wrap-ansi": ["wrap-ansi@6.2.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA=="], + "backoffice/@tanstack/react-start/@tanstack/start-plugin-core/lightningcss/lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.33.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg=="], - "@apidevtools/swagger-cli/yargs/find-up/locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="], + "backoffice/@tanstack/react-start/@tanstack/start-plugin-core/lightningcss/lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.33.0", "", { "os": "linux", "cpu": "arm" }, "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ=="], - "@apidevtools/swagger-cli/yargs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + "backoffice/@tanstack/react-start/@tanstack/start-plugin-core/lightningcss/lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.33.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg=="], - "@apidevtools/swagger-cli/yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + "backoffice/@tanstack/react-start/@tanstack/start-plugin-core/lightningcss/lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.33.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ=="], - "dockerode/tar-fs/tar-stream/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], + "backoffice/@tanstack/react-start/@tanstack/start-plugin-core/lightningcss/lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.33.0", "", { "os": "linux", "cpu": "x64" }, "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg=="], - "storybook/@vitest/expect/@vitest/utils/@vitest/pretty-format": ["@vitest/pretty-format@3.2.4", "", { "dependencies": { "tinyrainbow": "^2.0.0" } }, "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA=="], + "backoffice/@tanstack/react-start/@tanstack/start-plugin-core/lightningcss/lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.33.0", "", { "os": "linux", "cpu": "x64" }, "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw=="], - "@apidevtools/swagger-cli/yargs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + "backoffice/@tanstack/react-start/@tanstack/start-plugin-core/lightningcss/lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.33.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA=="], - "@apidevtools/swagger-cli/yargs/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="], + "backoffice/@tanstack/react-start/@tanstack/start-plugin-core/lightningcss/lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.33.0", "", { "os": "win32", "cpu": "x64" }, "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA=="], + + "backoffice/@tanstack/react-start/@tanstack/start-server-core/@tanstack/router-core/cookie-es": ["cookie-es@3.1.1", "", {}, "sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg=="], + + "marble-api/tailwind-preset/tailwindcss/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + + "marble-api/tailwind-preset/tailwindcss/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], "@apidevtools/swagger-cli/yargs/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="], + + "marble-api/tailwind-preset/tailwindcss/chokidar/readdirp/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], } } diff --git a/package.json b/package.json index 9d0da4ab8d..c59a4f94a7 100644 --- a/package.json +++ b/package.json @@ -16,13 +16,16 @@ "cookie": "^0.7.2", "cross-spawn": "^7.0.5", "minimatch": "9.0.7", - "glob": "10.5.0" + "glob": "10.5.0", + "react": "18.3.1", + "react-dom": "18.3.1" }, "packageManager": "bun@1.3.10", "private": true, "scripts": { "format:write": "biome format . --write", "format:check": "biome format .", + "postinstall": "node scripts/link-single-react.mjs", "test:all": "bun run -F '*' unit-tests", "update-deps": "bun update --latest -r -i; clear; bun pm ls --all > packages-licenses.txt" }, @@ -32,6 +35,8 @@ "packages/*" ], "dependencies": { + "react": "18.3.1", + "react-dom": "18.3.1", "tailwindcss-grid-areas": "^0.1.1" } } diff --git a/packages/app-builder/package.json b/packages/app-builder/package.json index 6f07a2a6b1..4ec7ba7200 100644 --- a/packages/app-builder/package.json +++ b/packages/app-builder/package.json @@ -124,12 +124,12 @@ "tailwindcss-radix": "^4.0.2", "temporal-polyfill": "^1.0.2", "tiny-invariant": "^1.3.3", - "ts-pattern": "^5.6.2", + "ts-pattern": "^5.9.0", "typescript-utils": "workspace:*", "ui-design-system": "workspace:*", "ui-icons": "workspace:*", "uuid": "^14.0.0", - "zod": "^4.1.8", + "zod": "^4.1.11", "zustand": "^5.0.14" } } diff --git a/packages/app-builder/src/components/Analytics/CustomFiltersForm.tsx b/packages/app-builder/src/components/Analytics/CustomFiltersForm.tsx index ee791e5962..d4f6e5159f 100644 --- a/packages/app-builder/src/components/Analytics/CustomFiltersForm.tsx +++ b/packages/app-builder/src/components/Analytics/CustomFiltersForm.tsx @@ -1,4 +1,3 @@ -import { Panel } from '@app-builder/components/Panel'; import type { DateRangeFilter } from '@app-builder/models/analytics'; import { useGetCustomFiltersConfigQuery } from '@app-builder/queries/analytics/get-custom-filters-config'; import { useDeleteFilterMutation } from '@app-builder/queries/settings/scenarios/delete-filter'; @@ -23,7 +22,7 @@ import { useQueryClient } from '@tanstack/react-query'; import { useEffect, useMemo, useState } from 'react'; import toast from 'react-hot-toast'; import { useTranslation } from 'react-i18next'; -import { Button, cn, MenuCommand, Modal, Typo } from 'ui-design-system'; +import { Button, cn, MenuCommand, Modal, Panel, Typo } from 'ui-design-system'; import { Icon } from 'ui-icons'; interface CustomFiltersFormProps { diff --git a/packages/app-builder/src/components/CaseManager/AiReview/AiReviewPanel.tsx b/packages/app-builder/src/components/CaseManager/AiReview/AiReviewPanel.tsx index 2fd882e340..eb069c4aec 100644 --- a/packages/app-builder/src/components/CaseManager/AiReview/AiReviewPanel.tsx +++ b/packages/app-builder/src/components/CaseManager/AiReview/AiReviewPanel.tsx @@ -1,4 +1,3 @@ -import { Panel } from '@app-builder/components/Panel'; import { type AiCaseReviewListItem, type AiCaseReviewStatus } from '@app-builder/models/cases'; import { useAddReviewToCaseCommentsMutation } from '@app-builder/queries/add-review-to-case-comments'; import { useEnqueueCaseReviewMutation } from '@app-builder/queries/ask-case-review'; @@ -8,7 +7,7 @@ import { useFormatDateTime } from '@app-builder/utils/format'; import { useState } from 'react'; import toast from 'react-hot-toast'; import { useTranslation } from 'react-i18next'; -import { Button, Markdown, Tag, Typo } from 'ui-design-system'; +import { Button, Markdown, Panel, Tag, Typo } from 'ui-design-system'; import { Icon } from 'ui-icons'; import { AiReviewStatusMessage } from './AiReviewStatusMessage'; diff --git a/packages/app-builder/src/components/CaseManager/CaseEvents.tsx b/packages/app-builder/src/components/CaseManager/CaseEvents.tsx index 8cb3ef5359..35bf72ccf8 100644 --- a/packages/app-builder/src/components/CaseManager/CaseEvents.tsx +++ b/packages/app-builder/src/components/CaseManager/CaseEvents.tsx @@ -1,5 +1,4 @@ import { CaseEventDetail } from '@app-builder/components/Cases/Events/CaseEventDetail'; -import { Panel } from '@app-builder/components/Panel'; import { type CaseEvent, type CaseEventType, type CaseStatus } from '@app-builder/models/cases'; import { type CalendarDayDistance, @@ -11,7 +10,7 @@ import { useFormatTimezone } from '@app-builder/utils/format'; import { useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { match } from 'ts-pattern'; -import { Button, cn, Typo } from 'ui-design-system'; +import { Button, cn, Panel, Typo } from 'ui-design-system'; import { Icon } from 'ui-icons'; type CaseEventsProps = { diff --git a/packages/app-builder/src/components/CaseManager/ContinuousScreening/RequestSideInfo.tsx b/packages/app-builder/src/components/CaseManager/ContinuousScreening/RequestSideInfo.tsx index d189e55be9..2bb64ea494 100644 --- a/packages/app-builder/src/components/CaseManager/ContinuousScreening/RequestSideInfo.tsx +++ b/packages/app-builder/src/components/CaseManager/ContinuousScreening/RequestSideInfo.tsx @@ -1,6 +1,5 @@ import { Callout } from '@app-builder/components/Callout'; import { DataListGrid } from '@app-builder/components/DataModelExplorer/DataListGrid'; -import { Panel } from '@app-builder/components/Panel'; import { EntityProperties } from '@app-builder/components/Screenings/EntityProperties'; import { EntityDatasetsList } from '@app-builder/components/Screenings/MatchCard/match-card-entity-components'; import { TopicTag } from '@app-builder/components/Screenings/TopicTag'; @@ -17,7 +16,7 @@ import { import { useState } from 'react'; import { Trans, useTranslation } from 'react-i18next'; import { match } from 'ts-pattern'; -import { Button, Card, cn, Tag, Typo } from 'ui-design-system'; +import { Button, Card, cn, Panel, Tag, Typo } from 'ui-design-system'; import { Icon } from 'ui-icons'; import { ObjectDetails } from './ObjectDetails'; import { RequestDetail } from './RequestDetail'; diff --git a/packages/app-builder/src/components/CaseManager/KycEnrichment/KycEnrichmentPanel.tsx b/packages/app-builder/src/components/CaseManager/KycEnrichment/KycEnrichmentPanel.tsx index dd0d041d0b..c8e12c1f31 100644 --- a/packages/app-builder/src/components/CaseManager/KycEnrichment/KycEnrichmentPanel.tsx +++ b/packages/app-builder/src/components/CaseManager/KycEnrichment/KycEnrichmentPanel.tsx @@ -1,4 +1,3 @@ -import { Panel } from '@app-builder/components/Panel'; import { useLoaderRevalidator } from '@app-builder/contexts/LoaderRevalidatorContext'; import { useAddCommentMutation } from '@app-builder/queries/cases/add-comment'; import { useCreateKycEnrichmentQuery } from '@app-builder/queries/cases/create-kyc-enrichment'; @@ -6,7 +5,7 @@ import * as Sentry from '@sentry/tanstackstart-react'; import { useEffect, useState } from 'react'; import toast from 'react-hot-toast'; import { useTranslation } from 'react-i18next'; -import { Markdown, Typo } from 'ui-design-system'; +import { Markdown, Panel, Typo } from 'ui-design-system'; import { Icon } from 'ui-icons'; import { Callout } from '../../Callout'; import { Spinner } from '../../Spinner'; diff --git a/packages/app-builder/src/components/CaseManager/PrincipalPage.tsx b/packages/app-builder/src/components/CaseManager/PrincipalPage.tsx index d07c2f7698..8d98bdfac5 100644 --- a/packages/app-builder/src/components/CaseManager/PrincipalPage.tsx +++ b/packages/app-builder/src/components/CaseManager/PrincipalPage.tsx @@ -5,7 +5,6 @@ import { DataFields } from '@app-builder/components/Data/DataVisualisation/DataF import { DataExplorerPanel } from '@app-builder/components/DataModelExplorer/DataExplorerPanel'; import { DataModelExplorerProvider } from '@app-builder/components/DataModelExplorer/Provider'; import { pageLayoutGutter } from '@app-builder/components/Page/page-layout'; -import { Panel } from '@app-builder/components/Panel'; import { DataModel, DataModelObject } from '@app-builder/models'; import { CaseDetail, PivotObject } from '@app-builder/models/cases'; import { FeatureAccesses } from '@app-builder/models/feature-access'; @@ -22,7 +21,7 @@ import type { Client360Table } from 'marble-api'; import { type FeatureAccessLevelDto } from 'marble-api/generated/feature-access-api'; import { useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { Button, Card, CtaV2ClassName, cn, Tag, TagList } from 'ui-design-system'; +import { Button, Card, CtaV2ClassName, cn, Panel, Tag, TagList } from 'ui-design-system'; import { Icon } from 'ui-icons'; import { AiReviewCard } from './AiReview/AiReviewCard'; import { CaseEvents } from './CaseEvents'; diff --git a/packages/app-builder/src/components/CaseManager/SnoozePanel/CaseSnoozePanel.tsx b/packages/app-builder/src/components/CaseManager/SnoozePanel/CaseSnoozePanel.tsx index c1d414f01a..b669efc608 100644 --- a/packages/app-builder/src/components/CaseManager/SnoozePanel/CaseSnoozePanel.tsx +++ b/packages/app-builder/src/components/CaseManager/SnoozePanel/CaseSnoozePanel.tsx @@ -1,7 +1,6 @@ import { casesI18n } from '@app-builder/components/Cases'; import { AddRuleSnooze } from '@app-builder/components/Cases/AddRuleSnooze'; import { Nudge } from '@app-builder/components/Nudge'; -import { Panel } from '@app-builder/components/Panel'; import { RuleGroup } from '@app-builder/components/Scenario/Rules/RuleGroup'; import { ScoreModifier } from '@app-builder/components/Scenario/Rules/ScoreModifier'; import { DataModel } from '@app-builder/models'; @@ -15,7 +14,7 @@ import { Dict } from '@swan-io/boxed'; import { formatRelative } from 'date-fns'; import { useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { Button, cn, Tabs, tabClassName } from 'ui-design-system'; +import { Button, cn, Panel, Tabs, tabClassName } from 'ui-design-system'; import { Icon } from 'ui-icons'; import { PivotObjectDetails } from './PivotObjectDetails'; diff --git a/packages/app-builder/src/components/Cases/CaseAlerts.tsx b/packages/app-builder/src/components/Cases/CaseAlerts.tsx index f409e1603e..e7b493a6a4 100644 --- a/packages/app-builder/src/components/Cases/CaseAlerts.tsx +++ b/packages/app-builder/src/components/Cases/CaseAlerts.tsx @@ -1,4 +1,3 @@ -import { Panel } from '@app-builder/components/Panel'; import { type DetailedCaseDecision } from '@app-builder/models/cases'; import { DataModel, getTriggerObjectFields } from '@app-builder/models/data-model'; import { type ReviewStatus } from '@app-builder/models/decision'; @@ -12,7 +11,7 @@ import { MouseEvent, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { map, pipe, take } from 'remeda'; import { match } from 'ts-pattern'; -import { Button, cn, ExpandableGroupTagLine, Tooltip } from 'ui-design-system'; +import { Button, cn, ExpandableGroupTagLine, Panel, Tooltip } from 'ui-design-system'; import { Icon } from 'ui-icons'; import { ReviewStatusTag } from '../Decisions/ReviewStatusTag'; import { FormatData } from '../FormatData'; diff --git a/packages/app-builder/src/components/Cases/CreateCase.tsx b/packages/app-builder/src/components/Cases/CreateCase.tsx index 33be735ed6..9ad65b8ebb 100644 --- a/packages/app-builder/src/components/Cases/CreateCase.tsx +++ b/packages/app-builder/src/components/Cases/CreateCase.tsx @@ -1,7 +1,6 @@ import { FormErrorOrDescription } from '@app-builder/components/Form/Tanstack/FormErrorOrDescription'; import { FormInput } from '@app-builder/components/Form/Tanstack/FormInput'; import { FormLabel } from '@app-builder/components/Form/Tanstack/FormLabel'; -import { Panel } from '@app-builder/components/Panel'; import { useLoaderRevalidator } from '@app-builder/contexts/LoaderRevalidatorContext'; import { CreateCasePayload, @@ -14,7 +13,7 @@ import { useForm } from '@tanstack/react-form'; import { useQueryClient } from '@tanstack/react-query'; import toast from 'react-hot-toast'; import { useTranslation } from 'react-i18next'; -import { SelectV2 } from 'ui-design-system'; +import { Panel, SelectV2 } from 'ui-design-system'; export function CreateCase({ inboxId }: { inboxId: string | null }) { const { t } = useTranslation(['cases', 'common']); diff --git a/packages/app-builder/src/components/Cases/DecisionPanel/DecisionPanel.tsx b/packages/app-builder/src/components/Cases/DecisionPanel/DecisionPanel.tsx index 625e43975d..c8dc5134cd 100644 --- a/packages/app-builder/src/components/Cases/DecisionPanel/DecisionPanel.tsx +++ b/packages/app-builder/src/components/Cases/DecisionPanel/DecisionPanel.tsx @@ -12,7 +12,6 @@ import { RulesExecutionsContainer, } from '@app-builder/components/Decisions/RulesExecutions/RulesExecutions'; import { CaseDetailTriggerObject } from '@app-builder/components/Decisions/TriggerObjectDetail'; -import { Panel } from '@app-builder/components/Panel'; import { ScoreModifier } from '@app-builder/components/Scenario/Rules/ScoreModifier'; import { Spinner } from '@app-builder/components/Spinner'; import { DataModel } from '@app-builder/models'; @@ -22,7 +21,7 @@ import { useScenarioIterationRules } from '@app-builder/queries/scenarios/scenar import { useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { match } from 'ts-pattern'; -import { Button, Switch } from 'ui-design-system'; +import { Button, Panel, Switch } from 'ui-design-system'; type DecisionPanelProps = { decision: DetailedCaseDecision; diff --git a/packages/app-builder/src/components/Cases/InboxPage.tsx b/packages/app-builder/src/components/Cases/InboxPage.tsx index f46f75affc..3b45816802 100644 --- a/packages/app-builder/src/components/Cases/InboxPage.tsx +++ b/packages/app-builder/src/components/Cases/InboxPage.tsx @@ -2,7 +2,6 @@ import { Page } from '@app-builder/components'; import { CasesList } from '@app-builder/components/Cases/Inbox/CasesList'; import { FavoriteInboxButton } from '@app-builder/components/Cases/Inbox/FavoriteInboxButton'; import { InboxFilterBar } from '@app-builder/components/Cases/Inbox/FilterBar/FilterBar'; -import { Panel } from '@app-builder/components/Panel'; import { MY_INBOX_ID } from '@app-builder/constants/inboxes'; import { useAgnosticNavigation } from '@app-builder/contexts/AgnosticNavigationContext'; import { useBase64Query } from '@app-builder/hooks/useBase64Query'; @@ -18,7 +17,7 @@ import { useQueryClient } from '@tanstack/react-query'; import { useEffect, useMemo, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { match } from 'ts-pattern'; -import { Button, cn, SearchInput } from 'ui-design-system'; +import { Button, cn, Panel, SearchInput } from 'ui-design-system'; import { Icon } from 'ui-icons'; import { Spinner } from '../Spinner'; import { CreateCase } from './CreateCase'; diff --git a/packages/app-builder/src/components/Cases/Overview/Panel/AIConfigPanelContent.tsx b/packages/app-builder/src/components/Cases/Overview/Panel/AIConfigPanelContent.tsx index 5c9b3593c6..7dc66e89a6 100644 --- a/packages/app-builder/src/components/Cases/Overview/Panel/AIConfigPanelContent.tsx +++ b/packages/app-builder/src/components/Cases/Overview/Panel/AIConfigPanelContent.tsx @@ -3,14 +3,13 @@ import { ExternalLink } from '@app-builder/components/ExternalLink'; import { FormErrorOrDescription } from '@app-builder/components/Form/Tanstack/FormErrorOrDescription'; import { FormLabel } from '@app-builder/components/Form/Tanstack/FormLabel'; import { FormTextArea } from '@app-builder/components/Form/Tanstack/FormTextArea'; -import { Panel } from '@app-builder/components/Panel'; import { type AiSettingSchema, aiSettingSchema } from '@app-builder/models/ai-settings'; import { useUpdateAiSettings } from '@app-builder/queries/cases/update-ai-settings'; import { getFieldErrors, handleSubmit } from '@app-builder/utils/form'; import { useForm } from '@tanstack/react-form'; import toast from 'react-hot-toast'; import { Trans, useTranslation } from 'react-i18next'; -import { Button, Input, Switch, Tooltip } from 'ui-design-system'; +import { Button, Input, Panel, Switch, Tooltip } from 'ui-design-system'; import { Icon } from 'ui-icons'; import { LanguageDropdown } from './LanguageDropdown'; diff --git a/packages/app-builder/src/components/Cases/Overview/Panel/AutoAssignmentPanelContent.tsx b/packages/app-builder/src/components/Cases/Overview/Panel/AutoAssignmentPanelContent.tsx index 2acf8df1f4..540a904953 100644 --- a/packages/app-builder/src/components/Cases/Overview/Panel/AutoAssignmentPanelContent.tsx +++ b/packages/app-builder/src/components/Cases/Overview/Panel/AutoAssignmentPanelContent.tsx @@ -1,4 +1,3 @@ -import { Panel, PanelSharpFactory } from '@app-builder/components/Panel'; import { Spinner } from '@app-builder/components/Spinner'; import { useLoaderRevalidator } from '@app-builder/contexts/LoaderRevalidatorContext'; import { type InboxWithCasesCount } from '@app-builder/models/inbox'; @@ -8,6 +7,7 @@ import { useState } from 'react'; import toast from 'react-hot-toast'; import { useTranslation } from 'react-i18next'; import { match } from 'ts-pattern'; +import { Panel, PanelSharpFactory } from 'ui-design-system'; import { InboxCard } from './InboxCard'; interface AutoAssignmentChanges { diff --git a/packages/app-builder/src/components/Cases/Overview/Panel/EscalationConditionsPanelContent.tsx b/packages/app-builder/src/components/Cases/Overview/Panel/EscalationConditionsPanelContent.tsx index a41cceb584..08c5f82fc8 100644 --- a/packages/app-builder/src/components/Cases/Overview/Panel/EscalationConditionsPanelContent.tsx +++ b/packages/app-builder/src/components/Cases/Overview/Panel/EscalationConditionsPanelContent.tsx @@ -1,4 +1,3 @@ -import { Panel, PanelSharpFactory } from '@app-builder/components/Panel'; import { Spinner } from '@app-builder/components/Spinner'; import { useLoaderRevalidator } from '@app-builder/contexts/LoaderRevalidatorContext'; import { type InboxMetadata } from '@app-builder/models/inbox'; @@ -8,7 +7,7 @@ import { useCallback, useEffect, useId, useRef, useState } from 'react'; import toast from 'react-hot-toast'; import { useTranslation } from 'react-i18next'; import { match } from 'ts-pattern'; -import { Button } from 'ui-design-system'; +import { Button, Panel, PanelSharpFactory } from 'ui-design-system'; import { type EscalationCondition, EscalationConditionRow } from './EscalationConditionRow'; interface EscalationConditionsPanelContentProps { diff --git a/packages/app-builder/src/components/Cases/Overview/Panel/SlaConfigPanelContent.tsx b/packages/app-builder/src/components/Cases/Overview/Panel/SlaConfigPanelContent.tsx index 5fda3beae5..3339b01b78 100644 --- a/packages/app-builder/src/components/Cases/Overview/Panel/SlaConfigPanelContent.tsx +++ b/packages/app-builder/src/components/Cases/Overview/Panel/SlaConfigPanelContent.tsx @@ -1,4 +1,3 @@ -import { Panel, PanelSharpFactory } from '@app-builder/components/Panel'; import { Spinner } from '@app-builder/components/Spinner'; import { useLoaderRevalidator } from '@app-builder/contexts/LoaderRevalidatorContext'; import { InboxWithCasesCount } from '@app-builder/models/inbox'; @@ -9,7 +8,7 @@ import { useForm } from '@tanstack/react-form'; import toast from 'react-hot-toast'; import { useTranslation } from 'react-i18next'; import { match } from 'ts-pattern'; -import { Input, Switch } from 'ui-design-system'; +import { Input, Panel, PanelSharpFactory, Switch } from 'ui-design-system'; import { z } from 'zod/v4'; const SLA_FORM_ID = 'sla-config-panel-form'; diff --git a/packages/app-builder/src/components/Cases/Overview/Panel/WorkflowConfigPanelContent.tsx b/packages/app-builder/src/components/Cases/Overview/Panel/WorkflowConfigPanelContent.tsx index 3c7e003a13..41f8e7b0ff 100644 --- a/packages/app-builder/src/components/Cases/Overview/Panel/WorkflowConfigPanelContent.tsx +++ b/packages/app-builder/src/components/Cases/Overview/Panel/WorkflowConfigPanelContent.tsx @@ -1,4 +1,3 @@ -import { Panel, PanelSharpFactory } from '@app-builder/components/Panel'; import { Spinner } from '@app-builder/components/Spinner'; import { useLoaderRevalidator } from '@app-builder/contexts/LoaderRevalidatorContext'; import { useGetInboxesQuery } from '@app-builder/queries/cases/get-inboxes'; @@ -7,6 +6,7 @@ import { useEffect, useState } from 'react'; import toast from 'react-hot-toast'; import { useTranslation } from 'react-i18next'; import { match } from 'ts-pattern'; +import { Panel, PanelSharpFactory } from 'ui-design-system'; import { WorkflowInboxCard, type WorkflowSettings } from './WorkflowInboxCard'; type InboxWorkflowState = Map; diff --git a/packages/app-builder/src/components/Cases/Overview/Section/AIConfigSection.tsx b/packages/app-builder/src/components/Cases/Overview/Section/AIConfigSection.tsx index 44f612c65e..aa817050f6 100644 --- a/packages/app-builder/src/components/Cases/Overview/Section/AIConfigSection.tsx +++ b/packages/app-builder/src/components/Cases/Overview/Section/AIConfigSection.tsx @@ -1,4 +1,3 @@ -import { Panel } from '@app-builder/components/Panel'; import { Spinner } from '@app-builder/components/Spinner'; import { useLoaderRevalidator } from '@app-builder/contexts/LoaderRevalidatorContext'; import { useGetAiSettingsQuery } from '@app-builder/queries/cases/get-ai-settings'; @@ -7,7 +6,7 @@ import { type FeatureAccessLevelDto } from 'marble-api/generated/feature-access- import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { match } from 'ts-pattern'; -import { Tag } from 'ui-design-system'; +import { Panel, Tag } from 'ui-design-system'; import { AIConfigPanelContent } from '../Panel/AIConfigPanelContent'; import { ConfigRow } from './ConfigRow'; diff --git a/packages/app-builder/src/components/Cases/Overview/Section/AutoAssignmentSection.tsx b/packages/app-builder/src/components/Cases/Overview/Section/AutoAssignmentSection.tsx index 8df77cb89f..166768c0e8 100644 --- a/packages/app-builder/src/components/Cases/Overview/Section/AutoAssignmentSection.tsx +++ b/packages/app-builder/src/components/Cases/Overview/Section/AutoAssignmentSection.tsx @@ -1,4 +1,3 @@ -import { Panel } from '@app-builder/components/Panel'; import { Spinner } from '@app-builder/components/Spinner'; import { type InboxWithCasesCount } from '@app-builder/models/inbox'; import { useGetInboxesQuery } from '@app-builder/queries/cases/get-inboxes'; @@ -7,7 +6,7 @@ import { type FeatureAccessLevelDto } from 'marble-api/generated/feature-access- import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { match } from 'ts-pattern'; -import { Button, cn, Tag } from 'ui-design-system'; +import { Button, cn, Panel, Tag } from 'ui-design-system'; import { Icon } from 'ui-icons'; import { InboxUserRow } from '../InboxUserRow'; import { AutoAssignmentPanelContent } from '../Panel/AutoAssignmentPanelContent'; diff --git a/packages/app-builder/src/components/Cases/Overview/Section/WorkflowConfigSection.tsx b/packages/app-builder/src/components/Cases/Overview/Section/WorkflowConfigSection.tsx index f125934ff9..04bbc7537a 100644 --- a/packages/app-builder/src/components/Cases/Overview/Section/WorkflowConfigSection.tsx +++ b/packages/app-builder/src/components/Cases/Overview/Section/WorkflowConfigSection.tsx @@ -1,5 +1,4 @@ import { SlaConfigPanelContent } from '@app-builder/components/Cases/Overview/Panel/SlaConfigPanelContent'; -import { Panel } from '@app-builder/components/Panel'; import { Spinner } from '@app-builder/components/Spinner'; import { type InboxMetadata } from '@app-builder/models/inbox'; import { useGetInboxesQuery } from '@app-builder/queries/cases/get-inboxes'; @@ -8,7 +7,7 @@ import { type FeatureAccessLevelDto } from 'marble-api/generated/feature-access- import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { match } from 'ts-pattern'; -import { Tag } from 'ui-design-system'; +import { Panel, Tag } from 'ui-design-system'; import { EscalationConditionsPanelContent } from '../Panel/EscalationConditionsPanelContent'; import { WorkflowConfigPanelContent } from '../Panel/WorkflowConfigPanelContent'; import { ConfigRow } from './ConfigRow'; diff --git a/packages/app-builder/src/components/ClientDetail/ClientDetailPage.tsx b/packages/app-builder/src/components/ClientDetail/ClientDetailPage.tsx index 0afb8ecb72..5428e1433b 100644 --- a/packages/app-builder/src/components/ClientDetail/ClientDetailPage.tsx +++ b/packages/app-builder/src/components/ClientDetail/ClientDetailPage.tsx @@ -4,7 +4,6 @@ import { DataFields } from '@app-builder/components/Data/DataVisualisation/DataF import { DataExplorerPanel } from '@app-builder/components/DataModelExplorer/DataExplorerPanel'; import { DataModelExplorerProvider } from '@app-builder/components/DataModelExplorer/Provider'; import { Page } from '@app-builder/components/Page'; -import { Panel } from '@app-builder/components/Panel'; import { Spinner } from '@app-builder/components/Spinner'; import { DataModelObject, isAnalyst } from '@app-builder/models'; import { SCORING_LEVELS_COLORS, SCORING_LEVELS_LABEL_KEYS, type ScoringSettings } from '@app-builder/models/scoring'; @@ -23,7 +22,7 @@ import { type FeatureAccessLevelDto } from 'marble-api/generated/feature-access- import { useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { match } from 'ts-pattern'; -import { Button, cn, Popover, Tag } from 'ui-design-system'; +import { Button, cn, Panel, Popover, Tag } from 'ui-design-system'; import { Icon } from 'ui-icons'; import { AlertHitsList } from './AlertHitsList'; import { ClientComments } from './ClientComments'; diff --git a/packages/app-builder/src/components/ClientDetail/DocumentsList.tsx b/packages/app-builder/src/components/ClientDetail/DocumentsList.tsx index ca1f5adf81..c10d039676 100644 --- a/packages/app-builder/src/components/ClientDetail/DocumentsList.tsx +++ b/packages/app-builder/src/components/ClientDetail/DocumentsList.tsx @@ -1,4 +1,3 @@ -import { Panel } from '@app-builder/components/Panel'; import { User } from '@app-builder/models/user'; import { useGetCaseNameQuery } from '@app-builder/queries/cases/get-name'; import { useGetAnnotationsQuery } from '@app-builder/queries/data/get-annotations'; @@ -13,7 +12,7 @@ import { FileEntityAnnotationDto } from 'marble-api'; import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { match } from 'ts-pattern'; -import { Button, CtaV2ClassName, useFormatLanguage } from 'ui-design-system'; +import { Button, CtaV2ClassName, Panel, useFormatLanguage } from 'ui-design-system'; import { Icon } from 'ui-icons'; import { Spinner } from '../Spinner'; diff --git a/packages/app-builder/src/components/ClientDetail/ScoreDetailPanel.tsx b/packages/app-builder/src/components/ClientDetail/ScoreDetailPanel.tsx index 33da2eb4ee..1ba64de052 100644 --- a/packages/app-builder/src/components/ClientDetail/ScoreDetailPanel.tsx +++ b/packages/app-builder/src/components/ClientDetail/ScoreDetailPanel.tsx @@ -1,5 +1,4 @@ import { formatReturnValue } from '@app-builder/components/AstBuilder/viewing/helpers'; -import { Panel } from '@app-builder/components/Panel'; import { Spinner } from '@app-builder/components/Spinner'; import { SwitchNodeView } from '@app-builder/components/UserScoring/SwitchNode/SwitchNodeView'; import { type CustomList } from '@app-builder/models/custom-list'; @@ -23,7 +22,7 @@ import { useFormatDateTime } from '@app-builder/utils/format'; import { type ScoringScore } from 'marble-api'; import { useTranslation } from 'react-i18next'; import { match, P } from 'ts-pattern'; -import { Tag, Typo } from 'ui-design-system'; +import { Panel, Tag, Typo } from 'ui-design-system'; interface ScoreDetailPanelProps { open: boolean; diff --git a/packages/app-builder/src/components/ContinuousScreening/ConfigurationPanel.tsx b/packages/app-builder/src/components/ContinuousScreening/ConfigurationPanel.tsx index bcb52ab652..8669e2b73b 100644 --- a/packages/app-builder/src/components/ContinuousScreening/ConfigurationPanel.tsx +++ b/packages/app-builder/src/components/ContinuousScreening/ConfigurationPanel.tsx @@ -5,8 +5,7 @@ import { import { useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { match } from 'ts-pattern'; -import { Button } from 'ui-design-system'; -import { Panel } from '../Panel'; +import { Button, Panel } from 'ui-design-system'; import { ContinuousScreeningConfigurationStepper, PartialCreateContinuousScreeningConfig, diff --git a/packages/app-builder/src/components/ContinuousScreening/ConfigurationsPage.tsx b/packages/app-builder/src/components/ContinuousScreening/ConfigurationsPage.tsx index cff7447e36..3dd05ad2ef 100644 --- a/packages/app-builder/src/components/ContinuousScreening/ConfigurationsPage.tsx +++ b/packages/app-builder/src/components/ContinuousScreening/ConfigurationsPage.tsx @@ -1,4 +1,3 @@ -import { Panel } from '@app-builder/components/Panel'; import { useAgnosticNavigation } from '@app-builder/contexts/AgnosticNavigationContext'; import { ContinuousScreeningConfig, @@ -10,7 +9,7 @@ import QueryString from 'qs'; import { useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { match, P } from 'ts-pattern'; -import { Button, ExpandableGroupTagLine, Tag } from 'ui-design-system'; +import { Button, ExpandableGroupTagLine, Panel, Tag } from 'ui-design-system'; import { Icon } from 'ui-icons'; import { CopyToClipboardButton } from '../CopyToClipboardButton'; import GridTable from '../GridTable'; diff --git a/packages/app-builder/src/components/ContinuousScreening/EditionValidationPanel.tsx b/packages/app-builder/src/components/ContinuousScreening/EditionValidationPanel.tsx index fc63c5bed9..999935578b 100644 --- a/packages/app-builder/src/components/ContinuousScreening/EditionValidationPanel.tsx +++ b/packages/app-builder/src/components/ContinuousScreening/EditionValidationPanel.tsx @@ -8,8 +8,8 @@ import { ScreeningAvailableFiltersAdapted } from '@app-builder/models/screening' import { useUpdateContinuousScreeningConfigurationMutation } from '@app-builder/queries/continuous-screening/update-configuration'; import toast from 'react-hot-toast'; import { useTranslation } from 'react-i18next'; +import { Panel, PanelSharpFactory } from 'ui-design-system'; import { Callout } from '../Callout'; -import { Panel, PanelSharpFactory } from '../Panel'; import { DatasetSelectionSection } from './validation/DatasetSelectionSection'; import { GeneralInfoSection } from './validation/GeneralInfoSection'; import { ObjectMappingSection } from './validation/ObjectMappingSection'; diff --git a/packages/app-builder/src/components/ContinuousScreening/PanelAddCsv.tsx b/packages/app-builder/src/components/ContinuousScreening/PanelAddCsv.tsx index 7397bfe2b1..8e0a5182f9 100644 --- a/packages/app-builder/src/components/ContinuousScreening/PanelAddCsv.tsx +++ b/packages/app-builder/src/components/ContinuousScreening/PanelAddCsv.tsx @@ -9,14 +9,13 @@ import { toggle } from 'radash'; import { type MouseEvent, type SyntheticEvent, useMemo, useState } from 'react'; import { Trans, useTranslation } from 'react-i18next'; import { match } from 'ts-pattern'; -import { Button, Card, cn, MenuCommand, Switch, Tag, TagProps, Typo } from 'ui-design-system'; +import { Button, Card, cn, MenuCommand, Panel, Switch, Tag, TagProps, Typo } from 'ui-design-system'; import { Icon } from 'ui-icons'; import { DownloadCsvTemplate, UploadForm, type UploadFormIntermediateStepProps, } from '../Data/SemanticTables/UploadData/UploadIngestionComponents'; -import { Panel } from '../Panel'; export function PanelAddCsv({ configuration, diff --git a/packages/app-builder/src/components/ContinuousScreening/observability/ClientDataIndexing.tsx b/packages/app-builder/src/components/ContinuousScreening/observability/ClientDataIndexing.tsx index ddaf0a99fb..4139e94275 100644 --- a/packages/app-builder/src/components/ContinuousScreening/observability/ClientDataIndexing.tsx +++ b/packages/app-builder/src/components/ContinuousScreening/observability/ClientDataIndexing.tsx @@ -1,13 +1,12 @@ import { Callout } from '@app-builder/components/Callout'; import GridTable from '@app-builder/components/GridTable'; -import { Panel } from '@app-builder/components/Panel'; import { Spinner } from '@app-builder/components/Spinner'; import type { ContinuousScreeningClientDataIndexingResponse } from '@app-builder/models/continuous-screening'; import { useContinuousScreeningClientDataIndexingInfiniteQuery } from '@app-builder/queries/continuous-screening/client-data-indexing'; import { formatNumber } from '@app-builder/utils/format'; import { useTranslation } from 'react-i18next'; import { match } from 'ts-pattern'; -import { Card, DefaultTooltip, Typo, useFormatLanguage } from 'ui-design-system'; +import { Card, DefaultTooltip, Panel, Typo, useFormatLanguage } from 'ui-design-system'; import { Icon } from 'ui-icons'; import { LIMIT_FOR_PANELS, TagStatus, useDateAtFormat } from './utils'; diff --git a/packages/app-builder/src/components/ContinuousScreening/observability/DatasetUpdate.tsx b/packages/app-builder/src/components/ContinuousScreening/observability/DatasetUpdate.tsx index eeb1088f24..24bd7ba6c1 100644 --- a/packages/app-builder/src/components/ContinuousScreening/observability/DatasetUpdate.tsx +++ b/packages/app-builder/src/components/ContinuousScreening/observability/DatasetUpdate.tsx @@ -1,6 +1,5 @@ import { Callout } from '@app-builder/components/Callout'; import GridTable from '@app-builder/components/GridTable'; -import { Panel } from '@app-builder/components/Panel'; import { Spinner } from '@app-builder/components/Spinner'; import type { ContinuousScreeningDatasetUpdateCompletion, @@ -10,7 +9,7 @@ import { useContinuousScreeningDatasetUpdatesInfiniteQuery } from '@app-builder/ import { formatNumber } from '@app-builder/utils/format'; import { useTranslation } from 'react-i18next'; import { match } from 'ts-pattern'; -import { Card, DefaultTooltip, Typo, useFormatLanguage } from 'ui-design-system'; +import { Card, DefaultTooltip, Panel, Typo, useFormatLanguage } from 'ui-design-system'; import { Icon } from 'ui-icons'; import { LIMIT_FOR_PANELS, TagStatus, useDateAtFormat } from './utils'; diff --git a/packages/app-builder/src/components/ContinuousScreening/observability/UpdateJobs.tsx b/packages/app-builder/src/components/ContinuousScreening/observability/UpdateJobs.tsx index b64cfd0776..3b9c733a17 100644 --- a/packages/app-builder/src/components/ContinuousScreening/observability/UpdateJobs.tsx +++ b/packages/app-builder/src/components/ContinuousScreening/observability/UpdateJobs.tsx @@ -1,13 +1,12 @@ import { Callout } from '@app-builder/components/Callout'; import GridTable from '@app-builder/components/GridTable'; -import { Panel } from '@app-builder/components/Panel'; import { Spinner } from '@app-builder/components/Spinner'; import { ContinuousScreeningUpdateJobSummary } from '@app-builder/models/continuous-screening'; import { useContinuousScreeningUpdateJobsInfiniteQuery } from '@app-builder/queries/continuous-screening/update-jobs'; import { formatOptionalDuration } from '@app-builder/utils/datetime'; import { useTranslation } from 'react-i18next'; import { match } from 'ts-pattern'; -import { Tooltip, Typo, useFormatLanguage } from 'ui-design-system'; +import { Panel, Tooltip, Typo, useFormatLanguage } from 'ui-design-system'; import { Icon } from 'ui-icons'; import { GridStatus, getProgressValue, LIMIT_FOR_PANELS, useDateAtFormat } from './utils'; diff --git a/packages/app-builder/src/components/Data/SemanticTables/CreateTable/CreateTableDrawer.tsx b/packages/app-builder/src/components/Data/SemanticTables/CreateTable/CreateTableDrawer.tsx index 2b865b5e49..487d546209 100644 --- a/packages/app-builder/src/components/Data/SemanticTables/CreateTable/CreateTableDrawer.tsx +++ b/packages/app-builder/src/components/Data/SemanticTables/CreateTable/CreateTableDrawer.tsx @@ -1,11 +1,10 @@ import { Callout } from '@app-builder/components/Callout'; -import { Panel } from '@app-builder/components/Panel'; import { useDataModel } from '@app-builder/services/data/data-model'; import { handleSubmit } from '@app-builder/utils/form'; import { useStore } from '@tanstack/react-form'; import { useCallback, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { Stepper, type StepperStep, Typo } from 'ui-design-system'; +import { Panel, Stepper, type StepperStep, Typo } from 'ui-design-system'; import { UnsavedChangesDialog } from '../Shared/UnsavedChangesDialog'; import { CreateTableFormContext, useCreateTableForm } from './CreateTableContext'; import { CreateTableEntityStep } from './CreateTableEntityStep'; diff --git a/packages/app-builder/src/components/Data/SemanticTables/EditTable/EditTableDrawer.tsx b/packages/app-builder/src/components/Data/SemanticTables/EditTable/EditTableDrawer.tsx index f4977e9e09..397c671281 100644 --- a/packages/app-builder/src/components/Data/SemanticTables/EditTable/EditTableDrawer.tsx +++ b/packages/app-builder/src/components/Data/SemanticTables/EditTable/EditTableDrawer.tsx @@ -1,12 +1,11 @@ import { Callout } from '@app-builder/components/Callout'; -import { Panel } from '@app-builder/components/Panel'; import { type DataModelField } from '@app-builder/models'; import { type LinkToSingle, type TableModel } from '@app-builder/models/data-model'; import { useDataModel } from '@app-builder/services/data/data-model'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import * as R from 'remeda'; -import { Button, cn } from 'ui-design-system'; +import { Button, cn, Panel } from 'ui-design-system'; import { Icon } from 'ui-icons'; import { inferSemanticTypeFromName } from '../../DataVisualisation/dataFieldsUtils'; import { diff --git a/packages/app-builder/src/components/Data/SemanticTables/Flow/TableRecordPreviewDrawer.tsx b/packages/app-builder/src/components/Data/SemanticTables/Flow/TableRecordPreviewDrawer.tsx index 9415c9d1e2..41cc498bed 100644 --- a/packages/app-builder/src/components/Data/SemanticTables/Flow/TableRecordPreviewDrawer.tsx +++ b/packages/app-builder/src/components/Data/SemanticTables/Flow/TableRecordPreviewDrawer.tsx @@ -1,10 +1,9 @@ import { DataFields } from '@app-builder/components/Data/DataVisualisation/DataFields'; -import { Panel } from '@app-builder/components/Panel'; import { Spinner } from '@app-builder/components/Spinner'; import { useObjectDetailsQuery } from '@app-builder/queries/data/get-object-details'; import { FormEvent, useEffect, useMemo, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { Button, Input, Tag } from 'ui-design-system'; +import { Button, Input, Panel, Tag } from 'ui-design-system'; interface TableRecordPreviewDrawerProps { open: boolean; diff --git a/packages/app-builder/src/components/Data/SemanticTables/UploadData/UploadTableDrawer.tsx b/packages/app-builder/src/components/Data/SemanticTables/UploadData/UploadTableDrawer.tsx index 0aba7c4d32..cc86e3fe6b 100644 --- a/packages/app-builder/src/components/Data/SemanticTables/UploadData/UploadTableDrawer.tsx +++ b/packages/app-builder/src/components/Data/SemanticTables/UploadData/UploadTableDrawer.tsx @@ -1,5 +1,4 @@ import { ExternalLink } from '@app-builder/components/ExternalLink'; -import { Panel } from '@app-builder/components/Panel'; import { LoadingIcon } from '@app-builder/components/Spinner'; import { type TableModel } from '@app-builder/models'; import { useUploadTableQuery } from '@app-builder/queries/data/upload-table'; @@ -8,7 +7,7 @@ import { useQueryClient } from '@tanstack/react-query'; import { type UploadLog } from 'marble-api'; import toast from 'react-hot-toast'; import { Trans, useTranslation } from 'react-i18next'; -import { Button, Tag, Typo } from 'ui-design-system'; +import { Button, Panel, Tag, Typo } from 'ui-design-system'; import { Icon } from 'ui-icons'; import { DownloadCsvTemplate, PastUploads, UploadForm } from './UploadIngestionComponents'; diff --git a/packages/app-builder/src/components/DataModelExplorer/DataExplorerPanel.tsx b/packages/app-builder/src/components/DataModelExplorer/DataExplorerPanel.tsx index 0d84f5b3f6..67ed0a9922 100644 --- a/packages/app-builder/src/components/DataModelExplorer/DataExplorerPanel.tsx +++ b/packages/app-builder/src/components/DataModelExplorer/DataExplorerPanel.tsx @@ -1,7 +1,7 @@ -import { Panel } from '@app-builder/components/Panel'; import { DataModel } from '@app-builder/models'; import { useEffect } from 'react'; import { useTranslation } from 'react-i18next'; +import { Panel } from 'ui-design-system'; import { DataModelExplorer } from '../DataModelExplorer/DataModelExplorer'; import { DataModelExplorerContext } from '../DataModelExplorer/Provider'; diff --git a/packages/app-builder/src/components/Decisions/DecisionRightPanel.tsx b/packages/app-builder/src/components/Decisions/DecisionRightPanel.tsx index 93e83d0b83..ebf74180cc 100644 --- a/packages/app-builder/src/components/Decisions/DecisionRightPanel.tsx +++ b/packages/app-builder/src/components/Decisions/DecisionRightPanel.tsx @@ -1,5 +1,4 @@ import { FormErrorOrDescription } from '@app-builder/components/Form/Tanstack/FormErrorOrDescription'; -import { Panel, PanelSharpFactory } from '@app-builder/components/Panel'; import { CaseDetail } from '@app-builder/models/cases'; import { existingCaseSchema, newCaseSchema, useAddToCaseMutation } from '@app-builder/queries/cases/add-to-case'; import { useGetInboxesQuery } from '@app-builder/queries/cases/get-inboxes'; @@ -9,7 +8,7 @@ import { useForm } from '@tanstack/react-form'; import { useNavigate, useRouter } from '@tanstack/react-router'; import { useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { Input, SelectV2, Switch } from 'ui-design-system'; +import { Input, Panel, PanelSharpFactory, SelectV2, Switch } from 'ui-design-system'; import { decisionsI18n } from './decisions-i18n'; interface DecisionRightPanelProps { diff --git a/packages/app-builder/src/components/Form/Tanstack/FormInput.tsx b/packages/app-builder/src/components/Form/Tanstack/FormInput.tsx index 1d9661b915..ac394cfc4f 100644 --- a/packages/app-builder/src/components/Form/Tanstack/FormInput.tsx +++ b/packages/app-builder/src/components/Form/Tanstack/FormInput.tsx @@ -2,7 +2,6 @@ import * as React from 'react'; import { Input, type InputProps } from 'ui-design-system'; interface FormInputProps extends Omit { - enablePasswordManagers?: boolean; valid?: boolean; type: | 'color' diff --git a/packages/app-builder/src/components/Scenario/Rules/RuleEditPanel.tsx b/packages/app-builder/src/components/Scenario/Rules/RuleEditPanel.tsx index fb12cd481e..c07dd8c79c 100644 --- a/packages/app-builder/src/components/Scenario/Rules/RuleEditPanel.tsx +++ b/packages/app-builder/src/components/Scenario/Rules/RuleEditPanel.tsx @@ -1,6 +1,5 @@ import { Callout } from '@app-builder/components/Callout'; import { FormErrorOrDescription } from '@app-builder/components/Form/Tanstack/FormErrorOrDescription'; -import { Panel, PanelSharpFactory } from '@app-builder/components/Panel'; import { authMiddleware } from '@app-builder/middlewares/auth-middleware'; import { AstNode, NewEmptyRuleAstNode, ScenarioValidation } from '@app-builder/models'; import { Scenario } from '@app-builder/models/scenario'; @@ -22,7 +21,7 @@ import { useEffect, useMemo, useRef, useState } from 'react'; import toast from 'react-hot-toast'; import { useTranslation } from 'react-i18next'; import { match } from 'ts-pattern'; -import { Button, Card, cn, NumberInput } from 'ui-design-system'; +import { Button, Card, cn, NumberInput, Panel, PanelSharpFactory } from 'ui-design-system'; import { Icon } from 'ui-icons'; import { z } from 'zod/v4'; import { FieldAstFormula } from '../Screening/FieldAstFormula'; diff --git a/packages/app-builder/src/components/Scenario/Rules/RulesPage.tsx b/packages/app-builder/src/components/Scenario/Rules/RulesPage.tsx index 3eb8d6e18a..a4330c5368 100644 --- a/packages/app-builder/src/components/Scenario/Rules/RulesPage.tsx +++ b/packages/app-builder/src/components/Scenario/Rules/RulesPage.tsx @@ -2,7 +2,6 @@ import { AstBuilder } from '@app-builder/components/AstBuilder'; import { OutcomeBadge } from '@app-builder/components/Decisions/OutcomeTag'; import { FiltersButton } from '@app-builder/components/Filters'; import { findDatasetByName, useDatasetTitle } from '@app-builder/components/ListAndTopicConfiguration/dataset-utils'; -import { Panel } from '@app-builder/components/Panel'; import { CreateScreeningButton } from '@app-builder/components/Screenings/CreateScreeningButton'; import { useDatasetTag } from '@app-builder/components/Screenings/DatasetTag'; import { AstNode, isUndefinedAstNode, ScenarioValidation } from '@app-builder/models'; @@ -27,7 +26,7 @@ import { Trans, useTranslation } from 'react-i18next'; import * as R from 'remeda'; import type { UUID } from 'short-uuid/src/types'; import { match } from 'ts-pattern'; -import { CtaV2ClassName, cn, ExpandableGroupTagLine, SearchInput, Tag, Tooltip } from 'ui-design-system'; +import { CtaV2ClassName, cn, ExpandableGroupTagLine, Panel, SearchInput, Tag, Tooltip } from 'ui-design-system'; import { Icon } from 'ui-icons'; import { CreateRule } from './Actions/CreateRule'; import { RuleEditPanel } from './RuleEditPanel'; diff --git a/packages/app-builder/src/components/Scenario/Rules/ScreeningRuleEditPanel.tsx b/packages/app-builder/src/components/Scenario/Rules/ScreeningRuleEditPanel.tsx index 76993bbaff..435a47858d 100644 --- a/packages/app-builder/src/components/Scenario/Rules/ScreeningRuleEditPanel.tsx +++ b/packages/app-builder/src/components/Scenario/Rules/ScreeningRuleEditPanel.tsx @@ -2,7 +2,6 @@ import { AstBuilder } from '@app-builder/components/AstBuilder'; import { Callout } from '@app-builder/components/Callout'; import { ExternalLink } from '@app-builder/components/ExternalLink'; import { FormErrorOrDescription } from '@app-builder/components/Form/Tanstack/FormErrorOrDescription'; -import { Panel, PanelSharpFactory } from '@app-builder/components/Panel'; import { ScreeningThreshold } from '@app-builder/components/ScreeningThreshold'; import { SEARCH_ENTITIES } from '@app-builder/constants/screening-entity'; import { authMiddleware } from '@app-builder/middlewares/auth-middleware'; @@ -38,7 +37,7 @@ import toast from 'react-hot-toast'; import { Trans, useTranslation } from 'react-i18next'; import * as R from 'remeda'; import { match } from 'ts-pattern'; -import { Button, Card, cn, Switch } from 'ui-design-system'; +import { Button, Card, cn, Panel, PanelSharpFactory, Switch } from 'ui-design-system'; import { Icon } from 'ui-icons'; import { z } from 'zod/v4'; import { EvaluationErrors } from '../ScenarioValidationError'; diff --git a/packages/app-builder/src/components/Screenings/FreeformSearch/ViewSavedResults.tsx b/packages/app-builder/src/components/Screenings/FreeformSearch/ViewSavedResults.tsx index c3bfaccf98..d4772537eb 100644 --- a/packages/app-builder/src/components/Screenings/FreeformSearch/ViewSavedResults.tsx +++ b/packages/app-builder/src/components/Screenings/FreeformSearch/ViewSavedResults.tsx @@ -1,6 +1,5 @@ import { CursorPaginationButtons, usePaginationsButton } from '@app-builder/components/Decisions/PaginationButtons'; import { DateRangeFilter } from '@app-builder/components/Filters'; -import { Panel } from '@app-builder/components/Panel'; import { IconDot } from '@app-builder/components/Screenings/MatchCard/match-card-entity-components'; import { SEARCH_ENTITIES, SearchableSchema } from '@app-builder/constants/screening-entity'; import { User } from '@app-builder/models'; @@ -18,7 +17,7 @@ import { ScreeningConfigBodySectionDto } from 'marble-api'; import { Fragment, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Temporal } from 'temporal-polyfill'; -import { Avatar, Button, Collapsible, cn, MenuCommand, Separator, Switch, Tag } from 'ui-design-system'; +import { Avatar, Button, Collapsible, cn, MenuCommand, Panel, Separator, Switch, Tag } from 'ui-design-system'; import { Icon } from 'ui-icons'; import FreeformMatchCard from './FreeformMatchCard'; diff --git a/packages/app-builder/src/components/Screenings/ScreeningPanel/ScreeningHitsPanel.tsx b/packages/app-builder/src/components/Screenings/ScreeningPanel/ScreeningHitsPanel.tsx index 7ef12ecf0b..ab0cc1383c 100644 --- a/packages/app-builder/src/components/Screenings/ScreeningPanel/ScreeningHitsPanel.tsx +++ b/packages/app-builder/src/components/Screenings/ScreeningPanel/ScreeningHitsPanel.tsx @@ -1,5 +1,4 @@ import { CalloutV2 } from '@app-builder/components/Callout'; -import { Panel } from '@app-builder/components/Panel'; import { LoaderRevalidatorContext } from '@app-builder/contexts/LoaderRevalidatorContext'; import type { Screening, ScreeningMatch } from '@app-builder/models/screening'; import { type ScreeningMatchPayload, type ScreeningStatus } from '@app-builder/models/screening'; @@ -21,7 +20,7 @@ import toast from 'react-hot-toast'; import { useTranslation } from 'react-i18next'; import { filter } from 'remeda'; import { match } from 'ts-pattern'; -import { Button, Checkbox, Typo } from 'ui-design-system'; +import { Button, Checkbox, Panel, Typo } from 'ui-design-system'; import { Icon } from 'ui-icons'; import { Spinner } from '../../Spinner'; import { MatchCard } from '../MatchCard'; diff --git a/packages/app-builder/src/components/Settings/AuditEvents/AuditEventDetailPanel.tsx b/packages/app-builder/src/components/Settings/AuditEvents/AuditEventDetailPanel.tsx index c474ed7ad4..8f80e32089 100644 --- a/packages/app-builder/src/components/Settings/AuditEvents/AuditEventDetailPanel.tsx +++ b/packages/app-builder/src/components/Settings/AuditEvents/AuditEventDetailPanel.tsx @@ -1,9 +1,9 @@ import { CopyToClipboardButton } from '@app-builder/components/CopyToClipboardButton'; -import { Panel } from '@app-builder/components/Panel'; import { type AuditEvent } from '@app-builder/models/audit-event'; import { formatDateTimeWithoutPresets, useFormatLanguage } from '@app-builder/utils/format'; import { type FunctionComponent } from 'react'; import { useTranslation } from 'react-i18next'; +import { Panel } from 'ui-design-system'; import { JsonDiff } from './JsonDiff'; import { OperationBadge } from './OperationBadge'; diff --git a/packages/app-builder/src/components/Settings/AuditEvents/AuditEventsTable.tsx b/packages/app-builder/src/components/Settings/AuditEvents/AuditEventsTable.tsx index 043c237647..9b8153933b 100644 --- a/packages/app-builder/src/components/Settings/AuditEvents/AuditEventsTable.tsx +++ b/packages/app-builder/src/components/Settings/AuditEvents/AuditEventsTable.tsx @@ -1,5 +1,4 @@ import { CopyToClipboardButton } from '@app-builder/components/CopyToClipboardButton'; -import { Panel } from '@app-builder/components/Panel'; import { ApiKey } from '@app-builder/models/api-keys'; import { type AuditEvent } from '@app-builder/models/audit-event'; import { useOrganizationUsers } from '@app-builder/services/organization/organization-users'; @@ -7,7 +6,7 @@ import { formatDateTimeWithoutPresets, useFormatLanguage } from '@app-builder/ut import { createColumnHelper, getCoreRowModel } from '@tanstack/react-table'; import { type FunctionComponent, useCallback, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { Table, useTable } from 'ui-design-system'; +import { Panel, Table, useTable } from 'ui-design-system'; import { AuditEventDetailPanel } from './AuditEventDetailPanel'; import { OperationBadge } from './OperationBadge'; diff --git a/packages/app-builder/src/components/UserScoring/GeneralInfoCard.tsx b/packages/app-builder/src/components/UserScoring/GeneralInfoCard.tsx index 87e54865bd..bfd927da3a 100644 --- a/packages/app-builder/src/components/UserScoring/GeneralInfoCard.tsx +++ b/packages/app-builder/src/components/UserScoring/GeneralInfoCard.tsx @@ -1,4 +1,3 @@ -import { Panel, PanelSharpFactory } from '@app-builder/components/Panel'; import { useAgnosticNavigation } from '@app-builder/contexts/AgnosticNavigationContext'; import { type ScenarioPublicationStatus } from '@app-builder/models/scenario/publication'; import { @@ -23,7 +22,7 @@ import { useNavigate, useRouter } from '@tanstack/react-router'; import { Fragment, useState } from 'react'; import toast from 'react-hot-toast'; import { useTranslation } from 'react-i18next'; -import { Button, NumberInput, type SelectOption, SelectV2, Tooltip } from 'ui-design-system'; +import { Button, NumberInput, Panel, PanelSharpFactory, type SelectOption, SelectV2, Tooltip } from 'ui-design-system'; import { Icon } from 'ui-icons'; import { ScoringLevelThresholds } from './ScoringLevelThresholds'; diff --git a/packages/app-builder/src/components/UserScoring/RulesTable.tsx b/packages/app-builder/src/components/UserScoring/RulesTable.tsx index d28b0c8efc..43fe5eccc2 100644 --- a/packages/app-builder/src/components/UserScoring/RulesTable.tsx +++ b/packages/app-builder/src/components/UserScoring/RulesTable.tsx @@ -1,4 +1,3 @@ -import { Panel } from '@app-builder/components/Panel'; import { NewAstNode } from '@app-builder/models'; import { NewAggregatorAstNode } from '@app-builder/models/astNode/aggregation'; import { NewSwitchAstNode } from '@app-builder/models/astNode/control-flow'; @@ -18,7 +17,7 @@ import { useState } from 'react'; import toast from 'react-hot-toast'; import { useTranslation } from 'react-i18next'; import { match } from 'ts-pattern'; -import { Button, cn, MenuCommand, Tag } from 'ui-design-system'; +import { Button, cn, MenuCommand, Panel, Tag } from 'ui-design-system'; import { Icon } from 'ui-icons'; import { v7 as uuidv7 } from 'uuid'; import { Spinner } from '../Spinner'; diff --git a/packages/app-builder/src/components/UserScoring/ScoringRuleEditPanel.tsx b/packages/app-builder/src/components/UserScoring/ScoringRuleEditPanel.tsx index 06d1636802..1f2ccc19da 100644 --- a/packages/app-builder/src/components/UserScoring/ScoringRuleEditPanel.tsx +++ b/packages/app-builder/src/components/UserScoring/ScoringRuleEditPanel.tsx @@ -1,5 +1,4 @@ import { AstBuilder } from '@app-builder/components/AstBuilder'; -import { Panel, PanelSharpFactory } from '@app-builder/components/Panel'; import { type DataModel } from '@app-builder/models'; import { type CustomList } from '@app-builder/models/custom-list'; import { @@ -18,7 +17,7 @@ import { import { useEffect, useMemo, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { match } from 'ts-pattern'; -import { cn, type SelectOption, SelectV2, Tag } from 'ui-design-system'; +import { cn, Panel, PanelSharpFactory, type SelectOption, SelectV2, Tag } from 'ui-design-system'; import { Icon } from 'ui-icons'; import { SwitchNode } from './SwitchNode'; diff --git a/packages/app-builder/src/components/UserScoring/ScoringSectionLayout.tsx b/packages/app-builder/src/components/UserScoring/ScoringSectionLayout.tsx index 0458051854..ebbc94a344 100644 --- a/packages/app-builder/src/components/UserScoring/ScoringSectionLayout.tsx +++ b/packages/app-builder/src/components/UserScoring/ScoringSectionLayout.tsx @@ -10,10 +10,20 @@ import { Link, Outlet, useMatches, useNavigate, useParams, useRouter } from '@ta import { useState } from 'react'; import toast from 'react-hot-toast'; import { useTranslation } from 'react-i18next'; -import { Button, NumberInput, type SelectOption, SelectV2, Tabs, Tooltip, Typo, tabClassName } from 'ui-design-system'; +import { + Button, + NumberInput, + Panel, + PanelSharpFactory, + type SelectOption, + SelectV2, + Tabs, + Tooltip, + Typo, + tabClassName, +} from 'ui-design-system'; import { Icon } from 'ui-icons'; import { Page } from '../Page'; -import { Panel, PanelSharpFactory } from '../Panel'; import { Spinner } from '../Spinner'; import { ScoringLevelThresholds } from './ScoringLevelThresholds'; diff --git a/packages/app-builder/src/routes/_app/_builder/detection/decisions/$decisionId.tsx b/packages/app-builder/src/routes/_app/_builder/detection/decisions/$decisionId.tsx index aa8a3f534a..1075d9f8d4 100644 --- a/packages/app-builder/src/routes/_app/_builder/detection/decisions/$decisionId.tsx +++ b/packages/app-builder/src/routes/_app/_builder/detection/decisions/$decisionId.tsx @@ -14,7 +14,6 @@ import { ScorePanel } from '@app-builder/components/Decisions/Score'; import { ScreeningDetail } from '@app-builder/components/Decisions/ScreeningDetail'; import { DecisionDetailTriggerObject } from '@app-builder/components/Decisions/TriggerObjectDetail'; import { pageLayoutGutter } from '@app-builder/components/Page/page-layout'; -import { Panel } from '@app-builder/components/Panel'; import { authMiddleware } from '@app-builder/middlewares/auth-middleware'; import { DataModel, isNotFoundHttpError } from '@app-builder/models'; import { Screening } from '@app-builder/models/screening'; @@ -29,7 +28,7 @@ import { createServerFn } from '@tanstack/react-start'; import { getRequest } from '@tanstack/react-start/server'; import { useTranslation } from 'react-i18next'; import * as R from 'remeda'; -import { Button, cn } from 'ui-design-system'; +import { Button, cn, Panel } from 'ui-design-system'; import { Icon } from 'ui-icons'; import * as z from 'zod/v4'; diff --git a/packages/app-builder/src/routes/_app/_builder/detection/decisions/index.tsx b/packages/app-builder/src/routes/_app/_builder/detection/decisions/index.tsx index f801d20fd6..d775cfee4d 100644 --- a/packages/app-builder/src/routes/_app/_builder/detection/decisions/index.tsx +++ b/packages/app-builder/src/routes/_app/_builder/detection/decisions/index.tsx @@ -17,7 +17,6 @@ import { } from '@app-builder/components/Decisions/PaginationButtons'; import { DetectionNavigationTabs } from '@app-builder/components/Detection'; import { FiltersButton } from '@app-builder/components/Filters'; -import { Panel } from '@app-builder/components/Panel'; import { useTanstackTableListSelection } from '@app-builder/hooks/useTanstackTableListSelection'; import { authMiddleware } from '@app-builder/middlewares/auth-middleware'; import { type PaginationParams } from '@app-builder/models/pagination'; @@ -31,7 +30,7 @@ import { createServerFn } from '@tanstack/react-start'; import { type MouseEvent, useCallback, useState } from 'react'; import toast from 'react-hot-toast'; import { useTranslation } from 'react-i18next'; -import { Button, SearchInput } from 'ui-design-system'; +import { Button, Panel, SearchInput } from 'ui-design-system'; import { Icon } from 'ui-icons'; import { z } from 'zod/v4'; diff --git a/packages/backoffice/.cta.json b/packages/backoffice/.cta.json new file mode 100644 index 0000000000..253bedc7d9 --- /dev/null +++ b/packages/backoffice/.cta.json @@ -0,0 +1,12 @@ +{ + "projectName": "backoffice", + "mode": "file-router", + "typescript": true, + "tailwind": true, + "packageManager": "bun", + "addOnOptions": {}, + "git": true, + "version": 1, + "framework": "react-cra", + "chosenAddOns": ["biome", "nitro", "start", "sentry", "compiler", "t3env", "tRPC", "tanstack-query"] +} diff --git a/packages/backoffice/.env.example b/packages/backoffice/.env.example new file mode 100644 index 0000000000..2fc133a596 --- /dev/null +++ b/packages/backoffice/.env.example @@ -0,0 +1,2 @@ +API_BASE_URL=http://localhost:8080 +SESSION_SECRET= diff --git a/packages/backoffice/.gitignore b/packages/backoffice/.gitignore new file mode 100644 index 0000000000..6221ecbd0e --- /dev/null +++ b/packages/backoffice/.gitignore @@ -0,0 +1,13 @@ +node_modules +.DS_Store +dist +dist-ssr +*.local +count.txt +.env +.nitro +.tanstack +.wrangler +.output +.vinxi +todos.json diff --git a/packages/backoffice/.vscode/settings.json b/packages/backoffice/.vscode/settings.json new file mode 100644 index 0000000000..70dd163cce --- /dev/null +++ b/packages/backoffice/.vscode/settings.json @@ -0,0 +1,35 @@ +{ + "files.watcherExclude": { + "**/routeTree.gen.ts": true + }, + "search.exclude": { + "**/routeTree.gen.ts": true + }, + "files.readonlyInclude": { + "**/routeTree.gen.ts": true + }, + "[javascript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[javascriptreact]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[typescript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[typescriptreact]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[json]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[jsonc]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[css]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "editor.codeActionsOnSave": { + "source.organizeImports.biome": "explicit" + } +} diff --git a/packages/backoffice/PRODUCT.md b/packages/backoffice/PRODUCT.md new file mode 100644 index 0000000000..af7ea9468f --- /dev/null +++ b/packages/backoffice/PRODUCT.md @@ -0,0 +1,124 @@ +# Product + + + +## Platform + +web + +## Users + +Checkmarble internal staff only — the team that onboards new customers and +operates the Marble platform (onboarding / customer success / support / +engineering). The primary situation is provisioning a new customer +**organization** and then managing it over its lifetime. This surface is never +exposed to customers or to self-hosting super-admins; it is an internal +operator console. + +## Product Purpose + +The backoffice is the internal control plane for Marble, Checkmarble's fraud / +AML transaction-monitoring and decisioning platform. It lets Checkmarble +operators create and administer the customer organizations that run on Marble: +standing up a new org, seeding its data model, managing its users and roles, +toggling gated features, and (planned) managing licences and an operational +overview. Success is an operator completing a provisioning or administration +task quickly and correctly, without touching a database or asking an engineer. + +## Positioning + +Not a market-facing product — its value is operational leverage for the +Checkmarble team. The distinctive mechanism is **spec-driven organization +provisioning**: an operator can stand up a fully configured org from a single +JSON import spec that declares org settings (timezone, sanctions threshold / +limit), admin users, the full data model (tables, fields, links), and optional +seeding (ingestion row counts and generated decisions) — or start from a +template, or create an empty org by name. This turns customer onboarding from a +manual, multi-system setup into a reviewable, repeatable artifact. + +## Operating Context + +- Operators work against a running Marble backend via the backoffice API + (`marble-api` backoffice client) with token-based auth; deployments may use an + OIDC provider. +- Core workflows today: + - **Organizations** — list all orgs (name, ID) and drill into one. + - **Create organization** — three flows: upload/drag a JSON import spec, + pick a template, or create an empty org with just a name. The import flow + shows a full review (settings, admins, data model tabs per table with + fields and links, seeding recap) before the operator confirms. + - **Organization users** — list users and add a user (first/last name, + email, role). Available roles depend on the org's `roles` feature access. + - **Organization features** — set overridable feature access to + `restricted` / `test` / `allowed` and save. +- Data these operators reason about: organizations, users, roles, feature + access, data-model tables/fields/links, ingestion seeds, and decisions. + +## Capabilities and Constraints + +- **User roles** (assigned within a customer org): `ADMIN`, `PUBLISHER`, + `BUILDER`, `VIEWER`, `ANALYST`. When the org's `roles` feature is + `restricted`, only `ADMIN` is assignable. +- **Overridable features** (per org, value `restricted` / `test` / `allowed`): + `test_run`, `sanctions`, `case_auto_assign`, `case_ai_assist`, + `continuous_screening`. +- **Import spec** carries org settings (name, default scenario timezone, + sanctions threshold, sanctions limit), admins, a data model (tables → fields + with type/description, and inter-table links), and optional seeds (per-table + ingestion counts, per-trigger decision counts). Max import file size 20 MB, + JSON only. +- Built on the shared Marble frontend monorepo: TanStack Start (SSR), + TanStack Router (file-based routing), TanStack Query / Form, tRPC, Firebase + auth, Zod validation, `marble-api`, `ui-design-system`, `ui-icons`, Sentry. +- **In scope now, not yet built** (treat as committed product surfaces to + design, not scaffolding to ignore): + - **Dashboard** — the operator's landing surface; currently renders nothing + and needs a real operational overview. + - **Licences** — a genuine feature (licence management); currently a + placeholder. + - **Organization settings** — org-level settings surface; route exists, + content undecided. + - **Templates** — the "create from template" path is stubbed (Template 1/2/3); + real templates and their selection UX are undecided. + +## Brand Commitments + +- Identity is Marble / Checkmarble. This surface uses the shared Marble design + system (`ui-design-system` components, `ui-icons`, and the shared Tailwind + token vocabulary — e.g. `surface-card`, `grey-border`, `text-h1`, spacing + `gap-md`) as its base and stays recognizably part of Marble. +- **Latitude:** as an internal operator tool it may diverge from the customer + app where that serves operators — e.g. higher density, faster task paths, and + admin-specific affordances — provided it builds on the shared system rather + than inventing a parallel one. + +## Evidence on Hand + +- Real, working surfaces in code: Organizations list, org detail with Users and + Features tabs, the Create-Organization panel (import / template / empty), and + the import review flow. These are the ground truth for behavior and data + shapes. +- No marketing content, testimonials, customers, benchmarks, pricing, or + licensing terms exist in this package — future work must not fabricate them. + Templates (Template 1/2/3) are placeholders, not real templates. + +## Product Principles + +1. **Operator speed over polish theater.** These are internal power users doing + repetitive, high-stakes provisioning; optimize for scannability, few clicks, + and confident confirmation, not decoration. +2. **Show the whole artifact before committing.** Destructive or provisioning + actions (import, seeding) get a complete, reviewable recap first — the + operator should never guess what a click will create. +3. **Correctness is the product.** Roles, feature gates, and data-model shapes + are enforced by real schemas; the UI must make the valid path obvious and the + invalid path hard. +4. **One family with the customer app.** Reuse the shared design system so the + backoffice reads as Marble, diverging only where operator ergonomics demand + it. + +## Accessibility & Inclusion + +No product-specific accessibility standard was established beyond honoring the +shared design system's accessible primitives (keyboard-navigable menus, +dialogs, and form controls from `ui-design-system`). diff --git a/packages/backoffice/README.md b/packages/backoffice/README.md new file mode 100644 index 0000000000..a81a1297b0 --- /dev/null +++ b/packages/backoffice/README.md @@ -0,0 +1,217 @@ +# Backoffice + +This is the internal operator console for Marble. It is used by Checkmarble staff to provision and administer the customer organizations running on a Marble backend: creating an org, seeding its data model, managing its users and roles, toggling gated features, and managing licences. + +It is never exposed to customers. Access requires a Marble user whose role is `MARBLE_ADMIN`. + +> For the product brief (users, positioning, principles, planned surfaces), see [PRODUCT.md](./PRODUCT.md). + +## What it does + +- **Organizations launchpad** (`src/components/pages/dashboard.tsx`) — searchable list of every organization, plus the entry point to create a new one. +- **Create organization** (`src/components/organisms/CreateOrganizationPanel/`) — three flows: + - _Import_ — drop a JSON import spec (org settings, admins, data model tables/fields/links, optional ingestion and decision seeds). `ImportFlow.tsx` renders a full reviewable recap before the operator confirms. Validated by `src/schemas/org-import.ts`. + - _Archetype_ — apply a backend-provided template and declare the org admins. + - _Empty_ — create an org from just a name. Newly created orgs get every overridable feature set to `restricted`. +- **Organization overview** (`src/components/pages/organization.overview.tsx`) — configuration, people and feature access for one org. Feature access is edited through `FeatureAccessPanel` (`allowed` / `restricted` / `test`, over the features listed in `src/schemas/features.ts`). +- **Organization users** (`src/components/pages/organization.users.tsx`) — list users and add one. Assignable roles come from `USER_ROLES` in `src/schemas/user.ts`; when the org's `roles` feature is `restricted`, only `ADMIN` is offered. +- **Licences** (`src/components/pages/licenses.tsx`) — list licences with their expiry state, and create or edit one over entitlements grouped into Platform / Screening / Cases (`src/server-fns/licenses.ts`). + +## Getting started + +### Requirements + +- A running Marble backend, reachable at `API_BASE_URL`. +- A user on that backend with the `MARBLE_ADMIN` role. + +### Environment + +Create your own `.env` file based on `.env.example`: + +```bash +cp packages/backoffice/.env.example packages/backoffice/.env +``` + +Variables validated in `src/env.ts`: + +| Variable | Scope | Required | Description | +| ---------------- | ------ | -------- | --------------------------------------------------------------- | +| `API_BASE_URL` | server | yes | Base URL of the Marble backend, e.g. `http://localhost:8080` | +| `SESSION_SECRET` | server | yes | Secret used to seal the `auth-session` cookie. Any long string. | +| `VITE_APP_TITLE` | client | no | Document title | + +Read directly, outside the schema: `VITE_SENTRY_DSN` (`src/router.tsx` and `instrument.server.mjs`) and `PORT` (SSR tRPC base URL, defaults to `3000`). + +> There is **no Firebase configuration to set locally.** The app fetches it from the backend's `/config` endpoint at boot (`getAppConfigFn` in `src/server-fns/core.ts`) and initializes the Firebase SDK from that. + +### Run + +```bash +# from the repo root +bun install + +# start the backoffice in dev mode +bun run -F backoffice dev +``` + +## Authentication + +Firebase Google sign-in, exchanged for a Marble token that we keep in an encrypted server-side session cookie. + +1. `/sign-in` calls `useFirebase().signInWithGoogle()` (`src/hooks/useFirebase.ts`). Firebase is initialized from `appConfig.auth.firebase`, not from env vars. +2. The resulting Firebase ID token is posted to `signinFn` (`src/server-fns/auth.ts`), which calls `marblecoreApi.postToken` and stores the returned Marble token in the `auth-session` cookie (`src/utils/session.ts`, sealed with `SESSION_SECRET`). +3. `authMiddleware` (`src/middlewares/auth.ts`) reads that token and exposes `context.authFetch` — a `fetch` that adds the bearer header, and on a `401` clears the session and redirects to `/sign-in`. `needAuth` composes it and redirects immediately when there is no valid token. +4. `routes/_app/_private.tsx` additionally requires `currentUser.role === 'MARBLE_ADMIN'`, logging the user out otherwise. +5. On firebase deployments, `TokenRefresher` in the same file re-mints the Marble token from the Firebase ID token every 20 minutes via `refreshTokenFn`. + +Every server function that talks to the backend goes through `needAuth`, so `context.authFetch` is the only way data leaves the server. + +## Project structure + +``` +src/ + routes/ # File-based routes (TanStack Router). routeTree.gen.ts is generated — don't edit it. + components/ + pages/ # One component per screen, mounted by a route + organisms/ # Multi-step / stateful features (CreateOrganizationPanel, FeatureAccessPanel) + common/ # ErrorComponent, GridContentLoader + core/ # SuspenseQuery + data/ # queryOptions / mutationOptions factories, one file per domain + server-fns/ # createServerFn handlers — the only place that calls the Marble API + middlewares/ # authMiddleware / needAuth, appConfigMiddleware, global middlewares + schemas/ # Zod schemas shared between server fns and forms + contexts/ # AppConfig, StickyRoots + hooks/ # useFirebase, useInterval, useIntersection + integrations/ # TanStack Query client + tRPC wiring + utils/ # session.ts (auth cookie), user-preferences.ts (theme cookie) + env.ts # T3Env schema + router.tsx # Router creation, SSR query integration, client Sentry init + start.ts # Global middleware registration +``` + +> Unlike `app-builder`, this package has no `models/` / `repositories/` / `services/` layers. The equivalent split is `server-fns/` (server-side API calls) + `data/` (React Query options) + `schemas/` (validation). + +## Routing + +| Route file | Role | +| ---------------------------------------------- | --------------------------------------------------------------------------- | +| `index.tsx` | Server-only `GET`: redirects to `/sign-in` or `/dashboard` | +| `__root.tsx` | HTML shell, theme from user preferences, devtools | +| `_app.tsx` | Loads the backend app config and provides `AppConfigContext` | +| `_app/_public.tsx` | Bounces already-authenticated users to `/dashboard` | +| `_app/_public/sign-in.tsx` | Google sign-in screen | +| `_app/_private.tsx` | Requires auth + `MARBLE_ADMIN`; renders the top bar and the token refresher | +| `_app/_private/dashboard.tsx` | `/dashboard` — organizations launchpad | +| `_app/_private/organizations/$orgId.*.tsx` | Org layout with `overview` and `users` tabs | +| `_app/_private/licenses/index.tsx` | `/licenses` — licence management | +| `api.trpc.$.tsx` | tRPC fetch adapter mounted at `/api/trpc` | + +`routeTree.gen.ts` is regenerated by the router plugin on `dev` and `build`. + +## Adding a new screen + +1. **Server function** in `src/server-fns/.ts`. Always go through `needAuth` and pass `context.authFetch` to the `marble-api` client. Validate the input with Zod. + + ```typescript + export const getWidgetFn = createServerFn({ method: 'GET' }) + .middleware([needAuth]) + .validator(z.object({ widgetId: z.uuid() })) + .handler(async ({ context, data }) => { + const { widget } = await backofficeApi.getWidget(data.widgetId, { + baseUrl: env.API_BASE_URL, + fetch: context.authFetch, + }); + + return widget; + }); + ``` + +2. **Query / mutation options** in `src/data/.ts`. Mutations declare which query keys they invalidate (see [Conventions](#conventions)). + + ```typescript + export const getWidgetQueryOptions = (widgetId: string) => + queryOptions({ + queryKey: ['widgets', widgetId], + queryFn: () => getWidgetFn({ data: { widgetId } }), + }); + + export const updateWidget = () => + mutationOptions({ + mutationFn: (payload: { widgetId: string; name: string }) => updateWidgetFn({ data: payload }), + meta: { + invalidates: (data: { widgetId: string }) => [['widgets', data.widgetId]], + }, + }); + ``` + +3. **Route** under `src/routes/_app/_private/`, prefetching in the loader so the data streams with the document. + + ```tsx + export const Route = createFileRoute('/_app/_private/widgets/$widgetId')({ + component: RouteComponent, + loader: ({ params, context }) => { + context.queryClient.prefetchQuery(getWidgetQueryOptions(params.widgetId)); + }, + }); + + function RouteComponent() { + const { widgetId } = Route.useParams(); + return ; + } + ``` + +4. **Page component** in `src/components/pages/`, reading the data through `SuspenseQuery` so loading and error states are colocated with the query. + + ```tsx + const WidgetError = makeQueryErrorComponent(Could not load this widget.); + + export const WidgetPage = ({ widgetId }: { widgetId: string }) => ( + } + errorComponent={WidgetError} + > + {(widget) =>

{widget.name}

} +
+ ); + ``` + +## Conventions + +- **Invalidate through `meta.invalidates`.** Mutations don't call `invalidateQueries` themselves; they declare `meta: { invalidates: (variables) => [[...queryKey]] }` and the shared `MutationCache` in `src/integrations/tanstack-query/root-provider.tsx` invalidates every matching query on success. The `meta` shape is typed in `src/global.d.ts`. +- Query defaults are a 10s `staleTime` and no retries on `3xx` `Response` errors — those are the redirects thrown by server functions on auth failure. +- Validate every server function input with Zod (import from `zod/v4`). Shapes shared with forms live in `src/schemas/`. +- Import from `src/` with the `@bo/*` alias (declared in the root `tsconfig.base.json`), e.g. `import { env } from '@bo/env'`. +- UI comes from `ui-design-system` and `ui-icons`; use `cn` from `ui-design-system` for class merging and the shared Tailwind tokens (`surface-card`, `grey-border`, `text-h1`, `gap-md`, …) from `tailwind-preset`. +- `ts-pattern` for branching on discriminated state, `remeda` for data helpers, `sharpstate` for local state in the multi-step organisms, `@tanstack/react-form` for forms. + +## Scripts + +```bash +# Start the dev server +bun run -F backoffice dev + +# Typecheck +bun run -F backoffice type-check + +# Lint / format / both (biome) +bun run -F backoffice lint +bun run -F backoffice format +bun run -F backoffice check + +# Production build and run +bun run -F backoffice build +bun run -F backoffice start +``` + +To check the code locally like the CI does, from the repo root: + +```bash +bun run -F "*" type-check && bunx biome check +``` + +## Deployment + +Vite builds the app through Nitro (`node-server` preset, see `vite.config.ts`) into `.output/server/index.mjs`. The `build` script also copies `instrument.server.mjs` next to it, which initializes server-side Sentry. + +The image is built from `Dockerfile.backoffice` at the repo root (Bun build stage, distroless Node.js 22 runtime, listening on `PORT` — 8080 by default) and deployed to Cloud Run by `.github/workflows/build_and_deploy.yaml`. diff --git a/packages/backoffice/instrument.server.mjs b/packages/backoffice/instrument.server.mjs new file mode 100644 index 0000000000..770a660b9d --- /dev/null +++ b/packages/backoffice/instrument.server.mjs @@ -0,0 +1,10 @@ +import * as Sentry from '@sentry/tanstackstart-react' +Sentry.init({ + dsn: import.meta.env.VITE_SENTRY_DSN, + // Adds request headers and IP for users, for more info visit: + // https://docs.sentry.io/platforms/javascript/guides/tanstackstart-react/configuration/options/#sendDefaultPii + sendDefaultPii: true, + tracesSampleRate: 1.0, + replaysSessionSampleRate: 1.0, + replaysOnErrorSampleRate: 1.0, +}) diff --git a/packages/backoffice/package.json b/packages/backoffice/package.json new file mode 100644 index 0000000000..6b6d024eed --- /dev/null +++ b/packages/backoffice/package.json @@ -0,0 +1,66 @@ +{ + "name": "backoffice", + "private": true, + "type": "module", + "scripts": { + "dev": "vite dev", + "build": "vite build && cp instrument.server.mjs .output/server/instrument.server.mjs", + "preview": "vite preview", + "test": "vitest run", + "format": "biome format", + "lint": "biome lint", + "check": "biome check", + "start": "bun .output/server/index.mjs", + "type-check": "tsc --noEmit" + }, + "dependencies": { + "@marble/shared": "workspace:*", + "@sentry/tanstackstart-react": "^10.52.0", + "@t3-oss/env-core": "^0.13.8", + "@tailwindcss/vite": "^4.2.4", + "@tanstack/react-devtools": "^0.10.5", + "@tanstack/react-form": "^1.29.3", + "@tanstack/react-query": "^5.99.2", + "@tanstack/react-query-devtools": "^5.84.2", + "@tanstack/react-router": "1.170.16", + "@tanstack/react-router-devtools": "1.167.0", + "@tanstack/react-router-ssr-query": "1.167.1", + "@tanstack/react-start": "1.168.26", + "@tanstack/router-plugin": "1.168.18", + "@trpc/client": "^11.4.3", + "@trpc/server": "^11.4.3", + "@trpc/tanstack-react-query": "^11.4.3", + "firebase": "^12.13.0", + "lucide-react": "^0.544.0", + "marble-api": "workspace:*", + "nitro": "^3.0.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-dropzone-esm": "^15.2.0", + "react-error-boundary": "^6.0.0", + "react-hot-toast": "^2.5.2", + "remeda": "^2.38.0", + "sharpstate": "^0.0.13", + "superjson": "^2.2.6", + "tailwindcss": "4.3.2", + "ts-pattern": "^5.9.0", + "ui-design-system": "workspace:*", + "ui-icons": "workspace:*", + "vite-tsconfig-paths": "^6.1.1", + "zod": "^4.1.11" + }, + "devDependencies": { + "@tanstack/devtools-vite": "^0.6.0", + "@testing-library/dom": "^10.4.0", + "@testing-library/react": "16.3.2", + "@types/node": "25.6.2", + "@types/react": "18.3.24", + "@types/react-dom": "^18.3.5", + "@vitejs/plugin-react": "^5.0.4", + "babel-plugin-react-compiler": "^1.0.0", + "jsdom": "29.1.1", + "vite": "^7.3.6", + "vitest": "4.1.8", + "web-vitals": "^5.1.0" + } +} diff --git a/packages/backoffice/public/favicon.ico b/packages/backoffice/public/favicon.ico new file mode 100644 index 0000000000..5ab2008e2c Binary files /dev/null and b/packages/backoffice/public/favicon.ico differ diff --git a/packages/backoffice/public/favicons/android-chrome-192x192.png b/packages/backoffice/public/favicons/android-chrome-192x192.png new file mode 100644 index 0000000000..cb96ba5421 Binary files /dev/null and b/packages/backoffice/public/favicons/android-chrome-192x192.png differ diff --git a/packages/backoffice/public/favicons/android-chrome-512x512.png b/packages/backoffice/public/favicons/android-chrome-512x512.png new file mode 100644 index 0000000000..78cd76d740 Binary files /dev/null and b/packages/backoffice/public/favicons/android-chrome-512x512.png differ diff --git a/packages/backoffice/public/favicons/apple-touch-icon.png b/packages/backoffice/public/favicons/apple-touch-icon.png new file mode 100644 index 0000000000..d6547c7c75 Binary files /dev/null and b/packages/backoffice/public/favicons/apple-touch-icon.png differ diff --git a/packages/backoffice/public/favicons/favicon-16x16.png b/packages/backoffice/public/favicons/favicon-16x16.png new file mode 100644 index 0000000000..01dc9d6f9b Binary files /dev/null and b/packages/backoffice/public/favicons/favicon-16x16.png differ diff --git a/packages/backoffice/public/favicons/favicon-32x32.png b/packages/backoffice/public/favicons/favicon-32x32.png new file mode 100644 index 0000000000..9a7c9af5f1 Binary files /dev/null and b/packages/backoffice/public/favicons/favicon-32x32.png differ diff --git a/packages/backoffice/public/robots.txt b/packages/backoffice/public/robots.txt new file mode 100644 index 0000000000..e9e57dc4d4 --- /dev/null +++ b/packages/backoffice/public/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/packages/backoffice/public/site.webmanifest b/packages/backoffice/public/site.webmanifest new file mode 100644 index 0000000000..38360c39f6 --- /dev/null +++ b/packages/backoffice/public/site.webmanifest @@ -0,0 +1,19 @@ +{ + "name": "Marble Backoffice", + "short_name": "Marble BO", + "icons": [ + { + "src": "/favicons/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/favicons/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/packages/backoffice/src/components/StickyElement.tsx b/packages/backoffice/src/components/StickyElement.tsx new file mode 100644 index 0000000000..ebd55fb372 --- /dev/null +++ b/packages/backoffice/src/components/StickyElement.tsx @@ -0,0 +1,19 @@ +import useIntersection from '@bo/hooks/useIntersection'; +import { useRef } from 'react'; +import { cn } from 'ui-design-system'; + +type StickyContainerProps = { + children: React.ReactNode; + rootRef?: React.RefObject; +}; + +export const StickyContainer = ({ children, rootRef }: StickyContainerProps) => { + const sentinelRef = useRef(null); + const intersection = useIntersection(sentinelRef, {}); + + return ( +
+ {children} +
+ ); +}; diff --git a/packages/backoffice/src/components/common/ErrorComponent.tsx b/packages/backoffice/src/components/common/ErrorComponent.tsx new file mode 100644 index 0000000000..fcee35198b --- /dev/null +++ b/packages/backoffice/src/components/common/ErrorComponent.tsx @@ -0,0 +1,41 @@ +import { ReactNode } from 'react'; +import { Button } from 'ui-design-system'; +import { Icon } from 'ui-icons'; + +type ErrorComponentProps = { + message: string; +}; + +export const ErrorComponent = ({ message }: ErrorComponentProps) => { + return ( +
+ +

{message}

+
+ ); +}; + +export function QueryErrorComponent({ + error: _error, + reset, + children, +}: { + error: any; + reset: () => void; + children: ReactNode; +}) { + return ( +
+ {children} + +
+ ); +} + +export function makeQueryErrorComponent(message: ReactNode) { + return (props: { error: any; reset: () => void }) => { + return ; + }; +} diff --git a/packages/backoffice/src/components/common/GridContentLoader.tsx b/packages/backoffice/src/components/common/GridContentLoader.tsx new file mode 100644 index 0000000000..ff6dadde3e --- /dev/null +++ b/packages/backoffice/src/components/common/GridContentLoader.tsx @@ -0,0 +1,10 @@ +export function GridContentLoader() { + return ( +
+
+
+ ); +} diff --git a/packages/backoffice/src/components/common/Toaster.tsx b/packages/backoffice/src/components/common/Toaster.tsx new file mode 100644 index 0000000000..ed7bc4edf2 --- /dev/null +++ b/packages/backoffice/src/components/common/Toaster.tsx @@ -0,0 +1,56 @@ +import { Toaster as HotToaster, ToastBar, toast } from 'react-hot-toast'; +import { Icon } from 'ui-icons'; + +const LoaderIcon = ( +
+); + +const SuccessIcon = ; + +const ErrorIcon = ; + +// react-hot-toast writes its own inline background, so the token has to be applied inline +// too. `.dark` lives on , so the custom properties still resolve per theme. +const toastStyle = { + background: 'var(--color-surface-card)', + color: 'var(--color-grey-primary)', +}; + +export function Toaster() { + return ( + + {(currentToast) => ( + + {({ icon, message }) => ( + <> + {icon} + {message} + {currentToast.type !== 'loading' ? ( + + ) : null} + + )} + + )} + + ); +} diff --git a/packages/backoffice/src/components/core/SuspenseQuery.tsx b/packages/backoffice/src/components/core/SuspenseQuery.tsx new file mode 100644 index 0000000000..6448dcafae --- /dev/null +++ b/packages/backoffice/src/components/core/SuspenseQuery.tsx @@ -0,0 +1,57 @@ +import { + QueryErrorResetBoundary, + UseSuspenseQueryOptions, + UseSuspenseQueryResult, + useSuspenseQuery, +} from '@tanstack/react-query'; +import { Suspense } from 'react'; +import { ErrorBoundary } from 'react-error-boundary'; + +type AnySuspenseQueryOptions = UseSuspenseQueryOptions; + +type ChildProp = + T extends UseSuspenseQueryOptions + ? (data: UseSuspenseQueryResult['data']) => React.ReactNode + : never; + +type SuspenseQueryProps = SuspenseQueryComponentProps & { + errorComponent: ({ error, reset }: { error: any; reset: () => void }) => React.ReactNode; + fallback?: React.ReactNode; +}; + +type SuspenseQueryComponentProps = { + query: T; + children: ChildProp; +}; + +export function SuspenseQuery({ + query, + children, + errorComponent: ErrorComponent, + fallback, +}: SuspenseQueryProps) { + return ( + + {({ reset }) => ( + ( + + )} + > + + + + + )} + + ); +} + +function SuspensedQueryComponent({ + query, + children, +}: SuspenseQueryComponentProps) { + const { data } = useSuspenseQuery(query); + return children(data); +} diff --git a/packages/backoffice/src/components/organisms/CreateOrganizationPanel/ChoiceStep.tsx b/packages/backoffice/src/components/organisms/CreateOrganizationPanel/ChoiceStep.tsx new file mode 100644 index 0000000000..50008f2989 --- /dev/null +++ b/packages/backoffice/src/components/organisms/CreateOrganizationPanel/ChoiceStep.tsx @@ -0,0 +1,483 @@ +import { makeQueryErrorComponent } from '@bo/components/common/ErrorComponent'; +import { SuspenseQuery } from '@bo/components/core/SuspenseQuery'; +import { applyOrganizationArchetype, createEmptyOrganization, listOrganizationArchetypes } from '@bo/data/organization'; +import { orgImportSpecSchema } from '@bo/schemas/org-import'; +import { createEmptyOrganizationFnInputSchema } from '@bo/server-fns/organization'; +import { useForm } from '@tanstack/react-form'; +import { useMutation } from '@tanstack/react-query'; +import { useRouter } from '@tanstack/react-router'; +import type { ArchetypeDto } from 'marble-api/generated/marblecore-api'; +import { type ReactNode, useState } from 'react'; +import { useDropzone } from 'react-dropzone-esm'; +import { Button, cn, Input } from 'ui-design-system'; +import { Icon, type IconName } from 'ui-icons'; +import { z } from 'zod/v4'; +import { OrganizationCreationFlow } from './types'; + +export const MAX_FILE_SIZE_MB = 20; +export const MAX_FILE_SIZE = MAX_FILE_SIZE_MB * 1024 * 1024; + +type MethodKey = 'upload' | 'archetype' | 'empty'; + +const METHODS: { key: MethodKey; icon: IconName; title: string; description: string }[] = [ + { + key: 'upload', + icon: 'upload', + title: 'From a data upload', + description: 'Provision a fully configured org from a JSON import spec.', + }, + { + key: 'archetype', + icon: 'category', + title: 'From an archetype', + description: 'Start from a predefined organization template.', + }, + { + key: 'empty', + icon: 'plus', + title: 'Empty organization', + description: 'Create a blank org with just a name, then configure it later.', + }, +]; + +export const ChoiceStep = ({ onChooseFlow }: { onChooseFlow: (flow: OrganizationCreationFlow) => void }) => { + const [selected, setSelected] = useState('upload'); + + return ( +
+ {METHODS.map((method) => ( + setSelected(method.key)} + > + {method.key === 'upload' ? : null} + {method.key === 'archetype' ? : null} + {method.key === 'empty' ? : null} + + ))} +
+ ); +}; + +function MethodRow({ + method, + active, + onSelect, + children, +}: { + method: (typeof METHODS)[number]; + active: boolean; + onSelect: () => void; + children: ReactNode; +}) { + return ( +
+ + {active ?
{children}
: null} +
+ ); +} + +/* --------------------------------- Upload ---------------------------------- */ + +function UploadMethod({ onChooseFlow }: { onChooseFlow: (flow: OrganizationCreationFlow) => void }) { + const [error, setError] = useState(null); + + const { getRootProps, getInputProps, isDragActive } = useDropzone({ + onDrop: async (acceptedFiles, fileRejections) => { + setError(null); + if (fileRejections.length > 0) { + setError(`Upload a single JSON file under ${MAX_FILE_SIZE_MB} MB.`); + return; + } + const file = acceptedFiles[0]; + if (!file) return; + + try { + const data = JSON.parse(await file.text()); + const parsed = orgImportSpecSchema.safeParse(data); + if (parsed.success) { + onChooseFlow({ type: 'import', data: parsed.data }); + } else { + // Surface the offending paths — a generic message here makes a spec produced by a + // newer backend indistinguishable from a corrupt file. + console.error('Invalid organization import spec', parsed.error.issues); + setError(`This file isn’t a valid organization import spec.\n${z.prettifyError(parsed.error)}`); + } + } catch { + setError('This file isn’t valid JSON.'); + } + }, + accept: { 'application/json': ['.json'] }, + multiple: false, + maxSize: MAX_FILE_SIZE, + }); + + return ( +
+
+ + + + + + {isDragActive ? 'Drop the file to import' : 'Drag a JSON import spec here'} + + + or click to browse · JSON only · up to {MAX_FILE_SIZE_MB} MB + +
+ {error ? ( +

+ + {error} +

+ ) : null} +
+ ); +} + +/* -------------------------------- Archetype -------------------------------- */ + +const ArchetypesError = makeQueryErrorComponent( + Could not load archetypes., +); + +function ArchetypeMethod() { + return ( + } + errorComponent={ArchetypesError} + > + {(archetypes) => } + + ); +} + +const archetypeFormSchema = z.object({ + org_name: z.string().min(1, 'An organisation name is required.'), + admins: z + .array( + z.object({ + email: z.email('Enter a valid email address.'), + first_name: z.string().optional(), + last_name: z.string().optional(), + }), + ) + .min(1), +}); + +type ArchetypeFormValues = z.infer; + +function firstError(errors: unknown[]): string | null { + for (const error of errors) { + if (typeof error === 'string') return error; + if (error && typeof error === 'object' && 'message' in error) { + return String((error as { message: unknown }).message); + } + } + return null; +} + +function ErrorText({ children }: { children: ReactNode }) { + if (!children) return null; + return {children}; +} + +function ArchetypeStep({ archetypes }: { archetypes: ArchetypeDto[] }) { + const router = useRouter(); + const applyMutation = useMutation(applyOrganizationArchetype()); + const [selected, setSelected] = useState(archetypes[0]?.name ?? null); + + const form = useForm({ + defaultValues: { + org_name: '', + admins: [{ email: '', first_name: '', last_name: '' }], + } as ArchetypeFormValues, + validators: { + onMount: archetypeFormSchema, + onChange: archetypeFormSchema, + onSubmit: archetypeFormSchema, + }, + onSubmit: async ({ value, formApi }) => { + if (!selected || !formApi.state.isValid) return; + const { orgId } = await applyMutation.mutateAsync({ + name: selected, + org_name: value.org_name, + admins: value.admins, + }); + router.navigate({ to: '/organizations/$orgId', params: { orgId } }); + }, + }); + + if (archetypes.length === 0) { + return

No archetypes are available yet.

; + } + + return ( +
+
+ {archetypes.map((archetype) => { + const active = selected === archetype.name; + return ( + + ); + })} +
+ + { + e.preventDefault(); + e.stopPropagation(); + form.handleSubmit(); + }} + > + + {(field) => ( + + )} + + + + {(adminsField) => ( +
+
+ Admins + +
+ + {adminsField.state.value.map((_, index) => ( +
+
+ + {(field) => ( +
+ field.handleChange(e.target.value)} + onBlur={field.handleBlur} + placeholder="admin@company.com" + /> + {field.state.meta.isTouched ? ( + {firstError(field.state.meta.errors)} + ) : null} +
+ )} +
+ {adminsField.state.value.length > 1 ? ( + + ) : null} +
+
+ + {(field) => ( + field.handleChange(e.target.value)} + placeholder="First name (optional)" + /> + )} + + + {(field) => ( + field.handleChange(e.target.value)} + placeholder="Last name (optional)" + /> + )} + +
+
+ ))} +
+ )} +
+ + {applyMutation.isError ? ( +

+ + Could not create the organization. Check the details and try again. +

+ ) : null} + + [state.canSubmit] as const}> + {([canSubmit]) => ( + + )} + + +
+ ); +} + +function ArchetypesSkeleton() { + return ( +
+ {Array.from({ length: 3 }).map((_, index) => ( +
+
+
+
+ ))} +
+ ); +} + +/* ---------------------------------- Empty ---------------------------------- */ + +function EmptyMethod() { + const createEmptyOrganizationMutation = useMutation(createEmptyOrganization()); + const router = useRouter(); + + const form = useForm({ + defaultValues: { + name: '', + }, + validators: { + onSubmit: createEmptyOrganizationFnInputSchema, + onChange: createEmptyOrganizationFnInputSchema, + onMount: createEmptyOrganizationFnInputSchema, + }, + onSubmit: async ({ value }) => { + const organization = await createEmptyOrganizationMutation.mutateAsync(value); + router.navigate({ + to: '/organizations/$orgId', + params: { orgId: organization.id }, + }); + }, + }); + + return ( +
{ + e.preventDefault(); + e.stopPropagation(); + form.handleSubmit(); + }} + > + + {(field) => ( + + )} + + [state.canSubmit]}> + {([canSubmit]) => ( + + )} + +
+ ); +} diff --git a/packages/backoffice/src/components/organisms/CreateOrganizationPanel/ImportFlow.tsx b/packages/backoffice/src/components/organisms/CreateOrganizationPanel/ImportFlow.tsx new file mode 100644 index 0000000000..a4b1f6a033 --- /dev/null +++ b/packages/backoffice/src/components/organisms/CreateOrganizationPanel/ImportFlow.tsx @@ -0,0 +1,446 @@ +import { importOrganization } from '@bo/data/organization'; +import { OrgImportSpec } from '@bo/schemas/org-import'; +import { useForm } from '@tanstack/react-form'; +import { useMutation } from '@tanstack/react-query'; +import { type ReactNode, useState } from 'react'; +import { Button, Checkbox, Input, Panel, PanelSharpFactory, Tabs, Typo, tabClassName } from 'ui-design-system'; +import { Icon } from 'ui-icons'; +import { z } from 'zod/v4'; + +const FORM_ID = 'org-import-form'; + +// Both sanctions fields are `*int` on the backend, so reject floats here rather than +// letting the spec schema fail later with no field to point at. +const numericString = z + .string() + .optional() + .refine((value) => !value || Number.isInteger(Number(value)), 'Enter a whole number.'); + +const importEditSchema = z.object({ + org: z.object({ + name: z.string().min(1, 'A name is required.'), + default_scenario_timezone: z.string().optional(), + sanctions_threshold: numericString, + sanctions_limit: numericString, + }), + admins: z + .array( + z.object({ + // Only the email is required — the backend stores both names as-is and never + // validates them (createAdmins in org_import_usecase.go). + email: z.email('Enter a valid email address.'), + first_name: z.string(), + last_name: z.string(), + }), + ) + // The export never carries admins, and the backend indexes `admins[0]` without a guard + // (org_import_usecase.go), so submitting an empty list crashes the import. + .min(1, 'Add at least one admin.'), +}); + +type ImportEditValues = z.infer; + +export const ImportFlow = ({ data }: { data: OrgImportSpec }) => { + const panelSharp = PanelSharpFactory.useSharp(); + const importOrgMutation = useMutation(importOrganization()); + + const form = useForm({ + defaultValues: { + org: { + name: data.org.name, + default_scenario_timezone: data.org.default_scenario_timezone ?? '', + sanctions_threshold: data.org.sanctions_threshold?.toString() ?? '', + sanctions_limit: data.org.sanctions_limit?.toString() ?? '', + }, + admins: (data.admins ?? []).map((admin) => ({ + email: admin.email, + first_name: admin.first_name ?? '', + last_name: admin.last_name ?? '', + })), + } as ImportEditValues, + validators: { + onMount: importEditSchema, + onChange: importEditSchema, + onSubmit: importEditSchema, + }, + onSubmit: async ({ value, formApi }) => { + if (!formApi.state.isValid) return; + const editedSpec: OrgImportSpec = { + ...data, + org: { + // Spread first: the form only covers four fields, and rebuilding `org` from + // scratch would drop everything else the spec carries (screening_providers, + // environment, and any key a newer backend added). + ...data.org, + name: value.org.name, + default_scenario_timezone: value.org.default_scenario_timezone || undefined, + sanctions_threshold: value.org.sanctions_threshold ? Number(value.org.sanctions_threshold) : undefined, + sanctions_limit: value.org.sanctions_limit ? Number(value.org.sanctions_limit) : undefined, + }, + admins: value.admins, + }; + await importOrgMutation.mutateAsync(editedSpec); + + panelSharp.actions.close(); + }, + }); + + return ( + <> +
{ + event.preventDefault(); + event.stopPropagation(); + form.handleSubmit(); + }} + > + {/* -------- Organization settings (editable) -------- */} +
+
+ + {(field) => ( + + field.handleChange(event.target.value)} + onBlur={field.handleBlur} + placeholder="Acme Inc." + /> + {field.state.meta.isTouched ? {firstError(field.state.meta.errors)} : null} + + )} + + + + {(field) => ( + + field.handleChange(event.target.value)} + onBlur={field.handleBlur} + placeholder="Europe/Paris" + /> + + )} + + +
+ + {(field) => ( + + field.handleChange(event.target.value)} + onBlur={field.handleBlur} + placeholder="Optional" + /> + {field.state.meta.isTouched ? {firstError(field.state.meta.errors)} : null} + + )} + + + + {(field) => ( + + field.handleChange(event.target.value)} + onBlur={field.handleBlur} + placeholder="Optional" + /> + {field.state.meta.isTouched ? {firstError(field.state.meta.errors)} : null} + + )} + +
+
+
+ + {/* -------- Admins (editable) -------- */} + + {(adminsField) => ( +
adminsField.pushValue({ email: '', first_name: '', last_name: '' })} + > + + Add admin + + } + > + {adminsField.state.value.length === 0 ? ( +

+ No admins yet — add at least one to administer this organization. +

+ ) : ( +
+ {adminsField.state.value.map((_, index) => ( +
+
+ + {(field) => ( +
+ field.handleChange(event.target.value)} + onBlur={field.handleBlur} + placeholder="admin@company.com" + /> + {field.state.meta.isTouched ? ( + {firstError(field.state.meta.errors)} + ) : null} +
+ )} +
+ +
+
+ + {(field) => ( +
+ field.handleChange(event.target.value)} + onBlur={field.handleBlur} + placeholder="First name (optional)" + /> + {field.state.meta.isTouched ? ( + {firstError(field.state.meta.errors)} + ) : null} +
+ )} +
+ + {(field) => ( +
+ field.handleChange(event.target.value)} + onBlur={field.handleBlur} + placeholder="Last name (optional)" + /> + {field.state.meta.isTouched ? ( + {firstError(field.state.meta.errors)} + ) : null} +
+ )} +
+
+
+ ))} +
+ )} +
+ )} +
+ + {/* -------- Read-only recap (imported as-is) -------- */} + + + + {importOrgMutation.isError ? ( +

+ + Import failed. Check the settings above and try again. +

+ ) : null} + + + + + [state.canSubmit] as const}> + {([canSubmit]) => ( + + )} + + + + ); +}; + +/* -------------------------------- Helpers ---------------------------------- */ + +function Section({ + title, + hint, + action, + children, +}: { + title: string; + hint?: string; + action?: ReactNode; + children: ReactNode; +}) { + return ( +
+
+
+ {title} + {hint ? {hint} : null} +
+ {action} +
+ {children} +
+ ); +} + +function Field({ label, children }: { label: string; children: ReactNode }) { + return ( + + ); +} + +function ErrorText({ children }: { children: ReactNode }) { + if (!children) return null; + return {children}; +} + +function firstError(errors: unknown[]): string | null { + for (const error of errors) { + if (typeof error === 'string') return error; + if (error && typeof error === 'object' && 'message' in error) { + return String((error as { message: unknown }).message); + } + } + return null; +} + +/* --------------------------- Read-only recap ------------------------------- */ + +/** + * `seeds` is a struct on the backend, so an export always carries it — with both maps + * `null`. Presence therefore says nothing; only content does. + */ +function seedLines(seeds: OrgImportSpec['seeds']) { + if (!seeds) return []; + return [ + ...Object.entries(seeds.ingestion ?? {}).map(([table, { count }]) => `${count} ${table}`), + ...Object.entries(seeds.decisions ?? {}).map(([triggerType, count]) => `${count} ${triggerType} decisions`), + ]; +} + +const SeedingSection = ({ lines }: { lines: string[] }) => { + if (lines.length === 0) return null; + + return ( +
+
+ Seeding + +
+
+ Activating the seeding will create: +
+ {lines.map((line) => ( +
{line}
+ ))} +
+
+
+ ); +}; + +const DataModelRecap = ({ data }: { data: OrgImportSpec }) => { + const tables = data.data_model.tables ?? []; + const [activeTab, setActiveTab] = useState(tables[0]?.name); + const currentTable = tables.find((table) => table.name === activeTab); + + return ( +
+ + Data model + ({tables.length} tables) + + + {tables.map((table) => ( + + ))} + + {currentTable ? ( +
+
+
Name
+
Description
+
Type
+
+ {Object.entries(currentTable.fields ?? {}).map(([key, field]) => ( +
+
{key}
+
{field.description}
+
{field.data_type}
+
+ ))} + +
+ ) : null} +
+ ); +}; + +type TableLinksProps = { + data: OrgImportSpec; + currentTable: NonNullable[number]; +}; + +const TableLinks = ({ data, currentTable }: TableLinksProps) => { + const linksForTable = (data.data_model.links ?? []).filter( + (link) => link.parent_table_name === currentTable.name || link.child_table_name === currentTable.name, + ); + + return ( + <> +
+
Links
+
+ {linksForTable.map((link) => ( +
+
+ {link.parent_table_name} → {link.child_table_name} +
+
+ ))} + + ); +}; diff --git a/packages/backoffice/src/components/organisms/CreateOrganizationPanel/index.tsx b/packages/backoffice/src/components/organisms/CreateOrganizationPanel/index.tsx new file mode 100644 index 0000000000..3824a163a4 --- /dev/null +++ b/packages/backoffice/src/components/organisms/CreateOrganizationPanel/index.tsx @@ -0,0 +1,42 @@ +import { useState } from 'react'; +import { match } from 'ts-pattern'; +import { Panel } from 'ui-design-system'; +import { ChoiceStep } from './ChoiceStep'; +import { ImportFlow } from './ImportFlow'; +import { OrganizationCreationFlow } from './types'; + +export const CreateOrganizationPanel = ({ + open, + onOpenChange, +}: { + open: boolean; + onOpenChange: (open: boolean) => void; +}) => { + const [flow, setFlow] = useState(null); + const handleChooseFlow = (choice: OrganizationCreationFlow) => { + setFlow(choice); + }; + + const handleOnOpenChange = (open: boolean) => { + if (!open) { + setFlow(null); + } + onOpenChange(open); + }; + + return ( + + + + Create a new organization +
+ {match(flow) + .with(null, () => ) + .with({ type: 'import' }, ({ data }) => ) + .exhaustive()} +
+
+
+
+ ); +}; diff --git a/packages/backoffice/src/components/organisms/CreateOrganizationPanel/types.ts b/packages/backoffice/src/components/organisms/CreateOrganizationPanel/types.ts new file mode 100644 index 0000000000..2a4daebfd6 --- /dev/null +++ b/packages/backoffice/src/components/organisms/CreateOrganizationPanel/types.ts @@ -0,0 +1,3 @@ +import { OrgImportSpec } from '@bo/schemas/org-import'; + +export type OrganizationCreationFlow = { type: 'import'; data: OrgImportSpec }; diff --git a/packages/backoffice/src/components/organisms/FeatureAccessPanel/index.tsx b/packages/backoffice/src/components/organisms/FeatureAccessPanel/index.tsx new file mode 100644 index 0000000000..ee7479870e --- /dev/null +++ b/packages/backoffice/src/components/organisms/FeatureAccessPanel/index.tsx @@ -0,0 +1,194 @@ +import { makeQueryErrorComponent } from '@bo/components/common/ErrorComponent'; +import { SuspenseQuery } from '@bo/components/core/SuspenseQuery'; +import { listOrganizationFeatures, patchOrganizationFeatures } from '@bo/data/organization'; +import { + type FeatureValue, + OVERRIDABLE_FEATURES, + type PatchOrganizationFeaturesPayload, + patchOrganizationFeaturesPayloadSchema, +} from '@bo/schemas/features'; +import { useForm } from '@tanstack/react-form'; +import { useMutation } from '@tanstack/react-query'; +import { FeatureAccessDto } from 'marble-api/generated/backoffice-api'; +import { cn, Panel } from 'ui-design-system'; + +const FormError = makeQueryErrorComponent( + Could not load feature access., +); + +type FeatureAccessPanelProps = { + orgId: string; + open: boolean; + onOpenChange: (open: boolean) => void; +}; + +export function FeatureAccessPanel({ orgId, open, onOpenChange }: FeatureAccessPanelProps) { + return ( + + + + +
+ Feature access +

+ Set which capabilities this organization can use. +

+
+
+ } + errorComponent={FormError} + > + {(featureAccess) => ( + onOpenChange(false)} /> + )} + +
+
+
+ ); +} + +const FEATURE_LABELS: Record<(typeof OVERRIDABLE_FEATURES)[number], string> = { + test_run: 'Test run', + sanctions: 'Sanctions', + case_auto_assign: 'Case auto-assign', + case_ai_assist: 'Case AI assist', + continuous_screening: 'Continuous screening', + ai_rule_building: 'AI Rule building', + lexisnexis: 'Lexis Nexis', +}; + +const ACCESS_LEVELS: { value: FeatureValue; label: string; dot: string }[] = [ + { value: 'restricted', label: 'Restricted', dot: 'bg-grey-disabled' }, + { value: 'test', label: 'Test', dot: 'bg-yellow-primary' }, + { value: 'allowed', label: 'Allowed', dot: 'bg-green-primary' }, +]; + +const FORM_ID = 'feature-access-form'; + +function FeaturesForm({ + orgId, + featureAccess, + onSaved, +}: { + orgId: string; + featureAccess: FeatureAccessDto; + onSaved: () => void; +}) { + const patchMutation = useMutation(patchOrganizationFeatures()); + + const form = useForm({ + defaultValues: Object.fromEntries( + OVERRIDABLE_FEATURES.map((feature) => [feature, featureAccess[feature]]), + ) as PatchOrganizationFeaturesPayload, + validators: { + onMount: patchOrganizationFeaturesPayloadSchema, + onChange: patchOrganizationFeaturesPayloadSchema, + onSubmit: patchOrganizationFeaturesPayloadSchema, + }, + onSubmit: async ({ value, formApi }) => { + if (!formApi.state.isValid) return; + await patchMutation.mutateAsync({ orgId, features: value }); + onSaved(); + }, + }); + + return ( + <> +
{ + event.preventDefault(); + event.stopPropagation(); + form.handleSubmit(); + }} + > + {OVERRIDABLE_FEATURES.map((feature) => ( + + {(field) => ( +
+ {FEATURE_LABELS[feature]} + field.handleChange(value)} + /> +
+ )} +
+ ))} +
+ + + + [state.canSubmit, state.isDirty]}> + {([canSubmit, isDirty]) => ( + + )} + + + + ); +} + +function AccessSegmentedControl({ + label, + value, + onChange, +}: { + label: string; + value: FeatureValue | undefined; + onChange: (value: FeatureValue) => void; +}) { + return ( +
+ {ACCESS_LEVELS.map((level) => { + const active = value === level.value; + return ( + + ); + })} +
+ ); +} + +function FeaturesFormSkeleton() { + return ( +
+ {Array.from({ length: OVERRIDABLE_FEATURES.length }).map((_, index) => ( +
+
+
+
+ ))} +
+ ); +} diff --git a/packages/backoffice/src/components/pages/dashboard.tsx b/packages/backoffice/src/components/pages/dashboard.tsx new file mode 100644 index 0000000000..d4a1e3f736 --- /dev/null +++ b/packages/backoffice/src/components/pages/dashboard.tsx @@ -0,0 +1,211 @@ +import { makeQueryErrorComponent } from '@bo/components/common/ErrorComponent'; +import { SuspenseQuery } from '@bo/components/core/SuspenseQuery'; +import { CreateOrganizationPanel } from '@bo/components/organisms/CreateOrganizationPanel'; +import { listOrganizationsQueryOptions } from '@bo/data/organization'; +import { useRouter } from '@tanstack/react-router'; +import { type ReactNode, useState } from 'react'; +import { Button, Command, CommandEmpty, CommandInput, CommandItem, CommandList, Kbd, Typo } from 'ui-design-system'; +import { Icon } from 'ui-icons'; + +const ErrorComponent = makeQueryErrorComponent(Something went wrong while fetching organizations); + +export function DashboardPage() { + const [isCreatingOrg, setIsCreatingOrg] = useState(false); + const openCreate = () => setIsCreatingOrg(true); + + return ( + <> + + + + + } + errorComponent={ErrorComponent} + > + {(organizations) => + organizations.length === 0 ? ( +
+ +
+ ) : ( + + + + + ) + } +
+ + + + ); +} + +function LaunchpadColumn({ children }: { children: ReactNode }) { + return
{children}
; +} + +function LaunchpadHeader({ onCreate }: { onCreate: () => void }) { + return ( +
+
+ Organizations + Jump to an organization or provision a new one. +
+ +
+ ); +} + +type Organization = { id: string; name: string }; + +function OrganizationLauncher({ organizations, onCreate }: { organizations: Organization[]; onCreate: () => void }) { + const router = useRouter(); + const [query, setQuery] = useState(''); + + const openOrganization = (orgId: string) => { + router.navigate({ to: '/organizations/$orgId', params: { orgId } }); + }; + + const sorted = [...organizations].sort((a, b) => a.name.localeCompare(b.name, undefined, { sensitivity: 'base' })); + const hasQuery = query.trim().length > 0; + + return ( + +
+ + + {query.length > 0 ? ( + + ) : null} +
+ + + {hasQuery ? ( + +
+ No organization matches your search. + +
+
+ ) : null} + + {sorted.map((organization) => ( + openOrganization(organization.id)} + className="group gap-md rounded-lg px-md py-sm data-[selected=true]:bg-purple-background-light" + > + + {organization.name.charAt(0).toUpperCase()} + + + {organization.name} + + {organization.id} + + + + + ))} +
+ +
+
+ + + + to navigate + + + + to open + +
+ + {organizations.length} {organizations.length === 1 ? 'organization' : 'organizations'} + +
+
+ ); +} + +function EmptyState({ onCreate }: { onCreate: () => void }) { + return ( +
+ + + +
+ No organizations yet + Provision your first customer organization to get started. +
+ +
+ ); +} + +function LaunchpadSkeleton() { + return ( +
+
+ +
+
+
+ {Array.from({ length: 6 }).map((_, index) => ( +
+
+
+
+
+
+
+ ))} +
+
+
+
+
+ ); +} diff --git a/packages/backoffice/src/components/pages/licenses.tsx b/packages/backoffice/src/components/pages/licenses.tsx new file mode 100644 index 0000000000..2aaa265301 --- /dev/null +++ b/packages/backoffice/src/components/pages/licenses.tsx @@ -0,0 +1,649 @@ +import { makeQueryErrorComponent } from '@bo/components/common/ErrorComponent'; +import { SuspenseQuery } from '@bo/components/core/SuspenseQuery'; +import { createLicense, listLicensesQueryOptions, updateLicense } from '@bo/data/licenses'; +import { licensePayloadSchema } from '@bo/server-fns/licenses'; +import { useForm } from '@tanstack/react-form'; +import { useMutation } from '@tanstack/react-query'; +import type { LicenseDto, LicenseEntitlementsDto } from 'marble-api/generated/backoffice-api'; +import { type ReactNode, useMemo, useState } from 'react'; +import { Button, cn, Input, MenuCommand, Panel, Switch, Tag, TextArea, Typo } from 'ui-design-system'; +import { Icon } from 'ui-icons'; +import { z } from 'zod/v4'; + +/* ---------------------------------- Domain --------------------------------- */ + +const EXPIRING_SOON_DAYS = 30; +const DAY_MS = 24 * 60 * 60 * 1000; + +type EntitlementKey = keyof LicenseEntitlementsDto; + +const ENTITLEMENT_GROUPS: { title: string; items: { key: EntitlementKey; label: string }[] }[] = [ + { + title: 'Platform', + items: [ + { key: 'sso', label: 'SSO' }, + { key: 'user_roles', label: 'User roles' }, + { key: 'webhooks', label: 'Webhooks' }, + { key: 'analytics', label: 'Analytics' }, + { key: 'workflows', label: 'Workflows' }, + { key: 'rule_snoozes', label: 'Rule snoozes' }, + { key: 'test_run', label: 'Test run' }, + { key: 'data_enrichment', label: 'Data enrichment' }, + { key: 'user_scoring', label: 'User scoring' }, + ], + }, + { + title: 'Screening', + items: [ + { key: 'sanctions', label: 'Sanctions' }, + { key: 'continuous_screening', label: 'Continuous screening' }, + { key: 'lexisnexis', label: 'LexisNexis' }, + ], + }, + { + title: 'Cases', + items: [ + { key: 'auto_assignment', label: 'Auto-assignment' }, + { key: 'case_ai_assist', label: 'Case AI assist' }, + ], + }, +]; + +const ENTITLEMENT_KEYS = ENTITLEMENT_GROUPS.flatMap((group) => group.items.map((item) => item.key)); +const ENTITLEMENT_TOTAL = ENTITLEMENT_KEYS.length; + +const emptyEntitlements = (): LicenseEntitlementsDto => + Object.fromEntries(ENTITLEMENT_KEYS.map((key) => [key, false])) as LicenseEntitlementsDto; + +function enabledCount(entitlements: LicenseEntitlementsDto) { + return ENTITLEMENT_KEYS.reduce((count, key) => count + (entitlements[key] ? 1 : 0), 0); +} + +type LicenseStatus = 'active' | 'expiring' | 'expired' | 'suspended'; + +function getStatus(license: LicenseDto, now: number): LicenseStatus { + if (license.suspended_at) return 'suspended'; + const expiresAt = new Date(license.expiration_date).getTime(); + if (expiresAt < now) return 'expired'; + if (expiresAt < now + EXPIRING_SOON_DAYS * DAY_MS) return 'expiring'; + return 'active'; +} + +const STATUS_TAG: Record = { + active: { label: 'Active', color: 'green' }, + expiring: { label: 'Expiring soon', color: 'yellow' }, + expired: { label: 'Expired', color: 'red' }, + suspended: { label: 'Suspended', color: 'grey' }, +}; + +/* -------------------------------- Formatting ------------------------------- */ + +const dateFormatter = new Intl.DateTimeFormat('en', { day: '2-digit', month: 'short', year: 'numeric' }); +const relativeFormatter = new Intl.RelativeTimeFormat('en', { numeric: 'auto' }); + +function formatDate(iso: string) { + return dateFormatter.format(new Date(iso)); +} + +function formatRelative(iso: string, now: number) { + const days = Math.round((new Date(iso).getTime() - now) / DAY_MS); + if (Math.abs(days) >= 60) return relativeFormatter.format(Math.round(days / 30), 'month'); + if (Math.abs(days) >= 1) return relativeFormatter.format(days, 'day'); + return 'today'; +} + +/* ---------------------------------- Page ----------------------------------- */ + +const LicensesError = makeQueryErrorComponent( + Could not load licences., +); + +type PanelState = { mode: 'create' } | { mode: 'edit'; license: LicenseDto } | null; + +export function LicensesPage() { + const [panel, setPanel] = useState(null); + + return ( +
+
+
+ Licences +

+ Issue, inspect and revoke the license keys that unlock Marble for each customer. +

+
+ +
+ + } errorComponent={LicensesError}> + {(licenses) => setPanel({ mode: 'edit', license })} />} + + + (open ? null : setPanel(null))} /> +
+ ); +} + +/* ---------------------------------- List ----------------------------------- */ + +function LicensesList({ licenses, onEdit }: { licenses: LicenseDto[]; onEdit: (license: LicenseDto) => void }) { + const now = Date.now(); + const [search, setSearch] = useState(''); + + const sections = useMemo(() => { + const term = search.trim().toLowerCase(); + const matched = term + ? licenses.filter( + (license) => + license.organization_name.toLowerCase().includes(term) || license.description.toLowerCase().includes(term), + ) + : licenses; + + const attention: LicenseDto[] = []; + const active: LicenseDto[] = []; + const suspended: LicenseDto[] = []; + for (const license of matched) { + const status = getStatus(license, now); + if (status === 'suspended') suspended.push(license); + else if (status === 'expired' || status === 'expiring') attention.push(license); + else active.push(license); + } + + const byExpiry = (a: LicenseDto, b: LicenseDto) => + new Date(a.expiration_date).getTime() - new Date(b.expiration_date).getTime(); + const byName = (a: LicenseDto, b: LicenseDto) => a.organization_name.localeCompare(b.organization_name); + + return { + matched, + attention: attention.sort(byExpiry), + active: active.sort(byName), + suspended: suspended.sort(byName), + }; + }, [licenses, search, now]); + + if (licenses.length === 0) { + return ; + } + + return ( +
+
+ setSearch('')} + placeholder="Search by organisation or description" + value={search} + onChange={(event) => setSearch(event.currentTarget.value)} + aria-label="Search licences" + /> +
+ + {sections.matched.length === 0 ? ( + + ) : ( +
+ + + +
+ )} +
+ ); +} + +function LicenseSection({ + title, + icon, + tone, + licenses, + now, + onEdit, +}: { + title: string; + icon?: 'warning'; + tone?: 'attention'; + licenses: LicenseDto[]; + now: number; + onEdit: (license: LicenseDto) => void; +}) { + if (licenses.length === 0) return null; + + return ( +
+
+ {icon ? ( + + ) : null} + {title} + {licenses.length} +
+
    + {licenses.map((license) => ( + onEdit(license)} /> + ))} +
+
+ ); +} + +function LicenseRow({ license, now, onEdit }: { license: LicenseDto; now: number; onEdit: () => void }) { + const status = getStatus(license, now); + const tag = STATUS_TAG[status]; + const count = enabledCount(license.license_entitlements); + const updateMutation = useMutation(updateLicense()); + + const toggleSuspend = (suspend: boolean) => + updateMutation.mutate({ + licenseId: license.id, + payload: { + expiration_date: license.expiration_date, + organization_name: license.organization_name, + description: license.description, + license_entitlements: license.license_entitlements, + suspend, + }, + }); + + return ( +
  • +
    + {license.organization_name} + {license.description ? ( + {license.description} + ) : null} +
    + + + {tag.label} + + + + {count}/{ENTITLEMENT_TOTAL} enabled + + + + {formatDate(license.expiration_date)} + + {status === 'expired' ? 'Expired ' : 'Expires '} + {formatRelative(license.expiration_date, now)} + + + +
    + + + + + + + + + {license.suspended_at ? ( + toggleSuspend(false)}> + Reactivate + + ) : ( + toggleSuspend(true)}> + Suspend + + )} + + + +
    +
  • + ); +} + +/* ------------------------------- Secret value ------------------------------ */ + +function SecretValue({ + value, + defaultRevealed = false, + className, +}: { + value: string; + defaultRevealed?: boolean; + className?: string; +}) { + const [revealed, setRevealed] = useState(defaultRevealed); + const [copied, setCopied] = useState(false); + + const copy = () => { + navigator.clipboard.writeText(value).then(() => { + setCopied(true); + window.setTimeout(() => setCopied(false), 1500); + }); + }; + + return ( + + + {revealed ? value : '••••••••'} + + + + + ); +} + +/* ------------------------------ Empty / skeleton --------------------------- */ + +function EmptyState({ title, body }: { title: string; body: string }) { + return ( +
    + {title} +

    {body}

    +
    + ); +} + +function LicensesSkeleton() { + return ( +
    +
    +
      + {Array.from({ length: 4 }).map((_, index) => ( +
    • +
      +
      +
      +
      +
      +
    • + ))} +
    +
    + ); +} + +/* ------------------------------- Create / edit ----------------------------- */ + +const licenseFormSchema = licensePayloadSchema.extend({ + expiration_date: z.string().min(1, 'An expiration date is required.'), +}); + +type LicenseFormValues = z.infer; + +const FORM_ID = 'license-form'; + +function toDateInputValue(iso: string) { + const date = new Date(iso); + if (Number.isNaN(date.getTime())) return ''; + return date.toISOString().slice(0, 10); +} + +function LicensePanel({ state, onOpenChange }: { state: PanelState; onOpenChange: (open: boolean) => void }) { + return ( + + + + {state ? onOpenChange(false)} /> : null} + + + + ); +} + +function LicensePanelBody({ state, onClose }: { state: NonNullable; onClose: () => void }) { + const isEdit = state.mode === 'edit'; + const existing = isEdit ? state.license : null; + + const createMutation = useMutation(createLicense()); + const updateMutation = useMutation(updateLicense()); + const [suspend, setSuspend] = useState(Boolean(existing?.suspended_at)); + const [createdLicense, setCreatedLicense] = useState(null); + + const form = useForm({ + defaultValues: { + organization_name: existing?.organization_name ?? '', + description: existing?.description ?? '', + expiration_date: existing ? toDateInputValue(existing.expiration_date) : '', + license_entitlements: existing?.license_entitlements ?? emptyEntitlements(), + } as LicenseFormValues, + validators: { + onMount: licenseFormSchema, + onChange: licenseFormSchema, + onSubmit: licenseFormSchema, + }, + onSubmit: async ({ value, formApi }) => { + if (!formApi.state.isValid) return; + const payload = { + ...value, + expiration_date: new Date(value.expiration_date).toISOString(), + }; + if (existing) { + await updateMutation.mutateAsync({ licenseId: existing.id, payload: { ...payload, suspend } }); + onClose(); + } else { + const created = await createMutation.mutateAsync(payload); + setCreatedLicense(created); + } + }, + }); + + if (createdLicense) { + return ; + } + + const setAllEntitlements = (enabled: boolean) => + form.setFieldValue( + 'license_entitlements', + Object.fromEntries(ENTITLEMENT_KEYS.map((key) => [key, enabled])) as LicenseEntitlementsDto, + ); + + return ( + <> + +
    + {isEdit ? 'Edit licence' : 'Create licence'} +

    + {isEdit + ? 'Update entitlements, expiry, and access for this customer.' + : 'Grant a customer access to Marble by issuing a new licence key.'} +

    +
    +
    + +
    { + event.preventDefault(); + event.stopPropagation(); + form.handleSubmit(); + }} + > + + {(field) => ( + + field.handleChange(event.currentTarget.value)} + onBlur={field.handleBlur} + placeholder="Acme Inc." + /> + + )} + + + + {(field) => ( + +