From bbfccc2d21a1224c12f5dc86eda51cf25ce7af00 Mon Sep 17 00:00:00 2001
From: kualta
Date: Tue, 8 Sep 2026 15:31:07 -0500
Subject: [PATCH 1/2] Publish shared Focus provider and practice picker
---
README.md | 44 ++
app/FocusShowcase.tsx | 249 +++++++++++
app/main.tsx | 13 +-
bun.lock | 473 ++++++++++++++++++--
package.json | 14 +-
src/focus/index.ts | 4 +
src/focus/panel.tsx | 506 +++++++++++++++++++++
src/focus/provider.tsx | 481 ++++++++++++++++++++
src/focus/study-subject-picker.tsx | 680 +++++++++++++++++++++++++++++
src/focus/text.tsx | 121 +++++
tests/focus-provider.fixture.tsx | 72 +++
tests/focus-provider.spec.ts | 53 +++
tests/focus.spec.ts | 60 +++
13 files changed, 2737 insertions(+), 33 deletions(-)
create mode 100644 app/FocusShowcase.tsx
create mode 100644 src/focus/index.ts
create mode 100644 src/focus/panel.tsx
create mode 100644 src/focus/provider.tsx
create mode 100644 src/focus/study-subject-picker.tsx
create mode 100644 src/focus/text.tsx
create mode 100644 tests/focus-provider.fixture.tsx
create mode 100644 tests/focus-provider.spec.ts
create mode 100644 tests/focus.spec.ts
diff --git a/README.md b/README.md
index 78522c3..60c491b 100644
--- a/README.md
+++ b/README.md
@@ -56,3 +56,47 @@ bun run build && bunx playwright test tests/a11y.spec.ts
## License
MIT
+
+## Practice sessions
+
+`@flow-industries/ui/focus` is an opt-in entry point for `FocusProvider`,
+`FocusPanel`, `StudySubjectPicker`, and the associated hooks and types. Install
+`@flow-industries/id` version 0.22.0 or newer alongside the UI package to use it.
+The SDK peer is optional for applications using only other UI components.
+
+```tsx
+import { createFocusApi } from "@flow-industries/id/focus";
+import { FocusPanel, FocusProvider, useFocus } from "@flow-industries/ui/focus";
+
+function Practice() {
+ const focus = useFocus();
+ return ;
+}
+
+// Keep this API instance stable; credentials and surface belong to the host.
+const api = createFocusApi(authHost, getToken, "web");
+
+
+
+;
+```
+
+Pass a stable authenticated account ID as `viewerId`, or `null` for an inert
+provider. The host retains its guest, disabled-account, and embedded-surface
+policy: omit the provider/panel wherever practice must be excluded. Account
+changes clear session and subject state and discard old asynchronous responses.
+The provider restores active sessions on mount and refreshes when the document
+becomes visible. Outside a provider, hooks return an inert value.
+
+`FocusPanel` accepts an explicit `focus` value, an optional `managementLink`, and
+`text` as an injected `FocusText` translator. Use
+`text={createFocusText(locale, messages)}` for locale and message overrides. The controlled `StudySubjectPicker`
+accepts catalog/subjects, busy/error state, and pick/create callbacks; the host
+owns requests when using it alone. Arrow keys navigate, Enter selects, and
+Escape clears search or returns from a category. Private subject labels are
+marked `data-user-content` and isolated for bidirectional text.
+
+The showcase at `/#focus` provides account, delay, error, reload, and theme
+controls with local fixture data. Run `bun run build` then
+`bunx playwright test tests/focus.spec.ts` for recovery, privacy, keyboard and
+failure checks.
diff --git a/app/FocusShowcase.tsx b/app/FocusShowcase.tsx
new file mode 100644
index 0000000..2f8b0f8
--- /dev/null
+++ b/app/FocusShowcase.tsx
@@ -0,0 +1,249 @@
+import {
+ type ActiveAction,
+ createFocusApi,
+ type FocusApi,
+ type StudySubject,
+} from "@flow-industries/id/focus";
+import { type ReactNode, useMemo, useState } from "react";
+import { Button } from "../src/components/ui/button";
+import { FocusPanel, FocusProvider, useFocus } from "../src/focus";
+
+const catalog = {
+ version: 1,
+ categories: [
+ {
+ slug: "languages",
+ label: "Languages",
+ fields: [
+ { slug: "languages/chinese", label: "Chinese", aliases: ["Mandarin"] },
+ ],
+ },
+ ],
+};
+
+function createDemoApi(viewer: string): FocusApi {
+ const base = createFocusApi(
+ "https://unused.invalid",
+ async () => null,
+ "web",
+ );
+ const key = `focus-showcase-${viewer}`;
+ function read(): ActiveAction | null {
+ // SAFETY: This showcase reads only the session shape it writes under its viewer-specific key.
+ const saved = JSON.parse(localStorage.getItem(key) ?? "null") as
+ | (ActiveAction & { sampledAt?: number })
+ | null;
+ if (!saved) return null;
+ if (!saved.paused)
+ saved.accruedSeconds +=
+ (Date.now() - (saved.sampledAt ?? Date.now())) / 1000;
+ return saved;
+ }
+ async function respond(value: T): Promise {
+ await new Promise((resolve) =>
+ setTimeout(resolve, Number(localStorage.getItem("focus-delay") ?? 0)),
+ );
+ if (localStorage.getItem("focus-failure") === "true")
+ throw new Error("Demo unavailable");
+ return value;
+ }
+ const subjects: StudySubject[] = JSON.parse(
+ localStorage.getItem(`${key}-subjects`) ?? "null",
+ ) ?? [
+ {
+ id: `${viewer}-chinese`,
+ field: "languages/chinese",
+ name: `${viewer}'s Chinese`,
+ archivedAt: null,
+ createdAt: new Date().toISOString(),
+ lastUsedAt: new Date().toISOString(),
+ },
+ ];
+ return {
+ ...base,
+ catalog: () =>
+ respond({
+ actions: [
+ {
+ id: "action.study",
+ label: "Practice",
+ description: "Practice a subject",
+ mode: "linear",
+ base: 10,
+ flowMultiplier: true,
+ userStartable: true,
+ requiresSubject: true,
+ },
+ {
+ id: "game.action.meditation",
+ label: "Meditation",
+ description: "Take a moment",
+ mode: "linear",
+ base: 10,
+ flowMultiplier: true,
+ userStartable: true,
+ requiresSubject: false,
+ },
+ ],
+ }),
+ active: () => respond(read()),
+ studyCatalog: () => respond(catalog),
+ subjects: () => respond({ subjects }),
+ async createSubject(request) {
+ const subject = {
+ ...subjects[0],
+ id: crypto.randomUUID(),
+ name: request.name ?? "Chinese",
+ field: request.field ?? null,
+ };
+ await respond(null);
+ subjects.push(subject);
+ localStorage.setItem(`${key}-subjects`, JSON.stringify(subjects));
+ return { subject };
+ },
+ async start(request) {
+ const previous = read();
+ if (previous && !request.replace)
+ return respond({ error: "active_session", active: previous });
+ const subject = subjects.find((item) => item.id === request.subjectId);
+ const session: ActiveAction = {
+ sessionId: crypto.randomUUID(),
+ source: request.source,
+ label: request.source === "action.study" ? "Practice" : "Meditation",
+ surface: "web",
+ startedAt: new Date().toISOString(),
+ paused: false,
+ accruedSeconds: 90,
+ subject: subject
+ ? { id: subject.id, name: subject.name, field: subject.field }
+ : null,
+ priorMinutes: 0,
+ flowScore: 0,
+ };
+ await respond(null);
+ localStorage.setItem(
+ key,
+ JSON.stringify({ ...session, sampledAt: Date.now() }),
+ );
+ return { session };
+ },
+ async event(request) {
+ const active = read();
+ await respond(null);
+ if (active && active.sessionId === request.sessionId) {
+ if (request.kind === "pause") active.paused = true;
+ if (request.kind === "resume") active.paused = false;
+ localStorage.setItem(
+ key,
+ JSON.stringify({ ...active, sampledAt: Date.now() }),
+ );
+ }
+ return { ok: true, recorded: true };
+ },
+ async finish() {
+ const active = read();
+ await respond(null);
+ localStorage.removeItem(key);
+ return {
+ ok: true,
+ sessionId: active?.sessionId ?? "",
+ source: active?.source ?? "action.study",
+ label: active?.label ?? "Practice",
+ subject: active?.subject ?? null,
+ xpGranted: 12,
+ durationSeconds: Math.floor(active?.accruedSeconds ?? 0),
+ };
+ },
+ summary: async (range) =>
+ respond({
+ range,
+ categories: [],
+ total: { seconds: viewer === "Alice" ? 420 : 120, sessions: 1 },
+ subjects: subjects.map((subject) => ({
+ subject,
+ focusedSeconds: viewer === "Alice" ? 420 : 120,
+ sessions: 1,
+ lastAt: subject.createdAt,
+ seconds: viewer === "Alice" ? 420 : 120,
+ })),
+ }),
+ };
+}
+
+function DemoPanel(): ReactNode {
+ const focus = useFocus();
+ return (
+ <>
+
+ Practice statistics}
+ />
+ >
+ );
+}
+
+export function FocusShowcase(): ReactNode {
+ const [viewer, setViewer] = useState("Alice");
+ const [failure, setFailure] = useState(
+ localStorage.getItem("focus-failure") === "true",
+ );
+ const [delay, setDelay] = useState(
+ localStorage.getItem("focus-delay") === "1000",
+ );
+ const [dark, setDark] = useState(false);
+ const api = useMemo(() => createDemoApi(viewer ?? "Guest"), [viewer]);
+ return (
+
+ Focus
+
+
+
+
+
+
+
+ {viewer ?? "Guest"}
+
+
+
+
+
+
+ );
+}
diff --git a/app/main.tsx b/app/main.tsx
index 2cf289a..5842202 100644
--- a/app/main.tsx
+++ b/app/main.tsx
@@ -1,9 +1,16 @@
-import { StrictMode } from "react";
+import { lazy, StrictMode, Suspense } from "react";
import { createRoot } from "react-dom/client";
import "./styles.css";
import { App } from "./App";
+
import { initRum } from "./rum";
+const FocusShowcase = lazy(() =>
+ import("./FocusShowcase").then((module) => ({
+ default: module.FocusShowcase,
+ })),
+);
+
initRum(
import.meta.env.VITE_OO_RUM_TOKEN ?? "rumIPhQpKsQRwq4Piit",
import.meta.env.VITE_APP_VERSION ?? "dev",
@@ -11,6 +18,8 @@ initRum(
createRoot(document.getElementById("root")!).render(
-
+ Loading practice…
}>
+ {window.location.hash === "#focus" ? : }
+
,
);
diff --git a/bun.lock b/bun.lock
index 6ecd019..fc31b3e 100644
--- a/bun.lock
+++ b/bun.lock
@@ -23,6 +23,7 @@
"devDependencies": {
"@axe-core/playwright": "^4.12.1",
"@biomejs/biome": "2.5.8",
+ "@flow-industries/id": "0.22.0",
"@flow-industries/lint": "0.3.0",
"@openobserve/browser-logs": "^0.3.1",
"@openobserve/browser-rum": "^0.3.1",
@@ -41,13 +42,55 @@
"vite": "^7.2.7",
},
"peerDependencies": {
+ "@flow-industries/id": ">=0.22.0",
"react": ">=19.0.0",
"react-dom": ">=19.0.0",
"tailwindcss": ">=4.0.0",
},
+ "optionalPeers": [
+ "@flow-industries/id",
+ ],
},
},
"packages": {
+ "@adraffy/ens-normalize": ["@adraffy/ens-normalize@1.11.1", "", {}, "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ=="],
+
+ "@aws-sdk/checksums": ["@aws-sdk/checksums@3.1000.29", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-Dtu0gr4dnATZAPwEYbpCsG+MpLM7OAliy2gTepEFQwl1vZ6DL3QMH2FveMa3HLvPsOdhJsPRB3KtxVhph9T75A=="],
+
+ "@aws-sdk/client-s3": ["@aws-sdk/client-s3@3.1128.0", "", { "dependencies": { "@aws-sdk/checksums": "^3.1000.29", "@aws-sdk/core": "^3.977.9", "@aws-sdk/credential-provider-node": "^3.972.82", "@aws-sdk/middleware-sdk-s3": "^3.972.75", "@aws-sdk/signature-v4-multi-region": "^3.996.46", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/fetch-http-handler": "^5.7.2", "@smithy/node-http-handler": "^4.11.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-tYEB4058LdhTiSS7sCVVSpqSAdjIc1jTaf1dDPoIRJbR/XI5A2ZOuCiV1Aebo/pria/pUJBOT0WjdZVIwaZtDA=="],
+
+ "@aws-sdk/core": ["@aws-sdk/core@3.977.9", "", { "dependencies": { "@aws-sdk/types": "^3.974.5", "@aws-sdk/xml-builder": "^3.972.40", "@aws/lambda-invoke-store": "^0.3.0", "@smithy/core": "^3.33.3", "@smithy/signature-v4": "^5.6.12", "@smithy/types": "^4.17.2", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-reqPFEQrZxDZpeGj4PFMepBeR5LGYHRqq/L0motTzgFkCRBA4rFdaVXDSLYyGHhxVz7sT2PDnPN9CluGSfgyJA=="],
+
+ "@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.972.70", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-H404B7dJl2mCrBqahDEYsanB0xhdDp6tXnXcTUnXmmpy2Q3J0Ho0bUajZ2jr/RdwzCyS59Gi8xXIFwPLGBl6Uw=="],
+
+ "@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.972.72", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/fetch-http-handler": "^5.7.2", "@smithy/node-http-handler": "^4.11.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-X98zYOrVOeuosCX+6ktf29FC2N2GHPLia7qv6mzPzTc+RPAuHWCDS++Z6JK7eGYqb/v6uaW7bAXaOvDBfol+0w=="],
+
+ "@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.973.15", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/credential-provider-env": "^3.972.70", "@aws-sdk/credential-provider-http": "^3.972.72", "@aws-sdk/credential-provider-login": "^3.972.77", "@aws-sdk/credential-provider-process": "^3.972.70", "@aws-sdk/credential-provider-sso": "^3.973.14", "@aws-sdk/credential-provider-web-identity": "^3.972.76", "@aws-sdk/nested-clients": "^3.997.44", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/credential-provider-imds": "^4.4.16", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-Rykg6s5ceBuynMOGWgoowO4N+27JfnqXAnVaSunZl0hOO1XodSrxGNz6sCEbnmS0lAfQZDKyb3fbr46gSuv6Sg=="],
+
+ "@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.972.77", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/nested-clients": "^3.997.44", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-Jb59xfEISoN5mmbnA+HYqdtrSX3CgCtJoof+V5D8/TgUI56W63GEEd5Y58WijU3Ou6+WEgaLD1feVzaRXV5IDQ=="],
+
+ "@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.82", "", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.70", "@aws-sdk/credential-provider-http": "^3.972.72", "@aws-sdk/credential-provider-ini": "^3.973.15", "@aws-sdk/credential-provider-process": "^3.972.70", "@aws-sdk/credential-provider-sso": "^3.973.14", "@aws-sdk/credential-provider-web-identity": "^3.972.76", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/credential-provider-imds": "^4.4.16", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-znDkEOGXB8W3kG1LJUKP3foBZY/9qLM0eil/DxWXSp37XsdsRLQHE/d/OaCGGVgKpA6znR38h/+INk8do1FjiA=="],
+
+ "@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.972.70", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-2ry03fGRJr4sV3jI+ocjj5JqALnFD6ymM5KiNCDZMvq8bX2GSbE0vji4aM43TVCl2nXqqLRZaUxdq/KeWRAY4Q=="],
+
+ "@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.973.14", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/nested-clients": "^3.997.44", "@aws-sdk/token-providers": "3.1116.0", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-jkhg/8ocAAoc0RFyLMhCw+/zZh7gystQgd4F4hznNa8P4Cc501PQmxd+jGLiMHodPJ+7Zv/3znM62gZojyasmA=="],
+
+ "@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.972.76", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/nested-clients": "^3.997.44", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-d3AGyVu759PGr35mEB2s22xxlNEA5rpdxtSPJthfPFJvoQ8dt357iVPECqWfUxXp1toJAvKmbtcIYVGigaGsCA=="],
+
+ "@aws-sdk/middleware-sdk-s3": ["@aws-sdk/middleware-sdk-s3@3.972.75", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/signature-v4-multi-region": "^3.996.46", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-wMIsNumRVKaNMKhvU/s9VrdEwE8S6gSzXp4RygFG5BEMnGkkXf8cjh8zf7cKJBpUDpqTWqwbz5isEgp9rH6Lng=="],
+
+ "@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.997.44", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/signature-v4-multi-region": "^3.996.46", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/fetch-http-handler": "^5.7.2", "@smithy/node-http-handler": "^4.11.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-NhEgryjlBF9w38ZXqGymQV28IhkYa1mKhlbYnqIis57AYwWGVYfUPgg/qC2rLRqOUfblxx++irvju10kVTa8Vw=="],
+
+ "@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.996.46", "", { "dependencies": { "@aws-sdk/types": "^3.974.5", "@smithy/signature-v4": "^5.6.12", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-L+2xZTye/2T96f3lwCws0Zw6GG2JHZW9e8FpVgGBeeExSKyeoZ6CWRpBml/7DNiK/O26jrgPM9F+Ay8VkgzUWQ=="],
+
+ "@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.1116.0", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/nested-clients": "^3.997.44", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-ygIivKqh8aHzNkucOCXHyIBgBpLPfrSI0mCqXF+vLBsPTUKqj0VSqAY0GFPe7lQl4HntjOcQ+KSyS7oUV2C54Q=="],
+
+ "@aws-sdk/types": ["@aws-sdk/types@3.974.5", "", { "dependencies": { "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-LkwLL2BLbC6wNNm4JaH9mbEqBMdOZCct6VAYqhdN4U1xrWM+fUJQEfbHwQgDypapOWTRtlk25akb5afM0P8CIQ=="],
+
+ "@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.40", "", { "dependencies": { "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-wlFmCIGUlwF4zx/kncw+bmxTQh1HeSJq4mYV/V5cZUSJadDP3kXvGW8Rn21cimj/7y9ju+47oYWXi97vF7czaA=="],
+
+ "@aws/lambda-invoke-store": ["@aws/lambda-invoke-store@0.3.0", "", {}, "sha512-sl4Bm6yiMNYrZKkqqDFWN0UfnWhlS8ivKxrYl+6t0gCLrqr8y3B2IqZZbFRkfaVVp7C/baApyh71P+LeE1A2sQ=="],
+
"@axe-core/playwright": ["@axe-core/playwright@4.12.1", "", { "dependencies": { "axe-core": "~4.12.1" }, "peerDependencies": { "playwright-core": ">= 1.0.0" } }, "sha512-rMd7xriptqKpP+w5265i4Hdkv2X5kbu6uiBi/B2I7uf3hieRBM3qDCfaKPtxfiYb2mKXfF+yLODJwIx+Jv1GDw=="],
"@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="],
@@ -94,6 +137,24 @@
"@base-ui/utils": ["@base-ui/utils@0.2.6", "", { "dependencies": { "@babel/runtime": "^7.28.6", "@floating-ui/utils": "^0.2.11", "reselect": "^5.1.1", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "@types/react": "^17 || ^18 || ^19", "react": "^17 || ^18 || ^19", "react-dom": "^17 || ^18 || ^19" }, "optionalPeers": ["@types/react"] }, "sha512-yQ+qeuqohwhsNpoYDqqXaLllYAkPCP4vYdDrVo8FQXaAPfHWm1pG/Vm+jmGTA5JFS0BAIjookyapuJFY8F9PIw=="],
+ "@better-auth/core": ["@better-auth/core@1.7.3", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.41.1", "@standard-schema/spec": "^1.1.0", "zod": "^4.5.4" }, "peerDependencies": { "@better-auth/utils": "0.4.2", "@better-fetch/fetch": "1.3.1", "@cloudflare/workers-types": ">=4", "@opentelemetry/api": "^1.9.0", "better-call": "1.4.0", "jose": "^6.1.0", "kysely": "^0.28.5 || ^0.29.0", "nanostores": "^1.0.1" }, "optionalPeers": ["@cloudflare/workers-types", "@opentelemetry/api"] }, "sha512-JdP7lOkyE83jgjn7RilJj1XvZ7n2JjRsErKJuaXchjyuNo6cf1iVd3GtbhAtiUyJJkWdk8yL+LaUBKT80H0zLA=="],
+
+ "@better-auth/drizzle-adapter": ["@better-auth/drizzle-adapter@1.7.3", "", { "peerDependencies": { "@better-auth/core": "^1.7.3", "@better-auth/utils": "0.4.2", "drizzle-orm": "^0.45.2 || >=1.0.0-rc.1 <2.0.0" }, "optionalPeers": ["drizzle-orm"] }, "sha512-S+nQRlxbUhkR43LrSv8c98ZvOvmv3nrtOnHkiZXkdDkr60PWp7maC2cqgzZ2C9exCC1a+4TugJlx2jRL+r+/9A=="],
+
+ "@better-auth/kysely-adapter": ["@better-auth/kysely-adapter@1.7.3", "", { "peerDependencies": { "@better-auth/core": "^1.7.3", "@better-auth/utils": "0.4.2", "kysely": "^0.28.17 || ^0.29.0" }, "optionalPeers": ["kysely"] }, "sha512-UIsyJMIrjUnT+yTaS6dkCxYYmtPwxFHxwSJ8+CLty2II5w9BewlDxDA0/QzhoL/InYCPxQ5Y6xIgLHZG1dhwRA=="],
+
+ "@better-auth/memory-adapter": ["@better-auth/memory-adapter@1.7.3", "", { "peerDependencies": { "@better-auth/core": "^1.7.3", "@better-auth/utils": "0.4.2" } }, "sha512-WdLANFY/QWC3G351RCzxU+Y9YlW+BQ1oG9NwBTSOUWQw5rZ87ws+weU8tvAMO7sQ4C9gKIlkOKBKUKXrSt91Tw=="],
+
+ "@better-auth/mongo-adapter": ["@better-auth/mongo-adapter@1.7.3", "", { "peerDependencies": { "@better-auth/core": "^1.7.3", "@better-auth/utils": "0.4.2", "mongodb": "^6.0.0 || ^7.0.0" }, "optionalPeers": ["mongodb"] }, "sha512-YL9m01tNogmFmRvOWJ46M9WwE6HirCXHDell29mtsQB/Qs1TPNLrgj7ybGMMGhQuyj6S218+8Wbls8m9s+i8RQ=="],
+
+ "@better-auth/prisma-adapter": ["@better-auth/prisma-adapter@1.7.3", "", { "peerDependencies": { "@better-auth/core": "^1.7.3", "@better-auth/utils": "0.4.2", "@prisma/client": "^5.0.0 || ^6.0.0 || ^7.0.0", "prisma": "^5.0.0 || ^6.0.0 || ^7.0.0" }, "optionalPeers": ["@prisma/client", "prisma"] }, "sha512-TJ/DhlU7oLzrC626/1wfYA1Pl+lVsXa/zXBZ8d7Rlc2YO5fGd5fsAYJdRrYMyA51iZEo+rWLXMhZ0cez1BamsQ=="],
+
+ "@better-auth/telemetry": ["@better-auth/telemetry@1.7.3", "", { "peerDependencies": { "@better-auth/core": "^1.7.3", "@better-auth/utils": "0.4.2", "@better-fetch/fetch": "1.3.1" } }, "sha512-aixgHbJhGvS8PRczX/LR3murYyBnIvOGmJw37ZZBMg6ZtLR/UBJAkufbDi1HYn5THSuTJ3D5DtY85Ahh/ABQtw=="],
+
+ "@better-auth/utils": ["@better-auth/utils@0.4.2", "", { "dependencies": { "@noble/hashes": "^2.0.1" } }, "sha512-AUxrvu+HaaODsUyzDxFgwd/8RZ1yZaYo42LXKSrU2oGgR38pS1ij8nqQKNgtTWoYGpNevNXtCfgTy6loHveW9A=="],
+
+ "@better-fetch/fetch": ["@better-fetch/fetch@1.3.1", "", {}, "sha512-ABkD1WhyfPZprKRQI3bhATjeiFuNWC9PXhfGWqL+sg/gKrM977oFrYkdb4msM3hgUGonr7KlOsOFT5TU2rht9g=="],
+
"@biomejs/biome": ["@biomejs/biome@2.5.8", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.5.8", "@biomejs/cli-darwin-x64": "2.5.8", "@biomejs/cli-linux-arm64": "2.5.8", "@biomejs/cli-linux-arm64-musl": "2.5.8", "@biomejs/cli-linux-x64": "2.5.8", "@biomejs/cli-linux-x64-musl": "2.5.8", "@biomejs/cli-win32-arm64": "2.5.8", "@biomejs/cli-win32-x64": "2.5.8" }, "bin": { "biome": "bin/biome" } }, "sha512-aeAeeJB9fSDc7Gq+2GqpQxA0qBj6gj1k2R6L1cYqGePKP/baIq1WX8y6B+D+nRsO5ViQL22K/8IwbqERW0q1nw=="],
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.5.8", "", { "os": "darwin", "cpu": "arm64" }, "sha512-mk1QON9PHllvvLN5gU3f4rMxeh4syK5p9OvKyWH6/W8ueh04uaC8TUXXByhGufWf/y5mQc03ZLM45zU+cmqMjA=="],
@@ -112,7 +173,7 @@
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.5.8", "", { "os": "win32", "cpu": "x64" }, "sha512-I2czzXTY61f3nFJxXoMDq80t7MivxDEnCjE+8sDKoFfcKMaoQdkqhIFQ3KyY0XLzeSpUBYeNAXgD+iOV/BU0VA=="],
- "@emnapi/runtime": ["@emnapi/runtime@1.9.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw=="],
+ "@emnapi/runtime": ["@emnapi/runtime@1.11.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA=="],
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.7", "", { "os": "aix", "cpu": "ppc64" }, "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg=="],
@@ -174,59 +235,69 @@
"@floating-ui/utils": ["@floating-ui/utils@0.2.11", "", {}, "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg=="],
+ "@flow-industries/id": ["@flow-industries/id@0.22.0", "", { "dependencies": { "@aws-sdk/client-s3": "^3.1073.0", "@flow-industries/ui": "^0.21.1", "@hono/otel": "^1.1.2", "@openobserve/browser-logs": "^0.3.1", "@openobserve/browser-rum": "^0.3.1", "@opentelemetry/api": "^1.9.1", "@opentelemetry/exporter-trace-otlp-http": "^0.218.0", "@opentelemetry/resources": "^2.7.1", "@opentelemetry/sdk-trace-base": "^2.7.1", "@opentelemetry/sdk-trace-node": "^2.7.1", "@opentelemetry/semantic-conventions": "^1.41.1", "@react-email/components": "^1.0.12", "@react-email/render": "^2.0.8", "@tanstack/query-sync-storage-persister": "^5.90.22", "@tanstack/react-query": "^5.90.20", "@tanstack/react-query-persist-client": "^5.90.22", "@tanstack/react-router": "^1.160.0", "better-auth": "^1.4.17", "drizzle-orm": "^0.45.1", "geist": "^1.7.0", "hono": "^4.11.5", "jose": "^6.1.3", "lucide-react": "^0.563.0", "motion": "^12.33.0", "pino": "^10.3.1", "postgres": "^3.4.8", "react": "^19.2.4", "react-dom": "^19.2.4", "react-intersection-observer": "^10.0.2", "sharp": "^0.35.2", "tempo.ts": "^0.14.2", "viem": "2.47.10", "wagmi": "^3.4.2", "zod": "^4.3.6", "zustand": "^5.0.11" }, "peerDependencies": { "@tanstack/react-start": ">=1.168.0", "@wagmi/core": ">=3.0.0", "ox": ">=0.14.0" }, "optionalPeers": ["@tanstack/react-start", "@wagmi/core"] }, "sha512-qYGu9pwgH01fA7bZTqYezWo0A/q8xSnUCeb6nm9xxNW+SZqhzaMOqQUBf9CsdF/XorVYhtlSZNXHKI8Xo3dtuA=="],
+
"@flow-industries/lint": ["@flow-industries/lint@0.3.0", "", {}, "sha512-JKKCS+WMcdI9EbK0iyIt1qa2LRfv0u06UYvCnd9dykdhyO+7uglu+T8ShotAIweDytQMhj/+iHmgDozI+Uv15w=="],
+ "@flow-industries/ui": ["@flow-industries/ui@0.21.2", "", { "dependencies": { "@base-ui/react": "^1.3.0", "@hookform/resolvers": "^5.2.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "date-fns": "^4.1.0", "embla-carousel-react": "^8.6.0", "input-otp": "^1.4.2", "lucide-react": "^0.562.0", "motion": "^12.24.0", "react-hook-form": "^7.70.0", "react-resizable-panels": "^4.9.0", "recharts": "3.8.0", "tailwind-merge": "^3.4.0", "tw-animate-css": "^1.4.0", "zod": "^4.3.5" }, "peerDependencies": { "react": ">=19.0.0", "react-dom": ">=19.0.0", "tailwindcss": ">=4.0.0" } }, "sha512-XEr/01WLa4+8E1EblAB1UOKoEPgsX9XntZQ1p98akLwan1g1IPWQjZTSlkZ33wIrCVolqyZhOh0A1CAKXcQjog=="],
+
+ "@hono/otel": ["@hono/otel@1.1.2", "", { "dependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/semantic-conventions": "^1.28.0" }, "peerDependencies": { "hono": ">=4.0.0" } }, "sha512-UaBMKPGaQTj4sjvpGqQ+57eolTwMI2znzxV/QBUF99XxhcmqtqaZX95flXpGgWb+lnlinlCy23Y1sZ8+TzzM9A=="],
+
"@hookform/resolvers": ["@hookform/resolvers@5.2.2", "", { "dependencies": { "@standard-schema/utils": "^0.3.0" }, "peerDependencies": { "react-hook-form": "^7.55.0" } }, "sha512-A/IxlMLShx3KjV/HeTcTfaMxdwy690+L/ZADoeaTltLx+CVuzkeVIPuybK3jrRfw7YZnmdKsVVHAlEPIAEUNlA=="],
"@img/colour": ["@img/colour@1.1.0", "", {}, "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ=="],
- "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w=="],
+ "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.3.3" }, "os": "darwin", "cpu": "arm64" }, "sha512-Uhfl4V4lhP2nbUVF9+hyH1+luj86f1gUFeo8ALYxFoULoU+G87D43BfeMP8XHsk9boxAnCY/bf2EHwhA7MuGsA=="],
+
+ "@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.3.3" }, "os": "darwin", "cpu": "x64" }, "sha512-hWniXY3bG5qKpkKrAwPe4y+VTPmf086YQAnkxWh7uA1YrlRouWGa0M0Mxj3ZjnXFkv7/TD1bTy9lGUK26vRvWw=="],
+
+ "@img/sharp-freebsd-wasm32": ["@img/sharp-freebsd-wasm32@0.35.4", "", { "dependencies": { "@img/sharp-wasm32": "0.35.4" }, "os": "freebsd" }, "sha512-lIsKw/BU+kjB4eZjxrYrZmwOJYi3Ajrv66iAlBmUPyKc3HpnloevB1g3wxGD9P/5BbQ1brBGl65VRRrCvQDEqA=="],
- "@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.4" }, "os": "darwin", "cpu": "x64" }, "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw=="],
+ "@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.3.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-suTBPTDGrI9WodccaDdwZItTSaBYASlBk1NSfElSHrUfzu3szG6lvIF58+WiFvnfzuK8ZBFS5zE00PxqxnRiPg=="],
- "@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g=="],
+ "@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.3.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-FVJZ5mITMobmXIz/hPDTw0EintTW5H3WfrxwLqEqjiIihlu+hVRyGrFQ60xl0Lxn7Bt3zdpevPaQi0HEzqz9fw=="],
- "@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg=="],
+ "@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.3.3", "", { "os": "linux", "cpu": "arm" }, "sha512-3rbU4vqXXc3hY/OiXdl52xZvT0F1yEngWfvqudtPJg/KkyiaQw2DRsFrNzpmLvfavbwOq3qXn36GP8obHRULQA=="],
- "@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.4", "", { "os": "linux", "cpu": "arm" }, "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A=="],
+ "@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.3.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-0DaL0A6Xu6sQSQFwe4iVCrKWU2cCTItnRsYsCdxAMm9NF6twAA9BKnoqy4hqz4+azQ0JHuA26qiUKsf1XJ/v5A=="],
- "@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw=="],
+ "@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.3.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-cdn1OvUBwsXhbC0zSzJnNzf5MZ/mTrobawDvNXBTxe8VtqKAm0sRuEY2Evzovb/w9JMk4TvRxqt1mekSuJz64w=="],
- "@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA=="],
+ "@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.3.3", "", { "os": "linux", "cpu": "none" }, "sha512-HjPVx7yKz+0lqdhDlTw1tt90wamBoxhiXpvl1XZpJLiHH4RCJ5yDTqH+VlYPv2fwFs89JFw4c1IexYOcQUi4IQ=="],
- "@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.2.4", "", { "os": "linux", "cpu": "none" }, "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA=="],
+ "@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.3.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-neWLh+3yCNThxnfy3c4BbVBeGgt9aftno+XbT56iK28RgeDs3UOFWviLWlUu0bArYVYJaFDK+RRohbicUNCm8Q=="],
- "@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ=="],
+ "@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.3.3", "", { "os": "linux", "cpu": "x64" }, "sha512-4vKmvAst9nrowcqquKFAyZJUDolUaIp8uRiN0mWFguJ1IplC9/pitXtlnnlU4aa/eJw3J7i67V+pwUL+wZGdsA=="],
- "@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw=="],
+ "@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.3.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-Y9kQaLMuNoB0bPYOOdcZMaseNrFpPodIWWMrx+CZyydf2xn68j9WYc6sWWRrDwNkzCQjKYfc68L7jKjGlHMibw=="],
- "@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw=="],
+ "@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.3.3", "", { "os": "linux", "cpu": "x64" }, "sha512-fj8Mv0HHfD1Rr+4I68+3agJynxDWtBFgicTbSOb9Bke6pIwzGcJ+RX/yHjmiEGFMCavY/dxvem7MyNaJF+wDiw=="],
- "@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg=="],
+ "@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.3.3" }, "os": "linux", "cpu": "arm" }, "sha512-7OAS8gI0EReKGVN2HssHlM6umJgxF5VI3xN0p9FA91p/YO+ou5hiNghLdZ5BEHztwaaK5+bLKRf8x/o2L2nk9A=="],
- "@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.4" }, "os": "linux", "cpu": "arm" }, "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw=="],
+ "@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.3.3" }, "os": "linux", "cpu": "arm64" }, "sha512-De4jpEnAU8Hd5oT0j1G3uL4ZvTuipVMn7YC6vPaJhy6/7EwEae0SVAoBrUMYQbkLGDm85taVWwuPc1a44LTzCQ=="],
- "@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg=="],
+ "@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.3.3" }, "os": "linux", "cpu": "ppc64" }, "sha512-2oYZJeIl4kCcMGk4ouZVjnkCtFrpQFlNEtJ6GbxzhHQchwH0NH/qEb9ykmOl29dqwMq+JhFdZn+1ak2FKhI9fQ=="],
- "@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.4" }, "os": "linux", "cpu": "ppc64" }, "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA=="],
+ "@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.3.3" }, "os": "linux", "cpu": "none" }, "sha512-cPbNChoRURAWdebDIHSenxRpgEdy7JkPydSnUxRm9VvKD7m0/xVaR/8Fzlu81pk5nHEvHH87UZUA7cTtwnbJSA=="],
- "@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.2.4" }, "os": "linux", "cpu": "none" }, "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw=="],
+ "@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.3.3" }, "os": "linux", "cpu": "s390x" }, "sha512-RY0JFY8Fd6RonCBtHz+DvadaPkXDSI1AUn6yWL9TipqkZ1vY8w8evqdgyDFnkm4/K1ve1TvZiaePP5oSd4+WVQ=="],
- "@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.4" }, "os": "linux", "cpu": "s390x" }, "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg=="],
+ "@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.3.3" }, "os": "linux", "cpu": "x64" }, "sha512-9qvvEAuk8k89TfWUoX2htWjbAMX8p+NxCppjpcg5k6xMsjhBQPTsoIh36h9Qde4WRuGpJeYnOjdosDn/cnv+OA=="],
- "@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ=="],
+ "@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.3.3" }, "os": "linux", "cpu": "arm64" }, "sha512-KB5jxpfWQTr0nc3xdHtWChdbifHrBGsd2SM62Eyxrl8afikm+f5qGBU75SJIZBT/S1MC8XyacdlXBMSWq6OURA=="],
- "@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg=="],
+ "@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.3.3" }, "os": "linux", "cpu": "x64" }, "sha512-f+eZJZIQNEEd26RPSW+76chwOf1XtA2Y/O+5ocVyLliHkeih3e+jhLVBdNTd2rS3IbNXK8+ug93Vf5ZXtF5Lxg=="],
- "@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q=="],
+ "@img/sharp-wasm32": ["@img/sharp-wasm32@0.35.4", "", { "dependencies": { "@emnapi/runtime": "^1.11.3" } }, "sha512-zQnl4Kwp7Q6NHsENtU2T/00Zi+w3AQNwz3+UaTyVBy2FpXrzXzGjndpK61onhZjRtRpQXxCTeqw19bVyXOh7jA=="],
- "@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.5", "", { "dependencies": { "@emnapi/runtime": "^1.7.0" }, "cpu": "none" }, "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw=="],
+ "@img/sharp-webcontainers-wasm32": ["@img/sharp-webcontainers-wasm32@0.35.4", "", { "dependencies": { "@img/sharp-wasm32": "0.35.4" }, "cpu": "none" }, "sha512-ESfNkywmCfPNyaZjxooddJQiQ+l/nTpGEOGthxiLnIHXC/CmcBixnfwUleX9mCz9ovrUUvKMap/pm8RYbzfwaA=="],
- "@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g=="],
+ "@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.35.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-iNdlBX9gLVvqe2I3uIJSIKTq6wckP/DYxZtcqxm09x5Gi24DnFBmPAWZmr60ZyYMG0xlzo6goG3670ar+RXvRw=="],
- "@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg=="],
+ "@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.35.4", "", { "os": "win32", "cpu": "ia32" }, "sha512-kqRsbaa5CS6KHlpxnN7WhE6vAAugXyZButpRdvDWetlv6Qv4N9WTcrWzF7tXfB9T7MsoadqdI8hmwLq6UlLvtw=="],
- "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="],
+ "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.35.4", "", { "os": "win32", "cpu": "x64" }, "sha512-XtmnYhBcrORsJ4XJngyzr/EWP0hRZLAZRFaApdKuviyqF78+ylxh2y06ZmtULAMOnObJ3ucpN0AcwSWnMowTRg=="],
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
@@ -256,6 +327,12 @@
"@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.2.3", "", { "os": "win32", "cpu": "x64" }, "sha512-Ibm29/GgB/ab5n7XKqlStkm54qqZE8v2FnijUPBgrd67FWrac45o/RsNlaOWjme/B5UqeWt/8KM4aWBwA1D2Kw=="],
+ "@noble/ciphers": ["@noble/ciphers@2.4.0", "", {}, "sha512-AnjFn0Jv92laAkvMrghlFZq4qQCIN/4DxFV/eooqtC2YTjB7kBeLMS2T9KJX4Dn+ZVXLOwK0lSgqDtx9gvxtiw=="],
+
+ "@noble/curves": ["@noble/curves@1.9.1", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA=="],
+
+ "@noble/hashes": ["@noble/hashes@2.4.0", "", {}, "sha512-X5XaVWZIBCT7HHZGm5I7ZQXDwLG+bGXuSrMQAW+7Zvl87h1kmc1ZB1VSRJcpUfoUrGQp4Fkoxm5kZ+Ms+aW+eA=="],
+
"@openobserve/browser-core": ["@openobserve/browser-core@0.3.1", "", {}, "sha512-Q5BazD4GsL/+fQGPVfSfKveGwYhor0KnMF1exSfce07ngVTf3ZBttKVHjZSVdrpiR/0Jm1DCbeyZt8xqgXA9Xw=="],
"@openobserve/browser-logs": ["@openobserve/browser-logs@0.3.1", "", { "dependencies": { "@openobserve/browser-core": "0.3.1" }, "peerDependencies": { "@openobserve/browser-rum": "0.3.1" }, "optionalPeers": ["@openobserve/browser-rum"] }, "sha512-TootKFGsfaXA1KLuheU6XC7Sv9CQWILY5zRAVdOLJKdfPGQ3d5wBPyZIqUe91WeE3lGLCI8YF/7X9iqRcfj90g=="],
@@ -264,10 +341,88 @@
"@openobserve/browser-rum-core": ["@openobserve/browser-rum-core@0.3.1", "", { "dependencies": { "@openobserve/browser-core": "0.3.1" } }, "sha512-cv2WEtntLVabMFbzP4XvlpuYOx6ToFYheJyGUs4jagv/nlW6U+a4DnajSK0Mtgmizz4H3IDVI4LmxHNuRxAHbA=="],
+ "@opentelemetry/api": ["@opentelemetry/api@1.9.1", "", {}, "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q=="],
+
+ "@opentelemetry/api-logs": ["@opentelemetry/api-logs@0.218.0", "", { "dependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-fmEWp5kXlGEc3i/lR698Hz41DfGyN4Tbe4g7L1AxSc7fF8Xeh/FQ9Quqpa9dVA413Q1Ad43QOLzU4JoXgbFPWw=="],
+
+ "@opentelemetry/context-async-hooks": ["@opentelemetry/context-async-hooks@2.11.0", "", { "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-Tr79DyWI8itsBdg+jH+opjfrwLzX+erk1/ExkIwhWoAVjVrJIn2y5+cGjTC0Vy8fyNIA/y8wuJPZwr1T3xCZeQ=="],
+
+ "@opentelemetry/core": ["@opentelemetry/core@2.7.1", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-QAqIj32AtK6+pEVNG7EOVxHdE06RP+FM5qpiEJ4RtDcFIqKUZHYhl7/7UY5efhwmwNAg7j8QbJVBLxMerc0+gw=="],
+
+ "@opentelemetry/exporter-trace-otlp-http": ["@opentelemetry/exporter-trace-otlp-http@0.218.0", "", { "dependencies": { "@opentelemetry/core": "2.7.1", "@opentelemetry/otlp-exporter-base": "0.218.0", "@opentelemetry/otlp-transformer": "0.218.0", "@opentelemetry/resources": "2.7.1", "@opentelemetry/sdk-trace-base": "2.7.1" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-8dqezsmPhtKitIK/eTipZhYl9EX2/gNQ5zUMhaz3uxEURwfkNf8IPvo6yNfrzbxdtpAOybS/+h7wmIWYqFSpiw=="],
+
+ "@opentelemetry/otlp-exporter-base": ["@opentelemetry/otlp-exporter-base@0.218.0", "", { "dependencies": { "@opentelemetry/core": "2.7.1", "@opentelemetry/otlp-transformer": "0.218.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-ZwqpkNL5W7RyGJPDZ9g06DvKp8KFTWPJPN12anpMQYSKpTSU0z3EIZuPq9vPGpS8siFyOqDYDAuCwlNO9FqgbA=="],
+
+ "@opentelemetry/otlp-transformer": ["@opentelemetry/otlp-transformer@0.218.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.218.0", "@opentelemetry/core": "2.7.1", "@opentelemetry/resources": "2.7.1", "@opentelemetry/sdk-logs": "0.218.0", "@opentelemetry/sdk-metrics": "2.7.1", "@opentelemetry/sdk-trace-base": "2.7.1" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-CFaKH87WAzjuJ4awowTTLzUvMfaRfiOFG5+qm5S5ncyalRtN4ecQ+YmuANJSCrVPuvZFEkUgKhBPBndxi3rHsQ=="],
+
+ "@opentelemetry/resources": ["@opentelemetry/resources@2.11.0", "", { "dependencies": { "@opentelemetry/core": "2.11.0", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-Ie7+8q8MDF4FAEQCKVMTx3ReUvxiIAgIiiW3c9JdmP8+HMcDy20puT+AHjexnExgnbvBxjQ9fjkFDWrikJ2jQA=="],
+
+ "@opentelemetry/sdk-logs": ["@opentelemetry/sdk-logs@0.218.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.218.0", "@opentelemetry/core": "2.7.1", "@opentelemetry/resources": "2.7.1", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.4.0 <1.10.0" } }, "sha512-QvnNdugatFTVCJXH0Mcu7GOOJSylA9j127kIezOE4YwTI4YbowRons2K4WZTv5FMS8T4q9P0NdaRHdkSmeAIag=="],
+
+ "@opentelemetry/sdk-metrics": ["@opentelemetry/sdk-metrics@2.7.1", "", { "dependencies": { "@opentelemetry/core": "2.7.1", "@opentelemetry/resources": "2.7.1" }, "peerDependencies": { "@opentelemetry/api": ">=1.9.0 <1.10.0" } }, "sha512-MpDJdkiFDs3Pm1RHO3KByuZbuBdJEXEAkiC0+yJdsZGVCdf1RpHR6n+LHDcS7ffmfrt5kVCzJSCfm4z2C7v0uQ=="],
+
+ "@opentelemetry/sdk-trace": ["@opentelemetry/sdk-trace@2.11.0", "", { "dependencies": { "@opentelemetry/core": "2.11.0", "@opentelemetry/resources": "2.11.0", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-fFnTqGm8/G73GQVnxYi7LXa1ZVYEUvgL6XI1LpvV0bPC7WQ/ZGgKxCSl8FnlZBKto9JHHEFTO6s6CUpvvtwFrA=="],
+
+ "@opentelemetry/sdk-trace-base": ["@opentelemetry/sdk-trace-base@2.11.0", "", { "dependencies": { "@opentelemetry/core": "2.11.0", "@opentelemetry/resources": "2.11.0", "@opentelemetry/sdk-trace": "2.11.0", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-H19x/TX/LZdqiYOjM7fqtSxwlplC5pgelavqbQdHbhdq0q/AI/TGkM2dfGuuynTXmJPeF2HoZVoPDu+TGoW78A=="],
+
+ "@opentelemetry/sdk-trace-node": ["@opentelemetry/sdk-trace-node@2.11.0", "", { "dependencies": { "@opentelemetry/context-async-hooks": "2.11.0", "@opentelemetry/core": "2.11.0", "@opentelemetry/sdk-trace-base": "2.11.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-CuvCMJmZxswhNLlM2LfuLOW3h3fZujA4hsG4B+Sz4dX2zvaXO8Ng74cnDHWD64gLszTlhiG3c0iNUjj4g+0/sA=="],
+
+ "@opentelemetry/semantic-conventions": ["@opentelemetry/semantic-conventions@1.43.0", "", {}, "sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg=="],
+
+ "@pinojs/redact": ["@pinojs/redact@0.4.0", "", {}, "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg=="],
+
"@playwright/test": ["@playwright/test@1.62.1", "", { "dependencies": { "playwright": "1.62.1" }, "bin": { "playwright": "cli.js" } }, "sha512-DTcUc8qii+cpHvtOwggMtBRMjKZHXYWdw8syRYu2vtzuq4Wxphqq4NfCs5Zt44L6mA8rfDfj+PHnxFc/FeK6mQ=="],
+ "@react-email/body": ["@react-email/body@0.3.0", "", { "peerDependencies": { "react": "^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-uGo0BOOzjbMUo3lu+BIDWayvn5o6Xyfmnlla5VGf05n8gHMvO1ll7U4FtzWe3hxMLwt53pmc4iE0M+B5slG+Ug=="],
+
+ "@react-email/button": ["@react-email/button@0.2.1", "", { "peerDependencies": { "react": "^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-qXyj7RZLE7POy9BMKSoqQ00tOXThjOZSUnI2Yu9i29IHngPlmrNayIWBoVKtElES7OWwypUcpiajwi1mUWx6/A=="],
+
+ "@react-email/code-block": ["@react-email/code-block@0.2.1", "", { "dependencies": { "prismjs": "^1.30.0" }, "peerDependencies": { "react": "^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-M3B7JpVH4ytgn83/ujRR1k1DQHvTeABiDM61OvAbjLRPhC/5KLHU5KkzIbbuGIrjWwxAbL1kSQzU8MhLEtSxyw=="],
+
+ "@react-email/code-inline": ["@react-email/code-inline@0.0.6", "", { "peerDependencies": { "react": "^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-jfhebvv3dVsp3OdPgKXnk8+e2pBiDVZejDOBFzBa/IblrAJ9cQDkN6rBD5IyEg8hTOxwbw3iaI/yZFmDmIguIA=="],
+
+ "@react-email/column": ["@react-email/column@0.0.14", "", { "peerDependencies": { "react": "^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-f+W+Bk2AjNO77zynE33rHuQhyqVICx4RYtGX9NKsGUg0wWjdGP0qAuIkhx9Rnmk4/hFMo1fUrtYNqca9fwJdHg=="],
+
+ "@react-email/components": ["@react-email/components@1.0.12", "", { "dependencies": { "@react-email/body": "0.3.0", "@react-email/button": "0.2.1", "@react-email/code-block": "0.2.1", "@react-email/code-inline": "0.0.6", "@react-email/column": "0.0.14", "@react-email/container": "0.0.16", "@react-email/font": "0.0.10", "@react-email/head": "0.0.13", "@react-email/heading": "0.0.16", "@react-email/hr": "0.0.12", "@react-email/html": "0.0.12", "@react-email/img": "0.0.12", "@react-email/link": "0.0.13", "@react-email/markdown": "0.0.18", "@react-email/preview": "0.0.14", "@react-email/render": "2.0.6", "@react-email/row": "0.0.13", "@react-email/section": "0.0.17", "@react-email/tailwind": "2.0.7", "@react-email/text": "0.1.6" }, "peerDependencies": { "react": "^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-tH18JhPDWgE+3jnYkzyB6ZrZdfNnEsFe4PwmuXmlOw4NGIysP8wPY5aXZg++pTG9qUabXg1nzX/FGHGkObH8xQ=="],
+
+ "@react-email/container": ["@react-email/container@0.0.16", "", { "peerDependencies": { "react": "^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-QWBB56RkkU0AJ9h+qy33gfT5iuZknPC7Un/IjZv9B0QmMIK+WWacc0cH6y2SV5Cv/b99hU94fjEMOOO4enpkbQ=="],
+
+ "@react-email/font": ["@react-email/font@0.0.10", "", { "peerDependencies": { "react": "^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-0urVSgCmQIfx5r7Xc586miBnQUVnGp3OTYUm8m5pwtQRdTRO5XrTtEfNJ3JhYhSOruV0nD8fd+dXtKXobum6tA=="],
+
+ "@react-email/head": ["@react-email/head@0.0.13", "", { "peerDependencies": { "react": "^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-AJg6le/08Gz4tm+6MtKXqtNNyKHzmooOCdmtqmWxD7FxoAdU1eVcizhtQ0gcnVaY6ethEyE/hnEzQxt1zu5Kog=="],
+
+ "@react-email/heading": ["@react-email/heading@0.0.16", "", { "peerDependencies": { "react": "^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-jmsKnQm1ykpBzw4hCYHwBkt5pW2jScXffPeEH5ZRF5tZeF5b1pvlFTO9han7C0pCkZYo1kEvWiRtx69yfCIwuw=="],
+
+ "@react-email/hr": ["@react-email/hr@0.0.12", "", { "peerDependencies": { "react": "^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-TwmOmBDibavUQpXBxpmZYi2Iks/yeZOzFYh+di9EltMSnEabH8dMZXrl+pxNXzCgZ2XE8HY7VmUL65Lenfu5PA=="],
+
+ "@react-email/html": ["@react-email/html@0.0.12", "", { "peerDependencies": { "react": "^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-KTShZesan+UsreU7PDUV90afrZwU5TLwYlALuCSU0OT+/U8lULNNbAUekg+tGwCnOfIKYtpDPKkAMRdYlqUznw=="],
+
+ "@react-email/img": ["@react-email/img@0.0.12", "", { "peerDependencies": { "react": "^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-sRCpEARNVTf3FQhZOC+JTvu5r6ubiYWkT0ucYXg8ctkyi4G8QG+jgYPiNUqVeTLA2STOfmPM/nrk1nb84y6CPQ=="],
+
+ "@react-email/link": ["@react-email/link@0.0.13", "", { "peerDependencies": { "react": "^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-lkWc/NjOcefRZMkQoSDDbuKBEBDES9aXnFEOuPH845wD3TxPwh+QTf0fStuzjoRLUZWpHnio4z7qGGRYusn/sw=="],
+
+ "@react-email/markdown": ["@react-email/markdown@0.0.18", "", { "dependencies": { "marked": "^15.0.12" }, "peerDependencies": { "react": "^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-gSuYK5fsMbGk87jDebqQ6fa2fKcWlkf2Dkva8kMONqLgGCq8/0d+ZQYMEJsdidIeBo3kmsnHZPrwdFB4HgjUXg=="],
+
+ "@react-email/preview": ["@react-email/preview@0.0.14", "", { "peerDependencies": { "react": "^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-aYK8q0IPkBXyMsbpMXgxazwHxYJxTrXrV95GFuu2HbEiIToMwSyUgb8HDFYwPqqfV03/jbwqlsXmFxsOd+VNaw=="],
+
+ "@react-email/render": ["@react-email/render@2.1.0", "", { "dependencies": { "entities": "^4.5.0", "html-to-text": "^9.0.5", "html5parser": "^3.0.0", "prettier": "^3.5.3" }, "peerDependencies": { "react": "^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-F+zE3O6d6sW6Aj2UjvZAA17R7tJKM7kcq2mgV6k4HCT8jeLLFaVP2txMtH1lgqYFRMZ0Gxsd37q2PRyiXLXXxA=="],
+
+ "@react-email/row": ["@react-email/row@0.0.13", "", { "peerDependencies": { "react": "^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-bYnOac40vIKCId7IkwuLAAsa3fKfSfqCvv6epJKmPE0JBuu5qI4FHFCl9o9dVpIIS08s/ub+Y/txoMt0dYziGw=="],
+
+ "@react-email/section": ["@react-email/section@0.0.17", "", { "peerDependencies": { "react": "^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-qNl65ye3W0Rd5udhdORzTV9ezjb+GFqQQSae03NDzXtmJq6sqVXNWNiVolAjvJNypim+zGXmv6J9TcV5aNtE/w=="],
+
+ "@react-email/tailwind": ["@react-email/tailwind@2.0.7", "", { "dependencies": { "tailwindcss": "^4.1.18" }, "peerDependencies": { "@react-email/body": ">=0", "@react-email/button": ">=0", "@react-email/code-block": ">=0", "@react-email/code-inline": ">=0", "@react-email/container": ">=0", "@react-email/heading": ">=0", "@react-email/hr": ">=0", "@react-email/img": ">=0", "@react-email/link": ">=0", "@react-email/preview": ">=0", "@react-email/text": ">=0", "react": "^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@react-email/body", "@react-email/button", "@react-email/code-block", "@react-email/code-inline", "@react-email/container", "@react-email/heading", "@react-email/hr", "@react-email/img", "@react-email/link", "@react-email/preview"] }, "sha512-kGw80weVFXikcnCXbigTGXGWQ0MRCSYNCudcdkWxebkWYd0FG6/NPoN3V1p/u68/4+NxZwYPVi2fhnp0x23HdA=="],
+
+ "@react-email/text": ["@react-email/text@0.1.6", "", { "peerDependencies": { "react": "^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-TYqkioRS45wTR5il3dYk/SbUjjEdhSwh9BtRNB99qNH1pXAwA45H7rAuxehiu8iJQJH0IyIr+6n62gBz9ezmsw=="],
+
"@reduxjs/toolkit": ["@reduxjs/toolkit@2.11.2", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "@standard-schema/utils": "^0.3.0", "immer": "^11.0.0", "redux": "^5.0.1", "redux-thunk": "^3.1.0", "reselect": "^5.1.0" }, "peerDependencies": { "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" }, "optionalPeers": ["react", "react-redux"] }, "sha512-Kd6kAHTA6/nUpp8mySPqj3en3dm0tdMIgbttnQ1xFMVpufoj+ADi8pXLBsd4xzTRHQa7t/Jv8W5UnCuW4kuWMQ=="],
+ "@remix-run/fetch-router": ["@remix-run/fetch-router@0.17.0", "", { "dependencies": { "@remix-run/route-pattern": "^0.19.0", "@remix-run/session": "^0.4.1" } }, "sha512-3FeJGrTqrKKCvZdQWijbCXTEHKcdttkLFbI2ogfpZ+iDYSNZ9036wgDXuuoZqg6d+D0E8Unhk5ZwrLKDCd/hOw=="],
+
+ "@remix-run/route-pattern": ["@remix-run/route-pattern@0.19.0", "", {}, "sha512-RXKaIJ2Lx01uyZc0iw+yLzowFCa1/NuB8jN7QTo4QUe2CaUGtvPGdhgrTUp75lyNNCSJIrM9SaAJ6c1pjZdmoA=="],
+
+ "@remix-run/session": ["@remix-run/session@0.4.2", "", {}, "sha512-NGzu6/gC5xD/tq40W0WqzTt4JhCdSCIwDHM1aa13JBqb4Ml/Mb0kmXqjfOe/gBYfu6AA11nRQ/BJyr+VduTodA=="],
+
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.3", "", {}, "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q=="],
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.60.1", "", { "os": "android", "cpu": "arm" }, "sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA=="],
@@ -320,6 +475,26 @@
"@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.60.1", "", { "os": "win32", "cpu": "x64" }, "sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ=="],
+ "@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="],
+
+ "@scure/bip32": ["@scure/bip32@1.7.0", "", { "dependencies": { "@noble/curves": "~1.9.0", "@noble/hashes": "~1.8.0", "@scure/base": "~1.2.5" } }, "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw=="],
+
+ "@scure/bip39": ["@scure/bip39@1.6.0", "", { "dependencies": { "@noble/hashes": "~1.8.0", "@scure/base": "~1.2.5" } }, "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A=="],
+
+ "@selderee/plugin-htmlparser2": ["@selderee/plugin-htmlparser2@0.11.0", "", { "dependencies": { "domhandler": "^5.0.3", "selderee": "^0.11.0" } }, "sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ=="],
+
+ "@smithy/core": ["@smithy/core@3.33.3", "", { "dependencies": { "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-CsOeKq/9kA3y6VJHt+/+VTCtBaxJ4OTFpgrjIUhPpDIKxBci1k2bJaQASF2h/ELWrulGp+t97DZ0mevfAD8idg=="],
+
+ "@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.5.2", "", { "dependencies": { "@smithy/core": "^3.33.2", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-A9uSdn72ozbRUSit0eib0TW7nXuNPlaeM0zcGkJ+nE6tFcSDbnmtwoxbTCFBukVQcszDAyvsd7+rTduPTXpygg=="],
+
+ "@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.8.0", "", { "dependencies": { "@smithy/core": "^3.33.3", "@smithy/types": "^4.18.0", "tslib": "^2.6.2" } }, "sha512-ycSJu3tFAQ4v04CBB0agqFMVsSQ1iG3yw+SpgxRqKfaURpQD4CZ8Wn0zPMmSnOuTpTh65Vz+EA0rMrw089wvkA=="],
+
+ "@smithy/node-http-handler": ["@smithy/node-http-handler@4.12.1", "", { "dependencies": { "@smithy/core": "^3.33.3", "@smithy/types": "^4.18.0", "tslib": "^2.6.2" } }, "sha512-ThMkboGeONWXAelq9FvGsuJC4rOi+qyC4/zhUF58xYpxUg5sQKx2VXZYJmtNjr4dSuBJ1HeJXETQILCz3wOHvw=="],
+
+ "@smithy/signature-v4": ["@smithy/signature-v4@5.7.3", "", { "dependencies": { "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-7ImGm+FkHRLcBaRttIAMZ6bzJZWb2cJGoYjq46F2UjycujWzrL9GEN9h4w7eQyXJYnltrUhxbbieBAIRrdqpow=="],
+
+ "@smithy/types": ["@smithy/types@4.18.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CgB6HHWer/vrKps24ulRIbpcpb7K4xAU7SkZ7YHzBPlwHsvsrCJFEXK421s+cJzX+ZrqtA/TuU5w1HzI7k9N8A=="],
+
"@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="],
"@standard-schema/utils": ["@standard-schema/utils@0.3.0", "", {}, "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g=="],
@@ -356,6 +531,26 @@
"@tailwindcss/vite": ["@tailwindcss/vite@4.2.2", "", { "dependencies": { "@tailwindcss/node": "4.2.2", "@tailwindcss/oxide": "4.2.2", "tailwindcss": "4.2.2" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7 || ^8" } }, "sha512-mEiF5HO1QqCLXoNEfXVA1Tzo+cYsrqV7w9Juj2wdUFyW07JRenqMG225MvPwr3ZD9N1bFQj46X7r33iHxLUW0w=="],
+ "@tanstack/history": ["@tanstack/history@1.162.2", "", {}, "sha512-Lemp3DJbzNqcin/nZpWxycDaEqySDbnIshDbyHJMMCapD4ZQMe57szRpBXOfzfP6fyWAtHNrLrcBUyANJ6Vlow=="],
+
+ "@tanstack/query-core": ["@tanstack/query-core@5.102.8", "", {}, "sha512-ZNjkJ33CqvPNec/6lZBnHqLc3EVGPZ9ySLhYahU9TcuRFdmwXewuj0c4hwSWcGHqEUwcSrKeZ+oGcvPBqXcQcg=="],
+
+ "@tanstack/query-persist-client-core": ["@tanstack/query-persist-client-core@5.102.8", "", { "dependencies": { "@tanstack/query-core": "5.102.8" } }, "sha512-t3v4/D6ejo/BrPzM5gm/AT3c4CWPCxFa+0cIjAeHAeanGPG6rCjFS1hZnPZH/rf55qe3qYYgx5U6iBZMY1PQjA=="],
+
+ "@tanstack/query-sync-storage-persister": ["@tanstack/query-sync-storage-persister@5.102.8", "", { "dependencies": { "@tanstack/query-core": "5.102.8", "@tanstack/query-persist-client-core": "5.102.8" } }, "sha512-UvIpYl6jipKJHfITAieQaXMvVPoJh2IkQkWDYZNRPycoGbNYdqB+UdRVoXkZagB3EdeKnlC7sA61grsEC87Wfw=="],
+
+ "@tanstack/react-query": ["@tanstack/react-query@5.102.8", "", { "dependencies": { "@tanstack/query-core": "5.102.8" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-TYBea4OuXWD7MhaSHq069TWbFe7rcwWN6kzT7JF0OKi1K6c1gTv2IzD6A6ExJsCMozdkqBWeuIUZmu4KQg0O5A=="],
+
+ "@tanstack/react-query-persist-client": ["@tanstack/react-query-persist-client@5.102.8", "", { "dependencies": { "@tanstack/query-persist-client-core": "5.102.8" }, "peerDependencies": { "@tanstack/react-query": "^5.102.8", "react": "^18 || ^19" } }, "sha512-WOZReC+m9klekPtG7eeZ3txJeMA9lg2R0RytSG3yXcZgJItQAVIyoobJdbdIQtlpgcU2tSzsOEBtJacs2vlCOA=="],
+
+ "@tanstack/react-router": ["@tanstack/react-router@1.170.33", "", { "dependencies": { "@tanstack/history": "1.162.2", "@tanstack/react-store": "^0.9.3", "@tanstack/router-core": "1.171.28", "isbot": "^5.1.22" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-iNnI98vH3kO/V4dy6YM0CInhqwWBddU0G5wZK5jiMvr3HsK2avDQSRx3RY/y6v+6zQAqb2kD6hUPHIenrJBTSw=="],
+
+ "@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=="],
+
+ "@tanstack/router-core": ["@tanstack/router-core@1.171.28", "", { "dependencies": { "@tanstack/history": "1.162.2", "cookie-es": "^3.0.0", "seroval": "^1.6.2", "seroval-plugins": "^1.6.2" } }, "sha512-PvPWSklhw6i9b0rzScVh0btQsK5u/gBYN3mBHyDzhC/U4LrB3WzPXPkUunQUKvQOGXCp16UEb7Htc/ITGm5DkQ=="],
+
+ "@tanstack/store": ["@tanstack/store@0.9.3", "", {}, "sha512-8reSzl/qGWGGVKhBoxXPMWzATSbZLZFWhwBAFO9NAyp0TxzfBP0mIrGb8CP8KrQTmvzXlR/vFPPUrHTLBGyFyw=="],
+
"@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="],
"@types/babel__generator": ["@types/babel__generator@7.27.0", "", { "dependencies": { "@babel/types": "^7.0.0" } }, "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg=="],
@@ -394,12 +589,26 @@
"@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=="],
+ "@wagmi/connectors": ["@wagmi/connectors@8.2.0", "", { "peerDependencies": { "@base-org/account": "^2.5.1", "@coinbase/wallet-sdk": "^4.3.6", "@metamask/connect-evm": "^2.1.0", "@safe-global/safe-apps-provider": "~0.18.6", "@safe-global/safe-apps-sdk": "^9.1.0", "@wagmi/core": "3.6.5", "@walletconnect/ethereum-provider": "^2.21.1", "accounts": "~0.18", "typescript": ">=5.9.3", "viem": "2.x" }, "optionalPeers": ["@base-org/account", "@coinbase/wallet-sdk", "@metamask/connect-evm", "@safe-global/safe-apps-provider", "@safe-global/safe-apps-sdk", "@walletconnect/ethereum-provider", "accounts", "typescript"] }, "sha512-hPwdmePYjQqSWlw9JmzrzVgmw2PJ+NJsUQ/BuPBYbzBS8+cW5vWdqiaKLB4qTF9m+yr+zSp7u91KBgvOWz50og=="],
+
+ "@wagmi/core": ["@wagmi/core@3.6.5", "", { "dependencies": { "eventemitter3": "5.0.1", "mipd": "0.0.7", "zustand": "5.0.0" }, "peerDependencies": { "@tanstack/query-core": ">=5.0.0", "accounts": "~0.18", "typescript": ">=5.9.3", "viem": "2.x" }, "optionalPeers": ["@tanstack/query-core", "accounts", "typescript"] }, "sha512-zfKvLNT1V1+/RgrrUcRvteKx+V+Iv9ZHPWseIVKFA9mX5WE0H8J6zWZGWXSQCKbz5xGSUoatNFCkNFSzqQp+AA=="],
+
+ "abitype": ["abitype@1.2.3", "", { "peerDependencies": { "typescript": ">=5.0.4", "zod": "^3.22.0 || ^4.0.0" }, "optionalPeers": ["typescript", "zod"] }, "sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg=="],
+
+ "atomic-sleep": ["atomic-sleep@1.0.0", "", {}, "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ=="],
+
"axe-core": ["axe-core@4.12.1", "", {}, "sha512-s7iGf5GaVMxEG0ENN9x+xTr7GFZCb1ZP/1uATUpCEK2X78nDB3RwbtFCo9pGAf9ru+VwoQ464DkaLEeRM08wJA=="],
"baseline-browser-mapping": ["baseline-browser-mapping@2.10.16", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-Lyf3aK28zpsD1yQMiiHD4RvVb6UdMoo8xzG2XzFIfR9luPzOpcBlAsT/qfB1XWS1bxWT+UtE4WmQgsp297FYOA=="],
+ "better-auth": ["better-auth@1.7.3", "", { "dependencies": { "@better-auth/core": "1.7.3", "@better-auth/drizzle-adapter": "1.7.3", "@better-auth/kysely-adapter": "1.7.3", "@better-auth/memory-adapter": "1.7.3", "@better-auth/mongo-adapter": "1.7.3", "@better-auth/prisma-adapter": "1.7.3", "@better-auth/telemetry": "1.7.3", "@better-auth/utils": "0.4.2", "@better-fetch/fetch": "1.3.1", "@noble/ciphers": "^2.2.0", "@noble/hashes": "^2.2.0", "better-call": "1.4.0", "defu": "^6.1.4", "jose": "^6.2.3", "kysely": "^0.28.17 || ^0.29.0", "nanostores": "^1.3.0", "zod": "^4.5.4" }, "peerDependencies": { "@lynx-js/react": "*", "@prisma/client": "^5.0.0 || ^6.0.0 || ^7.0.0", "@sveltejs/kit": "^2.0.0", "@tanstack/react-start": "^1.0.0", "@tanstack/solid-start": "^1.0.0", "better-sqlite3": "^12.0.0", "drizzle-kit": ">=0.31.4 || >=1.0.0-beta.1", "drizzle-orm": "^0.45.2 || >=1.0.0-rc.1 <2.0.0", "mongodb": "^6.0.0 || ^7.0.0", "mysql2": "^3.0.0", "next": "^14.0.0 || ^15.0.0 || ^16.0.0", "pg": "^8.0.0", "prisma": "^5.0.0 || ^6.0.0 || ^7.0.0", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0", "solid-js": "^1.0.0", "svelte": "^4.0.0 || ^5.0.0", "vitest": "^2.0.0 || ^3.0.0 || ^4.0.0", "vue": "^3.0.0" }, "optionalPeers": ["@lynx-js/react", "@prisma/client", "@sveltejs/kit", "@tanstack/react-start", "@tanstack/solid-start", "better-sqlite3", "drizzle-kit", "drizzle-orm", "mongodb", "mysql2", "next", "pg", "prisma", "react", "react-dom", "solid-js", "svelte", "vitest", "vue"] }, "sha512-8xGp68JQ+l36kniDEgP8bP99TLi1GdEv0NTEUBkyqnYnus/cgFUZseUfqUHKzr2BAsg2O6aD88I9f0U68shanQ=="],
+
+ "better-call": ["better-call@1.4.0", "", { "dependencies": { "@better-auth/utils": "^0.5.0", "@better-fetch/fetch": "^1.3.1", "rou3": "^0.9.1", "set-cookie-parser": "^3.1.2" }, "peerDependencies": { "zod": "^4.0.0" }, "optionalPeers": ["zod"] }, "sha512-bBKOT4vv1kZLDgxVePdilk/Jwkn+dtRRsmi3DzHcDP+WnswyVl6dR59l2HEeP/0cB+bDoopASAesWDPIdd/zZA=="],
+
"biome-anti-slop": ["biome-anti-slop@0.1.0", "", { "peerDependencies": { "@biomejs/biome": ">=2.5.0" }, "bin": { "biome-anti-slop": "bin/cli.mjs" } }, "sha512-bL0H0n8LGnPH9Gus3SCpF4Q2NEFp6Xe+b6hIOQ1+f8nCvY0FbHCq+5tUpzbDkgdlFr2ZeOObuf3ryQdLu49anA=="],
+ "bowser": ["bowser@2.14.1", "", {}, "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg=="],
+
"browserslist": ["browserslist@4.28.2", "", { "dependencies": { "baseline-browser-mapping": "^2.10.12", "caniuse-lite": "^1.0.30001782", "electron-to-chromium": "^1.5.328", "node-releases": "^2.0.36", "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg=="],
"caniuse-lite": ["caniuse-lite@1.0.30001787", "", {}, "sha512-mNcrMN9KeI68u7muanUpEejSLghOKlVhRqS/Za2IeyGllJ9I9otGpR9g3nsw7n4W378TE/LyIteA0+/FOZm4Kg=="],
@@ -412,6 +621,8 @@
"convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="],
+ "cookie-es": ["cookie-es@3.1.1", "", {}, "sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg=="],
+
"csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
"d3-array": ["d3-array@3.2.4", "", { "dependencies": { "internmap": "1 - 2" } }, "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg=="],
@@ -442,8 +653,22 @@
"decimal.js-light": ["decimal.js-light@2.5.1", "", {}, "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg=="],
+ "deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="],
+
+ "defu": ["defu@6.1.7", "", {}, "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ=="],
+
"detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
+ "dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="],
+
+ "domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="],
+
+ "domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="],
+
+ "domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="],
+
+ "drizzle-orm": ["drizzle-orm@0.45.2", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1.13", "@prisma/client": "*", "@tidbcloud/serverless": "*", "@types/better-sqlite3": "*", "@types/pg": "*", "@types/sql.js": "*", "@upstash/redis": ">=1.34.7", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "better-sqlite3": ">=7", "bun-types": "*", "expo-sqlite": ">=14.0.0", "gel": ">=2", "knex": "*", "kysely": "*", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "sql.js": ">=1", "sqlite3": ">=5" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@prisma/client", "@tidbcloud/serverless", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@upstash/redis", "@vercel/postgres", "@xata.io/client", "better-sqlite3", "bun-types", "expo-sqlite", "gel", "knex", "kysely", "mysql2", "pg", "postgres", "sql.js", "sqlite3"] }, "sha512-kY0BSaTNYWnoDMVoyY8uxmyHjpJW1geOmBMdSSicKo9CIIWkSxMIj2rkeSR51b8KAPB7m+qysjuHme5nKP+E5Q=="],
+
"electron-to-chromium": ["electron-to-chromium@1.5.334", "", {}, "sha512-mgjZAz7Jyx1SRCwEpy9wefDS7GvNPazLthHg8eQMJ76wBdGQQDW33TCrUTvQ4wzpmOrv2zrFoD3oNufMdyMpog=="],
"embla-carousel": ["embla-carousel@8.6.0", "", {}, "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA=="],
@@ -454,6 +679,8 @@
"enhanced-resolve": ["enhanced-resolve@5.20.1", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.0" } }, "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA=="],
+ "entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
+
"es-toolkit": ["es-toolkit@1.45.1", "", {}, "sha512-/jhoOj/Fx+A+IIyDNOvO3TItGmlMKhtX8ISAHKE90c4b/k1tqaqEZ+uUqfpU8DMnW5cgNJv606zS55jGvza0Xw=="],
"esbuild": ["esbuild@0.27.7", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.7", "@esbuild/android-arm": "0.27.7", "@esbuild/android-arm64": "0.27.7", "@esbuild/android-x64": "0.27.7", "@esbuild/darwin-arm64": "0.27.7", "@esbuild/darwin-x64": "0.27.7", "@esbuild/freebsd-arm64": "0.27.7", "@esbuild/freebsd-x64": "0.27.7", "@esbuild/linux-arm": "0.27.7", "@esbuild/linux-arm64": "0.27.7", "@esbuild/linux-ia32": "0.27.7", "@esbuild/linux-loong64": "0.27.7", "@esbuild/linux-mips64el": "0.27.7", "@esbuild/linux-ppc64": "0.27.7", "@esbuild/linux-riscv64": "0.27.7", "@esbuild/linux-s390x": "0.27.7", "@esbuild/linux-x64": "0.27.7", "@esbuild/netbsd-arm64": "0.27.7", "@esbuild/netbsd-x64": "0.27.7", "@esbuild/openbsd-arm64": "0.27.7", "@esbuild/openbsd-x64": "0.27.7", "@esbuild/openharmony-arm64": "0.27.7", "@esbuild/sunos-x64": "0.27.7", "@esbuild/win32-arm64": "0.27.7", "@esbuild/win32-ia32": "0.27.7", "@esbuild/win32-x64": "0.27.7" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w=="],
@@ -474,20 +701,38 @@
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
+ "hono": ["hono@4.13.7", "", {}, "sha512-c8/gF9ac8Y78/agExVocyLevgR+JlpNB444Py0FSX8pJoPdYUfUzRcXtYEYGwt6l19qIlVZPN5Mfsw9jFShmQQ=="],
+
+ "html-to-text": ["html-to-text@9.0.5", "", { "dependencies": { "@selderee/plugin-htmlparser2": "^0.11.0", "deepmerge": "^4.3.1", "dom-serializer": "^2.0.0", "htmlparser2": "^8.0.2", "selderee": "^0.11.0" } }, "sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg=="],
+
+ "html5parser": ["html5parser@3.0.0", "", {}, "sha512-iNpSopa+4YHX50UOk825tBy7MghmXHo/ZpLskBYN0kAr1xhH8GlIMk5bLRXcZlfP3AnLUcSuFMu8C4MdOUxA8A=="],
+
+ "htmlparser2": ["htmlparser2@8.0.2", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.0.1", "entities": "^4.4.0" } }, "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA=="],
+
"immer": ["immer@10.2.0", "", {}, "sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw=="],
"input-otp": ["input-otp@1.4.2", "", { "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-l3jWwYNvrEa6NTCt7BECfCm48GvwuZzkoeG3gBL2w4CHeOXW3eKFmf9UNYkNfYc3mxMrthMnxjIE07MT0zLBQA=="],
"internmap": ["internmap@2.0.3", "", {}, "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="],
+ "isbot": ["isbot@5.2.2", "", {}, "sha512-iQcBXcd+Rv/pkubRyGh2utW2j1oPG5hZY6TUhVPpqK4G+o3IbxpJNx04hgksjc/N7GK5pEorUxDeg31cFgEk/w=="],
+
+ "isows": ["isows@1.0.7", "", { "peerDependencies": { "ws": "*" } }, "sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg=="],
+
"jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="],
+ "jose": ["jose@6.2.12", "", {}, "sha512-9NiFmJEex0sy2Dk58j2UGBSHgUs2ypF9eZSu4L6vjOX3Dp96Sw1F3uL+H+D1sx02jZZdzUT0HgvCy59CuvXcWw=="],
+
"js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
"jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="],
"json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="],
+ "kysely": ["kysely@0.29.5", "", {}, "sha512-ooa+eSbBNPTo3MycPEuW5jdrxQdQwdtB3LC3h43FiXQbIry5tR0C5lDG7eealK0E4D7XjrnOP5DIUg/LyjRMYQ=="],
+
+ "leac": ["leac@0.6.0", "", {}, "sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg=="],
+
"lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="],
"lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="],
@@ -518,6 +763,10 @@
"magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
+ "marked": ["marked@15.0.12", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA=="],
+
+ "mipd": ["mipd@0.0.7", "", { "peerDependencies": { "typescript": ">=5.0.4" }, "optionalPeers": ["typescript"] }, "sha512-aAPZPNDQ3uMTdKbuO2YmAw2TxLHO0moa4YKAyETM/DTj5FloZo+a+8tU+iv4GmW+sOxKLSRwcSFuczk+Cpt6fg=="],
+
"motion": ["motion@12.38.0", "", { "dependencies": { "framer-motion": "^12.38.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-uYfXzeHlgThchzwz5Te47dlv5JOUC7OB4rjJ/7XTUgtBZD8CchMN8qEJ4ZVsUmTyYA44zjV0fBwsiktRuFnn+w=="],
"motion-dom": ["motion-dom@12.38.0", "", { "dependencies": { "motion-utils": "^12.36.0" } }, "sha512-pdkHLD8QYRp8VfiNLb8xIBJis1byQ9gPT3Jnh2jqfFtAsWUA3dEepDlsWe/xMpO8McV+VdpKVcp+E+TGJEtOoA=="],
@@ -528,26 +777,54 @@
"nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
+ "nanostores": ["nanostores@1.5.3", "", {}, "sha512-rQLB6eV4f2AW/n3L0JmwCROpaisYy9EDEADvEFSd1C/qG8hB6O5TPlh9A791JRbJr4CnMQBzptDcvD9OR1+6WA=="],
+
"next": ["next@16.2.3", "", { "dependencies": { "@next/env": "16.2.3", "@swc/helpers": "0.5.15", "baseline-browser-mapping": "^2.9.19", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.2.3", "@next/swc-darwin-x64": "16.2.3", "@next/swc-linux-arm64-gnu": "16.2.3", "@next/swc-linux-arm64-musl": "16.2.3", "@next/swc-linux-x64-gnu": "16.2.3", "@next/swc-linux-x64-musl": "16.2.3", "@next/swc-win32-arm64-msvc": "16.2.3", "@next/swc-win32-x64-msvc": "16.2.3", "sharp": "^0.34.5" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-9V3zV4oZFza3PVev5/poB9g0dEafVcgNyQ8eTRop8GvxZjV2G15FC5ARuG1eFD42QgeYkzJBJzHghNP8Ad9xtA=="],
"node-releases": ["node-releases@2.0.37", "", {}, "sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg=="],
+ "on-exit-leak-free": ["on-exit-leak-free@2.1.2", "", {}, "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA=="],
+
+ "ox": ["ox@0.14.7", "", { "dependencies": { "@adraffy/ens-normalize": "^1.11.0", "@noble/ciphers": "^1.3.0", "@noble/curves": "1.9.1", "@noble/hashes": "^1.8.0", "@scure/bip32": "^1.7.0", "@scure/bip39": "^1.6.0", "abitype": "^1.2.3", "eventemitter3": "5.0.1" }, "peerDependencies": { "typescript": ">=5.4.0" }, "optionalPeers": ["typescript"] }, "sha512-zSQ/cfBdolj7U4++NAvH7sI+VG0T3pEohITCgcQj8KlawvTDY4vGVhDT64Atsm0d6adWfIYHDpu88iUBMMp+AQ=="],
+
+ "parseley": ["parseley@0.12.1", "", { "dependencies": { "leac": "^0.6.0", "peberminta": "^0.9.0" } }, "sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw=="],
+
+ "peberminta": ["peberminta@0.9.0", "", {}, "sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ=="],
+
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
"picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="],
+ "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=="],
+
+ "pino-std-serializers": ["pino-std-serializers@7.1.0", "", {}, "sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw=="],
+
"playwright": ["playwright@1.62.1", "", { "dependencies": { "playwright-core": "1.62.1" }, "optionalDependencies": { "fsevents": "2.3.2" }, "bin": { "playwright": "cli.js" } }, "sha512-0M+L3LAD8/nm554LOla9Ayx0j0tmFZ0FBcoQ7F1VuVHpM/XpiC8RcDzBQB8W5+hA8L22THxELzeF+2WcUzvcLg=="],
"playwright-core": ["playwright-core@1.62.1", "", { "bin": { "playwright-core": "cli.js" } }, "sha512-wPYSwEBJY9GHraISXqyqtx0na0LpO3XEX7jNDhntbex7tzUS7kLnZsOlFruFJB4Hi/rhDMjXGqHewDZ68nYZVw=="],
"postcss": ["postcss@8.5.9", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw=="],
+ "postgres": ["postgres@3.4.9", "", {}, "sha512-GD3qdB0x1z9xgFI6cdRD6xu2Sp2WCOEoe3mtnyB5Ee0XrrL5Pe+e4CCnJrRMnL1zYtRDZmQQVbvOttLnKDLnaw=="],
+
+ "prettier": ["prettier@3.9.6", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g=="],
+
+ "prismjs": ["prismjs@1.30.0", "", {}, "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="],
+
+ "process-warning": ["process-warning@5.1.0", "", {}, "sha512-jQSaVHsPgtyw60e1rQ/A+/ArPEj/S8pS/vFnyGa/gYFXrKk/6RuDkoqVDQ5NI5MmS01698ltlAk0NoDBNLujRw=="],
+
+ "quick-format-unescaped": ["quick-format-unescaped@4.0.4", "", {}, "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg=="],
+
"react": ["react@19.2.5", "", {}, "sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA=="],
"react-dom": ["react-dom@19.2.5", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.5" } }, "sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag=="],
"react-hook-form": ["react-hook-form@7.72.1", "", { "peerDependencies": { "react": "^16.8.0 || ^17 || ^18 || ^19" } }, "sha512-RhwBoy2ygeVZje+C+bwJ8g0NjTdBmDlJvAUHTxRjTmSUKPYsKfMphkS2sgEMotsY03bP358yEYlnUeZy//D9Ig=="],
+ "react-intersection-observer": ["react-intersection-observer@10.1.0", "", { "peerDependencies": { "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["react-dom"] }, "sha512-V8HDu3+Llg6OEhOxx8LnUSS0t4VS+1Xk9ZatkI8Jct/H0CwKnqFTCu8NT3q7ghJTghTdIrEMPSWr2dkKPG+gdQ=="],
+
"react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
"react-redux": ["react-redux@9.2.0", "", { "dependencies": { "@types/use-sync-external-store": "^0.0.6", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { "@types/react": "^18.2.25 || ^19", "react": "^18.0 || ^19", "redux": "^5.0.0" }, "optionalPeers": ["@types/react", "redux"] }, "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g=="],
@@ -556,6 +833,8 @@
"react-resizable-panels": ["react-resizable-panels@4.9.0", "", { "peerDependencies": { "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" } }, "sha512-sEl+hA6y9/kxa0aPlrUC+G1lcShAf/PiIjoeC8kWXxa53RfAVplVCIxEl01Nwa4L2iRa5JXBXq1/mI8ch6qOZQ=="],
+ "real-require": ["real-require@0.2.0", "", {}, "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg=="],
+
"recharts": ["recharts@3.8.0", "", { "dependencies": { "@reduxjs/toolkit": "^1.9.0 || 2.x.x", "clsx": "^2.1.1", "decimal.js-light": "^2.5.1", "es-toolkit": "^1.39.3", "eventemitter3": "^5.0.1", "immer": "^10.1.1", "react-redux": "8.x.x || 9.x.x", "reselect": "5.1.1", "tiny-invariant": "^1.3.3", "use-sync-external-store": "^1.2.2", "victory-vendor": "^37.0.2" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-is": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Z/m38DX3L73ExO4Tpc9/iZWHmHnlzWG4njQbxsF5aSjwqmHNDDIm0rdEBArkwsBvR8U6EirlEHiQNYWCVh9sGQ=="],
"redux": ["redux@5.0.1", "", {}, "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w=="],
@@ -566,14 +845,30 @@
"rollup": ["rollup@4.60.1", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.60.1", "@rollup/rollup-android-arm64": "4.60.1", "@rollup/rollup-darwin-arm64": "4.60.1", "@rollup/rollup-darwin-x64": "4.60.1", "@rollup/rollup-freebsd-arm64": "4.60.1", "@rollup/rollup-freebsd-x64": "4.60.1", "@rollup/rollup-linux-arm-gnueabihf": "4.60.1", "@rollup/rollup-linux-arm-musleabihf": "4.60.1", "@rollup/rollup-linux-arm64-gnu": "4.60.1", "@rollup/rollup-linux-arm64-musl": "4.60.1", "@rollup/rollup-linux-loong64-gnu": "4.60.1", "@rollup/rollup-linux-loong64-musl": "4.60.1", "@rollup/rollup-linux-ppc64-gnu": "4.60.1", "@rollup/rollup-linux-ppc64-musl": "4.60.1", "@rollup/rollup-linux-riscv64-gnu": "4.60.1", "@rollup/rollup-linux-riscv64-musl": "4.60.1", "@rollup/rollup-linux-s390x-gnu": "4.60.1", "@rollup/rollup-linux-x64-gnu": "4.60.1", "@rollup/rollup-linux-x64-musl": "4.60.1", "@rollup/rollup-openbsd-x64": "4.60.1", "@rollup/rollup-openharmony-arm64": "4.60.1", "@rollup/rollup-win32-arm64-msvc": "4.60.1", "@rollup/rollup-win32-ia32-msvc": "4.60.1", "@rollup/rollup-win32-x64-gnu": "4.60.1", "@rollup/rollup-win32-x64-msvc": "4.60.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w=="],
+ "rou3": ["rou3@0.9.2", "", {}, "sha512-3SOzvaAg8rkHrXtRjpCvCvbyO5to9oOO27Z/XqHEYXfMRVSw/qMIVdmaOk9W2lcRLtR6dlqTjo9hDeJk70QBYQ=="],
+
+ "safe-stable-stringify": ["safe-stable-stringify@2.5.0", "", {}, "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA=="],
+
"scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
- "semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
+ "selderee": ["selderee@0.11.0", "", { "dependencies": { "parseley": "^0.12.0" } }, "sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA=="],
+
+ "semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="],
+
+ "seroval": ["seroval@1.6.7", "", {}, "sha512-AeDcLh0yO2SFm9W71essgnSzLV9DI8ZH0x0knXn2DMnUZj728mpLbxjlbB6IqKCmqh8JA3cEqRyGoNkt584JcQ=="],
+
+ "seroval-plugins": ["seroval-plugins@1.6.7", "", { "peerDependencies": { "seroval": "^1.0" } }, "sha512-4Nk35ttD3DTDJW4hgw5StsVAPeU6qnDFnULAouw6tQ7oLTV/ICXrWpsXo2EE52eSP2joUMazbVf52mFEcADqRw=="],
- "sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="],
+ "set-cookie-parser": ["set-cookie-parser@3.1.2", "", {}, "sha512-5/r/lTwbJ3zQ+qwdUFZYeRNqda7P5HD8zQKqlSjdGt1/S0cjLAphHusj4Y58ahDtWn/g32xrIS58/ikOvwl0Lw=="],
+
+ "sharp": ["sharp@0.35.4", "", { "dependencies": { "@img/colour": "^1.1.0", "detect-libc": "^2.1.2", "semver": "^7.8.5" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.35.4", "@img/sharp-darwin-x64": "0.35.4", "@img/sharp-freebsd-wasm32": "0.35.4", "@img/sharp-libvips-darwin-arm64": "1.3.3", "@img/sharp-libvips-darwin-x64": "1.3.3", "@img/sharp-libvips-linux-arm": "1.3.3", "@img/sharp-libvips-linux-arm64": "1.3.3", "@img/sharp-libvips-linux-ppc64": "1.3.3", "@img/sharp-libvips-linux-riscv64": "1.3.3", "@img/sharp-libvips-linux-s390x": "1.3.3", "@img/sharp-libvips-linux-x64": "1.3.3", "@img/sharp-libvips-linuxmusl-arm64": "1.3.3", "@img/sharp-libvips-linuxmusl-x64": "1.3.3", "@img/sharp-linux-arm": "0.35.4", "@img/sharp-linux-arm64": "0.35.4", "@img/sharp-linux-ppc64": "0.35.4", "@img/sharp-linux-riscv64": "0.35.4", "@img/sharp-linux-s390x": "0.35.4", "@img/sharp-linux-x64": "0.35.4", "@img/sharp-linuxmusl-arm64": "0.35.4", "@img/sharp-linuxmusl-x64": "0.35.4", "@img/sharp-webcontainers-wasm32": "0.35.4", "@img/sharp-win32-arm64": "0.35.4", "@img/sharp-win32-ia32": "0.35.4", "@img/sharp-win32-x64": "0.35.4" } }, "sha512-n++8XWcj+jCOr2IOl7h8LbKnGBDY4aPbmprMONBNFdn0ImXqpGVv5zliDs0V9HbmbCQLpbuo2ej9rAoOQTvMDA=="],
+
+ "sonic-boom": ["sonic-boom@4.2.1", "", { "dependencies": { "atomic-sleep": "^1.0.0" } }, "sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q=="],
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
+ "split2": ["split2@4.2.0", "", {}, "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg=="],
+
"styled-jsx": ["styled-jsx@5.1.6", "", { "dependencies": { "client-only": "0.0.1" }, "peerDependencies": { "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" } }, "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA=="],
"tabbable": ["tabbable@6.4.0", "", {}, "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg=="],
@@ -584,6 +879,10 @@
"tapable": ["tapable@2.3.2", "", {}, "sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA=="],
+ "tempo.ts": ["tempo.ts@0.14.2", "", { "dependencies": { "@remix-run/fetch-router": "~0.17.0", "ox": "~0.14.0" }, "peerDependencies": { "viem": ">=2.43.3" }, "optionalPeers": ["viem"] }, "sha512-N4UkP2X/KDLmYUEIEWUDAk1m/USbKMzTjjUz1m0LwrIEVfoDlcSbBRc9jp14gLZcJVDlnq+fWHFVcH+GdrySgQ=="],
+
+ "thread-stream": ["thread-stream@4.2.0", "", { "dependencies": { "real-require": "^1.0.0" } }, "sha512-e2zZ96wSChazBsbENf/Pcm/4swHt2cEKQ92rhUjkL9GCKiTDJIaTBenjE/m9DXi0QBmTMDkFDdOomUy20A1tDQ=="],
+
"tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="],
"tinyglobby": ["tinyglobby@0.2.16", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg=="],
@@ -602,14 +901,60 @@
"victory-vendor": ["victory-vendor@37.3.6", "", { "dependencies": { "@types/d3-array": "^3.0.3", "@types/d3-ease": "^3.0.0", "@types/d3-interpolate": "^3.0.1", "@types/d3-scale": "^4.0.2", "@types/d3-shape": "^3.1.0", "@types/d3-time": "^3.0.0", "@types/d3-timer": "^3.0.0", "d3-array": "^3.1.6", "d3-ease": "^3.0.1", "d3-interpolate": "^3.0.1", "d3-scale": "^4.0.2", "d3-shape": "^3.1.0", "d3-time": "^3.0.0", "d3-timer": "^3.0.1" } }, "sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ=="],
+ "viem": ["viem@2.47.10", "", { "dependencies": { "@noble/curves": "1.9.1", "@noble/hashes": "1.8.0", "@scure/bip32": "1.7.0", "@scure/bip39": "1.6.0", "abitype": "1.2.3", "isows": "1.0.7", "ox": "0.14.7", "ws": "8.18.3" }, "peerDependencies": { "typescript": ">=5.0.4" }, "optionalPeers": ["typescript"] }, "sha512-D+l6SDDZWB5bh8u9hgICzMX2/egMrgEQ+Pef/QkZgmOl6bOTyCQMSgWAH8jZTWJ/218J9QNv7s/9BH6Wu5oPDg=="],
+
"vite": ["vite@7.3.2", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg=="],
+ "wagmi": ["wagmi@3.7.7", "", { "dependencies": { "@wagmi/connectors": "8.2.0", "@wagmi/core": "3.6.5", "use-sync-external-store": "1.4.0" }, "peerDependencies": { "@tanstack/react-query": ">=5.0.0", "react": ">=18", "typescript": ">=5.9.3", "viem": "2.x" }, "optionalPeers": ["typescript"] }, "sha512-J9YTRKwOVt+L135nMiitwGALrJqpXFhLX8AZzbECWeAQ1aI9Uz8Pz0GGMqtbKe7xJtmOx838OChT7YkMs9k8OA=="],
+
+ "ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="],
+
"yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
"zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="],
+ "zustand": ["zustand@5.0.15", "", { "peerDependencies": { "@types/react": ">=18.0.0", "immer": ">=9.0.6", "react": ">=18.0.0", "use-sync-external-store": ">=1.2.0" }, "optionalPeers": ["@types/react", "immer", "react", "use-sync-external-store"] }, "sha512-MpSEjRiBkA9crSYeOUH32rJC7SVqAbm0Fqcqge/bUi2PPoLcBWKOsG+C8mevmpr8TwXHBVkChbbJiyvkE+i/3A=="],
+
+ "@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
+
+ "@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
+
+ "@better-auth/core/zod": ["zod@4.5.4", "", {}, "sha512-sC95tT5iHHH9gtpj6A81kh+NEaRAUFN+qlUPDUbRfOMvNf5QCBqsb3WgvnpVtK5Y+4UfA6KqufotuTvMGiTlsA=="],
+
+ "@flow-industries/id/lucide-react": ["lucide-react@0.563.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-8dXPB2GI4dI8jV4MgUDGBeLdGk8ekfqVZ0BdLcrRzocGgG75ltNEmWS+gE7uokKF/0oSUuczNDT+g9hFJ23FkA=="],
+
+ "@flow-industries/ui/zod": ["zod@4.5.4", "", {}, "sha512-sC95tT5iHHH9gtpj6A81kh+NEaRAUFN+qlUPDUbRfOMvNf5QCBqsb3WgvnpVtK5Y+4UfA6KqufotuTvMGiTlsA=="],
+
+ "@noble/curves/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="],
+
+ "@opentelemetry/exporter-trace-otlp-http/@opentelemetry/resources": ["@opentelemetry/resources@2.7.1", "", { "dependencies": { "@opentelemetry/core": "2.7.1", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-DeT6KKolmC4e/dRQvMQ/RwlnzhaqeiFOXY5ngoOPJ07GgVVKxZOg9EcrNZb5aTzUn+iCrJldAgOfQm1O/QfPAQ=="],
+
+ "@opentelemetry/exporter-trace-otlp-http/@opentelemetry/sdk-trace-base": ["@opentelemetry/sdk-trace-base@2.7.1", "", { "dependencies": { "@opentelemetry/core": "2.7.1", "@opentelemetry/resources": "2.7.1", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-NAYIlsF8MPUsKqJMiDQJTMPOmlbawC1Iz/omMLygZ1C9am8fTKYjTaI+OZM+WTY3t3Glo0wnOg/6/pac6RGPPw=="],
+
+ "@opentelemetry/otlp-transformer/@opentelemetry/resources": ["@opentelemetry/resources@2.7.1", "", { "dependencies": { "@opentelemetry/core": "2.7.1", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-DeT6KKolmC4e/dRQvMQ/RwlnzhaqeiFOXY5ngoOPJ07GgVVKxZOg9EcrNZb5aTzUn+iCrJldAgOfQm1O/QfPAQ=="],
+
+ "@opentelemetry/otlp-transformer/@opentelemetry/sdk-trace-base": ["@opentelemetry/sdk-trace-base@2.7.1", "", { "dependencies": { "@opentelemetry/core": "2.7.1", "@opentelemetry/resources": "2.7.1", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-NAYIlsF8MPUsKqJMiDQJTMPOmlbawC1Iz/omMLygZ1C9am8fTKYjTaI+OZM+WTY3t3Glo0wnOg/6/pac6RGPPw=="],
+
+ "@opentelemetry/resources/@opentelemetry/core": ["@opentelemetry/core@2.11.0", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-7YP44XH0tV6+Mb54x2YGf84i7yi+31MBZlE8JwvozkxyTvXbSp10X7cI7YE49ChJ3shMJoBmCJF3+1QFBJctGA=="],
+
+ "@opentelemetry/sdk-logs/@opentelemetry/resources": ["@opentelemetry/resources@2.7.1", "", { "dependencies": { "@opentelemetry/core": "2.7.1", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-DeT6KKolmC4e/dRQvMQ/RwlnzhaqeiFOXY5ngoOPJ07GgVVKxZOg9EcrNZb5aTzUn+iCrJldAgOfQm1O/QfPAQ=="],
+
+ "@opentelemetry/sdk-metrics/@opentelemetry/resources": ["@opentelemetry/resources@2.7.1", "", { "dependencies": { "@opentelemetry/core": "2.7.1", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-DeT6KKolmC4e/dRQvMQ/RwlnzhaqeiFOXY5ngoOPJ07GgVVKxZOg9EcrNZb5aTzUn+iCrJldAgOfQm1O/QfPAQ=="],
+
+ "@opentelemetry/sdk-trace/@opentelemetry/core": ["@opentelemetry/core@2.11.0", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-7YP44XH0tV6+Mb54x2YGf84i7yi+31MBZlE8JwvozkxyTvXbSp10X7cI7YE49ChJ3shMJoBmCJF3+1QFBJctGA=="],
+
+ "@opentelemetry/sdk-trace-base/@opentelemetry/core": ["@opentelemetry/core@2.11.0", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-7YP44XH0tV6+Mb54x2YGf84i7yi+31MBZlE8JwvozkxyTvXbSp10X7cI7YE49ChJ3shMJoBmCJF3+1QFBJctGA=="],
+
+ "@opentelemetry/sdk-trace-node/@opentelemetry/core": ["@opentelemetry/core@2.11.0", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-7YP44XH0tV6+Mb54x2YGf84i7yi+31MBZlE8JwvozkxyTvXbSp10X7cI7YE49ChJ3shMJoBmCJF3+1QFBJctGA=="],
+
+ "@react-email/components/@react-email/render": ["@react-email/render@2.0.6", "", { "dependencies": { "html-to-text": "^9.0.5", "prettier": "^3.5.3" }, "peerDependencies": { "react": "^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-xOzaYkH3jLZKqN5MqrTXYnmqBYUnZSVbkxdb5PGGmDcK6sKDVMliaDiSwfXajRC9JtSHTcGc2tmGLHWuCgVpog=="],
+
"@reduxjs/toolkit/immer": ["immer@11.1.4", "", {}, "sha512-XREFCPo6ksxVzP4E0ekD5aMdf8WMwmdNaz6vuvxgI40UaEiu6q3p8X52aU6GdyvLY3XXX/8R7JOTXStz/nBbRw=="],
+ "@scure/bip32/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="],
+
+ "@scure/bip39/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="],
+
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.9.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" }, "bundled": true }, "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA=="],
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.9.2", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw=="],
@@ -622,10 +967,82 @@
"@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
+ "@wagmi/core/eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="],
+
+ "@wagmi/core/zustand": ["zustand@5.0.0", "", { "peerDependencies": { "@types/react": ">=18.0.0", "immer": ">=9.0.6", "react": ">=18.0.0", "use-sync-external-store": ">=1.2.0" }, "optionalPeers": ["@types/react", "immer", "react", "use-sync-external-store"] }, "sha512-LE+VcmbartOPM+auOjCCLQOsQ05zUTp8RkgwRzefUk+2jISdMMFnxvyTjA4YNWr5ZGXYbVsEMZosttuxUBkojQ=="],
+
+ "better-auth/zod": ["zod@4.5.4", "", {}, "sha512-sC95tT5iHHH9gtpj6A81kh+NEaRAUFN+qlUPDUbRfOMvNf5QCBqsb3WgvnpVtK5Y+4UfA6KqufotuTvMGiTlsA=="],
+
+ "better-call/@better-auth/utils": ["@better-auth/utils@0.5.0", "", { "dependencies": { "@noble/hashes": "^2.0.1" } }, "sha512-BL8W4EfIZFwlu0r54m3v1ztjDhu6dDe/amLTm0xybmbZaNgYUqhD3SjpAsnq0q8YD6/ki4iwIgxJNLP/N3TxiA=="],
+
"next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
+ "next/sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="],
+
+ "ox/@noble/ciphers": ["@noble/ciphers@1.3.0", "", {}, "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw=="],
+
+ "ox/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="],
+
+ "ox/eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="],
+
"playwright/fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="],
- "sharp/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
+ "thread-stream/real-require": ["real-require@1.0.0", "", {}, "sha512-P4nbQYQfePJxRSmY+v/KINxVucm4NF3p3s7pJveMTtom52FR4YGltUQLB8idDXwDDWW+eYrWDFbuzUnjoWHF7g=="],
+
+ "viem/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="],
+
+ "wagmi/use-sync-external-store": ["use-sync-external-store@1.4.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw=="],
+
+ "next/sharp/@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w=="],
+
+ "next/sharp/@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.4" }, "os": "darwin", "cpu": "x64" }, "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw=="],
+
+ "next/sharp/@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g=="],
+
+ "next/sharp/@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg=="],
+
+ "next/sharp/@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.4", "", { "os": "linux", "cpu": "arm" }, "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A=="],
+
+ "next/sharp/@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw=="],
+
+ "next/sharp/@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA=="],
+
+ "next/sharp/@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.2.4", "", { "os": "linux", "cpu": "none" }, "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA=="],
+
+ "next/sharp/@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ=="],
+
+ "next/sharp/@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw=="],
+
+ "next/sharp/@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw=="],
+
+ "next/sharp/@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg=="],
+
+ "next/sharp/@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.4" }, "os": "linux", "cpu": "arm" }, "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw=="],
+
+ "next/sharp/@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg=="],
+
+ "next/sharp/@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.4" }, "os": "linux", "cpu": "ppc64" }, "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA=="],
+
+ "next/sharp/@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.2.4" }, "os": "linux", "cpu": "none" }, "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw=="],
+
+ "next/sharp/@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.4" }, "os": "linux", "cpu": "s390x" }, "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg=="],
+
+ "next/sharp/@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ=="],
+
+ "next/sharp/@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg=="],
+
+ "next/sharp/@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q=="],
+
+ "next/sharp/@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.5", "", { "dependencies": { "@emnapi/runtime": "^1.7.0" }, "cpu": "none" }, "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw=="],
+
+ "next/sharp/@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g=="],
+
+ "next/sharp/@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg=="],
+
+ "next/sharp/@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="],
+
+ "next/sharp/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
+
+ "next/sharp/@img/sharp-wasm32/@emnapi/runtime": ["@emnapi/runtime@1.9.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw=="],
}
}
diff --git a/package.json b/package.json
index ef13f67..25c39e8 100644
--- a/package.json
+++ b/package.json
@@ -30,12 +30,14 @@
"./icons": "./src/components/icons.tsx",
"./styles/tokens.css": "./src/styles/tokens.css",
"./styles/base.css": "./src/styles/base.css",
- "./styles/fonts.css": "./src/styles/fonts.css"
+ "./styles/fonts.css": "./src/styles/fonts.css",
+ "./focus": "./src/focus/index.ts"
},
"peerDependencies": {
"react": ">=19.0.0",
"react-dom": ">=19.0.0",
- "tailwindcss": ">=4.0.0"
+ "tailwindcss": ">=4.0.0",
+ "@flow-industries/id": ">=0.22.0"
},
"dependencies": {
"@base-ui/react": "^1.3.0",
@@ -72,6 +74,12 @@
"react-dom": "^19.2.3",
"tailwindcss": "^4.1.18",
"typescript": "~5.9.3",
- "vite": "^7.2.7"
+ "vite": "^7.2.7",
+ "@flow-industries/id": "0.22.0"
+ },
+ "peerDependenciesMeta": {
+ "@flow-industries/id": {
+ "optional": true
+ }
}
}
diff --git a/src/focus/index.ts b/src/focus/index.ts
new file mode 100644
index 0000000..d86d620
--- /dev/null
+++ b/src/focus/index.ts
@@ -0,0 +1,4 @@
+export * from "./panel";
+export * from "./provider";
+export * from "./study-subject-picker";
+export * from "./text";
diff --git a/src/focus/panel.tsx b/src/focus/panel.tsx
new file mode 100644
index 0000000..c9b884c
--- /dev/null
+++ b/src/focus/panel.tsx
@@ -0,0 +1,506 @@
+import {
+ type ActionCatalogEntry,
+ type ActiveAction,
+ actionHeadline,
+ estimateActionXp,
+ flowMultiplier,
+ formatElapsed,
+ STUDY_SOURCE,
+} from "@flow-industries/id/focus";
+import { ChevronLeft, Pause, Play, Repeat, Square } from "lucide-react";
+import {
+ createContext,
+ type ReactNode,
+ useContext,
+ useEffect,
+ useState,
+} from "react";
+import { Button } from "../components/ui/button";
+import { cn } from "../utils/cn";
+import {
+ type FocusContextValue,
+ type StartFocusOptions,
+ useFocusElapsed,
+} from "./provider";
+import { StudySubjectPicker } from "./study-subject-picker";
+import { type FocusText, FocusTextProvider, useFocusText } from "./text";
+
+type Picking = { step: "actions" | "study"; replace: boolean };
+
+export function catalogEntryFor(
+ catalog: ActionCatalogEntry[] | null,
+ source: string,
+): ActionCatalogEntry | null {
+ return catalog?.find((entry) => entry.id === source) ?? null;
+}
+
+export interface FocusPanelProps {
+ focus: FocusContextValue;
+ text?: FocusText;
+ surface?: "game" | "talk" | "web";
+ managementLink?: ReactNode;
+ className?: string;
+}
+const PanelContext = createContext(null);
+function usePanel(): FocusPanelProps {
+ const panel = useContext(PanelContext);
+ if (!panel) throw new Error("FocusPanel context missing");
+ return panel;
+}
+function usePanelFocus(): FocusContextValue {
+ return usePanel().focus;
+}
+export function FocusPanel(props: FocusPanelProps): ReactNode {
+ return (
+
+
+
+
+
+ );
+}
+
+interface PanelProps {
+ className?: string;
+}
+
+function Panel({ className }: PanelProps): ReactNode {
+ const focus = usePanelFocus();
+ const { managementLink } = usePanel();
+ const { state } = focus;
+ const [picking, setPicking] = useState(null);
+ const panel = (view: string, body: ReactNode) => (
+
+ {body}
+ {managementLink}
+
+ );
+
+ if (state.finished) return panel("finished", );
+ if (state.conflict && focus.pendingStart) {
+ return panel(
+ "conflict",
+ ,
+ );
+ }
+ if (state.active && !picking) {
+ return panel(
+ "running",
+ setPicking({ step: "actions", replace: true })}
+ />,
+ );
+ }
+ const replace = picking?.replace ?? false;
+ if (picking?.step === "study") {
+ return panel(
+ "study",
+ setPicking({ step: "actions", replace })}
+ onStarted={() => setPicking(null)}
+ />,
+ );
+ }
+ return panel(
+ "picker",
+ setPicking({ step: "study", replace })}
+ onStarted={() => setPicking(null)}
+ onBack={state.active ? () => setPicking(null) : undefined}
+ />,
+ );
+}
+
+const PANEL = "flex min-h-0 flex-col gap-3 p-3 text-sm";
+
+function FailureNote(): ReactNode {
+ const { state } = usePanelFocus();
+ const { t } = useFocusText();
+ if (!state.failed) return null;
+ return (
+
+ {t("focus.failed")}
+
+ );
+}
+
+interface PickerViewProps {
+ replace: boolean;
+ onStudy: () => void;
+ onStarted: () => void;
+ onBack?: () => void;
+}
+
+function PickerView({
+ replace,
+ onStudy,
+ onStarted,
+ onBack,
+}: PickerViewProps): ReactNode {
+ const focus = usePanelFocus();
+ const { catalog, catalogFailed, state } = focus;
+ const { t } = useFocusText();
+ const running = state.active;
+
+ const startPlain = async (entry: ActionCatalogEntry) => {
+ const outcome = await focus.start({ source: entry.id, replace });
+ if (outcome !== "failed") onStarted();
+ };
+
+ return (
+ <>
+
+ {onBack ? (
+
+ ) : null}
+
+
{t("focus.pickerTitle")}
+
+ {replace && running
+ ? t("focus.switchNote", {
+ action: actionHeadline(running, t("focus.title")),
+ })
+ : t("focus.description")}
+
+
+
+ {catalog === null ? (
+
+ {catalogFailed ? t("focus.catalogFailed") : t("focus.catalogLoading")}
+
+ ) : (
+
+ {catalog
+ .filter(
+ (entry) => entry.id !== running?.source || entry.requiresSubject,
+ )
+ .map((entry) => (
+ -
+
+
{entry.label}
+
+ {entry.description}
+
+
+
+
+ ))}
+
+ )}
+ {state.phase === "unknown" ? (
+
+ {t("focus.sessionLoading")}
+
+ ) : null}
+
+ >
+ );
+}
+
+interface StudyStepProps {
+ replace: boolean;
+ onBack: () => void;
+ onStarted: () => void;
+}
+
+function StudyStep({ replace, onBack, onStarted }: StudyStepProps): ReactNode {
+ const focus = usePanelFocus();
+ const text = useFocusText();
+ const { t } = text;
+ const [createFailed, setCreateFailed] = useState(false);
+ const [creating, setCreating] = useState(false);
+ const [todaySeconds, setTodaySeconds] = useState<
+ Record | undefined
+ >(undefined);
+ useEffect(() => {
+ focus.loadStudy();
+ }, [focus.loadStudy]);
+
+ const { api } = focus;
+ useEffect(() => {
+ setTodaySeconds(undefined);
+ if (!api || !focus.enabled) return;
+ let current = true;
+ void api
+ .summary("today")
+ .then((summary) => {
+ if (!current) return;
+ setTodaySeconds(
+ Object.fromEntries(
+ summary.subjects.map((entry) => [entry.subject.id, entry.seconds]),
+ ),
+ );
+ })
+ .catch(() => {});
+ return () => {
+ current = false;
+ };
+ }, [api, focus.enabled]);
+
+ const startWith = async (subjectId: string) => {
+ const outcome = await focus.start({
+ source: STUDY_SOURCE,
+ subjectId,
+ replace,
+ });
+ if (outcome !== "failed") onStarted();
+ };
+
+ return (
+ <>
+ void startWith(subject.id)}
+ onCreate={(request) => {
+ setCreating(true);
+ setCreateFailed(false);
+ void focus
+ .createSubject(request)
+ .then((subject) => {
+ if (!subject) {
+ setCreateFailed(true);
+ return;
+ }
+ return startWith(subject.id);
+ })
+ .finally(() => setCreating(false));
+ }}
+ />
+ {createFailed ? (
+
+ {t("study.createFailed")}
+
+ ) : null}
+
+ >
+ );
+}
+
+interface RunningViewProps {
+ active: ActiveAction;
+ onSwitch: () => void;
+}
+
+function RunningView({ active, onSwitch }: RunningViewProps): ReactNode {
+ const focus = usePanelFocus();
+ const elapsed = useFocusElapsed(focus.state);
+ const { surface } = usePanel();
+ const { formatNumber, t } = useFocusText();
+ const entry = catalogEntryFor(focus.catalog, active.source);
+ const xp = entry
+ ? estimateActionXp(entry, {
+ elapsedSeconds: elapsed,
+ priorMinutes: active.priorMinutes,
+ flowScore: active.flowScore,
+ })
+ : null;
+ const headline = actionHeadline(active, t("focus.title"));
+
+ return (
+ <>
+
+
+ {active.paused ? t("focus.paused") : t("focus.running")}
+ {active.surface !== surface
+ ? ` · ${t(`focus.startedIn.${active.surface}`)}`
+ : ""}
+
+
+ {headline}
+
+
+
+
+ {t("focus.elapsed")}
+
+ {formatElapsed(elapsed)}
+
+
+ {xp !== null ? (
+
+
+ {t("focus.xp", { xp: formatNumber(xp) })}
+
+
+ {t("focus.flowMultiplier", {
+ multiplier: formatNumber(flowMultiplier(active.flowScore)),
+ })}
+
+
+ ) : null}
+
+
+
+
+
+
+
+ >
+ );
+}
+
+function FinishedView(): ReactNode {
+ const focus = usePanelFocus();
+ const { formatNumber, t } = useFocusText();
+ const finished = focus.state.finished;
+ if (!finished) return null;
+ const headline = actionHeadline(finished, t("focus.title"));
+ const elapsed = formatElapsed(finished.durationSeconds);
+ return (
+ <>
+ {t("focus.finishedTitle")}
+
+
+ {finished.xpGranted > 0
+ ? t("focus.finishedSummary", {
+ action: headline,
+ elapsed,
+ xp: formatNumber(finished.xpGranted),
+ })
+ : t("focus.finishedNoXp", { action: headline, elapsed })}
+
+
+
+ >
+ );
+}
+
+interface ConflictViewProps {
+ conflict: ActiveAction;
+ requested: StartFocusOptions;
+}
+
+function ConflictView({ conflict, requested }: ConflictViewProps): ReactNode {
+ const focus = usePanelFocus();
+ const { t } = useFocusText();
+ const entry = catalogEntryFor(focus.catalog, requested.source);
+ const subject = requested.subjectId
+ ? (focus.study.subjects?.find((s) => s.id === requested.subjectId) ?? null)
+ : null;
+ const requestedLabel = actionHeadline(
+ { label: entry?.label ?? null, source: requested.source, subject },
+ t("focus.title"),
+ );
+ return (
+ <>
+ {t("focus.conflictTitle")}
+
+
+ {t("focus.conflictBody", {
+ action: actionHeadline(conflict, t("focus.title")),
+ where: t(`focus.startedIn.${conflict.surface}`),
+ requested: requestedLabel,
+ })}
+
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/src/focus/provider.tsx b/src/focus/provider.tsx
new file mode 100644
index 0000000..a11ab1b
--- /dev/null
+++ b/src/focus/provider.tsx
@@ -0,0 +1,481 @@
+import {
+ type ActionCatalogEntry,
+ type CreateStudySubjectInput,
+ elapsedSeconds,
+ type FocusApi,
+ type FocusSessionState,
+ focusSessionReducer,
+ INITIAL_FOCUS_STATE,
+ isActiveSessionConflict,
+ type StudyCatalog,
+ type StudySubject,
+} from "@flow-industries/id/focus";
+import {
+ createContext,
+ type ReactNode,
+ useCallback,
+ useContext,
+ useEffect,
+ useLayoutEffect,
+ useMemo,
+ useReducer,
+ useRef,
+ useState,
+} from "react";
+
+export interface StartFocusOptions {
+ source: string;
+ subjectId?: string;
+ replace?: boolean;
+}
+
+export type StartFocusOutcome = "started" | "conflict" | "failed";
+
+export interface StudyData {
+ catalog: StudyCatalog | null;
+ subjects: StudySubject[] | null;
+ failed: boolean;
+}
+
+export interface FocusContextValue {
+ /** Signed in with a usable account; everything else is inert otherwise. */
+ enabled: boolean;
+ viewerId: string | null;
+ /** The client the provider talks through, shared with the host management page so it
+ * never builds a second one; null outside a provider. */
+ api: FocusApi | null;
+ state: FocusSessionState;
+ catalog: ActionCatalogEntry[] | null;
+ catalogFailed: boolean;
+ study: StudyData;
+ /** The start a 409 interrupted, kept so "Switch" can repeat it with `replace`. */
+ pendingStart: StartFocusOptions | null;
+ refresh: () => void;
+ loadStudy: () => void;
+ start: (options: StartFocusOptions) => Promise;
+ pause: () => Promise;
+ resume: () => Promise;
+ stop: () => Promise;
+ createSubject: (
+ request: CreateStudySubjectInput,
+ ) => Promise;
+ dismissFinished: () => void;
+ dismissConflict: () => void;
+}
+
+const EMPTY_STUDY: StudyData = { catalog: null, subjects: null, failed: false };
+
+const EMPTY: FocusContextValue = {
+ enabled: false,
+ viewerId: null,
+ api: null,
+ state: INITIAL_FOCUS_STATE,
+ catalog: null,
+ catalogFailed: false,
+ study: EMPTY_STUDY,
+ pendingStart: null,
+ refresh: () => {},
+ loadStudy: () => {},
+ start: async () => "failed",
+ pause: async () => {},
+ resume: async () => {},
+ stop: async () => {},
+ createSubject: async () => null,
+ dismissFinished: () => {},
+ dismissConflict: () => {},
+};
+
+const FocusContext = createContext(EMPTY);
+
+export interface FocusProviderProps {
+ api: FocusApi;
+ viewerId: string | null;
+ children: ReactNode;
+}
+
+export function FocusProvider({
+ api,
+ viewerId,
+ children,
+}: FocusProviderProps): ReactNode {
+ return (
+
+ {children}
+
+ );
+}
+
+function FocusSessionProvider({
+ api,
+ viewerId,
+ children,
+}: FocusProviderProps): ReactNode {
+ const enabled = viewerId !== null;
+ const [state, dispatch] = useReducer(
+ focusSessionReducer,
+ INITIAL_FOCUS_STATE,
+ );
+ const stateRef = useRef(state);
+ stateRef.current = state;
+ const [catalog, setCatalog] = useState(null);
+ const [catalogFailed, setCatalogFailed] = useState(false);
+ const [study, setStudy] = useState(EMPTY_STUDY);
+ const [pendingStart, setPendingStart] = useState(
+ null,
+ );
+ const generationRef = useRef(0);
+ const studyRequestedRef = useRef(false);
+ const mountedRef = useRef(false);
+ const requestRef = useRef(false);
+ const creatingRef = useRef(false);
+ const readRef = useRef(0);
+
+ const read = useCallback(() => {
+ if (!enabled || !mountedRef.current) return;
+ const generation = generationRef.current;
+ const request = ++readRef.current;
+ void api
+ .active()
+ .then((active) => {
+ if (generationRef.current !== generation || request !== readRef.current)
+ return;
+ dispatch({ type: "read", active, at: Date.now() });
+ })
+ .catch(() => {
+ if (generationRef.current !== generation || request !== readRef.current)
+ return;
+ dispatch({ type: "read-failed" });
+ });
+ }, [api, enabled]);
+
+ const loadCatalog = useCallback(() => {
+ if (!enabled || !mountedRef.current) return;
+ const generation = generationRef.current;
+ void api
+ .catalog()
+ .then((result) => {
+ if (generationRef.current !== generation) return;
+ setCatalog(result.actions);
+ setCatalogFailed(false);
+ })
+ .catch(() => {
+ if (generationRef.current !== generation) return;
+ setCatalogFailed(true);
+ });
+ }, [api, enabled]);
+
+ const loadSubjects = useCallback(() => {
+ if (!enabled || !mountedRef.current) return;
+ const generation = generationRef.current;
+ void api
+ .subjects()
+ .then((result) => {
+ if (generationRef.current !== generation) return;
+ setStudy((current) => ({
+ ...current,
+ subjects: result.subjects,
+ }));
+ })
+ .catch(() => {
+ if (generationRef.current !== generation) return;
+ setStudy((current) => ({ ...current, failed: true }));
+ });
+ }, [api, enabled]);
+
+ const markSubjectUsed = useCallback((subjectId: string, at: string) => {
+ setStudy((current) => ({
+ ...current,
+ subjects:
+ current.subjects?.map((subject) =>
+ subject.id === subjectId ? { ...subject, lastUsedAt: at } : subject,
+ ) ?? null,
+ }));
+ }, []);
+
+ const loadStudy = useCallback(() => {
+ if (!enabled || !mountedRef.current) return;
+ studyRequestedRef.current = true;
+ const generation = generationRef.current;
+ void Promise.allSettled([api.studyCatalog(), api.subjects()]).then(
+ ([catalog, subjects]) => {
+ if (generationRef.current !== generation) return;
+ setStudy((current) => ({
+ catalog:
+ catalog.status === "fulfilled" ? catalog.value : current.catalog,
+ subjects:
+ subjects.status === "fulfilled"
+ ? subjects.value.subjects
+ : current.subjects,
+ failed:
+ catalog.status === "rejected" || subjects.status === "rejected",
+ }));
+ },
+ );
+ }, [api, enabled]);
+
+ useLayoutEffect(() => {
+ mountedRef.current = true;
+ requestRef.current = false;
+ creatingRef.current = false;
+ generationRef.current += 1;
+ dispatch({ type: "reset" });
+ setCatalog(null);
+ setCatalogFailed(false);
+ setStudy(EMPTY_STUDY);
+ setPendingStart(null);
+ studyRequestedRef.current = false;
+ if (viewerId !== null) {
+ read();
+ loadCatalog();
+ }
+ return () => {
+ mountedRef.current = false;
+ generationRef.current += 1;
+ };
+ }, [viewerId, read, loadCatalog]);
+
+ useEffect(() => {
+ if (!enabled || !mountedRef.current) return;
+ const generation = generationRef.current;
+ const onVisibility = () => {
+ const active = stateRef.current.active;
+ if (document.visibilityState === "hidden") {
+ if (active) {
+ void api
+ .event({ sessionId: active.sessionId, kind: "focus_lost" })
+ .catch(() => {});
+ }
+ return;
+ }
+ if (!active) {
+ read();
+ return;
+ }
+ void api
+ .event({ sessionId: active.sessionId, kind: "focus_gained" })
+ .catch(() => {})
+ .finally(() => {
+ if (generationRef.current === generation) read();
+ });
+ };
+ document.addEventListener("visibilitychange", onVisibility);
+ return () => document.removeEventListener("visibilitychange", onVisibility);
+ }, [enabled, api, read]);
+
+ const start = useCallback(
+ async (options: StartFocusOptions): Promise => {
+ if (!enabled || !mountedRef.current || requestRef.current)
+ return "failed";
+ const generation = generationRef.current;
+ requestRef.current = true;
+ readRef.current += 1;
+ dispatch({ type: "request" });
+ try {
+ const result = await api.start(options);
+ if (generationRef.current !== generation) return "failed";
+ if (isActiveSessionConflict(result)) {
+ setPendingStart(options);
+ dispatch({ type: "conflict", active: result.active });
+ return "conflict";
+ }
+ setPendingStart(null);
+ dispatch({ type: "started", session: result.session, at: Date.now() });
+ read();
+ if (options.subjectId) {
+ markSubjectUsed(options.subjectId, result.session.startedAt);
+ if (studyRequestedRef.current) loadSubjects();
+ }
+ return "started";
+ } catch {
+ if (generationRef.current === generation) {
+ dispatch({ type: "request-failed" });
+ }
+ return "failed";
+ } finally {
+ if (generationRef.current === generation) requestRef.current = false;
+ }
+ },
+ [api, enabled, read, loadSubjects, markSubjectUsed],
+ );
+
+ const transition = useCallback(
+ async (kind: "pause" | "resume") => {
+ const active = stateRef.current.active;
+ if (!enabled || !mountedRef.current || !active || requestRef.current)
+ return;
+ const generation = generationRef.current;
+ requestRef.current = true;
+ readRef.current += 1;
+ dispatch({ type: "request" });
+ try {
+ await api.event({ sessionId: active.sessionId, kind });
+ if (generationRef.current !== generation) return;
+ dispatch({
+ type: kind === "pause" ? "paused" : "resumed",
+ at: Date.now(),
+ });
+ } catch {
+ if (generationRef.current === generation) {
+ dispatch({ type: "request-failed" });
+ }
+ } finally {
+ if (generationRef.current === generation) requestRef.current = false;
+ }
+ },
+ [api, enabled],
+ );
+
+ const pause = useCallback(() => transition("pause"), [transition]);
+ const resume = useCallback(() => transition("resume"), [transition]);
+
+ const stop = useCallback(async () => {
+ const active = stateRef.current.active;
+ if (!enabled || !mountedRef.current || !active || requestRef.current)
+ return;
+ const generation = generationRef.current;
+ requestRef.current = true;
+ readRef.current += 1;
+ dispatch({ type: "request" });
+ try {
+ const result = await api.finish({ sessionId: active.sessionId });
+ if (generationRef.current !== generation) return;
+ dispatch({ type: "finished", result, at: Date.now() });
+ read();
+ } catch {
+ if (generationRef.current === generation) {
+ dispatch({ type: "request-failed" });
+ }
+ } finally {
+ if (generationRef.current === generation) requestRef.current = false;
+ }
+ }, [api, enabled, read]);
+
+ const createSubject = useCallback(
+ async (request: CreateStudySubjectInput) => {
+ if (!enabled || !mountedRef.current || creatingRef.current) return null;
+ creatingRef.current = true;
+ const generation = generationRef.current;
+ try {
+ const { subject } = await api.createSubject(request);
+ if (generationRef.current !== generation) return null;
+ setStudy((current) => ({
+ ...current,
+ subjects: current.subjects
+ ? [
+ ...current.subjects.filter((row) => row.id !== subject.id),
+ subject,
+ ]
+ : [subject],
+ }));
+ return subject;
+ } catch {
+ return null;
+ } finally {
+ if (generationRef.current === generation) creatingRef.current = false;
+ }
+ },
+ [api, enabled],
+ );
+
+ const dismissFinished = useCallback(
+ () => dispatch({ type: "dismiss-finished" }),
+ [],
+ );
+ const dismissConflict = useCallback(() => {
+ setPendingStart(null);
+ dispatch({ type: "dismiss-conflict" });
+ }, []);
+
+ const value = useMemo(
+ () => ({
+ enabled,
+ viewerId,
+ api: enabled ? api : null,
+ state,
+ catalog,
+ catalogFailed,
+ study,
+ pendingStart,
+ refresh: read,
+ loadStudy,
+ start,
+ pause,
+ resume,
+ stop,
+ createSubject,
+ dismissFinished,
+ dismissConflict,
+ }),
+ [
+ enabled,
+ viewerId,
+ api,
+ state,
+ catalog,
+ catalogFailed,
+ study,
+ pendingStart,
+ read,
+ loadStudy,
+ start,
+ pause,
+ resume,
+ stop,
+ createSubject,
+ dismissFinished,
+ dismissConflict,
+ ],
+ );
+
+ return (
+ {children}
+ );
+}
+
+/** Outside a provider — the embed, or an SSR pass — this answers an inert,
+ * signed-out value instead of throwing: a missing Focus must never take a
+ * chat surface down with it. */
+export function useFocus(): FocusContextValue {
+ return useContext(FocusContext);
+}
+
+/** The running action, or null. */
+export function useActiveAction(): FocusSessionState["active"] {
+ const { state } = useFocus();
+ return state.active;
+}
+
+const CLOCK_TICK_MS = 250;
+
+/** Whole seconds elapsed on the running action, advancing on the local clock
+ * from the last server sample and frozen while paused. Re-renders only when
+ * the displayed second changes. */
+export function useFocusElapsed(providedState?: FocusSessionState): number {
+ const context = useFocus();
+ const state = providedState ?? context.state;
+ const anchor = state.anchor;
+ const [shown, setShown] = useState(() =>
+ anchor ? Math.floor(elapsedSeconds(anchor, Date.now())) : 0,
+ );
+
+ useEffect(() => {
+ if (!anchor) {
+ setShown(0);
+ return;
+ }
+ const tick = () => {
+ const whole = Math.floor(elapsedSeconds(anchor, Date.now()));
+ setShown((current) => (current === whole ? current : whole));
+ };
+ tick();
+ if (anchor.paused) return;
+ const id = window.setInterval(tick, CLOCK_TICK_MS);
+ return () => window.clearInterval(id);
+ }, [anchor]);
+
+ return shown;
+}
diff --git a/src/focus/study-subject-picker.tsx b/src/focus/study-subject-picker.tsx
new file mode 100644
index 0000000..7ff05f8
--- /dev/null
+++ b/src/focus/study-subject-picker.tsx
@@ -0,0 +1,680 @@
+import type {
+ StudyCatalog,
+ StudyCategory,
+ StudyField,
+ StudySubject,
+} from "@flow-industries/id/focus";
+import {
+ recentSubjects,
+ type StudySearchHit,
+ searchStudy,
+} from "@flow-industries/id/focus";
+import { ChevronLeft, ChevronRight, Plus, Search } from "lucide-react";
+import {
+ type FormEvent,
+ type KeyboardEvent,
+ type ReactNode,
+ type RefObject,
+ useEffect,
+ useId,
+ useMemo,
+ useRef,
+ useState,
+} from "react";
+import { Button } from "../components/ui/button";
+import { Input } from "../components/ui/input";
+import { cn } from "../utils/cn";
+import {
+ type FocusText,
+ FocusTextProvider,
+ isolateBidi,
+ useFocusText,
+} from "./text";
+
+const CLAIM_FOCUS_RETRY_MS = 30;
+const CLAIM_FOCUS_ATTEMPTS = 6;
+
+/** Moves focus to `ref` when `enabled` turns on. One `focus()` is not enough
+ * here: the Base UI popup that hosts this picker re-homes focus onto itself
+ * on the frame after a focused child unmounts (the button that opened this
+ * step, the search input the add form replaces), so the claim is retried for
+ * a few frames until it holds. */
+function useClaimFocus(
+ ref: RefObject,
+ enabled: boolean,
+) {
+ useEffect(() => {
+ if (!enabled) return;
+ const input = ref.current;
+ if (!input) return;
+ let attempts = 0;
+ let timer = 0;
+ const claim = () => {
+ if (
+ document.activeElement === input ||
+ attempts >= CLAIM_FOCUS_ATTEMPTS
+ ) {
+ return;
+ }
+ attempts += 1;
+ input.focus();
+ timer = window.setTimeout(claim, CLAIM_FOCUS_RETRY_MS);
+ };
+ claim();
+ return () => window.clearTimeout(timer);
+ }, [ref, enabled]);
+}
+
+export interface StudySubjectPickerProps {
+ text?: FocusText;
+ catalog: StudyCatalog | null;
+ subjects: StudySubject[] | null;
+ /** Data could not be loaded; the picker still offers "Add your own". */
+ failed?: boolean;
+ /** A start or create is in flight — options stay visible but inert. */
+ busy?: boolean;
+ /** Seconds studied today per subject id, rendered as "today: 42 min".
+ * Omitted until the summary API exists; the row simply shows nothing. */
+ todaySeconds?: Record;
+ onPick: (subject: StudySubject) => void;
+ onCreate: (request: { name?: string; field?: string }) => void;
+ /** Rendered as the leading back control when the host has a previous step. */
+ onBack?: () => void;
+ autoFocus?: boolean;
+ className?: string;
+}
+
+type PickerOption =
+ | { kind: "subject"; id: string; subject: StudySubject }
+ | {
+ kind: "field";
+ id: string;
+ field: StudyField;
+ category: StudyCategory;
+ alias: string | null;
+ }
+ | { kind: "category"; id: string; category: StudyCategory }
+ | { kind: "add"; id: string; name: string | null };
+
+type OptionGroup = {
+ key: string;
+ label: string | null;
+ options: PickerOption[];
+};
+
+function subjectOption(subject: StudySubject): PickerOption {
+ return { kind: "subject", id: `subject:${subject.id}`, subject };
+}
+
+function hitOption(hit: StudySearchHit): PickerOption {
+ if (hit.kind === "subject") {
+ return { kind: "subject", id: `subject:${hit.id}`, subject: hit.subject };
+ }
+ return {
+ kind: "field",
+ id: `field:${hit.id}`,
+ field: hit.ref.field,
+ category: hit.ref.category,
+ alias: hit.alias,
+ };
+}
+
+export function StudySubjectPicker(props: StudySubjectPickerProps): ReactNode {
+ return (
+
+
+
+ );
+}
+
+function Picker({
+ catalog,
+ subjects,
+ failed = false,
+ busy = false,
+ todaySeconds,
+ onPick,
+ onCreate,
+ onBack,
+ autoFocus = false,
+ className,
+}: StudySubjectPickerProps): ReactNode {
+ const { formatNumber, t } = useFocusText();
+ const baseId = useId();
+ const inputRef = useRef(null);
+ const [query, setQuery] = useState("");
+ const [categorySlug, setCategorySlug] = useState(null);
+ const [adding, setAdding] = useState(null);
+ const [activeIndex, setActiveIndex] = useState(0);
+ const trimmedQuery = query.trim();
+
+ const category = useMemo(
+ () =>
+ categorySlug && catalog
+ ? (catalog.categories.find((c) => c.slug === categorySlug) ?? null)
+ : null,
+ [catalog, categorySlug],
+ );
+
+ const groups = useMemo(() => {
+ const liveSubjects = subjects ?? [];
+ if (trimmedQuery) {
+ const needle = trimmedQuery.toLowerCase();
+ const results = catalog
+ ? searchStudy(trimmedQuery, { catalog, subjects: liveSubjects }).map(
+ hitOption,
+ )
+ : liveSubjects
+ .filter((s) => s.name.toLowerCase().includes(needle))
+ .map(subjectOption);
+ return [
+ {
+ key: "results",
+ label: t("study.results"),
+ options: results,
+ },
+ {
+ key: "add",
+ label: null,
+ options: [{ kind: "add", id: "add:named", name: trimmedQuery }],
+ },
+ ];
+ }
+ if (category) {
+ return [
+ {
+ key: `category:${category.slug}`,
+ label: category.label,
+ options: category.fields.map((field) => ({
+ kind: "field" as const,
+ id: `field:${field.slug}`,
+ field,
+ category,
+ alias: null,
+ })),
+ },
+ ];
+ }
+ const recent = recentSubjects(liveSubjects);
+ const result: OptionGroup[] = [];
+ if (recent.length > 0) {
+ result.push({
+ key: "recent",
+ label: t("study.recent"),
+ options: recent.map(subjectOption),
+ });
+ }
+ if (catalog) {
+ result.push({
+ key: "browse",
+ label: t("study.browse"),
+ options: catalog.categories.map((c) => ({
+ kind: "category" as const,
+ id: `category:${c.slug}`,
+ category: c,
+ })),
+ });
+ }
+ result.push({
+ key: "add",
+ label: null,
+ options: [{ kind: "add", id: "add:own", name: null }],
+ });
+ return result;
+ }, [catalog, category, subjects, t, trimmedQuery]);
+
+ const options = useMemo(() => groups.flatMap((g) => g.options), [groups]);
+ const clampedIndex = Math.min(activeIndex, Math.max(0, options.length - 1));
+ const activeOption = options[clampedIndex] ?? null;
+ const listId = `${baseId}-listbox`;
+ const optionDomId = (option: PickerOption) =>
+ `${baseId}-${option.id.replace(/[^a-zA-Z0-9_-]/g, "_")}`;
+
+ useClaimFocus(inputRef, autoFocus && adding === null);
+
+ useEffect(() => {
+ if (!activeOption) return;
+ document
+ .getElementById(optionDomId(activeOption))
+ ?.scrollIntoView({ block: "nearest" });
+ });
+
+ const optionLabel = (option: PickerOption): string => {
+ switch (option.kind) {
+ case "subject":
+ return t("study.pickSubject", { subject: option.subject.name });
+ case "field":
+ return `${t("study.pickSubject", { subject: option.field.label })} · ${option.category.label}`;
+ case "category":
+ return t("study.openCategory", { category: option.category.label });
+ case "add":
+ return option.name
+ ? t("study.addNamed", { name: option.name })
+ : t("study.addOwn");
+ }
+ };
+
+ const choose = (option: PickerOption) => {
+ if (busy) return;
+ switch (option.kind) {
+ case "subject":
+ onPick(option.subject);
+ return;
+ case "field":
+ onCreate({ field: option.field.slug });
+ return;
+ case "category":
+ setCategorySlug(option.category.slug);
+ setActiveIndex(0);
+ return;
+ case "add":
+ setAdding(option.name ?? "");
+ return;
+ }
+ };
+
+ const onKeyDown = (event: KeyboardEvent) => {
+ switch (event.key) {
+ case "ArrowDown":
+ event.preventDefault();
+ setActiveIndex(
+ options.length ? (clampedIndex + 1) % options.length : 0,
+ );
+ return;
+ case "ArrowUp":
+ event.preventDefault();
+ setActiveIndex(
+ options.length
+ ? (clampedIndex - 1 + options.length) % options.length
+ : 0,
+ );
+ return;
+ case "Home":
+ if (!query) {
+ event.preventDefault();
+ setActiveIndex(0);
+ }
+ return;
+ case "End":
+ if (!query) {
+ event.preventDefault();
+ setActiveIndex(Math.max(0, options.length - 1));
+ }
+ return;
+ case "Enter":
+ if (activeOption) {
+ event.preventDefault();
+ choose(activeOption);
+ }
+ return;
+ case "Escape":
+ if (query) {
+ event.preventDefault();
+ event.stopPropagation();
+ setQuery("");
+ setActiveIndex(0);
+ } else if (category) {
+ event.preventDefault();
+ event.stopPropagation();
+ setCategorySlug(null);
+ setActiveIndex(0);
+ }
+ return;
+ }
+ };
+
+ if (adding !== null) {
+ return (
+ setAdding(null)}
+ className={className}
+ />
+ );
+ }
+
+ const loading = !failed && (subjects === null || catalog === null);
+ let statusMessage: string | null = null;
+ if (loading) statusMessage = t("study.loading");
+ else if (failed) statusMessage = t("study.failed");
+
+ let back: { label: string; onClick: () => void } | null = null;
+ if (category) {
+ back = {
+ label: t("study.allCategories"),
+ onClick: () => {
+ setCategorySlug(null);
+ setActiveIndex(0);
+ inputRef.current?.focus();
+ },
+ };
+ } else if (onBack) {
+ back = { label: t("focus.pickerTitle"), onClick: onBack };
+ }
+
+ return (
+
+
+ {back ? (
+
+ ) : null}
+
+
{t("study.title")}
+
+ {t("study.description")}
+
+
+
+
+
+ {
+ setQuery(event.target.value);
+ setActiveIndex(0);
+ }}
+ onKeyDown={onKeyDown}
+ className="h-9 ps-8 text-sm md:text-sm"
+ data-study-search=""
+ />
+
+
+ {t(
+ "study.optionCount",
+ { count: formatNumber(options.length) },
+ options.length,
+ )}
+
+ {statusMessage ? (
+
+ {statusMessage}
+
+ ) : null}
+
+ {groups.map((group) => {
+ if (group.options.length === 0) {
+ if (group.key !== "results") return null;
+ return (
+
+ {t("study.noResults", { query: trimmedQuery })}
+
+ );
+ }
+ return (
+
+ {group.label ? (
+
+ {group.label}
+
+ ) : null}
+ {group.options.map((option) => {
+ const active = activeOption?.id === option.id;
+ return (
+
+ );
+ })}
+
+ );
+ })}
+
+
+ );
+}
+
+interface OptionBodyProps {
+ option: PickerOption;
+ todaySeconds?: Record;
+}
+
+function OptionBody({ option, todaySeconds }: OptionBodyProps): ReactNode {
+ const { formatNumber, t } = useFocusText();
+ switch (option.kind) {
+ case "subject": {
+ const seconds = todaySeconds?.[option.subject.id];
+ return (
+ <>
+
+ {option.subject.name}
+
+ {seconds !== undefined && seconds > 0 ? (
+
+ {t("study.todayMinutes", {
+ minutes: formatNumber(Math.round(seconds / 60)),
+ })}
+
+ ) : null}
+ >
+ );
+ }
+ case "field":
+ return (
+ <>
+
+ {option.field.label}
+ {option.alias ? (
+
+ {t("study.alias", { alias: option.alias })}
+
+ ) : null}
+
+
+ {option.category.label}
+
+ >
+ );
+ case "category":
+ return (
+ <>
+
+ {option.category.label}
+
+
+ {t(
+ "study.fieldCount",
+ { count: formatNumber(option.category.fields.length) },
+ option.category.fields.length,
+ )}
+
+
+ >
+ );
+ case "add":
+ return (
+ <>
+
+
+ {option.name
+ ? t("study.addNamed", { name: isolateBidi(option.name) })
+ : t("study.addOwn")}
+
+ >
+ );
+ }
+}
+
+interface AddSubjectFormProps {
+ catalog: StudyCatalog | null;
+ initialName: string;
+ busy: boolean;
+ onSubmit: (request: { name: string; field?: string }) => void;
+ onBack: () => void;
+ className?: string;
+}
+
+function AddSubjectForm({
+ catalog,
+ initialName,
+ busy,
+ onSubmit,
+ onBack,
+ className,
+}: AddSubjectFormProps): ReactNode {
+ const { t } = useFocusText();
+ const nameId = useId();
+ const categoryId = useId();
+ const [name, setName] = useState(initialName);
+ const [categorySlug, setCategorySlug] = useState("");
+ const nameRef = useRef(null);
+
+ useClaimFocus(nameRef, true);
+
+ const submit = (event: FormEvent) => {
+ event.preventDefault();
+ const trimmed = name.trim();
+ if (!trimmed || busy) return;
+ onSubmit(
+ categorySlug ? { name: trimmed, field: categorySlug } : { name: trimmed },
+ );
+ };
+
+ return (
+
+ );
+}
+
+interface FieldRowProps {
+ id: string;
+ label: string;
+ children: ReactNode;
+}
+
+function FieldRow({ id, label, children }: FieldRowProps): ReactNode {
+ return (
+
+
+ {children}
+
+ );
+}
diff --git a/src/focus/text.tsx b/src/focus/text.tsx
new file mode 100644
index 0000000..007a9c6
--- /dev/null
+++ b/src/focus/text.tsx
@@ -0,0 +1,121 @@
+import { createContext, type ReactNode, useContext } from "react";
+
+type TextEntry = string | { one: string; other: string };
+
+const CATALOG = {
+ "common.done": "Done",
+ "focus.title": "Focus",
+ "focus.description": "Start an action and earn XP without entering a room.",
+ "focus.pickerTitle": "Start an action",
+ "focus.catalogLoading": "Loading actions…",
+ "focus.catalogFailed": "Actions are unavailable right now.",
+ "focus.sessionLoading": "Checking for a running action…",
+ "focus.start": "Start",
+ "focus.startAction": "Start {action}",
+ "focus.choose": "Choose…",
+ "focus.chooseAction": "Choose what to {action}",
+ "focus.running": "In progress",
+ "focus.paused": "Paused",
+ "focus.pause": "Pause",
+ "focus.resume": "Resume",
+ "focus.stop": "Stop",
+ "focus.switch": "Switch…",
+ "focus.switchNote": "Stopping {action} grants its XP now.",
+ "focus.elapsed": "Elapsed",
+ "focus.xp": "+{xp} XP",
+ "focus.flowMultiplier": "Flow Score ×{multiplier}",
+ "focus.startedIn.game": "Started in the game",
+ "focus.startedIn.talk": "Started in Talk",
+ "focus.startedIn.web": "Started on the web",
+ "focus.pill":
+ "{action}, {elapsed} elapsed, about {xp} XP. Open the running action.",
+ "focus.pillPaused":
+ "{action}, paused at {elapsed}, about {xp} XP. Open the running action.",
+ "focus.finishedTitle": "Nice work",
+ "focus.finishedSummary": "{action} · {elapsed} · +{xp} XP",
+ "focus.finishedNoXp":
+ "{action} · {elapsed} · too short to earn XP this time.",
+ "focus.conflictTitle": "Already in progress",
+ "focus.conflictBody":
+ "{action} is running ({where}). Switch to {requested}? The running action stops and gets its XP.",
+ "focus.conflictSwitch": "Switch",
+ "focus.conflictKeep": "Keep going",
+ "focus.failed": "That didn't go through — try again.",
+ "study.title": "What are you practicing today?",
+ "study.description": "Each subject keeps its own time.",
+ "study.searchLabel": "Search subjects",
+ "study.searchPlaceholder": "Search, e.g. Chinese",
+ "study.recent": "Recent",
+ "study.browse": "Browse",
+ "study.results": "Results",
+ "study.noResults": "Nothing matches “{query}”.",
+ "study.addOwn": "Add your own",
+ "study.addNamed": "Add “{name}”",
+ "study.addName": "Subject name",
+ "study.addNamePlaceholder": "e.g. Math for my test",
+ "study.addCategory": "Category (optional)",
+ "study.addCategoryNone": "No category",
+ "study.addSubmit": "Add and start",
+ "study.allCategories": "All categories",
+ "study.alias": "also “{alias}”",
+ "study.todayMinutes": "today: {minutes} min",
+ "study.loading": "Loading subjects…",
+ "study.failed": "Subjects are unavailable right now.",
+ "study.pickSubject": "Start practicing {subject}",
+ "study.openCategory": "Browse {category}",
+ "study.fieldCount": { one: "{count} field", other: "{count} fields" },
+ "study.optionCount": { one: "{count} option", other: "{count} options" },
+ "study.createFailed": "Couldn't add that subject — try again.",
+} as const satisfies Record;
+
+export type FocusTextKey = keyof typeof CATALOG;
+
+export type TextValues = Record;
+export interface FocusText {
+ t: (key: FocusTextKey, values?: TextValues, count?: number) => string;
+ formatNumber: (value: number) => string;
+}
+export function isolateBidi(value: string | number): string {
+ return `\u2068${value}\u2069`;
+}
+export function createFocusText(
+ locale = "en",
+ messages: Partial> = {},
+): FocusText {
+ const numbers = new Intl.NumberFormat(locale);
+ const plurals = new Intl.PluralRules(locale);
+ return {
+ formatNumber: (value) => numbers.format(value),
+ t(key, values = {}, count) {
+ const entry: TextEntry = messages[key] ?? CATALOG[key];
+ let template: string;
+ // biome-ignore lint: TextEntry is an explicit public string-or-plural contract.
+ if (typeof entry === "string") template = entry;
+ else if (plurals.select(count ?? 0) === "one") template = entry.one;
+ else template = entry.other;
+ return template.replace(/\{([^}]+)\}/g, (_match, name: string) =>
+ String(values[name] ?? ""),
+ );
+ },
+ };
+}
+export const defaultFocusText = createFocusText();
+const FocusTextContext = createContext(defaultFocusText);
+interface FocusTextProviderProps {
+ text?: FocusText;
+ children: ReactNode;
+}
+
+export function FocusTextProvider({
+ text = defaultFocusText,
+ children,
+}: FocusTextProviderProps): ReactNode {
+ return (
+
+ {children}
+
+ );
+}
+export function useFocusText(): FocusText {
+ return useContext(FocusTextContext);
+}
diff --git a/tests/focus-provider.fixture.tsx b/tests/focus-provider.fixture.tsx
new file mode 100644
index 0000000..4dd8151
--- /dev/null
+++ b/tests/focus-provider.fixture.tsx
@@ -0,0 +1,72 @@
+import { createFocusApi, type FocusApi } from "@flow-industries/id/focus";
+import { StrictMode, useEffect, useMemo, useState } from "react";
+import { createRoot } from "react-dom/client";
+import { FocusProvider, useFocus } from "../src/focus/provider";
+
+function Observer() {
+ const { study, loadStudy } = useFocus();
+ useEffect(() => loadStudy(), [loadStudy]);
+ return (
+ <>
+
+
+ >
+ );
+}
+
+function Fixture() {
+ const [viewer, setViewer] = useState("Alice");
+ const api = useMemo(
+ () => ({
+ ...createFocusApi("https://unused.invalid", async () => null, "web"),
+ active: async () => null,
+ catalog: async () => ({ actions: [] }),
+ studyCatalog: async () => {
+ if (localStorage.getItem("failure") === "catalog")
+ throw new Error("Catalog unavailable");
+ return {
+ version: 1,
+ categories: [{ slug: "languages", label: "Languages", fields: [] }],
+ };
+ },
+ subjects: async () => {
+ if (localStorage.getItem("failure") === "subjects")
+ throw new Error("Subjects unavailable");
+ if (viewer === "Alice")
+ await new Promise((resolve) => setTimeout(resolve, 250));
+ return {
+ subjects: [
+ {
+ id: viewer,
+ name: viewer,
+ field: null,
+ archivedAt: null,
+ createdAt: "2026-09-08T00:00:00Z",
+ lastUsedAt: "2026-09-08T00:00:00Z",
+ },
+ ],
+ };
+ },
+ }),
+ [viewer],
+ );
+ return (
+ <>
+
+
+
+
+ >
+ );
+}
+const root = document.getElementById("root");
+if (root)
+ createRoot(root).render(
+
+
+ ,
+ );
diff --git a/tests/focus-provider.spec.ts b/tests/focus-provider.spec.ts
new file mode 100644
index 0000000..ff06b65
--- /dev/null
+++ b/tests/focus-provider.spec.ts
@@ -0,0 +1,53 @@
+import { execFileSync } from "node:child_process";
+import { expect, test } from "@playwright/test";
+
+const script = execFileSync(
+ "bun",
+ ["build", "tests/focus-provider.fixture.tsx", "--target", "browser"],
+ { encoding: "utf8", maxBuffer: 5_000_000 },
+);
+
+test.beforeEach(async ({ page }) => {
+ await page.route("**/provider-fixture", (route) =>
+ route.fulfill({
+ contentType: "text/html",
+ body: '',
+ }),
+ );
+ await page.route("**/provider-fixture.js", (route) =>
+ route.fulfill({ contentType: "text/javascript", body: script }),
+ );
+});
+
+test("child mount loads study and account change discards delayed old subjects", async ({
+ page,
+}) => {
+ await page.goto("/provider-fixture");
+ await expect(page.locator("output")).toContainText('"name":"Alice"');
+ await page.reload();
+ await page.getByRole("button", { name: "Switch" }).click();
+ await expect(page.locator("output")).toContainText('"name":"Bob"');
+ await page.waitForTimeout(350);
+ await expect(page.locator("output")).not.toContainText('"name":"Alice"');
+});
+
+for (const failure of ["catalog", "subjects"]) {
+ test(`preserves successful data when ${failure} fails and recovers`, async ({
+ page,
+ }) => {
+ await page.addInitScript(
+ (value) => localStorage.setItem("failure", value),
+ failure,
+ );
+ await page.goto("/provider-fixture");
+ await expect(page.locator("output")).toContainText('"failed":true');
+ await expect(page.locator("output")).toContainText(
+ failure === "catalog" ? '"name":"Alice"' : '"label":"Languages"',
+ );
+ await page.evaluate(() => localStorage.removeItem("failure"));
+ await page.getByRole("button", { name: "Retry" }).click();
+ await expect(page.locator("output")).toContainText('"failed":false');
+ await expect(page.locator("output")).toContainText('"name":"Alice"');
+ await expect(page.locator("output")).toContainText('"label":"Languages"');
+ });
+}
diff --git a/tests/focus.spec.ts b/tests/focus.spec.ts
new file mode 100644
index 0000000..14116b0
--- /dev/null
+++ b/tests/focus.spec.ts
@@ -0,0 +1,60 @@
+import { expect, test } from "@playwright/test";
+import type { FocusShowcase } from "../app/FocusShowcase";
+
+export type FocusFixture = typeof FocusShowcase;
+
+test.beforeEach(async ({ page }) => {
+ await page.goto("/#focus");
+});
+
+test("keyboard selection, pause, reload recovery and finish", async ({
+ page,
+}) => {
+ await page.getByRole("button", { name: "Choose what to Practice" }).click();
+ const search = page.getByRole("combobox");
+ await expect(search).toBeFocused();
+ await search.fill("Chinese");
+ await search.press("Enter");
+ await expect(page.locator('[data-focus-view="running"]')).toContainText(
+ "Alice's Chinese",
+ );
+ await page.getByRole("button", { name: "Pause", exact: true }).click();
+ const elapsed = await page.locator("[data-focus-elapsed]").textContent();
+ await page.reload();
+ await expect(
+ page.getByRole("button", { name: "Resume", exact: true }),
+ ).toBeVisible();
+ await expect(page.locator("[data-focus-elapsed]")).toHaveText(elapsed ?? "");
+ await page.getByRole("button", { name: "Stop", exact: true }).click();
+ await expect(page.locator('[data-focus-view="finished"]')).toBeVisible();
+});
+
+test("account changes discard delayed private subjects and guest stays inert", async ({
+ page,
+}) => {
+ await page.getByRole("button", { name: "Slow responses" }).click();
+ await page.getByRole("button", { name: "Choose what to Practice" }).click();
+ await page.getByRole("button", { name: "Switch account" }).click();
+ await page.getByRole("button", { name: "Choose what to Practice" }).click();
+ await expect(
+ page.getByRole("option", { name: /Bob's Chinese/ }),
+ ).toBeVisible();
+ await expect(page.locator("[data-study-picker]")).not.toContainText("Alice");
+ await page.getByRole("button", { name: "Sign out", exact: true }).click();
+ await expect(page.locator("[data-study-picker]")).toHaveCount(0);
+ await expect(page.locator("[data-focus-view]")).not.toContainText("Bob");
+});
+
+test("mutation failure retains session and retry succeeds", async ({
+ page,
+}) => {
+ await page.getByRole("button", { name: "Start Meditation" }).click();
+ await page.getByRole("button", { name: "Simulate errors" }).click();
+ await page.getByRole("button", { name: "Stop", exact: true }).click();
+ await expect(
+ page.locator('[data-focus-view="running"] [role="status"]'),
+ ).toBeVisible();
+ await page.getByRole("button", { name: "Simulate errors" }).click();
+ await page.getByRole("button", { name: "Stop", exact: true }).click();
+ await expect(page.locator('[data-focus-view="finished"]')).toBeVisible();
+});
From acfc8e79f675e3415c07934f918cd64629d0722a Mon Sep 17 00:00:00 2001
From: kualta
Date: Tue, 8 Sep 2026 15:42:04 -0500
Subject: [PATCH 2/2] Restore success text contrast and prepare UI 0.23
---
.github/workflows/a11y.yml | 2 +-
package.json | 2 +-
src/styles/tokens.css | 2 +-
.../components-dark.png | Bin 567334 -> 566821 bytes
.../components-light.png | Bin 549105 -> 549108 bytes
5 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/a11y.yml b/.github/workflows/a11y.yml
index a97951e..5d238b3 100644
--- a/.github/workflows/a11y.yml
+++ b/.github/workflows/a11y.yml
@@ -21,7 +21,7 @@ jobs:
- run: npm install -g bun
- run: bun install --frozen-lockfile
- run: bun run build
- - run: bunx playwright test tests/a11y.spec.ts tests/error-boundary.spec.ts tests/semantics.spec.ts
+ - run: bunx playwright test tests/a11y.spec.ts tests/error-boundary.spec.ts tests/semantics.spec.ts tests/focus.spec.ts tests/focus-provider.spec.ts
- if: failure()
uses: actions/upload-artifact@v4
with:
diff --git a/package.json b/package.json
index 25c39e8..b811dd6 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@flow-industries/ui",
- "version": "0.22.0",
+ "version": "0.23.0",
"license": "MIT",
"repository": {
"type": "git",
diff --git a/src/styles/tokens.css b/src/styles/tokens.css
index 4d2cab7..779f881 100644
--- a/src/styles/tokens.css
+++ b/src/styles/tokens.css
@@ -124,7 +124,7 @@
--success: #09b270;
--success-background: color-mix(in oklab, var(--success) 12%, var(--background));
- --success-foreground: var(--success);
+ --success-foreground: #067447;
--input-focus: color-mix(in oklab, var(--focus) 12%, var(--input));
--focus: var(--color-pink);
--overlay: oklch(0 0 0 / 0.75);
diff --git a/tests/visual.spec.ts-snapshots/components-dark.png b/tests/visual.spec.ts-snapshots/components-dark.png
index e2c03d376d75686ce6127784f0a6d19ab12149b3..d8a2666bf5e401ff03b790f7c6599ed750948230 100644
GIT binary patch
literal 566821
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%0DZ*+k*S3Auko~n2CG;IPtAt
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