@odla-ai/chapter 0.38.1 → 0.39.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/worker-context.ts","../../src/auth.ts","../../src/worker-routes.ts","../../src/discussion-reference-security.ts","../../src/member.ts","../../src/application-id.ts","../../src/email-identity.ts","../../src/tiers.ts","../../src/tiers-store.ts","../../src/scheduling.ts","../../src/admission-grants-contract.ts","../../src/signup-control-canonical.ts","../../src/admission-grants.ts","../../src/flow-fields.ts","../../src/gift-offers.ts","../../src/clerk-roles.ts","../../src/crm-sync.ts","../../src/network.ts","../../src/network-contract.ts","../../src/email.ts","../../src/notify.ts","../../src/pipeline.ts","../../src/approve-application.ts","../../src/join-continuation.ts","../../src/join-continuation-server.ts","../../src/signup-control-store.ts","../../src/session.ts","../../src/clerk.ts","../../src/worker-provisioning.ts","../../src/worker-routes-network-receive.ts","../../src/worker-routes-signup-control.ts","../../src/signup-control-contract.ts","../../src/membership-page.ts","../../src/signup-control-validate.ts","../../src/worker-routes-member-content.ts","../../src/member-content-canonical.ts","../../src/member-content-validation-helpers.ts","../../src/member-content-validation.ts","../../src/member-content.ts","../../src/member-content-store.ts","../../src/worker-routes-admission-grants.ts","../../src/worker-routes-admin-admission.ts","../../src/worker-routes-schedule.ts","../../src/payments.ts","../../src/payments-stripe.ts","../../src/gift-codes.ts","../../src/gift-store.ts","../../src/gift-checkout.ts","../../src/gift-intents.ts","../../src/worker-routes-payments.ts","../../src/worker-routes-gifts.ts","../../src/worker-routes-admin.ts","../../src/reconcile.ts","../../src/worker-routes-admin-people.ts","../../src/worker-routes-admin-clerk.ts","../../src/series.ts","../../src/worker-routes-admin-dashboard.ts","../../src/worker-routes-admin-lifecycle.ts","../../src/worker-routes-admin-comms.ts","../../src/worker-routes-network.ts","../../src/worker-network-fetch.ts","../../src/worker-network-push.ts","../../src/worker-routes-network-records.ts","../../src/worker-routes-network-notes.ts","../../src/worker-routes-network-shared-notes.ts","../../src/worker-routes-formation.ts","../../src/signup-control-delivery.ts","../../src/member-content-delivery.ts","../../src/admission-grants-delivery.ts","../../src/signup-control-theme.ts","../../src/signup-control-theme-worker.ts","../../src/worker.ts"],"sourcesContent":["// Shared context for the chapter Worker: env typing, the odla-db admin client,\n// Clerk-JWT verification, and the source-aware auth helpers. Split out of\n// worker.ts so the route modules share ONE construction of the caches (public\n// config + JWKS) per site, and the worker entry stays a thin composer under the\n// per-file LOC cap. Nothing here is re-exported from the worker entry, so the\n// public `@odla-ai/chapter/worker` surface is unchanged by the split.\nimport { initAdmin } from \"@odla-ai/db\";\nimport { createRemoteJWKSet, jwtVerify } from \"jose\";\nimport { isAdminRole, roleFromClaim } from \"./auth\";\nimport type { Chapter } from \"./types\";\n\n/** The Cloudflare SEND_EMAIL binding payload. */\nexport interface EmailPayload {\n from: string;\n to: string[];\n subject: string;\n text?: string;\n html?: string;\n replyTo?: string;\n headers?: Record<string, string>;\n}\n\n/** The Worker env a chapter site provides (wrangler vars + the ODLA_API_KEY\n * secret pushed by provision). */\nexport interface ChapterEnv {\n ASSETS: { fetch(req: Request): Promise<Response> };\n ODLA_ENDPOINT: string;\n ODLA_TENANT: string;\n ODLA_PLATFORM: string;\n ODLA_APP_ID: string;\n /** Registry lifetime for this exact app/database. Discussion reference\n * reads fail closed when it is absent or stale. */\n ODLA_APP_INCARNATION?: string;\n ODLA_ENV: string;\n ODLA_API_KEY: string;\n SEND_EMAIL?: { send(payload: EmailPayload): Promise<{ messageId: string }> };\n EMAIL_FROM?: string;\n}\n\n/** Options for `chapterWorker`. */\nexport interface ChapterWorkerOptions {\n chapter: Chapter;\n /** CRM mount point. Default \"/api/crm\". */\n crmBasePath?: string;\n /** Host routes, tried BEFORE the built-ins — so a wrapping site can add its own\n * routes (or override/alias a built-in path) and reuse chapter's auth via the\n * shared {@link WorkerContext}, instead of re-verifying JWTs itself. */\n routes?: Route[];\n}\n\n/** The registry public-config a site reads to boot Clerk sign-in. */\nexport type PublicConfig = { env?: string; clerkPublishableKey?: string | null; issuer?: string | null };\n/** The odla-db admin client type. */\nexport type Db = ReturnType<typeof initAdmin>;\n\n/** A verified session: the Clerk `sub`, optional email, and the raw JWT payload\n * (so the role claim can be read for auth source \"claim\"). */\nexport interface Verified {\n userId: string;\n email?: string;\n payload: Record<string, unknown>;\n}\n\n/** JSON response helper. */\nexport const json = (body: unknown, status = 200): Response =>\n new Response(JSON.stringify(body), { status, headers: { \"content-type\": \"application/json\" } });\n\n/**\n * Build the per-site Worker context: env-independent helpers closing over the\n * public-config and JWKS caches, plus the source-aware auth gate (JWT claim or\n * the odla-db `admins` allowlist). Constructed once per `chapterWorker` and\n * shared by every route module.\n */\nexport function createWorkerContext(options: ChapterWorkerOptions) {\n const { chapter } = options;\n const auth = chapter.auth;\n const crmBase = options.crmBasePath ?? \"/api/crm\";\n\n let publicConfigCache: { value: PublicConfig; at: number } | null = null;\n const jwksByIssuer = new Map<string, ReturnType<typeof createRemoteJWKSet>>();\n\n async function getPublicConfig(env: ChapterEnv): Promise<PublicConfig> {\n if (publicConfigCache && Date.now() - publicConfigCache.at < 5 * 60_000) return publicConfigCache.value;\n const res = await fetch(`${env.ODLA_PLATFORM}/registry/apps/${env.ODLA_APP_ID}/public-config?env=${env.ODLA_ENV}`);\n if (!res.ok) throw new Error(`public-config fetch failed: ${res.status}`);\n const value = (await res.json()) as PublicConfig;\n publicConfigCache = { value, at: Date.now() };\n return value;\n }\n\n async function verifyUser(req: Request, env: ChapterEnv): Promise<Verified | null> {\n const header = req.headers.get(\"authorization\") ?? \"\";\n if (!header.startsWith(\"Bearer \")) return null;\n const token = header.slice(7);\n const { issuer } = await getPublicConfig(env);\n if (!issuer) return null;\n let jwks = jwksByIssuer.get(issuer);\n if (!jwks) {\n jwks = createRemoteJWKSet(new URL(`${issuer}/.well-known/jwks.json`));\n jwksByIssuer.set(issuer, jwks);\n }\n try {\n const { payload } = await jwtVerify(token, jwks, { issuer });\n if (!payload.sub) return null;\n return {\n userId: payload.sub,\n email: typeof payload.email === \"string\" ? payload.email : undefined,\n payload: payload as Record<string, unknown>,\n };\n } catch {\n return null;\n }\n }\n\n function makeDb(env: ChapterEnv): Db {\n return initAdmin({ appId: env.ODLA_TENANT, adminToken: env.ODLA_API_KEY, endpoint: env.ODLA_ENDPOINT });\n }\n\n // The `admins` allowlist gate (auth source \"table\"): no route ever writes it, so\n // membership can only be granted by a human in odla Studio.\n async function isAdminEmail(db: Db, email: string | undefined): Promise<boolean> {\n if (!email) return false;\n const { admins } = await db.query({ admins: { $: { where: { email: email.toLowerCase() }, limit: 1 } } });\n return Array.isArray(admins) && admins.length > 0;\n }\n\n // The read-only `superAdmins` tier — queried, never written (Studio-only).\n async function isSuperAdminEmail(db: Db, email: string | undefined): Promise<boolean> {\n if (!auth.superAdmins || !email) return false;\n const { superAdmins } = await db.query({ superAdmins: { $: { where: { email: email.toLowerCase() }, limit: 1 } } });\n return Array.isArray(superAdmins) && superAdmins.length > 0;\n }\n\n // The user's role, resolved per the auth source: a JWT claim, or the `admins`\n // allowlist synthesized to the admin rung / the lowest one.\n async function roleFor(db: Db, u: Verified): Promise<string> {\n if (auth.source === \"claim\") return roleFromClaim(u.payload, auth);\n return (await isAdminEmail(db, u.email)) ? auth.adminRole : (auth.ladder[0] as string);\n }\n\n // Admin authorization — the boolean gate used by /api/me and the CRM surface.\n async function isAdmin(db: Db, u: Verified): Promise<boolean> {\n if (auth.source === \"claim\") return isAdminRole(roleFromClaim(u.payload, auth), auth);\n return isAdminEmail(db, u.email);\n }\n\n function crmSender(env: ChapterEnv) {\n if (!env.SEND_EMAIL || !env.EMAIL_FROM) return undefined;\n const binding = env.SEND_EMAIL;\n return {\n async send(payload: EmailPayload): Promise<{ messageId: string }> {\n return binding.send(payload);\n },\n };\n }\n\n return { chapter, auth, crmBase, getPublicConfig, verifyUser, makeDb, isAdminEmail, isSuperAdminEmail, roleFor, isAdmin, crmSender };\n}\n\n/** The value returned by {@link createWorkerContext}, threaded to every route. */\nexport type WorkerContext = ReturnType<typeof createWorkerContext>;\n\n/** A worker route handler: owns the request (returns a Response) or falls through\n * (returns null). Host routes passed to `chapterWorker` compose against the same\n * {@link WorkerContext} the built-ins receive. */\nexport type Route = (req: Request, url: URL, env: ChapterEnv, ctx: WorkerContext) => Promise<Response | null>;\n","// Identity + authorization for a chapter/hub site — the pieces every membership\n// site needs and none should re-derive: a resolved role policy, role resolution\n// from a JWT claim, the privilege-escalation guard, and a tenant-vault read.\n// Everything here is pure or structural (no runtime @odla-ai/db import), so it is\n// trivially testable and the worker stays the only thing that talks to odla-db.\nimport type { ChapterAuth, ChapterMode, ResolvedAuth } from \"./types\";\n\n/**\n * Apply defaults + validate the auth config into a {@link ResolvedAuth}. Defaults\n * by mode: `chapter` → the `provisional/member/admin` claim ladder with the\n * `superAdmins` tier; `hub` → the `admins` allowlist table with no super tier.\n * Throws at import on a bad policy.\n */\nexport function resolveAuth(mode: ChapterMode, auth: ChapterAuth | undefined): ResolvedAuth {\n const a = auth ?? {};\n const source = a.source ?? (mode === \"hub\" ? \"table\" : \"claim\");\n if (source !== \"claim\" && source !== \"table\") {\n throw new Error(`defineChapter.auth.source: must be \"claim\" or \"table\" — got ${JSON.stringify(a.source)}`);\n }\n const claim = a.claim ?? \"role\";\n if (typeof claim !== \"string\" || claim === \"\") {\n throw new Error(\"defineChapter.auth.claim: must be a non-empty string\");\n }\n const ladder = a.ladder ?? [\"provisional\", \"member\", \"admin\"];\n if (!Array.isArray(ladder) || ladder.length === 0 || !ladder.every((r) => typeof r === \"string\" && r !== \"\")) {\n throw new Error(\"defineChapter.auth.ladder: must be a non-empty array of role strings\");\n }\n const adminRole = ladder[ladder.length - 1] as string;\n const superAdmins = a.superAdmins ?? source === \"claim\";\n return { source, claim, ladder, adminRole, superAdmins };\n}\n\n/** The role from a verified JWT payload, per the resolved policy. An unknown or\n * missing claim falls back to the lowest ladder rung (fail safe, never admin). */\nexport function roleFromClaim(payload: Record<string, unknown>, auth: ResolvedAuth): string {\n const raw = payload[auth.claim];\n return typeof raw === \"string\" && auth.ladder.includes(raw) ? raw : (auth.ladder[0] as string);\n}\n\n/** Does a role meet the admin bar (the highest ladder rung)? */\nexport function isAdminRole(role: string, auth: ResolvedAuth): boolean {\n return role === auth.adminRole;\n}\n\n/** Inputs to the role-change guard — resolved by the caller (route) from the\n * identity provider + the read-only `superAdmins` table. */\nexport interface RoleChangeContext {\n actorId: string;\n actorIsSuper: boolean;\n targetId: string;\n targetCurrentRole: string;\n targetIsSuper: boolean;\n newRole: string;\n auth: ResolvedAuth;\n}\n\n/** The result of {@link canChangeRole}: allow, or deny with the HTTP status +\n * message the route should return. */\nexport type GuardResult = { ok: true } | { ok: false; status: number; error: string };\n\n/**\n * The privilege-escalation guard — package-enforced so every site gets it and\n * none re-derives it. Denies: an out-of-ladder role; changing your own role;\n * touching a super-admin unless you are one; and (when a `superAdmins` tier\n * exists) creating or altering an admin unless you are a super-admin. Note the\n * super-admin tier itself is never writable here — it lives in the read-only\n * `superAdmins` table, set only in odla Studio.\n */\nexport function canChangeRole(ctx: RoleChangeContext): GuardResult {\n const { auth } = ctx;\n if (!auth.ladder.includes(ctx.newRole)) {\n return { ok: false, status: 400, error: `role must be one of: ${auth.ladder.join(\", \")}` };\n }\n if (ctx.actorId === ctx.targetId) {\n return { ok: false, status: 400, error: \"you cannot change your own role\" };\n }\n if (ctx.targetIsSuper && !ctx.actorIsSuper) {\n return { ok: false, status: 403, error: \"this person is a super-admin; their access is managed in odla Studio\" };\n }\n const touchesAdmin = ctx.newRole === auth.adminRole || ctx.targetCurrentRole === auth.adminRole;\n if (auth.superAdmins && touchesAdmin && !ctx.actorIsSuper) {\n return { ok: false, status: 403, error: `only super-admins can create or change an ${auth.adminRole}` };\n }\n return { ok: true };\n}\n\n/** Structural view of odla-db's tenant-vault read, so chapter takes no runtime\n * dependency on @odla-ai/db. The worker's admin client satisfies this. */\nexport interface SecretStore {\n secrets: { get(name: string): Promise<string> };\n}\n\n/**\n * Read a tenant-vault secret by name; `undefined` when it is absent or the vault\n * errors, so callers degrade gracefully (e.g. `paymentsReady: false`) rather than\n * throwing. Never logs the value.\n */\nexport async function getVaultSecret(db: SecretStore, name: string): Promise<string | undefined> {\n try {\n const value = await db.secrets.get(name);\n return typeof value === \"string\" && value !== \"\" ? value : undefined;\n } catch {\n return undefined;\n }\n}\n","// Route handlers for the chapter Worker. Each returns a Response when it owns the\n// request, or null to fall through to the next handler (finally ASSETS). Split\n// out of worker.ts so the entry stays a thin composer under the per-file LOC cap;\n// behaviour and route order are unchanged from the original single-file handler.\nimport { createCrmRoutes } from \"@odla-ai/crm\";\nimport { authorizeCrmDiscussionReference } from \"./discussion-reference-security\";\nimport { getVaultSecret, isAdminRole } from \"./auth\";\nimport { joinConfig, submitApplication } from \"./member\";\nimport { joinConfigTiers } from \"./tiers\";\nimport { loadOfferableTiers, loadTiers } from \"./tiers-store\";\nimport { resolveScheduling } from \"./scheduling\";\nimport { findAdmissionGrant } from \"./admission-grants\";\nimport { normalizeChapterEmail } from \"./email-identity\";\nimport { chapterFlowFieldContract } from \"./flow-fields\";\nimport { findGiftOffer, publicGiftOffers } from \"./gift-offers\";\nimport { continueJoin } from \"./join-continuation-server\";\nimport { controlledApplication, loadActiveSignupControl } from \"./signup-control-store\";\nimport { memberApplication } from \"./session\";\nimport type { ApplicationRecord, MeetingRecord, MemberApplication } from \"./session\";\nimport { json } from \"./worker-context\";\nimport type { Route } from \"./worker-context\";\nimport type { ChapterDb, ChapterScheduling } from \"./types\";\nimport {\n notifyAdminOfApplication,\n provisionApplicant,\n syncApplicantPrivateMetadata,\n} from \"./worker-provisioning\";\n\nexport type { Route };\n\n// The signed-in member's own application (chapter mode): the latest by email,\n// folded with its latest scheduled meeting and rendered in the group's timezone.\n// The meetings row is canonical, so no live-calendar reconcile is needed here.\nasync function memberSessionApplication(\n db: ChapterDb,\n chapterId: string,\n email: string,\n): Promise<{ application: MemberApplication; source: Record<string, unknown> } | null> {\n let apps = (await db.query({ applications: { $: {\n where: { emailNormalized: normalizeChapterEmail(email) }, limit: 20,\n } } })).applications;\n if (!apps?.length) apps = (await db.query({ applications: { $: { where: { email }, limit: 20 } } })).applications;\n const app = Array.isArray(apps) ? [...apps].sort((a, b) => Number(b.createdAt ?? 0) - Number(a.createdAt ?? 0))[0] : undefined;\n if (!app) return null;\n const meetings = (\n await db.query({ meetings: { $: { where: { applicationId: app.id, status: \"scheduled\" }, order: { createdAt: \"desc\" }, limit: 1 } } })\n ).meetings;\n const meeting = Array.isArray(meetings) ? meetings[0] : undefined;\n const groups = (await db.query({ groups: { $: { where: { id: chapterId }, limit: 1 } } })).groups;\n const group = Array.isArray(groups) ? groups[0] : undefined;\n const timezone = resolveScheduling(group?.schedulingJson as ChapterScheduling | undefined).timezone;\n return {\n application: memberApplication(app as unknown as ApplicationRecord, meeting as unknown as MeetingRecord | undefined, timezone),\n source: app,\n };\n}\n\n/** GET /api/health — a public liveness probe (what deploy checks hit). */\nexport const handleHealth: Route = async (_req, url) => (url.pathname === \"/api/health\" ? json({ ok: true }) : null);\n\n/** GET /api/config — the public Clerk publishable key, so the SPA can boot sign-in. */\nexport const handleConfig: Route = async (_req, url, env, ctx) => {\n if (url.pathname !== \"/api/config\") return null;\n try {\n const { clerkPublishableKey } = await ctx.getPublicConfig(env);\n return json({ clerkPublishableKey: clerkPublishableKey ?? null, env: env.ODLA_ENV });\n } catch {\n return json({ clerkPublishableKey: null, env: env.ODLA_ENV });\n }\n};\n\n/** GET /api/me — the signed-in user's role, admin authorization, and super-admin\n * tier. In chapter mode it also carries the member's own `application` (their\n * status + booked call), so the member area renders from one call. */\nexport const handleMe: Route = async (req, url, env, ctx) => {\n if (url.pathname !== \"/api/me\") return null;\n const u = await ctx.verifyUser(req, env);\n if (!u) return json({ authorized: false }, 401);\n const db = ctx.makeDb(env);\n const role = await ctx.roleFor(db, u);\n const superAdmin = await ctx.isSuperAdminEmail(db, u.email);\n const base = { authorized: isAdminRole(role, ctx.auth), role, superAdmin, email: u.email ?? null };\n if (ctx.chapter.mode !== \"chapter\" || !u.email) return json(base);\n const member = await memberSessionApplication(db as unknown as ChapterDb, ctx.chapter.id, u.email);\n let privateMetadataSynced = false;\n if (\n member &&\n ctx.chapter.account !== \"none\" &&\n typeof member.source.clerkPrivateMetadataSyncedAt !== \"number\"\n ) {\n // Invitation metadata cannot be private. Complete that write after the\n // accepted account first authenticates; the marker makes later /api/me\n // reads database-only. Existing pre-private-metadata accounts take the same\n // path once, which also removes Chapter's former public profile keys.\n privateMetadataSynced = await syncApplicantPrivateMetadata(\n db as unknown as ChapterDb,\n ctx.chapter,\n String(member.source.id),\n member.source,\n u.userId,\n );\n }\n if (member && !privateMetadataSynced && member.source.clerkUserId !== u.userId) {\n // Identity linking is independent of the best-effort metadata mirror. A\n // failed Clerk PATCH must not hide a verified application↔account match,\n // and a directly-created account may already be marked synced before its\n // first session reveals the user id.\n await (db as unknown as ChapterDb).transact([{\n t: \"update\",\n ns: \"applications\",\n id: String(member.source.id),\n attrs: { clerkUserId: u.userId },\n }]).catch(() => undefined);\n }\n return json({ ...base, application: member?.application ?? null });\n};\n\n/** /api/crm/* — the CRM admin surface (mounted at ctx.crmBase). */\nexport const handleCrm: Route = async (req, url, env, ctx) => {\n const crmBase = ctx.crmBase;\n if (url.pathname !== crmBase && !url.pathname.startsWith(crmBase + \"/\")) return null;\n const db = ctx.makeDb(env);\n const routes = createCrmRoutes({\n crm: ctx.chapter.crm,\n db: db as never,\n authorize: async (r: Request) => {\n const u = await ctx.verifyUser(r, env);\n if (!u || !(await ctx.isAdmin(db, u))) return null;\n return u.email ? { userId: u.userId, email: u.email } : { userId: u.userId };\n },\n authorizeDiscussionReferences: (r: Request) =>\n authorizeCrmDiscussionReference(r, env),\n sender: ctx.crmSender(env),\n from: env.EMAIL_FROM,\n envName: env.ODLA_ENV,\n baseUrl: url.origin,\n basePath: crmBase,\n });\n const res = await routes(req);\n if (res) return res;\n return json({ error: \"not found\" }, 404);\n};\n\n/** Chapter-mode public member surface: GET /api/join-config, POST /api/applications.\n * Returns null in hub mode so those paths fall through to ASSETS. */\nexport const handleMember: Route = async (req, url, env, ctx) => {\n const chapter = ctx.chapter;\n if (chapter.mode !== \"chapter\") return null;\n\n // Public join config: prices + policy copy + payment readiness (B1/C2).\n if (req.method === \"GET\" && url.pathname === \"/api/join-config\") {\n const db = ctx.makeDb(env);\n const groupId = url.searchParams.get(\"group\") ?? chapter.id;\n const { groups } = await db.query({ groups: { $: { where: { id: groupId }, limit: 1 } } });\n const group = Array.isArray(groups) ? groups[0] : undefined;\n if (!group) return json({ error: \"not found\" }, 404);\n const stripeKey = await getVaultSecret(db as unknown as ChapterDb, \"stripe_secret_key\");\n const paymentsReady = Boolean(group.stripePublishableKey && group.stripePriceId && stripeKey);\n const offered = await loadOfferableTiers(\n db as unknown as ChapterDb, group as never, Boolean(stripeKey),\n );\n const activeControl = chapter.signupControl\n ? await loadActiveSignupControl(db as unknown as ChapterDb, chapter.id, env.ODLA_ENV)\n : null;\n const application = controlledApplication(chapter.application, activeControl?.document);\n return json({\n ...joinConfig(group as never, paymentsReady, joinConfigTiers(offered), application.conditions),\n fieldContract: chapterFlowFieldContract(chapter, \"join\", application),\n copy: { ...chapter.copy.join, ...(activeControl?.document.application?.copy ?? {}) },\n ...(activeControl ? { signupControl: {\n revision: activeControl.revision,\n digest: activeControl.digest,\n membershipPage: activeControl.document.membershipPage,\n application: activeControl.document.application,\n theme: activeControl.document.theme,\n } } : {}),\n giftOffers: publicGiftOffers(activeControl?.document.giftOffers, Date.now()),\n });\n }\n\n // Resume a redirect-interrupted join flow from canonical database state. The\n // application id is the existing unguessable capability used by payment and\n // booking routes; this response exposes no applicant fields.\n if (req.method === \"GET\" && url.pathname === \"/api/join/resume\") {\n const applicationId = url.searchParams.get(\"application\") ?? \"\";\n if (!applicationId) return json({ error: \"application is required\" }, 400);\n const db = ctx.makeDb(env) as unknown as ChapterDb;\n const apps = (await db.query({\n applications: { $: { where: { id: applicationId }, limit: 1 } },\n })).applications;\n const app = Array.isArray(apps) ? apps[0] : undefined;\n if (!app || String(app.groupId ?? \"\") !== chapter.id) return json({ error: \"not found\" }, 404);\n\n const meetings = (await db.query({\n meetings: {\n $: {\n where: { applicationId, status: \"scheduled\" },\n order: { createdAt: \"desc\" },\n limit: 1,\n },\n },\n })).meetings;\n const meeting = Array.isArray(meetings) ? meetings[0] : undefined;\n if (meeting && typeof meeting.startAt === \"number\") {\n const groups = (await db.query({\n groups: { $: { where: { id: chapter.id }, limit: 1 } },\n })).groups;\n const group = Array.isArray(groups) ? groups[0] : undefined;\n const timezone = resolveScheduling(group?.schedulingJson as ChapterScheduling | undefined).timezone;\n return json({\n state: \"done\",\n applicationId,\n booked: { startAt: meeting.startAt, timezone },\n });\n }\n\n const groups = (await db.query({\n groups: { $: { where: { id: chapter.id }, limit: 1 } },\n })).groups;\n const group = Array.isArray(groups) ? groups[0] : undefined;\n if (!group) return json({ error: \"not found\" }, 404);\n const state = await continueJoin(db, ctx, env, url.origin, app, group);\n if (state) return json({ state, applicationId, ...(state === \"gift\" ? { claimId: app.giftClaimId } : {}) });\n return json({ error: `application cannot resume from status \"${String(app.status ?? \"\")}\"` }, 409);\n }\n\n // Public application submit — validated, body-capped, idempotent (B2/B3).\n if (req.method === \"POST\" && url.pathname === \"/api/applications\") {\n const raw = await req.text();\n if (raw.length > chapter.application.bodyCap) return json({ error: \"request body too large\" }, 413);\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n const submissionId = typeof parsed.submissionId === \"string\" ? parsed.submissionId : undefined;\n const db = ctx.makeDb(env) as unknown as ChapterDb;\n const activeControl = chapter.signupControl\n ? await loadActiveSignupControl(db, chapter.id, env.ODLA_ENV)\n : null;\n const effectiveChapter = activeControl\n ? { ...chapter, application: controlledApplication(chapter.application, activeControl.document) }\n : chapter;\n // Resolve the offered tiers only when the applicant claims one, so a\n // chapter that never uses tiers pays for no extra read.\n const offeredTierIds = typeof parsed.tierId === \"string\" && parsed.tierId\n ? (await loadTiers(db, { id: chapter.id })).map((tier) => tier.id)\n : undefined;\n const now = Date.now();\n const requestedGiftId = typeof parsed.giftOfferId === \"string\" ? parsed.giftOfferId : \"\";\n const giftOffer = requestedGiftId ? findGiftOffer(activeControl?.document.giftOffers, requestedGiftId, now) : null;\n if (requestedGiftId && !giftOffer) return json({ error: \"gift offer is unavailable\" }, 400);\n const effectiveGrant = !giftOffer && typeof parsed.email === \"string\"\n ? await findAdmissionGrant(db, chapter.id, parsed.email, now)\n : null;\n const result = await submitApplication(db, effectiveChapter, parsed, {\n submissionId,\n groupId: chapter.id,\n now,\n newId: () => crypto.randomUUID(),\n ...(offeredTierIds ? { tierIds: offeredTierIds } : {}),\n ...(effectiveGrant?.decision === \"waive_interview\" ? { admissionGrant: effectiveGrant } : {}),\n ...(giftOffer ? { giftOfferId: giftOffer.id } : {}),\n });\n if (!result.ok) return json({ error: result.error }, 400);\n if (!result.duplicate) {\n // The trigger is declarative (sends.adminNotification); addressing + copy\n // stay owner-editable on the group row.\n if (effectiveChapter.sends.adminNotification === \"submit\") {\n await notifyAdminOfApplication(db, env, chapter.id, result.id, parsed);\n }\n await provisionApplicant(db, effectiveChapter, result.id, parsed);\n }\n const apps = (await db.query({ applications: { $: { where: { id: result.id }, limit: 1 } } })).applications;\n const canonical = Array.isArray(apps) ? apps[0] : undefined;\n const groups = (await db.query({ groups: { $: { where: { id: chapter.id }, limit: 1 } } })).groups;\n const group = Array.isArray(groups) ? groups[0] : undefined;\n const state = canonical && group\n ? await continueJoin(db, ctx, env, url.origin, canonical, group)\n : null;\n return json({\n id: result.id,\n duplicate: result.duplicate,\n status: result.status,\n ...(state ? { state } : {}),\n // Echoed so a site can see (and assert in an integration test) whether its\n // join page actually posted the ack. Absent consent is otherwise invisible.\n disclaimerAckAt: result.disclaimerAckAt,\n });\n }\n\n return null;\n};\n","import type { CrmDiscussionReferenceActor } from \"@odla-ai/crm\";\nimport type { ChapterEnv } from \"./worker-context\";\n\ninterface Verification {\n actor?: { id?: unknown; kind?: unknown; email?: unknown };\n authority?: {\n appId?: unknown;\n appIncarnation?: unknown;\n appEnv?: unknown;\n capability?: unknown;\n product?: unknown;\n projectCapability?: unknown;\n audience?: unknown;\n };\n}\n\n/**\n * Verify Registry's short-lived CRM reference assertion. This deliberately\n * grants only product reference reads; CRM mutations retain Chapter's Clerk\n * admin gate and never accept this token.\n */\nexport async function authorizeCrmDiscussionReference(\n req: Request,\n env: ChapterEnv,\n fetcher: typeof fetch = fetch,\n): Promise<CrmDiscussionReferenceActor | null> {\n const match = req.headers.get(\"authorization\")?.match(/^Bearer ([^\\s]+)$/);\n const appIncarnation = env.ODLA_APP_INCARNATION;\n const expectedTenant = env.ODLA_ENV === \"prod\"\n ? env.ODLA_APP_ID\n : `${env.ODLA_APP_ID}--${env.ODLA_ENV}`;\n if (\n !match ||\n env.ODLA_TENANT !== expectedTenant ||\n typeof appIncarnation !== \"string\" ||\n !/^[a-f0-9]{32}$/.test(appIncarnation)\n ) return null;\n const requestUrl = new URL(req.url);\n requestUrl.search = \"\";\n requestUrl.hash = \"\";\n const audience = requestUrl.href;\n try {\n const url = new URL(\n \"/registry/discuss/reference-authority/verify\",\n env.ODLA_PLATFORM,\n );\n const response = await fetcher(url, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({\n token: match[1],\n appId: env.ODLA_APP_ID,\n appIncarnation,\n env: env.ODLA_ENV,\n product: \"crm\",\n projectCapability: \"crm.read\",\n audience,\n }),\n redirect: \"manual\",\n });\n if (!response.ok) return null;\n const value = await response.json() as Verification;\n if (\n value.authority?.appId !== env.ODLA_APP_ID ||\n value.authority.appIncarnation !== appIncarnation ||\n value.authority.appEnv !== env.ODLA_ENV ||\n value.authority.capability !== \"product.reference.read\" ||\n value.authority.product !== \"crm\" ||\n value.authority.projectCapability !== \"crm.read\" ||\n value.authority.audience !== audience ||\n typeof value.actor?.id !== \"string\" ||\n (value.actor.kind !== \"human\" && value.actor.kind !== \"agent\") ||\n (value.actor.email !== undefined &&\n typeof value.actor.email !== \"string\")\n ) return null;\n return {\n userId: value.actor.id,\n discussionReferenceScope: \"all\",\n ...(value.actor.email ? { email: value.actor.email } : {}),\n };\n } catch {\n return null;\n }\n}\n","// The public member surface logic: the join config a site's join page reads (B1)\n// and the idempotent application submit (B2 validation + B3 exactly-once). Both\n// take the structural ChapterDb, so they're tested against an in-memory fake and\n// carry no runtime @odla-ai/db import. The worker builds the real db client, does\n// Clerk verification, enforces the body cap, and mounts these on chapter routes.\nimport type { Chapter, ChapterApplication, ChapterDb, ResolvedApplication } from \"./types\";\nimport { assertFieldCondition, resolveFieldStates } from \"@odla-ai/crm\";\nimport type { FieldConditions } from \"@odla-ai/crm\";\nimport { applicationIdForSubmission } from \"./application-id\";\nimport type { JoinConfigTier } from \"./tiers\";\nimport type { AdmissionGrantRow } from \"./admission-grants\";\nimport { normalizeChapterEmail } from \"./email-identity\";\n\n// The reference join form. `focus` (a json field) is always accepted.\nconst DEFAULT_REQUIRED = [\"firstName\", \"lastName\", \"email\", \"referral\", \"whoYouAre\", \"message\"];\nconst DEFAULT_OPTIONAL = [\"referralName\", \"linkedin\", \"phone\", \"state\"];\nconst SCHEMA_FIELD = /^[A-Za-z_][A-Za-z0-9_-]*$/;\n\n/** Apply defaults + validate the application config. Throws at import on bad shape. */\nexport function resolveApplication(a: ChapterApplication | undefined): ResolvedApplication {\n const required = a?.required ?? DEFAULT_REQUIRED;\n const optional = a?.optional ?? DEFAULT_OPTIONAL;\n for (const [name, arr] of [[\"required\", required], [\"optional\", optional]] as const) {\n if (!Array.isArray(arr) || !arr.every((f) => typeof f === \"string\" && f !== \"\")) {\n throw new Error(`defineChapter.application.${name}: must be an array of field-name strings`);\n }\n const unsafe = arr.find((field) => !SCHEMA_FIELD.test(field));\n if (unsafe) {\n throw new Error(`defineChapter.application.${name}: field \"${unsafe}\" must match ${SCHEMA_FIELD.source}`);\n }\n }\n const duplicate = [...required, ...optional].find((field, index, fields) => fields.indexOf(field) !== index);\n if (duplicate) {\n throw new Error(`defineChapter.application: duplicate field \"${duplicate}\" across required/optional lists`);\n }\n if (a?.profileFields !== undefined && (!Array.isArray(a.profileFields) || !a.profileFields.every((f) => typeof f === \"string\" && f !== \"\"))) {\n throw new Error(\"defineChapter.application.profileFields: must be an array of field-name strings\");\n }\n if (a?.crmFields !== undefined && (!Array.isArray(a.crmFields) || !a.crmFields.every((f) => typeof f === \"string\" && f !== \"\"))) {\n throw new Error(\"defineChapter.application.crmFields: must be an array of field-name strings\");\n }\n // Conditions are checked when the chapter is defined, so a typo fails at\n // startup rather than quietly misbehaving on a live join page. Fields that\n // fail open at runtime are the deliberate second line of defence, not this.\n const conditions = a?.conditions ?? {};\n for (const [field, declared] of Object.entries(conditions)) {\n for (const key of [\"visibleWhen\", \"requiredWhen\"] as const) {\n const expression = declared?.[key];\n if (expression === undefined) continue;\n if (typeof expression !== \"string\" || !expression.trim()) {\n throw new Error(`defineChapter.application.conditions.${field}.${key}: must be a non-empty CEL condition`);\n }\n assertFieldCondition(expression, `defineChapter.application.conditions.${field}.${key}`);\n }\n }\n return {\n required,\n optional,\n conditions,\n maxLen: a?.maxLen ?? {},\n defaultMaxLen: a?.defaultMaxLen ?? 2000,\n bodyCap: a?.bodyCap ?? 32768,\n requireDisclaimerAck: a?.requireDisclaimerAck ?? true,\n profileFields: a?.profileFields ?? [],\n crmFields: a?.crmFields ?? [],\n maxArrayLen: a?.maxArrayLen ?? 100,\n validateEmail: a?.validateEmail ?? true,\n };\n}\n\n// A permissive email shape check: one @, a dot-bearing domain, no whitespace.\n// Deliberately not RFC-exhaustive — the goal is to reject \"notanemail\" before it\n// fails the downstream Clerk create, not to adjudicate exotic-but-valid addresses.\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\n/** Whether a string looks like an email address (see {@link EMAIL_RE}). Exported\n * so a site building its own submit path applies the same rule chapter does. */\nexport function isValidEmail(value: unknown): boolean {\n return typeof value === \"string\" && EMAIL_RE.test(value);\n}\n\n/** Bound an array-valued field: drop non-primitive elements and cap the length,\n * so a client cannot post an unbounded array. Non-arrays pass through unchanged. */\nexport function clampArray(value: unknown, max: number): unknown {\n if (!Array.isArray(value)) return value;\n return value.filter((x) => typeof x === \"string\" || typeof x === \"number\" || typeof x === \"boolean\").slice(0, max);\n}\n\n/** Whether a submit body carries a genuine disclaimer acknowledgement. Accepts\n * the boolean an API client sends and the string a plain HTML form posts. */\nexport function hasDisclaimerAck(fields: Record<string, unknown>): boolean {\n return fields.disclaimerAck === true || fields.disclaimerAck === \"true\";\n}\n\n// Clerk carries these as first-class user fields, so repeating them in\n// public_metadata would be duplicated state that can drift.\nconst IDENTITY_FIELDS = new Set([\"email\", \"firstName\", \"lastName\"]);\n\n/**\n * The applicant profile written to the Clerk account's backend-only\n * `private_metadata.profile`. Projects each configured non-identity field, plus\n * `focus` (clamped), but ONLY those in `application.profileFields`. Derived\n * from config, so a site's own field names project without this package knowing\n * them. Pure; returns `undefined` when there is nothing to write.\n */\nexport function applicantProfile(\n chapter: Chapter,\n fields: Record<string, unknown>,\n): Record<string, unknown> | undefined {\n const app = chapter.application;\n const allowed = (f: string): boolean => app.profileFields.includes(f);\n const profile: Record<string, unknown> = {};\n for (const f of [...app.required, ...app.optional]) {\n if (IDENTITY_FIELDS.has(f) || !allowed(f)) continue;\n const v = fields[f];\n if (typeof v === \"string\" && v.trim() !== \"\") profile[f] = v.trim();\n }\n if (fields.focus !== undefined && allowed(\"focus\")) profile.focus = clampArray(fields.focus, app.maxArrayLen);\n return Object.keys(profile).length > 0 ? profile : undefined;\n}\n\n/** A validated submission, or a 400-worthy validation error the route returns.\n * `disclaimerAckAt` reports what THIS request recorded — a number when consent\n * was stamped, `null` when none was supplied. It is always present so a missing\n * consent record is visible in the response rather than silently absent from a\n * row nobody reads until an audit. */\nexport type SubmitResult =\n | { ok: true; id: string; duplicate: boolean; status: string; disclaimerAckAt: number | null }\n | { ok: false; error: string };\n\n/**\n * Submit a membership application (B2 + B3). Validates the configured required\n * fields + max lengths, writes the `applications` row at the pipeline's initial\n * status, and — when the client supplies a `submissionId` — stamps it as the\n * transaction's mutationId (`join:${submissionId}`) so a double-tap can never\n * create two applications. The application id is derived from that same stable\n * input, so the duplicate response returns the first request's canonical id\n * rather than a fresh, nonexistent one. Idempotency is package-enforced.\n * `now`/`newId` are injected (deterministic in tests).\n */\nexport async function submitApplication(\n db: ChapterDb,\n chapter: Chapter,\n fields: Record<string, unknown>,\n opts: {\n submissionId?: string;\n groupId?: string;\n now: number;\n newId: () => string;\n /** Tier ids this chapter offers. A posted `tierId` outside it is refused;\n * omit to accept any (pre-tier callers). */\n tierIds?: readonly string[];\n /** Effective one-use waiver selected by the server, never by the client. */\n admissionGrant?: AdmissionGrantRow;\n /** Server-validated gift offer selected from active signed control. */\n giftOfferId?: string;\n },\n): Promise<SubmitResult> {\n const app = chapter.application;\n // Requiredness is resolved against the answers, not read off a static list,\n // so a conditionally-hidden field is not demanded and a conditionally-\n // required one cannot be skipped by posting straight to this route. The\n // renderer calls the same resolver, so the form and the validator cannot\n // disagree. With no conditions declared this is exactly the old static loop.\n const fieldStates = resolveFieldStates(app.conditions ?? {}, fields, app.required);\n for (const [f, state] of Object.entries(fieldStates)) {\n if (!state.required) continue;\n const v = fields[f];\n if (typeof v !== \"string\" || v.trim() === \"\") return { ok: false, error: `${f} is required` };\n }\n for (const f of [...app.required, ...app.optional]) {\n const v = fields[f];\n const cap = app.maxLen[f] ?? app.defaultMaxLen;\n if (typeof v === \"string\" && v.length > cap) return { ok: false, error: `${f} exceeds ${cap} characters` };\n }\n // A malformed email can only fail the downstream Clerk create; reject it here\n // as a clean 400. A valid application always has a valid email, so no genuine\n // submission is newly rejected.\n if (app.validateEmail && typeof fields.email === \"string\" && !isValidEmail(fields.email.trim())) {\n return { ok: false, error: \"email must be a valid email address\" };\n }\n\n const acked = hasDisclaimerAck(fields);\n if (app.requireDisclaimerAck && !acked) {\n return { ok: false, error: \"disclaimerAck is required\" };\n }\n\n const id = opts.submissionId\n ? await applicationIdForSubmission(opts.submissionId)\n : opts.newId();\n const row: Record<string, unknown> = { id, status: chapter.pipeline.initial, createdAt: opts.now };\n for (const f of [...app.required, ...app.optional]) {\n // A field the conditions hid was never asked, so a value for it is stale\n // or forged. Storing it would answer a question on the applicant's behalf.\n if (fieldStates[f]?.visible === false) continue;\n if (typeof fields[f] === \"string\") row[f] = (fields[f] as string).trim();\n }\n if (fields.focus !== undefined) row.focus = clampArray(fields.focus, app.maxArrayLen);\n if (opts.groupId) row.groupId = opts.groupId;\n if (typeof fields.email === \"string\" && isValidEmail(fields.email.trim())) {\n row.emailNormalized = normalizeChapterEmail(fields.email);\n }\n if (opts.admissionGrant?.decision === \"waive_interview\") {\n row.admissionGrantId = opts.admissionGrant.id;\n row.admissionSource = opts.admissionGrant.sourceScope;\n row.interviewWaivedAt = opts.now;\n }\n if (opts.giftOfferId) row.giftOfferId = opts.giftOfferId;\n // A tier decides what this member is charged, so the posted id is checked\n // against what the chapter actually offers rather than trusted. An unknown\n // id is refused instead of silently dropped: dropping it would bill the\n // applicant whatever the fallback tier costs.\n if (typeof fields.tierId === \"string\" && fields.tierId) {\n if (opts.tierIds && !opts.tierIds.includes(fields.tierId)) {\n return { ok: false, error: \"tierId is not an offered tier\" };\n }\n row.tierId = fields.tierId;\n }\n // The disclaimer acknowledgement is a compliance record, so it is stamped from\n // the server clock on a genuine ack and left absent otherwise — a client-supplied\n // timestamp would be forgeable, and a row that always carries one would record\n // consent nobody gave.\n if (acked) row.disclaimerAckAt = opts.now;\n\n const ops: Parameters<ChapterDb[\"transact\"]>[0] = [\n { t: \"update\", ns: \"applications\", id, attrs: row },\n ];\n if (opts.admissionGrant?.decision === \"waive_interview\") {\n ops.push({ t: \"update\", ns: \"admissionGrants\", id: opts.admissionGrant.id, attrs: {\n consumedAt: opts.now,\n consumedApplicationId: id,\n } });\n }\n const { duplicate } = await db.transact(\n ops,\n opts.submissionId ? { mutationId: `join:${opts.submissionId}` } : undefined,\n );\n return { ok: true, id, duplicate, status: chapter.pipeline.initial, disclaimerAckAt: acked ? opts.now : null };\n}\n\n/** The `groups`-row fields the join config exposes. */\nexport interface JoinConfigGroup {\n id: string;\n name: string;\n standardPriceCents?: number;\n foundingDiscountCents?: number;\n disclaimerText?: string;\n refundPolicyText?: string;\n trustCopy?: string;\n commitmentText?: string;\n normsText?: string;\n}\n\n/**\n * The public join config (B1) a site's join page reads: copy + prices from the\n * group row plus `paymentsReady`. When payments aren't wired the join flow drops\n * the payment step (C2) — the worker computes `paymentsReady` from the group's\n * Stripe keys + vault secret. Pure.\n *\n * `tiers` carries the offerable membership tiers. It is additive: the legacy\n * `standardPriceCents`/`foundingDiscountCents` fields still describe the first\n * tier, so a join page written before tiers keeps rendering unchanged. A free\n * tier appears here with `free: true` even when Stripe is unconfigured, because\n * nothing needs charging for it.\n */\nexport function joinConfig(\n group: JoinConfigGroup,\n paymentsReady: boolean,\n tiers: readonly JoinConfigTier[] = [],\n conditions: Readonly<Record<string, FieldConditions>> = {},\n): Record<string, unknown> {\n return {\n id: group.id,\n name: group.name,\n standardPriceCents: group.standardPriceCents ?? 0,\n foundingDiscountCents: group.foundingDiscountCents ?? 0,\n tiers: [...tiers],\n // The browser evaluates the same conditions the server enforces.\n conditions,\n disclaimerText: group.disclaimerText ?? \"\",\n refundPolicyText: group.refundPolicyText ?? \"\",\n trustCopy: group.trustCopy ?? \"\",\n commitmentText: group.commitmentText ?? \"\",\n normsText: group.normsText ?? \"\",\n paymentsReady,\n };\n}\n","// Application creates use a caller-stable submission id as their database\n// mutation id. The entity id must be derived from that same stable input: if a\n// committed request is retried, the database correctly skips the new ops and\n// Chapter must still return the id of the row written by the first request.\n\nconst APPLICATION_ID_DOMAIN = \"odla-ai/chapter/application/v1:\";\n\n/**\n * Derive the UUID-shaped capability for an idempotent application submission.\n * SHA-256 prevents a caller from choosing a submission id that overwrites a\n * known application id; UUIDv8 bits preserve the identifier shape consumers\n * already expect.\n */\nexport async function applicationIdForSubmission(submissionId: string): Promise<string> {\n const input = new TextEncoder().encode(`${APPLICATION_ID_DOMAIN}${submissionId}`);\n const bytes = new Uint8Array(await crypto.subtle.digest(\"SHA-256\", input)).slice(0, 16);\n bytes[6] = (bytes[6]! & 0x0f) | 0x80;\n bytes[8] = (bytes[8]! & 0x3f) | 0x80;\n const hex = [...bytes].map((byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n}\n","/**\n * Normalize an email address for Chapter identity lookups.\n *\n * Chapter treats the address literally: surrounding whitespace and ASCII case\n * are insignificant, but the local part is otherwise preserved. In\n * particular, provider-specific aliases are never collapsed, so\n * `foo+bar@gmail.com` and `foo@gmail.com` remain distinct applicants,\n * admission decisions, purchasers, and beneficiaries.\n */\nexport function normalizeChapterEmail(email: string): string {\n return email.trim().toLowerCase();\n}\n","// Membership tiers. A chapter offers one or more tiers, and a tier — not the\n// group — decides what a member pays. Keeping the price on the tier is what\n// makes a free tier expressible: `paymentsReady` used to gate the whole join\n// flow on the group holding a Stripe price, so a £0 membership was unjoinable.\n//\n// Everything here is pure so the join page, the checkout route and the seeder\n// agree about which tiers exist and which of them can actually be bought.\n\n/** One membership tier a chapter offers. `priceCents: 0` means free. */\nexport interface ChapterTier {\n /** Stable slug, referenced by `applications.tierId`. Never renumbered. */\n id: string;\n /** The group this tier belongs to. */\n groupId: string;\n /** Display name, e.g. \"Founding\". */\n name: string;\n /** Price in minor units. `0` is free and needs no Stripe price. */\n priceCents: number;\n /** Stripe price to subscribe. Required only when `priceCents > 0`. */\n stripePriceId?: string | null;\n /** Short description shown beside the tier on the join page. */\n blurb?: string;\n /** Ascending display order; ties fall back to `id` for a stable sort. */\n sortOrder: number;\n /** An inactive tier is retained for existing members but never offered. */\n active: boolean;\n}\n\n/**\n * A tier as declared in `defineChapter`, before it becomes a row.\n *\n * `groupId` is absent here because the chapter owns exactly one group at seed\n * time; the seeder fills it in.\n */\nexport interface ChapterTierConfig {\n id: string;\n name: string;\n priceCents: number;\n stripePriceId?: string;\n blurb?: string;\n /** Defaults to declaration order when omitted. */\n sortOrder?: number;\n /** Defaults to true; set false to retire a tier without deleting it. */\n active?: boolean;\n}\n\n/** Build the seed rows for a chapter's declared tiers. */\nexport function buildTierSeeds(\n groupId: string,\n configured: readonly ChapterTierConfig[] = [],\n now = 0,\n): Array<Record<string, unknown>> {\n return configured.map((tier, index) => ({\n id: tier.id,\n groupId,\n name: tier.name,\n priceCents: tier.priceCents,\n ...(tier.stripePriceId ? { stripePriceId: tier.stripePriceId } : {}),\n ...(tier.blurb ? { blurb: tier.blurb } : {}),\n sortOrder: tier.sortOrder ?? index,\n active: tier.active !== false,\n createdAt: now,\n }));\n}\n\n/** The `groups`-row fields tier payability depends on. */\nexport interface TierGroup {\n id?: string;\n stripePublishableKey?: string | null;\n /** Legacy single price, used only to synthesize an implicit tier. */\n stripePriceId?: string | null;\n standardPriceCents?: number;\n foundingDiscountCents?: number;\n}\n\n/**\n * Whether this tier costs nothing. A free tier never touches Stripe.\n *\n * Free means both no price AND no Stripe price to charge against. The second\n * half matters for chapters that predate tiers: a group can carry a real\n * `stripePriceId` while `standardPriceCents` is 0, because the cents field is\n * display copy and the amount actually lives in Stripe. Reading such a group as\n * free would silently stop charging an existing paying chapter.\n */\nexport function tierIsFree(\n tier: Pick<ChapterTier, \"priceCents\"> & { stripePriceId?: string | null },\n): boolean {\n return !(tier.priceCents > 0) && !tier.stripePriceId;\n}\n\n/**\n * Whether a tier can actually be joined right now.\n *\n * A free tier is always joinable — there is nothing to charge, so Stripe being\n * unconfigured is irrelevant to it. A paid tier needs the group's publishable\n * key, its own Stripe price, and the vault secret; missing any of those drops\n * the tier rather than half-charging for it.\n */\nexport function tierPayable(\n tier: Pick<ChapterTier, \"priceCents\" | \"stripePriceId\">,\n group: TierGroup,\n hasSecretKey: boolean,\n): boolean {\n if (tierIsFree(tier)) return true;\n return Boolean(group.stripePublishableKey && tier.stripePriceId && hasSecretKey);\n}\n\n/** Sort by `sortOrder`, then `id`, so a page never reorders between reads. */\nfunction byOrder(a: ChapterTier, b: ChapterTier): number {\n return a.sortOrder - b.sortOrder || a.id.localeCompare(b.id);\n}\n\n/**\n * The tiers a chapter offers, given the stored rows.\n *\n * A chapter that predates tiers has no rows, and must keep working untouched:\n * one implicit `\"standard\"` tier is synthesized from the group's legacy\n * `standardPriceCents`/`stripePriceId` columns. That is why there is no\n * migration — an existing chapter reads exactly as it did before, and writing\n * its first real tier row takes over.\n */\nexport function resolveTiers(group: TierGroup, rows: readonly ChapterTier[] = []): ChapterTier[] {\n const stored = rows.filter((tier) => tier.active);\n if (stored.length) return [...stored].sort(byOrder);\n return [{\n id: \"standard\",\n groupId: String(group.id ?? \"\"),\n name: \"Membership\",\n priceCents: group.standardPriceCents ?? 0,\n ...(group.stripePriceId ? { stripePriceId: group.stripePriceId } : {}),\n sortOrder: 0,\n active: true,\n }];\n}\n\n/** The tiers to show on the join page: active, and joinable as configured. */\nexport function offerableTiers(\n tiers: readonly ChapterTier[],\n group: TierGroup,\n hasSecretKey: boolean,\n): ChapterTier[] {\n return tiers.filter((tier) => tier.active && tierPayable(tier, group, hasSecretKey));\n}\n\n/**\n * Resolve the tier an application chose.\n *\n * An absent `tierId` is the pre-tier case and selects the only offered tier\n * when exactly one exists; with several it is genuinely ambiguous and returns\n * `null`, because guessing would charge someone the wrong price.\n */\nexport function findTier(\n tiers: readonly ChapterTier[],\n tierId: string | null | undefined,\n): ChapterTier | null {\n if (!tierId) return tiers.length === 1 ? tiers[0]! : null;\n return tiers.find((tier) => tier.id === tierId) ?? null;\n}\n\n/** The public shape of a tier on the join config. Never exposes Stripe ids. */\nexport interface JoinConfigTier {\n id: string;\n name: string;\n priceCents: number;\n blurb: string;\n free: boolean;\n}\n\n/** Project tiers for the public join config, dropping provider identifiers. */\nexport function joinConfigTiers(tiers: readonly ChapterTier[]): JoinConfigTier[] {\n return tiers.map((tier) => ({\n id: tier.id,\n name: tier.name,\n priceCents: tier.priceCents,\n blurb: tier.blurb ?? \"\",\n free: tierIsFree(tier),\n }));\n}\n","// Reading tiers out of the database. Kept apart from tiers.ts so the decision\n// logic there stays pure and directly testable, and apart from the route\n// modules so both the join config and the checkout resolve tiers identically —\n// a page that offers a tier the checkout would refuse is the bug this prevents.\nimport type { ChapterDb } from \"./types\";\nimport { offerableTiers, resolveTiers, type ChapterTier, type TierGroup } from \"./tiers\";\n\n/** A `groups` row as the tier loader needs it. */\nexport type TierGroupRow = TierGroup & { id?: string };\n\nfunction rowToTier(row: Record<string, unknown>, groupId: string): ChapterTier {\n return {\n id: String(row.id ?? \"\"),\n groupId: String(row.groupId ?? groupId),\n name: String(row.name ?? \"\"),\n priceCents: typeof row.priceCents === \"number\" ? row.priceCents : 0,\n ...(typeof row.stripePriceId === \"string\" && row.stripePriceId\n ? { stripePriceId: row.stripePriceId }\n : {}),\n ...(typeof row.blurb === \"string\" ? { blurb: row.blurb } : {}),\n sortOrder: typeof row.sortOrder === \"number\" ? row.sortOrder : 0,\n // A row that never set `active` is offered; only an explicit false retires\n // a tier, so a half-seeded row cannot silently hide a membership.\n active: row.active !== false,\n };\n}\n\n/**\n * Every tier a group offers, ordered, including the implicit tier synthesized\n * for a chapter that predates tiers. Never throws on a missing namespace: a\n * deployment whose schema has not been pushed yet reads as \"no rows\", which\n * resolves to the legacy single tier.\n */\nexport async function loadTiers(db: ChapterDb, group: TierGroupRow): Promise<ChapterTier[]> {\n const groupId = String(group.id ?? \"\");\n let rows: unknown;\n try {\n rows = (await db.query({\n tiers: { $: { where: { groupId }, order: { sortOrder: \"asc\" }, limit: 100 } },\n }) as Record<string, unknown>).tiers;\n } catch {\n rows = undefined;\n }\n const list = Array.isArray(rows)\n ? rows.map((row) => rowToTier(row as Record<string, unknown>, groupId))\n : [];\n return resolveTiers(group, list);\n}\n\n/** The tiers a join page may show: active, and joinable as configured. */\nexport async function loadOfferableTiers(\n db: ChapterDb,\n group: TierGroupRow,\n hasSecretKey: boolean,\n): Promise<ChapterTier[]> {\n return offerableTiers(await loadTiers(db, group), group, hasSecretKey);\n}\n","// Scheduling core — config resolution + the booking invariants, ported from the\n// proven production worker. Everything here is PURE (no @odla-ai/calendar, no\n// db), so the correctness properties are unit-testable and package-enforced; the\n// worker route owns only the I/O (FreeBusy, computeBookableSlots, calendar\n// create/reschedule, the db writes) and calls these.\n//\n// Package-enforced invariants:\n// - the `meetings` row is canonical; applications.meetingAt and the calendar\n// event are projections written from it.\n// - one intro event per application, forever: a rebooking RESCHEDULES the\n// existing event (preserving its Meet link + invite thread), never creates a\n// second — see {@link bookingDecision} + {@link introIdempotencyKey}.\n// - status never moves backward on booking; you can only book from a pipeline\n// stage in `bookableFrom` — see `canBook` in ./pipeline + applicationBookingUpdate.\n// - endAt is always derived server-side, never client-supplied — see\n// {@link endForSlot}.\nimport type { ChapterScheduling } from \"./types\";\n\n/** A fully-resolved scheduling config (every field present). */\nexport interface ResolvedScheduling {\n slotMinutes: number;\n days: readonly number[];\n startHour: number;\n endHour: number;\n timezone: string;\n minNoticeHours: number;\n windowDays: number;\n summaryTemplate: string;\n}\n\n/** Proven defaults: 45-minute weekday slots, 9–5 Pacific, 24h notice,\n * a 14-day window. The summary is generic (a chapter's group seed supplies a\n * name-branded one). */\nexport const SCHEDULING_DEFAULTS: ResolvedScheduling = {\n slotMinutes: 45,\n days: [1, 2, 3, 4, 5],\n startHour: 9,\n endHour: 17,\n timezone: \"America/Los_Angeles\",\n minNoticeHours: 24,\n windowDays: 14,\n summaryTemplate: \"Introduction call with {{firstName}} {{lastName}}\",\n};\n\nfunction isValidTimeZone(tz: string): boolean {\n try {\n new Intl.DateTimeFormat(undefined, { timeZone: tz });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Resolve a group's scheduling config against the defaults, validating every\n * bound at config-write time (throws on a bad config, so a\n * misconfiguration surfaces immediately rather than yielding empty slots).\n * `windowDays` is capped at 62 because Google FreeBusy is.\n */\nexport function resolveScheduling(config?: ChapterScheduling): ResolvedScheduling {\n const result = validateScheduling(config);\n if (result.ok) return result.value;\n const detail = Object.entries(result.errors)\n .map(([field, message]) => `${field}: ${message}`)\n .join(\" \");\n throw new Error(`scheduling: ${detail}`);\n}\n\n/** Validation messages keyed by form field. */\nexport type SchedulingErrors = Record<string, string>;\n\n/**\n * Validate a scheduling config field by field, collecting owner-readable messages\n * rather than throwing on the first problem. An admin settings form needs to say\n * *which* field is wrong and why — \"pick at least one day\" beats a stack trace —\n * so the admin route returns these directly. {@link resolveScheduling} is the\n * throwing wrapper for internal/config-time use.\n */\nexport function validateScheduling(\n config?: ChapterScheduling,\n): { ok: true; value: ResolvedScheduling } | { ok: false; errors: SchedulingErrors } {\n const d = config ?? {};\n const c: ResolvedScheduling = {\n slotMinutes: d.slotMinutes ?? SCHEDULING_DEFAULTS.slotMinutes,\n days: d.days ?? SCHEDULING_DEFAULTS.days,\n startHour: d.startHour ?? SCHEDULING_DEFAULTS.startHour,\n endHour: d.endHour ?? SCHEDULING_DEFAULTS.endHour,\n timezone: d.timezone ?? SCHEDULING_DEFAULTS.timezone,\n minNoticeHours: d.minNoticeHours ?? SCHEDULING_DEFAULTS.minNoticeHours,\n windowDays: d.windowDays ?? SCHEDULING_DEFAULTS.windowDays,\n summaryTemplate: d.summaryTemplate ?? SCHEDULING_DEFAULTS.summaryTemplate,\n };\n const errors: SchedulingErrors = {};\n if (!(c.slotMinutes >= 15 && c.slotMinutes <= 240)) {\n errors.slotMinutes = \"Slot length must be between 15 and 240 minutes.\";\n }\n if (!(c.windowDays >= 1 && c.windowDays <= 62)) {\n errors.windowDays = \"Booking window must be between 1 and 62 days (the calendar caps look-ahead at 62).\";\n }\n if (!(c.minNoticeHours >= 0 && c.minNoticeHours <= 336)) {\n errors.minNoticeHours = \"Minimum notice must be between 0 and 336 hours.\";\n }\n if (!(c.startHour >= 0 && c.startHour < c.endHour && c.endHour <= 24)) {\n errors.hours = \"Hours must satisfy 0 ≤ start < end ≤ 24.\";\n }\n const days = [...c.days];\n if (!days.length) errors.days = \"Pick at least one day.\";\n else if (!days.every((n) => Number.isInteger(n) && n >= 0 && n <= 6)) {\n errors.days = \"Days must be weekday numbers, 0 (Sunday) through 6 (Saturday).\";\n }\n if (typeof c.timezone !== \"string\" || !isValidTimeZone(c.timezone)) {\n errors.timezone = `\"${String(c.timezone)}\" is not a valid IANA timezone (for example \"America/Los_Angeles\").`;\n }\n if (typeof c.summaryTemplate !== \"string\") errors.summaryTemplate = \"Calendar summary template must be text.\";\n return Object.keys(errors).length > 0 ? { ok: false, errors } : { ok: true, value: { ...c, days } };\n}\n\n/** Statuses a member may book/reschedule from (early pipeline only). */\n// Booking eligibility is answered by the configured pipeline — canBook(status,\n// pipeline) in ./pipeline — not a hardcoded status list, so a chapter that\n// customizes its stages gets one consistent answer.\n\n/** The availability window: `[now, now + windowDays]` in epoch ms. */\nexport function slotWindow(now: number, windowDays: number): { from: number; to: number } {\n return { from: now, to: now + windowDays * 86_400_000 };\n}\n\n/** The slot's end instant, always derived from its start (never client-supplied). */\nexport function endForSlot(startAt: number, slotMinutes: number): number {\n return startAt + slotMinutes * 60_000;\n}\n\n/** Double-book pre-check: the requested start must land exactly on a currently\n * bookable slot boundary. */\nexport function isSlotAvailable(slots: readonly { startAt: number }[], startAt: number): boolean {\n return slots.some((s) => s.startAt === startAt);\n}\n\n/** Render a meeting summary from its template (`{{firstName}}`/`{{lastName}}`). */\nexport function renderSummary(template: string, app: { firstName?: string | null; lastName?: string | null }): string {\n return template.replace(\"{{firstName}}\", app.firstName ?? \"\").replace(\"{{lastName}}\", app.lastName ?? \"\");\n}\n\n/** The prior scheduled meeting for an application, as far as booking cares. */\nexport interface ExistingMeeting {\n id: string;\n googleEventId?: string | null;\n meetUrl?: string | null;\n htmlLink?: string | null;\n}\n\n/** Decide reschedule-vs-create: reschedule iff there's an existing event to move,\n * so the Meet link + invite thread survive and no second event is minted. */\nexport function bookingDecision(existing: ExistingMeeting | null | undefined): { reschedule: boolean; eventId: string | null } {\n const eventId = existing?.googleEventId ?? null;\n return { reschedule: Boolean(eventId), eventId };\n}\n\n/** The create idempotency key — one intro event per application, forever, so a\n * retried create returns the same booking rather than a duplicate. */\nexport function introIdempotencyKey(applicationId: string): string {\n return `application:${applicationId}:intro`;\n}\n\n/** The canonical `meetings` row for a first booking. A `type` (not `interface`)\n * so it stays assignable to a db op's `attrs` (Record<string, unknown>). */\nexport type NewMeetingRow = {\n id: string;\n applicationId: string;\n groupId: string;\n startAt: number;\n endAt: number;\n timezone: string;\n status: \"scheduled\";\n googleEventId: string;\n meetUrl?: string;\n htmlLink?: string;\n drift: \"none\";\n createdAt: number;\n};\n\n/** Build the new `meetings` row after the calendar created the event. Optional\n * scalars are omitted (never null), per the odla-db porting rule. */\nexport function meetingCreateRow(i: {\n meetingId: string;\n applicationId: string;\n groupId: string;\n startAt: number;\n endAt: number;\n timezone: string;\n googleEventId: string;\n meetUrl?: string | null;\n htmlLink?: string | null;\n createdAt: number;\n}): NewMeetingRow {\n return {\n id: i.meetingId,\n applicationId: i.applicationId,\n groupId: i.groupId,\n startAt: i.startAt,\n endAt: i.endAt,\n timezone: i.timezone,\n status: \"scheduled\",\n googleEventId: i.googleEventId,\n ...(i.meetUrl ? { meetUrl: i.meetUrl } : {}),\n ...(i.htmlLink ? { htmlLink: i.htmlLink } : {}),\n drift: \"none\",\n createdAt: i.createdAt,\n };\n}\n\n/** The `meetings`-row patch for a reschedule (same row id, moved in place). */\nexport type MeetingReschedulePatch = {\n startAt: number;\n endAt: number;\n drift: \"none\";\n};\n\n/** Patch to move an existing meeting to a new window. */\nexport function meetingRescheduleUpdate(startAt: number, endAt: number): MeetingReschedulePatch {\n return { startAt, endAt, drift: \"none\" };\n}\n\n/** The `applications`-row patch after a booking. */\nexport type ApplicationBookingPatch = {\n meetingAt: number;\n meetingLink?: string;\n status?: \"call_scheduled\";\n};\n\n/** Project the booking onto the application row: cache the time, adopt the\n * calendar link if any, and advance the status to `call_scheduled` unless it is\n * already there (never backward). */\nexport function applicationBookingUpdate(\n currentStatus: string,\n startAt: number,\n htmlLink?: string | null,\n): ApplicationBookingPatch {\n return {\n meetingAt: startAt,\n ...(htmlLink ? { meetingLink: htmlLink } : {}),\n ...(currentStatus !== \"call_scheduled\" ? { status: \"call_scheduled\" as const } : {}),\n };\n}\n","/** Current wire version for parent-authored admission decisions. */\nexport const ADMISSION_GRANTS_SCHEMA_VERSION = 1 as const;\n/** Dedicated signed Parent → Chapter delivery endpoint. */\nexport const ADMISSION_GRANTS_PATH = \"/api/admission-grants\" as const;\n\n/** Whether an exact email can skip or must retain the Chapter interview. */\nexport type AdmissionDecision = \"waive_interview\" | \"require_interview\";\n\n/** One bounded admission decision. Email is PII and never enters public config. */\nexport interface AdmissionGrantInput {\n id: string;\n email: string;\n decision: AdmissionDecision;\n note?: string;\n expiresAt?: number;\n}\n\n/** Complete desired Parent state for one Chapter and environment. */\nexport interface AdmissionGrantDocument {\n schemaVersion: typeof ADMISSION_GRANTS_SCHEMA_VERSION;\n revision: number;\n generatedAt: number;\n source: { appId: string; actor: string };\n target: { chapterId: string; environment: string };\n grants: readonly AdmissionGrantInput[];\n}\n\n/** Canonical desired-state document paired with its integrity digest. */\nexport interface AdmissionGrantEnvelope {\n digest: string;\n document: AdmissionGrantDocument;\n}\n\n/** Chapter acknowledgement for an accepted or idempotently replayed revision. */\nexport interface AdmissionGrantReceipt {\n ok: true;\n target: { chapterId: string; environment: string };\n revision: number;\n digest: string;\n status: \"accepted\" | \"replayed\";\n acknowledgedAt: number;\n}\n\n/** Stable machine-readable rejection reasons returned by a Chapter receiver. */\nexport type AdmissionGrantRejection =\n | \"invalid_document\"\n | \"invalid_digest\"\n | \"wrong_source\"\n | \"wrong_target\"\n | \"wrong_environment\"\n | \"stale_revision\"\n | \"conflicting_revision\"\n | \"materialization_failed\";\n","const encoder = new TextEncoder();\n\nfunction canonicalValue(value: unknown): string {\n if (value === null || typeof value === \"boolean\" || typeof value === \"number\" || typeof value === \"string\") {\n return JSON.stringify(value);\n }\n if (Array.isArray(value)) return `[${value.map(canonicalValue).join(\",\")}]`;\n if (typeof value !== \"object\") throw new TypeError(\"signup control contains an unsupported value\");\n const record = value as Record<string, unknown>;\n const entries = Object.keys(record).sort().flatMap((key) => {\n const item = record[key];\n return item === undefined ? [] : [`${JSON.stringify(key)}:${canonicalValue(item)}`];\n });\n return `{${entries.join(\",\")}}`;\n}\n\n/** Serialize JSON-like signup state with recursively sorted object keys. */\nexport function canonicalSignupControl(value: unknown): string {\n return canonicalValue(value);\n}\n\n/** Compute the protocol's canonical SHA-256 digest for desired signup state. */\nexport async function signupControlDigest(document: unknown): Promise<string> {\n const digest = await crypto.subtle.digest(\"SHA-256\", encoder.encode(canonicalSignupControl(document)));\n return `sha256:${Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\")}`;\n}\n\n/** Pair one desired-state document with its canonical digest for delivery. */\nexport async function createSignupControlEnvelope(document: import(\"./signup-control-contract\").SignupControlDocument) {\n return { document, digest: await signupControlDigest(document) };\n}\n","import type {\n AdmissionDecision,\n AdmissionGrantDocument,\n AdmissionGrantEnvelope,\n AdmissionGrantInput,\n} from \"./admission-grants-contract\";\nimport { ADMISSION_GRANTS_SCHEMA_VERSION } from \"./admission-grants-contract\";\nimport type { ChapterDb, DbOp } from \"./types\";\nimport { signupControlDigest } from \"./signup-control-canonical\";\nimport { normalizeChapterEmail } from \"./email-identity\";\n\nconst ID = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,127}$/;\nconst MAX_GRANTS = 2_000;\nconst MAX_NOTE = 2_000;\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nconst isAdmissionEmail = (value: string): boolean => EMAIL_RE.test(value);\n\n/** Exact email natural key: trim and lowercase, with no provider alias rules. */\nexport function normalizeAdmissionEmail(email: string): string {\n return normalizeChapterEmail(email);\n}\n\n/** Validated normalized admission document or all contract errors. */\nexport type AdmissionGrantValidation =\n | { ok: true; value: AdmissionGrantDocument }\n | { ok: false; errors: readonly string[] };\n\n/** Validate and normalize a complete Parent admission document. */\nexport function validateAdmissionGrantDocument(input: unknown): AdmissionGrantValidation {\n const errors: string[] = [];\n const root = input && typeof input === \"object\" ? input as Record<string, unknown> : {};\n if (root.schemaVersion !== ADMISSION_GRANTS_SCHEMA_VERSION) errors.push(\"document.schemaVersion must be 1\");\n const revision = Number(root.revision);\n const generatedAt = Number(root.generatedAt);\n if (!Number.isSafeInteger(revision) || revision < 1) errors.push(\"document.revision must be a positive integer\");\n if (!Number.isFinite(generatedAt) || generatedAt <= 0) errors.push(\"document.generatedAt must be epoch milliseconds\");\n const source = root.source && typeof root.source === \"object\" ? root.source as Record<string, unknown> : {};\n const target = root.target && typeof root.target === \"object\" ? root.target as Record<string, unknown> : {};\n const sourceId = typeof source.appId === \"string\" ? source.appId : \"\";\n const sourceActor = typeof source.actor === \"string\" ? source.actor.trim() : \"\";\n const chapterId = typeof target.chapterId === \"string\" ? target.chapterId : \"\";\n const environment = typeof target.environment === \"string\" ? target.environment : \"\";\n if (!ID.test(sourceId)) errors.push(\"document.source.appId must be an identifier\");\n if (!sourceActor || sourceActor.length > 256) errors.push(\"document.source.actor must be 1-256 characters\");\n if (!ID.test(chapterId)) errors.push(\"document.target.chapterId must be an identifier\");\n if (!ID.test(environment)) errors.push(\"document.target.environment must be an identifier\");\n if (!Array.isArray(root.grants)) errors.push(\"document.grants must be an array\");\n const rawGrants = Array.isArray(root.grants) ? root.grants : [];\n if (rawGrants.length > MAX_GRANTS) errors.push(`document.grants supports at most ${MAX_GRANTS} entries`);\n const grants: AdmissionGrantInput[] = [];\n const seenIds = new Set<string>();\n const seenEmails = new Set<string>();\n for (const [index, raw] of rawGrants.slice(0, MAX_GRANTS).entries()) {\n const grant = raw && typeof raw === \"object\" ? raw as Record<string, unknown> : {};\n const id = typeof grant.id === \"string\" ? grant.id : \"\";\n const email = typeof grant.email === \"string\" ? grant.email.trim() : \"\";\n const normalized = normalizeAdmissionEmail(email);\n const decision = grant.decision;\n const note = typeof grant.note === \"string\" ? grant.note.trim() : undefined;\n const expiresAt = grant.expiresAt === undefined ? undefined : Number(grant.expiresAt);\n if (!ID.test(id)) errors.push(`document.grants[${index}].id must be an identifier`);\n if (seenIds.has(id)) errors.push(`document.grants repeats id \"${id}\"`);\n if (!isAdmissionEmail(normalized)) errors.push(`document.grants[${index}].email must be valid`);\n if (seenEmails.has(normalized)) errors.push(`document.grants repeats email \"${normalized}\"`);\n if (decision !== \"waive_interview\" && decision !== \"require_interview\") {\n errors.push(`document.grants[${index}].decision is invalid`);\n }\n if (note && note.length > MAX_NOTE) errors.push(`document.grants[${index}].note is too long`);\n if (expiresAt !== undefined && (!Number.isFinite(expiresAt) || expiresAt <= 0)) {\n errors.push(`document.grants[${index}].expiresAt must be epoch milliseconds`);\n }\n seenIds.add(id);\n seenEmails.add(normalized);\n grants.push({\n id,\n email,\n decision: decision as AdmissionDecision,\n ...(note ? { note } : {}),\n ...(expiresAt !== undefined ? { expiresAt } : {}),\n });\n }\n if (errors.length) return { ok: false, errors };\n return {\n ok: true,\n value: {\n schemaVersion: ADMISSION_GRANTS_SCHEMA_VERSION,\n revision,\n generatedAt,\n source: { appId: sourceId, actor: sourceActor },\n target: { chapterId, environment },\n grants,\n },\n };\n}\n\n/** Pair a validated desired-state document with its canonical digest. */\nexport async function createAdmissionGrantEnvelope(document: AdmissionGrantDocument): Promise<AdmissionGrantEnvelope> {\n const checked = validateAdmissionGrantDocument(document);\n if (!checked.ok) throw new TypeError(`Invalid admission grant document: ${checked.errors.join(\"; \")}`);\n return { document: checked.value, digest: await signupControlDigest(checked.value) };\n}\n\n/** Materialized local or Parent admission decision stored by a Chapter. */\nexport interface AdmissionGrantRow {\n id: string;\n sourceGrantId: string;\n sourceScope: \"local\" | \"parent\";\n sourceId: string;\n targetId: string;\n email: string;\n emailNormalized: string;\n decision: AdmissionDecision;\n active: boolean;\n createdAt: number;\n note?: string;\n expiresAt?: number;\n revokedAt?: number;\n consumedAt?: number;\n consumedApplicationId?: string;\n}\n\nconst rows = (value: unknown): Array<Record<string, unknown>> => Array.isArray(value) ? value : [];\n\nfunction asGrant(row: Record<string, unknown>): AdmissionGrantRow | null {\n if (typeof row.id !== \"string\" || typeof row.emailNormalized !== \"string\") return null;\n if (row.sourceScope !== \"local\" && row.sourceScope !== \"parent\") return null;\n if (row.decision !== \"waive_interview\" && row.decision !== \"require_interview\") return null;\n return row as unknown as AdmissionGrantRow;\n}\n\n/** Resolve the effective current decision. Local rows always outrank Parent rows. */\nexport async function findAdmissionGrant(\n db: ChapterDb,\n targetId: string,\n email: string,\n now: number,\n): Promise<AdmissionGrantRow | null> {\n const emailNormalized = normalizeAdmissionEmail(email);\n if (!isAdmissionEmail(emailNormalized)) return null;\n const result = await db.query({ admissionGrants: { $: { where: { emailNormalized }, limit: 100 } } });\n const active = rows(result.admissionGrants)\n .map(asGrant)\n .filter((grant): grant is AdmissionGrantRow => Boolean(\n grant && grant.targetId === targetId && grant.active === true && !grant.revokedAt &&\n (!grant.expiresAt || grant.expiresAt > now) && !grant.consumedApplicationId,\n ))\n .sort((a, b) => {\n const scope = Number(b.sourceScope === \"local\") - Number(a.sourceScope === \"local\");\n return scope || b.createdAt - a.createdAt;\n });\n return active[0] ?? null;\n}\n\n/** Stored receipt for one signed Parent admission revision. */\nexport interface AdmissionGrantRevisionRow {\n id: string;\n sourceId: string;\n targetId: string;\n environment: string;\n revision: number;\n digest: string;\n active: boolean;\n receivedAt: number;\n}\n\nasync function hasAdmissionRevision(\n db: ChapterDb,\n sourceId: string,\n targetId: string,\n environment: string,\n): Promise<boolean> {\n const where = { sourceId, targetId, environment };\n if (db.aggregate) {\n return Number((await db.aggregate(\"admissionGrantRevisions\", { count: true }, { where })).count ?? 0) > 0;\n }\n const found = await db.query({ admissionGrantRevisions: {} });\n return rows(found.admissionGrantRevisions).some((row) =>\n row.sourceId === sourceId && row.targetId === targetId && row.environment === environment);\n}\n\n/** Read the newest received revision without issuing an ordered query over empty history. */\nexport async function loadLatestAdmissionRevision(\n db: ChapterDb,\n sourceId: string,\n targetId: string,\n environment: string,\n): Promise<AdmissionGrantRevisionRow | null> {\n if (!await hasAdmissionRevision(db, sourceId, targetId, environment)) return null;\n const result = await db.query({ admissionGrantRevisions: { $: {\n where: { sourceId, targetId, environment }, order: { revision: \"desc\" }, limit: 1,\n } } });\n const row = rows(result.admissionGrantRevisions)\n .sort((a, b) => Number(b.revision ?? 0) - Number(a.revision ?? 0))[0];\n return row ? row as unknown as AdmissionGrantRevisionRow : null;\n}\n\n/** Replace only Parent-authored rows; local Chapter decisions remain untouched. */\nexport async function materializeAdmissionGrants(\n db: ChapterDb,\n envelope: AdmissionGrantEnvelope,\n previous: AdmissionGrantRevisionRow | null,\n receivedAt: number,\n): Promise<void> {\n const { document, digest } = envelope;\n const current = rows((await db.query({ admissionGrants: { $: {\n where: { sourceScope: \"parent\", sourceId: document.source.appId, targetId: document.target.chapterId },\n limit: MAX_GRANTS,\n } } })).admissionGrants);\n const incomingIds = new Set(document.grants.map((grant) => `admission:parent:${document.source.appId}:${grant.id}`));\n const ops: DbOp[] = [];\n for (const row of current) {\n const id = String(row.id ?? \"\");\n if (id && !incomingIds.has(id)) ops.push({ t: \"update\", ns: \"admissionGrants\", id, attrs: {\n active: false, revokedAt: receivedAt, revokedBy: document.source.actor,\n updatedAt: receivedAt, updatedBy: document.source.actor,\n } });\n }\n for (const grant of document.grants) {\n const id = `admission:parent:${document.source.appId}:${grant.id}`;\n const existing = current.find((row) => row.id === id);\n ops.push({ t: \"update\", ns: \"admissionGrants\", id, attrs: {\n id,\n sourceGrantId: grant.id,\n sourceScope: \"parent\",\n sourceId: document.source.appId,\n targetId: document.target.chapterId,\n email: grant.email,\n emailNormalized: normalizeAdmissionEmail(grant.email),\n decision: grant.decision,\n ...(grant.note ? { note: grant.note } : {}),\n ...(grant.expiresAt ? { expiresAt: grant.expiresAt } : {}),\n active: true,\n sourceRevision: document.revision,\n createdAt: Number(existing?.createdAt ?? receivedAt),\n createdBy: String(existing?.createdBy ?? document.source.actor),\n updatedAt: receivedAt,\n updatedBy: document.source.actor,\n } });\n const retract = [\n ...(!grant.note && existing?.note !== undefined ? [\"note\"] : []),\n ...(grant.expiresAt === undefined && existing?.expiresAt !== undefined ? [\"expiresAt\"] : []),\n ];\n if (retract.length) ops.push({ t: \"retract\", ns: \"admissionGrants\", id, attrs: retract });\n }\n if (previous?.active) ops.push({ t: \"update\", ns: \"admissionGrantRevisions\", id: previous.id, attrs: { active: false } });\n const revisionId = `admission-revision:${document.source.appId}:${document.target.environment}:${document.revision}`;\n ops.push({ t: \"update\", ns: \"admissionGrantRevisions\", id: revisionId, attrs: {\n id: revisionId,\n sourceId: document.source.appId,\n targetId: document.target.chapterId,\n environment: document.target.environment,\n revision: document.revision,\n digest,\n active: true,\n receivedAt,\n } });\n await db.transact(ops, { mutationId: `admission-grants:${document.source.appId}:${document.target.environment}:${document.revision}:${digest}` });\n}\n","import type { Crm, FieldConditions, FieldDef, FieldType } from \"@odla-ai/crm\";\nimport type { Chapter, ResolvedApplication, ResolvedLeaderFormation } from \"./types\";\n\n/** Current public schema version for Chapter flow-field contracts. */\nexport const CHAPTER_FLOW_FIELDS_SCHEMA_VERSION = 1 as const;\n\n/** Configurable Chapter intake journeys that publish field contracts. */\nexport type ChapterFieldFlow = \"join\" | \"formation\";\n\n/** Email comparison policy advertised by an email field. */\nexport type ChapterEmailIdentity = \"literal\";\n\n/**\n * One effective field in a Chapter intake journey.\n *\n * IDs, value types, and options come from the follower-declared schema. A hub\n * or CMS may select, order, and configure only those declared fields; it cannot\n * use this presentation document to add storage or widen follower authority.\n */\nexport interface ChapterFlowField {\n id: string;\n label: string;\n type: FieldType;\n required: boolean;\n order: number;\n maxLength?: number;\n options?: readonly string[];\n conditions?: FieldConditions;\n /** Present only for an email identity field. Aliases such as `+tag` remain significant. */\n emailIdentity?: ChapterEmailIdentity;\n}\n\n/** Ordered, versioned effective field state for one Chapter journey. */\nexport interface ChapterFlowFieldContract {\n schemaVersion: typeof CHAPTER_FLOW_FIELDS_SCHEMA_VERSION;\n flow: ChapterFieldFlow;\n fields: readonly ChapterFlowField[];\n}\n\nconst APPLICATION_LABELS: Readonly<Record<string, string>> = {\n firstName: \"First name\",\n lastName: \"Last name\",\n email: \"Email\",\n referral: \"Referral source\",\n referralName: \"Referral name\",\n whoYouAre: \"Who you are\",\n linkedin: \"LinkedIn\",\n message: \"Intro message\",\n phone: \"Phone\",\n state: \"State\",\n};\n\nfunction humanize(id: string): string {\n const text = id.replace(/([a-z0-9])([A-Z])/g, \"$1 $2\").replace(/[_-]+/g, \" \").trim();\n return text ? `${text[0]!.toUpperCase()}${text.slice(1)}` : id;\n}\n\nfunction applicationDefs(chapter: Chapter): Record<string, FieldDef> {\n try {\n return chapter.crm.type(\"person\").fields;\n } catch {\n return {};\n }\n}\n\nfunction applicationType(id: string, def: FieldDef | undefined): FieldType {\n // Application rows accept configurable strings. Preserve the richer\n // string-like CRM hints without claiming that a numeric/date/json CRM field\n // changes the application storage contract.\n if (def && [\"string\", \"email\", \"url\", \"enum\"].includes(def.type)) return def.type;\n return id === \"email\" ? \"email\" : id === \"linkedin\" ? \"url\" : \"string\";\n}\n\n/** Resolve the exact ordered fields accepted by the membership application flow. */\nexport function applicationFlowFields(\n chapter: Chapter,\n application: ResolvedApplication = chapter.application,\n): ChapterFlowField[] {\n const defs = applicationDefs(chapter);\n return [...application.required, ...application.optional].map((id, order) => {\n const def = defs[id];\n const conditions = application.conditions[id];\n const type = applicationType(id, def);\n return {\n id,\n label: def?.label ?? APPLICATION_LABELS[id] ?? humanize(id),\n type,\n required: application.required.includes(id),\n order,\n maxLength: application.maxLen[id] ?? application.defaultMaxLen,\n ...(type === \"enum\" && def?.options ? { options: [...def.options] } : {}),\n ...(conditions ? { conditions: { ...conditions } } : {}),\n ...(type === \"email\" ? { emailIdentity: \"literal\" as const } : {}),\n };\n });\n}\n\n/** Common resolver retained separately so the legacy formationFields helper cannot drift. */\nexport function resolveFormationFlowFields(\n crm: Crm,\n formation: ResolvedLeaderFormation,\n): ChapterFlowField[] {\n if (!formation.enabled) return [];\n const def = crm.type(formation.type);\n return [...formation.required, ...formation.optional].map((id, order) => {\n const field = def.fields[id]!;\n return {\n id,\n label: field.label ?? humanize(id),\n type: field.type,\n required: formation.required.includes(id),\n order,\n maxLength: formation.maxLen[id] ?? formation.defaultMaxLen,\n ...(field.options ? { options: [...field.options] } : {}),\n ...(id === def.emailField || field.type === \"email\" ? { emailIdentity: \"literal\" as const } : {}),\n };\n });\n}\n\n/** Resolve the exact ordered fields accepted by the chapter-formation flow. */\nexport function formationFlowFields(\n chapter: Chapter,\n formation: ResolvedLeaderFormation = chapter.formation,\n): ChapterFlowField[] {\n return resolveFormationFlowFields(chapter.crm, formation);\n}\n\n/**\n * Build the public field contract consumed by follower forms and CMS previews.\n * The optional application is the already-authorized effective selection from\n * signup control; it never expands the follower's declared application schema.\n */\nexport function chapterFlowFieldContract(\n chapter: Chapter,\n flow: ChapterFieldFlow,\n application: ResolvedApplication = chapter.application,\n): ChapterFlowFieldContract {\n return {\n schemaVersion: CHAPTER_FLOW_FIELDS_SCHEMA_VERSION,\n flow,\n fields: flow === \"join\"\n ? applicationFlowFields(chapter, application)\n : formationFlowFields(chapter),\n };\n}\n","/** Current nested gift-catalog version inside signup-control. */\nexport const GIFT_OFFER_CATALOG_VERSION = 1 as const;\n/** Maximum signed gift SKUs accepted in one catalog revision. */\nexport const MAX_GIFT_OFFERS = 20;\n\n/** Membership tier or standalone entitlement fulfilled by redemption. */\nexport type GiftOfferTarget =\n | { type: \"tier\"; tierId: string }\n | { type: \"entitlement\"; entitlementKey: string };\n\n/** Server-authored gift SKU; provider identifiers never reach public config. */\nexport interface GiftOffer {\n id: string;\n target: GiftOfferTarget;\n billingMode: \"one_time\" | \"subscription\";\n stripePriceId: string;\n priceCents: number;\n currency: string;\n redemptionLifetimeHours: number;\n activeFrom?: number;\n activeUntil?: number;\n title: string;\n description: string;\n ctaLabel: string;\n}\n\n/** Versioned bounded collection delegated through signed signup control. */\nexport interface GiftOfferCatalog {\n schemaVersion: typeof GIFT_OFFER_CATALOG_VERSION;\n offers: readonly GiftOffer[];\n}\n\n/** Provider-free gift offer shape rendered by Chapter and exact CMS previews. */\nexport type PublicGiftOffer = Omit<GiftOffer, \"stripePriceId\" | \"target\">;\n\n/** Result of validating and normalizing an untrusted gift catalog. */\nexport type GiftOfferValidation =\n | { ok: true; value: GiftOfferCatalog }\n | { ok: false; errors: readonly string[] };\n\nconst ID = /^[a-z][a-z0-9-]{1,79}$/;\nconst PRICE = /^price_[A-Za-z0-9]{12,}$/;\nconst CURRENCY = /^[a-z]{3}$/;\nconst record = (value: unknown): Record<string, unknown> | null =>\n value && typeof value === \"object\" && !Array.isArray(value) ? value as Record<string, unknown> : null;\nconst text = (value: unknown, path: string, errors: string[], max: number): string => {\n if (typeof value !== \"string\" || !value.trim()) { errors.push(`${path} is required`); return \"\"; }\n if (value.trim().length > max) errors.push(`${path} must be at most ${max} characters`);\n return value.trim();\n};\n\n/** Validate and normalize gift offers against the same document's tier ids. */\nexport function validateGiftOfferCatalog(input: unknown, tierIds: ReadonlySet<string>): GiftOfferValidation {\n const errors: string[] = [];\n const root = record(input);\n if (!root) return { ok: false, errors: [\"document.giftOffers must be an object\"] };\n for (const key of Object.keys(root)) if (key !== \"schemaVersion\" && key !== \"offers\") errors.push(`document.giftOffers.${key} is not supported`);\n if (root.schemaVersion !== GIFT_OFFER_CATALOG_VERSION) errors.push(\"document.giftOffers.schemaVersion must be 1\");\n if (!Array.isArray(root.offers)) errors.push(\"document.giftOffers.offers must be an array\");\n const rawOffers = Array.isArray(root.offers) ? root.offers : [];\n if (rawOffers.length > MAX_GIFT_OFFERS) errors.push(`document.giftOffers.offers supports at most ${MAX_GIFT_OFFERS} entries`);\n const ids = new Set<string>();\n const offers: GiftOffer[] = [];\n for (const [index, raw] of rawOffers.slice(0, MAX_GIFT_OFFERS).entries()) {\n const path = `document.giftOffers.offers[${index}]`;\n const item = record(raw);\n if (!item) { errors.push(`${path} must be an object`); continue; }\n const allowed = new Set([\"id\", \"target\", \"billingMode\", \"stripePriceId\", \"priceCents\", \"currency\", \"redemptionLifetimeHours\", \"activeFrom\", \"activeUntil\", \"title\", \"description\", \"ctaLabel\"]);\n for (const key of Object.keys(item)) if (!allowed.has(key)) errors.push(`${path}.${key} is not supported`);\n const id = text(item.id, `${path}.id`, errors, 80);\n if (id && !ID.test(id)) errors.push(`${path}.id must be a lowercase kebab-case id`);\n if (ids.has(id)) errors.push(`${path}.id duplicates \"${id}\"`);\n ids.add(id);\n const targetRaw = record(item.target);\n let target: GiftOfferTarget = { type: \"entitlement\", entitlementKey: \"invalid\" };\n if (targetRaw?.type === \"tier\") {\n const tierId = text(targetRaw.tierId, `${path}.target.tierId`, errors, 80);\n if (!tierIds.has(tierId)) errors.push(`${path}.target.tierId must reference a declared tier`);\n target = { type: \"tier\", tierId };\n } else if (targetRaw?.type === \"entitlement\") {\n const entitlementKey = text(targetRaw.entitlementKey, `${path}.target.entitlementKey`, errors, 80);\n if (entitlementKey && !ID.test(entitlementKey)) errors.push(`${path}.target.entitlementKey must be a lowercase kebab-case id`);\n target = { type: \"entitlement\", entitlementKey };\n } else errors.push(`${path}.target.type must be tier or entitlement`);\n if (item.billingMode !== \"one_time\" && item.billingMode !== \"subscription\") errors.push(`${path}.billingMode must be one_time or subscription`);\n const stripePriceId = text(item.stripePriceId, `${path}.stripePriceId`, errors, 128);\n if (stripePriceId && !PRICE.test(stripePriceId)) errors.push(`${path}.stripePriceId must be a real Stripe Price id`);\n if (!Number.isSafeInteger(item.priceCents) || Number(item.priceCents) < 1 || Number(item.priceCents) > 100_000_000) errors.push(`${path}.priceCents must be an integer from 1 to 100,000,000`);\n const currency = typeof item.currency === \"string\" ? item.currency.trim().toLowerCase() : \"\";\n if (!CURRENCY.test(currency)) errors.push(`${path}.currency must be a lowercase ISO currency code`);\n const lifetime = Number(item.redemptionLifetimeHours);\n if (!Number.isSafeInteger(lifetime) || lifetime < 1 || lifetime > 8_760) errors.push(`${path}.redemptionLifetimeHours must be an integer from 1 to 8760`);\n const activeFrom = item.activeFrom === undefined ? undefined : Number(item.activeFrom);\n const activeUntil = item.activeUntil === undefined ? undefined : Number(item.activeUntil);\n if (activeFrom !== undefined && (!Number.isSafeInteger(activeFrom) || activeFrom < 1)) errors.push(`${path}.activeFrom must be epoch milliseconds`);\n if (activeUntil !== undefined && (!Number.isSafeInteger(activeUntil) || activeUntil < 1)) errors.push(`${path}.activeUntil must be epoch milliseconds`);\n if (activeFrom !== undefined && activeUntil !== undefined && activeUntil <= activeFrom) errors.push(`${path}.activeUntil must follow activeFrom`);\n offers.push({\n id, target, billingMode: item.billingMode as GiftOffer[\"billingMode\"], stripePriceId,\n priceCents: Number(item.priceCents), currency, redemptionLifetimeHours: lifetime,\n ...(activeFrom !== undefined ? { activeFrom } : {}), ...(activeUntil !== undefined ? { activeUntil } : {}),\n title: text(item.title, `${path}.title`, errors, 160), description: text(item.description, `${path}.description`, errors, 2_000),\n ctaLabel: text(item.ctaLabel, `${path}.ctaLabel`, errors, 120),\n });\n }\n return errors.length ? { ok: false, errors } : { ok: true, value: { schemaVersion: 1, offers } };\n}\n\n/** Whether an offer is active at an exact server time. */\nexport const giftOfferActive = (offer: GiftOffer, now: number): boolean =>\n (!offer.activeFrom || offer.activeFrom <= now) && (!offer.activeUntil || offer.activeUntil > now);\n\n/** Public provider-free active catalog projection. */\nexport function publicGiftOffers(catalog: GiftOfferCatalog | undefined, now: number): PublicGiftOffer[] {\n return (catalog?.offers ?? []).filter((offer) => giftOfferActive(offer, now)).map(({ stripePriceId: _stripe, target: _target, ...offer }) => offer);\n}\n\n/** Resolve one currently active server-authoritative offer. */\nexport function findGiftOffer(catalog: GiftOfferCatalog | undefined, offerId: string, now: number): GiftOffer | null {\n return catalog?.offers.find((offer) => offer.id === offerId && giftOfferActive(offer, now)) ?? null;\n}\n","// The odla->Clerk write half: server-side Clerk role read/list/write, the gap\n// beside clerk.ts's create/invite/heal. Roles live in `public_metadata.role`; an\n// absent role means the lowest rung (\"provisional\") — chapter never writes it at\n// create. Account profile signals live in backend-only `private_metadata`; the\n// role write is a MERGE-PATCH of only `{ role }`, so it cannot clobber them.\n// Chapter calls the Clerk Backend API over fetch with the vault\n// `clerk_secret_key`.\n\nconst CLERK_API = \"https://api.clerk.com\";\nconst DEFAULT_ROLE = \"provisional\";\nconst PAGE = 100;\n\n/** A Clerk user as chapter's role layer sees it. `role` defaults to the lowest\n * rung when `public_metadata` carries none. Raw public/private metadata is\n * returned only from this backend helper; `profile` and `applicationId` are the\n * normalized Chapter-owned private signals. */\nexport interface ClerkUserRecord {\n id: string;\n email?: string;\n role: string;\n publicMetadata: Record<string, unknown>;\n privateMetadata: Record<string, unknown>;\n profile: Record<string, unknown>;\n applicationId?: string;\n}\n\n// The Clerk Backend API user object — only the fields chapter reads.\ninterface ClerkApiUser {\n id?: unknown;\n email_addresses?: Array<{ email_address?: unknown }>;\n public_metadata?: Record<string, unknown>;\n private_metadata?: Record<string, unknown>;\n}\n\nfunction toRecord(u: ClerkApiUser): ClerkUserRecord | null {\n if (typeof u.id !== \"string\") return null;\n const pm = (u.public_metadata ?? {}) as Record<string, unknown>;\n const privateMetadata = (u.private_metadata ?? {}) as Record<string, unknown>;\n const rawProfile = privateMetadata.profile;\n const profile = rawProfile && typeof rawProfile === \"object\" && !Array.isArray(rawProfile)\n ? rawProfile as Record<string, unknown>\n : {};\n const applicationId = typeof privateMetadata.applicationId === \"string\"\n ? privateMetadata.applicationId\n : undefined;\n const role = typeof pm.role === \"string\" && pm.role ? pm.role : DEFAULT_ROLE;\n const email = u.email_addresses?.[0]?.email_address;\n return {\n id: u.id,\n email: typeof email === \"string\" ? email : undefined,\n role,\n publicMetadata: pm,\n privateMetadata,\n profile,\n ...(applicationId ? { applicationId } : {}),\n };\n}\n\nasync function clerkGet(path: string, secretKey: string, fetchImpl: typeof fetch): Promise<unknown> {\n const res = await fetchImpl(`${CLERK_API}${path}`, { headers: { authorization: `Bearer ${secretKey}` } });\n if (!res.ok) throw new Error(`clerk GET ${path} → ${res.status}`);\n return res.json();\n}\n\n/** Look a Clerk user up by email. `null` when no such user — or when the lookup\n * fails (a role gate treats an unresolvable user as absent, matching the site's\n * own fallback). Role defaults to provisional when unset. */\nexport async function clerkGetUserByEmail(secretKey: string, email: string, fetchImpl: typeof fetch = fetch): Promise<ClerkUserRecord | null> {\n const data = await clerkGet(`/v1/users?email_address=${encodeURIComponent(email)}&limit=1`, secretKey, fetchImpl).catch(() => null);\n const user = Array.isArray(data) ? (data[0] as ClerkApiUser | undefined) : undefined;\n return user ? toRecord(user) : null;\n}\n\n/** Fetch a Clerk user by id, for role-change gating. `null` when missing or on a\n * failed lookup. Role defaults to provisional when unset. */\nexport async function clerkGetUser(secretKey: string, id: string, fetchImpl: typeof fetch = fetch): Promise<ClerkUserRecord | null> {\n const data = await clerkGet(`/v1/users/${encodeURIComponent(id)}`, secretKey, fetchImpl).catch(() => null);\n return data ? toRecord(data as ClerkApiUser) : null;\n}\n\n/** List ALL Clerk users with their roles, auto-paginating. A membership community\n * outgrows one page, and a fixed `limit=100` would silently drop members from the\n * admin roster with no error — so this pages (offset in steps of {@link PAGE})\n * until a short page. A page fetch that fails THROWS rather than returning a\n * partial list, so the caller never mistakes a truncated roster for the whole. */\nexport async function clerkListUsers(secretKey: string, fetchImpl: typeof fetch = fetch): Promise<ClerkUserRecord[]> {\n const out: ClerkUserRecord[] = [];\n for (let offset = 0; ; offset += PAGE) {\n const data = await clerkGet(`/v1/users?limit=${PAGE}&offset=${offset}`, secretKey, fetchImpl);\n const page = Array.isArray(data) ? (data as ClerkApiUser[]) : [];\n for (const u of page) {\n const record = toRecord(u);\n if (record) out.push(record);\n }\n if (page.length < PAGE) break;\n }\n return out;\n}\n\n/** Write a user's role: a MERGE-PATCH of only `{ role }` on `public_metadata`.\n * The backend-only profile lives in `private_metadata`, so the two signals\n * cannot overwrite each other. Returns whether the role write stuck. */\nexport async function clerkSetRole(secretKey: string, id: string, role: string, fetchImpl: typeof fetch = fetch): Promise<boolean> {\n const res = await fetchImpl(`${CLERK_API}/v1/users/${encodeURIComponent(id)}/metadata`, {\n method: \"PATCH\",\n headers: { authorization: `Bearer ${secretKey}`, \"content-type\": \"application/json\" },\n body: JSON.stringify({ public_metadata: { role } }),\n });\n return res.ok;\n}\n","// The OPERATIONAL slice of the one-way person projection: applications + $users\n// -> crm_record, mirroring pipeline stage, a billing snapshot, and the Clerk\n// identity link. `network.ts` projects identity/contact on submit; this adds the\n// operational state the admin surface and the hub read from, so the pipeline\n// stays authoritative in `applications.status` while the CRM carries one\n// relationship surface over the person. Fired AFTER the authoritative write and\n// wrapped in `.catch` at every call site: a CRM hiccup never 5xxs a lifecycle op.\n//\n// Idempotent by construction — every sync resolves the person by lowercased\n// primary email first, so re-running (including the backfill route) updates in\n// place. Generalized from the reference site: the field set is the site's\n// configured `crmFields`, not a hardcoded list.\nimport { createRecord, updateRecord, setStage, linkIdentity } from \"@odla-ai/crm\";\nimport { sharedPersonInput } from \"./network\";\nimport type { ProjectionDeps } from \"./network\";\nimport type { Chapter, ChapterDb } from \"./types\";\n\nconst str = (v: unknown): string => (typeof v === \"string\" ? v : v == null ? \"\" : String(v));\n\n/** Build the projection deps from a worker request's db + context.\n *\n * Shared so every route that writes `applications.status` mirrors it the same\n * way. Status is written from four places (admin approve, admin PATCH, the\n * Stripe webhook, and booking) and the admin dashboard reads its pipeline from\n * `crm_record.stage`, so a route that skips the mirror silently reports the\n * wrong funnel. */\nexport const crmDeps = (\n db: ChapterDb,\n ctx: { chapter: Chapter },\n): ProjectionDeps & { chapter: Chapter } => ({\n crm: ctx.chapter.crm,\n db,\n now: () => Date.now(),\n newId: () => crypto.randomUUID(),\n chapter: ctx.chapter,\n});\n\n/** The crm `person` input for one application row: the built-in identity/contact\n * fields plus each configured `crmFields` value present on the row. */\nexport function personInputFromApp(chapter: Chapter, app: Record<string, unknown>): Record<string, unknown> {\n const input = sharedPersonInput({\n email: str(app.email),\n firstName: str(app.firstName) || undefined,\n lastName: str(app.lastName) || undefined,\n phone: str(app.phone) || undefined,\n linkedin: str(app.linkedin) || undefined,\n hubRecordId: str(app.id),\n });\n for (const f of chapter.application.crmFields) {\n if (app[f] !== undefined) input[f] = app[f];\n }\n if (app.id !== undefined) input.applicationId = str(app.id);\n return input;\n}\n\n// Promoted billing-facet columns derived from the application's Stripe fields +\n// status. Written directly (not through createRecord/updateRecord, which never\n// touch promoted columns), so they never clobber the person input.\nfunction billingColumns(app: Record<string, unknown>): Record<string, unknown> {\n const status = str(app.status);\n const paid = Boolean(app.stripeSubscriptionId) && status !== \"refunded\";\n const billingStatus = status === \"refunded\" ? \"refunded\" : app.canceled === true ? \"canceled\" : paid ? \"active\" : \"none\";\n const cols: Record<string, unknown> = { billingStatus };\n if (app.stripeCustomerId) cols.stripeCustomerId = str(app.stripeCustomerId);\n if (app.stripeSubscriptionId) cols.subscriptionId = str(app.stripeSubscriptionId);\n if (typeof app.renewalAt === \"number\") cols.renewalAt = app.renewalAt;\n return cols;\n}\n\n/** Upsert the person record for one application (or a synthetic `{ email,\n * firstName }` account row) and mirror its stage, billing snapshot, and Clerk\n * identity. `stage` is the `applications.status` to mirror — omit for\n * account-only rows not in the pipeline. Throws on failure (the backfill route\n * counts; the operational call sites wrap in `.catch`). */\nexport async function syncApplicationToCrm(\n deps: ProjectionDeps & { chapter: Chapter },\n opts: { app: Record<string, unknown>; stage?: string },\n): Promise<string | null> {\n const emailKey = str(opts.app.email).toLowerCase();\n if (!emailKey) return null;\n // The narrower shape the crm record helpers take (no chapter).\n const recordDeps = { crm: deps.crm, db: deps.db as never, now: deps.now, newId: deps.newId };\n const input = personInputFromApp(deps.chapter, opts.app);\n\n const { crm_record } = await deps.db.query({\n crm_record: { $: { where: { type: \"person\", primaryEmail: emailKey }, limit: 1 } },\n });\n const existing = crm_record?.[0] ?? null;\n const stage = opts.stage || undefined;\n\n let recordId: string;\n if (existing && typeof existing.id === \"string\") {\n recordId = existing.id;\n await updateRecord(recordDeps, { id: recordId, input });\n } else {\n const created = await createRecord(recordDeps, { type: \"person\", input, ...(stage ? { stage } : {}) });\n recordId = created.id;\n }\n\n // Stage mirror: move only on an actual change, under a stable mutationId so a\n // replay never piles up duplicate stage_change activities. Best-effort — a\n // stage not on the crm person type must not fail the whole sync.\n if (existing && stage && existing.stage !== stage) {\n await setStage(recordDeps, { id: recordId, to: stage, authorId: \"system\", mutationId: `crm:stage:${recordId}:${stage}` }).catch(() => undefined);\n }\n\n await deps.db.transact([{ t: \"update\", ns: \"crm_record\", id: recordId, attrs: billingColumns(opts.app) }]);\n\n // Identity link: stamps clerkUserId when a $users row matches the email; a\n // no-op until the person has an account. Best-effort — a just-created record\n // can briefly lag the read, and the link retries on the next sync.\n await linkIdentity(recordDeps, { recordId, email: emailKey, mutationId: `crm:link:${recordId}:${emailKey}` }).catch(() => undefined);\n\n return recordId;\n}\n\n/** Backfill / repair: project every application (newest per person) and every\n * account-only `$users` row into the CRM. Idempotent (safe to re-run). Dev\n * volumes fit one 1000-row page. Returns `{ synced, errors }`. */\nexport async function backfillCrm(deps: ProjectionDeps & { chapter: Chapter }): Promise<{ synced: number; errors: Array<{ email: string; error: string }> }> {\n const data = await deps.db.query({\n applications: { $: { order: { createdAt: \"desc\" }, limit: 1000 } },\n $users: { $: { limit: 1000 } },\n });\n const seen = new Set<string>();\n let synced = 0;\n const errors: Array<{ email: string; error: string }> = [];\n\n const run = async (app: Record<string, unknown>, stage?: string): Promise<void> => {\n const key = str(app.email).toLowerCase();\n if (!key || seen.has(key)) return; // newest-first: one record per person\n seen.add(key);\n try {\n await syncApplicationToCrm(deps, { app, stage });\n synced += 1;\n } catch (err) {\n errors.push({ email: key, error: err instanceof Error ? err.message : String(err) });\n }\n };\n\n for (const a of (data.applications ?? []) as Array<Record<string, unknown>>) await run(a, str(a.status));\n for (const u of (data.$users ?? []) as Array<Record<string, unknown>>) {\n if (u.deleted === true) continue;\n await run({ email: u.email, firstName: str(u.name) });\n }\n return { synced, errors };\n}\n","// Leader → follower projection of a deliberately allowlisted CRM field set.\n//\n// Invariants (package-enforced so no site re-derives them):\n// - One-way: the chapter never writes back to the hub through this path.\n// - Idempotent: every received record carries the leader's stable site +\n// record identity. A structured crm_record_origin row maps that identity to\n// the local CRM record, so a re-share updates instead of duplicating even\n// after an email/domain changes. Legacy tags remain as a migration bridge.\n// - Natural-key convergence: a person unifies by primary email and a business\n// by its configured domain slot (then name), so an arriving applicant and a\n// prior leader share compose into one person.\n// - Operational state stays local. Pipeline/account/billing state is not copied\n// into another site's authority; the push transfers the shared record fields.\n//\n// Reuses @odla-ai/crm's record ops (full validation via crm.prepare), driven by\n// the resolved chapter CRM engine + the structural ChapterDb.\nimport {\n createRecord,\n getRecordByOrigin,\n updateRecord,\n upsertRecordOrigin,\n} from \"@odla-ai/crm\";\nimport type { Crm, CrmRecord } from \"@odla-ai/crm\";\nimport type { ChapterDb, ResolvedNetworkTarget } from \"./types\";\nimport {\n DEFAULT_SHARE_FIELDS,\n type NormalizedSharedRecord,\n type ProjectionDeps,\n type SharedBusiness,\n type SharedPerson,\n type SharedRecord,\n} from \"./network-contract\";\nexport { DEFAULT_SHARE_FIELDS } from \"./network-contract\";\nexport type {\n NetworkRollup, NetworkRollupTarget,\n NetworkSnapshot,\n ProjectionDeps,\n SharedBusiness,\n SharedPerson,\n SharedRecord,\n SharedRecordV1,\n SharedRecordV2,\n} from \"./network-contract\";\n\n/** Map a shared prospect to a crm `person` input (only the fields the default\n * person type accepts). Name falls back to first+last, then the email. */\nexport function sharedPersonInput(person: SharedPerson): Record<string, unknown> {\n const email = person.email.toLowerCase();\n const fullName = [person.firstName, person.lastName].filter(Boolean).join(\" \").trim();\n const input: Record<string, unknown> = { name: person.name ?? fullName ?? email, email };\n if (input.name === \"\") input.name = email;\n if (person.firstName) input.firstName = person.firstName;\n if (person.lastName) input.lastName = person.lastName;\n if (person.phone) input.phone = person.phone;\n if (person.linkedin) input.linkedin = person.linkedin;\n return input;\n}\n\nfunction shortHash(value: string): string {\n let a = 0x811c9dc5;\n let b = 0x9e3779b9;\n for (let i = 0; i < value.length; i += 1) {\n const n = value.charCodeAt(i);\n a = Math.imul(a ^ n, 0x01000193);\n b = Math.imul(b ^ n, 0x85ebca6b);\n }\n return `${(a >>> 0).toString(36)}${(b >>> 0).toString(36)}`;\n}\n\n/** Backward-compatible display tag retained while structured origin rows are\n * the durable leader-id → local-record mapping. */\nexport function networkSourceTag(type: string, hubRecordId: string, sourceId?: string): string {\n const typeKey = type.toLowerCase();\n const readable = /^[a-z0-9_-]+$/.test(hubRecordId);\n const prefix = sourceId ? `network:${sourceId.toLowerCase()}:${typeKey}` : `network:${typeKey}`;\n const raw = `${prefix}:${hubRecordId}`;\n if (readable && raw.length <= 64) return raw;\n return `network:${typeKey.slice(0, 16)}:${shortHash(`${sourceId ?? \"\"}\\u0000${type}\\u0000${hubRecordId}`)}`;\n}\n\n/** Normalize the backwards-compatible person/business shapes into the versioned\n * generic record envelope the receiver writes. */\nexport function normalizeSharedRecord(\n record: SharedPerson | SharedBusiness | SharedRecord,\n fallbackSourceId = \"legacy-source\",\n): NormalizedSharedRecord {\n if (\"input\" in record && record.version === 2) {\n return {\n version: 2,\n sourceId: record.source.siteId,\n sourceRecordId: record.source.recordId,\n type: record.type,\n input: record.input,\n };\n }\n if (\"input\" in record) {\n return {\n version: 1,\n sourceId: fallbackSourceId,\n sourceRecordId: record.hubRecordId,\n type: record.type,\n input: record.input,\n };\n }\n if (\"type\" in record && record.type === \"company\") {\n const input: Record<string, unknown> = { name: record.name };\n for (const key of [\"domain\", \"industry\", \"location\", \"linkedin\", \"notes\"] as const) {\n if (record[key]) input[key] = record[key];\n }\n return {\n version: 1,\n sourceId: fallbackSourceId,\n sourceRecordId: record.hubRecordId,\n type: \"company\",\n input,\n };\n }\n return {\n version: 1,\n sourceId: fallbackSourceId,\n sourceRecordId: record.hubRecordId,\n type: \"person\",\n input: sharedPersonInput(record),\n };\n}\n\n/** Build the allowlisted payload sent from one leader CRM record to a target.\n * A target with an explicit `fields` map only accepts the types it lists. */\nexport function sharedRecordFromCrm(\n crm: Crm,\n record: CrmRecord,\n target: ResolvedNetworkTarget,\n sourceId?: string,\n): SharedRecord {\n if (target.fields && !target.fields[record.type]) {\n throw new Error(`${target.name} does not accept \"${record.type}\" records`);\n }\n const def = crm.type(record.type);\n const fields = target.fields?.[record.type] ?? DEFAULT_SHARE_FIELDS[record.type];\n if (!fields) {\n throw new Error(`${target.name} requires an explicit field allowlist for \"${record.type}\" records`);\n }\n const nameField = def.nameField ?? \"name\";\n const input: Record<string, unknown> = {};\n for (const field of new Set([nameField, ...fields])) {\n const value = record.fields?.[field];\n if (value !== undefined) input[field] = value;\n }\n if (input[nameField] === undefined) input[nameField] = record.name;\n return sourceId\n ? { version: 2, source: { siteId: sourceId, recordId: record.id }, type: record.type, input }\n : { version: 1, type: record.type, hubRecordId: record.id, input };\n}\n\n// Resolve an existing crm_record person by lowercased primaryEmail and update it,\n// else create one under the given mutationId. The shared core of every one-way\n// person projection (hub share, arriving applicant).\nasync function upsertPerson(\n deps: ProjectionDeps,\n opts: { email: string; input: Record<string, unknown>; mutationId: string },\n): Promise<{ recordId: string }> {\n const email = opts.email.toLowerCase();\n const crmDeps = { crm: deps.crm, db: deps.db as never, now: deps.now, newId: deps.newId };\n const { crm_record } = await deps.db.query({ crm_record: { $: { where: { type: \"person\", primaryEmail: email }, limit: 1 } } });\n const existing = crm_record?.[0];\n if (existing && typeof existing.id === \"string\") {\n await updateRecord(crmDeps, { id: existing.id, input: opts.input });\n return { recordId: existing.id };\n }\n const created = await createRecord(crmDeps, { type: \"person\", input: opts.input, mutationId: opts.mutationId });\n return { recordId: created.id };\n}\n\nasync function findSharedRecord(\n deps: ProjectionDeps,\n record: NormalizedSharedRecord,\n tag: string,\n): Promise<Record<string, unknown> | undefined> {\n const structured = await getRecordByOrigin(\n { crm: deps.crm, db: deps.db as never, now: deps.now, newId: deps.newId },\n record.sourceId,\n record.sourceRecordId,\n );\n if (structured) return structured as unknown as Record<string, unknown>;\n const mapped = await deps.db.query({ crm_tag: { $: { where: { tag }, limit: 1 } } });\n const mappedId = mapped.crm_tag?.[0]?.recordId;\n if (typeof mappedId === \"string\") {\n const found = await deps.db.query({ crm_record: { $: { where: { id: mappedId }, limit: 1 } } });\n if (found.crm_record?.[0]) return found.crm_record[0];\n }\n const def = deps.crm.type(record.type);\n const emailField = def.emailField;\n if (emailField && typeof record.input[emailField] === \"string\") {\n const primaryEmail = record.input[emailField].toLowerCase();\n const found = await deps.db.query({\n crm_record: { $: { where: { type: record.type, primaryEmail }, limit: 1 } },\n });\n if (found.crm_record?.[0]) return found.crm_record[0];\n }\n const domain = record.input.domain;\n const domainSlot = def.fields.domain?.slot;\n if (typeof domain === \"string\" && domainSlot) {\n const found = await deps.db.query({\n crm_record: { $: { where: { type: record.type, [domainSlot]: domain }, limit: 1 } },\n });\n if (found.crm_record?.[0]) return found.crm_record[0];\n }\n const nameField = def.nameField ?? \"name\";\n const name = record.input[nameField];\n if (record.type === \"company\" && typeof name === \"string\" && name.trim()) {\n const found = await deps.db.query({\n crm_record: { $: { where: { type: record.type, name: name.trim() }, limit: 1 } },\n });\n if (found.crm_record?.[0]) return found.crm_record[0];\n }\n return undefined;\n}\n\n/**\n * Upsert a leader-shared CRM record into this follower. Accepts the original\n * person wire shape plus the versioned generic shape. Re-shares resolve through\n * a durable provenance tag; people/businesses also converge by natural key.\n */\nexport async function projectSharedRecord(\n deps: ProjectionDeps,\n shared: SharedPerson | SharedBusiness | SharedRecord,\n options: { sourceId?: string; sourceUrl?: string } = {},\n): Promise<{ recordId: string }> {\n const record = normalizeSharedRecord(shared, options.sourceId);\n if (!record.type.trim() || !record.sourceId.trim() || !record.sourceRecordId.trim()) {\n throw new Error(\"type, source site id, and source record id must be non-empty\");\n }\n if (options.sourceId && options.sourceId !== record.sourceId) {\n throw new Error(\"signed sender does not match payload source\");\n }\n const tag = networkSourceTag(record.type, record.sourceRecordId, record.version === 2 ? record.sourceId : undefined);\n const crmDeps = { crm: deps.crm, db: deps.db as never, now: deps.now, newId: deps.newId };\n const existing = await findSharedRecord(deps, record, tag);\n let recordId: string;\n if (existing && typeof existing.id === \"string\") {\n // Do not use one permanent mutation id for updates: a later leader edit is a\n // new desired state and must not be mistaken for a retry of an older push.\n await updateRecord(crmDeps, { id: existing.id, input: record.input });\n recordId = existing.id;\n } else {\n // A deterministic id makes concurrent first deliveries converge even when\n // both requests observe no provenance row before either transaction lands.\n recordId = `network_${shortHash(`${record.sourceId}\\u0000${record.type}\\u0000${record.sourceRecordId}`)}`;\n await createRecord({ ...crmDeps, newId: () => recordId }, {\n type: record.type,\n input: record.input,\n mutationId: `share-create:${tag}`,\n });\n }\n await deps.db.transact(\n [{ t: \"update\", ns: \"crm_tag\", id: tag, attrs: { key: `${recordId}:${tag}`, recordId, tag, createdAt: deps.now() } }],\n { mutationId: `share-map:${tag}:${recordId}` },\n );\n await upsertRecordOrigin(crmDeps, {\n recordId,\n sourceId: record.sourceId,\n sourceRecordId: record.sourceRecordId,\n ...(options.sourceUrl ? { sourceUrl: options.sourceUrl } : {}),\n payloadVersion: record.version,\n });\n return { recordId };\n}\n\n/** An arriving applicant, as far as the CRM projection cares. `extra` carries the\n * site-configured `crmFields` (values from the application), merged on top of the\n * built-in identity/contact set. */\nexport interface Applicant {\n applicationId: string;\n email: string;\n firstName?: string;\n lastName?: string;\n phone?: string;\n linkedin?: string;\n extra?: Record<string, unknown>;\n}\n\n/**\n * Project an arriving applicant into this chapter's `crm_record`, so a new\n * application shows up in the CRM immediately, unified by email with any prior\n * record. Idempotent per application (`apply:${applicationId}`). Best-effort at\n * the call site — a projection failure never fails the application.\n *\n * `extra` fields (a site's `crmFields`) are merged on top of the base person. If\n * an extra field is not on the crm person type, crm validation throws — so the\n * projection retries with the base person alone, ensuring a misconfigured\n * enrichment never silently drops the applicant from the CRM entirely.\n */\nexport async function projectApplicant(deps: ProjectionDeps, applicant: Applicant): Promise<{ recordId: string }> {\n const base = sharedPersonInput({\n email: applicant.email,\n firstName: applicant.firstName,\n lastName: applicant.lastName,\n phone: applicant.phone,\n linkedin: applicant.linkedin,\n hubRecordId: applicant.applicationId,\n });\n const mutationId = `apply:${applicant.applicationId}`;\n const extra = applicant.extra ?? {};\n if (Object.keys(extra).length === 0) return upsertPerson(deps, { email: applicant.email, input: base, mutationId });\n try {\n return await upsertPerson(deps, { email: applicant.email, input: { ...base, ...extra }, mutationId });\n } catch {\n return upsertPerson(deps, { email: applicant.email, input: base, mutationId });\n }\n}\n","import type { Crm, TypeSummary } from \"@odla-ai/crm\";\nimport type { ChapterDb } from \"./types\";\n\n/** The contact data the hub shares for a prospect. `hubRecordId` is the stable\n * idempotency key (the hub's crm_record id). */\nexport interface SharedPerson {\n email: string;\n name?: string;\n firstName?: string;\n lastName?: string;\n phone?: string;\n linkedin?: string;\n hubRecordId: string;\n}\n\n/** Convenience wire shape for sharing the default `company` CRM type. */\nexport interface SharedBusiness {\n type: \"company\";\n name: string;\n domain?: string;\n industry?: string;\n location?: string;\n linkedin?: string;\n notes?: string;\n hubRecordId: string;\n}\n\n/** Versioned generic wire shape. `input` is validated against the follower's\n * own CRM type before any write, so a leader cannot smuggle undeclared fields. */\nexport interface SharedRecordV1 {\n version: 1;\n type: string;\n hubRecordId: string;\n input: Record<string, unknown>;\n}\n\n/** Current wire envelope. `source.siteId` prevents records from two leaders\n * with the same local id from colliding in a follower CRM. */\nexport interface SharedRecordV2 {\n version: 2;\n source: { siteId: string; recordId: string };\n type: string;\n input: Record<string, unknown>;\n}\n\n/** Accepted generic share envelopes. Version 1 remains readable for migration. */\nexport type SharedRecord = SharedRecordV1 | SharedRecordV2;\n\n/** Privacy-bounded follower status returned to an authenticated leader. */\nexport interface NetworkSnapshot {\n version: 1;\n site: { id: string; name: string; mode: string };\n generatedAt: number;\n types: TypeSummary[];\n}\n\n/** One configured target's latest live result in a leader rollup. */\nexport interface NetworkRollupTarget {\n id: string;\n name: string;\n url: string;\n available: boolean;\n generatedAt?: number;\n types?: TypeSummary[];\n error?: string;\n}\n\n/** Cross-target totals returned to the local leader admin. */\nexport interface NetworkRollup {\n configured: number;\n available: number;\n totalRecords: number;\n types: Array<{ type: string; total: number; stages: Record<string, number> }>;\n targets: NetworkRollupTarget[];\n}\n\n/** Privacy-bounded CRM record returned by a follower to one configured,\n * authenticated reader. */\nexport interface NetworkRecord {\n id: string;\n type: string;\n name: string;\n stage?: string;\n fields: Record<string, unknown>;\n createdAt: number;\n updatedAt: number;\n}\n\n/** One bounded, offset-paged follower record window. */\nexport interface NetworkRecordPage {\n version: 1;\n site: { id: string; name: string };\n type: string;\n records: NetworkRecord[];\n total: number;\n limit: number;\n offset: number;\n}\n\n/** Leader-private note attached to a stable remote record identity. */\nexport interface NetworkRecordNote {\n id: string;\n targetId: string;\n recordType: string;\n recordId: string;\n body: string;\n authorId: string;\n authorEmail?: string;\n createdAt: number;\n}\n\n/** A note deliberately shared across the federation edge and stored in the\n * follower CRM activity feed. Unlike NetworkRecordNote, this is visible to\n * the follower's own CRM admins. */\nexport interface NetworkSharedNote {\n id: string;\n sourceId: string;\n recordType: string;\n recordId: string;\n body: string;\n createdAt: number;\n}\n\nexport interface NormalizedSharedRecord {\n version: 1 | 2;\n sourceId: string;\n sourceRecordId: string;\n type: string;\n input: Record<string, unknown>;\n}\n\n/** Dependencies for applying a shared projection. */\nexport interface ProjectionDeps {\n crm: Crm;\n db: ChapterDb;\n now: () => number;\n newId: () => string;\n}\n\n/** Safe defaults when a target does not declare an explicit field allowlist. */\nexport const DEFAULT_SHARE_FIELDS: Readonly<Record<string, readonly string[]>> = {\n person: [\"name\", \"email\", \"firstName\", \"lastName\", \"phone\", \"linkedin\"],\n company: [\"name\", \"domain\", \"industry\", \"location\", \"linkedin\", \"notes\"],\n};\n","// The chapter email pipeline: exactly-once delivery, a non-production fail-safe,\n// and template rendering. Every property here is easy to get wrong and expensive\n// to get wrong, so the correctness-critical decisions — the dedupe check (E1),\n// the dev-redirect / log-only fail-safe (E2), and template rendering (E4) — are\n// PURE and fully tested in this module. The worker supplies the transport +\n// odla-db and performs the actual send + emailLog write around these decisions.\n//\n// Chapter's operational templates ({ subject, text, enabled? }) are\n// transactional lifecycle mail by construction — a site owner edits the copy in\n// Settings but cannot reclassify one as marketing. Consent-gated marketing blasts\n// go through @odla-ai/crm, which owns the transactional-vs-marketing template\n// class as code (E3), so relabeling copy can never bypass the consent gate.\n\n/** One owner-editable template row on the group. `enabled` absent = enabled. */\nexport interface EmailTemplateRow {\n subject: string;\n text: string;\n enabled?: boolean;\n}\n\n/** The `groups`-row fields the email pipeline reads. */\nexport interface EmailGroup {\n id: string;\n name: string;\n replyTo: string;\n /** Non-prod debug inbox: all mail redirects here outside prod (E2). */\n debugEmail?: string;\n refundPolicyText?: string;\n commitmentText?: string;\n normsText?: string;\n emailTemplates: Record<string, EmailTemplateRow>;\n}\n\n/** `{{placeholder}}` substitution; unknown placeholders render empty. */\nexport function render(template: string, vars: Record<string, string>): string {\n return template.replace(/\\{\\{(\\w+)\\}\\}/g, (_, key: string) => vars[key] ?? \"\");\n}\n\n/** Group-level vars every template receives, under the caller's vars. */\nfunction groupVars(group: EmailGroup, vars: Record<string, string>): Record<string, string> {\n return {\n ...vars,\n refundPolicyText: group.refundPolicyText ?? \"\",\n commitmentText: group.commitmentText ?? \"\",\n normsText: group.normsText ?? \"\",\n };\n}\n\n/**\n * Re-render a template's body for history/preview (E4): the CRM comms history\n * reads back emails whose body predates `emailLog.body` by rendering the current\n * template with the recipient's vars. Same substitution + group vars as the send\n * path. `null` for an unknown template. Reflects the copy as it reads today, not\n * necessarily the exact bytes originally sent (only `emailLog.body` is byte-exact).\n */\nexport function renderTemplateBody(group: EmailGroup, template: string, vars: Record<string, string>): string | null {\n const tpl = group.emailTemplates?.[template];\n if (!tpl) return null;\n return render(tpl.text, groupVars(group, vars));\n}\n\n/**\n * E1 (exactly-once): given the prior `emailLog` rows for a `dedupeKey`, has the\n * mail already been delivered? A prior row with **no error** means yes — the\n * caller short-circuits the resend. Failure rows (which carry an `error` and are\n * written without the dedupe mutationId) do not count, so a retry after a failure\n * can still succeed.\n */\nexport function isAlreadySent(priorRows: ReadonlyArray<{ error?: unknown }>): boolean {\n return priorRows.some((row) => !row.error);\n}\n\n/** The pure delivery decision produced by {@link planDelivery}. */\nexport type DeliveryDecision =\n | { deliver: false; reason: \"template-missing\" | \"disabled\" }\n | {\n deliver: true;\n /** Which transport to use — `log-only` records the send but delivers nothing. */\n transport: \"cloudflare\" | \"log-only\";\n to: string;\n subject: string;\n text: string;\n /** True when redirected to the non-prod debug inbox. */\n redirected: boolean;\n };\n\n/**\n * The pure delivery decision (E2 fail-safe + E3 enabled). Given the env, group,\n * template, recipient, and whether a real Cloudflare transport is wired:\n * - missing template → not delivered (`template-missing`);\n * - disabled template and not forced → not delivered (`disabled`);\n * - **non-prod with a debug inbox** → REDIRECT to it, `\"[dev] \"` subject prefix,\n * a dev-redirect note in the body, so test applicants never receive real mail;\n * - **non-prod with NO debug inbox** → force `log-only` (deliver nothing) — the\n * fail-safe that protects every site's test data;\n * - prod → deliver via the real transport (`cloudflare` if wired, else `log-only`).\n */\nexport function planDelivery(input: {\n envName: string;\n group: EmailGroup;\n template: string;\n to: string;\n vars: Record<string, string>;\n /** Whether a Cloudflare Email Service transport (binding + verified from) is wired. */\n cloudflareReady: boolean;\n /** The admin test route may send a disabled template. */\n force?: boolean;\n}): DeliveryDecision {\n const tpl = input.group.emailTemplates?.[input.template];\n if (!tpl) return { deliver: false, reason: \"template-missing\" };\n if (tpl.enabled === false && !input.force) return { deliver: false, reason: \"disabled\" };\n\n const vars = groupVars(input.group, input.vars);\n const isProd = input.envName === \"prod\";\n const redirect = !isProd && !!input.group.debugEmail;\n const transport: \"cloudflare\" | \"log-only\" =\n !isProd && !redirect ? \"log-only\" : input.cloudflareReady ? \"cloudflare\" : \"log-only\";\n const to = redirect ? (input.group.debugEmail as string) : input.to;\n const subject = (redirect ? \"[dev] \" : \"\") + render(tpl.subject, vars);\n const text = redirect\n ? `(dev redirect; original recipient: ${input.to})\\n\\n` + render(tpl.text, vars)\n : render(tpl.text, vars);\n return { deliver: true, transport, to, subject, text, redirected: redirect };\n}\n","// sendTemplated — the operational-email orchestration that wires the pure email\n// decisions (./email: isAlreadySent E1, planDelivery E2/E3) to odla-db + a\n// transport. Structural (takes a ChapterDb + a sender), so it's FakeDb-testable\n// like submitApplication/projectSharedRecord. The worker's lifecycle routes call\n// it to send the prep / payment-confirmation / admin-alert mail.\n//\n// Exactly-once is enforced twice: a prior successful emailLog row short-circuits\n// the resend (query + isAlreadySent), AND the success row is written under the\n// `email:${dedupeKey}` mutationId so a racing double-send dedupes at the db layer.\n// Failure rows omit the mutationId, so a retry after a transient failure can send.\nimport { isAlreadySent, planDelivery } from \"./email\";\nimport type { EmailGroup } from \"./email\";\nimport type { ChapterDb } from \"./types\";\n\n/** The canonical lifecycle email templates chapter fires, in send-order. Owner-\n * editable copy lives on the group row; this is the fixed set the admin email\n * editor + test route iterate. */\nexport const EMAIL_TEMPLATE_NAMES = [\"adminNotification\", \"paymentConfirmation\", \"prepEmail\", \"onboardingInvite\"] as const;\n\n/** One of {@link EMAIL_TEMPLATE_NAMES}. */\nexport type EmailTemplateName = (typeof EMAIL_TEMPLATE_NAMES)[number];\n\n/** The mail transport (the worker's Cloudflare SEND_EMAIL binding). */\nexport interface MailSender {\n send(payload: { from: string; to: string[]; subject: string; text?: string; replyTo?: string }): Promise<{ messageId: string }>;\n}\n\n/** Deps for {@link sendTemplated} — the db, the env name (drives the fail-safe),\n * the transport + from (absent ⇒ log-only), and injected clock/id. */\nexport interface NotifyDeps {\n db: ChapterDb;\n envName: string;\n sender?: MailSender;\n from?: string;\n now: () => number;\n newId: () => string;\n}\n\n/** One templated send. `dedupeKey` is the exactly-once key. */\nexport interface NotifyInput {\n group: EmailGroup;\n template: string;\n to: string;\n vars: Record<string, string>;\n dedupeKey: string;\n applicationId?: string;\n /** The admin test route may send a disabled template. */\n force?: boolean;\n}\n\n/** The outcome. `sent:true` includes the already-sent short-circuit. */\nexport interface NotifyResult {\n sent: boolean;\n reason?: string;\n}\n\n/**\n * Send a templated lifecycle email exactly once. Short-circuits on a prior\n * successful send; otherwise plans delivery (dev fail-safe applies), sends via the\n * transport when one is wired and the plan calls for it, and records an emailLog\n * row either way (success keyed for exactly-once, failure unkeyed for retry).\n */\nexport async function sendTemplated(deps: NotifyDeps, input: NotifyInput): Promise<NotifyResult> {\n const { emailLog } = await deps.db.query({ emailLog: { $: { where: { dedupeKey: input.dedupeKey } } } });\n const prior = (Array.isArray(emailLog) ? emailLog : []) as Array<{ error?: unknown }>;\n if (isAlreadySent(prior)) return { sent: true, reason: \"already-sent\" };\n\n const cloudflareReady = Boolean(deps.sender && deps.from);\n const decision = planDelivery({\n envName: deps.envName,\n group: input.group,\n template: input.template,\n to: input.to,\n vars: input.vars,\n cloudflareReady,\n force: input.force,\n });\n if (!decision.deliver) return { sent: false, reason: decision.reason };\n\n let error: string | undefined;\n let messageId: string | undefined;\n if (decision.transport === \"cloudflare\" && deps.sender && deps.from) {\n try {\n const res = await deps.sender.send({\n from: deps.from,\n to: [decision.to],\n subject: decision.subject,\n text: decision.text,\n replyTo: input.group.replyTo,\n });\n messageId = res.messageId;\n } catch (e) {\n error = e instanceof Error ? e.message : String(e);\n }\n }\n\n const id = deps.newId();\n const row: Record<string, unknown> = {\n id,\n groupId: input.group.id,\n to: decision.to,\n template: input.template,\n subject: decision.subject,\n body: decision.text,\n transport: decision.transport,\n redirected: decision.redirected,\n dedupeKey: input.dedupeKey,\n sentAt: deps.now(),\n ...(input.applicationId ? { applicationId: input.applicationId } : {}),\n ...(messageId ? { messageId } : {}),\n ...(error ? { error } : {}),\n };\n await deps.db.transact([{ t: \"update\", ns: \"emailLog\", id, attrs: row }], error ? undefined : { mutationId: `email:${input.dedupeKey}` });\n return error ? { sent: false, reason: error } : { sent: true };\n}\n\n/** Project a `groups` row into the {@link EmailGroup} the email pipeline reads. */\nexport function emailGroupFrom(row: Record<string, unknown>): EmailGroup {\n const str = (v: unknown): string | undefined => (typeof v === \"string\" ? v : undefined);\n const templates = row.emailTemplates && typeof row.emailTemplates === \"object\" ? row.emailTemplates : {};\n return {\n id: String(row.id),\n name: String(row.name ?? \"\"),\n replyTo: str(row.replyTo) ?? \"\",\n debugEmail: str(row.debugEmail),\n refundPolicyText: str(row.refundPolicyText),\n commitmentText: str(row.commitmentText),\n normsText: str(row.normsText),\n emailTemplates: templates as EmailGroup[\"emailTemplates\"],\n };\n}\n","// The application status pipeline — config, not code. Which statuses exist, which\n// a member can book an intro call from, and which an admin can approve from\n// differ per site; the one invariant every site wants is that status never moves\n// backwards. All of this is pure + tested here; the worker enforces it on every\n// status write, and the CRM record.stage mirrors application.status (never the\n// reverse). Defaults reproduce the proven membership pipeline exactly.\nimport type { ChapterPipeline, ResolvedPipeline } from \"./types\";\n\nconst DEFAULT_STAGES = [\n \"submitted\",\n \"paid_pending_vetting\",\n \"call_scheduled\",\n \"interviewed\",\n \"approved\",\n \"declined\",\n \"refunded\",\n] as const;\nconst DEFAULT_BOOKABLE = [\"submitted\", \"paid_pending_vetting\", \"call_scheduled\"] as const;\nconst DEFAULT_APPROVABLE = [\"paid_pending_vetting\", \"call_scheduled\", \"interviewed\"] as const;\n\n/**\n * Apply defaults + validate the pipeline config. With no config, the complete\n * reference pipeline. With `stages` given but the subsets omitted, the subsets\n * default to empty (a site opts in to bookable/approvable states explicitly).\n * Throws at import on a bad pipeline (empty/duplicate stages, an initial or a\n * subset entry not on the ladder).\n */\nexport function resolvePipeline(p: ChapterPipeline | undefined): ResolvedPipeline {\n const usingDefaults = !p?.stages;\n const stages = p?.stages ?? [...DEFAULT_STAGES];\n if (!Array.isArray(stages) || stages.length === 0 || !stages.every((s) => typeof s === \"string\" && s !== \"\")) {\n throw new Error(\"defineChapter.pipeline.stages: must be a non-empty array of status strings\");\n }\n if (new Set(stages).size !== stages.length) {\n throw new Error(\"defineChapter.pipeline.stages: statuses must be unique\");\n }\n const initial = p?.initial ?? (stages[0] as string);\n if (!stages.includes(initial)) {\n throw new Error(`defineChapter.pipeline.initial: \"${initial}\" is not one of the stages`);\n }\n const bookableFrom = p?.bookableFrom ?? (usingDefaults ? [...DEFAULT_BOOKABLE] : []);\n const approvableFrom = p?.approvableFrom ?? (usingDefaults ? [...DEFAULT_APPROVABLE] : []);\n for (const [name, subset] of [\n [\"bookableFrom\", bookableFrom],\n [\"approvableFrom\", approvableFrom],\n ] as const) {\n for (const s of subset) {\n if (!stages.includes(s)) throw new Error(`defineChapter.pipeline.${name}: \"${s}\" is not one of the stages`);\n }\n }\n return { stages, bookableFrom, approvableFrom, initial };\n}\n\n/** The ordinal of a status in the ladder, or -1 if unknown. */\nexport function stageIndex(status: string, p: ResolvedPipeline): number {\n return p.stages.indexOf(status);\n}\n\n/**\n * The status-never-moves-backwards invariant: a transition is allowed only when\n * both statuses are on the ladder and `to` is at or ahead of `from`. The worker\n * calls this before every status write; a violation is a 409, never a silent\n * downgrade.\n */\nexport function canTransition(from: string, to: string, p: ResolvedPipeline): boolean {\n const fi = p.stages.indexOf(from);\n const ti = p.stages.indexOf(to);\n return fi >= 0 && ti >= 0 && ti >= fi;\n}\n\n/** May an intro call be booked from this status? */\nexport function canBook(status: string, p: ResolvedPipeline): boolean {\n return p.bookableFrom.includes(status);\n}\n\n/** May an application be approved (→ member) from this status? */\nexport function canApprove(status: string, p: ResolvedPipeline): boolean {\n return p.approvableFrom.includes(status);\n}\n","import { getVaultSecret } from \"./auth\";\nimport { clerkGetUserByEmail, clerkSetRole } from \"./clerk-roles\";\nimport { crmDeps, syncApplicationToCrm } from \"./crm-sync\";\nimport { emailGroupFrom, sendTemplated } from \"./notify\";\nimport { canApprove, canTransition } from \"./pipeline\";\nimport type { ChapterDb } from \"./types\";\nimport type { ChapterEnv, WorkerContext } from \"./worker-context\";\n\ntype Row = Record<string, unknown>;\n\nexport interface ApproveApplicationResult {\n ok: boolean;\n status: number;\n error?: string;\n rolePromoted?: boolean;\n emailLogged?: boolean;\n duplicate?: boolean;\n}\n/**\n * Converge one application on approved state and repair every external effect.\n * Manual and waiver-driven approval use this exact operation. Database and\n * email idempotency keys are stable, while Clerk role and CRM writes are safe\n * to repeat after an ambiguous response.\n */\nexport async function approveApplication(input: {\n db: ChapterDb;\n env: ChapterEnv;\n ctx: WorkerContext;\n app: Row;\n origin: string;\n reason: \"manual\" | \"interview_waiver\";\n}): Promise<ApproveApplicationResult> {\n const { db, env, ctx, app } = input;\n const id = String(app.id ?? \"\");\n const status = String(app.status ?? \"\");\n if (!id) return { ok: false, status: 404, error: \"not found\" };\n if (input.reason === \"manual\" && status !== \"approved\" && !canApprove(status, ctx.chapter.pipeline)) {\n return { ok: false, status: 409, error: `cannot approve from status \"${status}\"` };\n }\n if (input.reason === \"interview_waiver\") {\n if (typeof app.interviewWaivedAt !== \"number\") return { ok: false, status: 409, error: \"interview waiver required\" };\n if (status !== \"approved\" && !canTransition(status, \"approved\", ctx.chapter.pipeline)) {\n return { ok: false, status: 409, error: `cannot approve from status \"${status}\"` };\n }\n }\n const write = await db.transact(\n [{ t: \"update\", ns: \"applications\", id, attrs: { status: \"approved\" } }],\n { mutationId: `approve:${id}` },\n );\n const approved = { ...app, status: \"approved\" };\n await syncApplicationToCrm(crmDeps(db, ctx), { app: approved, stage: \"approved\" }).catch(() => undefined);\n\n const { promoteTo, send } = ctx.chapter.operations.onApprove;\n let rolePromoted = false;\n const secret = await getVaultSecret(db, \"clerk_secret_key\");\n if (promoteTo !== false && secret) {\n let userId = typeof app.clerkUserId === \"string\" ? app.clerkUserId : null;\n if (!userId && typeof app.email === \"string\") {\n const found = await clerkGetUserByEmail(secret, app.email);\n userId = found?.id ?? null;\n if (userId) await db.transact([{ t: \"update\", ns: \"applications\", id, attrs: { clerkUserId: userId } }]);\n }\n if (userId) rolePromoted = await clerkSetRole(secret, userId, promoteTo);\n }\n\n let emailLogged = false;\n const groups = (await db.query({ groups: { $: { where: { id: String(app.groupId ?? ctx.chapter.id) }, limit: 1 } } })).groups;\n const group = Array.isArray(groups) ? groups[0] : undefined;\n if (send !== false && group && typeof app.email === \"string\") {\n const result = await sendTemplated(\n { db, envName: env.ODLA_ENV, sender: env.SEND_EMAIL, from: env.EMAIL_FROM, now: () => Date.now(), newId: () => crypto.randomUUID() },\n {\n group: emailGroupFrom(group),\n template: send,\n to: app.email,\n vars: { firstName: String(app.firstName ?? \"\"), membersUrl: `${input.origin}/members/` },\n applicationId: id,\n dedupeKey: `approve:${id}`,\n },\n );\n emailLogged = result.sent;\n }\n return { ok: true, status: 200, rolePromoted, emailLogged, duplicate: write.duplicate };\n}\n","import { canBook } from \"./pipeline\";\nimport type { ResolvedPipeline } from \"./types\";\n\n/** Canonical next action or browser-visible step after application submission. */\nexport type JoinContinuation = \"payment\" | \"paymentPending\" | \"booking\" | \"approve\" | \"accepted\";\n\n/** One server-side decision for submit, resume, and payment completion. */\nexport function resolveJoinContinuation(input: {\n status: string;\n initialStatus: string;\n pipeline: ResolvedPipeline;\n payable: boolean;\n subscriptionStarted: boolean;\n interviewWaived: boolean;\n}): JoinContinuation | null {\n if (input.status === \"approved\") return \"accepted\";\n if (input.interviewWaived) {\n if (!input.payable) return \"approve\";\n if (input.status === input.initialStatus) {\n return input.subscriptionStarted ? \"paymentPending\" : \"payment\";\n }\n return \"approve\";\n }\n if (!input.payable) return \"booking\";\n if (input.status === input.initialStatus) {\n return input.subscriptionStarted ? \"paymentPending\" : \"payment\";\n }\n if (canBook(input.status, input.pipeline)) return \"booking\";\n return null;\n}\n","import { findTier, tierIsFree, tierPayable } from \"./tiers\";\nimport { loadOfferableTiers } from \"./tiers-store\";\nimport { getVaultSecret } from \"./auth\";\nimport { approveApplication } from \"./approve-application\";\nimport { resolveJoinContinuation } from \"./join-continuation\";\nimport type { ChapterDb } from \"./types\";\nimport type { Route } from \"./worker-context\";\n\n/** Resolve and, when eligible, execute the canonical post-signup continuation. */\nexport async function continueJoin(\n db: ChapterDb,\n ctx: Parameters<Route>[3],\n env: Parameters<Route>[2],\n origin: string,\n app: Record<string, unknown>,\n group: Record<string, unknown>,\n): Promise<\"payment\" | \"paymentPending\" | \"booking\" | \"accepted\" | \"gift\" | null> {\n if (typeof app.giftOfferId === \"string\") {\n if (typeof app.giftClaimId === \"string\") return \"gift\";\n return typeof app.giftCheckoutStartedAt === \"number\" ? \"paymentPending\" : \"payment\";\n }\n const stripeKey = await getVaultSecret(db, \"stripe_secret_key\");\n const offered = await loadOfferableTiers(db, group as never, Boolean(stripeKey));\n const tier = findTier(offered, typeof app.tierId === \"string\" ? app.tierId : null);\n const payable = Boolean(tier) && !tierIsFree(tier!) && tierPayable(tier!, group as never, Boolean(stripeKey));\n const state = resolveJoinContinuation({\n status: String(app.status ?? \"\"), initialStatus: ctx.chapter.pipeline.initial,\n pipeline: ctx.chapter.pipeline, payable,\n subscriptionStarted: typeof app.stripeSubscriptionId === \"string\" && app.stripeSubscriptionId !== \"\",\n interviewWaived: typeof app.interviewWaivedAt === \"number\",\n });\n if (state !== \"approve\") return state;\n const approved = await approveApplication({ db, env, ctx, app, origin, reason: \"interview_waiver\" });\n return approved.ok ? \"accepted\" : null;\n}\n","import type { SignupControlDocument, SignupControlEnvelope } from \"./signup-control-contract\";\nimport type { Chapter, ChapterDb, DbOp, ResolvedApplication } from \"./types\";\n\ntype DbLookup = { ns: string; attr: string; value: string | number | boolean };\n\nexport interface StoredSignupControl {\n id: string;\n sourceId: string;\n targetId: string;\n environment: string;\n revision: number;\n digest: string;\n document: SignupControlDocument;\n active: boolean;\n receivedAt: number;\n}\n\nfunction asStored(row: Record<string, unknown> | undefined): StoredSignupControl | null {\n if (!row || typeof row.document !== \"object\" || row.document === null) return null;\n return row as unknown as StoredSignupControl;\n}\n\nasync function hasSignupControl(\n db: ChapterDb,\n targetId: string,\n environment: string,\n active?: true,\n): Promise<boolean> {\n const where = { targetId, environment, ...(active ? { active: true } : {}) };\n if (db.aggregate) {\n return Number((await db.aggregate(\"signupControls\", { count: true }, { where })).count ?? 0) > 0;\n }\n // Compatibility for structural test doubles that predate aggregate(). This\n // deliberately uses the empty-safe query shape and filters locally.\n const rows = (await db.query({ signupControls: {} })).signupControls;\n return Array.isArray(rows) && rows.some((row) =>\n row.targetId === targetId && row.environment === environment && (!active || row.active === true));\n}\n\nexport async function loadLatestSignupControl(\n db: ChapterDb,\n targetId: string,\n environment: string,\n): Promise<StoredSignupControl | null> {\n // Some deployed data planes do not terminate an ordered+filtered query when\n // the namespace has no matching rows. The count route is independently\n // bounded and empty-safe; only order a set we have proved is non-empty.\n if (!await hasSignupControl(db, targetId, environment)) return null;\n const rows = (await db.query({ signupControls: { $: {\n where: { targetId, environment }, order: { revision: \"desc\" }, limit: 1,\n } } })).signupControls;\n const latest = Array.isArray(rows)\n ? [...rows].sort((a, b) => Number(b.revision ?? 0) - Number(a.revision ?? 0))[0]\n : undefined;\n return asStored(latest);\n}\n\nexport async function loadActiveSignupControl(\n db: ChapterDb,\n targetId: string,\n environment: string,\n): Promise<StoredSignupControl | null> {\n if (!await hasSignupControl(db, targetId, environment, true)) return null;\n const rows = (await db.query({ signupControls: { $: {\n where: { targetId, environment, active: true }, order: { revision: \"desc\" }, limit: 1,\n } } })).signupControls;\n const active = Array.isArray(rows)\n ? [...rows].sort((a, b) => Number(b.revision ?? 0) - Number(a.revision ?? 0))[0]\n : undefined;\n return asStored(active);\n}\n\n/** Apply only field names the follower schema already declared. */\nexport function controlledApplication(\n base: ResolvedApplication,\n document: SignupControlDocument | undefined,\n): ResolvedApplication {\n const delegated = document?.application;\n return delegated\n ? { ...base, required: delegated.required, optional: delegated.optional, conditions: { ...(delegated.conditions ?? {}) } }\n : base;\n}\n\nexport function validateControlledApplication(chapter: Chapter, document: SignupControlDocument): string[] {\n if (!document.application) return [];\n const declared = new Set([...chapter.application.required, ...chapter.application.optional]);\n return [...document.application.required, ...document.application.optional]\n .filter((field) => !declared.has(field))\n .map((field) => `document.application field \"${field}\" is not declared by this chapter schema`);\n}\n\nfunction groupAttrs(document: SignupControlDocument): Record<string, unknown> {\n const first = [...document.tiers].filter((tier) => tier.available).sort((a, b) => a.sortOrder - b.sortOrder)[0];\n const firstPaid = [...document.tiers].find((tier) => tier.available && tier.priceCents > 0);\n return {\n ...(first ? { standardPriceCents: first.priceCents } : {}),\n foundingDiscountCents: 0,\n ...(firstPaid?.stripePriceId ? { stripePriceId: firstPaid.stripePriceId } : {}),\n ...(document.policy ?? {}),\n ...(document.scheduling ? { schedulingJson: document.scheduling } : {}),\n };\n}\n\nconst byPublicId = (ns: \"groups\" | \"tiers\", value: string): DbLookup => ({\n ns,\n attr: \"id\",\n value,\n});\n\n/** Transactionally activate one revision and materialize the tables checkout already reads. */\nexport async function materializeSignupControl(\n db: ChapterDb,\n envelope: SignupControlEnvelope,\n previous: StoredSignupControl | null,\n receivedAt: number,\n): Promise<void> {\n const { document, digest } = envelope;\n const currentRows = (await db.query({ tiers: { $: {\n where: { groupId: document.target.chapterId }, limit: 100,\n } } })).tiers ?? [];\n const incoming = new Set(document.tiers.map((tier) => tier.id));\n const ops: DbOp<string | DbLookup>[] = [];\n if (previous?.active) ops.push({ t: \"update\", ns: \"signupControls\", id: previous.id, attrs: { active: false } });\n for (const row of currentRows) {\n const id = String(row.id ?? \"\");\n if (id && !incoming.has(id)) {\n ops.push({ t: \"update\", ns: \"tiers\", id: byPublicId(\"tiers\", id), attrs: { active: false } });\n }\n }\n for (const tier of document.tiers) {\n const tierRef = byPublicId(\"tiers\", tier.id);\n ops.push({ t: \"update\", ns: \"tiers\", id: tierRef, attrs: {\n id: tier.id,\n groupId: document.target.chapterId,\n name: tier.name,\n priceCents: tier.priceCents,\n ...(tier.stripePriceId ? { stripePriceId: tier.stripePriceId } : {}),\n ...(tier.blurb ? { blurb: tier.blurb } : {}),\n sortOrder: tier.sortOrder,\n active: tier.available,\n createdAt: receivedAt,\n } });\n const retract = [\n ...(!tier.stripePriceId ? [\"stripePriceId\"] : []),\n ...(!tier.blurb ? [\"blurb\"] : []),\n ];\n if (retract.length) ops.push({ t: \"retract\", ns: \"tiers\", id: tierRef, attrs: retract });\n }\n const groupRef = byPublicId(\"groups\", document.target.chapterId);\n const attrs = groupAttrs(document);\n ops.push({\n t: \"update\",\n ns: \"groups\",\n id: groupRef,\n attrs,\n });\n if (!(\"stripePriceId\" in attrs)) {\n ops.push({ t: \"retract\", ns: \"groups\", id: groupRef, attrs: [\"stripePriceId\"] });\n }\n const id = `signup-control:${document.target.environment}:${document.revision}`;\n ops.push({ t: \"update\", ns: \"signupControls\", id, attrs: {\n id,\n sourceId: document.source.appId,\n targetId: document.target.chapterId,\n environment: document.target.environment,\n revision: document.revision,\n digest,\n document,\n active: true,\n receivedAt,\n } });\n await db.transact(ops, { mutationId: `signup-control:${document.target.environment}:${document.revision}:${digest}` });\n}\n","// The member session — what GET /api/me returns to a signed-in applicant/member.\n// Ported from the reference application's summary + /api/me reconciliation. The\n// SHAPING is pure and package-enforced so no site re-derives it; the worker owns\n// only the I/O around it (locating the application by email, reconciling the\n// meeting against the calendar) and hands the resolved rows here.\n//\n// Two invariants live here, not in a site:\n// - `paid` is DERIVED, never a stored flag: a subscription exists and the\n// application wasn't refunded. Sites can't drift a stale boolean out of sync\n// with Stripe.\n// - the live meeting row wins: its startAt/meetUrl/timezone override whatever\n// the application row cached, and a non-scheduled meeting (a cancellation\n// adopted from the calendar) forces meetingAt back to null.\n\n/** An application row, as far as the session cares about it. */\nexport interface ApplicationRecord {\n id: string;\n firstName?: string | null;\n lastName?: string | null;\n email?: string | null;\n status: string;\n meetingAt?: number | null;\n meetingLink?: string | null;\n createdAt?: number | null;\n stripeSubscriptionId?: string | null;\n renewalAt?: number | null;\n canceled?: boolean;\n tierId?: string | null;\n}\n\n/** The reconciled meeting row (already adopted against the calendar), or null. */\nexport interface MeetingRecord {\n status: string;\n startAt?: number | null;\n meetUrl?: string | null;\n timezone?: string | null;\n}\n\n/** The stable, non-meeting fields of an application (safe to expose to its own\n * owner). */\nexport interface ApplicationSummary {\n id: string;\n firstName: string | null;\n lastName: string | null;\n email: string | null;\n status: string;\n createdAt: number | null;\n meetingLink: string | null;\n paid: boolean;\n renewalAt: number | null;\n canceled: boolean;\n /** Server-authoritative membership tier selected on this application. */\n tierId: string | null;\n}\n\n/** A summary plus the reconciled meeting fields — the `application` the member\n * area renders. */\nexport interface MemberApplication extends ApplicationSummary {\n meetingAt: number | null;\n meetUrl: string | null;\n timezone: string;\n}\n\n/** The full GET /api/me payload for a signed-in user. */\nexport interface MemberSession {\n userId: string;\n email: string | null;\n role: string;\n superAdmin: boolean;\n application: MemberApplication | null;\n}\n\n/** Derive the summary fields from an application row. `paid` is computed, not\n * read, so it can never contradict Stripe. */\nexport function applicationSummary(app: ApplicationRecord): ApplicationSummary {\n return {\n id: app.id,\n firstName: app.firstName ?? null,\n lastName: app.lastName ?? null,\n email: app.email ?? null,\n status: app.status,\n createdAt: app.createdAt ?? null,\n meetingLink: app.meetingLink ?? null,\n paid: Boolean(app.stripeSubscriptionId) && app.status !== \"refunded\",\n renewalAt: app.renewalAt ?? null,\n canceled: app.canceled === true,\n tierId: app.tierId ?? null,\n };\n}\n\n/** Fold a (possibly absent, already-reconciled) meeting into the application the\n * member area renders. The live meeting overrides the application's cached\n * meeting fields; a non-`scheduled` meeting clears the booking. */\nexport function memberApplication(\n app: ApplicationRecord,\n meeting: MeetingRecord | null | undefined,\n defaultTimezone: string,\n): MemberApplication {\n const summary = applicationSummary(app);\n let meetingAt = app.meetingAt ?? null;\n let meetUrl: string | null = null;\n let timezone = defaultTimezone;\n if (meeting) {\n timezone = meeting.timezone ?? timezone;\n if (meeting.status === \"scheduled\") {\n meetingAt = meeting.startAt ?? null;\n meetUrl = meeting.meetUrl ?? null;\n } else {\n meetingAt = null;\n }\n }\n return { ...summary, meetingAt, meetUrl, timezone };\n}\n\n/** Identity of the signed-in user, from the verified session. */\nexport interface SessionUser {\n userId: string;\n email?: string | null;\n role: string;\n}\n\n/** Assemble the GET /api/me payload. `application` is null when the user has no\n * application on file (an admin who never applied, or a brand-new account). */\nexport function memberSession(\n user: SessionUser,\n opts: { application: MemberApplication | null; superAdmin: boolean },\n): MemberSession {\n return {\n userId: user.userId,\n email: user.email ?? null,\n role: user.role,\n superAdmin: opts.superAdmin,\n application: opts.application,\n };\n}\n","// Apply-time account provisioning. When an application arrives, the worker mints\n// a Clerk invitation so the applicant gets a path into their member area — the\n// generalized server-side account step. Chapter calls the Clerk\n// Backend API directly over fetch (vault clerk_secret_key), mirroring\n// @odla-ai/auth-clerk's createInvitation but self-contained, so it never pulls the\n// auth-clerk UI package into the worker bundle. Best-effort at the call site: a\n// provisioning failure never fails the application.\n\n/** The outcome of a Clerk provisioning call. `existed` marks the heal case: Clerk\n * rejected it because the account/invitation is already there, which is the end\n * state we wanted anyway. */\nexport interface ClerkResult {\n ok: boolean;\n status: number;\n existed?: boolean;\n /** Set when an `existed` heal also refreshed the account's metadata. */\n refreshed?: boolean;\n}\n\n// Clerk answers 422 when the email already has a user (or a pending invitation).\n// For apply-time provisioning that's success, not failure — the account exists.\nconst heal = (status: number): ClerkResult =>\n status === 422 ? { ok: true, status, existed: true } : { ok: false, status };\n\n/** Inputs for a Clerk invitation. */\nexport interface ClerkInviteInput {\n email: string;\n /** Where the accept-invitation link lands (usually the member area). */\n redirectUrl?: string;\n /** Written to the invitation's `public_metadata`. Clerk application\n * invitations cannot carry private metadata, so never put applicant profile\n * fields here. Chapter completes that backend-only write after acceptance. */\n publicMetadata?: Record<string, unknown>;\n}\n\n/** Build the Clerk Backend API invitation request (path + JSON body). Pure, so\n * the wire shape is testable without a network call. */\nexport function clerkInviteRequest(input: ClerkInviteInput): { path: string; body: Record<string, unknown> } {\n return {\n path: \"/v1/invitations\",\n body: {\n email_address: input.email,\n notify: true,\n ...(input.redirectUrl ? { redirect_url: input.redirectUrl } : {}),\n ...(input.publicMetadata ? { public_metadata: input.publicMetadata } : {}),\n },\n };\n}\n\n/** POST the invitation to the Clerk Backend API. A repeat invite for an\n * already-invited email heals to `{ ok: true, existed: true }` rather than\n * reporting a failure the caller would have to special-case. */\nexport async function createClerkInvitation(\n secretKey: string,\n input: ClerkInviteInput,\n fetchImpl: typeof fetch = fetch,\n): Promise<ClerkResult> {\n const { path, body } = clerkInviteRequest(input);\n const res = await fetchImpl(`https://api.clerk.com${path}`, {\n method: \"POST\",\n headers: { authorization: `Bearer ${secretKey}`, \"content-type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n return res.ok ? { ok: true, status: res.status } : heal(res.status);\n}\n\n/** Inputs for a server-side Clerk user create. */\nexport interface ClerkUserInput {\n email: string;\n firstName?: string;\n lastName?: string;\n /** Backend-authored, browser-readable claims such as `role`. */\n publicMetadata?: Record<string, unknown>;\n /** Backend-only account signals and profile data. */\n privateMetadata?: Record<string, unknown>;\n /** Optional metadata merge used only when create returns 422 for an existing\n * account. This lets migrations remove legacy keys without putting tombstone\n * values on a newly-created user. Defaults to the create metadata. */\n repairMetadata?: ClerkMetadataInput;\n}\n\n/** Build the Clerk Backend API user-create request. The account is created\n * passwordless (the member signs in via the site's Clerk flow), so join step 3\n * can say the account is ready — the \"create\" alternative to an invitation. */\nexport function clerkUserRequest(input: ClerkUserInput): { path: string; body: Record<string, unknown> } {\n return {\n path: \"/v1/users\",\n body: {\n email_address: [input.email],\n skip_password_requirement: true,\n ...(input.firstName ? { first_name: input.firstName } : {}),\n ...(input.lastName ? { last_name: input.lastName } : {}),\n ...(input.publicMetadata !== undefined ? { public_metadata: input.publicMetadata } : {}),\n ...(input.privateMetadata !== undefined ? { private_metadata: input.privateMetadata } : {}),\n },\n };\n}\n\n/** One merge-PATCH to the metadata fields Clerk exposes on its Backend API. */\nexport interface ClerkMetadataInput {\n publicMetadata?: Record<string, unknown>;\n privateMetadata?: Record<string, unknown>;\n}\n\n/** Merge metadata into an existing Clerk user. Nested `null` values remove old\n * keys, which Chapter uses to migrate its former public profile into private\n * metadata without disturbing the public `role` claim. */\nexport async function updateClerkUserMetadata(\n secretKey: string,\n userId: string,\n input: ClerkMetadataInput,\n fetchImpl: typeof fetch = fetch,\n): Promise<boolean> {\n const res = await fetchImpl(`https://api.clerk.com/v1/users/${encodeURIComponent(userId)}/metadata`, {\n method: \"PATCH\",\n headers: { authorization: `Bearer ${secretKey}`, \"content-type\": \"application/json\" },\n body: JSON.stringify({\n ...(input.publicMetadata !== undefined ? { public_metadata: input.publicMetadata } : {}),\n ...(input.privateMetadata !== undefined ? { private_metadata: input.privateMetadata } : {}),\n }),\n });\n return res.ok;\n}\n\n/** Look a Clerk account up by email and merge its metadata.\n *\n * Returns `false` when no matching user can be resolved or Clerk rejects the\n * lookup or update. Chapter uses this for create-healing and invitation\n * adoption so a repeated application repairs the private account snapshot.\n */\nexport async function updateClerkUserMetadataByEmail(\n secretKey: string,\n email: string,\n input: ClerkMetadataInput,\n fetchImpl: typeof fetch = fetch,\n): Promise<boolean> {\n const auth = { authorization: `Bearer ${secretKey}` };\n const found = await fetchImpl(`https://api.clerk.com/v1/users?email_address=${encodeURIComponent(email)}&limit=1`, { headers: auth });\n if (!found.ok) return false;\n const users = (await found.json().catch(() => null)) as Array<{ id?: unknown }> | null;\n const id = Array.isArray(users) && typeof users[0]?.id === \"string\" ? users[0].id : undefined;\n if (!id) return false;\n return updateClerkUserMetadata(secretKey, id, input, fetchImpl);\n}\n\n/** Create the applicant's Clerk account server-side. A repeat for an email that\n * already has an account heals to `{ ok: true, existed: true }` — the account\n * exists, which is the state apply-time provisioning wanted — and refreshes\n * supplied public/private metadata on the existing account so a re-application\n * repairs a previously missed create (`refreshed: true`). */\nexport async function createClerkUser(\n secretKey: string,\n input: ClerkUserInput,\n fetchImpl: typeof fetch = fetch,\n): Promise<ClerkResult> {\n const { path, body } = clerkUserRequest(input);\n const res = await fetchImpl(`https://api.clerk.com${path}`, {\n method: \"POST\",\n headers: { authorization: `Bearer ${secretKey}`, \"content-type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n if (res.ok) return { ok: true, status: res.status };\n const healed = heal(res.status);\n const repair = input.repairMetadata ?? {\n ...(input.publicMetadata !== undefined ? { publicMetadata: input.publicMetadata } : {}),\n ...(input.privateMetadata !== undefined ? { privateMetadata: input.privateMetadata } : {}),\n };\n if (\n !healed.existed ||\n (repair.publicMetadata === undefined && repair.privateMetadata === undefined)\n ) return healed;\n const refreshed = await updateClerkUserMetadataByEmail(secretKey, input.email, {\n ...(repair.publicMetadata !== undefined ? { publicMetadata: repair.publicMetadata } : {}),\n ...(repair.privateMetadata !== undefined ? { privateMetadata: repair.privateMetadata } : {}),\n }, fetchImpl).catch(() => false);\n return { ...healed, refreshed };\n}\n","import { getVaultSecret } from \"./auth\";\nimport {\n createClerkInvitation,\n createClerkUser,\n updateClerkUserMetadata,\n updateClerkUserMetadataByEmail,\n} from \"./clerk\";\nimport { applicantProfile } from \"./member\";\nimport { projectApplicant } from \"./network\";\nimport { emailGroupFrom, sendTemplated } from \"./notify\";\nimport type { Chapter, ChapterDb } from \"./types\";\nimport type { ChapterEnv } from \"./worker-context\";\n\nexport const applicantPrivateMetadata = (\n chapter: Chapter,\n applicationId: string,\n fields: Record<string, unknown>,\n removeMissingProfile = false,\n): Record<string, unknown> => {\n const profile = applicantProfile(chapter, fields);\n return {\n applicationId,\n ...(profile ? { profile } : removeMissingProfile ? { profile: null } : {}),\n };\n};\n\n// The previous Chapter contract wrote these keys into browser-readable public\n// metadata. A private-profile sync removes only those Chapter-owned keys while\n// preserving `public_metadata.role` and any host-owned public claims.\nexport const publicProfileRemoval = { applicationId: null, profile: null };\n\nexport async function markPrivateMetadataSynced(\n db: ChapterDb,\n applicationId: string,\n clerkUserId?: string,\n): Promise<void> {\n await db.transact([{\n t: \"update\",\n ns: \"applications\",\n id: applicationId,\n attrs: {\n clerkPrivateMetadataSyncedAt: Date.now(),\n ...(clerkUserId ? { clerkUserId } : {}),\n },\n }]);\n}\n\n/** Complete or repair the backend-only Clerk snapshot once an invited/manual\n * account exists. This is called on first member-session load and is idempotent:\n * Clerk deep-merges the private keys and removes only Chapter's former public\n * profile keys. */\nexport async function syncApplicantPrivateMetadata(\n db: ChapterDb,\n chapter: Chapter,\n applicationId: string,\n fields: Record<string, unknown>,\n clerkUserId: string,\n): Promise<boolean> {\n if (chapter.account === \"none\") return false;\n try {\n const secret = await getVaultSecret(db, \"clerk_secret_key\");\n if (!secret) return false;\n const ok = await updateClerkUserMetadata(secret, clerkUserId, {\n publicMetadata: publicProfileRemoval,\n privateMetadata: applicantPrivateMetadata(chapter, applicationId, fields, true),\n });\n if (!ok) return false;\n await markPrivateMetadataSynced(db, applicationId, clerkUserId);\n return true;\n } catch {\n return false;\n }\n}\n\n// Apply-time provisioning is best-effort: project the applicant into crm_record\n// and optionally mint a Clerk account or invitation.\nexport async function provisionApplicant(\n db: ChapterDb,\n chapter: Chapter,\n applicationId: string,\n fields: Record<string, unknown>,\n): Promise<void> {\n const email = typeof fields.email === \"string\" ? fields.email : \"\";\n if (!email) return;\n const stringValue = (value: unknown): string | undefined =>\n typeof value === \"string\" ? value : undefined;\n const extra: Record<string, unknown> = {};\n for (const field of chapter.application.crmFields) {\n if (fields[field] !== undefined) extra[field] = fields[field];\n }\n try {\n await projectApplicant(\n { crm: chapter.crm, db, now: () => Date.now(), newId: () => crypto.randomUUID() },\n {\n applicationId,\n email,\n firstName: stringValue(fields.firstName),\n lastName: stringValue(fields.lastName),\n phone: stringValue(fields.phone),\n linkedin: stringValue(fields.linkedin),\n extra,\n },\n );\n } catch {\n // CRM projection is best-effort.\n }\n if (chapter.account === \"none\") return;\n try {\n const secret = await getVaultSecret(db, \"clerk_secret_key\");\n if (!secret) return;\n const privateMetadata = applicantPrivateMetadata(chapter, applicationId, fields);\n if (chapter.account === \"create\") {\n const result = await createClerkUser(secret, {\n email,\n firstName: stringValue(fields.firstName),\n lastName: stringValue(fields.lastName),\n privateMetadata,\n repairMetadata: {\n publicMetadata: publicProfileRemoval,\n privateMetadata: applicantPrivateMetadata(chapter, applicationId, fields, true),\n },\n });\n if (result.ok && (!result.existed || result.refreshed)) {\n await markPrivateMetadataSynced(db, applicationId);\n }\n } else {\n // Clerk application invitations only transfer public metadata. Send no\n // applicant data with the invite; if the account already exists, repair it\n // now, otherwise /api/me completes the private write after acceptance.\n const result = await createClerkInvitation(secret, { email });\n if (result.existed) {\n const refreshed = await updateClerkUserMetadataByEmail(secret, email, {\n publicMetadata: publicProfileRemoval,\n privateMetadata: applicantPrivateMetadata(chapter, applicationId, fields, true),\n });\n if (refreshed) await markPrivateMetadataSynced(db, applicationId);\n }\n }\n } catch {\n // Account provisioning is best-effort.\n }\n}\n\n// Notify a human when an application arrives. The dedupe key makes the\n// best-effort send exactly-once per application.\nexport async function notifyAdminOfApplication(\n db: ChapterDb,\n env: ChapterEnv,\n chapterId: string,\n applicationId: string,\n fields: Record<string, unknown>,\n): Promise<void> {\n try {\n const groups = (\n await db.query({ groups: { $: { where: { id: chapterId }, limit: 1 } } })\n ).groups;\n const group = Array.isArray(groups) ? groups[0] : undefined;\n if (!group || typeof group.notificationEmail !== \"string\" || !group.notificationEmail) return;\n const stringValue = (value: unknown): string => typeof value === \"string\" ? value : \"\";\n await sendTemplated(\n {\n db,\n envName: env.ODLA_ENV,\n sender: env.SEND_EMAIL,\n from: env.EMAIL_FROM,\n now: () => Date.now(),\n newId: () => crypto.randomUUID(),\n },\n {\n group: emailGroupFrom(group),\n template: \"adminNotification\",\n to: group.notificationEmail,\n vars: {\n firstName: stringValue(fields.firstName),\n lastName: stringValue(fields.lastName),\n email: stringValue(fields.email),\n phone: stringValue(fields.phone),\n state: stringValue(fields.state),\n },\n dedupeKey: `apply:${applicationId}:admin`,\n applicationId,\n },\n );\n } catch {\n // Never fail the application on a notification error.\n }\n}\n","// Follower-side receiver for one allowlisted CRM projection. Kept separate\n// from member routes and leader fan-out so each security boundary stays small.\nimport { FEDERATION_HEADERS, verifyFederatedRequest } from \"@odla-ai/db\";\nimport { getVaultSecret } from \"./auth\";\nimport { normalizeSharedRecord, projectSharedRecord } from \"./network\";\nimport { json } from \"./worker-context\";\nimport type { Route } from \"./worker-context\";\nimport type { ChapterDb } from \"./types\";\n\n/** POST /api/network/shared — signed leader projection into this site's CRM. */\nexport const handleNetworkShared: Route = async (req, url, env, ctx) => {\n if (req.method !== \"POST\" || url.pathname !== \"/api/network/shared\") return null;\n const db = ctx.makeDb(env);\n const secret = await getVaultSecret(db as unknown as ChapterDb, \"network_share_secret\");\n if (!secret) return json({ error: \"unauthorized\" }, 401);\n\n let raw: string;\n let sourceId: string | undefined;\n if (req.headers.has(FEDERATION_HEADERS.version)) {\n const verified = await verifyFederatedRequest(req, { secret });\n if (!verified.ok) return json({ error: \"unauthorized\", reason: verified.reason }, 401);\n raw = verified.body;\n sourceId = verified.sender;\n } else {\n // Version-1 migration path. New leaders sign requests; the bearer path\n // remains readable while a follower upgrades in place.\n const provided = (req.headers.get(\"authorization\") ?? \"\").replace(/^Bearer /, \"\");\n if (provided.length !== secret.length || provided !== secret) {\n return json({ error: \"unauthorized\" }, 401);\n }\n raw = await req.text();\n }\n let payload: Record<string, unknown>;\n try {\n payload = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n if (\"input\" in payload) {\n const v1 = payload.version === 1 && typeof payload.hubRecordId === \"string\" && payload.hubRecordId.trim();\n const source = payload.source as { siteId?: unknown; recordId?: unknown } | undefined;\n const v2 = payload.version === 2 &&\n source &&\n typeof source.siteId === \"string\" &&\n source.siteId.trim() &&\n typeof source.recordId === \"string\" &&\n source.recordId.trim();\n if ((!v1 && !v2) ||\n typeof payload.type !== \"string\" ||\n !payload.type.trim() ||\n !payload.input ||\n typeof payload.input !== \"object\" ||\n Array.isArray(payload.input)\n ) {\n return json({ error: \"a supported version, source record, type, and input are required\" }, 400);\n }\n } else if (typeof payload.hubRecordId !== \"string\" || !payload.hubRecordId.trim()) {\n return json({ error: \"hubRecordId is required\" }, 400);\n } else if (payload.type !== \"company\" && typeof payload.email !== \"string\") {\n return json({ error: \"legacy person shares require email\" }, 400);\n } else if (payload.type === \"company\" && typeof payload.name !== \"string\") {\n return json({ error: \"business shares require name\" }, 400);\n }\n try {\n const { recordId } = await projectSharedRecord(\n { crm: ctx.chapter.crm, db: db as unknown as ChapterDb, now: () => Date.now(), newId: () => crypto.randomUUID() },\n payload as never,\n sourceId ? { sourceId } : {},\n );\n const record = normalizeSharedRecord(payload as never, sourceId);\n return json({ recordId, type: record.type });\n } catch (error) {\n return json({\n error: error instanceof Error ? error.message : \"invalid shared record\",\n }, 400);\n }\n};\n","import { verifyFederatedRequest } from \"@odla-ai/db\";\nimport { getVaultSecret } from \"./auth\";\nimport { signupControlDigest } from \"./signup-control-canonical\";\nimport {\n SIGNUP_CONTROL_PATH,\n type SignupControlEnvelope,\n type SignupControlRejection,\n} from \"./signup-control-contract\";\nimport { validateSignupControlDocument } from \"./signup-control-validate\";\nimport {\n loadLatestSignupControl,\n materializeSignupControl,\n validateControlledApplication,\n} from \"./signup-control-store\";\nimport { json } from \"./worker-context\";\nimport type { Route } from \"./worker-context\";\nimport type { ChapterDb } from \"./types\";\n\nconst reject = (reason: SignupControlRejection, status: number, errors?: readonly string[]) =>\n json({ ok: false, reason, ...(errors ? { errors } : {}) }, status);\n\n/** Dedicated signed receiver for complete signup configuration. */\nexport const handleSignupControl: Route = async (req, url, env, ctx) => {\n if (req.method !== \"POST\" || url.pathname !== SIGNUP_CONTROL_PATH) return null;\n const authority = ctx.chapter.signupControl;\n if (!authority) return json({ error: \"not found\" }, 404);\n const db = ctx.makeDb(env) as unknown as ChapterDb;\n const secret = await getVaultSecret(db, authority.secretName);\n if (!secret) return json({ error: \"unauthorized\" }, 401);\n const verified = await verifyFederatedRequest(req, { secret, senders: [authority.sourceId] });\n if (!verified.ok) return json({ error: \"unauthorized\", reason: verified.reason }, 401);\n let input: Record<string, unknown>;\n try {\n input = JSON.parse(verified.body) as Record<string, unknown>;\n } catch {\n return reject(\"invalid_document\", 400, [\"request body must be JSON\"]);\n }\n const digest = typeof input.digest === \"string\" ? input.digest : \"\";\n const checked = validateSignupControlDocument(input.document);\n if (!checked.ok) return reject(\"invalid_document\", 400, checked.errors);\n const document = checked.value;\n if (document.source.appId !== authority.sourceId) return reject(\"wrong_source\", 403);\n if (document.target.chapterId !== ctx.chapter.id) return reject(\"wrong_target\", 409);\n if (document.target.environment !== env.ODLA_ENV) return reject(\"wrong_environment\", 409);\n if (document.target.stripeMode !== authority.stripeMode) return reject(\"wrong_stripe_mode\", 409);\n const applicationErrors = validateControlledApplication(ctx.chapter, document);\n if (applicationErrors.length) return reject(\"invalid_document\", 400, applicationErrors);\n if (!digest || await signupControlDigest(document) !== digest) return reject(\"invalid_digest\", 400);\n const latest = await loadLatestSignupControl(db, ctx.chapter.id, env.ODLA_ENV);\n if (latest && document.revision < latest.revision) return reject(\"stale_revision\", 409);\n if (latest && document.revision === latest.revision) {\n if (latest.digest !== digest) return reject(\"conflicting_revision\", 409);\n return json({\n ok: true,\n target: { chapterId: ctx.chapter.id, environment: env.ODLA_ENV },\n revision: latest.revision,\n digest: latest.digest,\n status: \"replayed\",\n acknowledgedAt: latest.receivedAt,\n });\n }\n const receivedAt = Date.now();\n try {\n await materializeSignupControl(db, { digest, document } as SignupControlEnvelope, latest, receivedAt);\n } catch {\n return reject(\"materialization_failed\", 503);\n }\n return json({\n ok: true,\n target: { chapterId: ctx.chapter.id, environment: env.ODLA_ENV },\n revision: document.revision,\n digest,\n status: \"accepted\",\n acknowledgedAt: receivedAt,\n });\n};\n","import type { FieldConditions } from \"@odla-ai/crm\";\nimport type { MembershipPageDocument } from \"./membership-page\";\nimport type { ChapterScheduling } from \"./types\";\nimport type { GiftOfferCatalog } from \"./gift-offers\";\n\n/** Current wire-format version for complete signup-control documents. */\nexport const SIGNUP_CONTROL_SCHEMA_VERSION = 1 as const;\n/** Package-owned follower endpoint for signed signup-control delivery. */\nexport const SIGNUP_CONTROL_PATH = \"/api/signup-control\" as const;\n\n/** One authoritative membership tier in a signup-control revision. */\nexport interface SignupControlTier {\n id: string;\n name: string;\n available: boolean;\n sortOrder: number;\n priceCents: number;\n stripePriceId?: string;\n blurb?: string;\n}\n\n/** A bounded application contract. Fields must already exist in the follower schema. */\nexport interface SignupControlApplication {\n required: readonly string[];\n optional: readonly string[];\n conditions?: Readonly<Record<string, FieldConditions>>;\n copy?: Readonly<Record<string, string>>;\n}\n\n/** Delegated legal and trust copy used by the packaged join journey. */\nexport interface SignupControlPolicy {\n disclaimerText: string;\n refundPolicyText: string;\n trustCopy?: string;\n commitmentText?: string;\n normsText?: string;\n}\n\n/** Bounded semantic design tokens delegated to the chapter signup surface. */\nexport interface SignupControlTheme {\n /** Includes color, spacing, and typography tokens such as font families. */\n tokens: Readonly<Record<string, string | number>>;\n}\n\n/** Complete desired state delivered by a controlling hub. */\nexport interface SignupControlDocument {\n schemaVersion: typeof SIGNUP_CONTROL_SCHEMA_VERSION;\n revision: number;\n generatedAt: number;\n source: { appId: string };\n target: { chapterId: string; environment: string; stripeMode: \"test\" | \"live\" };\n tiers: readonly SignupControlTier[];\n membershipPage: MembershipPageDocument;\n application?: SignupControlApplication;\n policy?: SignupControlPolicy;\n scheduling?: ChapterScheduling;\n theme?: SignupControlTheme;\n giftOffers?: GiftOfferCatalog;\n}\n\n/** Digest travels beside the document so the exact desired state is attestable. */\nexport interface SignupControlEnvelope {\n digest: string;\n document: SignupControlDocument;\n}\n\n/** Exact follower acknowledgement for one accepted or replayed revision. */\nexport interface SignupControlReceipt {\n ok: true;\n target: { chapterId: string; environment: string };\n revision: number;\n digest: string;\n status: \"accepted\" | \"replayed\";\n acknowledgedAt: number;\n}\n\n/** Stable reason codes returned when a follower refuses desired state. */\nexport type SignupControlRejection =\n | \"invalid_document\"\n | \"invalid_digest\"\n | \"wrong_source\"\n | \"wrong_target\"\n | \"wrong_environment\"\n | \"wrong_stripe_mode\"\n | \"stale_revision\"\n | \"conflicting_revision\"\n | \"materialization_failed\";\n\n/** Normalized document result returned by the package validator. */\nexport type SignupControlValidation =\n | { ok: true; value: SignupControlDocument }\n | { ok: false; errors: readonly string[] };\n","/** The first stable, shared Chapter membership-page renderer contract. */\nexport const MEMBERSHIP_PAGE_RENDERER = \"membership-cards-v1\" as const;\n\n/** Fixed visual emphasis choices supported by the versioned card renderer. */\nexport type MembershipTierVariant = \"standard\" | \"featured\" | \"supporting\";\n\n/** A bounded, token-rendered aside within one membership card. */\nexport interface MembershipTierCallout {\n label?: string;\n bodyMarkdown: string;\n}\n\n/** Scarcity copy displayed without changing tier availability or checkout. */\nexport interface MembershipTierCapacity {\n total: number;\n label?: string;\n}\n\n/**\n * Presentation attached to one server-authoritative membership tier.\n *\n * Price, free/paid state, identity, and application targeting deliberately do\n * not live here. They are resolved from the public Chapter join config so\n * authored marketing copy can never change what checkout charges.\n */\nexport interface MembershipTierPresentation {\n tierId: string;\n variant?: MembershipTierVariant;\n badge?: string;\n summaryMarkdown?: string;\n priceEyebrow?: string;\n compareAtPriceCents?: number;\n billingLabel?: string;\n priceNoteMarkdown?: string;\n capacity?: MembershipTierCapacity;\n benefits?: readonly string[];\n callout?: MembershipTierCallout;\n ctaLabel?: string;\n}\n\n/** A bounded document that can be reviewed once and rendered by any Chapter host. */\nexport interface MembershipPageDocument {\n schemaVersion: 1;\n renderer: typeof MEMBERSHIP_PAGE_RENDERER;\n tiers: readonly MembershipTierPresentation[];\n footnoteMarkdown?: string;\n}\n\n/** Minimal server-authoritative tier identity and charged amount used during validation. */\nexport interface MembershipTierAuthority {\n id: string;\n priceCents: number;\n}\n\n/** Live tier authority used to reject missing, unknown, or misleading presentation. */\nexport interface MembershipPageValidationOptions {\n /** When supplied, every live tier must occur exactly once in the document. */\n tiers?: readonly MembershipTierAuthority[];\n}\n\n/** A normalized document or the complete actionable list of validation failures. */\nexport type MembershipPageValidationResult =\n | { ok: true; value: MembershipPageDocument }\n | { ok: false; errors: readonly string[] };\n\nconst TIER_ID = /^[a-z][a-z0-9-]{0,79}$/;\nconst VARIANTS = new Set<MembershipTierVariant>([\"standard\", \"featured\", \"supporting\"]);\nconst ROOT_KEYS = new Set([\"schemaVersion\", \"renderer\", \"tiers\", \"footnoteMarkdown\"]);\nconst TIER_KEYS = new Set([\n \"tierId\", \"variant\", \"badge\", \"summaryMarkdown\", \"priceEyebrow\",\n \"compareAtPriceCents\", \"billingLabel\", \"priceNoteMarkdown\", \"capacity\",\n \"benefits\", \"callout\", \"ctaLabel\",\n]);\nconst CALLOUT_KEYS = new Set([\"label\", \"bodyMarkdown\"]);\nconst CAPACITY_KEYS = new Set([\"total\", \"label\"]);\nconst MAX_TIERS = 20;\nconst MAX_BENEFITS = 24;\nconst MAX_MARKDOWN = 65_536;\nconst MAX_LABEL = 160;\n\nconst objectRecord = (value: unknown): Record<string, unknown> | null =>\n value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? value as Record<string, unknown>\n : null;\n\nfunction rejectUnknownKeys(\n value: Record<string, unknown>,\n allowed: ReadonlySet<string>,\n path: string,\n errors: string[],\n): void {\n for (const key of Object.keys(value)) {\n if (!allowed.has(key)) errors.push(`${path}.${key} is not supported`);\n }\n}\n\nfunction boundedString(\n value: unknown,\n path: string,\n errors: string[],\n max: number,\n required = false,\n): string | undefined {\n if (value === undefined) {\n if (required) errors.push(`${path} is required`);\n return undefined;\n }\n if (typeof value !== \"string\") {\n errors.push(`${path} must be a string`);\n return undefined;\n }\n const text = value.trim();\n if (required && !text) errors.push(`${path} is required`);\n if (text.length > max) errors.push(`${path} must be at most ${max.toLocaleString(\"en-US\")} characters`);\n return text;\n}\n\n/**\n * Validate and normalize a membership-page document without evaluating code,\n * accepting HTML, or allowing authored links/styles. Markdown slots are later\n * rendered by @odla-ai/ui's bounded safe Markdown component.\n */\nexport function validateMembershipPageDocument(\n input: unknown,\n options: MembershipPageValidationOptions = {},\n): MembershipPageValidationResult {\n const errors: string[] = [];\n const root = objectRecord(input);\n if (!root) return { ok: false, errors: [\"document must be an object\"] };\n rejectUnknownKeys(root, ROOT_KEYS, \"document\", errors);\n if (root.schemaVersion !== 1) errors.push(\"document.schemaVersion must be 1\");\n if (root.renderer !== MEMBERSHIP_PAGE_RENDERER) {\n errors.push(`document.renderer must be \\\"${MEMBERSHIP_PAGE_RENDERER}\\\"`);\n }\n if (!Array.isArray(root.tiers)) errors.push(\"document.tiers must be an array\");\n const rawTiers = Array.isArray(root.tiers) ? root.tiers : [];\n if (Array.isArray(root.tiers) && rawTiers.length === 0) errors.push(\"document.tiers must include at least one tier\");\n if (rawTiers.length > MAX_TIERS) errors.push(`document.tiers supports at most ${MAX_TIERS} entries`);\n\n const authority = new Map((options.tiers ?? []).map((tier) => [tier.id, tier]));\n const seen = new Set<string>();\n const tiers: MembershipTierPresentation[] = [];\n for (const [index, raw] of rawTiers.slice(0, MAX_TIERS).entries()) {\n const path = `document.tiers[${index}]`;\n const item = objectRecord(raw);\n if (!item) {\n errors.push(`${path} must be an object`);\n continue;\n }\n rejectUnknownKeys(item, TIER_KEYS, path, errors);\n const tierId = boundedString(item.tierId, `${path}.tierId`, errors, 80, true) ?? \"\";\n if (tierId && !TIER_ID.test(tierId)) errors.push(`${path}.tierId must be a lowercase kebab-case id`);\n if (seen.has(tierId)) errors.push(`${path}.tierId duplicates \\\"${tierId}\\\"`);\n seen.add(tierId);\n if (authority.size && !authority.has(tierId)) errors.push(`${path}.tierId \\\"${tierId}\\\" is not an offered tier`);\n\n const variant = item.variant;\n if (variant !== undefined && (typeof variant !== \"string\" || !VARIANTS.has(variant as MembershipTierVariant))) {\n errors.push(`${path}.variant must be standard, featured, or supporting`);\n }\n const compareAt = item.compareAtPriceCents;\n if (compareAt !== undefined && (!Number.isInteger(compareAt) || Number(compareAt) < 0 || Number(compareAt) > 100_000_000)) {\n errors.push(`${path}.compareAtPriceCents must be an integer from 0 to 100,000,000`);\n }\n const actual = authority.get(tierId)?.priceCents;\n if (Number.isInteger(compareAt) && actual !== undefined && Number(compareAt) <= actual) {\n errors.push(`${path}.compareAtPriceCents must be greater than the authoritative tier price`);\n }\n\n let benefits: string[] | undefined;\n if (item.benefits !== undefined) {\n if (!Array.isArray(item.benefits)) errors.push(`${path}.benefits must be an array`);\n else {\n if (item.benefits.length > MAX_BENEFITS) errors.push(`${path}.benefits supports at most ${MAX_BENEFITS} entries`);\n benefits = item.benefits.slice(0, MAX_BENEFITS).flatMap((benefit, benefitIndex) => {\n const text = boundedString(benefit, `${path}.benefits[${benefitIndex}]`, errors, 2_000, true);\n return text ? [text] : [];\n });\n }\n }\n\n let callout: MembershipTierCallout | undefined;\n if (item.callout !== undefined) {\n const rawCallout = objectRecord(item.callout);\n if (!rawCallout) errors.push(`${path}.callout must be an object`);\n else {\n rejectUnknownKeys(rawCallout, CALLOUT_KEYS, `${path}.callout`, errors);\n const bodyMarkdown = boundedString(rawCallout.bodyMarkdown, `${path}.callout.bodyMarkdown`, errors, MAX_MARKDOWN, true);\n const label = boundedString(rawCallout.label, `${path}.callout.label`, errors, MAX_LABEL);\n if (bodyMarkdown) callout = { ...(label ? { label } : {}), bodyMarkdown };\n }\n }\n\n let capacity: MembershipTierCapacity | undefined;\n if (item.capacity !== undefined) {\n const rawCapacity = objectRecord(item.capacity);\n if (!rawCapacity) errors.push(`${path}.capacity must be an object`);\n else {\n rejectUnknownKeys(rawCapacity, CAPACITY_KEYS, `${path}.capacity`, errors);\n const total = rawCapacity.total;\n if (!Number.isInteger(total) || Number(total) < 1 || Number(total) > 1_000_000) {\n errors.push(`${path}.capacity.total must be an integer from 1 to 1,000,000`);\n }\n const label = boundedString(rawCapacity.label, `${path}.capacity.label`, errors, MAX_LABEL);\n if (Number.isInteger(total) && Number(total) >= 1 && Number(total) <= 1_000_000) {\n capacity = { total: Number(total), ...(label ? { label } : {}) };\n }\n }\n }\n\n const badge = boundedString(item.badge, `${path}.badge`, errors, MAX_LABEL);\n const summaryMarkdown = boundedString(item.summaryMarkdown, `${path}.summaryMarkdown`, errors, MAX_MARKDOWN);\n const priceEyebrow = boundedString(item.priceEyebrow, `${path}.priceEyebrow`, errors, MAX_LABEL);\n const billingLabel = boundedString(item.billingLabel, `${path}.billingLabel`, errors, MAX_LABEL);\n const priceNoteMarkdown = boundedString(item.priceNoteMarkdown, `${path}.priceNoteMarkdown`, errors, MAX_MARKDOWN);\n const ctaLabel = boundedString(item.ctaLabel, `${path}.ctaLabel`, errors, MAX_LABEL);\n tiers.push({\n tierId,\n ...(typeof variant === \"string\" && VARIANTS.has(variant as MembershipTierVariant) ? { variant: variant as MembershipTierVariant } : {}),\n ...(badge ? { badge } : {}),\n ...(summaryMarkdown ? { summaryMarkdown } : {}),\n ...(priceEyebrow ? { priceEyebrow } : {}),\n ...(Number.isInteger(compareAt) ? { compareAtPriceCents: Number(compareAt) } : {}),\n ...(billingLabel ? { billingLabel } : {}),\n ...(priceNoteMarkdown ? { priceNoteMarkdown } : {}),\n ...(capacity ? { capacity } : {}),\n ...(benefits ? { benefits } : {}),\n ...(callout ? { callout } : {}),\n ...(ctaLabel ? { ctaLabel } : {}),\n });\n }\n if (authority.size) {\n for (const tierId of authority.keys()) {\n if (!seen.has(tierId)) errors.push(`document.tiers is missing offered tier \\\"${tierId}\\\"`);\n }\n }\n const footnoteMarkdown = boundedString(root.footnoteMarkdown, \"document.footnoteMarkdown\", errors, MAX_MARKDOWN);\n if (errors.length) return { ok: false, errors };\n return {\n ok: true,\n value: {\n schemaVersion: 1,\n renderer: MEMBERSHIP_PAGE_RENDERER,\n tiers,\n ...(footnoteMarkdown ? { footnoteMarkdown } : {}),\n },\n };\n}\n\n/** Validate a document or fail closed with all actionable validation errors. */\nexport function membershipPageDocument(\n input: unknown,\n options: MembershipPageValidationOptions = {},\n): MembershipPageDocument {\n const result = validateMembershipPageDocument(input, options);\n if (!result.ok) throw new TypeError(`Invalid membership page document: ${result.errors.join(\"; \")}`);\n return result.value;\n}\n","import { resolveApplication } from \"./member\";\nimport { validateMembershipPageDocument } from \"./membership-page\";\nimport { validateScheduling } from \"./scheduling\";\nimport { validateGiftOfferCatalog } from \"./gift-offers\";\nimport type {\n SignupControlApplication,\n SignupControlDocument,\n SignupControlPolicy,\n SignupControlTheme,\n SignupControlTier,\n SignupControlValidation,\n} from \"./signup-control-contract\";\n\nconst SLUG = /^[a-z0-9][a-z0-9-]{1,62}$/;\nconst ENVIRONMENT = /^[a-z][a-z0-9_-]{0,62}$/;\nconst TIER = /^[a-z][a-z0-9-]{0,79}$/;\nconst PRICE = /^price_[A-Za-z0-9]{12,}$/;\nconst ROOT_KEYS = new Set([\n \"schemaVersion\", \"revision\", \"generatedAt\", \"source\", \"target\", \"tiers\",\n \"membershipPage\", \"application\", \"policy\", \"scheduling\", \"theme\", \"giftOffers\",\n]);\nconst TIER_KEYS = new Set([\"id\", \"name\", \"available\", \"sortOrder\", \"priceCents\", \"stripePriceId\", \"blurb\"]);\n\nconst recordOf = (value: unknown): Record<string, unknown> | null =>\n value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? value as Record<string, unknown>\n : null;\n\nfunction unknownKeys(value: Record<string, unknown>, allowed: ReadonlySet<string>, path: string, errors: string[]): void {\n for (const key of Object.keys(value)) if (!allowed.has(key)) errors.push(`${path}.${key} is not supported`);\n}\n\nfunction text(value: unknown, path: string, errors: string[], max = 65_536): string {\n if (typeof value !== \"string\" || !value.trim()) {\n errors.push(`${path} is required`);\n return \"\";\n }\n if (value.length > max) errors.push(`${path} must be at most ${max} characters`);\n return value.trim();\n}\n\nfunction tiersOf(value: unknown, errors: string[]): SignupControlTier[] {\n if (!Array.isArray(value) || !value.length) {\n errors.push(\"document.tiers must be a non-empty array\");\n return [];\n }\n if (value.length > 20) errors.push(\"document.tiers supports at most 20 entries\");\n const seen = new Set<string>();\n return value.slice(0, 20).flatMap((raw, index) => {\n const path = `document.tiers[${index}]`;\n const item = recordOf(raw);\n if (!item) {\n errors.push(`${path} must be an object`);\n return [];\n }\n unknownKeys(item, TIER_KEYS, path, errors);\n const id = text(item.id, `${path}.id`, errors, 80);\n if (id && !TIER.test(id)) errors.push(`${path}.id must be a lowercase kebab-case id`);\n if (seen.has(id)) errors.push(`${path}.id duplicates \"${id}\"`);\n seen.add(id);\n const name = text(item.name, `${path}.name`, errors, 160);\n if (typeof item.available !== \"boolean\") errors.push(`${path}.available must be boolean`);\n if (!Number.isInteger(item.sortOrder) || Number(item.sortOrder) < 0) errors.push(`${path}.sortOrder must be a non-negative integer`);\n if (!Number.isInteger(item.priceCents) || Number(item.priceCents) < 0 || Number(item.priceCents) > 100_000_000) {\n errors.push(`${path}.priceCents must be an integer from 0 to 100,000,000`);\n }\n if (item.stripePriceId !== undefined && (typeof item.stripePriceId !== \"string\" || !PRICE.test(item.stripePriceId))) {\n errors.push(`${path}.stripePriceId must be a real Stripe Price id`);\n }\n if (item.available === true && Number(item.priceCents) > 0 && !item.stripePriceId) {\n errors.push(`${path}.stripePriceId is required for an available paid tier`);\n }\n const blurb = item.blurb === undefined ? undefined : text(item.blurb, `${path}.blurb`, errors, 4_000);\n return [{\n id, name, available: item.available === true,\n sortOrder: Number(item.sortOrder) || 0,\n priceCents: Number(item.priceCents) || 0,\n ...(typeof item.stripePriceId === \"string\" ? { stripePriceId: item.stripePriceId } : {}),\n ...(blurb ? { blurb } : {}),\n }];\n });\n}\n\nfunction applicationOf(value: unknown, errors: string[]): SignupControlApplication | undefined {\n if (value === undefined) return undefined;\n const input = recordOf(value);\n if (!input) {\n errors.push(\"document.application must be an object\");\n return undefined;\n }\n unknownKeys(input, new Set([\"required\", \"optional\", \"conditions\", \"copy\"]), \"document.application\", errors);\n try {\n const resolved = resolveApplication(input);\n const copy = recordOf(input.copy);\n if (input.copy !== undefined && (!copy || Object.values(copy).some((item) => typeof item !== \"string\"))) {\n errors.push(\"document.application.copy must contain only string values\");\n }\n return {\n required: resolved.required,\n optional: resolved.optional,\n ...(Object.keys(resolved.conditions).length ? { conditions: resolved.conditions } : {}),\n ...(copy ? { copy: copy as Record<string, string> } : {}),\n };\n } catch (error) {\n errors.push(error instanceof Error ? error.message : \"document.application is invalid\");\n return undefined;\n }\n}\n\nfunction policyOf(value: unknown, errors: string[]): SignupControlPolicy | undefined {\n if (value === undefined) return undefined;\n const input = recordOf(value);\n if (!input) {\n errors.push(\"document.policy must be an object\");\n return undefined;\n }\n const allowed = new Set([\"disclaimerText\", \"refundPolicyText\", \"trustCopy\", \"commitmentText\", \"normsText\"]);\n unknownKeys(input, allowed, \"document.policy\", errors);\n const result = {} as Record<string, string>;\n for (const key of allowed) {\n if (input[key] === undefined && key !== \"disclaimerText\" && key !== \"refundPolicyText\") continue;\n result[key] = text(input[key], `document.policy.${key}`, errors);\n }\n return result as unknown as SignupControlPolicy;\n}\n\nfunction themeOf(value: unknown, errors: string[]): SignupControlTheme | undefined {\n if (value === undefined) return undefined;\n const input = recordOf(value);\n const tokens = recordOf(input?.tokens);\n if (!input || !tokens) {\n errors.push(\"document.theme.tokens must be an object\");\n return undefined;\n }\n unknownKeys(input, new Set([\"tokens\"]), \"document.theme\", errors);\n if (Object.keys(tokens).length > 256) errors.push(\"document.theme.tokens supports at most 256 entries\");\n let serializedLength = 0;\n for (const [key, token] of Object.entries(tokens)) {\n if (!/^--ui-[a-z0-9][a-z0-9-]{0,94}$/.test(key)) {\n errors.push(`document.theme.tokens.${key} must be an allowlisted --ui-* custom property`);\n }\n const rendered = String(token).trim();\n serializedLength += key.length + rendered.length + 4;\n if ((typeof token !== \"string\" && typeof token !== \"number\") ||\n (typeof token === \"number\" && !Number.isFinite(token)) ||\n !rendered || rendered.length > 1_000 ||\n /[\\u0000-\\u001f\\u007f\\\\<>{};]|\\/\\*|\\*\\/|(?:^|[^a-z])(?:url|expression)\\s*\\(|@import/i.test(rendered)) {\n errors.push(`document.theme.tokens.${key} must be a bounded breakout-safe CSS value`);\n }\n }\n if (serializedLength > 65_536) errors.push(\"document.theme.tokens exceeds the serialized size bound\");\n return { tokens: tokens as Record<string, string | number> };\n}\n\n/** Validate and normalize one complete desired signup state. */\nexport function validateSignupControlDocument(input: unknown): SignupControlValidation {\n const errors: string[] = [];\n const root = recordOf(input);\n if (!root) return { ok: false, errors: [\"document must be an object\"] };\n unknownKeys(root, ROOT_KEYS, \"document\", errors);\n if (root.schemaVersion !== 1) errors.push(\"document.schemaVersion must be 1\");\n if (!Number.isSafeInteger(root.revision) || Number(root.revision) < 1) errors.push(\"document.revision must be a positive integer\");\n if (!Number.isSafeInteger(root.generatedAt) || Number(root.generatedAt) < 1) errors.push(\"document.generatedAt must be epoch milliseconds\");\n const source = recordOf(root.source);\n const target = recordOf(root.target);\n const appId = text(source?.appId, \"document.source.appId\", errors, 63);\n const chapterId = text(target?.chapterId, \"document.target.chapterId\", errors, 63);\n const environment = text(target?.environment, \"document.target.environment\", errors, 63);\n if (appId && !SLUG.test(appId)) errors.push(\"document.source.appId must be a lowercase app slug\");\n if (chapterId && !SLUG.test(chapterId)) errors.push(\"document.target.chapterId must be a lowercase app slug\");\n if (environment && !ENVIRONMENT.test(environment)) errors.push(\"document.target.environment is invalid\");\n if (target?.stripeMode !== \"test\" && target?.stripeMode !== \"live\") errors.push(\"document.target.stripeMode must be test or live\");\n const tiers = tiersOf(root.tiers, errors);\n const available = tiers.filter((tier) => tier.available).sort((a, b) => a.sortOrder - b.sortOrder);\n const page = validateMembershipPageDocument(root.membershipPage, { tiers: available });\n if (!page.ok) errors.push(...page.errors);\n else if (page.value.tiers.some((tier, index) => tier.tierId !== available[index]?.id)) {\n errors.push(\"document.membershipPage.tiers must follow the available tier display order\");\n }\n const application = applicationOf(root.application, errors);\n const policy = policyOf(root.policy, errors);\n let scheduling;\n if (root.scheduling !== undefined) {\n const checked = validateScheduling(root.scheduling as never);\n if (!checked.ok) errors.push(...Object.entries(checked.errors).map(([key, value]) => `document.scheduling.${key}: ${value}`));\n else scheduling = root.scheduling;\n }\n const theme = themeOf(root.theme, errors);\n const giftOffers = root.giftOffers === undefined\n ? undefined\n : validateGiftOfferCatalog(root.giftOffers, new Set(tiers.map((tier) => tier.id)));\n if (giftOffers && !giftOffers.ok) errors.push(...giftOffers.errors);\n if (errors.length || !page.ok) return { ok: false, errors };\n return { ok: true, value: {\n schemaVersion: 1,\n revision: Number(root.revision),\n generatedAt: Number(root.generatedAt),\n source: { appId },\n target: { chapterId, environment, stripeMode: target?.stripeMode as \"test\" | \"live\" },\n tiers,\n membershipPage: page.value,\n ...(application ? { application } : {}),\n ...(policy ? { policy } : {}),\n ...(scheduling ? { scheduling } : {}),\n ...(theme ? { theme } : {}),\n ...(giftOffers?.ok ? { giftOffers: giftOffers.value } : {}),\n } };\n}\n","import { verifyFederatedRequest } from \"@odla-ai/db\";\nimport { getVaultSecret } from \"./auth\";\nimport { normalizeAdmissionEmail } from \"./admission-grants\";\nimport { memberContentDigest } from \"./member-content-canonical\";\nimport {\n MEMBER_CONTENT_CONTROL_PATH,\n MEMBER_CONTENT_PATH,\n composeMemberContent,\n projectMemberContent,\n validateMemberContentDocument,\n type MemberContentDocument,\n type MemberContentEnvelope,\n type MemberContentRejection,\n} from \"./member-content\";\nimport {\n loadActiveMemberContentControl,\n loadLatestMemberContentControl,\n loadLocalMemberContent,\n materializeMemberContentControl,\n saveLocalMemberContent,\n} from \"./member-content-store\";\nimport { loadOfferableTiers, loadTiers } from \"./tiers-store\";\nimport { json } from \"./worker-context\";\nimport type { Route } from \"./worker-context\";\nimport type { ChapterDb } from \"./types\";\n\nconst ADMIN_PATH = \"/api/admin/member-content\";\nconst BODY_CAP = 1_000_000;\n\nconst reject = (reason: MemberContentRejection, status: number, errors?: readonly string[]) =>\n json({ ok: false, reason, ...(errors ? { errors } : {}) }, status);\n\nasync function groupAndTiers(db: ChapterDb, chapterId: string) {\n const groups = (await db.query({ groups: { $: { where: { id: chapterId }, limit: 1 } } })).groups;\n const group = Array.isArray(groups) ? groups[0] : undefined;\n if (!group) return { group: null, tiers: [] };\n return { group, tiers: await loadTiers(db, group as never) };\n}\n\nasync function memberTierId(db: ChapterDb, chapterId: string, email: string | undefined): Promise<string | null> {\n if (!email) return null;\n let rows = (await db.query({ applications: { $: {\n where: { emailNormalized: normalizeAdmissionEmail(email) }, limit: 20,\n } } })).applications;\n if (!rows?.length) rows = (await db.query({ applications: { $: { where: { email }, limit: 20 } } })).applications;\n const latest = Array.isArray(rows)\n ? [...rows]\n .filter((row) => String(row.groupId ?? chapterId) === chapterId)\n .sort((a, b) => Number(b.createdAt ?? 0) - Number(a.createdAt ?? 0))[0]\n : undefined;\n return typeof latest?.tierId === \"string\" && latest.tierId ? latest.tierId : null;\n}\n\nasync function activeDocuments(db: ChapterDb, chapterId: string, environment: string) {\n const [parent, chapter] = await Promise.all([\n loadActiveMemberContentControl(db, chapterId, environment),\n loadLocalMemberContent(db, chapterId, environment),\n ]);\n return { parent, chapter };\n}\n\n/** Signed, replay-safe receiver for inherited Parent member content. */\nexport const handleMemberContentControl: Route = async (req, url, env, ctx) => {\n if (req.method !== \"POST\" || url.pathname !== MEMBER_CONTENT_CONTROL_PATH) return null;\n const settings = ctx.chapter.memberContent?.parent;\n if (!settings) return json({ error: \"not found\" }, 404);\n const db = ctx.makeDb(env) as unknown as ChapterDb;\n const secret = await getVaultSecret(db, settings.secretName);\n if (!secret) return json({ error: \"unauthorized\" }, 401);\n const verified = await verifyFederatedRequest(req, { secret, senders: [settings.sourceId] });\n if (!verified.ok) return json({ error: \"unauthorized\", reason: verified.reason }, 401);\n let input: Record<string, unknown>;\n try {\n input = JSON.parse(verified.body) as Record<string, unknown>;\n } catch {\n return reject(\"invalid_document\", 400, [\"request body must be JSON\"]);\n }\n const digest = typeof input.digest === \"string\" ? input.digest : \"\";\n const initial = validateMemberContentDocument(input.document, {\n sourceType: \"parent\",\n });\n if (!initial.ok) return reject(\"invalid_document\", 400, initial.errors);\n const document = initial.value;\n if (document.source.appId !== settings.sourceId) return reject(\"wrong_source\", 403);\n if (document.target?.chapterId !== ctx.chapter.id) return reject(\"wrong_target\", 409);\n if (document.target.environment !== env.ODLA_ENV) return reject(\"wrong_environment\", 409);\n const { tiers } = await groupAndTiers(db, ctx.chapter.id);\n const checked = validateMemberContentDocument(document, {\n sourceType: \"parent\",\n sourceAppId: settings.sourceId,\n tiers,\n });\n if (!checked.ok) return reject(\"invalid_document\", 400, checked.errors);\n const local = await loadLocalMemberContent(db, ctx.chapter.id, env.ODLA_ENV);\n if (local) {\n const localCheck = validateMemberContentDocument(local.document, {\n sourceType: \"chapter\",\n sourceAppId: ctx.chapter.id,\n tiers,\n parentPages: document.pages,\n });\n if (!localCheck.ok) {\n return reject(\"invalid_document\", 409, localCheck.errors.map((error) => `existing chapter content: ${error}`));\n }\n }\n if (!digest || await memberContentDigest(document) !== digest) return reject(\"invalid_digest\", 400);\n const latest = await loadLatestMemberContentControl(db, ctx.chapter.id, env.ODLA_ENV);\n if (latest && document.revision < latest.revision) return reject(\"stale_revision\", 409);\n if (latest && document.revision === latest.revision) {\n if (latest.digest !== digest) return reject(\"conflicting_revision\", 409);\n return json({\n ok: true,\n target: document.target,\n revision: latest.revision,\n digest: latest.digest,\n status: \"replayed\",\n acknowledgedAt: latest.receivedAt,\n });\n }\n const receivedAt = Date.now();\n try {\n await materializeMemberContentControl(db, { digest, document } as MemberContentEnvelope, latest, receivedAt);\n } catch {\n return reject(\"materialization_failed\", 503);\n }\n return json({\n ok: true,\n target: document.target,\n revision: document.revision,\n digest,\n status: \"accepted\",\n acknowledgedAt: receivedAt,\n });\n};\n\n/** Authenticated, server-filtered member catalog. */\nexport const handleMemberContent: Route = async (req, url, env, ctx) => {\n if (req.method !== \"GET\" || url.pathname !== MEMBER_CONTENT_PATH) return null;\n if (!ctx.chapter.memberContent) return json({ error: \"not found\" }, 404);\n const user = await ctx.verifyUser(req, env);\n if (!user) return json({ error: \"unauthorized\" }, 401);\n const db = ctx.makeDb(env) as unknown as ChapterDb;\n const role = await ctx.roleFor(db as never, user);\n const admin = await ctx.isAdmin(db as never, user);\n const roleIndex = ctx.chapter.auth.ladder.indexOf(role);\n const memberIndex = Math.max(0, ctx.chapter.auth.ladder.length - 2);\n if (!admin && roleIndex < memberIndex) return json({ error: \"member access required\" }, 403);\n const [{ parent, chapter }, { group, tiers }, tierId] = await Promise.all([\n activeDocuments(db, ctx.chapter.id, env.ODLA_ENV),\n groupAndTiers(db, ctx.chapter.id),\n memberTierId(db, ctx.chapter.id, user.email),\n ]);\n const effective = composeMemberContent(parent?.document, chapter?.document);\n let offerable = tiers;\n if (group) {\n const stripeSecret = await getVaultSecret(db, \"stripe_secret_key\");\n offerable = await loadOfferableTiers(db, group as never, Boolean(stripeSecret));\n }\n return json(projectMemberContent(effective, { tierId, admin }, offerable));\n};\n\n/** Admin read/write surface. Parent pages remain read-only; only the local document is replaced. */\nexport const handleAdminMemberContent: Route = async (req, url, env, ctx) => {\n if (url.pathname !== ADMIN_PATH) return null;\n if (!ctx.chapter.memberContent) return json({ error: \"not found\" }, 404);\n const user = await ctx.verifyUser(req, env);\n if (!user) return json({ error: \"unauthorized\" }, 401);\n const db = ctx.makeDb(env) as unknown as ChapterDb;\n if (!await ctx.isAdmin(db as never, user)) return json({ error: \"forbidden\" }, 403);\n const [{ parent, chapter }, { tiers }] = await Promise.all([\n activeDocuments(db, ctx.chapter.id, env.ODLA_ENV),\n groupAndTiers(db, ctx.chapter.id),\n ]);\n if (req.method === \"GET\") {\n const effective = composeMemberContent(parent?.document, chapter?.document);\n return json({\n parent: parent ? { revision: parent.revision, digest: parent.digest, document: parent.document } : null,\n chapter: chapter ? { revision: chapter.revision, document: chapter.document } : null,\n effective,\n tiers: tiers.map(({ id, name, priceCents, active }) => ({ id, name, priceCents, active })),\n localAuthoring: ctx.chapter.memberContent.localAuthoring,\n });\n }\n if (req.method !== \"PUT\") return json({ error: \"method not allowed\" }, 405);\n if (!ctx.chapter.memberContent.localAuthoring) return json({ error: \"local authoring is disabled\" }, 403);\n const raw = await req.text();\n if (raw.length > BODY_CAP) return json({ error: \"request body too large\" }, 413);\n let input: Record<string, unknown>;\n try {\n input = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n const expectedRevision = Number(input.expectedRevision);\n if (!Number.isInteger(expectedRevision) || expectedRevision < 0) {\n return json({ error: \"expectedRevision must be a non-negative integer\" }, 400);\n }\n const now = Date.now();\n const documentInput = withLocalAuthority(input.document, expectedRevision + 1, now, ctx.chapter.id);\n const checked = validateMemberContentDocument(documentInput, {\n sourceType: \"chapter\",\n sourceAppId: ctx.chapter.id,\n tiers,\n parentPages: parent?.document.pages ?? [],\n });\n if (!checked.ok) return json({ error: \"invalid member content\", errors: checked.errors }, 400);\n try {\n const saved = await saveLocalMemberContent(\n db,\n checked.value,\n env.ODLA_ENV,\n expectedRevision,\n now,\n user.email ?? user.userId,\n );\n return json({ ok: true, revision: saved.revision, document: saved.document });\n } catch (error) {\n if (error instanceof Error && error.message === \"member_content_revision_conflict\") {\n return json({ error: \"member content changed; reload before saving\" }, 409);\n }\n return json({ error: \"member content could not be saved\" }, 503);\n }\n};\n\nfunction withLocalAuthority(value: unknown, revision: number, generatedAt: number, appId: string): unknown {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return value;\n return {\n ...(value as Record<string, unknown>),\n schemaVersion: 1,\n revision,\n generatedAt,\n source: { type: \"chapter\", appId },\n };\n}\n","const encoder = new TextEncoder();\n\nfunction canonicalValue(value: unknown): string {\n if (value === null || typeof value === \"boolean\" || typeof value === \"number\" || typeof value === \"string\") {\n return JSON.stringify(value);\n }\n if (Array.isArray(value)) return `[${value.map(canonicalValue).join(\",\")}]`;\n if (typeof value !== \"object\") throw new TypeError(\"member content contains an unsupported value\");\n const record = value as Record<string, unknown>;\n const entries = Object.keys(record).sort().flatMap((key) => {\n const item = record[key];\n return item === undefined ? [] : [`${JSON.stringify(key)}:${canonicalValue(item)}`];\n });\n return `{${entries.join(\",\")}}`;\n}\n\n/** Serialize JSON-like member content with recursively sorted object keys. */\nexport function canonicalMemberContent(value: unknown): string {\n return canonicalValue(value);\n}\n\n/** Compute the canonical SHA-256 digest for one Parent content revision. */\nexport async function memberContentDigest(document: unknown): Promise<string> {\n const digest = await crypto.subtle.digest(\"SHA-256\", encoder.encode(canonicalMemberContent(document)));\n return `sha256:${Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\")}`;\n}\n\n/** Pair one content document with the exact digest the follower acknowledges. */\nexport async function createMemberContentEnvelope(document: import(\"./member-content\").MemberContentDocument) {\n return { document, digest: await memberContentDigest(document) };\n}\n","import type { MemberPageAudience, MemberPageUpsellOffer } from \"./member-content\";\n\nexport const ID = /^[a-z][a-z0-9-]{0,79}$/;\nexport const SLUG = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\nexport const ROOT_KEYS = new Set([\"schemaVersion\", \"revision\", \"generatedAt\", \"source\", \"target\", \"pages\", \"upsellOverrides\"]);\nexport const SOURCE_KEYS = new Set([\"type\", \"appId\"]);\nexport const TARGET_KEYS = new Set([\"chapterId\", \"environment\"]);\nexport const PAGE_KEYS = new Set([\"id\", \"slug\", \"title\", \"summary\", \"navigation\", \"audience\", \"teaserMarkdown\", \"bodyMarkdown\", \"upsell\"]);\nexport const NAV_KEYS = new Set([\"section\", \"order\", \"parentId\"]);\nexport const AUDIENCE_KEYS = new Set([\"kind\", \"tierIds\"]);\nexport const UPSELL_KEYS = new Set([\"owner\", \"offer\"]);\nexport const OFFER_KEYS = new Set([\"tierId\", \"label\", \"bodyMarkdown\", \"ctaLabel\"]);\nexport const OVERRIDE_KEYS = new Set([\"pageId\", \"offer\"]);\nexport const MAX_PAGES = 100;\nexport const MAX_MARKDOWN = 65_536;\nexport const MAX_TEXT = 240;\n\nexport const record = (value: unknown): Record<string, unknown> | null =>\n value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? value as Record<string, unknown>\n : null;\n\nexport function unknownKeys(value: Record<string, unknown>, allowed: ReadonlySet<string>, path: string, errors: string[]): void {\n for (const key of Object.keys(value)) if (!allowed.has(key)) errors.push(`${path}.${key} is not supported`);\n}\n\nexport function textValue(value: unknown, path: string, errors: string[], max = MAX_TEXT, required = false): string | undefined {\n if (value === undefined) {\n if (required) errors.push(`${path} is required`);\n return undefined;\n }\n if (typeof value !== \"string\") {\n errors.push(`${path} must be a string`);\n return undefined;\n }\n const valueText = value.trim();\n if (required && !valueText) errors.push(`${path} is required`);\n if (valueText.length > max) errors.push(`${path} must be at most ${max.toLocaleString(\"en-US\")} characters`);\n return valueText;\n}\n\nexport function offerValue(\n value: unknown,\n path: string,\n errors: string[],\n tiers: ReadonlySet<string>,\n audience?: MemberPageAudience,\n): MemberPageUpsellOffer | undefined {\n const raw = record(value);\n if (!raw) {\n errors.push(`${path} must be an object`);\n return undefined;\n }\n unknownKeys(raw, OFFER_KEYS, path, errors);\n const tierId = textValue(raw.tierId, `${path}.tierId`, errors, 80, true) ?? \"\";\n if (tierId && !ID.test(tierId)) errors.push(`${path}.tierId must be a lowercase kebab-case id`);\n if (tiers.size && !tiers.has(tierId)) errors.push(`${path}.tierId must reference a declared tier`);\n if (audience?.kind === \"tiers\" && tierId && !audience.tierIds.includes(tierId)) {\n errors.push(`${path}.tierId must grant access to this page`);\n }\n const label = textValue(raw.label, `${path}.label`, errors);\n const bodyMarkdown = textValue(raw.bodyMarkdown, `${path}.bodyMarkdown`, errors, MAX_MARKDOWN);\n const ctaLabel = textValue(raw.ctaLabel, `${path}.ctaLabel`, errors);\n return {\n tierId,\n ...(label ? { label } : {}),\n ...(bodyMarkdown ? { bodyMarkdown } : {}),\n ...(ctaLabel ? { ctaLabel } : {}),\n };\n}\n","import {\n MEMBER_CONTENT_SCHEMA_VERSION,\n type MemberContentDocument,\n type MemberContentPage,\n type MemberContentSource,\n type MemberContentTarget,\n type MemberContentValidationOptions,\n type MemberContentValidationResult,\n type MemberPageAudience,\n type MemberPageNavigation,\n type MemberPageUpsell,\n type MemberPageUpsellOverride,\n} from \"./member-content\";\nimport {\n AUDIENCE_KEYS,\n ID,\n MAX_MARKDOWN,\n MAX_PAGES,\n MAX_TEXT,\n NAV_KEYS,\n OVERRIDE_KEYS,\n PAGE_KEYS,\n ROOT_KEYS,\n SLUG,\n SOURCE_KEYS,\n TARGET_KEYS,\n UPSELL_KEYS,\n offerValue,\n record,\n textValue,\n unknownKeys,\n} from \"./member-content-validation-helpers\";\n\n/** Validate one complete parent or chapter authoring layer with actionable paths. */\nexport function validateMemberContentDocument(\n input: unknown,\n options: MemberContentValidationOptions = {},\n): MemberContentValidationResult {\n const errors: string[] = [];\n const root = record(input);\n if (!root) return { ok: false, errors: [\"document must be an object\"] };\n unknownKeys(root, ROOT_KEYS, \"document\", errors);\n if (root.schemaVersion !== MEMBER_CONTENT_SCHEMA_VERSION) errors.push(\"document.schemaVersion must be 1\");\n if (!Number.isInteger(root.revision) || Number(root.revision) < 1) errors.push(\"document.revision must be a positive integer\");\n if (!Number.isInteger(root.generatedAt) || Number(root.generatedAt) < 0) errors.push(\"document.generatedAt must be a non-negative integer timestamp\");\n\n const sourceRaw = record(root.source);\n let source: MemberContentSource = { type: \"chapter\", appId: \"invalid\" };\n if (!sourceRaw) errors.push(\"document.source must be an object\");\n else {\n unknownKeys(sourceRaw, SOURCE_KEYS, \"document.source\", errors);\n const type = sourceRaw.type;\n const appId = textValue(sourceRaw.appId, \"document.source.appId\", errors, 63, true) ?? \"\";\n if (type !== \"parent\" && type !== \"chapter\") errors.push(\"document.source.type must be parent or chapter\");\n if (appId && !ID.test(appId)) errors.push(\"document.source.appId must be a lowercase app slug\");\n if (options.sourceType && type !== options.sourceType) errors.push(`document.source.type must be ${options.sourceType}`);\n if (options.sourceAppId && appId !== options.sourceAppId) errors.push(`document.source.appId must be ${options.sourceAppId}`);\n if (type === \"parent\" || type === \"chapter\") source = { type, appId };\n }\n\n let target: MemberContentTarget | undefined;\n if (root.target !== undefined) {\n const targetRaw = record(root.target);\n if (!targetRaw) errors.push(\"document.target must be an object\");\n else {\n unknownKeys(targetRaw, TARGET_KEYS, \"document.target\", errors);\n const chapterId = textValue(targetRaw.chapterId, \"document.target.chapterId\", errors, 63, true) ?? \"\";\n const environment = textValue(targetRaw.environment, \"document.target.environment\", errors, 80, true) ?? \"\";\n target = { chapterId, environment };\n }\n }\n if (source.type === \"parent\" && !target) errors.push(\"document.target is required for parent content\");\n if (source.type === \"chapter\" && target) errors.push(\"document.target is not supported for chapter content\");\n\n if (!Array.isArray(root.pages)) errors.push(\"document.pages must be an array\");\n const rawPages = Array.isArray(root.pages) ? root.pages : [];\n if (rawPages.length > MAX_PAGES) errors.push(`document.pages supports at most ${MAX_PAGES} entries`);\n const tierIds = new Set((options.tiers ?? []).map((tier) => tier.id));\n const knownParentIds = new Set((options.parentPages ?? []).map((page) => page.id));\n const ids = new Set<string>();\n const slugs = new Set<string>();\n const pages: MemberContentPage[] = [];\n for (const [index, value] of rawPages.slice(0, MAX_PAGES).entries()) {\n const path = `document.pages[${index}]`;\n const raw = record(value);\n if (!raw) {\n errors.push(`${path} must be an object`);\n continue;\n }\n unknownKeys(raw, PAGE_KEYS, path, errors);\n const id = textValue(raw.id, `${path}.id`, errors, 80, true) ?? \"\";\n const slug = textValue(raw.slug, `${path}.slug`, errors, 120, true) ?? \"\";\n const title = textValue(raw.title, `${path}.title`, errors, MAX_TEXT, true) ?? \"\";\n if (id && !ID.test(id)) errors.push(`${path}.id must be a lowercase kebab-case id`);\n if (slug && !SLUG.test(slug)) errors.push(`${path}.slug must be a lowercase URL slug`);\n if (ids.has(id) || knownParentIds.has(id)) errors.push(`${path}.id duplicates page \"${id}\"`);\n if (slugs.has(slug) || (options.parentPages ?? []).some((page) => page.slug === slug)) errors.push(`${path}.slug duplicates \"${slug}\"`);\n ids.add(id);\n slugs.add(slug);\n\n const navRaw = record(raw.navigation);\n let navigation: MemberPageNavigation = { section: \"General\", order: index };\n if (!navRaw) errors.push(`${path}.navigation must be an object`);\n else {\n unknownKeys(navRaw, NAV_KEYS, `${path}.navigation`, errors);\n const section = textValue(navRaw.section, `${path}.navigation.section`, errors, 120, true) ?? \"\";\n const order = navRaw.order;\n if (!Number.isInteger(order) || Number(order) < 0 || Number(order) > 1_000_000) {\n errors.push(`${path}.navigation.order must be an integer from 0 to 1,000,000`);\n }\n const parentId = textValue(navRaw.parentId, `${path}.navigation.parentId`, errors, 80);\n navigation = { section, order: Number.isInteger(order) ? Number(order) : index, ...(parentId ? { parentId } : {}) };\n }\n\n const audienceRaw = record(raw.audience);\n let audience: MemberPageAudience = { kind: \"all-members\" };\n if (!audienceRaw) errors.push(`${path}.audience must be an object`);\n else {\n unknownKeys(audienceRaw, AUDIENCE_KEYS, `${path}.audience`, errors);\n if (audienceRaw.kind === \"all-members\") {\n if (audienceRaw.tierIds !== undefined) errors.push(`${path}.audience.tierIds is not supported for all-members`);\n } else if (audienceRaw.kind === \"tiers\") {\n if (!Array.isArray(audienceRaw.tierIds) || audienceRaw.tierIds.length === 0) {\n errors.push(`${path}.audience.tierIds must be a non-empty array`);\n }\n const values = Array.isArray(audienceRaw.tierIds) ? audienceRaw.tierIds : [];\n const normalized: string[] = [];\n for (const [tierIndex, value] of values.entries()) {\n const tier = textValue(value, `${path}.audience.tierIds[${tierIndex}]`, errors, 80, true) ?? \"\";\n if (normalized.includes(tier)) errors.push(`${path}.audience.tierIds duplicates \"${tier}\"`);\n if (tierIds.size && !tierIds.has(tier)) errors.push(`${path}.audience.tierIds references undeclared tier \"${tier}\"`);\n normalized.push(tier);\n }\n audience = { kind: \"tiers\", tierIds: normalized };\n } else errors.push(`${path}.audience.kind must be all-members or tiers`);\n }\n\n const summary = textValue(raw.summary, `${path}.summary`, errors, 2_000);\n const teaserMarkdown = textValue(raw.teaserMarkdown, `${path}.teaserMarkdown`, errors, MAX_MARKDOWN);\n const bodyMarkdown = textValue(raw.bodyMarkdown, `${path}.bodyMarkdown`, errors, MAX_MARKDOWN, true) ?? \"\";\n let upsell: MemberPageUpsell | undefined;\n if (raw.upsell !== undefined) {\n const upsellRaw = record(raw.upsell);\n if (!upsellRaw) errors.push(`${path}.upsell must be an object`);\n else {\n unknownKeys(upsellRaw, UPSELL_KEYS, `${path}.upsell`, errors);\n const owner = upsellRaw.owner;\n if (owner !== \"parent\" && owner !== \"chapter\") errors.push(`${path}.upsell.owner must be parent or chapter`);\n if (source.type === \"chapter\" && owner === \"parent\") errors.push(`${path}.upsell.owner cannot be parent on a chapter page`);\n if (source.type === \"parent\" && owner === \"parent\" && upsellRaw.offer === undefined) errors.push(`${path}.upsell.offer is required when the parent owns the offer`);\n if (source.type === \"parent\" && owner === \"chapter\" && upsellRaw.offer !== undefined) errors.push(`${path}.upsell.offer must be set by the chapter after delegation`);\n const offer = upsellRaw.offer === undefined ? undefined : offerValue(upsellRaw.offer, `${path}.upsell.offer`, errors, tierIds, audience);\n if (owner === \"parent\") upsell = { owner, offer: offer ?? { tierId: \"\" } };\n else if (owner === \"chapter\") upsell = { owner, ...(offer ? { offer } : {}) };\n }\n }\n pages.push({ id, slug, title, ...(summary ? { summary } : {}), navigation, audience, ...(teaserMarkdown ? { teaserMarkdown } : {}), bodyMarkdown, ...(upsell ? { upsell } : {}) });\n }\n\n const allIds = new Set([...knownParentIds, ...ids]);\n for (const [index, page] of pages.entries()) {\n const parentId = page.navigation.parentId;\n if (parentId && !allIds.has(parentId)) errors.push(`document.pages[${index}].navigation.parentId references unknown page \"${parentId}\"`);\n if (parentId === page.id) errors.push(`document.pages[${index}].navigation.parentId cannot reference itself`);\n }\n for (const page of pages) {\n const seen = new Set([page.id]);\n let parentId = page.navigation.parentId;\n while (parentId) {\n if (seen.has(parentId)) {\n errors.push(`document.pages contains a navigation cycle at \"${page.id}\"`);\n break;\n }\n seen.add(parentId);\n parentId = pages.find((candidate) => candidate.id === parentId)?.navigation.parentId;\n }\n }\n\n let upsellOverrides: MemberPageUpsellOverride[] | undefined;\n if (root.upsellOverrides !== undefined) {\n if (source.type !== \"chapter\") errors.push(\"document.upsellOverrides is supported only for chapter content\");\n if (!Array.isArray(root.upsellOverrides)) errors.push(\"document.upsellOverrides must be an array\");\n const values = Array.isArray(root.upsellOverrides) ? root.upsellOverrides : [];\n const seen = new Set<string>();\n upsellOverrides = [];\n for (const [index, value] of values.entries()) {\n const path = `document.upsellOverrides[${index}]`;\n const raw = record(value);\n if (!raw) {\n errors.push(`${path} must be an object`);\n continue;\n }\n unknownKeys(raw, OVERRIDE_KEYS, path, errors);\n const pageId = textValue(raw.pageId, `${path}.pageId`, errors, 80, true) ?? \"\";\n if (seen.has(pageId)) errors.push(`${path}.pageId duplicates \"${pageId}\"`);\n seen.add(pageId);\n const parentPage = (options.parentPages ?? []).find((page) => page.id === pageId);\n if (!parentPage) errors.push(`${path}.pageId must reference a parent page`);\n else if (parentPage.upsell?.owner !== \"chapter\") errors.push(`${path}.pageId does not delegate upsell authority to the chapter`);\n const offer = offerValue(raw.offer, `${path}.offer`, errors, tierIds, parentPage?.audience);\n if (offer) upsellOverrides.push({ pageId, offer });\n }\n }\n if (errors.length) return { ok: false, errors };\n return { ok: true, value: {\n schemaVersion: MEMBER_CONTENT_SCHEMA_VERSION,\n revision: Number(root.revision),\n generatedAt: Number(root.generatedAt),\n source,\n ...(target ? { target } : {}),\n pages,\n ...(upsellOverrides ? { upsellOverrides } : {}),\n } };\n}\n\n/** Validate or fail closed with every actionable document error. */\nexport function memberContentDocument(input: unknown, options: MemberContentValidationOptions = {}): MemberContentDocument {\n const result = validateMemberContentDocument(input, options);\n if (!result.ok) throw new TypeError(`Invalid member content document: ${result.errors.join(\"; \")}`);\n return result.value;\n}\n","/** Versioned contract for authenticated member content. */\nexport const MEMBER_CONTENT_SCHEMA_VERSION = 1 as const;\n/** Authenticated member projection endpoint. */\nexport const MEMBER_CONTENT_PATH = \"/api/member-content\" as const;\n/** Dedicated signed Parent → Chapter content-delivery endpoint. */\nexport const MEMBER_CONTENT_CONTROL_PATH = \"/api/member-content-control\" as const;\n\n/** Authority that authored one independently stored member-content layer. */\nexport type MemberContentSourceType = \"parent\" | \"chapter\";\n/** Stable author identity attached to every member-content document and page. */\nexport interface MemberContentSource { type: MemberContentSourceType; appId: string }\n/** Chapter deployment that a parent member-content revision is intended for. */\nexport interface MemberContentTarget { chapterId: string; environment: string }\n\n/** Navigation is data, so agents do not have to coordinate route code. */\nexport interface MemberPageNavigation {\n section: string;\n order: number;\n parentId?: string;\n}\n\n/** Explicit sets avoid unsafe assumptions that commercial tiers form a ladder. */\nexport type MemberPageAudience =\n | { kind: \"all-members\" }\n | { kind: \"tiers\"; tierIds: readonly string[] };\n\n/** Authored offer copy. Price and provider identity deliberately do not live here. */\nexport interface MemberPageUpsellOffer {\n tierId: string;\n label?: string;\n bodyMarkdown?: string;\n ctaLabel?: string;\n}\n\n/** Parent offer authority is explicit; a Chapter can edit only a delegated offer. */\nexport type MemberPageUpsell =\n | { owner: \"parent\"; offer: MemberPageUpsellOffer }\n | { owner: \"chapter\"; offer?: MemberPageUpsellOffer };\n\n/** Authored member page whose body is disclosed only after server-side projection. */\nexport interface MemberContentPage {\n id: string;\n slug: string;\n title: string;\n summary?: string;\n navigation: MemberPageNavigation;\n audience: MemberPageAudience;\n /** Safe Markdown shown while the body is withheld. */\n teaserMarkdown?: string;\n /** Never serialized to a viewer whose audience does not match. */\n bodyMarkdown: string;\n upsell?: MemberPageUpsell;\n}\n\n/** Chapter-owned offer attached to a Parent page that delegated offer authority. */\nexport interface MemberPageUpsellOverride { pageId: string; offer: MemberPageUpsellOffer }\n\n/** One complete source layer. Parent and Chapter layers are stored independently. */\nexport interface MemberContentDocument {\n schemaVersion: typeof MEMBER_CONTENT_SCHEMA_VERSION;\n revision: number;\n generatedAt: number;\n source: MemberContentSource;\n target?: MemberContentTarget;\n pages: readonly MemberContentPage[];\n upsellOverrides?: readonly MemberPageUpsellOverride[];\n}\n\n/** Provider-neutral tier facts used to validate access and resolve safe offers. */\nexport interface MemberContentTierAuthority {\n id: string;\n name?: string;\n priceCents?: number;\n active?: boolean;\n}\n\n/** Local authority supplied while validating a member-content document. */\nexport interface MemberContentValidationOptions {\n sourceType?: MemberContentSourceType;\n sourceAppId?: string;\n tiers?: readonly MemberContentTierAuthority[];\n parentPages?: readonly MemberContentPage[];\n}\n\n/** Validated document or an actionable collection of contract errors. */\nexport type MemberContentValidationResult =\n | { ok: true; value: MemberContentDocument }\n | { ok: false; errors: readonly string[] };\n\n/** Composed member page retaining the identity of its authoring layer. */\nexport interface EffectiveMemberContentPage extends MemberContentPage { source: MemberContentSource }\n/** Deterministically ordered parent and chapter layers with their source revisions. */\nexport interface EffectiveMemberContent {\n pages: readonly EffectiveMemberContentPage[];\n parentRevision: number | null;\n chapterRevision: number | null;\n}\n/** Server-authoritative identity facts used for member-content disclosure. */\nexport interface MemberContentViewer { tierId: string | null; admin: boolean }\n/** Authored upsell joined to active chapter tier name and price authority. */\nexport interface ResolvedMemberPageUpsell extends MemberPageUpsellOffer { tierName: string; priceCents: number }\n\n/** Viewer-safe page result; locked projections never carry bodyMarkdown. */\nexport interface MemberContentPageProjection {\n id: string;\n slug: string;\n title: string;\n summary?: string;\n navigation: MemberPageNavigation;\n audience: MemberPageAudience;\n source: MemberContentSource;\n access: \"allowed\" | \"locked\";\n teaserMarkdown?: string;\n bodyMarkdown?: string;\n upsell?: ResolvedMemberPageUpsell;\n}\n\n/** Complete viewer-safe member navigation and revision projection. */\nexport interface MemberContentProjection {\n pages: readonly MemberContentPageProjection[];\n viewer: { tierId: string | null; admin: boolean };\n revisions: { parent: number | null; chapter: number | null };\n}\n\n/** Canonical parent document and digest transmitted over the signed control edge. */\nexport interface MemberContentEnvelope { digest: string; document: MemberContentDocument }\n/** Durable Chapter acknowledgement for an accepted or idempotently replayed revision. */\nexport interface MemberContentReceipt {\n ok: true;\n target: MemberContentTarget;\n revision: number;\n digest: string;\n status: \"accepted\" | \"replayed\";\n acknowledgedAt: number;\n}\n\n/** Stable rejection reasons returned by the signed member-content control endpoint. */\nexport type MemberContentRejection =\n | \"invalid_document\"\n | \"invalid_digest\"\n | \"wrong_source\"\n | \"wrong_target\"\n | \"wrong_environment\"\n | \"stale_revision\"\n | \"conflicting_revision\"\n | \"materialization_failed\";\n\nexport { memberContentDocument, validateMemberContentDocument } from \"./member-content-validation\";\n\nconst pageOrder = (a: EffectiveMemberContentPage, b: EffectiveMemberContentPage): number =>\n a.navigation.section.localeCompare(b.navigation.section)\n || a.navigation.order - b.navigation.order\n || a.title.localeCompare(b.title)\n || a.id.localeCompare(b.id);\n\n/** Compose immutable Parent content with independently stored Chapter content. */\nexport function composeMemberContent(\n parent: MemberContentDocument | null | undefined,\n chapter: MemberContentDocument | null | undefined,\n): EffectiveMemberContent {\n const pages: EffectiveMemberContentPage[] = [];\n const parentPages = new Map<string, EffectiveMemberContentPage>();\n for (const page of parent?.pages ?? []) {\n const effective = { ...page, source: parent!.source };\n parentPages.set(page.id, effective);\n pages.push(effective);\n }\n for (const override of chapter?.upsellOverrides ?? []) {\n const page = parentPages.get(override.pageId);\n if (page?.upsell?.owner === \"chapter\") page.upsell = { owner: \"chapter\", offer: override.offer };\n }\n for (const page of chapter?.pages ?? []) {\n if (parentPages.has(page.id) || pages.some((candidate) => candidate.slug === page.slug)) {\n throw new TypeError(`Chapter member page \"${page.id}\" conflicts with parent content`);\n }\n pages.push({ ...page, source: chapter!.source });\n }\n return {\n pages: pages.sort(pageOrder),\n parentRevision: parent?.revision ?? null,\n chapterRevision: chapter?.revision ?? null,\n };\n}\n\nconst allowed = (page: MemberContentPage, viewer: MemberContentViewer): boolean =>\n viewer.admin\n || page.audience.kind === \"all-members\"\n || (viewer.tierId !== null && page.audience.tierIds.includes(viewer.tierId));\n\n/** Restricted bodies are omitted and authored offers are joined to live tier authority. */\nexport function projectMemberContent(\n content: EffectiveMemberContent,\n viewer: MemberContentViewer,\n tiers: readonly MemberContentTierAuthority[],\n): MemberContentProjection {\n const authority = new Map(tiers.filter((tier) => tier.active !== false).map((tier) => [tier.id, tier]));\n return {\n viewer: { ...viewer },\n revisions: { parent: content.parentRevision, chapter: content.chapterRevision },\n pages: content.pages.map((page) => {\n const canRead = allowed(page, viewer);\n const offer = !canRead ? page.upsell?.offer : undefined;\n const tier = offer ? authority.get(offer.tierId) : undefined;\n const upsell = offer && tier && typeof tier.name === \"string\" && typeof tier.priceCents === \"number\"\n ? { ...offer, tierName: tier.name, priceCents: tier.priceCents }\n : undefined;\n return {\n id: page.id,\n slug: page.slug,\n title: page.title,\n ...(page.summary ? { summary: page.summary } : {}),\n navigation: page.navigation,\n audience: page.audience,\n source: page.source,\n access: canRead ? \"allowed\" as const : \"locked\" as const,\n ...(page.teaserMarkdown ? { teaserMarkdown: page.teaserMarkdown } : {}),\n ...(canRead ? { bodyMarkdown: page.bodyMarkdown } : {}),\n ...(upsell ? { upsell } : {}),\n };\n }),\n };\n}\n","import type { ChapterDb, DbOp } from \"./types\";\nimport type { MemberContentDocument, MemberContentEnvelope } from \"./member-content\";\n\nexport interface StoredMemberContentControl {\n id: string;\n sourceId: string;\n targetId: string;\n environment: string;\n revision: number;\n digest: string;\n document: MemberContentDocument;\n active: boolean;\n receivedAt: number;\n}\n\nexport interface StoredLocalMemberContent {\n id: string;\n chapterId: string;\n environment: string;\n revision: number;\n document: MemberContentDocument;\n updatedAt: number;\n updatedBy?: string;\n}\n\nconst control = (row: Record<string, unknown> | undefined): StoredMemberContentControl | null =>\n row && row.document && typeof row.document === \"object\" ? row as unknown as StoredMemberContentControl : null;\n\nconst local = (row: Record<string, unknown> | undefined): StoredLocalMemberContent | null =>\n row && row.document && typeof row.document === \"object\" ? row as unknown as StoredLocalMemberContent : null;\n\nasync function exists(db: ChapterDb, ns: string, where: Record<string, unknown>): Promise<boolean> {\n if (db.aggregate) return Number((await db.aggregate(ns, { count: true }, { where })).count ?? 0) > 0;\n const rows = (await db.query({ [ns]: {} }))[ns] ?? [];\n return rows.some((row) => Object.entries(where).every(([key, value]) => row[key] === value));\n}\n\nexport async function loadActiveMemberContentControl(\n db: ChapterDb,\n targetId: string,\n environment: string,\n): Promise<StoredMemberContentControl | null> {\n const where = { targetId, environment, active: true };\n if (!await exists(db, \"memberContentControls\", where)) return null;\n const rows = (await db.query({ memberContentControls: { $: {\n where,\n order: { revision: \"desc\" },\n limit: 1,\n } } })).memberContentControls;\n return control(Array.isArray(rows) ? [...rows].sort((a, b) => Number(b.revision) - Number(a.revision))[0] : undefined);\n}\n\nexport async function loadLatestMemberContentControl(\n db: ChapterDb,\n targetId: string,\n environment: string,\n): Promise<StoredMemberContentControl | null> {\n const where = { targetId, environment };\n if (!await exists(db, \"memberContentControls\", where)) return null;\n const rows = (await db.query({ memberContentControls: { $: {\n where,\n order: { revision: \"desc\" },\n limit: 1,\n } } })).memberContentControls;\n return control(Array.isArray(rows) ? [...rows].sort((a, b) => Number(b.revision) - Number(a.revision))[0] : undefined);\n}\n\nexport async function loadLocalMemberContent(\n db: ChapterDb,\n chapterId: string,\n environment: string,\n): Promise<StoredLocalMemberContent | null> {\n const id = `member-content-local:${environment}`;\n const rows = (await db.query({ memberContentLocal: { $: { where: { id }, limit: 1 } } })).memberContentLocal;\n return local(Array.isArray(rows) ? rows[0] : undefined);\n}\n\n/** Activate a Parent revision without touching the independently owned local row. */\nexport async function materializeMemberContentControl(\n db: ChapterDb,\n envelope: MemberContentEnvelope,\n previous: StoredMemberContentControl | null,\n receivedAt: number,\n): Promise<void> {\n const { document, digest } = envelope;\n const target = document.target!;\n const id = `member-content-control:${target.environment}:${document.revision}`;\n const ops: DbOp[] = [];\n if (previous?.active) {\n ops.push({ t: \"update\", ns: \"memberContentControls\", id: previous.id, attrs: { active: false } });\n }\n ops.push({ t: \"update\", ns: \"memberContentControls\", id, attrs: {\n id,\n sourceId: document.source.appId,\n targetId: target.chapterId,\n environment: target.environment,\n revision: document.revision,\n digest,\n document,\n active: true,\n receivedAt,\n } });\n await db.transact(ops, { mutationId: `member-content-control:${target.environment}:${document.revision}:${digest}` });\n}\n\n/** Save a complete local layer under an optimistic revision guard. */\nexport async function saveLocalMemberContent(\n db: ChapterDb,\n document: MemberContentDocument,\n environment: string,\n expectedRevision: number,\n updatedAt: number,\n updatedBy?: string,\n): Promise<StoredLocalMemberContent> {\n const id = `member-content-local:${environment}`;\n const current = await loadLocalMemberContent(db, document.source.appId, environment);\n if ((current?.revision ?? 0) !== expectedRevision) throw new Error(\"member_content_revision_conflict\");\n const row: StoredLocalMemberContent = {\n id,\n chapterId: document.source.appId,\n environment,\n revision: document.revision,\n document,\n updatedAt,\n ...(updatedBy ? { updatedBy } : {}),\n };\n await db.transact([{ t: \"update\", ns: \"memberContentLocal\", id, attrs: row as unknown as Record<string, unknown> }], {\n mutationId: `member-content-local:${environment}:${document.revision}`,\n guards: current\n ? [{ ns: \"memberContentLocal\", id, exists: true, equals: { revision: expectedRevision } }]\n : [{ ns: \"memberContentLocal\", id, exists: false }],\n });\n return row;\n}\n","import { verifyFederatedRequest } from \"@odla-ai/db\";\nimport { getVaultSecret } from \"./auth\";\nimport {\n ADMISSION_GRANTS_PATH,\n type AdmissionGrantEnvelope,\n type AdmissionGrantRejection,\n} from \"./admission-grants-contract\";\nimport {\n loadLatestAdmissionRevision,\n materializeAdmissionGrants,\n validateAdmissionGrantDocument,\n} from \"./admission-grants\";\nimport { signupControlDigest } from \"./signup-control-canonical\";\nimport { json } from \"./worker-context\";\nimport type { Route } from \"./worker-context\";\nimport type { ChapterDb } from \"./types\";\n\nconst reject = (reason: AdmissionGrantRejection, status: number, errors?: readonly string[]) =>\n json({ ok: false, reason, ...(errors ? { errors } : {}) }, status);\n\n/** Signed Parent → Chapter desired-state receiver for admission decisions. */\nexport const handleAdmissionGrants: Route = async (req, url, env, ctx) => {\n if (req.method !== \"POST\" || url.pathname !== ADMISSION_GRANTS_PATH) return null;\n const authority = ctx.chapter.signupControl;\n if (!authority) return json({ error: \"not found\" }, 404);\n const db = ctx.makeDb(env) as unknown as ChapterDb;\n const secret = await getVaultSecret(db, authority.secretName);\n if (!secret) return json({ error: \"unauthorized\" }, 401);\n const verified = await verifyFederatedRequest(req, { secret, senders: [authority.sourceId] });\n if (!verified.ok) return json({ error: \"unauthorized\", reason: verified.reason }, 401);\n let input: Record<string, unknown>;\n try {\n input = JSON.parse(verified.body) as Record<string, unknown>;\n } catch {\n return reject(\"invalid_document\", 400, [\"request body must be JSON\"]);\n }\n const digest = typeof input.digest === \"string\" ? input.digest : \"\";\n const checked = validateAdmissionGrantDocument(input.document);\n if (!checked.ok) return reject(\"invalid_document\", 400, checked.errors);\n const document = checked.value;\n if (document.source.appId !== authority.sourceId) return reject(\"wrong_source\", 403);\n if (document.target.chapterId !== ctx.chapter.id) return reject(\"wrong_target\", 409);\n if (document.target.environment !== env.ODLA_ENV) return reject(\"wrong_environment\", 409);\n if (!digest || await signupControlDigest(document) !== digest) return reject(\"invalid_digest\", 400);\n const latest = await loadLatestAdmissionRevision(db, authority.sourceId, ctx.chapter.id, env.ODLA_ENV);\n if (latest && document.revision < latest.revision) return reject(\"stale_revision\", 409);\n if (latest && document.revision === latest.revision) {\n if (latest.digest !== digest) return reject(\"conflicting_revision\", 409);\n return json({\n ok: true,\n target: { chapterId: ctx.chapter.id, environment: env.ODLA_ENV },\n revision: latest.revision,\n digest: latest.digest,\n status: \"replayed\",\n acknowledgedAt: latest.receivedAt,\n });\n }\n const receivedAt = Date.now();\n try {\n await materializeAdmissionGrants(db, { digest, document } as AdmissionGrantEnvelope, latest, receivedAt);\n } catch {\n return reject(\"materialization_failed\", 503);\n }\n return json({\n ok: true,\n target: { chapterId: ctx.chapter.id, environment: env.ODLA_ENV },\n revision: document.revision,\n digest,\n status: \"accepted\",\n acknowledgedAt: receivedAt,\n });\n};\n","import { isValidEmail } from \"./member\";\nimport { normalizeChapterEmail } from \"./email-identity\";\nimport { json } from \"./worker-context\";\nimport type { Route } from \"./worker-context\";\nimport type { ChapterDb } from \"./types\";\n\nasync function gate(req: Request, env: Parameters<Route>[2], ctx: Parameters<Route>[3]) {\n const rawDb = ctx.makeDb(env);\n const user = await ctx.verifyUser(req, env);\n if (!user) return json({ error: \"unauthorized\" }, 401);\n if (!(await ctx.isAdmin(rawDb, user))) return json({ error: \"forbidden\" }, 403);\n return { db: rawDb as unknown as ChapterDb, user };\n}\n\n/** Chapter-admin list/create/revoke surface for local admission decisions. */\nexport const handleAdminAdmissionGrants: Route = async (req, url, env, ctx) => {\n if (url.pathname === \"/api/admin/admission-grants\" && req.method === \"GET\") {\n const auth = await gate(req, env, ctx);\n if (auth instanceof Response) return auth;\n const result = await auth.db.query({ admissionGrants: { $: {\n where: { targetId: ctx.chapter.id }, order: { createdAt: \"desc\" }, limit: 500,\n } } });\n const grants = Array.isArray(result.admissionGrants)\n ? result.admissionGrants.map((row) => ({ ...row, emailNormalized: undefined }))\n : [];\n return json({ grants });\n }\n\n if (url.pathname === \"/api/admin/admission-grants\" && req.method === \"POST\") {\n const auth = await gate(req, env, ctx);\n if (auth instanceof Response) return auth;\n let body: Record<string, unknown>;\n try {\n body = JSON.parse(await req.text()) as Record<string, unknown>;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n const email = typeof body.email === \"string\" ? body.email.trim() : \"\";\n const emailNormalized = normalizeChapterEmail(email);\n if (!isValidEmail(emailNormalized)) return json({ error: \"email must be valid\" }, 400);\n const decision = body.decision ?? \"waive_interview\";\n if (decision !== \"waive_interview\" && decision !== \"require_interview\") {\n return json({ error: \"decision must be waive_interview or require_interview\" }, 400);\n }\n const note = typeof body.note === \"string\" ? body.note.trim() : \"\";\n if (note.length > 2_000) return json({ error: \"note is too long\" }, 400);\n const expiresAt = body.expiresAt === undefined || body.expiresAt === null\n ? undefined\n : Number(body.expiresAt);\n if (expiresAt !== undefined && (!Number.isFinite(expiresAt) || expiresAt <= Date.now())) {\n return json({ error: \"expiresAt must be a future epoch timestamp\" }, 400);\n }\n const sourceGrantId = crypto.randomUUID();\n const id = `admission:local:${ctx.chapter.id}:${sourceGrantId}`;\n const createdAt = Date.now();\n const actor = auth.user.email ?? auth.user.userId;\n await auth.db.transact([{ t: \"update\", ns: \"admissionGrants\", id, attrs: {\n id,\n sourceGrantId,\n sourceScope: \"local\",\n sourceId: ctx.chapter.id,\n targetId: ctx.chapter.id,\n email,\n emailNormalized,\n decision,\n ...(note ? { note } : {}),\n ...(expiresAt !== undefined ? { expiresAt } : {}),\n active: true,\n createdAt,\n createdBy: actor,\n updatedAt: createdAt,\n updatedBy: actor,\n } }], { mutationId: `admission-local-create:${sourceGrantId}` });\n return json({ grant: { id, sourceGrantId, sourceScope: \"local\", email, decision, active: true, createdAt, ...(note ? { note } : {}), ...(expiresAt ? { expiresAt } : {}) } }, 201);\n }\n\n const prefix = \"/api/admin/admission-grants/\";\n let revokeId = \"\";\n if (url.pathname.startsWith(prefix)) {\n try {\n revokeId = decodeURIComponent(url.pathname.slice(prefix.length));\n } catch {\n revokeId = \"\";\n }\n }\n if (/^admission:local:[a-z0-9-]+:[0-9a-f-]+$/.test(revokeId) && req.method === \"DELETE\") {\n const auth = await gate(req, env, ctx);\n if (auth instanceof Response) return auth;\n const id = revokeId;\n const found = await auth.db.query({ admissionGrants: { $: { where: { id }, limit: 1 } } });\n const row = Array.isArray(found.admissionGrants) ? found.admissionGrants[0] : undefined;\n if (!row || row.targetId !== ctx.chapter.id || row.sourceScope !== \"local\") return json({ error: \"not found\" }, 404);\n if (row.active !== true) return json({ ok: true, replayed: true });\n const revokedAt = Date.now();\n const actor = auth.user.email ?? auth.user.userId;\n await auth.db.transact([{ t: \"update\", ns: \"admissionGrants\", id, attrs: {\n active: false,\n revokedAt,\n revokedBy: actor,\n updatedAt: revokedAt,\n updatedBy: actor,\n } }], { mutationId: `admission-local-revoke:${id}` });\n return json({ ok: true, replayed: false });\n }\n return null;\n};\n","// Scheduling routes: GET /api/schedule/slots + POST /api/schedule/book. This\n// file owns the I/O — Google FreeBusy, the pure computeBookableSlots, the\n// calendar create/reschedule, and the db writes — and delegates every\n// correctness rule to ./scheduling. Calendar is RUNTIME-optional: a chapter with\n// no connected calendar has freeBusy throw, so /slots answers\n// { schedulingReady: false } (200) and the join flow degrades to \"we'll reach\n// out by email\" rather than erroring.\nimport { crmDeps, syncApplicationToCrm } from \"./crm-sync\";\nimport { computeBookableSlots, initCalendar } from \"@odla-ai/calendar\";\nimport { emailGroupFrom, sendTemplated } from \"./notify\";\nimport { json } from \"./worker-context\";\nimport type { ChapterEnv, WorkerContext } from \"./worker-context\";\nimport type { Route } from \"./worker-routes\";\nimport type { ChapterDb, ChapterScheduling, DbOp } from \"./types\";\nimport { canBook } from \"./pipeline\";\nimport {\n applicationBookingUpdate,\n bookingDecision,\n endForSlot,\n introIdempotencyKey,\n isSlotAvailable,\n meetingCreateRow,\n meetingRescheduleUpdate,\n renderSummary,\n resolveScheduling,\n slotWindow,\n} from \"./scheduling\";\nimport type { ExistingMeeting, ResolvedScheduling } from \"./scheduling\";\n\ntype Cal = ReturnType<typeof initCalendar>;\ntype Row = Record<string, unknown>;\n\n/** The stable `.code` off an OdlaError/provider error, else a safe default. */\nfunction errCode(err: unknown): string {\n if (err && typeof err === \"object\") {\n const code = (err as { code?: unknown }).code;\n if (typeof code === \"string\") return code;\n }\n return \"calendar_unavailable\";\n}\n\nfunction makeCalendar(env: ChapterEnv): Cal {\n // Calendar uses ODLA_APP_ID + ODLA_PLATFORM — distinct from the db client's\n // ODLA_TENANT + ODLA_ENDPOINT.\n return initCalendar({ appId: env.ODLA_APP_ID, env: env.ODLA_ENV, adminToken: env.ODLA_API_KEY, endpoint: env.ODLA_PLATFORM });\n}\n\nasync function firstRow(db: ChapterDb, ns: string, q: Record<string, unknown>): Promise<Row | undefined> {\n const res = await db.query({ [ns]: { $: q } });\n const rows = res[ns];\n return Array.isArray(rows) ? rows[0] : undefined;\n}\n\nasync function computeSlots(cal: Cal, cfg: ResolvedScheduling): Promise<Array<{ startAt: number; endAt: number }>> {\n const { from, to } = slotWindow(Date.now(), cfg.windowDays);\n const fb = await cal.availability.freeBusy({ timeMin: from, timeMax: to });\n return computeBookableSlots(fb.busy, {\n from: fb.timeMin,\n to: fb.timeMax,\n timezone: cfg.timezone,\n slotMinutes: cfg.slotMinutes,\n businessHours: { days: [...cfg.days], startHour: cfg.startHour, endHour: cfg.endHour },\n minNoticeMs: cfg.minNoticeHours * 3_600_000,\n });\n}\n\nasync function bookSlot(req: Request, env: ChapterEnv, ctx: WorkerContext): Promise<Response> {\n let body: Row;\n try {\n body = JSON.parse(await req.text()) as Row;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n const applicationId = typeof body.applicationId === \"string\" ? body.applicationId : \"\";\n const startAt = Number(body.startAt);\n if (!applicationId || !Number.isFinite(startAt)) return json({ error: \"applicationId and startAt required\" }, 400);\n\n const db = ctx.makeDb(env) as unknown as ChapterDb;\n const app = await firstRow(db, \"applications\", { where: { id: applicationId }, limit: 1 });\n if (!app) return json({ error: \"not found\" }, 404);\n const status = String(app.status ?? \"\");\n if (!canBook(status, ctx.chapter.pipeline)) return json({ error: `cannot book from status \"${status}\"` }, 409);\n\n const group = await firstRow(db, \"groups\", { where: { id: String(app.groupId ?? ctx.chapter.id) }, limit: 1 });\n if (!group) return json({ error: \"group not found\" }, 500);\n const cfg = resolveScheduling(group.schedulingJson as ChapterScheduling | undefined);\n const endAt = endForSlot(startAt, cfg.slotMinutes);\n const cal = makeCalendar(env);\n\n // Double-book guard, layer 1: the requested start must still be a live slot.\n let slots: Array<{ startAt: number }>;\n try {\n slots = await computeSlots(cal, cfg);\n } catch (err) {\n return json({ error: \"scheduling unavailable\", code: errCode(err) }, 503);\n }\n if (!isSlotAvailable(slots, startAt)) return json({ error: \"slot no longer available\", code: \"calendar_slot_unavailable\" }, 409);\n\n const summary = renderSummary(cfg.summaryTemplate, { firstName: app.firstName as string, lastName: app.lastName as string });\n const existing = (await firstRow(db, \"meetings\", {\n where: { applicationId, status: \"scheduled\" },\n order: { createdAt: \"desc\" },\n limit: 1,\n })) as ExistingMeeting | undefined;\n const decision = bookingDecision(existing);\n\n let meetUrl: string | null = null;\n let htmlLink: string | null = null;\n let meetingOp: DbOp;\n try {\n if (decision.reschedule && decision.eventId) {\n // Reschedule the SAME event — the Meet link + invite thread survive.\n await cal.actions.reschedule(decision.eventId, {\n idempotencyKey: `meeting:${String(existing?.id)}:reschedule:${startAt}:${endAt}`,\n startAt,\n endAt,\n });\n meetUrl = (existing?.meetUrl as string | undefined) ?? null;\n htmlLink = (existing?.htmlLink as string | undefined) ?? null;\n meetingOp = { t: \"update\", ns: \"meetings\", id: String(existing?.id), attrs: meetingRescheduleUpdate(startAt, endAt) };\n } else {\n const { booking } = await cal.actions.create(\n { summary, startAt, endAt, attendees: [String(app.email)], timezone: cfg.timezone, meet: true },\n { idempotencyKey: introIdempotencyKey(applicationId) },\n );\n meetUrl = booking.meetUrl ?? null;\n htmlLink = booking.htmlLink ?? null;\n const meetingId = crypto.randomUUID();\n meetingOp = {\n t: \"update\",\n ns: \"meetings\",\n id: meetingId,\n attrs: meetingCreateRow({\n meetingId,\n applicationId,\n groupId: String(group.id),\n startAt,\n endAt,\n timezone: cfg.timezone,\n googleEventId: booking.eventId,\n meetUrl: booking.meetUrl,\n htmlLink: booking.htmlLink,\n createdAt: Date.now(),\n }),\n };\n }\n } catch (err) {\n const code = errCode(err);\n // Double-book guard, layer 2 (authoritative): the provider rejected under lease.\n if (code === \"calendar_slot_unavailable\") return json({ error: \"slot no longer available\", code }, 409);\n return json({ error: \"booking failed\", code }, 502);\n }\n\n // meetings row is canonical; the application row is the projection.\n const bookingAttrs = applicationBookingUpdate(status, startAt, htmlLink);\n const appOp: DbOp = { t: \"update\", ns: \"applications\", id: applicationId, attrs: bookingAttrs };\n await db.transact([meetingOp, appOp]);\n\n // Booking is the other status transition that happens with no admin present.\n // The console reads its pipeline from crm_record.stage, so skipping the\n // mirror here leaves a booked applicant reading as merely submitted.\n // Best-effort: the member has already seen the booking confirmed.\n const booked = { ...app, ...bookingAttrs };\n await syncApplicationToCrm(crmDeps(db, ctx), { app: booked, stage: String(booked.status ?? \"\") }).catch(() => undefined);\n\n // Prep email — best-effort, exactly-once per application (never fails the booking).\n if (typeof app.email === \"string\" && app.email) {\n await sendTemplated(\n { db, envName: env.ODLA_ENV, sender: env.SEND_EMAIL, from: env.EMAIL_FROM, now: () => Date.now(), newId: () => crypto.randomUUID() },\n { group: emailGroupFrom(group), template: \"prepEmail\", to: app.email, vars: { firstName: String(app.firstName ?? \"\") }, dedupeKey: `prep:${applicationId}`, applicationId },\n ).catch(() => undefined);\n }\n\n return json({ ok: true, startAt, endAt, meetUrl, rescheduled: decision.reschedule });\n}\n\n/** GET /api/schedule/slots + POST /api/schedule/book (chapter mode only). */\nexport const handleSchedule: Route = async (req, url, env, ctx) => {\n if (ctx.chapter.mode !== \"chapter\") return null;\n\n if (req.method === \"GET\" && url.pathname === \"/api/schedule/slots\") {\n const db = ctx.makeDb(env) as unknown as ChapterDb;\n const group = await firstRow(db, \"groups\", { where: { id: url.searchParams.get(\"group\") ?? ctx.chapter.id }, limit: 1 });\n if (!group) return json({ error: \"not found\" }, 404);\n const cfg = resolveScheduling(group.schedulingJson as ChapterScheduling | undefined);\n try {\n const slots = await computeSlots(makeCalendar(env), cfg);\n return json({ schedulingReady: true, timezone: cfg.timezone, slotMinutes: cfg.slotMinutes, slots });\n } catch (err) {\n return json({ schedulingReady: false, code: errCode(err) });\n }\n }\n\n if (req.method === \"POST\" && url.pathname === \"/api/schedule/book\") {\n return bookSlot(req, env, ctx);\n }\n\n return null;\n};\n","// Payments primitives. Generic Stripe form encoding and webhook authenticity\n// live in @odla-ai/stripe; Chapter keeps only membership-specific readiness,\n// event normalization, and write sets. This preserves Chapter's public exports\n// while making the provider plumbing reusable by every app.\nexport { stripeForm, verifyStripeSignature } from \"@odla-ai/stripe\";\n\n// ── readiness + Stripe wire helpers ──\n\n/** A group row's payment configuration, as far as readiness cares. */\nexport interface PaymentsGroup {\n stripePublishableKey?: string | null;\n stripePriceId?: string | null;\n}\n\n/** Whether a group can take payment: a publishable key + a price id (both on the\n * group row) AND a secret key (the vault). Anything missing drops the join\n * flow's payment step (paymentsReady:false) rather than half-charging. */\nexport function paymentsReady(group: PaymentsGroup, hasSecretKey: boolean): boolean {\n return Boolean(group.stripePublishableKey && group.stripePriceId && hasSecretKey);\n}\n\n/** The Stripe idempotency key for creating an application's subscription — one\n * per application, so a client retry can't orphan a second subscription. */\nexport function subscriptionIdempotencyKey(applicationId: string): string {\n return `sub:${applicationId}`;\n}\n\n/** The db mutationId for a webhook-driven write — exactly-once per Stripe event,\n * so replays are deduped at the db layer. */\nexport function webhookMutationId(eventId: string): string {\n return `stripe:${eventId}`;\n}\n\n// ── webhook normalization (pure; the worker owns the db lookup + writes) ──\n\n/** A raw Stripe event, as far as normalization cares. */\nexport interface StripeEvent {\n id: string;\n type: string;\n data?: { object?: Record<string, unknown> };\n}\n\n/** A normalized, provider-agnostic webhook event. `kind` drives the db write;\n * the application is resolved from `applicationId` (metadata) or `customerId`. */\nexport type WebhookEvent =\n | { kind: \"gift_paid\"; giftIntentId: string; providerObjectId: string }\n | { kind: \"gift_revoked\"; giftIntentId: string; reason: \"refunded\" | \"canceled\" }\n | { kind: \"first_payment\"; applicationId?: string; customerId?: string; renewalAt?: number }\n | { kind: \"renewal\"; applicationId?: string; customerId?: string; renewalAt?: number }\n | { kind: \"refunded\"; applicationId?: string; customerId?: string }\n | { kind: \"canceled\"; applicationId?: string; customerId?: string }\n | { kind: \"ignored\"; type: string };\n\n/** Resolve the application reference on a Stripe object: `applicationId` from\n * metadata (direct, then subscription_details, then nested\n * parent.subscription_details), plus the customer id for the db fallback. */\nexport function findApplicationRef(obj: Record<string, unknown>): { applicationId?: string; customerId?: string } {\n const metaOf = (v: unknown): Record<string, unknown> =>\n v && typeof v === \"object\" ? ((v as Record<string, unknown>).metadata as Record<string, unknown>) ?? {} : {};\n const pick = (m: Record<string, unknown>): string | undefined =>\n typeof m.applicationId === \"string\" ? m.applicationId : undefined;\n const applicationId =\n pick(metaOf(obj)) ?? pick(metaOf(obj.subscription_details)) ?? pick(metaOf((obj.parent as Record<string, unknown> | undefined)?.subscription_details));\n const customerId = typeof obj.customer === \"string\" ? obj.customer : undefined;\n return { ...(applicationId ? { applicationId } : {}), ...(customerId ? { customerId } : {}) };\n}\n\n/** Resolve gift purchase metadata from direct or invoice subscription metadata. */\nexport function findGiftRef(obj: Record<string, unknown>): { giftIntentId?: string; providerObjectId: string } {\n const metaOf = (value: unknown): Record<string, unknown> =>\n value && typeof value === \"object\" ? ((value as Record<string, unknown>).metadata as Record<string, unknown>) ?? {} : {};\n const pick = (metadata: Record<string, unknown>): string | undefined =>\n typeof metadata.giftIntentId === \"string\" ? metadata.giftIntentId : undefined;\n const parent = obj.parent as Record<string, unknown> | undefined;\n const subscription = obj.subscription_details ?? parent?.subscription_details;\n const giftIntentId = pick(metaOf(obj)) ?? pick(metaOf(subscription));\n const subscriptionId = typeof obj.subscription === \"string\"\n ? obj.subscription\n : typeof (subscription as Record<string, unknown> | undefined)?.subscription === \"string\"\n ? String((subscription as Record<string, unknown>).subscription)\n : undefined;\n return { ...(giftIntentId ? { giftIntentId } : {}), providerObjectId: subscriptionId ?? String(obj.id ?? \"\") };\n}\n\n/** Normalize a verified Stripe event into a {@link WebhookEvent}. `invoice.paid`\n * splits into first_payment vs renewal by `billing_reason`; refunds and\n * cancellations map directly; everything else is ignored (acked, not retried). */\nexport function normalizeWebhookEvent(event: StripeEvent): WebhookEvent {\n const obj = event.data?.object ?? {};\n const gift = findGiftRef(obj);\n if (gift.giftIntentId) {\n if (event.type === \"payment_intent.succeeded\" ||\n (event.type === \"invoice.paid\" && obj.billing_reason === \"subscription_create\")) {\n return { kind: \"gift_paid\", giftIntentId: gift.giftIntentId, providerObjectId: gift.providerObjectId };\n }\n if (event.type === \"charge.refunded\") return { kind: \"gift_revoked\", giftIntentId: gift.giftIntentId, reason: \"refunded\" };\n if (event.type === \"customer.subscription.deleted\") return { kind: \"gift_revoked\", giftIntentId: gift.giftIntentId, reason: \"canceled\" };\n return { kind: \"ignored\", type: event.type };\n }\n const ref = findApplicationRef(obj);\n switch (event.type) {\n case \"invoice.paid\": {\n const lines = ((obj.lines as Record<string, unknown> | undefined)?.data as Array<Record<string, unknown>> | undefined) ?? [];\n const periodEnd = (lines[0]?.period as Record<string, unknown> | undefined)?.end;\n const renewalAt = typeof periodEnd === \"number\" ? periodEnd * 1000 : undefined;\n const kind = obj.billing_reason === \"subscription_create\" ? \"first_payment\" : \"renewal\";\n return { kind, ...ref, ...(renewalAt !== undefined ? { renewalAt } : {}) };\n }\n case \"charge.refunded\":\n return { kind: \"refunded\", ...ref };\n case \"customer.subscription.deleted\":\n return { kind: \"canceled\", ...ref };\n default:\n return { kind: \"ignored\", type: event.type };\n }\n}\n\n// ── webhook write-set builders (the authoritative writers of paid/refunded) ──\n\n/** First-payment patch: advance submitted→paid_pending_vetting (never any other\n * transition) and record the renewal date. Empty when nothing changed, so the\n * caller can skip the write. */\nexport function firstPaymentPatch(currentStatus: string, renewalAt?: number): { status?: \"paid_pending_vetting\"; renewalAt?: number } {\n return {\n ...(currentStatus === \"submitted\" ? { status: \"paid_pending_vetting\" as const } : {}),\n ...(renewalAt !== undefined ? { renewalAt } : {}),\n };\n}\n\n/** Renewal-invoice patch: just the new renewal date. */\nexport function renewalPatch(renewalAt: number): { renewalAt: number } {\n return { renewalAt };\n}\n\n/** Refund patch — the SOLE writer of status \"refunded\" (the admin refund route\n * issues the Stripe refund but never sets this; the webhook does). */\nexport function refundedPatch(): { status: \"refunded\" } {\n return { status: \"refunded\" };\n}\n\n/** Subscription-cancellation patch. */\nexport function canceledPatch(): { canceled: true } {\n return { canceled: true };\n}\n","// The Stripe payments provider — the only I/O half of payments. Talks to the\n// Stripe REST API over @odla-ai/stripe's fetch transport, and maps 1:1 onto the\n// membership-specific event normalization in ./payments. The worker\n// resolves secrets from the vault per request and constructs this; the routes own\n// every db write so idempotency stays at the db layer.\nimport { stripeRequest, verifyStripeSignature, type StripeRequestResult } from \"@odla-ai/stripe\";\nimport { normalizeWebhookEvent } from \"./payments\";\nimport type { StripeEvent, WebhookEvent } from \"./payments\";\n\n/** Inputs to create an application's founding-member subscription. */\nexport interface CreateSubscriptionInput {\n applicationId: string;\n groupId: string;\n email: string;\n name: string;\n priceId: string;\n existingCustomerId?: string;\n}\n\n/** The client secret to confirm card entry, plus the ids to persist. */\nexport interface CreateSubscriptionResult {\n customerId: string;\n subscriptionId: string;\n clientSecret: string;\n}\n\n/** The outcome of a full refund. */\nexport interface RefundResult {\n refundedCents: number | null;\n subscriptionCanceled: boolean;\n}\n\n/** The capabilities the payment routes depend on — Stripe is one impl. */\nexport interface PaymentsProvider {\n createSubscription(input: CreateSubscriptionInput): Promise<CreateSubscriptionResult>;\n ingestWebhook(\n rawBody: string,\n sigHeader: string,\n ): Promise<{ ok: true; eventId: string; event: WebhookEvent } | { ok: false; reason: \"bad_signature\" }>;\n refund(input: { customerId: string; subscriptionId: string }): Promise<RefundResult>;\n}\n\n/** The result of a Stripe Backend API call: ok + status + parsed JSON body. */\nexport type StripeResult = StripeRequestResult<Record<string, unknown>>;\n\n/** Call the Stripe Backend API (form-encoded, Bearer sk_). Exposed so the admin\n * billing/dashboard reads and the refund route share one Stripe client instead\n * of each re-deriving the auth + encoding. */\nexport async function stripeCall(\n sk: string,\n method: \"GET\" | \"POST\" | \"DELETE\",\n path: string,\n params?: Record<string, unknown>,\n idempotencyKey?: string,\n): Promise<StripeResult> {\n return stripeRequest(\n { secretKey: sk },\n method,\n path,\n params,\n idempotencyKey ? { idempotencyKey } : {},\n );\n}\n\nfunction fail(op: string, r: StripeResult): never {\n const err = new Error(`stripe ${op} failed: ${r.status}`) as Error & { code: string };\n err.code = \"stripe_error\";\n throw err;\n}\n\nfunction clientSecretOf(sub: Record<string, unknown>): string | undefined {\n const inv = sub.latest_invoice as Record<string, unknown> | undefined;\n const confirmation = inv?.confirmation_secret as Record<string, unknown> | undefined;\n const intent = inv?.payment_intent as Record<string, unknown> | undefined;\n const secret = confirmation?.client_secret ?? intent?.client_secret;\n return typeof secret === \"string\" ? secret : undefined;\n}\n\nfunction requireSecret(secretKey: string | undefined): string {\n if (!secretKey) {\n const err = new Error(\"stripe secret key missing\") as Error & { code: string };\n err.code = \"not_configured\";\n throw err;\n }\n return secretKey;\n}\n\n/** Build the Stripe provider. `secretKey` powers charging/refunds; `webhookSecret`\n * powers webhook ingest. Each is resolved from the vault per request, so the\n * webhook route can construct an ingest-only provider without the secret key. */\nexport function createStripeProvider(config: { secretKey?: string; webhookSecret?: string }): PaymentsProvider {\n const { secretKey, webhookSecret } = config;\n return {\n async createSubscription(input) {\n const sk = requireSecret(secretKey);\n const meta = { applicationId: input.applicationId, groupId: input.groupId, email: input.email };\n let customerId = input.existingCustomerId;\n if (!customerId) {\n const cust = await stripeCall(\n sk,\n \"POST\",\n \"/v1/customers\",\n { email: input.email, name: input.name, metadata: meta },\n `cus:${input.applicationId}`,\n );\n if (!cust.ok) fail(\"customer create\", cust);\n customerId = String(cust.body.id);\n }\n const sub = await stripeCall(\n sk,\n \"POST\",\n \"/v1/subscriptions\",\n {\n customer: customerId,\n \"items[0][price]\": input.priceId,\n payment_behavior: \"default_incomplete\",\n \"payment_settings[save_default_payment_method]\": \"on_subscription\",\n \"payment_settings[payment_method_types][0]\": \"card\",\n \"expand[0]\": \"latest_invoice.confirmation_secret\",\n metadata: meta,\n },\n // Hardening: one subscription per application, so a client\n // retry between create and the db write can't orphan a second one.\n `sub:${input.applicationId}`,\n );\n if (!sub.ok) fail(\"subscription create\", sub);\n const clientSecret = clientSecretOf(sub.body);\n if (!clientSecret) fail(\"subscription confirmation-secret missing\", sub);\n return { customerId, subscriptionId: String(sub.body.id), clientSecret };\n },\n\n async ingestWebhook(rawBody, sigHeader) {\n if (!webhookSecret || !(await verifyStripeSignature(rawBody, sigHeader, webhookSecret))) {\n return { ok: false, reason: \"bad_signature\" };\n }\n const event = JSON.parse(rawBody) as StripeEvent;\n return { ok: true, eventId: event.id, event: normalizeWebhookEvent(event) };\n },\n\n async refund(input) {\n const sk = requireSecret(secretKey);\n const charges = await stripeCall(sk, \"GET\", \"/v1/charges\", { customer: input.customerId, limit: 100 });\n if (!charges.ok) fail(\"charges list\", charges);\n const rows = (charges.body.data as Array<Record<string, unknown>> | undefined) ?? [];\n const paid = rows.filter((c) => c.status === \"succeeded\" && c.refunded !== true);\n const charge = paid[paid.length - 1]; // Stripe returns newest-first; refund the earliest.\n if (!charge) {\n const err = new Error(\"no paid charge to refund\") as Error & { code: string };\n err.code = \"no_charge\";\n throw err;\n }\n const refund = await stripeCall(sk, \"POST\", \"/v1/refunds\", { charge: String(charge.id) });\n if (!refund.ok) fail(\"refund\", refund);\n const cancel = await stripeCall(sk, \"DELETE\", `/v1/subscriptions/${input.subscriptionId}`);\n const amount = refund.body.amount;\n return { refundedCents: typeof amount === \"number\" ? amount : null, subscriptionCanceled: cancel.ok };\n },\n };\n}\n","/** Stored hash format version for high-entropy gift claim codes. */\nexport const GIFT_CODE_VERSION = 1 as const;\nexport const GIFT_CODE_BYTES = 32;\n\nconst base64url = (bytes: Uint8Array): string => {\n let binary = \"\";\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return btoa(binary).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/g, \"\");\n};\n\n/** Generate a 256-bit bearer code. Plaintext must be displayed once and discarded. */\nexport function createGiftCode(): string {\n const bytes = new Uint8Array(GIFT_CODE_BYTES);\n crypto.getRandomValues(bytes);\n return `gift${GIFT_CODE_VERSION}_${base64url(bytes)}`;\n}\n\n/** Hash a claim code with its Chapter and format version domain separation. */\nexport async function hashGiftCode(chapterId: string, code: string, version = GIFT_CODE_VERSION): Promise<string> {\n const bytes = new TextEncoder().encode(`odla-gift:${version}:${chapterId}:${code}`);\n return base64url(new Uint8Array(await crypto.subtle.digest(\"SHA-256\", bytes)));\n}\n\n/** Stable non-secret requester bucket hash used only for redemption rate limits. */\nexport async function giftRequesterBucket(chapterId: string, requester: string): Promise<string> {\n const bytes = new TextEncoder().encode(`odla-gift-rate:${chapterId}:${requester}`);\n return base64url(new Uint8Array(await crypto.subtle.digest(\"SHA-256\", bytes))).slice(0, 32);\n}\n","import type { GiftOffer, GiftOfferTarget } from \"./gift-offers\";\nimport { createGiftCode, GIFT_CODE_VERSION, hashGiftCode } from \"./gift-codes\";\nimport { normalizeChapterEmail } from \"./email-identity\";\nimport type { ChapterDb, DbOp } from \"./types\";\n\ntype Row = Record<string, unknown>;\nconst first = (value: unknown): Row | undefined => Array.isArray(value) ? value[0] as Row | undefined : undefined;\n\n/** Persisted purchase intent subset required by provider webhook issuance. */\nexport interface GiftIntentRow extends Row {\n id: string; chapterId: string; environment: string; offerId: string; offerSnapshot: GiftOffer;\n purchaserType: \"application\" | \"member\"; purchaserEmailNormalized: string;\n codeHash: string; codeVersion: number; codeIssuedAt: number; status: string;\n purchaserApplicationId?: string; purchaserUserId?: string; providerObjectId?: string;\n}\n\n/** Safe buyer-facing claim state; hashes and beneficiary identity are deliberately absent. */\nexport interface BuyerGiftClaim {\n id: string; offerId: string; status: \"pending\" | \"redeemed\" | \"expired\" | \"revoked\";\n createdAt: number; codeExpiresAt: number; redeemedAt?: number; revokedAt?: number;\n}\n\n/** Create a code/hash pair for a new or rotated claim. */\nexport async function prepareGiftCode(chapterId: string): Promise<{ code: string; codeHash: string; codeVersion: number }> {\n const code = createGiftCode();\n return { code, codeHash: await hashGiftCode(chapterId, code), codeVersion: GIFT_CODE_VERSION };\n}\n\n/** Issue exactly one immutable order and pending claim from a verified provider success. */\nexport async function issueGiftClaim(\n db: ChapterDb,\n intent: GiftIntentRow,\n provider: { eventId: string; objectId: string },\n now: number,\n): Promise<{ claimId: string; orderId: string; duplicate: boolean }> {\n const existing = first((await db.query({ giftClaims: { $: { where: { intentId: intent.id }, limit: 1 } } })).giftClaims);\n if (existing) return { claimId: String(existing.id), orderId: String(existing.orderId), duplicate: true };\n const offer = intent.offerSnapshot;\n const orderId = `gift-order:${intent.id}`;\n const claimId = `gift-claim:${intent.id}`;\n const shared = {\n chapterId: intent.chapterId, offerId: intent.offerId,\n ...(intent.purchaserApplicationId ? { purchaserApplicationId: intent.purchaserApplicationId } : {}),\n ...(intent.purchaserUserId ? { purchaserUserId: intent.purchaserUserId } : {}),\n purchaserEmailNormalized: intent.purchaserEmailNormalized,\n };\n const ops: DbOp[] = [\n { t: \"update\", ns: \"giftOrders\", id: orderId, attrs: {\n id: orderId, intentId: intent.id, ...shared, environment: intent.environment,\n offerSnapshot: offer, purchaserType: intent.purchaserType, providerEventId: provider.eventId,\n providerObjectId: provider.objectId, amountCents: offer.priceCents, currency: offer.currency,\n billingMode: offer.billingMode, createdAt: now,\n } },\n { t: \"update\", ns: \"giftClaims\", id: claimId, attrs: {\n id: claimId, orderId, intentId: intent.id, ...shared, target: offer.target,\n codeHash: intent.codeHash, codeVersion: intent.codeVersion, rotationCount: 0, codeIssuedAt: intent.codeIssuedAt,\n codeExpiresAt: now + offer.redemptionLifetimeHours * 3_600_000,\n attemptCount: 0, attemptWindowStartedAt: now, status: \"pending\", createdAt: now,\n } },\n { t: \"update\", ns: \"giftPurchaseIntents\", id: intent.id, attrs: { status: \"paid\", paidAt: now, claimId, updatedAt: now } },\n ];\n if (intent.purchaserApplicationId) ops.push({\n t: \"update\", ns: \"applications\", id: intent.purchaserApplicationId,\n attrs: { giftPaidAt: now, giftClaimId: claimId },\n });\n try {\n const result = await db.transact(ops, {\n mutationId: `gift-paid:${provider.eventId}`,\n guards: [{ ns: \"giftPurchaseIntents\", id: intent.id, exists: true, equals: { status: \"checkout_ready\" } }],\n });\n return { claimId, orderId, duplicate: result.duplicate };\n } catch {\n const raced = first((await db.query({ giftClaims: { $: { where: { intentId: intent.id }, limit: 1 } } })).giftClaims);\n if (raced) return { claimId: String(raced.id), orderId: String(raced.orderId), duplicate: true };\n throw new Error(\"gift issuance conflict\");\n }\n}\n\n/** Project claims for their buyer without code hashes or beneficiary PII. */\nexport function buyerGiftClaims(rows: readonly Row[], now: number): BuyerGiftClaim[] {\n return rows.map((row) => {\n const stored = String(row.status ?? \"pending\") as BuyerGiftClaim[\"status\"];\n const status = stored === \"pending\" && Number(row.codeExpiresAt) <= now ? \"expired\" : stored;\n return {\n id: String(row.id), offerId: String(row.offerId), status,\n createdAt: Number(row.createdAt), codeExpiresAt: Number(row.codeExpiresAt),\n ...(typeof row.redeemedAt === \"number\" ? { redeemedAt: row.redeemedAt } : {}),\n ...(typeof row.revokedAt === \"number\" ? { revokedAt: row.revokedAt } : {}),\n };\n });\n}\n\n/** Rotate only a pending unexpired claim with compare-and-set semantics. */\nexport async function rotateGiftClaim(db: ChapterDb, claim: Row, now: number): Promise<{ code: string } | null> {\n if (claim.status !== \"pending\" || Number(claim.codeExpiresAt) <= now) return null;\n const prepared = await prepareGiftCode(String(claim.chapterId));\n const currentRotation = Number(claim.rotationCount ?? 0);\n try {\n const write = await db.transact([{ t: \"update\", ns: \"giftClaims\", id: String(claim.id), attrs: {\n codeHash: prepared.codeHash, codeVersion: prepared.codeVersion, rotationCount: currentRotation + 1, codeIssuedAt: now,\n rotatedAt: now, attemptCount: 0, attemptWindowStartedAt: now,\n } }], {\n mutationId: `gift-rotate:${String(claim.id)}:${currentRotation + 1}`,\n guards: [{ ns: \"giftClaims\", id: String(claim.id), exists: true, equals: { status: \"pending\", rotationCount: currentRotation } }],\n });\n return write.duplicate ? null : { code: prepared.code };\n } catch {\n return null;\n }\n}\n\nexport interface RedeemGiftResult { kind: \"application\" | \"entitlement\"; id: string }\n\n/** Atomically consume one claim and bind its beneficiary application or entitlement. */\nexport async function redeemGiftClaim(\n db: ChapterDb,\n claim: Row,\n beneficiary: { email: string; userId: string },\n now: number,\n): Promise<RedeemGiftResult | null> {\n if (claim.status !== \"pending\" || Number(claim.codeExpiresAt) <= now) return null;\n const chapterId = String(claim.chapterId);\n const emailNormalized = normalizeChapterEmail(beneficiary.email);\n const target = claim.target as GiftOfferTarget;\n const ops: DbOp[] = [];\n let result: RedeemGiftResult;\n if (target.type === \"tier\") {\n const apps = (await db.query({ applications: { $: { where: { emailNormalized }, limit: 20 } } })).applications;\n const existing = apps?.filter((row) => row.groupId === chapterId)\n .sort((a, b) => Number(b.createdAt ?? 0) - Number(a.createdAt ?? 0))[0];\n const id = existing ? String(existing.id) : `gift-application:${String(claim.id)}`;\n const status = existing && existing.status !== \"submitted\" ? String(existing.status) : \"paid_pending_vetting\";\n ops.push({ t: \"update\", ns: \"applications\", id, attrs: {\n id, groupId: chapterId, email: beneficiary.email, emailNormalized, tierId: target.tierId,\n status, giftClaimId: String(claim.id), giftOrderId: String(claim.orderId),\n clerkUserId: beneficiary.userId, ...(existing ? {} : { createdAt: now }),\n } });\n result = { kind: \"application\", id };\n } else {\n const id = `gift-entitlement:${String(claim.id)}`;\n ops.push({ t: \"update\", ns: \"giftEntitlements\", id, attrs: {\n id, claimId: String(claim.id), orderId: String(claim.orderId), chapterId,\n entitlementKey: target.entitlementKey, beneficiaryEmailNormalized: emailNormalized,\n beneficiaryUserId: beneficiary.userId, active: true, createdAt: now,\n } });\n result = { kind: \"entitlement\", id };\n }\n ops.unshift({ t: \"update\", ns: \"giftClaims\", id: String(claim.id), attrs: {\n status: \"redeemed\", redeemedAt: now, beneficiaryEmailNormalized: emailNormalized,\n beneficiaryUserId: beneficiary.userId,\n ...(result.kind === \"application\" ? { applicationId: result.id } : { entitlementId: result.id }),\n attemptCount: Number(claim.attemptCount ?? 0) + 1,\n } });\n try {\n await db.transact(ops, {\n mutationId: `gift-redeem:${String(claim.id)}:${beneficiary.userId}`,\n guards: [{ ns: \"giftClaims\", id: String(claim.id), exists: true, equals: {\n status: \"pending\", codeVersion: Number(claim.codeVersion), codeHash: String(claim.codeHash),\n } }],\n });\n return result;\n } catch {\n return null;\n }\n}\n\n/** Revoke a claim and any redeemed access after provider refund or cancellation. */\nexport async function revokeGiftClaim(db: ChapterDb, claim: Row, reason: \"refunded\" | \"canceled\", now: number): Promise<boolean> {\n if (claim.status === \"revoked\") return false;\n const ops: DbOp[] = [{ t: \"update\", ns: \"giftClaims\", id: String(claim.id), attrs: {\n status: \"revoked\", revokedAt: now, revokedReason: reason,\n } }];\n if (claim.entitlementId) ops.push({ t: \"update\", ns: \"giftEntitlements\", id: String(claim.entitlementId), attrs: { active: false, revokedAt: now } });\n if (claim.applicationId) ops.push({ t: \"update\", ns: \"applications\", id: String(claim.applicationId), attrs: {\n giftRevokedAt: now, ...(reason === \"refunded\" ? { status: \"refunded\" } : { canceled: true }),\n } });\n try {\n await db.transact(ops, {\n mutationId: `gift-revoke:${String(claim.id)}:${reason}`,\n guards: [{ ns: \"giftClaims\", id: String(claim.id), exists: true, equals: { status: String(claim.status) } }],\n });\n return true;\n } catch {\n return false;\n }\n}\n","import { stripeCall } from \"./payments-stripe\";\nimport type { GiftIntentRow } from \"./gift-store\";\n\nexport interface GiftCheckoutResult {\n clientSecret: string;\n providerObjectId: string;\n customerId?: string;\n}\n\nconst clientSecret = (value: Record<string, unknown>): string | null => {\n const direct = value.client_secret;\n if (typeof direct === \"string\" && direct) return direct;\n const invoice = value.latest_invoice as Record<string, unknown> | undefined;\n const confirmation = invoice?.confirmation_secret as Record<string, unknown> | undefined;\n const intent = invoice?.payment_intent as Record<string, unknown> | undefined;\n const nested = confirmation?.client_secret ?? intent?.client_secret;\n return typeof nested === \"string\" && nested ? nested : null;\n};\n\n/** Create or idempotently recover Stripe checkout for one gift purchase intent. */\nexport async function startGiftProviderCheckout(\n secretKey: string,\n intent: GiftIntentRow,\n email: string,\n existingCustomerId?: string,\n): Promise<GiftCheckoutResult> {\n const offer = intent.offerSnapshot;\n const metadata = {\n giftIntentId: intent.id,\n chapterId: intent.chapterId,\n environment: intent.environment,\n offerId: intent.offerId,\n };\n let customerId = existingCustomerId;\n if (!customerId) {\n const customer = await stripeCall(secretKey, \"POST\", \"/v1/customers\", { email, metadata }, `gift-customer:${intent.id}`);\n if (!customer.ok) throw new Error(`gift customer create failed (${customer.status})`);\n customerId = String(customer.body.id);\n }\n if (offer.billingMode === \"subscription\") {\n const created = await stripeCall(secretKey, \"POST\", \"/v1/subscriptions\", {\n customer: customerId,\n \"items[0][price]\": offer.stripePriceId,\n payment_behavior: \"default_incomplete\",\n \"payment_settings[save_default_payment_method]\": \"on_subscription\",\n \"payment_settings[payment_method_types][0]\": \"card\",\n \"expand[0]\": \"latest_invoice.confirmation_secret\",\n metadata,\n }, `gift-subscription:${intent.id}`);\n const secret = created.ok ? clientSecret(created.body) : null;\n if (!created.ok || !secret) throw new Error(`gift subscription create failed (${created.status})`);\n return { clientSecret: secret, providerObjectId: String(created.body.id), customerId };\n }\n const price = await stripeCall(secretKey, \"GET\", `/v1/prices/${encodeURIComponent(offer.stripePriceId)}`);\n if (!price.ok || price.body.active === false || price.body.unit_amount !== offer.priceCents || price.body.currency !== offer.currency) {\n throw new Error(\"gift price does not match the signed offer\");\n }\n const created = await stripeCall(secretKey, \"POST\", \"/v1/payment_intents\", {\n customer: customerId,\n amount: offer.priceCents,\n currency: offer.currency,\n \"automatic_payment_methods[enabled]\": true,\n metadata,\n }, `gift-payment:${intent.id}`);\n const secret = created.ok ? clientSecret(created.body) : null;\n if (!created.ok || !secret) throw new Error(`gift payment create failed (${created.status})`);\n return { clientSecret: secret, providerObjectId: String(created.body.id), customerId };\n}\n","import type { GiftOffer } from \"./gift-offers\";\nimport { prepareGiftCode, type GiftIntentRow } from \"./gift-store\";\nimport { startGiftProviderCheckout } from \"./gift-checkout\";\nimport type { ChapterDb } from \"./types\";\n\nconst first = (value: unknown): Record<string, unknown> | undefined => Array.isArray(value) ? value[0] : undefined;\n\nexport interface StartGiftIntentInput {\n id: string;\n chapterId: string;\n environment: string;\n offer: GiftOffer;\n purchaserType: \"application\" | \"member\";\n purchaserEmail: string;\n purchaserEmailNormalized: string;\n purchaserApplicationId?: string;\n purchaserUserId?: string;\n existingCustomerId?: string;\n stripeSecret: string;\n publishableKey: string;\n now: number;\n}\n\nexport interface StartedGiftIntent {\n gift: true;\n intentId: string;\n clientSecret: string;\n publishableKey: string;\n lineItems: { standardCents: number; discountCents: number; dueTodayCents: number };\n giftCode?: string;\n}\n\n/** Persist hash-only intent state, then create an idempotent provider checkout. */\nexport async function startGiftIntent(db: ChapterDb, input: StartGiftIntentInput): Promise<StartedGiftIntent> {\n let stored = first((await db.query({ giftPurchaseIntents: { $: { where: { id: input.id }, limit: 1 } } })).giftPurchaseIntents);\n let giftCode: string | undefined;\n if (!stored) {\n const prepared = await prepareGiftCode(input.chapterId);\n const attrs = {\n id: input.id, chapterId: input.chapterId, environment: input.environment,\n purchaserType: input.purchaserType, purchaserEmailNormalized: input.purchaserEmailNormalized,\n ...(input.purchaserApplicationId ? { purchaserApplicationId: input.purchaserApplicationId } : {}),\n ...(input.purchaserUserId ? { purchaserUserId: input.purchaserUserId } : {}),\n offerId: input.offer.id, offerSnapshot: input.offer, status: \"created\",\n codeHash: prepared.codeHash, codeVersion: prepared.codeVersion, codeIssuedAt: input.now,\n createdAt: input.now, updatedAt: input.now,\n };\n const write = await db.transact([{ t: \"update\", ns: \"giftPurchaseIntents\", id: input.id, attrs }], {\n mutationId: `gift-intent:${input.id}`,\n });\n stored = write.duplicate\n ? first((await db.query({ giftPurchaseIntents: { $: { where: { id: input.id }, limit: 1 } } })).giftPurchaseIntents)\n : attrs;\n if (!write.duplicate) giftCode = prepared.code;\n }\n if (!stored || stored.chapterId !== input.chapterId || stored.environment !== input.environment ||\n stored.offerId !== input.offer.id || stored.purchaserEmailNormalized !== input.purchaserEmailNormalized) {\n throw new Error(\"gift purchase intent does not match this checkout\");\n }\n if (stored.status === \"paid\") throw new Error(\"gift purchase is already paid\");\n const checkout = await startGiftProviderCheckout(\n input.stripeSecret,\n stored as GiftIntentRow,\n input.purchaserEmail,\n typeof stored.providerCustomerId === \"string\" ? stored.providerCustomerId : input.existingCustomerId,\n );\n await db.transact([{ t: \"update\", ns: \"giftPurchaseIntents\", id: input.id, attrs: {\n status: \"checkout_ready\", providerObjectId: checkout.providerObjectId,\n ...(checkout.customerId ? { providerCustomerId: checkout.customerId } : {}),\n checkoutStartedAt: input.now, updatedAt: input.now,\n } }], { mutationId: `gift-checkout-ready:${input.id}:${checkout.providerObjectId}` });\n return {\n gift: true, intentId: input.id, clientSecret: checkout.clientSecret, publishableKey: input.publishableKey,\n lineItems: { standardCents: input.offer.priceCents, discountCents: 0, dueTodayCents: input.offer.priceCents },\n ...(giftCode ? { giftCode } : {}),\n };\n}\n","// Payment routes: POST /api/payments/subscription (start a founding-member\n// subscription), POST /api/webhooks/stripe (the AUTHORITATIVE writer of\n// paid/refunded/canceled, exactly-once per event id). Admin refund policy and\n// mechanics live in worker-routes-admin-lifecycle so exactly one built-in owns\n// that path. I/O only; the correctness rules live in ./payments and the provider\n// in ./payments-stripe.\nimport { getVaultSecret } from \"./auth\";\nimport { approveApplication } from \"./approve-application\";\nimport { crmDeps, syncApplicationToCrm } from \"./crm-sync\";\nimport { emailGroupFrom, sendTemplated } from \"./notify\";\nimport { canceledPatch, firstPaymentPatch, refundedPatch, renewalPatch, webhookMutationId } from \"./payments\";\nimport type { WebhookEvent } from \"./payments\";\nimport { createStripeProvider } from \"./payments-stripe\";\nimport { findTier, tierIsFree } from \"./tiers\";\nimport { loadTiers } from \"./tiers-store\";\nimport { loadActiveSignupControl } from \"./signup-control-store\";\nimport { findGiftOffer } from \"./gift-offers\";\nimport { normalizeChapterEmail } from \"./email-identity\";\nimport { startGiftIntent } from \"./gift-intents\";\nimport { issueGiftClaim, revokeGiftClaim, type GiftIntentRow } from \"./gift-store\";\nimport { json } from \"./worker-context\";\nimport type { ChapterEnv, WorkerContext } from \"./worker-context\";\nimport type { Route } from \"./worker-routes\";\nimport type { ChapterDb } from \"./types\";\n\ntype Row = Record<string, unknown>;\n\nconst codeOf = (err: unknown): string =>\n err && typeof err === \"object\" && typeof (err as { code?: unknown }).code === \"string\" ? (err as { code: string }).code : \"unknown\";\n\nasync function firstRow(db: ChapterDb, ns: string, q: Record<string, unknown>): Promise<Row | undefined> {\n const res = await db.query({ [ns]: { $: q } });\n const rows = res[ns];\n return Array.isArray(rows) ? rows[0] : undefined;\n}\n\nfunction lineItems(group: Row): { standardCents: number; discountCents: number; dueTodayCents: number } {\n const standard = Number(group.standardPriceCents ?? 0);\n const discount = Number(group.foundingDiscountCents ?? 0);\n return { standardCents: standard, discountCents: discount, dueTodayCents: standard - discount };\n}\n\n// Resolve the application an event targets: by metadata applicationId, else the\n// newest row for the Stripe customer.\nasync function findApplication(db: ChapterDb, event: WebhookEvent): Promise<Row | undefined> {\n if (\"applicationId\" in event && event.applicationId) {\n return firstRow(db, \"applications\", { where: { id: event.applicationId }, limit: 1 });\n }\n if (\"customerId\" in event && event.customerId) {\n return firstRow(db, \"applications\", { where: { stripeCustomerId: event.customerId }, order: { createdAt: \"desc\" }, limit: 1 });\n }\n return undefined;\n}\n\n// Best-effort payment-confirmation to the applicant on the first successful\n// invoice. Exactly-once per Stripe event via the dedupeKey.\nasync function notifyPaymentConfirmed(db: ChapterDb, env: ChapterEnv, eventId: string, app: Row): Promise<void> {\n try {\n if (typeof app.email !== \"string\" || !app.email) return;\n const group = await firstRow(db, \"groups\", { where: { id: String(app.groupId ?? \"\") }, limit: 1 });\n if (!group) return;\n await sendTemplated(\n { db, envName: env.ODLA_ENV, sender: env.SEND_EMAIL, from: env.EMAIL_FROM, now: () => Date.now(), newId: () => crypto.randomUUID() },\n {\n group: emailGroupFrom(group),\n template: \"paymentConfirmation\",\n to: app.email,\n vars: { firstName: typeof app.firstName === \"string\" ? app.firstName : \"\" },\n dedupeKey: `${eventId}:confirm`,\n applicationId: String(app.id),\n },\n );\n } catch {\n // never let a confirmation-email failure affect the webhook 200\n }\n}\n\n// Best-effort admin notification at PAYMENT time — the alternative trigger to\n// notifying on submit (sends.adminNotification: \"payment\"). Same template, same\n// exactly-once dedupe, different moment.\nasync function notifyAdminOfPayment(db: ChapterDb, env: ChapterEnv, eventId: string, app: Row): Promise<void> {\n try {\n const group = await firstRow(db, \"groups\", { where: { id: String(app.groupId ?? \"\") }, limit: 1 });\n if (!group || typeof group.notificationEmail !== \"string\" || !group.notificationEmail) return;\n const s = (v: unknown): string => (typeof v === \"string\" ? v : \"\");\n await sendTemplated(\n { db, envName: env.ODLA_ENV, sender: env.SEND_EMAIL, from: env.EMAIL_FROM, now: () => Date.now(), newId: () => crypto.randomUUID() },\n {\n group: emailGroupFrom(group),\n template: \"adminNotification\",\n to: group.notificationEmail,\n vars: { firstName: s(app.firstName), lastName: s(app.lastName), email: s(app.email), phone: s(app.phone), state: s(app.state) },\n dedupeKey: `${eventId}:admin`,\n applicationId: String(app.id),\n },\n );\n } catch {\n // never let a notification failure affect the webhook 200\n }\n}\n\n// The application-row patch for a resolved event (empty = skip the write).\nfunction webhookPatch(event: WebhookEvent, status: string): Record<string, unknown> {\n switch (event.kind) {\n case \"first_payment\":\n return firstPaymentPatch(status, event.renewalAt);\n case \"renewal\":\n return event.renewalAt !== undefined ? renewalPatch(event.renewalAt) : {};\n case \"refunded\":\n return refundedPatch();\n case \"canceled\":\n return canceledPatch();\n default:\n return {};\n }\n}\n\nasync function startSubscription(req: Request, env: ChapterEnv, ctx: WorkerContext): Promise<Response> {\n let body: Row;\n try {\n body = JSON.parse(await req.text()) as Row;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n const applicationId = typeof body.applicationId === \"string\" ? body.applicationId : \"\";\n if (!applicationId) return json({ error: \"applicationId required\" }, 400);\n if (body.refundPolicyAck !== true) return json({ error: \"refundPolicyAck required\" }, 400);\n\n const db = ctx.makeDb(env) as unknown as ChapterDb;\n const app = await firstRow(db, \"applications\", { where: { id: applicationId }, limit: 1 });\n if (!app) return json({ error: \"not found\" }, 404);\n // Single-charge guard: only from the initial state, so a re-post can't double-subscribe.\n if (app.status !== \"submitted\") return json({ error: \"already processed\" }, 409);\n\n const group = await firstRow(db, \"groups\", { where: { id: String(app.groupId ?? ctx.chapter.id) }, limit: 1 });\n const secretKey = await getVaultSecret(db, \"stripe_secret_key\");\n if (!group || !secretKey) return json({ error: \"payments not configured\" }, 503);\n if (typeof app.giftOfferId === \"string\") {\n const control = await loadActiveSignupControl(db, ctx.chapter.id, env.ODLA_ENV);\n const offer = findGiftOffer(control?.document.giftOffers, app.giftOfferId, Date.now());\n if (!offer || typeof group.stripePublishableKey !== \"string\" || !group.stripePublishableKey) {\n return json({ error: \"gift offer is unavailable\" }, 409);\n }\n try {\n const started = await startGiftIntent(db, {\n id: typeof app.giftIntentId === \"string\" ? app.giftIntentId : `gift-intent:${applicationId}`,\n chapterId: ctx.chapter.id, environment: env.ODLA_ENV, offer,\n purchaserType: \"application\", purchaserEmail: String(app.email ?? \"\"),\n purchaserEmailNormalized: normalizeChapterEmail(String(app.email ?? \"\")),\n purchaserApplicationId: applicationId, stripeSecret: secretKey,\n publishableKey: group.stripePublishableKey, now: Date.now(),\n });\n await db.transact([{ t: \"update\", ns: \"applications\", id: applicationId, attrs: {\n giftIntentId: started.intentId, giftCheckoutStartedAt: Date.now(), refundPolicyAckAt: Date.now(),\n } }]);\n return json(started);\n } catch (error) {\n return json({ error: error instanceof Error ? error.message : \"gift checkout failed\" }, 502);\n }\n }\n // The price comes from the tier the applicant chose, not the group, so a\n // chapter offering several tiers cannot charge everyone the first one.\n const tier = findTier(\n await loadTiers(db, group as never),\n typeof app.tierId === \"string\" ? app.tierId : null,\n );\n if (!tier) return json({ error: \"tier not found\", code: \"tier_unresolved\" }, 400);\n // A free tier has nothing to charge. Reaching checkout on one is a client\n // bug, and silently creating a zero subscription would hide it.\n if (tierIsFree(tier)) return json({ error: \"tier is free\", code: \"tier_not_payable\" }, 409);\n const priceId = tier.stripePriceId;\n if (!priceId) return json({ error: \"payments not configured\" }, 503);\n\n const provider = createStripeProvider({ secretKey });\n let result;\n try {\n result = await provider.createSubscription({\n applicationId,\n groupId: String(group.id),\n email: String(app.email ?? \"\"),\n name: `${app.firstName ?? \"\"} ${app.lastName ?? \"\"}`.trim(),\n priceId: String(priceId),\n existingCustomerId: typeof app.stripeCustomerId === \"string\" ? app.stripeCustomerId : undefined,\n });\n } catch (err) {\n return json({ error: \"payment setup failed\", code: codeOf(err) }, 502);\n }\n\n await db.transact([\n {\n t: \"update\",\n ns: \"applications\",\n id: applicationId,\n attrs: { stripeCustomerId: result.customerId, stripeSubscriptionId: result.subscriptionId, refundPolicyAckAt: Date.now() },\n },\n ]);\n return json({ clientSecret: result.clientSecret, publishableKey: group.stripePublishableKey ?? null, lineItems: lineItems(group) });\n}\n\nasync function ingestWebhook(req: Request, env: ChapterEnv, ctx: WorkerContext): Promise<Response> {\n const db = ctx.makeDb(env) as unknown as ChapterDb;\n const webhookSecret = await getVaultSecret(db, \"stripe_webhook_secret\");\n if (!webhookSecret) return json({ error: \"webhook not configured\" }, 503);\n\n const rawBody = await req.text();\n const ingest = await createStripeProvider({ webhookSecret }).ingestWebhook(rawBody, req.headers.get(\"stripe-signature\") ?? \"\");\n if (!ingest.ok) return json({ error: \"invalid signature\" }, 400);\n const { eventId, event } = ingest;\n if (event.kind === \"ignored\") return json({ ok: true, ignored: event.type });\n\n if (event.kind === \"gift_paid\" || event.kind === \"gift_revoked\") {\n const intent = await firstRow(db, \"giftPurchaseIntents\", { where: { id: event.giftIntentId }, limit: 1 });\n if (!intent || intent.chapterId !== ctx.chapter.id || intent.environment !== env.ODLA_ENV) {\n return json({ ok: true, matched: false });\n }\n if (event.kind === \"gift_paid\") {\n if (intent.providerObjectId !== event.providerObjectId) return json({ ok: true, matched: false });\n if (intent.status === \"refunded\" || intent.status === \"canceled\") return json({ ok: true, matched: false });\n try {\n const issued = await issueGiftClaim(db, intent as GiftIntentRow, {\n eventId, objectId: event.providerObjectId,\n }, Date.now());\n return json({ ok: true, matched: true, claimId: issued.claimId });\n } catch {\n return json({ error: \"gift issuance failed\" }, 503);\n }\n }\n await db.transact([{ t: \"update\", ns: \"giftPurchaseIntents\", id: event.giftIntentId, attrs: {\n status: event.reason, updatedAt: Date.now(),\n } }], { mutationId: `gift-revoked-intent:${eventId}` });\n const claim = await firstRow(db, \"giftClaims\", { where: { intentId: event.giftIntentId }, limit: 1 });\n if (claim) await revokeGiftClaim(db, claim, event.reason, Date.now());\n return json({ ok: true, matched: Boolean(claim) });\n }\n\n const app = await findApplication(db, event);\n if (!app) return json({ ok: true, matched: false });\n\n const patch = webhookPatch(event, String(app.status ?? \"\"));\n let next = app;\n if (Object.keys(patch).length) {\n await db.transact([{ t: \"update\", ns: \"applications\", id: String(app.id), attrs: patch }], { mutationId: webhookMutationId(eventId) });\n // Payment is one of the two status transitions that happen with no admin\n // present, so without this the console's pipeline (which reads\n // crm_record.stage) shows every paying member as still unpaid. Also\n // refreshes the billing snapshot on a renewal, which carries no status\n // change. Best-effort: Stripe retries a failed webhook, and re-charging is\n // a far worse outcome than a stale mirror the next sync repairs.\n next = { ...app, ...patch };\n await syncApplicationToCrm(crmDeps(db, ctx), { app: next, stage: String(next.status ?? \"\") }).catch(() => undefined);\n }\n if (event.kind === \"first_payment\") {\n await notifyPaymentConfirmed(db, env, eventId, app);\n if (ctx.chapter.sends.adminNotification === \"payment\") await notifyAdminOfPayment(db, env, eventId, app);\n if (typeof next.interviewWaivedAt === \"number\") {\n await approveApplication({\n db,\n env,\n ctx,\n app: next,\n origin: new URL(req.url).origin,\n reason: \"interview_waiver\",\n });\n }\n }\n return json({ ok: true });\n}\n\n/** The payment routes (chapter mode). Webhook + subscription are public and\n * capability-guarded by the unguessable application id / signed payload. */\nexport const handlePayments: Route = async (req, url, env, ctx) => {\n if (ctx.chapter.mode !== \"chapter\") return null;\n if (req.method === \"POST\" && url.pathname === \"/api/payments/subscription\") return startSubscription(req, env, ctx);\n if (req.method === \"POST\" && url.pathname === \"/api/webhooks/stripe\") return ingestWebhook(req, env, ctx);\n return null;\n};\n","import { getVaultSecret } from \"./auth\";\nimport { normalizeChapterEmail } from \"./email-identity\";\nimport { findGiftOffer, publicGiftOffers } from \"./gift-offers\";\nimport { giftRequesterBucket, hashGiftCode } from \"./gift-codes\";\nimport { startGiftIntent } from \"./gift-intents\";\nimport { buyerGiftClaims, redeemGiftClaim, rotateGiftClaim } from \"./gift-store\";\nimport { loadActiveSignupControl } from \"./signup-control-store\";\nimport { json } from \"./worker-context\";\nimport type { ChapterDb } from \"./types\";\nimport type { Route } from \"./worker-context\";\n\nconst first = (value: unknown): Record<string, unknown> | undefined => Array.isArray(value) ? value[0] : undefined;\nconst rows = (value: unknown): Array<Record<string, unknown>> => Array.isArray(value) ? value : [];\nconst invalid = () => json({ error: \"gift code is invalid or unavailable\" }, 400);\nconst userFor = async (req: Request, env: Parameters<Route>[2], ctx: Parameters<Route>[3]) => {\n const user = await ctx.verifyUser(req, env);\n return user?.email ? user : null;\n};\nconst loadClaim = async (db: ChapterDb, id: string) =>\n first((await db.query({ giftClaims: { $: { where: { id }, limit: 1 } } })).giftClaims);\n\nasync function consumeRateLimit(db: ChapterDb, chapterId: string, requester: string, now: number): Promise<boolean> {\n const bucket = await giftRequesterBucket(chapterId, requester);\n const id = `gift-rate:${chapterId}:${bucket}`;\n const current = first((await db.query({ giftRedemptionAttempts: { $: { where: { id }, limit: 1 } } })).giftRedemptionAttempts);\n const within = Boolean(current && now - Number(current.windowStartedAt) < 15 * 60_000);\n const attemptCount = within ? Number(current?.attemptCount ?? 0) + 1 : 1;\n if (attemptCount > 10) return false;\n await db.transact([{ t: \"update\", ns: \"giftRedemptionAttempts\", id, attrs: {\n id, chapterId, bucket, attemptCount, windowStartedAt: within ? Number(current?.windowStartedAt) : now, updatedAt: now,\n } }]);\n return true;\n}\n\n/** Authenticated buyer checkout/list/rotation and beneficiary redemption routes. */\nexport const handleGifts: Route = async (req, url, env, ctx) => {\n if (ctx.chapter.mode !== \"chapter\" || !url.pathname.startsWith(\"/api/gifts\")) return null;\n const db = ctx.makeDb(env) as unknown as ChapterDb;\n if (req.method === \"GET\" && url.pathname === \"/api/gifts\") {\n const user = await userFor(req, env, ctx);\n if (!user) return json({ error: \"unauthorized\" }, 401);\n const control = await loadActiveSignupControl(db, ctx.chapter.id, env.ODLA_ENV);\n const found = await db.query({ giftClaims: { $: { where: {\n purchaserEmailNormalized: normalizeChapterEmail(user.email!), chapterId: ctx.chapter.id,\n }, limit: 200 } } });\n const group = first((await db.query({ groups: { $: { where: { id: ctx.chapter.id }, limit: 1 } } })).groups);\n return json({\n offers: publicGiftOffers(control?.document.giftOffers, Date.now()),\n claims: buyerGiftClaims(rows(found.giftClaims).sort((a, b) => Number(b.createdAt) - Number(a.createdAt)), Date.now()),\n refundPolicyText: typeof group?.refundPolicyText === \"string\" ? group.refundPolicyText : \"\",\n });\n }\n if (req.method === \"POST\" && url.pathname === \"/api/gifts/checkout\") {\n const user = await userFor(req, env, ctx);\n if (!user) return json({ error: \"unauthorized\" }, 401);\n let body: Record<string, unknown>;\n try { body = JSON.parse(await req.text()) as Record<string, unknown>; }\n catch { return json({ error: \"invalid JSON body\" }, 400); }\n const purchaseId = typeof body.purchaseId === \"string\" ? body.purchaseId : \"\";\n if (!/^[A-Za-z0-9_-]{16,128}$/.test(purchaseId)) return json({ error: \"purchaseId is invalid\" }, 400);\n const control = await loadActiveSignupControl(db, ctx.chapter.id, env.ODLA_ENV);\n const offer = findGiftOffer(control?.document.giftOffers, typeof body.offerId === \"string\" ? body.offerId : \"\", Date.now());\n if (!offer) return json({ error: \"gift offer is unavailable\" }, 409);\n const group = first((await db.query({ groups: { $: { where: { id: ctx.chapter.id }, limit: 1 } } })).groups);\n const stripeSecret = await getVaultSecret(db, \"stripe_secret_key\");\n if (!group || !stripeSecret || typeof group.stripePublishableKey !== \"string\") return json({ error: \"payments not configured\" }, 503);\n const emailNormalized = normalizeChapterEmail(user.email!);\n const applications = rows((await db.query({ applications: { $: { where: { emailNormalized }, limit: 20 } } })).applications);\n const app = applications.sort((a, b) => Number(b.createdAt ?? 0) - Number(a.createdAt ?? 0))[0];\n try {\n return json(await startGiftIntent(db, {\n id: `gift-intent:${ctx.chapter.id}:${purchaseId}`, chapterId: ctx.chapter.id,\n environment: env.ODLA_ENV, offer, purchaserType: \"member\", purchaserEmail: user.email!,\n purchaserEmailNormalized: emailNormalized, purchaserUserId: user.userId,\n ...(typeof app?.stripeCustomerId === \"string\" ? { existingCustomerId: app.stripeCustomerId } : {}),\n stripeSecret, publishableKey: group.stripePublishableKey, now: Date.now(),\n }));\n } catch (error) {\n return json({ error: error instanceof Error ? error.message : \"gift checkout failed\" }, 502);\n }\n }\n const rotateMatch = url.pathname.match(/^\\/api\\/gifts\\/([^/]+)\\/rotate$/);\n if (req.method === \"POST\" && rotateMatch) {\n let claimId = \"\";\n try { claimId = decodeURIComponent(rotateMatch[1] as string); } catch { return invalid(); }\n if (!claimId.startsWith(\"gift-claim:\")) return invalid();\n const claim = await loadClaim(db, claimId);\n if (!claim || claim.chapterId !== ctx.chapter.id || Number(claim.rotationCount ?? 0) >= 10) return invalid();\n const user = await userFor(req, env, ctx);\n let applicationId = \"\";\n if (!user) {\n try { applicationId = String((JSON.parse(await req.text()) as Record<string, unknown>).applicationId ?? \"\"); }\n catch { return invalid(); }\n }\n const owns = user\n ? claim.purchaserEmailNormalized === normalizeChapterEmail(user.email!)\n : claim.purchaserApplicationId === applicationId;\n if (!owns) return invalid();\n const rotated = await rotateGiftClaim(db, claim, Date.now());\n return rotated ? json(rotated) : invalid();\n }\n if (req.method === \"POST\" && url.pathname === \"/api/gifts/redeem\") {\n const user = await userFor(req, env, ctx);\n if (!user) return json({ error: \"unauthorized\" }, 401);\n const now = Date.now();\n if (!await consumeRateLimit(db, ctx.chapter.id, `${user.userId}:${req.headers.get(\"cf-connecting-ip\") ?? \"no-ip\"}`, now)) {\n return json({ error: \"too many attempts\" }, 429);\n }\n let code = \"\";\n try { code = String((JSON.parse(await req.text()) as Record<string, unknown>).code ?? \"\").trim(); }\n catch { return invalid(); }\n if (!/^gift1_[A-Za-z0-9_-]{43}$/.test(code)) return invalid();\n const codeHash = await hashGiftCode(ctx.chapter.id, code);\n const claim = first((await db.query({ giftClaims: { $: { where: { codeHash }, limit: 1 } } })).giftClaims);\n if (!claim || claim.chapterId !== ctx.chapter.id) return invalid();\n if (claim.status !== \"pending\" || Number(claim.codeExpiresAt) <= now) {\n await db.transact([{ t: \"update\", ns: \"giftClaims\", id: String(claim.id), attrs: {\n attemptCount: Number(claim.attemptCount ?? 0) + 1,\n ...(claim.status === \"pending\" ? { status: \"expired\" } : {}),\n } }]).catch(() => undefined);\n return invalid();\n }\n const redeemed = await redeemGiftClaim(db, claim, { email: user.email!, userId: user.userId }, now);\n return redeemed ? json({ ok: true, ...redeemed }) : invalid();\n }\n return null;\n};\n","// Admin operational routes. GET /api/admin/meetings is the admin agenda,\n// reconciled against the live platform calendar: it reads upcoming events through\n// @odla-ai/calendar (chapter never calls Google directly) and adopts any\n// owner-side move/cancel onto the canonical meetings row + the application\n// projection, via the pure ./reconcile logic. Admin-gated; the read still\n// succeeds (serving canonical rows) if the calendar is unavailable.\nimport { initCalendar } from \"@odla-ai/calendar\";\nimport { reconcileMeetings } from \"./reconcile\";\nimport type { LiveEvent, MeetingForReconcile, ReconcileDecision } from \"./reconcile\";\nimport { resolveScheduling, validateScheduling } from \"./scheduling\";\nimport { json } from \"./worker-context\";\nimport type { ChapterEnv, WorkerContext } from \"./worker-context\";\nimport type { Route } from \"./worker-routes\";\nimport type { ChapterDb, ChapterScheduling, DbOp } from \"./types\";\n\n// Load the admin's target group (query param `group`, else the chapter), gated on\n// an admin session. Returns [db, group] or a Response to short-circuit.\nasync function adminGroup(\n req: Request,\n env: ChapterEnv,\n ctx: WorkerContext,\n url: URL,\n): Promise<{ db: ChapterDb; group: Record<string, unknown> } | Response> {\n const rawDb = ctx.makeDb(env);\n const u = await ctx.verifyUser(req, env);\n if (!u) return json({ error: \"unauthorized\" }, 401);\n if (!(await ctx.isAdmin(rawDb, u))) return json({ error: \"forbidden\" }, 403);\n const db = rawDb as unknown as ChapterDb;\n const groupId = url.searchParams.get(\"group\") ?? ctx.chapter.id;\n const group = (await db.query({ groups: { $: { where: { id: groupId }, limit: 1 } } })).groups?.[0];\n if (!group) return json({ error: \"not found\" }, 404);\n return { db, group };\n}\n\n/** GET/PUT /api/admin/scheduling — read the group's booking rules, or replace\n * them (validated via resolveScheduling; a bad config is a 400, never persisted).\n * The backend for the availability-editor section. */\nexport const handleAdminScheduling: Route = async (req, url, env, ctx) => {\n if (url.pathname !== \"/api/admin/scheduling\" || (req.method !== \"GET\" && req.method !== \"PUT\")) return null;\n const got = await adminGroup(req, env, ctx, url);\n if (got instanceof Response) return got;\n const { db, group } = got;\n\n if (req.method === \"GET\") {\n return json({ scheduling: resolveScheduling(group.schedulingJson as ChapterScheduling | undefined) });\n }\n let body: unknown;\n try {\n body = JSON.parse(await req.text());\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n // Field-keyed messages, not a thrown string: an owner-facing settings form needs\n // to say which field is wrong and why.\n const checked = validateScheduling(body as ChapterScheduling);\n if (!checked.ok) return json({ error: \"invalid scheduling config\", errors: checked.errors }, 400);\n await db.transact([{ t: \"update\", ns: \"groups\", id: String(group.id), attrs: { schedulingJson: checked.value } }]);\n return json({ scheduling: checked.value });\n};\n\nasync function upcomingEvents(env: ChapterEnv): Promise<LiveEvent[]> {\n const cal = initCalendar({ appId: env.ODLA_APP_ID, env: env.ODLA_ENV, adminToken: env.ODLA_API_KEY, endpoint: env.ODLA_PLATFORM });\n const res = await cal.availability.upcoming();\n return res.events.map((e) => ({ eventId: e.eventId, status: e.status, startAt: e.startAt, endAt: e.endAt }));\n}\n\nfunction toReconcile(rows: Array<Record<string, unknown>>): MeetingForReconcile[] {\n return rows.map((m) => ({\n id: String(m.id),\n applicationId: String(m.applicationId),\n googleEventId: typeof m.googleEventId === \"string\" ? m.googleEventId : null,\n status: String(m.status ?? \"\"),\n startAt: typeof m.startAt === \"number\" ? m.startAt : null,\n endAt: typeof m.endAt === \"number\" ? m.endAt : null,\n }));\n}\n\n/** GET /api/admin/meetings — the scheduled agenda, reconciled against the live\n * calendar (adopts owner moves/cancellations onto the canonical rows). */\nexport const handleAdminMeetings: Route = async (req, url, env, ctx) => {\n if (req.method !== \"GET\" || url.pathname !== \"/api/admin/meetings\") return null;\n const rawDb = ctx.makeDb(env);\n const u = await ctx.verifyUser(req, env);\n if (!u) return json({ error: \"unauthorized\" }, 401);\n if (!(await ctx.isAdmin(rawDb, u))) return json({ error: \"forbidden\" }, 403);\n const db = rawDb as unknown as ChapterDb;\n\n // ?all=1 includes cancelled/past rows; from/to bound the window (epoch ms).\n const all = url.searchParams.get(\"all\") === \"1\";\n const from = Number(url.searchParams.get(\"from\"));\n const to = Number(url.searchParams.get(\"to\"));\n\n const query = await db.query({\n meetings: { $: { where: all ? {} : { status: \"scheduled\" }, order: { startAt: \"asc\" }, limit: 500 } },\n });\n let rows = (Array.isArray(query.meetings) ? query.meetings : []) as Array<Record<string, unknown>>;\n if (Number.isFinite(from)) rows = rows.filter((m) => Number(m.startAt ?? 0) >= from);\n if (Number.isFinite(to)) rows = rows.filter((m) => Number(m.startAt ?? 0) <= to);\n\n let decisions: ReconcileDecision[] = [];\n try {\n decisions = reconcileMeetings(toReconcile(rows), await upcomingEvents(env), Date.now());\n } catch {\n // Calendar unavailable — serve the canonical rows without adopting edits.\n }\n\n // Apply adopt decisions (best-effort; the read still succeeds if a write fails).\n const patched = new Map<string, Record<string, unknown>>();\n for (const d of decisions) {\n const ops: DbOp[] = [\n { t: \"update\", ns: \"meetings\", id: d.meetingId, attrs: d.meetingPatch },\n { t: \"update\", ns: \"applications\", id: d.applicationId, attrs: d.applicationPatch },\n ];\n try {\n await db.transact(ops);\n patched.set(d.meetingId, d.meetingPatch);\n } catch {\n // leave the row as-is if the write fails\n }\n }\n\n // Join the applicant onto each row, and return the group timezone, so an admin\n // console can label and render the agenda without a second round trip. One\n // query, indexed by id — not N+1.\n const appQuery = await db.query({ applications: { $: { limit: 1000 } } });\n const byId = new Map<string, Record<string, unknown>>();\n for (const a of Array.isArray(appQuery.applications) ? appQuery.applications : []) {\n byId.set(String(a.id), a);\n }\n const applicantOf = (m: Record<string, unknown>): Record<string, unknown> | null => {\n const a = byId.get(String(m.applicationId));\n if (!a) return null;\n return { id: a.id, firstName: a.firstName, lastName: a.lastName, email: a.email, status: a.status };\n };\n\n const group = (await db.query({ groups: { $: { where: { id: ctx.chapter.id }, limit: 1 } } })).groups?.[0];\n const timezone = resolveScheduling(group?.schedulingJson as ChapterScheduling | undefined).timezone;\n\n // Reflect adopted patches; the row carries drift (drift, driftGoogleStartAt,\n // adoptedFromGoogleAt) and the Meet/Calendar links (meetUrl, htmlLink) already.\n const meetings = rows\n .map((m): Record<string, unknown> => ({ ...m, ...(patched.get(String(m.id)) ?? {}), applicant: applicantOf(m) }))\n .filter((m) => all || m.status === \"scheduled\");\n return json({ meetings, adopted: decisions.length, timezone });\n};\n","// The Google → chapter half of the bidirectional calendar sync. Booking writes\n// events TO the platform calendar (0.4.0's create/reschedule); this ADOPTS edits\n// FROM it: when the owner moves or cancels the intro call directly in Google,\n// reconcile mirrors that onto our canonical `meetings` row and the `application`\n// projection. Chapter never calls Google — the worker reads live events through\n// @odla-ai/calendar's upcoming() (platform-brokered) and applies the ops this\n// returns. Pure + testable; adoption policy (owner edits win) matches the shipped\n// original production worker.\n\n/** A `meetings` row, as far as reconciliation cares. */\nexport interface MeetingForReconcile {\n id: string;\n applicationId: string;\n googleEventId?: string | null;\n status: string;\n startAt?: number | null;\n endAt?: number | null;\n}\n\n/** One live calendar event (a subset of @odla-ai/calendar's Booking). */\nexport interface LiveEvent {\n eventId: string;\n status?: string;\n startAt?: number;\n endAt?: number;\n}\n\n/** An adopt decision: mirror a Google move/cancel onto our rows. */\nexport interface ReconcileDecision {\n meetingId: string;\n applicationId: string;\n kind: \"cancelled\" | \"moved\";\n /** Attrs to write onto the `meetings` row. */\n meetingPatch: Record<string, unknown>;\n /** Attrs to write onto the `applications` row (the projection). */\n applicationPatch: Record<string, unknown>;\n}\n\n/** Meetings still worth reconciling: a scheduled booking with a Google event that\n * starts in the future (or within the last hour, to catch a just-passed edit). */\nexport function isReconcilable(meeting: MeetingForReconcile, now: number): boolean {\n return meeting.status === \"scheduled\" && Boolean(meeting.googleEventId) && (meeting.startAt ?? 0) > now - 3_600_000;\n}\n\n/**\n * Diff canonical `meetings` against the live calendar events and return the adopt\n * decisions — only for meetings that actually changed (a still-matching meeting\n * is omitted). A meeting whose event vanished or is `cancelled` in Google is\n * adopted as cancelled (application `meetingAt` zeroed — 0 means \"was booked,\n * then cancelled\"); a meeting whose event moved adopts the new window (duration\n * preserved when the event omits `endAt`).\n */\nexport function reconcileMeetings(\n meetings: readonly MeetingForReconcile[],\n events: readonly LiveEvent[],\n now: number,\n): ReconcileDecision[] {\n const byEvent = new Map(events.map((e) => [e.eventId, e]));\n const decisions: ReconcileDecision[] = [];\n for (const m of meetings) {\n if (!isReconcilable(m, now) || !m.googleEventId) continue;\n const g = byEvent.get(m.googleEventId);\n if (!g || g.status === \"cancelled\") {\n decisions.push({\n meetingId: m.id,\n applicationId: m.applicationId,\n kind: \"cancelled\",\n meetingPatch: { status: \"cancelled\", drift: \"none\", adoptedFromGoogleAt: now },\n applicationPatch: { meetingAt: 0, meetingLink: \"\" },\n });\n } else if (g.startAt !== undefined && g.startAt !== m.startAt) {\n const duration = (m.endAt ?? 0) - (m.startAt ?? 0);\n decisions.push({\n meetingId: m.id,\n applicationId: m.applicationId,\n kind: \"moved\",\n meetingPatch: { startAt: g.startAt, endAt: g.endAt ?? g.startAt + duration, drift: \"none\", adoptedFromGoogleAt: now },\n applicationPatch: { meetingAt: g.startAt },\n });\n }\n }\n return decisions;\n}\n","// Admin roster + identity routes: the union people list, one person's access,\n// role changes, and the CRM backfill. Role changes wire chapter's package-\n// enforced canChangeRole guard (super-admin tier + self-demotion lockout) rather\n// than re-deriving the rules per site. All admin-gated.\nimport { canChangeRole, getVaultSecret } from \"./auth\";\nimport { clerkGetUser, clerkListUsers, clerkSetRole } from \"./clerk-roles\";\nimport { backfillCrm } from \"./crm-sync\";\nimport { applicationSummary } from \"./session\";\nimport { json } from \"./worker-context\";\nimport type { ChapterEnv, WorkerContext } from \"./worker-context\";\nimport type { Route } from \"./worker-routes\";\nimport type { ChapterDb } from \"./types\";\n\n// Gate + shape the verified admin identity. Returns { db, actor } or a Response.\nasync function adminGate(\n req: Request,\n env: ChapterEnv,\n ctx: WorkerContext,\n): Promise<{ db: ChapterDb; actor: { userId: string; email?: string } } | Response> {\n const rawDb = ctx.makeDb(env);\n const u = await ctx.verifyUser(req, env);\n if (!u) return json({ error: \"unauthorized\" }, 401);\n if (!(await ctx.isAdmin(rawDb, u))) return json({ error: \"forbidden\" }, 403);\n return { db: rawDb as unknown as ChapterDb, actor: { userId: u.userId, email: u.email ?? undefined } };\n}\n\nconst crmDeps = (db: ChapterDb, ctx: WorkerContext) => ({\n crm: ctx.chapter.crm,\n db,\n now: () => Date.now(),\n newId: () => crypto.randomUUID(),\n chapter: ctx.chapter,\n});\n\n/** POST /api/admin/crm/sync — backfill/reproject every person into the CRM.\n * Idempotent by email, so it doubles as migration and repair. */\nexport const handleAdminCrmSync: Route = async (req, url, env, ctx) => {\n if (req.method !== \"POST\" || url.pathname !== \"/api/admin/crm/sync\") return null;\n const gate = await adminGate(req, env, ctx);\n if (gate instanceof Response) return gate;\n const result = await backfillCrm(crmDeps(gate.db, ctx));\n return json({ ok: true, ...result });\n};\n\n/** GET /api/admin/people — one row per person, joined by lowercased email: the\n * `$users` mirror (accounts), applications (pipeline), and Clerk roles.\n * Applications first (newest on top), account-only rows after. */\nexport const handleAdminPeople: Route = async (req, url, env, ctx) => {\n if (req.method !== \"GET\" || url.pathname !== \"/api/admin/people\") return null;\n const gate = await adminGate(req, env, ctx);\n if (gate instanceof Response) return gate;\n const { db } = gate;\n\n const sk = await getVaultSecret(db, \"clerk_secret_key\");\n const [data, roleList] = await Promise.all([\n db.query({\n applications: { $: { order: { createdAt: \"desc\" }, limit: 200 } },\n $users: { $: { limit: 200 } },\n }),\n sk ? clerkListUsers(sk).catch(() => []) : Promise.resolve([]),\n ]);\n const clerkByUserId = new Map(roleList.map((u) => [u.id, u]));\n\n type PersonRow = {\n email: string;\n name: string;\n userId: string | null;\n role: string | null;\n profile: Record<string, unknown> | null;\n clerkApplicationId: string | null;\n application: ReturnType<typeof applicationSummary> | null;\n };\n const people = new Map<string, PersonRow>();\n\n for (const u of (data.$users ?? []) as Array<Record<string, unknown>>) {\n if (u.deleted === true) continue; // tombstoned Clerk users are not accounts\n const email = typeof u.email === \"string\" ? u.email : \"\";\n if (!email) continue;\n const clerk = clerkByUserId.get(String(u.id));\n people.set(email.toLowerCase(), {\n email,\n name: typeof u.name === \"string\" ? u.name : \"\",\n userId: typeof u.id === \"string\" ? u.id : null,\n role: clerk?.role ?? \"provisional\",\n profile: clerk ? clerk.profile : null,\n clerkApplicationId: clerk?.applicationId ?? null,\n application: null,\n });\n }\n for (const a of (data.applications ?? []) as Array<Record<string, unknown>>) {\n const key = String(a.email ?? \"\").toLowerCase();\n if (!key) continue;\n const name = `${a.firstName ?? \"\"} ${a.lastName ?? \"\"}`.trim();\n const row = people.get(key);\n if (row) {\n if (!row.application) row.application = applicationSummary(a as unknown as Parameters<typeof applicationSummary>[0]); // newest-first: keep the latest\n if (!row.name) row.name = name;\n } else {\n people.set(key, {\n email: String(a.email),\n name,\n userId: null,\n role: null,\n profile: null,\n clerkApplicationId: null,\n application: applicationSummary(a as unknown as Parameters<typeof applicationSummary>[0]),\n });\n }\n }\n const rows = [...people.values()].sort(\n (x, y) => ((y.application?.createdAt as number) ?? -1) - ((x.application?.createdAt as number) ?? -1),\n );\n return json({ people: rows });\n};\n\n/** GET /api/admin/people/access?userId= — a person's Clerk role + super-admin\n * flag, for the record panel's Access card. */\nexport const handleAdminPeopleAccess: Route = async (req, url, env, ctx) => {\n if (req.method !== \"GET\" || url.pathname !== \"/api/admin/people/access\") return null;\n const gate = await adminGate(req, env, ctx);\n if (gate instanceof Response) return gate;\n const { db } = gate;\n const targetId = url.searchParams.get(\"userId\") ?? \"\";\n if (!targetId.startsWith(\"user_\")) return json({ error: \"invalid userId\" }, 400);\n const sk = await getVaultSecret(db, \"clerk_secret_key\");\n if (!sk) return json({ error: \"role management unavailable: clerk_secret_key missing from vault\" }, 503);\n const info = await clerkGetUser(sk, targetId);\n if (!info) return json({ error: \"user lookup unavailable\" }, 502);\n return json({ userId: targetId, role: info.role, email: info.email ?? null, superAdmin: await ctx.isSuperAdminEmail(db as never, info.email) });\n};\n\n/** POST /api/admin/people/role — change a person's Clerk role. The escalation\n * rules (super-admin tier, self-demotion lockout) are enforced by chapter's\n * canChangeRole, not re-derived here. */\nexport const handleAdminPeopleRole: Route = async (req, url, env, ctx) => {\n if (req.method !== \"POST\" || url.pathname !== \"/api/admin/people/role\") return null;\n const gate = await adminGate(req, env, ctx);\n if (gate instanceof Response) return gate;\n const { db, actor } = gate;\n\n let body: Record<string, unknown>;\n try {\n body = (await req.json()) as Record<string, unknown>;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n const targetId = typeof body.userId === \"string\" ? body.userId : \"\";\n const newRole = typeof body.role === \"string\" ? body.role : \"\";\n if (!targetId.startsWith(\"user_\")) return json({ error: \"invalid userId\" }, 400);\n\n const sk = await getVaultSecret(db, \"clerk_secret_key\");\n if (!sk) return json({ error: \"role management unavailable: clerk_secret_key missing from vault\" }, 503);\n const target = await clerkGetUser(sk, targetId);\n\n const guard = canChangeRole({\n actorId: actor.userId,\n actorIsSuper: await ctx.isSuperAdminEmail(db as never, actor.email),\n targetId,\n targetCurrentRole: target?.role ?? \"provisional\",\n targetIsSuper: await ctx.isSuperAdminEmail(db as never, target?.email),\n newRole,\n auth: ctx.chapter.auth,\n });\n if (!guard.ok) return json({ error: guard.error }, guard.status);\n\n if (!(await clerkSetRole(sk, targetId, newRole))) return json({ error: \"role update failed upstream\" }, 502);\n return json({ ok: true });\n};\n","// Explicit migration/repair for Chapter's Clerk account snapshot. This is a\n// bounded admin action rather than a side effect of a roster GET: it moves the\n// former public profile keys into backend-only private metadata, preserves the\n// public role and host-owned metadata, and records the application marker.\nimport { getVaultSecret } from \"./auth\";\nimport { updateClerkUserMetadata } from \"./clerk\";\nimport { clerkListUsers } from \"./clerk-roles\";\nimport {\n applicantPrivateMetadata,\n markPrivateMetadataSynced,\n publicProfileRemoval,\n} from \"./worker-provisioning\";\nimport { json } from \"./worker-context\";\nimport type { Route } from \"./worker-context\";\nimport type { ChapterDb } from \"./types\";\n\nconst own = (value: Record<string, unknown>, key: string): boolean =>\n Object.prototype.hasOwnProperty.call(value, key);\n\nfunction canonical(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(canonical).join(\",\")}]`;\n if (value && typeof value === \"object\") {\n return `{${Object.entries(value as Record<string, unknown>)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([key, item]) => `${JSON.stringify(key)}:${canonical(item)}`)\n .join(\",\")}}`;\n }\n return JSON.stringify(value) ?? \"undefined\";\n}\n\nfunction positiveInt(raw: string | null, fallback: number, max: number): number {\n const parsed = Number(raw);\n return Number.isSafeInteger(parsed) && parsed >= 0\n ? Math.min(parsed, max)\n : fallback;\n}\n\n/** POST /api/admin/clerk/private-profiles/sync?offset=0&limit=50\n *\n * Processes a bounded slice of Clerk users and returns `nextOffset` until the\n * migration is complete. Re-running a slice is safe: current snapshots perform\n * no Clerk write and only repair the local sync marker/link when needed. */\nexport const handleAdminClerkPrivateProfileSync: Route = async (req, url, env, ctx) => {\n if (req.method !== \"POST\" || url.pathname !== \"/api/admin/clerk/private-profiles/sync\") return null;\n const rawDb = ctx.makeDb(env);\n const actor = await ctx.verifyUser(req, env);\n if (!actor) return json({ error: \"unauthorized\" }, 401);\n if (!(await ctx.isAdmin(rawDb, actor))) return json({ error: \"forbidden\" }, 403);\n if (ctx.chapter.mode !== \"chapter\" || ctx.chapter.account === \"none\") {\n return json({ error: \"private profile sync requires a side-effecting chapter account model\" }, 409);\n }\n const db = rawDb as unknown as ChapterDb;\n const secret = await getVaultSecret(db, \"clerk_secret_key\");\n if (!secret) return json({ error: \"clerk_secret_key missing from vault\" }, 503);\n\n let all;\n try {\n all = await clerkListUsers(secret);\n } catch {\n return json({ error: \"Clerk user listing failed\" }, 502);\n }\n const offset = positiveInt(url.searchParams.get(\"offset\"), 0, Number.MAX_SAFE_INTEGER);\n const limit = positiveInt(url.searchParams.get(\"limit\"), 50, 100) || 50;\n const users = all.slice(offset, offset + limit);\n const result = { updated: 0, alreadyCurrent: 0, noApplication: 0, failed: 0 };\n\n for (const user of users) {\n if (!user.email) {\n result.noApplication += 1;\n continue;\n }\n const apps = (await db.query({\n applications: { $: { where: { email: user.email }, order: { createdAt: \"desc\" }, limit: 1 } },\n })).applications;\n const app = Array.isArray(apps) ? apps[0] : undefined;\n if (!app || typeof app.id !== \"string\") {\n result.noApplication += 1;\n continue;\n }\n\n const desired = applicantPrivateMetadata(ctx.chapter, app.id, app);\n const desiredProfile = desired.profile ?? {};\n const legacyPublic = own(user.publicMetadata, \"applicationId\") || own(user.publicMetadata, \"profile\");\n const current = user.applicationId === app.id && canonical(user.profile) === canonical(desiredProfile);\n try {\n let updated = false;\n if (!current || legacyPublic) {\n const ok = await updateClerkUserMetadata(secret, user.id, {\n publicMetadata: publicProfileRemoval,\n privateMetadata: applicantPrivateMetadata(ctx.chapter, app.id, app, true),\n });\n if (!ok) {\n result.failed += 1;\n continue;\n }\n updated = true;\n }\n await markPrivateMetadataSynced(db, app.id, user.id);\n if (updated) result.updated += 1;\n else result.alreadyCurrent += 1;\n } catch {\n result.failed += 1;\n }\n }\n\n const nextOffset = offset + users.length < all.length\n ? offset + users.length\n : null;\n return json({\n totalUsers: all.length,\n offset,\n processed: users.length,\n nextOffset,\n ...result,\n });\n};\n","// Pure aggregation helpers for the admin dashboard: a weekly time-series bucketer\n// and the annualized-run-rate math for a Stripe subscription. Kept out of the\n// route so both dashboard and billing share one definition and it is unit-tested\n// without a network call.\n\n/** Bucket `{ t, v }` points into the last `weeks` weekly buckets ending at `now`\n * (epoch ms), summing `v` per bucket. Returns oldest→newest `{ weekStart, value\n * }`, so a caller renders a sparkline directly. Points outside the window are\n * ignored. */\nexport function bucketSeries(\n points: Array<{ t: number; v: number }>,\n now: number,\n weeks = 12,\n): Array<{ weekStart: number; value: number }> {\n const WEEK = 7 * 86_400_000;\n const end = now;\n const start = end - weeks * WEEK;\n const buckets = Array.from({ length: weeks }, (_, i) => ({ weekStart: start + i * WEEK, value: 0 }));\n for (const p of points) {\n if (!Number.isFinite(p.t) || p.t < start || p.t > end) continue;\n const idx = Math.min(weeks - 1, Math.floor((p.t - start) / WEEK));\n const bucket = buckets[idx];\n if (bucket) bucket.value += Number.isFinite(p.v) ? p.v : 0;\n }\n return buckets;\n}\n\n/** Labels and current/previous values for one dashboard comparison window. */\nexport interface DashboardMetricSeries {\n labels: string[];\n current: number[];\n previous: number[];\n}\n\n/** Week-over-week and month-over-month series consumed by MetricWidget. */\nexport interface DashboardMetricData {\n wow: DashboardMetricSeries;\n mom: DashboardMetricSeries;\n}\n\nfunction periodSeries(\n points: Array<{ t: number; v: number }>,\n now: number,\n count: number,\n periodMs: number,\n): DashboardMetricSeries {\n const start = now - count * periodMs;\n const previousStart = start - count * periodMs;\n const current = Array.from({ length: count }, () => 0);\n const previous = Array.from({ length: count }, () => 0);\n for (const point of points) {\n if (!Number.isFinite(point.t) || !Number.isFinite(point.v)) continue;\n if (point.t >= start && point.t <= now) {\n const index = Math.min(count - 1, Math.floor((point.t - start) / periodMs));\n current[index] = (current[index] ?? 0) + point.v;\n } else if (point.t >= previousStart && point.t < start) {\n const index = Math.min(count - 1, Math.floor((point.t - previousStart) / periodMs));\n previous[index] = (previous[index] ?? 0) + point.v;\n }\n }\n const labels = current.map((_, index) =>\n new Date(start + index * periodMs).toISOString().slice(5, 10));\n return { labels, current, previous };\n}\n\n/** MetricWidget-ready daily and weekly comparison windows. */\nexport function dashboardMetricData(\n points: Array<{ t: number; v: number }>,\n now: number,\n): DashboardMetricData {\n const DAY = 86_400_000;\n return {\n wow: periodSeries(points, now, 7, DAY),\n mom: periodSeries(points, now, 4, 7 * DAY),\n };\n}\n\n/** Annualized cents for a Stripe subscription: sum each item's\n * `unit_amount * quantity`, ×12 for monthly intervals. A yearly interval is\n * taken as-is. Returns 0 for a shape with no priced items. */\nexport function subAnnualCents(sub: Record<string, unknown>): number {\n const items = ((sub.items as { data?: Array<Record<string, unknown>> } | undefined)?.data ?? []);\n let cents = 0;\n for (const it of items) {\n const price = (it.price ?? {}) as { unit_amount?: number; recurring?: { interval?: string } };\n const per = (price.unit_amount ?? 0) * ((it.quantity as number) ?? 1);\n cents += price.recurring?.interval === \"month\" ? per * 12 : per;\n }\n return cents;\n}\n","// Admin aggregation routes: the dashboard overview and the billing table. Both\n// join db rows with live Stripe reads (Stripe is the source of truth for money),\n// keyed by the vault stripe_secret_key, and degrade to `billingReady: false`\n// when no key is vaulted — so a hub that runs no membership billing simply drops\n// the section. Admin-gated.\nimport { getVaultSecret } from \"./auth\";\nimport { stripeCall } from \"./payments-stripe\";\nimport { resolveScheduling } from \"./scheduling\";\nimport { dashboardMetricData, subAnnualCents } from \"./series\";\nimport { json } from \"./worker-context\";\nimport type { ChapterEnv, WorkerContext } from \"./worker-context\";\nimport type { Route } from \"./worker-routes\";\nimport type { ChapterDb, ChapterScheduling } from \"./types\";\n\nasync function gate(req: Request, env: ChapterEnv, ctx: WorkerContext): Promise<ChapterDb | Response> {\n const rawDb = ctx.makeDb(env);\n const u = await ctx.verifyUser(req, env);\n if (!u) return json({ error: \"unauthorized\" }, 401);\n if (!(await ctx.isAdmin(rawDb, u))) return json({ error: \"forbidden\" }, 403);\n return rawDb as unknown as ChapterDb;\n}\n\nconst rows = <T = Record<string, unknown>>(v: unknown): T[] => (Array.isArray(v) ? (v as T[]) : []);\n\n/** GET /api/admin/dashboard — application flow counts, pipeline stage counts +\n * weekly delta, the upcoming call agenda, and (when billing is wired) live\n * revenue series. One call powers the overview. */\nexport const handleAdminDashboard: Route = async (req, url, env, ctx) => {\n if (req.method !== \"GET\" || url.pathname !== \"/api/admin/dashboard\") return null;\n const got = await gate(req, env, ctx);\n if (got instanceof Response) return got;\n const db = got;\n\n const now = Date.now();\n const d7 = now - 7 * 86_400_000;\n const d30 = now - 30 * 86_400_000;\n const data = await db.query({\n applications: { $: { order: { createdAt: \"desc\" }, limit: 1000 } },\n meetings: {\n $: {\n where: { status: \"scheduled\" },\n order: { startAt: \"asc\" },\n limit: 500,\n },\n },\n crm_record: { $: { where: { type: \"person\" }, limit: 1000 } },\n groups: { $: { where: { id: ctx.chapter.id }, limit: 1 } },\n });\n const apps = rows(data.applications);\n const applications = {\n total: apps.length,\n last7: apps.filter((a) => (a.createdAt as number) >= d7).length,\n last30: apps.filter((a) => (a.createdAt as number) >= d30).length,\n };\n const pipeline: Record<string, number> = {};\n const pipelineDelta: Record<string, number> = {};\n for (const s of ctx.chapter.pipeline.stages) {\n pipeline[s] = 0;\n pipelineDelta[s] = 0;\n }\n for (const r of rows(data.crm_record)) {\n const s = r.stage as string;\n if (s in pipeline) {\n pipeline[s] = (pipeline[s] ?? 0) + 1;\n const sc = typeof r.stageChangedAt === \"number\" ? r.stageChangedAt : Date.parse(String(r.stageChangedAt));\n if (Number.isFinite(sc) && sc >= d7) pipelineDelta[s] = (pipelineDelta[s] ?? 0) + 1;\n }\n }\n\n const meetings = rows(data.meetings);\n const appById = new Map(apps.map((a) => [a.id, a]));\n const upcoming = meetings.filter((m) => (m.startAt as number) >= now - 3_600_000);\n const calls = { upcoming: upcoming.length, needsAttention: meetings.filter((m) => m.drift && m.drift !== \"none\").length };\n const agenda = upcoming.slice(0, 8).map((m) => {\n const a = appById.get(m.applicationId);\n return {\n id: m.id,\n startAt: m.startAt,\n meetUrl: m.meetUrl ?? null,\n htmlLink: m.htmlLink ?? null,\n drift: m.drift ?? \"none\",\n name: a ? `${a.firstName} ${a.lastName}` : \"(unknown)\",\n email: (a?.email as string) ?? null,\n };\n });\n const group = data.groups?.[0];\n const timezone = resolveScheduling(group?.schedulingJson as ChapterScheduling | undefined).timezone;\n\n let revenue: Record<string, unknown> = { billingReady: false };\n let revenueSeries: unknown = null;\n let membersSeries: unknown = null;\n const sk = await getVaultSecret(db, \"stripe_secret_key\");\n if (sk) {\n const subsRes = await stripeCall(sk, \"GET\", \"/v1/subscriptions\", { limit: 100, status: \"all\" });\n if (subsRes.ok) {\n const subs = rows(subsRes.body.data);\n const subMs = (s: Record<string, unknown>) => ((s.created as number) ?? 0) * 1000;\n membersSeries = dashboardMetricData(subs.map((s) => ({ t: subMs(s), v: 1 })), now);\n revenueSeries = dashboardMetricData(subs.map((s) => ({ t: subMs(s), v: subAnnualCents(s) })), now);\n const active = subs.filter((s) => s.status === \"active\");\n revenue = {\n billingReady: true,\n testMode: String(group?.stripePublishableKey ?? \"\").startsWith(\"pk_test\"),\n activeCount: active.length,\n annualRunRateCents: active.reduce((sum, s) => sum + subAnnualCents(s), 0),\n newPaid7: subs.filter((s) => subMs(s) >= d7).length,\n newPaid30: subs.filter((s) => subMs(s) >= d30).length,\n };\n }\n }\n const applicationsSeries = dashboardMetricData(apps.map((a) => ({ t: (a.createdAt as number) || 0, v: 1 })), now);\n return json({ applications, applicationsSeries, pipeline, pipelineDelta, calls, agenda, timezone, revenue, revenueSeries, membersSeries });\n};\n\ninterface SubItem {\n price?: { unit_amount?: number; recurring?: { interval?: string } };\n quantity?: number;\n current_period_end?: number;\n}\n\n/** GET /api/admin/billing — applications joined with live Stripe subscription\n * state. `truncated` flags a >100-subscription page instead of silently losing\n * rows. `billingReady: false` when no stripe_secret_key is vaulted. */\nexport const handleAdminBilling: Route = async (req, url, env, ctx) => {\n if (req.method !== \"GET\" || url.pathname !== \"/api/admin/billing\") return null;\n const got = await gate(req, env, ctx);\n if (got instanceof Response) return got;\n const db = got;\n\n const sk = await getVaultSecret(db, \"stripe_secret_key\");\n if (!sk) return json({ billingReady: false, rows: [], summary: null });\n const [data, subsRes] = await Promise.all([\n db.query({\n applications: { $: { order: { createdAt: \"desc\" }, limit: 200 } },\n groups: { $: { where: { id: ctx.chapter.id }, limit: 1 } },\n }),\n stripeCall(sk, \"GET\", \"/v1/subscriptions\", { limit: 100, status: \"all\" }),\n ]);\n const testMode = String(data.groups?.[0]?.stripePublishableKey ?? \"\").startsWith(\"pk_test\");\n if (!subsRes.ok) return json({ error: \"billing lookup failed upstream\" }, 502);\n const subById = new Map(rows(subsRes.body.data).map((s) => [s.id as string, s]));\n\n const billingRows = [];\n for (const a of rows(data.applications)) {\n if (!a.stripeCustomerId && !a.stripeSubscriptionId) continue;\n const sub = a.stripeSubscriptionId ? subById.get(a.stripeSubscriptionId as string) : undefined;\n const items = (sub?.items as { data?: SubItem[] } | undefined)?.data ?? [];\n let amountCents = 0;\n let interval = \"year\";\n for (const it of items) {\n amountCents += (it.price?.unit_amount ?? 0) * (it.quantity ?? 1);\n interval = it.price?.recurring?.interval ?? interval;\n }\n const periodEnd = (sub?.current_period_end as number | undefined) ?? items[0]?.current_period_end;\n billingRows.push({\n id: a.id as string,\n name: `${a.firstName} ${a.lastName}`,\n email: a.email as string,\n applicationStatus: a.status as string,\n subscriptionStatus: (sub?.status as string) ?? null,\n cancelAtPeriodEnd: sub?.cancel_at_period_end === true,\n amountCents,\n interval,\n renewalAt: periodEnd ? periodEnd * 1000 : ((a.renewalAt as number) ?? null),\n });\n }\n const renewing = billingRows.filter((r) => r.subscriptionStatus === \"active\" && !r.cancelAtPeriodEnd);\n const soonCutoff = Date.now() + 60 * 86_400_000;\n const summary = {\n activeCount: billingRows.filter((r) => r.subscriptionStatus === \"active\").length,\n annualizedCents: renewing.reduce((s, r) => s + r.amountCents * (r.interval === \"month\" ? 12 : 1), 0),\n renewingSoonCount: renewing.filter((r) => r.renewalAt && r.renewalAt < soonCutoff).length,\n pastDueCount: billingRows.filter((r) => r.subscriptionStatus === \"past_due\").length,\n canceledCount: billingRows.filter((r) => r.subscriptionStatus === \"canceled\" || r.cancelAtPeriodEnd).length,\n refundedCount: billingRows.filter((r) => r.applicationStatus === \"refunded\").length,\n };\n return json({\n billingReady: true,\n testMode,\n truncated: subsRes.body.has_more === true,\n rows: billingRows,\n summary,\n });\n};\n","// Admin lifecycle routes: meeting reschedule/cancel and application\n// approve/refund/manual-patch. These are the operational actions; each wires a\n// chapter primitive (canApprove, meetingRescheduleUpdate, refundedPatch) and the\n// operations policy seams (onApprove.promoteTo/send, refund.allowedFrom/\n// cancelSubscription), and mirrors the change into the CRM. Admin-gated.\nimport { computeBookableSlots, initCalendar } from \"@odla-ai/calendar\";\nimport { getVaultSecret } from \"./auth\";\nimport { approveApplication } from \"./approve-application\";\nimport { crmDeps, syncApplicationToCrm } from \"./crm-sync\";\nimport { stripeCall } from \"./payments-stripe\";\nimport { canTransition } from \"./pipeline\";\nimport { resolveScheduling, endForSlot, isSlotAvailable, meetingRescheduleUpdate, slotWindow } from \"./scheduling\";\nimport { json } from \"./worker-context\";\nimport type { ChapterEnv, WorkerContext } from \"./worker-context\";\nimport type { Route } from \"./worker-routes\";\nimport type { ChapterDb, ChapterScheduling } from \"./types\";\n\nasync function gate(req: Request, env: ChapterEnv, ctx: WorkerContext): Promise<ChapterDb | Response> {\n const rawDb = ctx.makeDb(env);\n const u = await ctx.verifyUser(req, env);\n if (!u) return json({ error: \"unauthorized\" }, 401);\n if (!(await ctx.isAdmin(rawDb, u))) return json({ error: \"forbidden\" }, 403);\n return rawDb as unknown as ChapterDb;\n}\n\nconst calFor = (env: ChapterEnv) =>\n initCalendar({ appId: env.ODLA_APP_ID, env: env.ODLA_ENV, adminToken: env.ODLA_API_KEY, endpoint: env.ODLA_PLATFORM });\nconst readJson = async (req: Request): Promise<Record<string, unknown> | null> => {\n try {\n return (await req.json()) as Record<string, unknown>;\n } catch {\n return null;\n }\n};\nasync function loadApp(db: ChapterDb, id: string): Promise<Record<string, unknown> | null> {\n const { applications } = await db.query({ applications: { $: { where: { id }, limit: 1 } } });\n return applications?.[0] ?? null;\n}\nasync function loadGroup(db: ChapterDb, id: string): Promise<Record<string, unknown> | null> {\n const { groups } = await db.query({ groups: { $: { where: { id }, limit: 1 } } });\n return groups?.[0] ?? null;\n}\n\n/** POST /api/admin/meetings/:id/reschedule — move an intro call to an open slot;\n * the Google event moves (Meet link + invite thread survive). */\nexport const handleAdminMeetingReschedule: Route = async (req, url, env, ctx) => {\n const m = url.pathname.match(/^\\/api\\/admin\\/meetings\\/([0-9a-f-]+)\\/reschedule$/);\n if (req.method !== \"POST\" || !m) return null;\n const got = await gate(req, env, ctx);\n if (got instanceof Response) return got;\n const db = got;\n const body = await readJson(req);\n const startAt = Number(body?.startAt);\n if (!Number.isFinite(startAt)) return json({ error: \"startAt required\" }, 400);\n\n const { meetings } = await db.query({ meetings: { $: { where: { id: m[1] }, limit: 1 } } });\n const meeting = meetings?.[0];\n if (!meeting) return json({ error: \"not found\" }, 404);\n if (meeting.status !== \"scheduled\") return json({ error: \"meeting is cancelled\" }, 409);\n if (!meeting.googleEventId) return json({ error: \"no calendar event on file\" }, 409);\n\n const cfg = resolveScheduling((await loadGroup(db, String(meeting.groupId ?? ctx.chapter.id)))?.schedulingJson as ChapterScheduling | undefined);\n const endAt = endForSlot(startAt, cfg.slotMinutes);\n const cal = calFor(env);\n try {\n const { from, to } = slotWindow(Date.now(), cfg.windowDays);\n const fb = await cal.availability.freeBusy({ timeMin: from, timeMax: to });\n const slots = computeBookableSlots(fb.busy, {\n from: fb.timeMin,\n to: fb.timeMax,\n timezone: cfg.timezone,\n slotMinutes: cfg.slotMinutes,\n businessHours: { days: [...cfg.days], startHour: cfg.startHour, endHour: cfg.endHour },\n minNoticeMs: cfg.minNoticeHours * 3_600_000,\n });\n if (!isSlotAvailable(slots, startAt)) return json({ error: \"slot no longer available\", code: \"calendar_slot_unavailable\" }, 409);\n await cal.actions.reschedule(String(meeting.googleEventId), {\n idempotencyKey: `meeting:${String(meeting.id)}:reschedule:${startAt}:${endAt}`,\n startAt,\n endAt,\n });\n } catch {\n return json({ error: \"reschedule failed upstream\" }, 502);\n }\n await db.transact([{ t: \"update\", ns: \"meetings\", id: String(meeting.id), attrs: meetingRescheduleUpdate(startAt, endAt) }]);\n await db.transact([{ t: \"update\", ns: \"applications\", id: String(meeting.applicationId), attrs: { meetingAt: startAt } }]);\n return json({ ok: true, startAt, endAt });\n};\n\n/** POST /api/admin/meetings/:id/cancel — cancel an intro call; the Google event\n * is removed (Google notifies the attendee). */\nexport const handleAdminMeetingCancel: Route = async (req, url, env, ctx) => {\n const m = url.pathname.match(/^\\/api\\/admin\\/meetings\\/([0-9a-f-]+)\\/cancel$/);\n if (req.method !== \"POST\" || !m) return null;\n const got = await gate(req, env, ctx);\n if (got instanceof Response) return got;\n const db = got;\n\n const { meetings } = await db.query({ meetings: { $: { where: { id: m[1] }, limit: 1 } } });\n const meeting = meetings?.[0];\n if (!meeting) return json({ error: \"not found\" }, 404);\n if (meeting.status !== \"scheduled\") return json({ error: \"already cancelled\" }, 409);\n if (meeting.googleEventId) {\n try {\n await calFor(env).actions.cancel(String(meeting.googleEventId), {\n idempotencyKey: `meeting:${String(meeting.id)}:cancel`,\n });\n } catch {\n return json({ error: \"cancel failed upstream\" }, 502);\n }\n }\n await db.transact([{ t: \"update\", ns: \"meetings\", id: String(meeting.id), attrs: { status: \"cancelled\", drift: \"none\" } }]);\n await db.transact([{ t: \"update\", ns: \"applications\", id: String(meeting.applicationId), attrs: { meetingAt: 0, meetingLink: \"\" } }]);\n return json({ ok: true });\n};\n\n/** POST /api/admin/applications/:id/approve — the deliberate approval: advance to\n * the approvable target, promote the Clerk role (operations.onApprove.promoteTo),\n * and send the approve template (operations.onApprove.send). Mirrors to CRM. */\nexport const handleAdminApprove: Route = async (req, url, env, ctx) => {\n const m = url.pathname.match(/^\\/api\\/admin\\/applications\\/([0-9a-f-]+)\\/approve$/);\n if (req.method !== \"POST\" || !m) return null;\n const got = await gate(req, env, ctx);\n if (got instanceof Response) return got;\n const db = got;\n const id = m[1] as string;\n\n const app = await loadApp(db, id);\n if (!app) return json({ error: \"not found\" }, 404);\n const result = await approveApplication({ db, env, ctx, app, origin: url.origin, reason: \"manual\" });\n if (!result.ok) return json({ error: result.error }, result.status);\n return json({ ok: true, status: \"approved\", rolePromoted: result.rolePromoted, emailLogged: result.emailLogged });\n};\n\n/** POST /api/admin/applications/:id/refund — refund the first paid charge and\n * (per operations.refund) cancel the subscription. The status flip to \"refunded\"\n * comes from the charge.refunded webhook, so Stripe stays the source of truth. */\nexport const handleAdminRefund: Route = async (req, url, env, ctx) => {\n const m = url.pathname.match(/^\\/api\\/admin\\/applications\\/([0-9a-f-]+)\\/refund$/);\n if (req.method !== \"POST\" || !m) return null;\n const got = await gate(req, env, ctx);\n if (got instanceof Response) return got;\n const db = got;\n\n const app = await loadApp(db, m[1] as string);\n if (!app) return json({ error: \"not found\" }, 404);\n if (app.status === \"refunded\") return json({ error: \"already refunded\" }, 409);\n const allowedFrom = ctx.chapter.operations.refund.allowedFrom;\n if (allowedFrom && !allowedFrom.includes(String(app.status))) {\n return json({ error: `cannot refund from status \"${String(app.status)}\"` }, 409);\n }\n const subscriptionId = app.stripeSubscriptionId as string | undefined;\n const customerId = app.stripeCustomerId as string | undefined;\n if (!customerId) return json({ error: \"no customer on file\" }, 409);\n const sk = await getVaultSecret(db, \"stripe_secret_key\");\n if (!sk) return json({ error: \"payments not configured\" }, 503);\n\n const charges = await stripeCall(sk, \"GET\", \"/v1/charges\", { customer: customerId, limit: 100 });\n if (!charges.ok) return json({ error: \"refund failed upstream\" }, 502);\n const succeeded = ((charges.body.data as Array<Record<string, unknown>>) ?? []).filter((c) => c.status === \"succeeded\" && c.refunded !== true);\n const firstCharge = succeeded[succeeded.length - 1];\n if (!firstCharge) return json({ error: \"no paid charge to refund\" }, 409);\n\n const refund = await stripeCall(sk, \"POST\", \"/v1/refunds\", { charge: String(firstCharge.id) });\n if (!refund.ok) return json({ error: \"refund failed upstream\" }, 502);\n let subscriptionCanceled = false;\n if (ctx.chapter.operations.refund.cancelSubscription && subscriptionId) {\n const cancel = await stripeCall(sk, \"DELETE\", `/v1/subscriptions/${subscriptionId}`);\n subscriptionCanceled = cancel.ok;\n }\n return json({ ok: true, refundedCents: (refund.body.amount as number) ?? null, subscriptionCanceled });\n};\n\n/** PATCH /api/admin/applications/:id — manual correction escape hatch. Sets\n * `status` (gated by canTransition) and/or `meetingAt`. Mirrors a status move to\n * the CRM. */\nexport const handleAdminApplicationPatch: Route = async (req, url, env, ctx) => {\n const m = url.pathname.match(/^\\/api\\/admin\\/applications\\/([0-9a-f-]+)$/);\n if (req.method !== \"PATCH\" || !m) return null;\n const got = await gate(req, env, ctx);\n if (got instanceof Response) return got;\n const db = got;\n const id = m[1] as string;\n const body = await readJson(req);\n if (!body) return json({ error: \"invalid JSON body\" }, 400);\n\n const app = await loadApp(db, id);\n if (!app) return json({ error: \"not found\" }, 404);\n\n const attrs: Record<string, unknown> = {};\n if (body.status !== undefined) {\n const to = String(body.status);\n if (!ctx.chapter.pipeline.stages.includes(to)) return json({ error: `status must be one of: ${ctx.chapter.pipeline.stages.join(\", \")}` }, 400);\n if (!canTransition(String(app.status), to, ctx.chapter.pipeline)) return json({ error: `cannot move from \"${String(app.status)}\" to \"${to}\"` }, 409);\n attrs.status = to;\n }\n if (body.meetingAt !== undefined) {\n if (typeof body.meetingAt !== \"number\" || !Number.isFinite(body.meetingAt)) return json({ error: \"meetingAt must be epoch milliseconds\" }, 400);\n attrs.meetingAt = body.meetingAt;\n }\n if (Object.keys(attrs).length === 0) return json({ error: \"nothing to update\" }, 400);\n\n await db.transact([{ t: \"update\", ns: \"applications\", id, attrs }]);\n if (attrs.status !== undefined) {\n await syncApplicationToCrm(crmDeps(db, ctx), { app: { ...app, ...attrs }, stage: String(attrs.status) }).catch(() => undefined);\n }\n return json({ ok: true });\n};\n","// Admin email + comms routes: read/write the group's owner-editable email config,\n// the send audit log, an owner-triggered test send, and one person's comms\n// timeline (sent lifecycle mail + the Google calendar invitations reconstructed\n// from meeting rows). Admin-gated.\nimport { renderTemplateBody } from \"./email\";\nimport { sendTemplated, emailGroupFrom, EMAIL_TEMPLATE_NAMES } from \"./notify\";\nimport { json } from \"./worker-context\";\nimport type { ChapterEnv, WorkerContext } from \"./worker-context\";\nimport type { Route } from \"./worker-routes\";\nimport type { ChapterDb } from \"./types\";\n\nasync function gate(req: Request, env: ChapterEnv, ctx: WorkerContext): Promise<ChapterDb | Response> {\n const rawDb = ctx.makeDb(env);\n const u = await ctx.verifyUser(req, env);\n if (!u) return json({ error: \"unauthorized\" }, 401);\n if (!(await ctx.isAdmin(rawDb, u))) return json({ error: \"forbidden\" }, 403);\n return rawDb as unknown as ChapterDb;\n}\nasync function loadGroup(db: ChapterDb, id: string): Promise<Record<string, unknown> | null> {\n const { groups } = await db.query({ groups: { $: { where: { id }, limit: 1 } } });\n return groups?.[0] ?? null;\n}\nconst str = (v: unknown, d = \"\"): string => (typeof v === \"string\" ? v : d);\nconst notifyDeps = (db: ChapterDb, env: ChapterEnv) => ({\n db,\n envName: env.ODLA_ENV,\n sender: env.SEND_EMAIL,\n from: env.EMAIL_FROM,\n now: () => Date.now(),\n newId: () => crypto.randomUUID(),\n});\n\n/** GET/PUT /api/admin/group/email — read the owner-editable email config\n * (templates + addresses + read-only delivery wiring), or replace it. */\nexport const handleAdminGroupEmail: Route = async (req, url, env, ctx) => {\n if (url.pathname !== \"/api/admin/group/email\" || (req.method !== \"GET\" && req.method !== \"PUT\")) return null;\n const got = await gate(req, env, ctx);\n if (got instanceof Response) return got;\n const db = got;\n const group = await loadGroup(db, ctx.chapter.id);\n if (!group) return json({ error: \"not found\" }, 404);\n\n if (req.method === \"GET\") {\n const stored = (group.emailTemplates ?? {}) as Record<string, { subject?: string; text?: string; enabled?: boolean }>;\n const emailTemplates: Record<string, { subject: string; text: string; enabled: boolean }> = {};\n for (const key of EMAIL_TEMPLATE_NAMES) {\n const t = stored[key];\n if (t) emailTemplates[key] = { subject: str(t.subject), text: str(t.text), enabled: t.enabled !== false };\n }\n return json({\n groupId: group.id,\n name: group.name,\n replyTo: str(group.replyTo),\n notificationEmail: str(group.notificationEmail),\n debugEmail: str(group.debugEmail),\n emailTemplates,\n commitmentText: str(group.commitmentText),\n normsText: str(group.normsText),\n refundPolicyText: str(group.refundPolicyText),\n // Read-only delivery wiring — surfaced so \"why did this not send?\" is\n // answerable without logs.\n envName: env.ODLA_ENV,\n transport: env.SEND_EMAIL && env.EMAIL_FROM ? \"cloudflare\" : \"log-only\",\n fromEmail: env.EMAIL_FROM ?? null,\n });\n }\n\n let body: Record<string, unknown>;\n try {\n body = (await req.json()) as Record<string, unknown>;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n const templates = body.emailTemplates;\n if (!templates || typeof templates !== \"object\") return json({ error: \"emailTemplates object required\" }, 400);\n const clean: Record<string, { subject: string; text: string; enabled: boolean }> = {};\n for (const key of EMAIL_TEMPLATE_NAMES) {\n const t = (templates as Record<string, { subject?: unknown; text?: unknown; enabled?: unknown }>)[key];\n const subject = typeof t?.subject === \"string\" ? t.subject.trim() : \"\";\n const text = typeof t?.text === \"string\" ? t.text : \"\";\n if (!subject || !text.trim()) return json({ error: `template \"${key}\" needs a subject and a body` }, 400);\n if (/[\\r\\n]/.test(subject) || subject.length > 200) return json({ error: `template \"${key}\" subject must be a single line under 200 characters` }, 400);\n if (text.length > 10_000) return json({ error: `template \"${key}\" body is too long` }, 400);\n clean[key] = { subject, text, enabled: t?.enabled !== false };\n }\n const emailish = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n const notificationEmail = str(body.notificationEmail).trim();\n const replyTo = str(body.replyTo).trim();\n const debugEmail = str(body.debugEmail).trim();\n if (!emailish.test(notificationEmail)) return json({ error: \"notification address must be a valid email\" }, 400);\n if (!emailish.test(replyTo)) return json({ error: \"reply-to address must be a valid email\" }, 400);\n if (debugEmail && !emailish.test(debugEmail)) return json({ error: \"debug address must be a valid email\" }, 400);\n const commitmentText = str(body.commitmentText);\n const normsText = str(body.normsText);\n if (commitmentText.length > 5000 || normsText.length > 5000) return json({ error: \"commitment/norms text is too long\" }, 400);\n\n await db.transact([{ t: \"update\", ns: \"groups\", id: ctx.chapter.id, attrs: { emailTemplates: clean, commitmentText, normsText, notificationEmail, replyTo, debugEmail } }]);\n return json({ ok: true });\n};\n\n/** GET /api/admin/email/log — the send audit: every attempted send. */\nexport const handleAdminEmailLog: Route = async (req, url, env, ctx) => {\n if (req.method !== \"GET\" || url.pathname !== \"/api/admin/email/log\") return null;\n const got = await gate(req, env, ctx);\n if (got instanceof Response) return got;\n const { emailLog } = await got.query({ emailLog: { $: { order: { sentAt: \"desc\" }, limit: 50 } } });\n const sends = ((emailLog ?? []) as Array<Record<string, unknown>>).map((r) => ({\n id: r.id,\n template: r.template,\n to: r.to,\n subject: r.subject,\n transport: r.transport,\n redirected: r.redirected === true,\n error: (r.error as string) ?? null,\n sentAt: r.sentAt,\n }));\n return json({ sends });\n};\n\n/** POST /api/admin/email/test — send one template with sample data to the\n * notification address, ignoring the `enabled` flag (the admin asked). */\nexport const handleAdminEmailTest: Route = async (req, url, env, ctx) => {\n if (req.method !== \"POST\" || url.pathname !== \"/api/admin/email/test\") return null;\n const got = await gate(req, env, ctx);\n if (got instanceof Response) return got;\n const db = got;\n let body: Record<string, unknown>;\n try {\n body = (await req.json()) as Record<string, unknown>;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n const template = str(body.template);\n if (!(EMAIL_TEMPLATE_NAMES as readonly string[]).includes(template)) {\n return json({ error: `template must be one of: ${EMAIL_TEMPLATE_NAMES.join(\", \")}` }, 400);\n }\n const group = await loadGroup(db, ctx.chapter.id);\n if (!group) return json({ error: \"not found\" }, 404);\n const res = await sendTemplated(notifyDeps(db, env), {\n group: emailGroupFrom(group),\n template,\n to: str(group.notificationEmail),\n vars: { firstName: \"Sample\", lastName: \"Person\", email: \"sample@example.com\", phone: \"(555) 010-0100\", state: \"CA\", adminUrl: `${url.origin}/admin/`, membersUrl: `${url.origin}/members/` },\n dedupeKey: `test:${template}:${Date.now()}`,\n force: true,\n });\n return json({ ok: res.sent, reason: res.reason ?? null, to: str(group.notificationEmail), redirected: env.ODLA_ENV !== \"prod\" && !!group.debugEmail });\n};\n\n/** GET /api/admin/people/:applicationId/comms — one person's timeline: sent\n * lifecycle mail (adminNotification dropped — it goes to the team) plus the\n * Google calendar invitations reconstructed from their meeting rows. */\nexport const handleAdminComms: Route = async (req, url, env, ctx) => {\n const m = url.pathname.match(/^\\/api\\/admin\\/people\\/([0-9a-fA-F-]+)\\/comms$/);\n if (req.method !== \"GET\" || !m) return null;\n const got = await gate(req, env, ctx);\n if (got instanceof Response) return got;\n const db = got;\n const appId = m[1] as string;\n\n const data = await db.query({\n emailLog: {\n $: {\n where: { applicationId: appId },\n order: { sentAt: \"desc\" },\n limit: 100,\n },\n },\n meetings: { $: { where: { applicationId: appId } } },\n applications: { $: { where: { id: appId }, limit: 1 } },\n });\n const app = data.applications?.[0] ?? null;\n const group = await loadGroup(db, str(app?.groupId, ctx.chapter.id));\n const vars: Record<string, string> | null = app\n ? { firstName: str(app.firstName), lastName: str(app.lastName), email: str(app.email), phone: str(app.phone), state: str(app.state), adminUrl: `${url.origin}/admin/`, membersUrl: `${url.origin}/members/` }\n : null;\n\n const emails = ((data.emailLog ?? []) as Array<Record<string, unknown>>)\n .filter((r) => r.template !== \"adminNotification\")\n .map((r): Record<string, unknown> => {\n let mailBody: string | null = typeof r.body === \"string\" ? r.body : null;\n if (!mailBody && group && vars) mailBody = renderTemplateBody(emailGroupFrom(group), String(r.template), vars);\n const channel = r.error ? \"email (failed)\" : r.redirected ? \"email (dev-redirected)\" : r.transport === \"log-only\" ? \"email (not delivered)\" : \"email\";\n return { kind: \"email\", channel, label: String(r.template), subject: str(r.subject), to: (r.to as string) ?? null, body: mailBody, at: r.sentAt as number, error: (r.error as string) ?? null };\n });\n const calendar = ((data.meetings ?? []) as Array<Record<string, unknown>>).map((m2): Record<string, unknown> => ({\n kind: \"calendar\",\n channel: \"Google Calendar\",\n label: m2.status === \"cancelled\" ? \"Invitation (call later cancelled)\" : \"Meeting invitation\",\n subject: \"Introduction call invitation\",\n to: null,\n at: (m2.createdAt as number) ?? (m2.startAt as number),\n error: null,\n }));\n const items = [...emails, ...calendar].sort((a, b) => ((b.at as number) ?? 0) - ((a.at as number) ?? 0));\n return json({ items });\n};\n","// Leader-side network routes. The receiving route has its own module; these\n// admin-gated routes expose configured targets and fan one CRM record out to\n// selected followers with per-target vaulted credentials.\nimport { getRecord, typeSummary } from \"@odla-ai/crm\";\nimport { signFederatedRequest, verifyFederatedRequest } from \"@odla-ai/db\";\nimport { getVaultSecret } from \"./auth\";\nimport { DEFAULT_SHARE_FIELDS } from \"./network\";\nimport { json } from \"./worker-context\";\nimport type { ChapterEnv, Db, Route, Verified, WorkerContext } from \"./worker-context\";\nimport type { ChapterDb, ResolvedNetworkTarget } from \"./types\";\nimport type { NetworkRollup, NetworkRollupTarget, NetworkSnapshot } from \"./network\";\nimport { fetchNetworkTarget } from \"./worker-network-fetch\";\nimport { pushNetworkRecord } from \"./worker-network-push\";\n\nasync function gate(\n req: Request,\n env: ChapterEnv,\n ctx: WorkerContext,\n): Promise<{ response: Response } | { db: Db; user: Verified }> {\n const db = ctx.makeDb(env);\n const user = await ctx.verifyUser(req, env);\n if (!user) return { response: json({ error: \"unauthorized\" }, 401) };\n if (!(await ctx.isAdmin(db, user))) return { response: json({ error: \"forbidden\" }, 403) };\n return { db, user };\n}\n\n/** GET /api/admin/network/targets — non-secret target metadata for the UI. */\nexport const handleAdminNetworkTargets: Route = async (req, url, env, ctx) => {\n if (req.method !== \"GET\" || url.pathname !== \"/api/admin/network/targets\") return null;\n const got = await gate(req, env, ctx);\n if (\"response\" in got) return got.response;\n return json({\n targets: ctx.chapter.network.targets.map(({ id, name, url: targetUrl, fields, sharedNotes }) => ({\n id,\n name,\n url: targetUrl,\n types: Object.keys(fields ?? DEFAULT_SHARE_FIELDS),\n sharedNotes,\n })),\n });\n};\n\n/** GET /api/network/snapshot — signed, aggregate-only follower status. The\n * response contains no people, sessions, record fields, or database keys. */\nexport const handleNetworkSnapshot: Route = async (req, url, env, ctx) => {\n if (req.method !== \"GET\" || url.pathname !== \"/api/network/snapshot\") return null;\n const db = ctx.makeDb(env);\n const secret = await getVaultSecret(db as unknown as ChapterDb, \"network_share_secret\");\n if (!secret) return json({ error: \"unauthorized\" }, 401);\n const verified = await verifyFederatedRequest(req, { secret });\n if (!verified.ok) return json({ error: \"unauthorized\", reason: verified.reason }, 401);\n const types = await Promise.all(\n Object.keys(ctx.chapter.crm.config.types).map((type) =>\n typeSummary({ crm: ctx.chapter.crm, db: db as never }, type)),\n );\n const snapshot: NetworkSnapshot = {\n version: 1,\n site: { id: ctx.chapter.id, name: ctx.chapter.name, mode: ctx.chapter.mode },\n generatedAt: Date.now(),\n types,\n };\n return json(snapshot);\n};\n\nasync function snapshotOne(\n db: ChapterDb,\n env: ChapterEnv,\n ctx: WorkerContext,\n target: ResolvedNetworkTarget,\n): Promise<NetworkRollupTarget> {\n const secret = await getVaultSecret(db, target.secretName);\n if (!secret) return { id: target.id, name: target.name, url: target.url, available: false, error: \"edge secret is missing\" };\n const destination = new URL(\"/api/network/snapshot\", target.url);\n try {\n const headers = await signFederatedRequest({\n secret,\n sender: ctx.chapter.id,\n method: \"GET\",\n url: destination,\n });\n const response = await fetchNetworkTarget(env, target, destination, {\n headers,\n signal: AbortSignal.timeout(10_000),\n });\n const body = (await response.json().catch(() => null)) as NetworkSnapshot | { error?: string } | null;\n if (\n !response.ok ||\n !body ||\n !(\"version\" in body) ||\n body.version !== 1 ||\n !(\"site\" in body) ||\n body.site.id !== target.id ||\n !Array.isArray(body.types)\n ) {\n const upstream = body && \"error\" in body && typeof body.error === \"string\" ? body.error : undefined;\n return {\n id: target.id,\n name: target.name,\n url: target.url,\n available: false,\n error: upstream ?? (response.ok ? \"invalid follower snapshot\" : `follower returned ${response.status}`),\n };\n }\n return {\n id: target.id,\n name: target.name,\n url: target.url,\n available: true,\n generatedAt: body.generatedAt,\n types: body.types,\n };\n } catch (error) {\n return {\n id: target.id,\n name: target.name,\n url: target.url,\n available: false,\n error: error instanceof Error ? error.message : \"snapshot failed\",\n };\n }\n}\n\n/** GET /api/admin/network/rollup — leader-authenticated fan-out to configured\n * follower snapshots, plus cross-target aggregate totals. */\nexport const handleAdminNetworkRollup: Route = async (req, url, env, ctx) => {\n if (req.method !== \"GET\" || url.pathname !== \"/api/admin/network/rollup\") return null;\n const got = await gate(req, env, ctx);\n if (\"response\" in got) return got.response;\n const targets = await Promise.all(\n ctx.chapter.network.targets.map((target) =>\n snapshotOne(got.db as unknown as ChapterDb, env, ctx, target)),\n );\n const byType = new Map<string, { type: string; total: number; stages: Record<string, number> }>();\n for (const target of targets) {\n for (const type of target.types ?? []) {\n const aggregate = byType.get(type.type) ?? { type: type.type, total: 0, stages: {} };\n aggregate.total += type.total;\n for (const [stage, count] of Object.entries(type.stages)) {\n aggregate.stages[stage] = (aggregate.stages[stage] ?? 0) + count;\n }\n byType.set(type.type, aggregate);\n }\n }\n const rollup: NetworkRollup = {\n configured: targets.length,\n available: targets.filter((target) => target.available).length,\n totalRecords: [...byType.values()].reduce((sum, type) => sum + type.total, 0),\n types: [...byType.values()],\n targets,\n };\n return json(rollup);\n};\n\n/** POST /api/admin/network/push `{ recordId, targetIds }` — push one leader CRM\n * record to one or more configured followers. Each follower receives an\n * independently validated, allowlisted projection; partial failure is explicit. */\nexport const handleAdminNetworkPush: Route = async (req, url, env, ctx) => {\n if (req.method !== \"POST\" || url.pathname !== \"/api/admin/network/push\") return null;\n const got = await gate(req, env, ctx);\n if (\"response\" in got) return got.response;\n let body: { recordId?: unknown; targetIds?: unknown };\n try {\n body = (await req.json()) as typeof body;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n if (typeof body.recordId !== \"string\" || !Array.isArray(body.targetIds) || body.targetIds.length === 0) {\n return json({ error: \"recordId and a non-empty targetIds array are required\" }, 400);\n }\n const requested = new Set(body.targetIds.filter((id): id is string => typeof id === \"string\"));\n if (requested.size !== body.targetIds.length) return json({ error: \"targetIds must contain unique strings\" }, 400);\n const targets = ctx.chapter.network.targets.filter((target) => requested.has(target.id));\n if (targets.length !== requested.size) return json({ error: \"one or more targetIds are not configured\" }, 400);\n\n const record = await getRecord({ crm: ctx.chapter.crm, db: got.db as never }, body.recordId);\n if (!record) return json({ error: \"record not found\" }, 404);\n const results = await Promise.all(\n targets.map((target) =>\n pushNetworkRecord(got.db as unknown as ChapterDb, env, ctx, target, record)),\n );\n return json({ ok: results.every((result) => result.ok), results });\n};\n","import type { ChapterEnv } from \"./worker-context\";\nimport type { ResolvedNetworkTarget } from \"./types\";\n\ninterface NetworkFetcher {\n fetch(request: Request): Promise<Response>;\n}\n\nfunction targetFetcher(\n env: ChapterEnv,\n target: ResolvedNetworkTarget,\n): NetworkFetcher | null {\n if (!target.binding) return null;\n const candidate = (env as unknown as Record<string, unknown>)[target.binding];\n if (\n typeof candidate !== \"object\" ||\n candidate === null ||\n !(\"fetch\" in candidate) ||\n typeof candidate.fetch !== \"function\"\n ) {\n throw new Error(`service binding \"${target.binding}\" is unavailable`);\n }\n return candidate as NetworkFetcher;\n}\n\nexport function fetchNetworkTarget(\n env: ChapterEnv,\n target: ResolvedNetworkTarget,\n destination: URL,\n init: RequestInit,\n): Promise<Response> {\n const binding = targetFetcher(env, target);\n return binding\n ? binding.fetch(new Request(destination, init))\n : globalThis.fetch(destination, init);\n}\n","import { recordDeliveryAttempt } from \"@odla-ai/crm\";\nimport type { CrmRecord } from \"@odla-ai/crm\";\nimport { signFederatedRequest } from \"@odla-ai/db\";\nimport { getVaultSecret } from \"./auth\";\nimport { sharedRecordFromCrm } from \"./network\";\nimport type { WorkerContext } from \"./worker-context\";\nimport type { ChapterDb, ResolvedNetworkTarget } from \"./types\";\nimport { fetchNetworkTarget } from \"./worker-network-fetch\";\n\nexport interface NetworkPushResult {\n id: string;\n name: string;\n ok: boolean;\n status?: number;\n recordId?: string;\n error?: string;\n}\n\nexport async function pushNetworkRecord(\n db: ChapterDb,\n env: Parameters<typeof fetchNetworkTarget>[0],\n ctx: WorkerContext,\n target: ResolvedNetworkTarget,\n record: CrmRecord,\n): Promise<NetworkPushResult> {\n const secret = await getVaultSecret(db, target.secretName);\n const crmDeps = {\n crm: ctx.chapter.crm,\n db: db as never,\n now: () => Date.now(),\n newId: () => crypto.randomUUID(),\n };\n if (!secret) {\n const error = `vault secret \"${target.secretName}\" is missing`;\n await recordDeliveryAttempt(crmDeps, {\n recordId: record.id,\n targetId: target.id,\n status: \"failed\",\n payloadVersion: 2,\n error,\n });\n return { id: target.id, name: target.name, ok: false, error };\n }\n let payload;\n try {\n payload = sharedRecordFromCrm(ctx.chapter.crm, record, target, ctx.chapter.id);\n } catch (err) {\n return {\n id: target.id,\n name: target.name,\n ok: false,\n error: err instanceof Error ? err.message : \"record is not shareable\",\n };\n }\n const payloadBody = JSON.stringify(payload);\n const destination = new URL(\"/api/network/shared\", target.url);\n try {\n const signed = await signFederatedRequest({\n secret,\n sender: ctx.chapter.id,\n method: \"POST\",\n url: destination,\n body: payloadBody,\n });\n const res = await fetchNetworkTarget(env, target, destination, {\n method: \"POST\",\n headers: { ...signed, \"content-type\": \"application/json\" },\n body: payloadBody,\n signal: AbortSignal.timeout(10_000),\n });\n const responseBody = (await res.json().catch(() => ({}))) as {\n recordId?: string;\n error?: string;\n };\n if (!res.ok) {\n const error = responseBody.error ?? \"follower rejected the record\";\n await recordDeliveryAttempt(crmDeps, {\n recordId: record.id,\n targetId: target.id,\n status: \"failed\",\n payloadVersion: 2,\n error,\n });\n return {\n id: target.id,\n name: target.name,\n ok: false,\n status: res.status,\n error,\n };\n }\n await recordDeliveryAttempt(crmDeps, {\n recordId: record.id,\n targetId: target.id,\n status: \"delivered\",\n payloadVersion: 2,\n ...(responseBody.recordId ? { remoteRecordId: responseBody.recordId } : {}),\n });\n return {\n id: target.id,\n name: target.name,\n ok: true,\n status: res.status,\n recordId: responseBody.recordId,\n };\n } catch (err) {\n const error = err instanceof Error ? err.message : \"delivery failed\";\n await recordDeliveryAttempt(crmDeps, {\n recordId: record.id,\n targetId: target.id,\n status: \"failed\",\n payloadVersion: 2,\n error,\n });\n return { id: target.id, name: target.name, ok: false, error };\n }\n}\n","import { listRecords } from \"@odla-ai/crm\";\nimport { signFederatedRequest, verifyFederatedRequest } from \"@odla-ai/db\";\nimport { getVaultSecret } from \"./auth\";\nimport type {\n NetworkRecord,\n NetworkRecordPage,\n} from \"./network-contract\";\nimport type { ChapterDb, ResolvedNetworkTarget } from \"./types\";\nimport { fetchNetworkTarget } from \"./worker-network-fetch\";\nimport { json } from \"./worker-context\";\nimport type {\n ChapterEnv,\n Db,\n Route,\n Verified,\n WorkerContext,\n} from \"./worker-context\";\n\nconst IDENTIFIER = /^[a-z][a-zA-Z0-9_]*$/;\nconst MAX_PAGE = 50;\nconst MAX_OFFSET = 10_000;\nconst MAX_SEARCH = 200;\n\nasync function gate(\n req: Request,\n env: ChapterEnv,\n ctx: WorkerContext,\n): Promise<{ response: Response } | { db: Db; user: Verified }> {\n const db = ctx.makeDb(env);\n const user = await ctx.verifyUser(req, env);\n if (!user) return { response: json({ error: \"unauthorized\" }, 401) };\n if (!(await ctx.isAdmin(db, user))) return { response: json({ error: \"forbidden\" }, 403) };\n return { db, user };\n}\n\nfunction integer(\n value: string | null,\n fallback: number,\n min: number,\n max: number,\n): number | null {\n if (value == null || value === \"\") return fallback;\n if (!/^\\d+$/.test(value)) return null;\n const parsed = Number(value);\n return Number.isSafeInteger(parsed) && parsed >= min && parsed <= max ? parsed : null;\n}\n\nfunction projectRecord(\n record: Awaited<ReturnType<typeof listRecords>>[\"records\"][number],\n allowed: readonly string[],\n): NetworkRecord {\n const fields = Object.fromEntries(\n allowed.flatMap((name) =>\n Object.prototype.hasOwnProperty.call(record.fields, name)\n ? [[name, record.fields[name]]]\n : []),\n );\n return {\n id: record.id,\n type: record.type,\n name: record.name,\n ...(record.stage ? { stage: record.stage } : {}),\n fields,\n createdAt: record.createdAt,\n updatedAt: record.updatedAt,\n };\n}\n\n/** GET /api/network/records — a signed, follower-owned CRM projection.\n * Merely possessing the edge secret is insufficient: the signed sender must\n * also be declared in `network.readers`, and only that reader's fields leave. */\nexport const handleNetworkRecords: Route = async (req, url, env, ctx) => {\n if (req.method !== \"GET\" || url.pathname !== \"/api/network/records\") return null;\n const db = ctx.makeDb(env);\n const secret = await getVaultSecret(db as unknown as ChapterDb, \"network_share_secret\");\n const readers = ctx.chapter.network.readers;\n if (!secret || readers.length === 0) return json({ error: \"unauthorized\" }, 401);\n const verified = await verifyFederatedRequest(req, {\n secret,\n senders: readers.map((reader) => reader.id),\n });\n if (!verified.ok) return json({ error: \"unauthorized\", reason: verified.reason }, 401);\n const reader = readers.find((candidate) => candidate.id === verified.sender);\n const type = url.searchParams.get(\"type\") ?? \"\";\n const allowed = reader?.fields[type];\n if (!IDENTIFIER.test(type) || !allowed) return json({ error: \"record type is not shared with this reader\" }, 403);\n const limit = integer(url.searchParams.get(\"limit\"), 25, 1, MAX_PAGE);\n const offset = integer(url.searchParams.get(\"offset\"), 0, 0, MAX_OFFSET);\n const search = (url.searchParams.get(\"search\") ?? \"\").trim();\n if (limit == null || offset == null || search.length > MAX_SEARCH) {\n return json({ error: \"invalid pagination or search parameters\" }, 400);\n }\n const page = await listRecords(\n { crm: ctx.chapter.crm, db: db as never },\n {\n type,\n limit,\n offset,\n ...(search ? { search } : {}),\n sort: { field: \"updatedAt\", dir: \"desc\" },\n },\n );\n const response: NetworkRecordPage = {\n version: 1,\n site: { id: ctx.chapter.id, name: ctx.chapter.name },\n type,\n records: page.records.map((record) => projectRecord(record, allowed)),\n total: page.total,\n limit: page.limit,\n offset: page.offset,\n };\n return json(response);\n};\n\nfunction targetFor(ctx: WorkerContext, id: string): ResolvedNetworkTarget | undefined {\n return ctx.chapter.network.targets.find((target) => target.id === id);\n}\n\nasync function readTargetRecords(\n db: ChapterDb,\n env: ChapterEnv,\n ctx: WorkerContext,\n target: ResolvedNetworkTarget,\n query: URLSearchParams,\n): Promise<{ ok: true; page: NetworkRecordPage } | { ok: false; error: string }> {\n const secret = await getVaultSecret(db, target.secretName);\n if (!secret) return { ok: false, error: \"edge secret is missing\" };\n const destination = new URL(\"/api/network/records\", target.url);\n destination.search = query.toString();\n try {\n const headers = await signFederatedRequest({\n secret,\n sender: ctx.chapter.id,\n method: \"GET\",\n url: destination,\n });\n const response = await fetchNetworkTarget(env, target, destination, {\n headers,\n signal: AbortSignal.timeout(10_000),\n });\n const body = (await response.json().catch(() => null)) as NetworkRecordPage | { error?: string } | null;\n if (\n !response.ok ||\n !body ||\n !(\"version\" in body) ||\n body.version !== 1 ||\n !(\"site\" in body) ||\n body.site.id !== target.id ||\n !Array.isArray(body.records)\n ) {\n const upstream = body && \"error\" in body && typeof body.error === \"string\" ? body.error : undefined;\n return {\n ok: false,\n error: upstream ?? (response.ok ? \"invalid follower record response\" : `follower returned ${response.status}`),\n };\n }\n return { ok: true, page: body };\n } catch (error) {\n return { ok: false, error: error instanceof Error ? error.message : \"record read failed\" };\n }\n}\n\n/** GET /api/admin/network/records — local-admin proxy for one signed follower\n * record window. Browser sessions and follower credentials never cross sites. */\nexport const handleAdminNetworkRecords: Route = async (req, url, env, ctx) => {\n if (req.method !== \"GET\" || url.pathname !== \"/api/admin/network/records\") return null;\n const got = await gate(req, env, ctx);\n if (\"response\" in got) return got.response;\n const targetId = url.searchParams.get(\"targetId\") ?? \"\";\n const type = url.searchParams.get(\"type\") ?? \"\";\n const target = targetFor(ctx, targetId);\n if (!target || !IDENTIFIER.test(type)) return json({ error: \"configured targetId and record type are required\" }, 400);\n const limit = integer(url.searchParams.get(\"limit\"), 25, 1, MAX_PAGE);\n const offset = integer(url.searchParams.get(\"offset\"), 0, 0, MAX_OFFSET);\n const search = (url.searchParams.get(\"search\") ?? \"\").trim();\n if (limit == null || offset == null || search.length > MAX_SEARCH) {\n return json({ error: \"invalid pagination or search parameters\" }, 400);\n }\n const query = new URLSearchParams({ type, limit: String(limit), offset: String(offset) });\n if (search) query.set(\"search\", search);\n const result = await readTargetRecords(\n got.db as unknown as ChapterDb,\n env,\n ctx,\n target,\n query,\n );\n return result.ok ? json(result.page) : json({ error: result.error }, 502);\n};\n","import type { NetworkRecordNote } from \"./network-contract\";\nimport { json } from \"./worker-context\";\nimport type { ChapterEnv, Db, Route, Verified, WorkerContext } from \"./worker-context\";\n\nconst IDENTIFIER = /^[a-z][a-zA-Z0-9_]*$/;\nconst RECORD_ID = /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,255}$/;\nconst MAX_NOTE = 4_000;\n\nasync function gate(\n req: Request,\n env: ChapterEnv,\n ctx: WorkerContext,\n): Promise<{ response: Response } | { db: Db; user: Verified }> {\n const db = ctx.makeDb(env);\n const user = await ctx.verifyUser(req, env);\n if (!user) return { response: json({ error: \"unauthorized\" }, 401) };\n if (!(await ctx.isAdmin(db, user))) return { response: json({ error: \"forbidden\" }, 403) };\n return { db, user };\n}\n\nfunction noteIdentity(url: URL, ctx: WorkerContext) {\n const targetId = url.searchParams.get(\"targetId\") ?? \"\";\n const recordType = url.searchParams.get(\"type\") ?? \"\";\n const recordId = url.searchParams.get(\"recordId\") ?? \"\";\n const configured = ctx.chapter.network.targets.some((target) => target.id === targetId);\n if (!configured || !IDENTIFIER.test(recordType) || !RECORD_ID.test(recordId)) return null;\n return {\n targetId,\n recordType,\n recordId,\n recordKey: `${targetId}:${recordType}:${recordId}`,\n };\n}\n\nfunction asNote(row: Record<string, unknown>): NetworkRecordNote {\n return {\n id: String(row.id),\n targetId: String(row.targetId),\n recordType: String(row.recordType),\n recordId: String(row.recordId),\n body: String(row.body),\n authorId: String(row.authorId),\n ...(typeof row.authorEmail === \"string\" ? { authorEmail: row.authorEmail } : {}),\n createdAt: Number(row.createdAt),\n };\n}\n\n/** GET/POST /api/admin/network/notes — leader-private annotations keyed to a\n * stable follower record identity. No note route exists on the follower. */\nexport const handleAdminNetworkNotes: Route = async (req, url, env, ctx) => {\n if (url.pathname !== \"/api/admin/network/notes\" || (req.method !== \"GET\" && req.method !== \"POST\")) return null;\n const got = await gate(req, env, ctx);\n if (\"response\" in got) return got.response;\n const identity = noteIdentity(url, ctx);\n if (!identity) return json({ error: \"valid targetId, type, and recordId are required\" }, 400);\n if (req.method === \"GET\") {\n const result = await got.db.query({\n networkNotes: {\n $: {\n where: { recordKey: identity.recordKey },\n order: { createdAt: \"desc\" },\n limit: 100,\n },\n },\n });\n return json({ notes: (result.networkNotes ?? []).map((row) => asNote(row as Record<string, unknown>)) });\n }\n const contentLength = Number(req.headers.get(\"content-length\") ?? 0);\n if (contentLength > MAX_NOTE * 2) return json({ error: \"note is too large\" }, 413);\n let input: { body?: unknown };\n try {\n input = (await req.json()) as typeof input;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n const body = typeof input.body === \"string\" ? input.body.trim() : \"\";\n if (!body || body.length > MAX_NOTE) return json({ error: `note must be 1–${MAX_NOTE} characters` }, 400);\n const id = crypto.randomUUID();\n const note: NetworkRecordNote = {\n id,\n targetId: identity.targetId,\n recordType: identity.recordType,\n recordId: identity.recordId,\n body,\n authorId: got.user.userId,\n ...(got.user.email ? { authorEmail: got.user.email } : {}),\n createdAt: Date.now(),\n };\n await got.db.transact([{\n t: \"update\",\n ns: \"networkNotes\",\n id,\n attrs: { ...note, recordKey: identity.recordKey },\n }]);\n return json({ note }, 201);\n};\n","import {\n addActivity,\n CRM_NS,\n getRecord,\n type CrmActivity,\n} from \"@odla-ai/crm\";\nimport { signFederatedRequest, verifyFederatedRequest } from \"@odla-ai/db\";\nimport { getVaultSecret } from \"./auth\";\nimport type { NetworkSharedNote } from \"./network-contract\";\nimport type { ChapterDb, ResolvedNetworkTarget } from \"./types\";\nimport { fetchNetworkTarget } from \"./worker-network-fetch\";\nimport { json } from \"./worker-context\";\nimport type {\n ChapterEnv,\n Db,\n Route,\n Verified,\n WorkerContext,\n} from \"./worker-context\";\n\nconst IDENTIFIER = /^[a-z][a-zA-Z0-9_]*$/;\nconst RECORD_ID = /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,255}$/;\nconst MUTATION_ID = /^[A-Za-z0-9_-]{16,128}$/;\nconst MAX_NOTE = 4_000;\nconst NETWORK_META = \"chapterNetwork\";\n\nasync function gate(\n req: Request,\n env: ChapterEnv,\n ctx: WorkerContext,\n): Promise<{ response: Response } | { db: Db; user: Verified }> {\n const db = ctx.makeDb(env);\n const user = await ctx.verifyUser(req, env);\n if (!user) return { response: json({ error: \"unauthorized\" }, 401) };\n if (!(await ctx.isAdmin(db, user))) return { response: json({ error: \"forbidden\" }, 403) };\n return { db, user };\n}\n\nfunction sharedNote(activity: CrmActivity, sourceId: string): NetworkSharedNote | null {\n const meta = activity.meta?.[NETWORK_META];\n if (!meta || typeof meta !== \"object\" || Array.isArray(meta)) return null;\n const value = meta as Record<string, unknown>;\n if (value.version !== 1 || value.sourceId !== sourceId || typeof value.body !== \"string\") return null;\n return {\n id: activity.id,\n sourceId,\n recordType: String(value.recordType ?? \"\"),\n recordId: activity.recordId,\n body: value.body,\n createdAt: activity.createdAt,\n };\n}\n\nasync function listSharedNotes(db: ChapterDb, sourceId: string, recordId: string): Promise<NetworkSharedNote[]> {\n const result = await db.query({\n [CRM_NS.activity]: {\n $: {\n where: {\n and: [\n { recordId },\n { authorId: `network:${sourceId}` },\n ],\n },\n order: { createdAt: \"desc\" },\n limit: 100,\n },\n },\n });\n return ((result[CRM_NS.activity] ?? []) as unknown as CrmActivity[])\n .flatMap((activity) => {\n const note = sharedNote(activity, sourceId);\n return note ? [note] : [];\n });\n}\n\nfunction sourceLabel(sourceId: string): string {\n return sourceId.split(\"-\").map((word) =>\n word ? `${word[0]?.toUpperCase()}${word.slice(1)}` : word).join(\" \");\n}\n\n/** GET/POST /api/network/shared-notes — a signed, follower-authorized note\n * lane. Writes append to the follower CRM feed, so the follower team sees the\n * note in its normal record workflow. */\nexport const handleNetworkSharedNotes: Route = async (req, url, env, ctx) => {\n if (url.pathname !== \"/api/network/shared-notes\" || (req.method !== \"GET\" && req.method !== \"POST\")) return null;\n if (req.method === \"POST\" && Number(req.headers.get(\"content-length\") ?? 0) > MAX_NOTE * 2) {\n return json({ error: \"note is too large\" }, 413);\n }\n const db = ctx.makeDb(env);\n const secret = await getVaultSecret(db as unknown as ChapterDb, \"network_share_secret\");\n const readers = ctx.chapter.network.readers;\n if (!secret || readers.length === 0) return json({ error: \"unauthorized\" }, 401);\n const verified = await verifyFederatedRequest(req, {\n secret,\n senders: readers.map((reader) => reader.id),\n });\n if (!verified.ok) return json({ error: \"unauthorized\", reason: verified.reason }, 401);\n const reader = readers.find((candidate) => candidate.id === verified.sender);\n const recordType = url.searchParams.get(\"type\") ?? \"\";\n const recordId = url.searchParams.get(\"recordId\") ?? \"\";\n if (!IDENTIFIER.test(recordType) || !RECORD_ID.test(recordId) || !reader?.sharedNotes.includes(recordType)) {\n return json({ error: \"shared notes are not enabled for this reader and record type\" }, 403);\n }\n const record = await getRecord({ crm: ctx.chapter.crm, db: db as never }, recordId);\n if (!record || record.type !== recordType) return json({ error: \"record not found\" }, 404);\n if (req.method === \"GET\") {\n return json({\n version: 1,\n site: { id: ctx.chapter.id, name: ctx.chapter.name },\n notes: await listSharedNotes(db as unknown as ChapterDb, verified.sender, recordId),\n });\n }\n let input: { body?: unknown; mutationId?: unknown };\n try {\n input = JSON.parse(verified.body) as typeof input;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n const body = typeof input.body === \"string\" ? input.body.trim() : \"\";\n const mutationId = typeof input.mutationId === \"string\" ? input.mutationId : \"\";\n if (!body || body.length > MAX_NOTE || !MUTATION_ID.test(mutationId)) {\n return json({ error: `body must be 1–${MAX_NOTE} characters and mutationId must be valid` }, 400);\n }\n const createdAt = Date.now();\n const id = `network:${verified.sender}:${mutationId}`;\n const result = await addActivity(\n {\n crm: ctx.chapter.crm,\n db: db as never,\n now: () => createdAt,\n newId: () => id,\n },\n {\n recordId,\n kind: \"note\",\n body: `Shared by ${sourceLabel(verified.sender)}: ${body}`,\n authorId: `network:${verified.sender}`,\n meta: {\n [NETWORK_META]: {\n version: 1,\n sourceId: verified.sender,\n recordType,\n body,\n },\n },\n mutationId: id,\n },\n );\n const note: NetworkSharedNote = {\n id,\n sourceId: verified.sender,\n recordType,\n recordId,\n body,\n createdAt,\n };\n return json({ version: 1, site: { id: ctx.chapter.id, name: ctx.chapter.name }, note, duplicate: result.duplicate }, 201);\n};\n\nfunction targetFor(ctx: WorkerContext, id: string): ResolvedNetworkTarget | undefined {\n return ctx.chapter.network.targets.find((target) => target.id === id);\n}\n\n/** GET/POST /api/admin/network/shared-notes — an admin-gated leader proxy.\n * The browser never receives the edge secret or a follower credential. */\nexport const handleAdminNetworkSharedNotes: Route = async (req, url, env, ctx) => {\n if (url.pathname !== \"/api/admin/network/shared-notes\" || (req.method !== \"GET\" && req.method !== \"POST\")) return null;\n const got = await gate(req, env, ctx);\n if (\"response\" in got) return got.response;\n const targetId = url.searchParams.get(\"targetId\") ?? \"\";\n const recordType = url.searchParams.get(\"type\") ?? \"\";\n const recordId = url.searchParams.get(\"recordId\") ?? \"\";\n const target = targetFor(ctx, targetId);\n if (!target || !target.sharedNotes.includes(recordType) || !IDENTIFIER.test(recordType) || !RECORD_ID.test(recordId)) {\n return json({ error: \"configured targetId, type, and recordId are required\" }, 400);\n }\n let body = \"\";\n if (req.method === \"POST\") {\n let input: { body?: unknown };\n try {\n input = (await req.json()) as typeof input;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n const note = typeof input.body === \"string\" ? input.body.trim() : \"\";\n if (!note || note.length > MAX_NOTE) return json({ error: `note must be 1–${MAX_NOTE} characters` }, 400);\n body = JSON.stringify({ body: note, mutationId: crypto.randomUUID() });\n }\n const secret = await getVaultSecret(got.db as unknown as ChapterDb, target.secretName);\n if (!secret) return json({ error: \"edge secret is missing\" }, 502);\n const destination = new URL(\"/api/network/shared-notes\", target.url);\n destination.search = new URLSearchParams({ type: recordType, recordId }).toString();\n try {\n const headers = await signFederatedRequest({\n secret,\n sender: ctx.chapter.id,\n method: req.method,\n url: destination,\n ...(body ? { body } : {}),\n });\n const response = await fetchNetworkTarget(env, target, destination, {\n method: req.method,\n headers: { ...headers, ...(body ? { \"content-type\": \"application/json\" } : {}) },\n ...(body ? { body } : {}),\n signal: AbortSignal.timeout(10_000),\n });\n const payload = await response.json().catch(() => null) as Record<string, unknown> | null;\n const site = payload?.site as { id?: unknown } | undefined;\n if (!response.ok || !payload || site?.id !== target.id) {\n return json({\n error: typeof payload?.error === \"string\" ? payload.error : `follower returned ${response.status}`,\n }, 502);\n }\n return json(payload, req.method === \"POST\" ? 201 : 200);\n } catch (error) {\n return json({ error: error instanceof Error ? error.message : \"shared note request failed\" }, 502);\n }\n};\n","// Public intake for prospective chapter formation. The host renders the form\n// in its own brand; this route exposes only configured fields and writes one\n// normal CRM record into the configured workflow.\nimport { createRecord } from \"@odla-ai/crm\";\nimport { applicationIdForSubmission } from \"./application-id\";\nimport { chapterFlowFieldContract } from \"./flow-fields\";\nimport { json } from \"./worker-context\";\nimport type { Route } from \"./worker-context\";\n\nconst SUBMISSION = /^[A-Za-z0-9_-]{8,128}$/;\n\n/** GET /api/formation/config and POST /api/formation/applications. */\nexport const handleFormation: Route = async (req, url, env, ctx) => {\n const formation = ctx.chapter.formation;\n if (!formation.enabled) return null;\n\n if (req.method === \"GET\" && url.pathname === \"/api/formation/config\") {\n const fieldContract = chapterFlowFieldContract(ctx.chapter, \"formation\");\n return json({\n type: formation.type,\n fieldContract,\n // Backward compatibility for hosts that consumed the original array.\n fields: fieldContract.fields,\n });\n }\n if (req.method !== \"POST\" || url.pathname !== \"/api/formation/applications\") return null;\n\n const raw = await req.text();\n if (raw.length > formation.bodyCap) return json({ error: \"request body too large\" }, 413);\n let body: Record<string, unknown>;\n try {\n body = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n if (!body || typeof body !== \"object\" || Array.isArray(body)) return json({ error: \"JSON body must be an object\" }, 400);\n\n const submissionId = typeof body.submissionId === \"string\" ? body.submissionId : undefined;\n if (submissionId && !SUBMISSION.test(submissionId)) {\n return json({ error: \"submissionId must be an 8–128 character base64url value\" }, 400);\n }\n const allowed = new Set([...formation.required, ...formation.optional]);\n const unknown = Object.keys(body).filter((field) => field !== \"submissionId\" && !allowed.has(field));\n if (unknown.length) return json({ error: `field \"${unknown[0]}\" is not accepted` }, 400);\n for (const field of formation.required) {\n const value = body[field];\n if (typeof value !== \"string\" || value.trim() === \"\") return json({ error: `${field} is required` }, 400);\n }\n const input: Record<string, unknown> = {};\n for (const field of allowed) {\n const value = body[field];\n if (value === undefined) continue;\n const cap = formation.maxLen[field] ?? formation.defaultMaxLen;\n if (typeof value === \"string\") {\n if (value.length > cap) return json({ error: `${field} exceeds ${cap} characters` }, 400);\n input[field] = value.trim();\n } else if (Array.isArray(value)) {\n input[field] = value.slice(0, 100);\n } else {\n input[field] = value;\n }\n }\n\n const db = ctx.makeDb(env);\n const id = submissionId\n ? await applicationIdForSubmission(`formation:${ctx.chapter.id}:${submissionId}`)\n : crypto.randomUUID();\n try {\n const created = await createRecord(\n {\n crm: ctx.chapter.crm,\n db: db as never,\n now: () => Date.now(),\n newId: () => id,\n },\n {\n type: formation.type,\n input,\n ...(submissionId ? { mutationId: `formation:${ctx.chapter.id}:${submissionId}` } : {}),\n },\n );\n return json({\n id,\n duplicate: created.duplicate,\n status: created.record.stage ?? null,\n }, created.duplicate ? 200 : 201);\n } catch (error) {\n const detail = error && typeof error === \"object\" && \"fields\" in error\n ? (error as { fields?: unknown }).fields\n : undefined;\n return json({\n error: error instanceof Error ? error.message : \"invalid formation application\",\n ...(detail ? { fields: detail } : {}),\n }, 400);\n }\n};\n","import { signFederatedRequest } from \"@odla-ai/db\";\nimport {\n SIGNUP_CONTROL_PATH,\n type SignupControlEnvelope,\n type SignupControlReceipt,\n} from \"./signup-control-contract\";\n\n/** Inputs for one signed hub-to-follower signup-control request. */\nexport interface SignupControlDeliveryOptions {\n secret: string;\n sender: string;\n targetUrl: string | URL;\n envelope: SignupControlEnvelope;\n fetch?: typeof globalThis.fetch;\n}\n\n/** Build and send one signed desired-state delivery. Durable retry belongs to the hub outbox. */\nexport async function deliverSignupControl(options: SignupControlDeliveryOptions): Promise<SignupControlReceipt> {\n const destination = new URL(SIGNUP_CONTROL_PATH, options.targetUrl);\n const body = JSON.stringify(options.envelope);\n const signed = await signFederatedRequest({\n secret: options.secret,\n sender: options.sender,\n method: \"POST\",\n url: destination,\n body,\n });\n const response = await (options.fetch ?? globalThis.fetch)(destination, {\n method: \"POST\",\n headers: { ...signed, \"content-type\": \"application/json\" },\n body,\n });\n const result = await response.json() as SignupControlReceipt | { reason?: string; error?: string };\n if (!response.ok || (!(\"ok\" in result) || result.ok !== true)) {\n const rejection = result as { reason?: string; error?: string };\n throw new Error(`signup control rejected (${response.status}): ${rejection.reason ?? rejection.error ?? \"unknown\"}`);\n }\n return result;\n}\n","import { signFederatedRequest } from \"@odla-ai/db\";\nimport {\n MEMBER_CONTENT_CONTROL_PATH,\n type MemberContentEnvelope,\n type MemberContentReceipt,\n} from \"./member-content\";\n\n/** Inputs for one signed Parent → Chapter member-content delivery. */\nexport interface MemberContentDeliveryOptions {\n secret: string;\n sender: string;\n targetUrl: string | URL;\n envelope: MemberContentEnvelope;\n fetch?: typeof globalThis.fetch;\n}\n\n/** Deliver one exact revision. Durable retry and approval remain Parent concerns. */\nexport async function deliverMemberContent(options: MemberContentDeliveryOptions): Promise<MemberContentReceipt> {\n const destination = new URL(MEMBER_CONTENT_CONTROL_PATH, options.targetUrl);\n const body = JSON.stringify(options.envelope);\n const signed = await signFederatedRequest({\n secret: options.secret,\n sender: options.sender,\n method: \"POST\",\n url: destination,\n body,\n });\n const response = await (options.fetch ?? globalThis.fetch)(destination, {\n method: \"POST\",\n headers: { ...signed, \"content-type\": \"application/json\" },\n body,\n });\n const result = await response.json() as MemberContentReceipt | { reason?: string; error?: string };\n if (!response.ok || !(\"ok\" in result) || result.ok !== true) {\n const failure = result as { reason?: string; error?: string };\n throw new Error(`member content rejected (${response.status}): ${failure.reason ?? failure.error ?? \"unknown\"}`);\n }\n return result;\n}\n","import { signFederatedRequest } from \"@odla-ai/db\";\nimport {\n ADMISSION_GRANTS_PATH,\n type AdmissionGrantEnvelope,\n type AdmissionGrantReceipt,\n} from \"./admission-grants-contract\";\n\n/** Inputs required to sign and deliver one Parent admission revision. */\nexport interface AdmissionGrantDeliveryOptions {\n secret: string;\n sender: string;\n targetUrl: string | URL;\n envelope: AdmissionGrantEnvelope;\n fetch?: typeof globalThis.fetch;\n}\n\n/** Deliver one signed Parent admission revision. Durable retry belongs upstream. */\nexport async function deliverAdmissionGrants(options: AdmissionGrantDeliveryOptions): Promise<AdmissionGrantReceipt> {\n const destination = new URL(ADMISSION_GRANTS_PATH, options.targetUrl);\n const body = JSON.stringify(options.envelope);\n const signed = await signFederatedRequest({\n secret: options.secret,\n sender: options.sender,\n method: \"POST\",\n url: destination,\n body,\n });\n const response = await (options.fetch ?? globalThis.fetch)(destination, {\n method: \"POST\",\n headers: { ...signed, \"content-type\": \"application/json\" },\n body,\n });\n const result = await response.json() as AdmissionGrantReceipt | { reason?: string; error?: string };\n if (!response.ok || !(\"ok\" in result) || result.ok !== true) {\n const failure = result as { reason?: string; error?: string };\n throw new Error(`admission grants rejected (${response.status}): ${failure.reason ?? failure.error ?? \"unknown\"}`);\n }\n return result;\n}\n","import type { SignupControlTheme } from \"./signup-control-contract\";\n\n/** Stable marker a static document can place where managed signup tokens belong. */\nexport const SIGNUP_CONTROL_THEME_MARKER = \"<!--odla:signup-control-theme-->\" as const;\n/** Stable id shared by the server renderer and browser hydration helper. */\nexport const SIGNUP_CONTROL_THEME_STYLE_ID = \"odla-signup-control-theme\" as const;\n\nconst TOKEN_NAME = /^--ui-[a-z0-9][a-z0-9-]{0,94}$/;\nconst DIGEST = /^sha256:[0-9a-f]{64}$/;\nconst UNSAFE_VALUE = /[\\u0000-\\u001f\\u007f\\\\<>{};]|\\/\\*|\\*\\/|(?:^|[^a-z])(?:url|expression)\\s*\\(|@import/i;\nconst MAX_TOKENS = 256;\nconst MAX_VALUE_LENGTH = 1_000;\nconst MAX_SERIALIZED_LENGTH = 65_536;\n\n/** The active revision shape exposed by `GET /api/join-config`. */\nexport interface SignupControlThemeRevision {\n revision: number;\n digest: string;\n theme?: SignupControlTheme;\n}\n\n/** Identity shared by initial HTML, response caching, and client hydration. */\nexport interface SignupControlThemeMetadata {\n source: \"active\" | \"bootstrap\";\n revision: number | null;\n digest: string | null;\n /** Include this value in any host-owned cache key for transformed HTML. */\n cacheKey: string;\n}\n\n/** A validated style block ready to place in an HTML head. */\nexport interface SignupControlThemeHead {\n css: string;\n head: string;\n metadata: SignupControlThemeMetadata;\n}\n\n/** Minimal DOM surface required by {@link hydrateSignupControlTheme}. */\nexport interface SignupControlThemeStyleTarget {\n textContent: string | null;\n getAttribute(name: string): string | null;\n setAttribute(name: string, value: string): void;\n removeAttribute(name: string): void;\n}\n\n/** Host-owned fallback inputs shared by server rendering and hydration. */\nexport interface SignupControlThemeOptions {\n /** Local site-owned tokens used only when no active managed revision exists. */\n bootstrapTokens?: Readonly<Record<string, string | number>>;\n}\n\nfunction validatedTokens(\n input: Readonly<Record<string, string | number>> | undefined,\n): Readonly<Record<string, string>> {\n const entries = Object.entries(input ?? {});\n if (entries.length > MAX_TOKENS) {\n throw new TypeError(`signup-control theme supports at most ${MAX_TOKENS} tokens`);\n }\n const tokens: Record<string, string> = {};\n let serializedLength = 0;\n for (const [name, raw] of entries.sort(([left], [right]) => left.localeCompare(right))) {\n if (!TOKEN_NAME.test(name)) {\n throw new TypeError(`signup-control theme token \"${name}\" must be an allowlisted --ui-* property`);\n }\n if ((typeof raw !== \"string\" && typeof raw !== \"number\") ||\n (typeof raw === \"number\" && !Number.isFinite(raw))) {\n throw new TypeError(`signup-control theme token \"${name}\" must be a finite string or number`);\n }\n const value = String(raw).trim();\n if (!value || value.length > MAX_VALUE_LENGTH || UNSAFE_VALUE.test(value)) {\n throw new TypeError(`signup-control theme token \"${name}\" has an unsafe or oversized value`);\n }\n serializedLength += name.length + value.length + 4;\n if (serializedLength > MAX_SERIALIZED_LENGTH) {\n throw new TypeError(\"signup-control theme exceeds the serialized size bound\");\n }\n tokens[name] = value;\n }\n return tokens;\n}\n\nfunction cssFor(tokens: Readonly<Record<string, string>>): string {\n const declarations = Object.entries(tokens).map(([name, value]) => ` ${name}: ${value};`);\n return declarations.length ? `:root {\\n${declarations.join(\"\\n\")}\\n}` : \"\";\n}\n\nfunction stateFor(\n revision: SignupControlThemeRevision | null,\n options: SignupControlThemeOptions,\n): { css: string; metadata: SignupControlThemeMetadata } {\n if (!revision) {\n return {\n css: cssFor(validatedTokens(options.bootstrapTokens)),\n metadata: { source: \"bootstrap\", revision: null, digest: null, cacheKey: \"signup-control:bootstrap\" },\n };\n }\n if (!Number.isSafeInteger(revision.revision) || revision.revision < 1 || !DIGEST.test(revision.digest)) {\n throw new TypeError(\"signup-control theme revision metadata is invalid\");\n }\n return {\n css: cssFor(validatedTokens(revision.theme?.tokens)),\n metadata: {\n source: \"active\",\n revision: revision.revision,\n digest: revision.digest,\n cacheKey: `signup-control:${revision.digest}`,\n },\n };\n}\n\nfunction attributes(metadata: SignupControlThemeMetadata): string {\n return [\n `id=\"${SIGNUP_CONTROL_THEME_STYLE_ID}\"`,\n `data-signup-control-source=\"${metadata.source}\"`,\n `data-signup-control-cache-key=\"${metadata.cacheKey}\"`,\n ...(metadata.revision === null ? [] : [`data-signup-control-revision=\"${metadata.revision}\"`]),\n ...(metadata.digest === null ? [] : [`data-signup-control-digest=\"${metadata.digest}\"`]),\n ].join(\" \");\n}\n\n/**\n * Render validated signup-control tokens for the initial HTML head. Passing\n * `null` emits the deterministic local bootstrap state; it never performs I/O.\n */\nexport function renderSignupControlThemeHead(\n revision: SignupControlThemeRevision | null,\n options: SignupControlThemeOptions = {},\n): SignupControlThemeHead {\n const { css, metadata } = stateFor(revision, options);\n return { css, metadata, head: `<style ${attributes(metadata)}>${css}</style>` };\n}\n\n/**\n * Replace the stable marker (preferred), an earlier Chapter style block, or the\n * closing head tag. The returned HTML always contains exactly one managed block.\n */\nexport function injectSignupControlThemeHead(\n html: string,\n rendered: SignupControlThemeHead,\n marker: string = SIGNUP_CONTROL_THEME_MARKER,\n): string {\n const existing = /<style\\b(?=[^>]*\\bid\\s*=\\s*[\"']odla-signup-control-theme[\"'])[^>]*>[\\s\\S]*?<\\/style>/gi;\n const existingBlocks = html.match(existing) ?? [];\n if (existingBlocks.length > 1) {\n throw new TypeError(\"signup-control theme style block must appear at most once\");\n }\n if (existingBlocks.length === 1) return html.replace(existing, rendered.head);\n const markerIndex = html.indexOf(marker);\n if (markerIndex >= 0) {\n if (html.indexOf(marker, markerIndex + marker.length) >= 0) {\n throw new TypeError(\"signup-control theme marker must appear exactly once\");\n }\n return `${html.slice(0, markerIndex)}${rendered.head}${html.slice(markerIndex + marker.length)}`;\n }\n const closingHead = html.search(/<\\/head\\s*>/i);\n if (closingHead < 0) throw new TypeError(\"signup-control theme requires an HTML head\");\n return `${html.slice(0, closingHead)}${rendered.head}${html.slice(closingHead)}`;\n}\n\n/**\n * Apply a newly fetched revision to the server-rendered style element. When the\n * revision and digest already match, this performs no writes and returns false,\n * so hydration cannot cause a visual token change.\n */\nexport function hydrateSignupControlTheme(\n target: SignupControlThemeStyleTarget,\n revision: SignupControlThemeRevision | null,\n options: SignupControlThemeOptions = {},\n): boolean {\n const next = stateFor(revision, options);\n const currentSource = target.getAttribute(\"data-signup-control-source\");\n const currentRevision = target.getAttribute(\"data-signup-control-revision\");\n const currentDigest = target.getAttribute(\"data-signup-control-digest\");\n if (currentSource === next.metadata.source &&\n currentRevision === (next.metadata.revision === null ? null : String(next.metadata.revision)) &&\n currentDigest === next.metadata.digest) {\n return false;\n }\n target.textContent = next.css;\n target.setAttribute(\"data-signup-control-source\", next.metadata.source);\n target.setAttribute(\"data-signup-control-cache-key\", next.metadata.cacheKey);\n if (next.metadata.revision === null) target.removeAttribute(\"data-signup-control-revision\");\n else target.setAttribute(\"data-signup-control-revision\", String(next.metadata.revision));\n if (next.metadata.digest === null) target.removeAttribute(\"data-signup-control-digest\");\n else target.setAttribute(\"data-signup-control-digest\", next.metadata.digest);\n return true;\n}\n","import { signupControlDigest } from \"./signup-control-canonical\";\nimport { loadActiveSignupControl } from \"./signup-control-store\";\nimport {\n injectSignupControlThemeHead,\n renderSignupControlThemeHead,\n type SignupControlThemeHead,\n type SignupControlThemeOptions,\n type SignupControlThemeRevision,\n} from \"./signup-control-theme\";\nimport { validateSignupControlDocument } from \"./signup-control-validate\";\nimport type { ChapterDb } from \"./types\";\n\n/** Inputs required to resolve one follower-local active signup theme. */\nexport interface ActiveSignupControlThemeOptions extends SignupControlThemeOptions {\n /** Follower-local database client. No controlling-hub request is performed. */\n db: ChapterDb;\n chapterId: string;\n environment: string;\n /** Optional host marker; defaults to `SIGNUP_CONTROL_THEME_MARKER`. */\n marker?: string;\n}\n\n/** Transformed HTML plus the exact theme and cache identity it contains. */\nexport interface ActiveSignupControlHtml {\n html: string;\n theme: SignupControlThemeHead;\n}\n\nasync function activeTheme(options: ActiveSignupControlThemeOptions): Promise<SignupControlThemeRevision | null> {\n const active = await loadActiveSignupControl(options.db, options.chapterId, options.environment);\n if (!active) return null;\n const checked = validateSignupControlDocument(active.document);\n if (!checked.ok) throw new TypeError(`active signup-control document is invalid: ${checked.errors.join(\"; \")}`);\n const document = checked.value;\n if (document.revision !== active.revision || document.target.chapterId !== options.chapterId ||\n document.target.environment !== options.environment || active.digest !== await signupControlDigest(document)) {\n throw new TypeError(\"active signup-control revision metadata or digest is invalid\");\n }\n return { revision: active.revision, digest: active.digest, theme: document.theme };\n}\n\n/**\n * Transform trusted host HTML with the follower-local last-known-good signup\n * theme. A missing active revision uses the documented bootstrap state; a read\n * failure or corrupt active row fails closed instead of fetching the hub.\n */\nexport async function renderActiveSignupControlHtml(\n html: string,\n options: ActiveSignupControlThemeOptions,\n): Promise<ActiveSignupControlHtml> {\n const theme = renderSignupControlThemeHead(await activeTheme(options), {\n bootstrapTokens: options.bootstrapTokens,\n });\n return { html: injectSignupControlThemeHead(html, theme, options.marker), theme };\n}\n\nasync function contentEtag(html: string): Promise<string> {\n const bytes = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(html));\n const hex = Array.from(new Uint8Array(bytes), (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n return `W/\"sha256-${hex}\"`;\n}\n\n/**\n * Transform an HTML response and make the cache contract safe by default.\n * `no-store` prevents a prior digest from surviving activation; hosts that own\n * a cache may instead key it with `result.theme.metadata.cacheKey` from\n * {@link renderActiveSignupControlHtml}.\n */\nexport async function withActiveSignupControlTheme(\n response: Response,\n options: ActiveSignupControlThemeOptions,\n): Promise<Response> {\n if (!response.ok || !(response.headers.get(\"content-type\") ?? \"\").toLowerCase().includes(\"text/html\")) {\n throw new TypeError(\"signup-control theme can only transform a successful HTML response\");\n }\n const rendered = await renderActiveSignupControlHtml(await response.text(), options);\n const headers = new Headers(response.headers);\n headers.delete(\"content-length\");\n headers.set(\"cache-control\", \"no-store\");\n headers.set(\"etag\", await contentEtag(rendered.html));\n headers.set(\"x-odla-signup-control-digest\", rendered.theme.metadata.digest ?? \"bootstrap\");\n if (rendered.theme.metadata.revision === null) headers.delete(\"x-odla-signup-control-revision\");\n else headers.set(\"x-odla-signup-control-revision\", String(rendered.theme.metadata.revision));\n return new Response(rendered.html, { status: response.status, statusText: response.statusText, headers });\n}\n","// chapterWorker — the Cloudflare Worker for a chapter/hub site. This entry\n// (@odla-ai/chapter/worker) is separate from the core so the CLI can load\n// odla.config.mjs without pulling in worker-runtime deps.\n//\n// The worker is the ONLY thing that talks to odla-db, using the app key\n// (ODLA_API_KEY), which bypasses the deny-all rules. Browsers never receive a\n// db credential. Access is admin-only: a request is authorized when its Clerk\n// session JWT verifies AND the user's role (a JWT claim, or a row in the\n// Studio-seeded `admins` allowlist) is an admin rung.\n//\n// The env typing + auth plumbing live in ./worker-context; the route handlers in\n// ./worker-routes. This entry only builds the context and runs the routes in\n// order — first match wins, else the static site (ASSETS).\n//\n// hub mode routes: GET /api/config, GET /api/me, /api/crm/*, POST\n// /api/network/{shared,snapshot,records}, else ASSETS. chapter mode adds the public member surface:\n// GET /api/join-config and POST /api/applications (idempotent).\nimport { createWorkerContext } from \"./worker-context\";\nimport type { ChapterEnv, ChapterWorkerOptions, Route } from \"./worker-context\";\nimport { handleConfig, handleCrm, handleHealth, handleMe, handleMember } from \"./worker-routes\";\nimport { handleNetworkShared } from \"./worker-routes-network-receive\";\nimport { handleSignupControl } from \"./worker-routes-signup-control\";\nimport {\n handleAdminMemberContent,\n handleMemberContent,\n handleMemberContentControl,\n} from \"./worker-routes-member-content\";\nimport { handleAdmissionGrants } from \"./worker-routes-admission-grants\";\nimport { handleAdminAdmissionGrants } from \"./worker-routes-admin-admission\";\nimport { handleSchedule } from \"./worker-routes-schedule\";\nimport { handlePayments } from \"./worker-routes-payments\";\nimport { handleGifts } from \"./worker-routes-gifts\";\nimport { handleAdminMeetings, handleAdminScheduling } from \"./worker-routes-admin\";\nimport { handleAdminCrmSync, handleAdminPeople, handleAdminPeopleAccess, handleAdminPeopleRole } from \"./worker-routes-admin-people\";\nimport { handleAdminClerkPrivateProfileSync } from \"./worker-routes-admin-clerk\";\nimport { handleAdminDashboard, handleAdminBilling } from \"./worker-routes-admin-dashboard\";\nimport { handleAdminMeetingReschedule, handleAdminMeetingCancel, handleAdminApprove, handleAdminRefund, handleAdminApplicationPatch } from \"./worker-routes-admin-lifecycle\";\nimport { handleAdminGroupEmail, handleAdminEmailLog, handleAdminEmailTest, handleAdminComms } from \"./worker-routes-admin-comms\";\nimport {\n handleAdminNetworkPush,\n handleAdminNetworkRollup,\n handleAdminNetworkTargets,\n handleNetworkSnapshot,\n} from \"./worker-routes-network\";\nimport {\n handleAdminNetworkRecords,\n handleNetworkRecords,\n} from \"./worker-routes-network-records\";\nimport { handleAdminNetworkNotes } from \"./worker-routes-network-notes\";\nimport {\n handleAdminNetworkSharedNotes,\n handleNetworkSharedNotes,\n} from \"./worker-routes-network-shared-notes\";\nimport { handleFormation } from \"./worker-routes-formation\";\nimport { json } from \"./worker-context\";\n\n// The route seam: a wrapping worker can build its own routes + reuse chapter's\n// auth by composing against these.\nexport { createWorkerContext } from \"./worker-context\";\nexport type { ChapterEnv, ChapterWorkerOptions, WorkerContext, Route } from \"./worker-context\";\nexport { deliverSignupControl } from \"./signup-control-delivery\";\nexport { deliverMemberContent } from \"./member-content-delivery\";\nexport { deliverAdmissionGrants } from \"./admission-grants-delivery\";\nexport type { AdmissionGrantDeliveryOptions } from \"./admission-grants-delivery\";\nexport type { SignupControlDeliveryOptions } from \"./signup-control-delivery\";\nexport type { MemberContentDeliveryOptions } from \"./member-content-delivery\";\nexport {\n renderActiveSignupControlHtml,\n withActiveSignupControlTheme,\n} from \"./signup-control-theme-worker\";\nexport type {\n ActiveSignupControlHtml,\n ActiveSignupControlThemeOptions,\n} from \"./signup-control-theme-worker\";\n\n// First-match-wins order. Host routes (options.routes) run BEFORE these.\nconst BUILTIN_ROUTES: Route[] = [\n handleHealth,\n handleConfig,\n handleMe,\n handleCrm,\n handleNetworkShared,\n handleSignupControl,\n handleMemberContentControl,\n handleAdmissionGrants,\n handleNetworkSnapshot,\n handleNetworkRecords,\n handleNetworkSharedNotes,\n handleFormation,\n handleMember,\n handleMemberContent,\n handleGifts,\n handleSchedule,\n handlePayments,\n handleAdminMeetings,\n handleAdminScheduling,\n // Roster + identity\n handleAdminPeople,\n handleAdminPeopleAccess,\n handleAdminPeopleRole,\n handleAdminCrmSync,\n handleAdminAdmissionGrants,\n handleAdminClerkPrivateProfileSync,\n // Aggregation\n handleAdminDashboard,\n handleAdminBilling,\n handleAdminMemberContent,\n // Lifecycle actions\n handleAdminMeetingReschedule,\n handleAdminMeetingCancel,\n handleAdminApprove,\n handleAdminRefund,\n handleAdminApplicationPatch,\n // Email + comms\n handleAdminGroupEmail,\n handleAdminEmailLog,\n handleAdminEmailTest,\n handleAdminComms,\n // Leader → follower record delivery\n handleAdminNetworkTargets,\n handleAdminNetworkRollup,\n handleAdminNetworkPush,\n handleAdminNetworkRecords,\n handleAdminNetworkNotes,\n handleAdminNetworkSharedNotes,\n // API requests must never fall through to an SPA asset response. Hosts still\n // get first refusal through options.routes, then this terminates unknown API\n // paths with an explicit machine-readable 404.\n async (_req, url) => url.pathname.startsWith(\"/api/\")\n ? json({ error: \"not found\" }, 404)\n : null,\n];\n\n/**\n * Build the Cloudflare `ExportedHandler` for a chapter/hub site: Clerk-JWT\n * verification, the source-aware admin gate, the mounted @odla-ai/crm routes, the\n * hub→chapter network projection, and the static-asset fallback. Hub mode serves\n * /api/health, /api/config, /api/me, /api/crm/*, /api/network/*; chapter mode\n * adds the public member surface (join/apply/pay/book) and the admin surface\n * (/api/admin/*).\n *\n * A wrapping site adds its own routes via `options.routes` — each receives the\n * same {@link WorkerContext} the built-ins get (so it reuses chapter's JWT\n * verify, db client, and role resolution instead of duplicating them), and runs\n * BEFORE the built-ins so it can override or alias a path.\n *\n * Observability is a host concern, not a chapter dependency. To trace, wrap the\n * result in your worker entry — `export default withObservability(chapterWorker(\n * { chapter }))` — with `withObservability` from `@odla-ai/o11y`. Sites that\n * don't run o11y bundle `@odla-ai/chapter/worker` without installing it.\n */\nexport function chapterWorker(options: ChapterWorkerOptions) {\n const ctx = createWorkerContext(options);\n const routes: Route[] = [...(options.routes ?? []), ...BUILTIN_ROUTES];\n return {\n async fetch(req: Request, env: ChapterEnv): Promise<Response> {\n const url = new URL(req.url);\n for (const route of routes) {\n const res = await route(req, url, env, ctx);\n if (res) return res;\n }\n // Everything else is the static site.\n return env.ASSETS.fetch(req);\n },\n };\n}\n"],"mappings":";AAMA,SAAS,iBAAiB;AAC1B,SAAS,oBAAoB,iBAAiB;;;AC2BvC,SAAS,cAAc,SAAkC,MAA4B;AAC1F,QAAM,MAAM,QAAQ,KAAK,KAAK;AAC9B,SAAO,OAAO,QAAQ,YAAY,KAAK,OAAO,SAAS,GAAG,IAAI,MAAO,KAAK,OAAO,CAAC;AACpF;AAGO,SAAS,YAAY,MAAc,MAA6B;AACrE,SAAO,SAAS,KAAK;AACvB;AA0BO,SAAS,cAAc,KAAqC;AACjE,QAAM,EAAE,KAAK,IAAI;AACjB,MAAI,CAAC,KAAK,OAAO,SAAS,IAAI,OAAO,GAAG;AACtC,WAAO,EAAE,IAAI,OAAO,QAAQ,KAAK,OAAO,wBAAwB,KAAK,OAAO,KAAK,IAAI,CAAC,GAAG;AAAA,EAC3F;AACA,MAAI,IAAI,YAAY,IAAI,UAAU;AAChC,WAAO,EAAE,IAAI,OAAO,QAAQ,KAAK,OAAO,kCAAkC;AAAA,EAC5E;AACA,MAAI,IAAI,iBAAiB,CAAC,IAAI,cAAc;AAC1C,WAAO,EAAE,IAAI,OAAO,QAAQ,KAAK,OAAO,uEAAuE;AAAA,EACjH;AACA,QAAM,eAAe,IAAI,YAAY,KAAK,aAAa,IAAI,sBAAsB,KAAK;AACtF,MAAI,KAAK,eAAe,gBAAgB,CAAC,IAAI,cAAc;AACzD,WAAO,EAAE,IAAI,OAAO,QAAQ,KAAK,OAAO,6CAA6C,KAAK,SAAS,GAAG;AAAA,EACxG;AACA,SAAO,EAAE,IAAI,KAAK;AACpB;AAaA,eAAsB,eAAe,IAAiB,MAA2C;AAC/F,MAAI;AACF,UAAM,QAAQ,MAAM,GAAG,QAAQ,IAAI,IAAI;AACvC,WAAO,OAAO,UAAU,YAAY,UAAU,KAAK,QAAQ;AAAA,EAC7D,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;ADxCO,IAAM,OAAO,CAAC,MAAe,SAAS,QAC3C,IAAI,SAAS,KAAK,UAAU,IAAI,GAAG,EAAE,QAAQ,SAAS,EAAE,gBAAgB,mBAAmB,EAAE,CAAC;AAQzF,SAAS,oBAAoB,SAA+B;AACjE,QAAM,EAAE,QAAQ,IAAI;AACpB,QAAM,OAAO,QAAQ;AACrB,QAAM,UAAU,QAAQ,eAAe;AAEvC,MAAI,oBAAgE;AACpE,QAAM,eAAe,oBAAI,IAAmD;AAE5E,iBAAe,gBAAgB,KAAwC;AACrE,QAAI,qBAAqB,KAAK,IAAI,IAAI,kBAAkB,KAAK,IAAI,IAAQ,QAAO,kBAAkB;AAClG,UAAM,MAAM,MAAM,MAAM,GAAG,IAAI,aAAa,kBAAkB,IAAI,WAAW,sBAAsB,IAAI,QAAQ,EAAE;AACjH,QAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM,+BAA+B,IAAI,MAAM,EAAE;AACxE,UAAM,QAAS,MAAM,IAAI,KAAK;AAC9B,wBAAoB,EAAE,OAAO,IAAI,KAAK,IAAI,EAAE;AAC5C,WAAO;AAAA,EACT;AAEA,iBAAe,WAAW,KAAc,KAA2C;AACjF,UAAM,SAAS,IAAI,QAAQ,IAAI,eAAe,KAAK;AACnD,QAAI,CAAC,OAAO,WAAW,SAAS,EAAG,QAAO;AAC1C,UAAM,QAAQ,OAAO,MAAM,CAAC;AAC5B,UAAM,EAAE,OAAO,IAAI,MAAM,gBAAgB,GAAG;AAC5C,QAAI,CAAC,OAAQ,QAAO;AACpB,QAAI,OAAO,aAAa,IAAI,MAAM;AAClC,QAAI,CAAC,MAAM;AACT,aAAO,mBAAmB,IAAI,IAAI,GAAG,MAAM,wBAAwB,CAAC;AACpE,mBAAa,IAAI,QAAQ,IAAI;AAAA,IAC/B;AACA,QAAI;AACF,YAAM,EAAE,QAAQ,IAAI,MAAM,UAAU,OAAO,MAAM,EAAE,OAAO,CAAC;AAC3D,UAAI,CAAC,QAAQ,IAAK,QAAO;AACzB,aAAO;AAAA,QACL,QAAQ,QAAQ;AAAA,QAChB,OAAO,OAAO,QAAQ,UAAU,WAAW,QAAQ,QAAQ;AAAA,QAC3D;AAAA,MACF;AAAA,IACF,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAEA,WAAS,OAAO,KAAqB;AACnC,WAAO,UAAU,EAAE,OAAO,IAAI,aAAa,YAAY,IAAI,cAAc,UAAU,IAAI,cAAc,CAAC;AAAA,EACxG;AAIA,iBAAe,aAAa,IAAQ,OAA6C;AAC/E,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,EAAE,OAAO,IAAI,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,MAAM,YAAY,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC;AACxG,WAAO,MAAM,QAAQ,MAAM,KAAK,OAAO,SAAS;AAAA,EAClD;AAGA,iBAAe,kBAAkB,IAAQ,OAA6C;AACpF,QAAI,CAAC,KAAK,eAAe,CAAC,MAAO,QAAO;AACxC,UAAM,EAAE,YAAY,IAAI,MAAM,GAAG,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,MAAM,YAAY,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC;AAClH,WAAO,MAAM,QAAQ,WAAW,KAAK,YAAY,SAAS;AAAA,EAC5D;AAIA,iBAAe,QAAQ,IAAQ,GAA8B;AAC3D,QAAI,KAAK,WAAW,QAAS,QAAO,cAAc,EAAE,SAAS,IAAI;AACjE,WAAQ,MAAM,aAAa,IAAI,EAAE,KAAK,IAAK,KAAK,YAAa,KAAK,OAAO,CAAC;AAAA,EAC5E;AAGA,iBAAe,QAAQ,IAAQ,GAA+B;AAC5D,QAAI,KAAK,WAAW,QAAS,QAAO,YAAY,cAAc,EAAE,SAAS,IAAI,GAAG,IAAI;AACpF,WAAO,aAAa,IAAI,EAAE,KAAK;AAAA,EACjC;AAEA,WAAS,UAAU,KAAiB;AAClC,QAAI,CAAC,IAAI,cAAc,CAAC,IAAI,WAAY,QAAO;AAC/C,UAAM,UAAU,IAAI;AACpB,WAAO;AAAA,MACL,MAAM,KAAK,SAAuD;AAChE,eAAO,QAAQ,KAAK,OAAO;AAAA,MAC7B;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,SAAS,MAAM,SAAS,iBAAiB,YAAY,QAAQ,cAAc,mBAAmB,SAAS,SAAS,UAAU;AACrI;;;AEzJA,SAAS,uBAAuB;;;ACiBhC,eAAsB,gCACpB,KACA,KACA,UAAwB,OACqB;AAC7C,QAAM,QAAQ,IAAI,QAAQ,IAAI,eAAe,GAAG,MAAM,mBAAmB;AACzE,QAAM,iBAAiB,IAAI;AAC3B,QAAM,iBAAiB,IAAI,aAAa,SACpC,IAAI,cACJ,GAAG,IAAI,WAAW,KAAK,IAAI,QAAQ;AACvC,MACE,CAAC,SACD,IAAI,gBAAgB,kBACpB,OAAO,mBAAmB,YAC1B,CAAC,iBAAiB,KAAK,cAAc,EACrC,QAAO;AACT,QAAM,aAAa,IAAI,IAAI,IAAI,GAAG;AAClC,aAAW,SAAS;AACpB,aAAW,OAAO;AAClB,QAAM,WAAW,WAAW;AAC5B,MAAI;AACF,UAAM,MAAM,IAAI;AAAA,MACd;AAAA,MACA,IAAI;AAAA,IACN;AACA,UAAM,WAAW,MAAM,QAAQ,KAAK;AAAA,MAClC,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU;AAAA,QACnB,OAAO,MAAM,CAAC;AAAA,QACd,OAAO,IAAI;AAAA,QACX;AAAA,QACA,KAAK,IAAI;AAAA,QACT,SAAS;AAAA,QACT,mBAAmB;AAAA,QACnB;AAAA,MACF,CAAC;AAAA,MACD,UAAU;AAAA,IACZ,CAAC;AACD,QAAI,CAAC,SAAS,GAAI,QAAO;AACzB,UAAM,QAAQ,MAAM,SAAS,KAAK;AAClC,QACE,MAAM,WAAW,UAAU,IAAI,eAC/B,MAAM,UAAU,mBAAmB,kBACnC,MAAM,UAAU,WAAW,IAAI,YAC/B,MAAM,UAAU,eAAe,4BAC/B,MAAM,UAAU,YAAY,SAC5B,MAAM,UAAU,sBAAsB,cACtC,MAAM,UAAU,aAAa,YAC7B,OAAO,MAAM,OAAO,OAAO,YAC1B,MAAM,MAAM,SAAS,WAAW,MAAM,MAAM,SAAS,WACrD,MAAM,MAAM,UAAU,UACrB,OAAO,MAAM,MAAM,UAAU,SAC/B,QAAO;AACT,WAAO;AAAA,MACL,QAAQ,MAAM,MAAM;AAAA,MACpB,0BAA0B;AAAA,MAC1B,GAAI,MAAM,MAAM,QAAQ,EAAE,OAAO,MAAM,MAAM,MAAM,IAAI,CAAC;AAAA,IAC1D;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AC7EA,SAAS,sBAAsB,0BAA0B;;;ACDzD,IAAM,wBAAwB;AAQ9B,eAAsB,2BAA2B,cAAuC;AACtF,QAAM,QAAQ,IAAI,YAAY,EAAE,OAAO,GAAG,qBAAqB,GAAG,YAAY,EAAE;AAChF,QAAM,QAAQ,IAAI,WAAW,MAAM,OAAO,OAAO,OAAO,WAAW,KAAK,CAAC,EAAE,MAAM,GAAG,EAAE;AACtF,QAAM,CAAC,IAAK,MAAM,CAAC,IAAK,KAAQ;AAChC,QAAM,CAAC,IAAK,MAAM,CAAC,IAAK,KAAQ;AAChC,QAAM,MAAM,CAAC,GAAG,KAAK,EAAE,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE;AAChF,SAAO,GAAG,IAAI,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,MAAM,GAAG,EAAE,CAAC,IAAI,IAAI,MAAM,IAAI,EAAE,CAAC,IAAI,IAAI,MAAM,IAAI,EAAE,CAAC,IAAI,IAAI,MAAM,EAAE,CAAC;AAC1G;;;ACXO,SAAS,sBAAsB,OAAuB;AAC3D,SAAO,MAAM,KAAK,EAAE,YAAY;AAClC;;;AFGA,IAAM,mBAAmB,CAAC,aAAa,YAAY,SAAS,YAAY,aAAa,SAAS;AAC9F,IAAM,mBAAmB,CAAC,gBAAgB,YAAY,SAAS,OAAO;AACtE,IAAM,eAAe;AAGd,SAAS,mBAAmB,GAAwD;AACzF,QAAM,WAAW,GAAG,YAAY;AAChC,QAAM,WAAW,GAAG,YAAY;AAChC,aAAW,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,YAAY,QAAQ,GAAG,CAAC,YAAY,QAAQ,CAAC,GAAY;AACnF,QAAI,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,OAAO,MAAM,YAAY,MAAM,EAAE,GAAG;AAC/E,YAAM,IAAI,MAAM,6BAA6B,IAAI,0CAA0C;AAAA,IAC7F;AACA,UAAM,SAAS,IAAI,KAAK,CAAC,UAAU,CAAC,aAAa,KAAK,KAAK,CAAC;AAC5D,QAAI,QAAQ;AACV,YAAM,IAAI,MAAM,6BAA6B,IAAI,YAAY,MAAM,gBAAgB,aAAa,MAAM,EAAE;AAAA,IAC1G;AAAA,EACF;AACA,QAAM,YAAY,CAAC,GAAG,UAAU,GAAG,QAAQ,EAAE,KAAK,CAAC,OAAO,OAAO,WAAW,OAAO,QAAQ,KAAK,MAAM,KAAK;AAC3G,MAAI,WAAW;AACb,UAAM,IAAI,MAAM,+CAA+C,SAAS,kCAAkC;AAAA,EAC5G;AACA,MAAI,GAAG,kBAAkB,WAAc,CAAC,MAAM,QAAQ,EAAE,aAAa,KAAK,CAAC,EAAE,cAAc,MAAM,CAAC,MAAM,OAAO,MAAM,YAAY,MAAM,EAAE,IAAI;AAC3I,UAAM,IAAI,MAAM,iFAAiF;AAAA,EACnG;AACA,MAAI,GAAG,cAAc,WAAc,CAAC,MAAM,QAAQ,EAAE,SAAS,KAAK,CAAC,EAAE,UAAU,MAAM,CAAC,MAAM,OAAO,MAAM,YAAY,MAAM,EAAE,IAAI;AAC/H,UAAM,IAAI,MAAM,6EAA6E;AAAA,EAC/F;AAIA,QAAM,aAAa,GAAG,cAAc,CAAC;AACrC,aAAW,CAAC,OAAO,QAAQ,KAAK,OAAO,QAAQ,UAAU,GAAG;AAC1D,eAAW,OAAO,CAAC,eAAe,cAAc,GAAY;AAC1D,YAAM,aAAa,WAAW,GAAG;AACjC,UAAI,eAAe,OAAW;AAC9B,UAAI,OAAO,eAAe,YAAY,CAAC,WAAW,KAAK,GAAG;AACxD,cAAM,IAAI,MAAM,wCAAwC,KAAK,IAAI,GAAG,qCAAqC;AAAA,MAC3G;AACA,2BAAqB,YAAY,wCAAwC,KAAK,IAAI,GAAG,EAAE;AAAA,IACzF;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ,GAAG,UAAU,CAAC;AAAA,IACtB,eAAe,GAAG,iBAAiB;AAAA,IACnC,SAAS,GAAG,WAAW;AAAA,IACvB,sBAAsB,GAAG,wBAAwB;AAAA,IACjD,eAAe,GAAG,iBAAiB,CAAC;AAAA,IACpC,WAAW,GAAG,aAAa,CAAC;AAAA,IAC5B,aAAa,GAAG,eAAe;AAAA,IAC/B,eAAe,GAAG,iBAAiB;AAAA,EACrC;AACF;AAKA,IAAM,WAAW;AAIV,SAAS,aAAa,OAAyB;AACpD,SAAO,OAAO,UAAU,YAAY,SAAS,KAAK,KAAK;AACzD;AAIO,SAAS,WAAW,OAAgB,KAAsB;AAC/D,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO;AAClC,SAAO,MAAM,OAAO,CAAC,MAAM,OAAO,MAAM,YAAY,OAAO,MAAM,YAAY,OAAO,MAAM,SAAS,EAAE,MAAM,GAAG,GAAG;AACnH;AAIO,SAAS,iBAAiB,QAA0C;AACzE,SAAO,OAAO,kBAAkB,QAAQ,OAAO,kBAAkB;AACnE;AAIA,IAAM,kBAAkB,oBAAI,IAAI,CAAC,SAAS,aAAa,UAAU,CAAC;AAS3D,SAAS,iBACd,SACA,QACqC;AACrC,QAAM,MAAM,QAAQ;AACpB,QAAMA,WAAU,CAAC,MAAuB,IAAI,cAAc,SAAS,CAAC;AACpE,QAAM,UAAmC,CAAC;AAC1C,aAAW,KAAK,CAAC,GAAG,IAAI,UAAU,GAAG,IAAI,QAAQ,GAAG;AAClD,QAAI,gBAAgB,IAAI,CAAC,KAAK,CAACA,SAAQ,CAAC,EAAG;AAC3C,UAAM,IAAI,OAAO,CAAC;AAClB,QAAI,OAAO,MAAM,YAAY,EAAE,KAAK,MAAM,GAAI,SAAQ,CAAC,IAAI,EAAE,KAAK;AAAA,EACpE;AACA,MAAI,OAAO,UAAU,UAAaA,SAAQ,OAAO,EAAG,SAAQ,QAAQ,WAAW,OAAO,OAAO,IAAI,WAAW;AAC5G,SAAO,OAAO,KAAK,OAAO,EAAE,SAAS,IAAI,UAAU;AACrD;AAqBA,eAAsB,kBACpB,IACA,SACA,QACA,MAauB;AACvB,QAAM,MAAM,QAAQ;AAMpB,QAAM,cAAc,mBAAmB,IAAI,cAAc,CAAC,GAAG,QAAQ,IAAI,QAAQ;AACjF,aAAW,CAAC,GAAG,KAAK,KAAK,OAAO,QAAQ,WAAW,GAAG;AACpD,QAAI,CAAC,MAAM,SAAU;AACrB,UAAM,IAAI,OAAO,CAAC;AAClB,QAAI,OAAO,MAAM,YAAY,EAAE,KAAK,MAAM,GAAI,QAAO,EAAE,IAAI,OAAO,OAAO,GAAG,CAAC,eAAe;AAAA,EAC9F;AACA,aAAW,KAAK,CAAC,GAAG,IAAI,UAAU,GAAG,IAAI,QAAQ,GAAG;AAClD,UAAM,IAAI,OAAO,CAAC;AAClB,UAAM,MAAM,IAAI,OAAO,CAAC,KAAK,IAAI;AACjC,QAAI,OAAO,MAAM,YAAY,EAAE,SAAS,IAAK,QAAO,EAAE,IAAI,OAAO,OAAO,GAAG,CAAC,YAAY,GAAG,cAAc;AAAA,EAC3G;AAIA,MAAI,IAAI,iBAAiB,OAAO,OAAO,UAAU,YAAY,CAAC,aAAa,OAAO,MAAM,KAAK,CAAC,GAAG;AAC/F,WAAO,EAAE,IAAI,OAAO,OAAO,sCAAsC;AAAA,EACnE;AAEA,QAAM,QAAQ,iBAAiB,MAAM;AACrC,MAAI,IAAI,wBAAwB,CAAC,OAAO;AACtC,WAAO,EAAE,IAAI,OAAO,OAAO,4BAA4B;AAAA,EACzD;AAEA,QAAM,KAAK,KAAK,eACZ,MAAM,2BAA2B,KAAK,YAAY,IAClD,KAAK,MAAM;AACf,QAAM,MAA+B,EAAE,IAAI,QAAQ,QAAQ,SAAS,SAAS,WAAW,KAAK,IAAI;AACjG,aAAW,KAAK,CAAC,GAAG,IAAI,UAAU,GAAG,IAAI,QAAQ,GAAG;AAGlD,QAAI,YAAY,CAAC,GAAG,YAAY,MAAO;AACvC,QAAI,OAAO,OAAO,CAAC,MAAM,SAAU,KAAI,CAAC,IAAK,OAAO,CAAC,EAAa,KAAK;AAAA,EACzE;AACA,MAAI,OAAO,UAAU,OAAW,KAAI,QAAQ,WAAW,OAAO,OAAO,IAAI,WAAW;AACpF,MAAI,KAAK,QAAS,KAAI,UAAU,KAAK;AACrC,MAAI,OAAO,OAAO,UAAU,YAAY,aAAa,OAAO,MAAM,KAAK,CAAC,GAAG;AACzE,QAAI,kBAAkB,sBAAsB,OAAO,KAAK;AAAA,EAC1D;AACA,MAAI,KAAK,gBAAgB,aAAa,mBAAmB;AACvD,QAAI,mBAAmB,KAAK,eAAe;AAC3C,QAAI,kBAAkB,KAAK,eAAe;AAC1C,QAAI,oBAAoB,KAAK;AAAA,EAC/B;AACA,MAAI,KAAK,YAAa,KAAI,cAAc,KAAK;AAK7C,MAAI,OAAO,OAAO,WAAW,YAAY,OAAO,QAAQ;AACtD,QAAI,KAAK,WAAW,CAAC,KAAK,QAAQ,SAAS,OAAO,MAAM,GAAG;AACzD,aAAO,EAAE,IAAI,OAAO,OAAO,gCAAgC;AAAA,IAC7D;AACA,QAAI,SAAS,OAAO;AAAA,EACtB;AAKA,MAAI,MAAO,KAAI,kBAAkB,KAAK;AAEtC,QAAM,MAA4C;AAAA,IAChD,EAAE,GAAG,UAAU,IAAI,gBAAgB,IAAI,OAAO,IAAI;AAAA,EACpD;AACA,MAAI,KAAK,gBAAgB,aAAa,mBAAmB;AACvD,QAAI,KAAK,EAAE,GAAG,UAAU,IAAI,mBAAmB,IAAI,KAAK,eAAe,IAAI,OAAO;AAAA,MAChF,YAAY,KAAK;AAAA,MACjB,uBAAuB;AAAA,IACzB,EAAE,CAAC;AAAA,EACL;AACA,QAAM,EAAE,UAAU,IAAI,MAAM,GAAG;AAAA,IAC7B;AAAA,IACA,KAAK,eAAe,EAAE,YAAY,QAAQ,KAAK,YAAY,GAAG,IAAI;AAAA,EACpE;AACA,SAAO,EAAE,IAAI,MAAM,IAAI,WAAW,QAAQ,QAAQ,SAAS,SAAS,iBAAiB,QAAQ,KAAK,MAAM,KAAK;AAC/G;AA2BO,SAAS,WACd,OACA,eACA,QAAmC,CAAC,GACpC,aAAwD,CAAC,GAChC;AACzB,SAAO;AAAA,IACL,IAAI,MAAM;AAAA,IACV,MAAM,MAAM;AAAA,IACZ,oBAAoB,MAAM,sBAAsB;AAAA,IAChD,uBAAuB,MAAM,yBAAyB;AAAA,IACtD,OAAO,CAAC,GAAG,KAAK;AAAA;AAAA,IAEhB;AAAA,IACA,gBAAgB,MAAM,kBAAkB;AAAA,IACxC,kBAAkB,MAAM,oBAAoB;AAAA,IAC5C,WAAW,MAAM,aAAa;AAAA,IAC9B,gBAAgB,MAAM,kBAAkB;AAAA,IACxC,WAAW,MAAM,aAAa;AAAA,IAC9B;AAAA,EACF;AACF;;;AG1MO,SAAS,WACd,MACS;AACT,SAAO,EAAE,KAAK,aAAa,MAAM,CAAC,KAAK;AACzC;AAUO,SAAS,YACd,MACA,OACA,cACS;AACT,MAAI,WAAW,IAAI,EAAG,QAAO;AAC7B,SAAO,QAAQ,MAAM,wBAAwB,KAAK,iBAAiB,YAAY;AACjF;AAGA,SAAS,QAAQ,GAAgB,GAAwB;AACvD,SAAO,EAAE,YAAY,EAAE,aAAa,EAAE,GAAG,cAAc,EAAE,EAAE;AAC7D;AAWO,SAAS,aAAa,OAAkBC,QAA+B,CAAC,GAAkB;AAC/F,QAAM,SAASA,MAAK,OAAO,CAAC,SAAS,KAAK,MAAM;AAChD,MAAI,OAAO,OAAQ,QAAO,CAAC,GAAG,MAAM,EAAE,KAAK,OAAO;AAClD,SAAO,CAAC;AAAA,IACN,IAAI;AAAA,IACJ,SAAS,OAAO,MAAM,MAAM,EAAE;AAAA,IAC9B,MAAM;AAAA,IACN,YAAY,MAAM,sBAAsB;AAAA,IACxC,GAAI,MAAM,gBAAgB,EAAE,eAAe,MAAM,cAAc,IAAI,CAAC;AAAA,IACpE,WAAW;AAAA,IACX,QAAQ;AAAA,EACV,CAAC;AACH;AAGO,SAAS,eACd,OACA,OACA,cACe;AACf,SAAO,MAAM,OAAO,CAAC,SAAS,KAAK,UAAU,YAAY,MAAM,OAAO,YAAY,CAAC;AACrF;AASO,SAAS,SACd,OACA,QACoB;AACpB,MAAI,CAAC,OAAQ,QAAO,MAAM,WAAW,IAAI,MAAM,CAAC,IAAK;AACrD,SAAO,MAAM,KAAK,CAAC,SAAS,KAAK,OAAO,MAAM,KAAK;AACrD;AAYO,SAAS,gBAAgB,OAAiD;AAC/E,SAAO,MAAM,IAAI,CAAC,UAAU;AAAA,IAC1B,IAAI,KAAK;AAAA,IACT,MAAM,KAAK;AAAA,IACX,YAAY,KAAK;AAAA,IACjB,OAAO,KAAK,SAAS;AAAA,IACrB,MAAM,WAAW,IAAI;AAAA,EACvB,EAAE;AACJ;;;ACvKA,SAAS,UAAU,KAA8B,SAA8B;AAC7E,SAAO;AAAA,IACL,IAAI,OAAO,IAAI,MAAM,EAAE;AAAA,IACvB,SAAS,OAAO,IAAI,WAAW,OAAO;AAAA,IACtC,MAAM,OAAO,IAAI,QAAQ,EAAE;AAAA,IAC3B,YAAY,OAAO,IAAI,eAAe,WAAW,IAAI,aAAa;AAAA,IAClE,GAAI,OAAO,IAAI,kBAAkB,YAAY,IAAI,gBAC7C,EAAE,eAAe,IAAI,cAAc,IACnC,CAAC;AAAA,IACL,GAAI,OAAO,IAAI,UAAU,WAAW,EAAE,OAAO,IAAI,MAAM,IAAI,CAAC;AAAA,IAC5D,WAAW,OAAO,IAAI,cAAc,WAAW,IAAI,YAAY;AAAA;AAAA;AAAA,IAG/D,QAAQ,IAAI,WAAW;AAAA,EACzB;AACF;AAQA,eAAsB,UAAU,IAAe,OAA6C;AAC1F,QAAM,UAAU,OAAO,MAAM,MAAM,EAAE;AACrC,MAAIC;AACJ,MAAI;AACF,IAAAA,SAAQ,MAAM,GAAG,MAAM;AAAA,MACrB,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,GAAG,OAAO,EAAE,WAAW,MAAM,GAAG,OAAO,IAAI,EAAE;AAAA,IAC9E,CAAC,GAA8B;AAAA,EACjC,QAAQ;AACN,IAAAA,QAAO;AAAA,EACT;AACA,QAAM,OAAO,MAAM,QAAQA,KAAI,IAC3BA,MAAK,IAAI,CAAC,QAAQ,UAAU,KAAgC,OAAO,CAAC,IACpE,CAAC;AACL,SAAO,aAAa,OAAO,IAAI;AACjC;AAGA,eAAsB,mBACpB,IACA,OACA,cACwB;AACxB,SAAO,eAAe,MAAM,UAAU,IAAI,KAAK,GAAG,OAAO,YAAY;AACvE;;;ACvBO,IAAM,sBAA0C;AAAA,EACrD,aAAa;AAAA,EACb,MAAM,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA,EACpB,WAAW;AAAA,EACX,SAAS;AAAA,EACT,UAAU;AAAA,EACV,gBAAgB;AAAA,EAChB,YAAY;AAAA,EACZ,iBAAiB;AACnB;AAEA,SAAS,gBAAgB,IAAqB;AAC5C,MAAI;AACF,QAAI,KAAK,eAAe,QAAW,EAAE,UAAU,GAAG,CAAC;AACnD,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAQO,SAAS,kBAAkB,QAAgD;AAChF,QAAM,SAAS,mBAAmB,MAAM;AACxC,MAAI,OAAO,GAAI,QAAO,OAAO;AAC7B,QAAM,SAAS,OAAO,QAAQ,OAAO,MAAM,EACxC,IAAI,CAAC,CAAC,OAAO,OAAO,MAAM,GAAG,KAAK,KAAK,OAAO,EAAE,EAChD,KAAK,GAAG;AACX,QAAM,IAAI,MAAM,eAAe,MAAM,EAAE;AACzC;AAYO,SAAS,mBACd,QACmF;AACnF,QAAM,IAAI,UAAU,CAAC;AACrB,QAAM,IAAwB;AAAA,IAC5B,aAAa,EAAE,eAAe,oBAAoB;AAAA,IAClD,MAAM,EAAE,QAAQ,oBAAoB;AAAA,IACpC,WAAW,EAAE,aAAa,oBAAoB;AAAA,IAC9C,SAAS,EAAE,WAAW,oBAAoB;AAAA,IAC1C,UAAU,EAAE,YAAY,oBAAoB;AAAA,IAC5C,gBAAgB,EAAE,kBAAkB,oBAAoB;AAAA,IACxD,YAAY,EAAE,cAAc,oBAAoB;AAAA,IAChD,iBAAiB,EAAE,mBAAmB,oBAAoB;AAAA,EAC5D;AACA,QAAM,SAA2B,CAAC;AAClC,MAAI,EAAE,EAAE,eAAe,MAAM,EAAE,eAAe,MAAM;AAClD,WAAO,cAAc;AAAA,EACvB;AACA,MAAI,EAAE,EAAE,cAAc,KAAK,EAAE,cAAc,KAAK;AAC9C,WAAO,aAAa;AAAA,EACtB;AACA,MAAI,EAAE,EAAE,kBAAkB,KAAK,EAAE,kBAAkB,MAAM;AACvD,WAAO,iBAAiB;AAAA,EAC1B;AACA,MAAI,EAAE,EAAE,aAAa,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,KAAK;AACrE,WAAO,QAAQ;AAAA,EACjB;AACA,QAAM,OAAO,CAAC,GAAG,EAAE,IAAI;AACvB,MAAI,CAAC,KAAK,OAAQ,QAAO,OAAO;AAAA,WACvB,CAAC,KAAK,MAAM,CAAC,MAAM,OAAO,UAAU,CAAC,KAAK,KAAK,KAAK,KAAK,CAAC,GAAG;AACpE,WAAO,OAAO;AAAA,EAChB;AACA,MAAI,OAAO,EAAE,aAAa,YAAY,CAAC,gBAAgB,EAAE,QAAQ,GAAG;AAClE,WAAO,WAAW,IAAI,OAAO,EAAE,QAAQ,CAAC;AAAA,EAC1C;AACA,MAAI,OAAO,EAAE,oBAAoB,SAAU,QAAO,kBAAkB;AACpE,SAAO,OAAO,KAAK,MAAM,EAAE,SAAS,IAAI,EAAE,IAAI,OAAO,OAAO,IAAI,EAAE,IAAI,MAAM,OAAO,EAAE,GAAG,GAAG,KAAK,EAAE;AACpG;AAQO,SAAS,WAAW,KAAa,YAAkD;AACxF,SAAO,EAAE,MAAM,KAAK,IAAI,MAAM,aAAa,MAAW;AACxD;AAGO,SAAS,WAAW,SAAiB,aAA6B;AACvE,SAAO,UAAU,cAAc;AACjC;AAIO,SAAS,gBAAgB,OAAuC,SAA0B;AAC/F,SAAO,MAAM,KAAK,CAAC,MAAM,EAAE,YAAY,OAAO;AAChD;AAGO,SAAS,cAAc,UAAkB,KAAsE;AACpH,SAAO,SAAS,QAAQ,iBAAiB,IAAI,aAAa,EAAE,EAAE,QAAQ,gBAAgB,IAAI,YAAY,EAAE;AAC1G;AAYO,SAAS,gBAAgB,UAA+F;AAC7H,QAAM,UAAU,UAAU,iBAAiB;AAC3C,SAAO,EAAE,YAAY,QAAQ,OAAO,GAAG,QAAQ;AACjD;AAIO,SAAS,oBAAoB,eAA+B;AACjE,SAAO,eAAe,aAAa;AACrC;AAqBO,SAAS,iBAAiB,GAWf;AAChB,SAAO;AAAA,IACL,IAAI,EAAE;AAAA,IACN,eAAe,EAAE;AAAA,IACjB,SAAS,EAAE;AAAA,IACX,SAAS,EAAE;AAAA,IACX,OAAO,EAAE;AAAA,IACT,UAAU,EAAE;AAAA,IACZ,QAAQ;AAAA,IACR,eAAe,EAAE;AAAA,IACjB,GAAI,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC1C,GAAI,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,IAAI,CAAC;AAAA,IAC7C,OAAO;AAAA,IACP,WAAW,EAAE;AAAA,EACf;AACF;AAUO,SAAS,wBAAwB,SAAiB,OAAuC;AAC9F,SAAO,EAAE,SAAS,OAAO,OAAO,OAAO;AACzC;AAYO,SAAS,yBACd,eACA,SACA,UACyB;AACzB,SAAO;AAAA,IACL,WAAW;AAAA,IACX,GAAI,WAAW,EAAE,aAAa,SAAS,IAAI,CAAC;AAAA,IAC5C,GAAI,kBAAkB,mBAAmB,EAAE,QAAQ,iBAA0B,IAAI,CAAC;AAAA,EACpF;AACF;;;AClPO,IAAM,kCAAkC;AAExC,IAAM,wBAAwB;;;ACHrC,IAAM,UAAU,IAAI,YAAY;AAEhC,SAAS,eAAe,OAAwB;AAC9C,MAAI,UAAU,QAAQ,OAAO,UAAU,aAAa,OAAO,UAAU,YAAY,OAAO,UAAU,UAAU;AAC1G,WAAO,KAAK,UAAU,KAAK;AAAA,EAC7B;AACA,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,IAAI,MAAM,IAAI,cAAc,EAAE,KAAK,GAAG,CAAC;AACxE,MAAI,OAAO,UAAU,SAAU,OAAM,IAAI,UAAU,8CAA8C;AACjG,QAAMC,UAAS;AACf,QAAM,UAAU,OAAO,KAAKA,OAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,QAAQ;AAC1D,UAAM,OAAOA,QAAO,GAAG;AACvB,WAAO,SAAS,SAAY,CAAC,IAAI,CAAC,GAAG,KAAK,UAAU,GAAG,CAAC,IAAI,eAAe,IAAI,CAAC,EAAE;AAAA,EACpF,CAAC;AACD,SAAO,IAAI,QAAQ,KAAK,GAAG,CAAC;AAC9B;AAGO,SAAS,uBAAuB,OAAwB;AAC7D,SAAO,eAAe,KAAK;AAC7B;AAGA,eAAsB,oBAAoB,UAAoC;AAC5E,QAAM,SAAS,MAAM,OAAO,OAAO,OAAO,WAAW,QAAQ,OAAO,uBAAuB,QAAQ,CAAC,CAAC;AACrG,SAAO,UAAU,MAAM,KAAK,IAAI,WAAW,MAAM,GAAG,CAAC,SAAS,KAAK,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC;AAC5G;;;ACdA,IAAM,KAAK;AACX,IAAM,aAAa;AACnB,IAAM,WAAW;AACjB,IAAMC,YAAW;AACjB,IAAM,mBAAmB,CAAC,UAA2BA,UAAS,KAAK,KAAK;AAGjE,SAAS,wBAAwB,OAAuB;AAC7D,SAAO,sBAAsB,KAAK;AACpC;AAQO,SAAS,+BAA+B,OAA0C;AACvF,QAAM,SAAmB,CAAC;AAC1B,QAAM,OAAO,SAAS,OAAO,UAAU,WAAW,QAAmC,CAAC;AACtF,MAAI,KAAK,kBAAkB,gCAAiC,QAAO,KAAK,kCAAkC;AAC1G,QAAM,WAAW,OAAO,KAAK,QAAQ;AACrC,QAAM,cAAc,OAAO,KAAK,WAAW;AAC3C,MAAI,CAAC,OAAO,cAAc,QAAQ,KAAK,WAAW,EAAG,QAAO,KAAK,8CAA8C;AAC/G,MAAI,CAAC,OAAO,SAAS,WAAW,KAAK,eAAe,EAAG,QAAO,KAAK,iDAAiD;AACpH,QAAM,SAAS,KAAK,UAAU,OAAO,KAAK,WAAW,WAAW,KAAK,SAAoC,CAAC;AAC1G,QAAM,SAAS,KAAK,UAAU,OAAO,KAAK,WAAW,WAAW,KAAK,SAAoC,CAAC;AAC1G,QAAM,WAAW,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ;AACnE,QAAM,cAAc,OAAO,OAAO,UAAU,WAAW,OAAO,MAAM,KAAK,IAAI;AAC7E,QAAM,YAAY,OAAO,OAAO,cAAc,WAAW,OAAO,YAAY;AAC5E,QAAM,cAAc,OAAO,OAAO,gBAAgB,WAAW,OAAO,cAAc;AAClF,MAAI,CAAC,GAAG,KAAK,QAAQ,EAAG,QAAO,KAAK,6CAA6C;AACjF,MAAI,CAAC,eAAe,YAAY,SAAS,IAAK,QAAO,KAAK,gDAAgD;AAC1G,MAAI,CAAC,GAAG,KAAK,SAAS,EAAG,QAAO,KAAK,iDAAiD;AACtF,MAAI,CAAC,GAAG,KAAK,WAAW,EAAG,QAAO,KAAK,mDAAmD;AAC1F,MAAI,CAAC,MAAM,QAAQ,KAAK,MAAM,EAAG,QAAO,KAAK,kCAAkC;AAC/E,QAAM,YAAY,MAAM,QAAQ,KAAK,MAAM,IAAI,KAAK,SAAS,CAAC;AAC9D,MAAI,UAAU,SAAS,WAAY,QAAO,KAAK,oCAAoC,UAAU,UAAU;AACvG,QAAM,SAAgC,CAAC;AACvC,QAAM,UAAU,oBAAI,IAAY;AAChC,QAAM,aAAa,oBAAI,IAAY;AACnC,aAAW,CAAC,OAAO,GAAG,KAAK,UAAU,MAAM,GAAG,UAAU,EAAE,QAAQ,GAAG;AACnE,UAAM,QAAQ,OAAO,OAAO,QAAQ,WAAW,MAAiC,CAAC;AACjF,UAAM,KAAK,OAAO,MAAM,OAAO,WAAW,MAAM,KAAK;AACrD,UAAM,QAAQ,OAAO,MAAM,UAAU,WAAW,MAAM,MAAM,KAAK,IAAI;AACrE,UAAM,aAAa,wBAAwB,KAAK;AAChD,UAAM,WAAW,MAAM;AACvB,UAAM,OAAO,OAAO,MAAM,SAAS,WAAW,MAAM,KAAK,KAAK,IAAI;AAClE,UAAM,YAAY,MAAM,cAAc,SAAY,SAAY,OAAO,MAAM,SAAS;AACpF,QAAI,CAAC,GAAG,KAAK,EAAE,EAAG,QAAO,KAAK,mBAAmB,KAAK,4BAA4B;AAClF,QAAI,QAAQ,IAAI,EAAE,EAAG,QAAO,KAAK,+BAA+B,EAAE,GAAG;AACrE,QAAI,CAAC,iBAAiB,UAAU,EAAG,QAAO,KAAK,mBAAmB,KAAK,uBAAuB;AAC9F,QAAI,WAAW,IAAI,UAAU,EAAG,QAAO,KAAK,kCAAkC,UAAU,GAAG;AAC3F,QAAI,aAAa,qBAAqB,aAAa,qBAAqB;AACtE,aAAO,KAAK,mBAAmB,KAAK,uBAAuB;AAAA,IAC7D;AACA,QAAI,QAAQ,KAAK,SAAS,SAAU,QAAO,KAAK,mBAAmB,KAAK,oBAAoB;AAC5F,QAAI,cAAc,WAAc,CAAC,OAAO,SAAS,SAAS,KAAK,aAAa,IAAI;AAC9E,aAAO,KAAK,mBAAmB,KAAK,wCAAwC;AAAA,IAC9E;AACA,YAAQ,IAAI,EAAE;AACd,eAAW,IAAI,UAAU;AACzB,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,MACvB,GAAI,cAAc,SAAY,EAAE,UAAU,IAAI,CAAC;AAAA,IACjD,CAAC;AAAA,EACH;AACA,MAAI,OAAO,OAAQ,QAAO,EAAE,IAAI,OAAO,OAAO;AAC9C,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,OAAO;AAAA,MACL,eAAe;AAAA,MACf;AAAA,MACA;AAAA,MACA,QAAQ,EAAE,OAAO,UAAU,OAAO,YAAY;AAAA,MAC9C,QAAQ,EAAE,WAAW,YAAY;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AACF;AA4BA,IAAM,OAAO,CAAC,UAAmD,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC;AAEjG,SAAS,QAAQ,KAAwD;AACvE,MAAI,OAAO,IAAI,OAAO,YAAY,OAAO,IAAI,oBAAoB,SAAU,QAAO;AAClF,MAAI,IAAI,gBAAgB,WAAW,IAAI,gBAAgB,SAAU,QAAO;AACxE,MAAI,IAAI,aAAa,qBAAqB,IAAI,aAAa,oBAAqB,QAAO;AACvF,SAAO;AACT;AAGA,eAAsB,mBACpB,IACA,UACA,OACA,KACmC;AACnC,QAAM,kBAAkB,wBAAwB,KAAK;AACrD,MAAI,CAAC,iBAAiB,eAAe,EAAG,QAAO;AAC/C,QAAM,SAAS,MAAM,GAAG,MAAM,EAAE,iBAAiB,EAAE,GAAG,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,IAAI,EAAE,EAAE,CAAC;AACpG,QAAM,SAAS,KAAK,OAAO,eAAe,EACvC,IAAI,OAAO,EACX,OAAO,CAAC,UAAsC;AAAA,IAC7C,SAAS,MAAM,aAAa,YAAY,MAAM,WAAW,QAAQ,CAAC,MAAM,cACvE,CAAC,MAAM,aAAa,MAAM,YAAY,QAAQ,CAAC,MAAM;AAAA,EACxD,CAAC,EACA,KAAK,CAAC,GAAG,MAAM;AACd,UAAM,QAAQ,OAAO,EAAE,gBAAgB,OAAO,IAAI,OAAO,EAAE,gBAAgB,OAAO;AAClF,WAAO,SAAS,EAAE,YAAY,EAAE;AAAA,EAClC,CAAC;AACH,SAAO,OAAO,CAAC,KAAK;AACtB;AAcA,eAAe,qBACb,IACA,UACA,UACA,aACkB;AAClB,QAAM,QAAQ,EAAE,UAAU,UAAU,YAAY;AAChD,MAAI,GAAG,WAAW;AAChB,WAAO,QAAQ,MAAM,GAAG,UAAU,2BAA2B,EAAE,OAAO,KAAK,GAAG,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI;AAAA,EAC1G;AACA,QAAM,QAAQ,MAAM,GAAG,MAAM,EAAE,yBAAyB,CAAC,EAAE,CAAC;AAC5D,SAAO,KAAK,MAAM,uBAAuB,EAAE,KAAK,CAAC,QAC/C,IAAI,aAAa,YAAY,IAAI,aAAa,YAAY,IAAI,gBAAgB,WAAW;AAC7F;AAGA,eAAsB,4BACpB,IACA,UACA,UACA,aAC2C;AAC3C,MAAI,CAAC,MAAM,qBAAqB,IAAI,UAAU,UAAU,WAAW,EAAG,QAAO;AAC7E,QAAM,SAAS,MAAM,GAAG,MAAM,EAAE,yBAAyB,EAAE,GAAG;AAAA,IAC5D,OAAO,EAAE,UAAU,UAAU,YAAY;AAAA,IAAG,OAAO,EAAE,UAAU,OAAO;AAAA,IAAG,OAAO;AAAA,EAClF,EAAE,EAAE,CAAC;AACL,QAAM,MAAM,KAAK,OAAO,uBAAuB,EAC5C,KAAK,CAAC,GAAG,MAAM,OAAO,EAAE,YAAY,CAAC,IAAI,OAAO,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC;AACtE,SAAO,MAAM,MAA8C;AAC7D;AAGA,eAAsB,2BACpB,IACA,UACA,UACA,YACe;AACf,QAAM,EAAE,UAAU,OAAO,IAAI;AAC7B,QAAM,UAAU,MAAM,MAAM,GAAG,MAAM,EAAE,iBAAiB,EAAE,GAAG;AAAA,IAC3D,OAAO,EAAE,aAAa,UAAU,UAAU,SAAS,OAAO,OAAO,UAAU,SAAS,OAAO,UAAU;AAAA,IACrG,OAAO;AAAA,EACT,EAAE,EAAE,CAAC,GAAG,eAAe;AACvB,QAAM,cAAc,IAAI,IAAI,SAAS,OAAO,IAAI,CAAC,UAAU,oBAAoB,SAAS,OAAO,KAAK,IAAI,MAAM,EAAE,EAAE,CAAC;AACnH,QAAM,MAAc,CAAC;AACrB,aAAW,OAAO,SAAS;AACzB,UAAM,KAAK,OAAO,IAAI,MAAM,EAAE;AAC9B,QAAI,MAAM,CAAC,YAAY,IAAI,EAAE,EAAG,KAAI,KAAK,EAAE,GAAG,UAAU,IAAI,mBAAmB,IAAI,OAAO;AAAA,MACxF,QAAQ;AAAA,MAAO,WAAW;AAAA,MAAY,WAAW,SAAS,OAAO;AAAA,MACjE,WAAW;AAAA,MAAY,WAAW,SAAS,OAAO;AAAA,IACpD,EAAE,CAAC;AAAA,EACL;AACA,aAAW,SAAS,SAAS,QAAQ;AACnC,UAAM,KAAK,oBAAoB,SAAS,OAAO,KAAK,IAAI,MAAM,EAAE;AAChE,UAAM,WAAW,QAAQ,KAAK,CAAC,QAAQ,IAAI,OAAO,EAAE;AACpD,QAAI,KAAK,EAAE,GAAG,UAAU,IAAI,mBAAmB,IAAI,OAAO;AAAA,MACxD;AAAA,MACA,eAAe,MAAM;AAAA,MACrB,aAAa;AAAA,MACb,UAAU,SAAS,OAAO;AAAA,MAC1B,UAAU,SAAS,OAAO;AAAA,MAC1B,OAAO,MAAM;AAAA,MACb,iBAAiB,wBAAwB,MAAM,KAAK;AAAA,MACpD,UAAU,MAAM;AAAA,MAChB,GAAI,MAAM,OAAO,EAAE,MAAM,MAAM,KAAK,IAAI,CAAC;AAAA,MACzC,GAAI,MAAM,YAAY,EAAE,WAAW,MAAM,UAAU,IAAI,CAAC;AAAA,MACxD,QAAQ;AAAA,MACR,gBAAgB,SAAS;AAAA,MACzB,WAAW,OAAO,UAAU,aAAa,UAAU;AAAA,MACnD,WAAW,OAAO,UAAU,aAAa,SAAS,OAAO,KAAK;AAAA,MAC9D,WAAW;AAAA,MACX,WAAW,SAAS,OAAO;AAAA,IAC7B,EAAE,CAAC;AACH,UAAM,UAAU;AAAA,MACd,GAAI,CAAC,MAAM,QAAQ,UAAU,SAAS,SAAY,CAAC,MAAM,IAAI,CAAC;AAAA,MAC9D,GAAI,MAAM,cAAc,UAAa,UAAU,cAAc,SAAY,CAAC,WAAW,IAAI,CAAC;AAAA,IAC5F;AACA,QAAI,QAAQ,OAAQ,KAAI,KAAK,EAAE,GAAG,WAAW,IAAI,mBAAmB,IAAI,OAAO,QAAQ,CAAC;AAAA,EAC1F;AACA,MAAI,UAAU,OAAQ,KAAI,KAAK,EAAE,GAAG,UAAU,IAAI,2BAA2B,IAAI,SAAS,IAAI,OAAO,EAAE,QAAQ,MAAM,EAAE,CAAC;AACxH,QAAM,aAAa,sBAAsB,SAAS,OAAO,KAAK,IAAI,SAAS,OAAO,WAAW,IAAI,SAAS,QAAQ;AAClH,MAAI,KAAK,EAAE,GAAG,UAAU,IAAI,2BAA2B,IAAI,YAAY,OAAO;AAAA,IAC5E,IAAI;AAAA,IACJ,UAAU,SAAS,OAAO;AAAA,IAC1B,UAAU,SAAS,OAAO;AAAA,IAC1B,aAAa,SAAS,OAAO;AAAA,IAC7B,UAAU,SAAS;AAAA,IACnB;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,EACF,EAAE,CAAC;AACH,QAAM,GAAG,SAAS,KAAK,EAAE,YAAY,oBAAoB,SAAS,OAAO,KAAK,IAAI,SAAS,OAAO,WAAW,IAAI,SAAS,QAAQ,IAAI,MAAM,GAAG,CAAC;AAClJ;;;AC7PO,IAAM,qCAAqC;AAmClD,IAAM,qBAAuD;AAAA,EAC3D,WAAW;AAAA,EACX,UAAU;AAAA,EACV,OAAO;AAAA,EACP,UAAU;AAAA,EACV,cAAc;AAAA,EACd,WAAW;AAAA,EACX,UAAU;AAAA,EACV,SAAS;AAAA,EACT,OAAO;AAAA,EACP,OAAO;AACT;AAEA,SAAS,SAAS,IAAoB;AACpC,QAAMC,QAAO,GAAG,QAAQ,sBAAsB,OAAO,EAAE,QAAQ,UAAU,GAAG,EAAE,KAAK;AACnF,SAAOA,QAAO,GAAGA,MAAK,CAAC,EAAG,YAAY,CAAC,GAAGA,MAAK,MAAM,CAAC,CAAC,KAAK;AAC9D;AAEA,SAAS,gBAAgB,SAA4C;AACnE,MAAI;AACF,WAAO,QAAQ,IAAI,KAAK,QAAQ,EAAE;AAAA,EACpC,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,SAAS,gBAAgB,IAAY,KAAsC;AAIzE,MAAI,OAAO,CAAC,UAAU,SAAS,OAAO,MAAM,EAAE,SAAS,IAAI,IAAI,EAAG,QAAO,IAAI;AAC7E,SAAO,OAAO,UAAU,UAAU,OAAO,aAAa,QAAQ;AAChE;AAGO,SAAS,sBACd,SACA,cAAmC,QAAQ,aACvB;AACpB,QAAM,OAAO,gBAAgB,OAAO;AACpC,SAAO,CAAC,GAAG,YAAY,UAAU,GAAG,YAAY,QAAQ,EAAE,IAAI,CAAC,IAAI,UAAU;AAC3E,UAAM,MAAM,KAAK,EAAE;AACnB,UAAM,aAAa,YAAY,WAAW,EAAE;AAC5C,UAAM,OAAO,gBAAgB,IAAI,GAAG;AACpC,WAAO;AAAA,MACL;AAAA,MACA,OAAO,KAAK,SAAS,mBAAmB,EAAE,KAAK,SAAS,EAAE;AAAA,MAC1D;AAAA,MACA,UAAU,YAAY,SAAS,SAAS,EAAE;AAAA,MAC1C;AAAA,MACA,WAAW,YAAY,OAAO,EAAE,KAAK,YAAY;AAAA,MACjD,GAAI,SAAS,UAAU,KAAK,UAAU,EAAE,SAAS,CAAC,GAAG,IAAI,OAAO,EAAE,IAAI,CAAC;AAAA,MACvE,GAAI,aAAa,EAAE,YAAY,EAAE,GAAG,WAAW,EAAE,IAAI,CAAC;AAAA,MACtD,GAAI,SAAS,UAAU,EAAE,eAAe,UAAmB,IAAI,CAAC;AAAA,IAClE;AAAA,EACF,CAAC;AACH;AAGO,SAAS,2BACd,KACA,WACoB;AACpB,MAAI,CAAC,UAAU,QAAS,QAAO,CAAC;AAChC,QAAM,MAAM,IAAI,KAAK,UAAU,IAAI;AACnC,SAAO,CAAC,GAAG,UAAU,UAAU,GAAG,UAAU,QAAQ,EAAE,IAAI,CAAC,IAAI,UAAU;AACvE,UAAM,QAAQ,IAAI,OAAO,EAAE;AAC3B,WAAO;AAAA,MACL;AAAA,MACA,OAAO,MAAM,SAAS,SAAS,EAAE;AAAA,MACjC,MAAM,MAAM;AAAA,MACZ,UAAU,UAAU,SAAS,SAAS,EAAE;AAAA,MACxC;AAAA,MACA,WAAW,UAAU,OAAO,EAAE,KAAK,UAAU;AAAA,MAC7C,GAAI,MAAM,UAAU,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,EAAE,IAAI,CAAC;AAAA,MACvD,GAAI,OAAO,IAAI,cAAc,MAAM,SAAS,UAAU,EAAE,eAAe,UAAmB,IAAI,CAAC;AAAA,IACjG;AAAA,EACF,CAAC;AACH;AAGO,SAAS,oBACd,SACA,YAAqC,QAAQ,WACzB;AACpB,SAAO,2BAA2B,QAAQ,KAAK,SAAS;AAC1D;AAOO,SAAS,yBACd,SACA,MACA,cAAmC,QAAQ,aACjB;AAC1B,SAAO;AAAA,IACL,eAAe;AAAA,IACf;AAAA,IACA,QAAQ,SAAS,SACb,sBAAsB,SAAS,WAAW,IAC1C,oBAAoB,OAAO;AAAA,EACjC;AACF;;;AC/IO,IAAM,6BAA6B;AAEnC,IAAM,kBAAkB;AAqC/B,IAAMC,MAAK;AACX,IAAM,QAAQ;AACd,IAAM,WAAW;AACjB,IAAM,SAAS,CAAC,UACd,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IAAI,QAAmC;AACnG,IAAM,OAAO,CAAC,OAAgB,MAAc,QAAkB,QAAwB;AACpF,MAAI,OAAO,UAAU,YAAY,CAAC,MAAM,KAAK,GAAG;AAAE,WAAO,KAAK,GAAG,IAAI,cAAc;AAAG,WAAO;AAAA,EAAI;AACjG,MAAI,MAAM,KAAK,EAAE,SAAS,IAAK,QAAO,KAAK,GAAG,IAAI,oBAAoB,GAAG,aAAa;AACtF,SAAO,MAAM,KAAK;AACpB;AAGO,SAAS,yBAAyB,OAAgB,SAAmD;AAC1G,QAAM,SAAmB,CAAC;AAC1B,QAAM,OAAO,OAAO,KAAK;AACzB,MAAI,CAAC,KAAM,QAAO,EAAE,IAAI,OAAO,QAAQ,CAAC,uCAAuC,EAAE;AACjF,aAAW,OAAO,OAAO,KAAK,IAAI,EAAG,KAAI,QAAQ,mBAAmB,QAAQ,SAAU,QAAO,KAAK,uBAAuB,GAAG,mBAAmB;AAC/I,MAAI,KAAK,kBAAkB,2BAA4B,QAAO,KAAK,6CAA6C;AAChH,MAAI,CAAC,MAAM,QAAQ,KAAK,MAAM,EAAG,QAAO,KAAK,6CAA6C;AAC1F,QAAM,YAAY,MAAM,QAAQ,KAAK,MAAM,IAAI,KAAK,SAAS,CAAC;AAC9D,MAAI,UAAU,SAAS,gBAAiB,QAAO,KAAK,+CAA+C,eAAe,UAAU;AAC5H,QAAM,MAAM,oBAAI,IAAY;AAC5B,QAAM,SAAsB,CAAC;AAC7B,aAAW,CAAC,OAAO,GAAG,KAAK,UAAU,MAAM,GAAG,eAAe,EAAE,QAAQ,GAAG;AACxE,UAAM,OAAO,8BAA8B,KAAK;AAChD,UAAM,OAAO,OAAO,GAAG;AACvB,QAAI,CAAC,MAAM;AAAE,aAAO,KAAK,GAAG,IAAI,oBAAoB;AAAG;AAAA,IAAU;AACjE,UAAMC,WAAU,oBAAI,IAAI,CAAC,MAAM,UAAU,eAAe,iBAAiB,cAAc,YAAY,2BAA2B,cAAc,eAAe,SAAS,eAAe,UAAU,CAAC;AAC9L,eAAW,OAAO,OAAO,KAAK,IAAI,EAAG,KAAI,CAACA,SAAQ,IAAI,GAAG,EAAG,QAAO,KAAK,GAAG,IAAI,IAAI,GAAG,mBAAmB;AACzG,UAAM,KAAK,KAAK,KAAK,IAAI,GAAG,IAAI,OAAO,QAAQ,EAAE;AACjD,QAAI,MAAM,CAACD,IAAG,KAAK,EAAE,EAAG,QAAO,KAAK,GAAG,IAAI,uCAAuC;AAClF,QAAI,IAAI,IAAI,EAAE,EAAG,QAAO,KAAK,GAAG,IAAI,mBAAmB,EAAE,GAAG;AAC5D,QAAI,IAAI,EAAE;AACV,UAAM,YAAY,OAAO,KAAK,MAAM;AACpC,QAAI,SAA0B,EAAE,MAAM,eAAe,gBAAgB,UAAU;AAC/E,QAAI,WAAW,SAAS,QAAQ;AAC9B,YAAM,SAAS,KAAK,UAAU,QAAQ,GAAG,IAAI,kBAAkB,QAAQ,EAAE;AACzE,UAAI,CAAC,QAAQ,IAAI,MAAM,EAAG,QAAO,KAAK,GAAG,IAAI,+CAA+C;AAC5F,eAAS,EAAE,MAAM,QAAQ,OAAO;AAAA,IAClC,WAAW,WAAW,SAAS,eAAe;AAC5C,YAAM,iBAAiB,KAAK,UAAU,gBAAgB,GAAG,IAAI,0BAA0B,QAAQ,EAAE;AACjG,UAAI,kBAAkB,CAACA,IAAG,KAAK,cAAc,EAAG,QAAO,KAAK,GAAG,IAAI,0DAA0D;AAC7H,eAAS,EAAE,MAAM,eAAe,eAAe;AAAA,IACjD,MAAO,QAAO,KAAK,GAAG,IAAI,0CAA0C;AACpE,QAAI,KAAK,gBAAgB,cAAc,KAAK,gBAAgB,eAAgB,QAAO,KAAK,GAAG,IAAI,+CAA+C;AAC9I,UAAM,gBAAgB,KAAK,KAAK,eAAe,GAAG,IAAI,kBAAkB,QAAQ,GAAG;AACnF,QAAI,iBAAiB,CAAC,MAAM,KAAK,aAAa,EAAG,QAAO,KAAK,GAAG,IAAI,+CAA+C;AACnH,QAAI,CAAC,OAAO,cAAc,KAAK,UAAU,KAAK,OAAO,KAAK,UAAU,IAAI,KAAK,OAAO,KAAK,UAAU,IAAI,IAAa,QAAO,KAAK,GAAG,IAAI,sDAAsD;AAC7L,UAAM,WAAW,OAAO,KAAK,aAAa,WAAW,KAAK,SAAS,KAAK,EAAE,YAAY,IAAI;AAC1F,QAAI,CAAC,SAAS,KAAK,QAAQ,EAAG,QAAO,KAAK,GAAG,IAAI,iDAAiD;AAClG,UAAM,WAAW,OAAO,KAAK,uBAAuB;AACpD,QAAI,CAAC,OAAO,cAAc,QAAQ,KAAK,WAAW,KAAK,WAAW,KAAO,QAAO,KAAK,GAAG,IAAI,4DAA4D;AACxJ,UAAM,aAAa,KAAK,eAAe,SAAY,SAAY,OAAO,KAAK,UAAU;AACrF,UAAM,cAAc,KAAK,gBAAgB,SAAY,SAAY,OAAO,KAAK,WAAW;AACxF,QAAI,eAAe,WAAc,CAAC,OAAO,cAAc,UAAU,KAAK,aAAa,GAAI,QAAO,KAAK,GAAG,IAAI,wCAAwC;AAClJ,QAAI,gBAAgB,WAAc,CAAC,OAAO,cAAc,WAAW,KAAK,cAAc,GAAI,QAAO,KAAK,GAAG,IAAI,yCAAyC;AACtJ,QAAI,eAAe,UAAa,gBAAgB,UAAa,eAAe,WAAY,QAAO,KAAK,GAAG,IAAI,qCAAqC;AAChJ,WAAO,KAAK;AAAA,MACV;AAAA,MAAI;AAAA,MAAQ,aAAa,KAAK;AAAA,MAAyC;AAAA,MACvE,YAAY,OAAO,KAAK,UAAU;AAAA,MAAG;AAAA,MAAU,yBAAyB;AAAA,MACxE,GAAI,eAAe,SAAY,EAAE,WAAW,IAAI,CAAC;AAAA,MAAI,GAAI,gBAAgB,SAAY,EAAE,YAAY,IAAI,CAAC;AAAA,MACxG,OAAO,KAAK,KAAK,OAAO,GAAG,IAAI,UAAU,QAAQ,GAAG;AAAA,MAAG,aAAa,KAAK,KAAK,aAAa,GAAG,IAAI,gBAAgB,QAAQ,GAAK;AAAA,MAC/H,UAAU,KAAK,KAAK,UAAU,GAAG,IAAI,aAAa,QAAQ,GAAG;AAAA,IAC/D,CAAC;AAAA,EACH;AACA,SAAO,OAAO,SAAS,EAAE,IAAI,OAAO,OAAO,IAAI,EAAE,IAAI,MAAM,OAAO,EAAE,eAAe,GAAG,OAAO,EAAE;AACjG;AAGO,IAAM,kBAAkB,CAAC,OAAkB,SAC/C,CAAC,MAAM,cAAc,MAAM,cAAc,SAAS,CAAC,MAAM,eAAe,MAAM,cAAc;AAGxF,SAAS,iBAAiB,SAAuC,KAAgC;AACtG,UAAQ,SAAS,UAAU,CAAC,GAAG,OAAO,CAAC,UAAU,gBAAgB,OAAO,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,eAAe,SAAS,QAAQ,SAAS,GAAG,MAAM,MAAM,KAAK;AACpJ;AAGO,SAAS,cAAc,SAAuC,SAAiB,KAA+B;AACnH,SAAO,SAAS,OAAO,KAAK,CAAC,UAAU,MAAM,OAAO,WAAW,gBAAgB,OAAO,GAAG,CAAC,KAAK;AACjG;;;AChHA,IAAM,YAAY;AAClB,IAAM,eAAe;AACrB,IAAM,OAAO;AAwBb,SAAS,SAAS,GAAyC;AACzD,MAAI,OAAO,EAAE,OAAO,SAAU,QAAO;AACrC,QAAM,KAAM,EAAE,mBAAmB,CAAC;AAClC,QAAM,kBAAmB,EAAE,oBAAoB,CAAC;AAChD,QAAM,aAAa,gBAAgB;AACnC,QAAM,UAAU,cAAc,OAAO,eAAe,YAAY,CAAC,MAAM,QAAQ,UAAU,IACrF,aACA,CAAC;AACL,QAAM,gBAAgB,OAAO,gBAAgB,kBAAkB,WAC3D,gBAAgB,gBAChB;AACJ,QAAM,OAAO,OAAO,GAAG,SAAS,YAAY,GAAG,OAAO,GAAG,OAAO;AAChE,QAAM,QAAQ,EAAE,kBAAkB,CAAC,GAAG;AACtC,SAAO;AAAA,IACL,IAAI,EAAE;AAAA,IACN,OAAO,OAAO,UAAU,WAAW,QAAQ;AAAA,IAC3C;AAAA,IACA,gBAAgB;AAAA,IAChB;AAAA,IACA;AAAA,IACA,GAAI,gBAAgB,EAAE,cAAc,IAAI,CAAC;AAAA,EAC3C;AACF;AAEA,eAAe,SAAS,MAAc,WAAmB,WAA2C;AAClG,QAAM,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,IAAI,IAAI,EAAE,SAAS,EAAE,eAAe,UAAU,SAAS,GAAG,EAAE,CAAC;AACxG,MAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM,aAAa,IAAI,WAAM,IAAI,MAAM,EAAE;AAChE,SAAO,IAAI,KAAK;AAClB;AAKA,eAAsB,oBAAoB,WAAmB,OAAe,YAA0B,OAAwC;AAC5I,QAAM,OAAO,MAAM,SAAS,2BAA2B,mBAAmB,KAAK,CAAC,YAAY,WAAW,SAAS,EAAE,MAAM,MAAM,IAAI;AAClI,QAAM,OAAO,MAAM,QAAQ,IAAI,IAAK,KAAK,CAAC,IAAiC;AAC3E,SAAO,OAAO,SAAS,IAAI,IAAI;AACjC;AAIA,eAAsB,aAAa,WAAmB,IAAY,YAA0B,OAAwC;AAClI,QAAM,OAAO,MAAM,SAAS,aAAa,mBAAmB,EAAE,CAAC,IAAI,WAAW,SAAS,EAAE,MAAM,MAAM,IAAI;AACzG,SAAO,OAAO,SAAS,IAAoB,IAAI;AACjD;AAOA,eAAsB,eAAe,WAAmB,YAA0B,OAAmC;AACnH,QAAM,MAAyB,CAAC;AAChC,WAAS,SAAS,KAAK,UAAU,MAAM;AACrC,UAAM,OAAO,MAAM,SAAS,mBAAmB,IAAI,WAAW,MAAM,IAAI,WAAW,SAAS;AAC5F,UAAM,OAAO,MAAM,QAAQ,IAAI,IAAK,OAA0B,CAAC;AAC/D,eAAW,KAAK,MAAM;AACpB,YAAME,UAAS,SAAS,CAAC;AACzB,UAAIA,QAAQ,KAAI,KAAKA,OAAM;AAAA,IAC7B;AACA,QAAI,KAAK,SAAS,KAAM;AAAA,EAC1B;AACA,SAAO;AACT;AAKA,eAAsB,aAAa,WAAmB,IAAY,MAAc,YAA0B,OAAyB;AACjI,QAAM,MAAM,MAAM,UAAU,GAAG,SAAS,aAAa,mBAAmB,EAAE,CAAC,aAAa;AAAA,IACtF,QAAQ;AAAA,IACR,SAAS,EAAE,eAAe,UAAU,SAAS,IAAI,gBAAgB,mBAAmB;AAAA,IACpF,MAAM,KAAK,UAAU,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC;AAAA,EACpD,CAAC;AACD,SAAO,IAAI;AACb;;;ACjGA,SAAS,gBAAAC,eAAc,gBAAAC,eAAc,UAAU,oBAAoB;;;ACInE;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACuHA,IAAM,uBAAoE;AAAA,EAC/E,QAAQ,CAAC,QAAQ,SAAS,aAAa,YAAY,SAAS,UAAU;AAAA,EACtE,SAAS,CAAC,QAAQ,UAAU,YAAY,YAAY,YAAY,OAAO;AACzE;;;ADjGO,SAAS,kBAAkB,QAA+C;AAC/E,QAAM,QAAQ,OAAO,MAAM,YAAY;AACvC,QAAM,WAAW,CAAC,OAAO,WAAW,OAAO,QAAQ,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK;AACpF,QAAM,QAAiC,EAAE,MAAM,OAAO,QAAQ,YAAY,OAAO,MAAM;AACvF,MAAI,MAAM,SAAS,GAAI,OAAM,OAAO;AACpC,MAAI,OAAO,UAAW,OAAM,YAAY,OAAO;AAC/C,MAAI,OAAO,SAAU,OAAM,WAAW,OAAO;AAC7C,MAAI,OAAO,MAAO,OAAM,QAAQ,OAAO;AACvC,MAAI,OAAO,SAAU,OAAM,WAAW,OAAO;AAC7C,SAAO;AACT;AAEA,SAAS,UAAU,OAAuB;AACxC,MAAI,IAAI;AACR,MAAI,IAAI;AACR,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,GAAG;AACxC,UAAM,IAAI,MAAM,WAAW,CAAC;AAC5B,QAAI,KAAK,KAAK,IAAI,GAAG,QAAU;AAC/B,QAAI,KAAK,KAAK,IAAI,GAAG,UAAU;AAAA,EACjC;AACA,SAAO,IAAI,MAAM,GAAG,SAAS,EAAE,CAAC,IAAI,MAAM,GAAG,SAAS,EAAE,CAAC;AAC3D;AAIO,SAAS,iBAAiB,MAAc,aAAqB,UAA2B;AAC7F,QAAM,UAAU,KAAK,YAAY;AACjC,QAAM,WAAW,gBAAgB,KAAK,WAAW;AACjD,QAAM,SAAS,WAAW,WAAW,SAAS,YAAY,CAAC,IAAI,OAAO,KAAK,WAAW,OAAO;AAC7F,QAAM,MAAM,GAAG,MAAM,IAAI,WAAW;AACpC,MAAI,YAAY,IAAI,UAAU,GAAI,QAAO;AACzC,SAAO,WAAW,QAAQ,MAAM,GAAG,EAAE,CAAC,IAAI,UAAU,GAAG,YAAY,EAAE,KAAS,IAAI,KAAS,WAAW,EAAE,CAAC;AAC3G;AAIO,SAAS,sBACdC,SACA,mBAAmB,iBACK;AACxB,MAAI,WAAWA,WAAUA,QAAO,YAAY,GAAG;AAC7C,WAAO;AAAA,MACL,SAAS;AAAA,MACT,UAAUA,QAAO,OAAO;AAAA,MACxB,gBAAgBA,QAAO,OAAO;AAAA,MAC9B,MAAMA,QAAO;AAAA,MACb,OAAOA,QAAO;AAAA,IAChB;AAAA,EACF;AACA,MAAI,WAAWA,SAAQ;AACrB,WAAO;AAAA,MACL,SAAS;AAAA,MACT,UAAU;AAAA,MACV,gBAAgBA,QAAO;AAAA,MACvB,MAAMA,QAAO;AAAA,MACb,OAAOA,QAAO;AAAA,IAChB;AAAA,EACF;AACA,MAAI,UAAUA,WAAUA,QAAO,SAAS,WAAW;AACjD,UAAM,QAAiC,EAAE,MAAMA,QAAO,KAAK;AAC3D,eAAW,OAAO,CAAC,UAAU,YAAY,YAAY,YAAY,OAAO,GAAY;AAClF,UAAIA,QAAO,GAAG,EAAG,OAAM,GAAG,IAAIA,QAAO,GAAG;AAAA,IAC1C;AACA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,UAAU;AAAA,MACV,gBAAgBA,QAAO;AAAA,MACvB,MAAM;AAAA,MACN;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,UAAU;AAAA,IACV,gBAAgBA,QAAO;AAAA,IACvB,MAAM;AAAA,IACN,OAAO,kBAAkBA,OAAM;AAAA,EACjC;AACF;AAIO,SAAS,oBACd,KACAA,SACA,QACA,UACc;AACd,MAAI,OAAO,UAAU,CAAC,OAAO,OAAOA,QAAO,IAAI,GAAG;AAChD,UAAM,IAAI,MAAM,GAAG,OAAO,IAAI,qBAAqBA,QAAO,IAAI,WAAW;AAAA,EAC3E;AACA,QAAM,MAAM,IAAI,KAAKA,QAAO,IAAI;AAChC,QAAM,SAAS,OAAO,SAASA,QAAO,IAAI,KAAK,qBAAqBA,QAAO,IAAI;AAC/E,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,GAAG,OAAO,IAAI,8CAA8CA,QAAO,IAAI,WAAW;AAAA,EACpG;AACA,QAAM,YAAY,IAAI,aAAa;AACnC,QAAM,QAAiC,CAAC;AACxC,aAAW,SAAS,oBAAI,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,GAAG;AACnD,UAAM,QAAQA,QAAO,SAAS,KAAK;AACnC,QAAI,UAAU,OAAW,OAAM,KAAK,IAAI;AAAA,EAC1C;AACA,MAAI,MAAM,SAAS,MAAM,OAAW,OAAM,SAAS,IAAIA,QAAO;AAC9D,SAAO,WACH,EAAE,SAAS,GAAG,QAAQ,EAAE,QAAQ,UAAU,UAAUA,QAAO,GAAG,GAAG,MAAMA,QAAO,MAAM,MAAM,IAC1F,EAAE,SAAS,GAAG,MAAMA,QAAO,MAAM,aAAaA,QAAO,IAAI,MAAM;AACrE;AAKA,eAAe,aACb,MACA,MAC+B;AAC/B,QAAM,QAAQ,KAAK,MAAM,YAAY;AACrC,QAAMC,WAAU,EAAE,KAAK,KAAK,KAAK,IAAI,KAAK,IAAa,KAAK,KAAK,KAAK,OAAO,KAAK,MAAM;AACxF,QAAM,EAAE,WAAW,IAAI,MAAM,KAAK,GAAG,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,UAAU,cAAc,MAAM,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC;AAC9H,QAAM,WAAW,aAAa,CAAC;AAC/B,MAAI,YAAY,OAAO,SAAS,OAAO,UAAU;AAC/C,UAAM,aAAaA,UAAS,EAAE,IAAI,SAAS,IAAI,OAAO,KAAK,MAAM,CAAC;AAClE,WAAO,EAAE,UAAU,SAAS,GAAG;AAAA,EACjC;AACA,QAAM,UAAU,MAAM,aAAaA,UAAS,EAAE,MAAM,UAAU,OAAO,KAAK,OAAO,YAAY,KAAK,WAAW,CAAC;AAC9G,SAAO,EAAE,UAAU,QAAQ,GAAG;AAChC;AAEA,eAAe,iBACb,MACAD,SACA,KAC8C;AAC9C,QAAM,aAAa,MAAM;AAAA,IACvB,EAAE,KAAK,KAAK,KAAK,IAAI,KAAK,IAAa,KAAK,KAAK,KAAK,OAAO,KAAK,MAAM;AAAA,IACxEA,QAAO;AAAA,IACPA,QAAO;AAAA,EACT;AACA,MAAI,WAAY,QAAO;AACvB,QAAM,SAAS,MAAM,KAAK,GAAG,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC;AACnF,QAAM,WAAW,OAAO,UAAU,CAAC,GAAG;AACtC,MAAI,OAAO,aAAa,UAAU;AAChC,UAAM,QAAQ,MAAM,KAAK,GAAG,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,SAAS,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC;AAC9F,QAAI,MAAM,aAAa,CAAC,EAAG,QAAO,MAAM,WAAW,CAAC;AAAA,EACtD;AACA,QAAM,MAAM,KAAK,IAAI,KAAKA,QAAO,IAAI;AACrC,QAAM,aAAa,IAAI;AACvB,MAAI,cAAc,OAAOA,QAAO,MAAM,UAAU,MAAM,UAAU;AAC9D,UAAM,eAAeA,QAAO,MAAM,UAAU,EAAE,YAAY;AAC1D,UAAM,QAAQ,MAAM,KAAK,GAAG,MAAM;AAAA,MAChC,YAAY,EAAE,GAAG,EAAE,OAAO,EAAE,MAAMA,QAAO,MAAM,aAAa,GAAG,OAAO,EAAE,EAAE;AAAA,IAC5E,CAAC;AACD,QAAI,MAAM,aAAa,CAAC,EAAG,QAAO,MAAM,WAAW,CAAC;AAAA,EACtD;AACA,QAAM,SAASA,QAAO,MAAM;AAC5B,QAAM,aAAa,IAAI,OAAO,QAAQ;AACtC,MAAI,OAAO,WAAW,YAAY,YAAY;AAC5C,UAAM,QAAQ,MAAM,KAAK,GAAG,MAAM;AAAA,MAChC,YAAY,EAAE,GAAG,EAAE,OAAO,EAAE,MAAMA,QAAO,MAAM,CAAC,UAAU,GAAG,OAAO,GAAG,OAAO,EAAE,EAAE;AAAA,IACpF,CAAC;AACD,QAAI,MAAM,aAAa,CAAC,EAAG,QAAO,MAAM,WAAW,CAAC;AAAA,EACtD;AACA,QAAM,YAAY,IAAI,aAAa;AACnC,QAAM,OAAOA,QAAO,MAAM,SAAS;AACnC,MAAIA,QAAO,SAAS,aAAa,OAAO,SAAS,YAAY,KAAK,KAAK,GAAG;AACxE,UAAM,QAAQ,MAAM,KAAK,GAAG,MAAM;AAAA,MAChC,YAAY,EAAE,GAAG,EAAE,OAAO,EAAE,MAAMA,QAAO,MAAM,MAAM,KAAK,KAAK,EAAE,GAAG,OAAO,EAAE,EAAE;AAAA,IACjF,CAAC;AACD,QAAI,MAAM,aAAa,CAAC,EAAG,QAAO,MAAM,WAAW,CAAC;AAAA,EACtD;AACA,SAAO;AACT;AAOA,eAAsB,oBACpB,MACA,QACA,UAAqD,CAAC,GACvB;AAC/B,QAAMA,UAAS,sBAAsB,QAAQ,QAAQ,QAAQ;AAC7D,MAAI,CAACA,QAAO,KAAK,KAAK,KAAK,CAACA,QAAO,SAAS,KAAK,KAAK,CAACA,QAAO,eAAe,KAAK,GAAG;AACnF,UAAM,IAAI,MAAM,8DAA8D;AAAA,EAChF;AACA,MAAI,QAAQ,YAAY,QAAQ,aAAaA,QAAO,UAAU;AAC5D,UAAM,IAAI,MAAM,6CAA6C;AAAA,EAC/D;AACA,QAAM,MAAM,iBAAiBA,QAAO,MAAMA,QAAO,gBAAgBA,QAAO,YAAY,IAAIA,QAAO,WAAW,MAAS;AACnH,QAAMC,WAAU,EAAE,KAAK,KAAK,KAAK,IAAI,KAAK,IAAa,KAAK,KAAK,KAAK,OAAO,KAAK,MAAM;AACxF,QAAM,WAAW,MAAM,iBAAiB,MAAMD,SAAQ,GAAG;AACzD,MAAI;AACJ,MAAI,YAAY,OAAO,SAAS,OAAO,UAAU;AAG/C,UAAM,aAAaC,UAAS,EAAE,IAAI,SAAS,IAAI,OAAOD,QAAO,MAAM,CAAC;AACpE,eAAW,SAAS;AAAA,EACtB,OAAO;AAGL,eAAW,WAAW,UAAU,GAAGA,QAAO,QAAQ,KAASA,QAAO,IAAI,KAASA,QAAO,cAAc,EAAE,CAAC;AACvG,UAAM,aAAa,EAAE,GAAGC,UAAS,OAAO,MAAM,SAAS,GAAG;AAAA,MACxD,MAAMD,QAAO;AAAA,MACb,OAAOA,QAAO;AAAA,MACd,YAAY,gBAAgB,GAAG;AAAA,IACjC,CAAC;AAAA,EACH;AACA,QAAM,KAAK,GAAG;AAAA,IACZ,CAAC,EAAE,GAAG,UAAU,IAAI,WAAW,IAAI,KAAK,OAAO,EAAE,KAAK,GAAG,QAAQ,IAAI,GAAG,IAAI,UAAU,KAAK,WAAW,KAAK,IAAI,EAAE,EAAE,CAAC;AAAA,IACpH,EAAE,YAAY,aAAa,GAAG,IAAI,QAAQ,GAAG;AAAA,EAC/C;AACA,QAAM,mBAAmBC,UAAS;AAAA,IAChC;AAAA,IACA,UAAUD,QAAO;AAAA,IACjB,gBAAgBA,QAAO;AAAA,IACvB,GAAI,QAAQ,YAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;AAAA,IAC5D,gBAAgBA,QAAO;AAAA,EACzB,CAAC;AACD,SAAO,EAAE,SAAS;AACpB;AA0BA,eAAsB,iBAAiB,MAAsB,WAAqD;AAChH,QAAM,OAAO,kBAAkB;AAAA,IAC7B,OAAO,UAAU;AAAA,IACjB,WAAW,UAAU;AAAA,IACrB,UAAU,UAAU;AAAA,IACpB,OAAO,UAAU;AAAA,IACjB,UAAU,UAAU;AAAA,IACpB,aAAa,UAAU;AAAA,EACzB,CAAC;AACD,QAAM,aAAa,SAAS,UAAU,aAAa;AACnD,QAAM,QAAQ,UAAU,SAAS,CAAC;AAClC,MAAI,OAAO,KAAK,KAAK,EAAE,WAAW,EAAG,QAAO,aAAa,MAAM,EAAE,OAAO,UAAU,OAAO,OAAO,MAAM,WAAW,CAAC;AAClH,MAAI;AACF,WAAO,MAAM,aAAa,MAAM,EAAE,OAAO,UAAU,OAAO,OAAO,EAAE,GAAG,MAAM,GAAG,MAAM,GAAG,WAAW,CAAC;AAAA,EACtG,QAAQ;AACN,WAAO,aAAa,MAAM,EAAE,OAAO,UAAU,OAAO,OAAO,MAAM,WAAW,CAAC;AAAA,EAC/E;AACF;;;ADpSA,IAAM,MAAM,CAAC,MAAwB,OAAO,MAAM,WAAW,IAAI,KAAK,OAAO,KAAK,OAAO,CAAC;AASnF,IAAM,UAAU,CACrB,IACA,SAC2C;AAAA,EAC3C,KAAK,IAAI,QAAQ;AAAA,EACjB;AAAA,EACA,KAAK,MAAM,KAAK,IAAI;AAAA,EACpB,OAAO,MAAM,OAAO,WAAW;AAAA,EAC/B,SAAS,IAAI;AACf;AAIO,SAAS,mBAAmB,SAAkB,KAAuD;AAC1G,QAAM,QAAQ,kBAAkB;AAAA,IAC9B,OAAO,IAAI,IAAI,KAAK;AAAA,IACpB,WAAW,IAAI,IAAI,SAAS,KAAK;AAAA,IACjC,UAAU,IAAI,IAAI,QAAQ,KAAK;AAAA,IAC/B,OAAO,IAAI,IAAI,KAAK,KAAK;AAAA,IACzB,UAAU,IAAI,IAAI,QAAQ,KAAK;AAAA,IAC/B,aAAa,IAAI,IAAI,EAAE;AAAA,EACzB,CAAC;AACD,aAAW,KAAK,QAAQ,YAAY,WAAW;AAC7C,QAAI,IAAI,CAAC,MAAM,OAAW,OAAM,CAAC,IAAI,IAAI,CAAC;AAAA,EAC5C;AACA,MAAI,IAAI,OAAO,OAAW,OAAM,gBAAgB,IAAI,IAAI,EAAE;AAC1D,SAAO;AACT;AAKA,SAAS,eAAe,KAAuD;AAC7E,QAAM,SAAS,IAAI,IAAI,MAAM;AAC7B,QAAM,OAAO,QAAQ,IAAI,oBAAoB,KAAK,WAAW;AAC7D,QAAM,gBAAgB,WAAW,aAAa,aAAa,IAAI,aAAa,OAAO,aAAa,OAAO,WAAW;AAClH,QAAM,OAAgC,EAAE,cAAc;AACtD,MAAI,IAAI,iBAAkB,MAAK,mBAAmB,IAAI,IAAI,gBAAgB;AAC1E,MAAI,IAAI,qBAAsB,MAAK,iBAAiB,IAAI,IAAI,oBAAoB;AAChF,MAAI,OAAO,IAAI,cAAc,SAAU,MAAK,YAAY,IAAI;AAC5D,SAAO;AACT;AAOA,eAAsB,qBACpB,MACA,MACwB;AACxB,QAAM,WAAW,IAAI,KAAK,IAAI,KAAK,EAAE,YAAY;AACjD,MAAI,CAAC,SAAU,QAAO;AAEtB,QAAM,aAAa,EAAE,KAAK,KAAK,KAAK,IAAI,KAAK,IAAa,KAAK,KAAK,KAAK,OAAO,KAAK,MAAM;AAC3F,QAAM,QAAQ,mBAAmB,KAAK,SAAS,KAAK,GAAG;AAEvD,QAAM,EAAE,WAAW,IAAI,MAAM,KAAK,GAAG,MAAM;AAAA,IACzC,YAAY,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,UAAU,cAAc,SAAS,GAAG,OAAO,EAAE,EAAE;AAAA,EACnF,CAAC;AACD,QAAM,WAAW,aAAa,CAAC,KAAK;AACpC,QAAM,QAAQ,KAAK,SAAS;AAE5B,MAAI;AACJ,MAAI,YAAY,OAAO,SAAS,OAAO,UAAU;AAC/C,eAAW,SAAS;AACpB,UAAME,cAAa,YAAY,EAAE,IAAI,UAAU,MAAM,CAAC;AAAA,EACxD,OAAO;AACL,UAAM,UAAU,MAAMC,cAAa,YAAY,EAAE,MAAM,UAAU,OAAO,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC,EAAG,CAAC;AACrG,eAAW,QAAQ;AAAA,EACrB;AAKA,MAAI,YAAY,SAAS,SAAS,UAAU,OAAO;AACjD,UAAM,SAAS,YAAY,EAAE,IAAI,UAAU,IAAI,OAAO,UAAU,UAAU,YAAY,aAAa,QAAQ,IAAI,KAAK,GAAG,CAAC,EAAE,MAAM,MAAM,MAAS;AAAA,EACjJ;AAEA,QAAM,KAAK,GAAG,SAAS,CAAC,EAAE,GAAG,UAAU,IAAI,cAAc,IAAI,UAAU,OAAO,eAAe,KAAK,GAAG,EAAE,CAAC,CAAC;AAKzG,QAAM,aAAa,YAAY,EAAE,UAAU,OAAO,UAAU,YAAY,YAAY,QAAQ,IAAI,QAAQ,GAAG,CAAC,EAAE,MAAM,MAAM,MAAS;AAEnI,SAAO;AACT;AAKA,eAAsB,YAAY,MAA2H;AAC3J,QAAM,OAAO,MAAM,KAAK,GAAG,MAAM;AAAA,IAC/B,cAAc,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,OAAO,GAAG,OAAO,IAAK,EAAE;AAAA,IACjE,QAAQ,EAAE,GAAG,EAAE,OAAO,IAAK,EAAE;AAAA,EAC/B,CAAC;AACD,QAAM,OAAO,oBAAI,IAAY;AAC7B,MAAI,SAAS;AACb,QAAM,SAAkD,CAAC;AAEzD,QAAM,MAAM,OAAO,KAA8B,UAAkC;AACjF,UAAM,MAAM,IAAI,IAAI,KAAK,EAAE,YAAY;AACvC,QAAI,CAAC,OAAO,KAAK,IAAI,GAAG,EAAG;AAC3B,SAAK,IAAI,GAAG;AACZ,QAAI;AACF,YAAM,qBAAqB,MAAM,EAAE,KAAK,MAAM,CAAC;AAC/C,gBAAU;AAAA,IACZ,SAAS,KAAK;AACZ,aAAO,KAAK,EAAE,OAAO,KAAK,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,EAAE,CAAC;AAAA,IACrF;AAAA,EACF;AAEA,aAAW,KAAM,KAAK,gBAAgB,CAAC,EAAsC,OAAM,IAAI,GAAG,IAAI,EAAE,MAAM,CAAC;AACvG,aAAW,KAAM,KAAK,UAAU,CAAC,GAAsC;AACrE,QAAI,EAAE,YAAY,KAAM;AACxB,UAAM,IAAI,EAAE,OAAO,EAAE,OAAO,WAAW,IAAI,EAAE,IAAI,EAAE,CAAC;AAAA,EACtD;AACA,SAAO,EAAE,QAAQ,OAAO;AAC1B;;;AGhHO,SAAS,OAAO,UAAkB,MAAsC;AAC7E,SAAO,SAAS,QAAQ,kBAAkB,CAAC,GAAG,QAAgB,KAAK,GAAG,KAAK,EAAE;AAC/E;AAGA,SAAS,UAAU,OAAmB,MAAsD;AAC1F,SAAO;AAAA,IACL,GAAG;AAAA,IACH,kBAAkB,MAAM,oBAAoB;AAAA,IAC5C,gBAAgB,MAAM,kBAAkB;AAAA,IACxC,WAAW,MAAM,aAAa;AAAA,EAChC;AACF;AASO,SAAS,mBAAmB,OAAmB,UAAkB,MAA6C;AACnH,QAAM,MAAM,MAAM,iBAAiB,QAAQ;AAC3C,MAAI,CAAC,IAAK,QAAO;AACjB,SAAO,OAAO,IAAI,MAAM,UAAU,OAAO,IAAI,CAAC;AAChD;AASO,SAAS,cAAc,WAAwD;AACpF,SAAO,UAAU,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK;AAC3C;AA2BO,SAAS,aAAa,OAUR;AACnB,QAAM,MAAM,MAAM,MAAM,iBAAiB,MAAM,QAAQ;AACvD,MAAI,CAAC,IAAK,QAAO,EAAE,SAAS,OAAO,QAAQ,mBAAmB;AAC9D,MAAI,IAAI,YAAY,SAAS,CAAC,MAAM,MAAO,QAAO,EAAE,SAAS,OAAO,QAAQ,WAAW;AAEvF,QAAM,OAAO,UAAU,MAAM,OAAO,MAAM,IAAI;AAC9C,QAAM,SAAS,MAAM,YAAY;AACjC,QAAM,WAAW,CAAC,UAAU,CAAC,CAAC,MAAM,MAAM;AAC1C,QAAM,YACJ,CAAC,UAAU,CAAC,WAAW,aAAa,MAAM,kBAAkB,eAAe;AAC7E,QAAM,KAAK,WAAY,MAAM,MAAM,aAAwB,MAAM;AACjE,QAAM,WAAW,WAAW,WAAW,MAAM,OAAO,IAAI,SAAS,IAAI;AACrE,QAAMC,QAAO,WACT,sCAAsC,MAAM,EAAE;AAAA;AAAA,IAAU,OAAO,IAAI,MAAM,IAAI,IAC7E,OAAO,IAAI,MAAM,IAAI;AACzB,SAAO,EAAE,SAAS,MAAM,WAAW,IAAI,SAAS,MAAAA,OAAM,YAAY,SAAS;AAC7E;;;AC1GO,IAAM,uBAAuB,CAAC,qBAAqB,uBAAuB,aAAa,kBAAkB;AA6ChH,eAAsB,cAAc,MAAkB,OAA2C;AAC/F,QAAM,EAAE,SAAS,IAAI,MAAM,KAAK,GAAG,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,MAAM,UAAU,EAAE,EAAE,EAAE,CAAC;AACvG,QAAM,QAAS,MAAM,QAAQ,QAAQ,IAAI,WAAW,CAAC;AACrD,MAAI,cAAc,KAAK,EAAG,QAAO,EAAE,MAAM,MAAM,QAAQ,eAAe;AAEtE,QAAM,kBAAkB,QAAQ,KAAK,UAAU,KAAK,IAAI;AACxD,QAAM,WAAW,aAAa;AAAA,IAC5B,SAAS,KAAK;AAAA,IACd,OAAO,MAAM;AAAA,IACb,UAAU,MAAM;AAAA,IAChB,IAAI,MAAM;AAAA,IACV,MAAM,MAAM;AAAA,IACZ;AAAA,IACA,OAAO,MAAM;AAAA,EACf,CAAC;AACD,MAAI,CAAC,SAAS,QAAS,QAAO,EAAE,MAAM,OAAO,QAAQ,SAAS,OAAO;AAErE,MAAI;AACJ,MAAI;AACJ,MAAI,SAAS,cAAc,gBAAgB,KAAK,UAAU,KAAK,MAAM;AACnE,QAAI;AACF,YAAM,MAAM,MAAM,KAAK,OAAO,KAAK;AAAA,QACjC,MAAM,KAAK;AAAA,QACX,IAAI,CAAC,SAAS,EAAE;AAAA,QAChB,SAAS,SAAS;AAAA,QAClB,MAAM,SAAS;AAAA,QACf,SAAS,MAAM,MAAM;AAAA,MACvB,CAAC;AACD,kBAAY,IAAI;AAAA,IAClB,SAAS,GAAG;AACV,cAAQ,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AAAA,IACnD;AAAA,EACF;AAEA,QAAM,KAAK,KAAK,MAAM;AACtB,QAAM,MAA+B;AAAA,IACnC;AAAA,IACA,SAAS,MAAM,MAAM;AAAA,IACrB,IAAI,SAAS;AAAA,IACb,UAAU,MAAM;AAAA,IAChB,SAAS,SAAS;AAAA,IAClB,MAAM,SAAS;AAAA,IACf,WAAW,SAAS;AAAA,IACpB,YAAY,SAAS;AAAA,IACrB,WAAW,MAAM;AAAA,IACjB,QAAQ,KAAK,IAAI;AAAA,IACjB,GAAI,MAAM,gBAAgB,EAAE,eAAe,MAAM,cAAc,IAAI,CAAC;AAAA,IACpE,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,IACjC,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,EAC3B;AACA,QAAM,KAAK,GAAG,SAAS,CAAC,EAAE,GAAG,UAAU,IAAI,YAAY,IAAI,OAAO,IAAI,CAAC,GAAG,QAAQ,SAAY,EAAE,YAAY,SAAS,MAAM,SAAS,GAAG,CAAC;AACxI,SAAO,QAAQ,EAAE,MAAM,OAAO,QAAQ,MAAM,IAAI,EAAE,MAAM,KAAK;AAC/D;AAGO,SAAS,eAAe,KAA0C;AACvE,QAAMC,OAAM,CAAC,MAAoC,OAAO,MAAM,WAAW,IAAI;AAC7E,QAAM,YAAY,IAAI,kBAAkB,OAAO,IAAI,mBAAmB,WAAW,IAAI,iBAAiB,CAAC;AACvG,SAAO;AAAA,IACL,IAAI,OAAO,IAAI,EAAE;AAAA,IACjB,MAAM,OAAO,IAAI,QAAQ,EAAE;AAAA,IAC3B,SAASA,KAAI,IAAI,OAAO,KAAK;AAAA,IAC7B,YAAYA,KAAI,IAAI,UAAU;AAAA,IAC9B,kBAAkBA,KAAI,IAAI,gBAAgB;AAAA,IAC1C,gBAAgBA,KAAI,IAAI,cAAc;AAAA,IACtC,WAAWA,KAAI,IAAI,SAAS;AAAA,IAC5B,gBAAgB;AAAA,EAClB;AACF;;;AClEO,SAAS,cAAc,MAAc,IAAY,GAA8B;AACpF,QAAM,KAAK,EAAE,OAAO,QAAQ,IAAI;AAChC,QAAM,KAAK,EAAE,OAAO,QAAQ,EAAE;AAC9B,SAAO,MAAM,KAAK,MAAM,KAAK,MAAM;AACrC;AAGO,SAAS,QAAQ,QAAgB,GAA8B;AACpE,SAAO,EAAE,aAAa,SAAS,MAAM;AACvC;AAGO,SAAS,WAAW,QAAgB,GAA8B;AACvE,SAAO,EAAE,eAAe,SAAS,MAAM;AACzC;;;ACtDA,eAAsB,mBAAmB,OAOH;AACpC,QAAM,EAAE,IAAI,KAAK,KAAK,IAAI,IAAI;AAC9B,QAAM,KAAK,OAAO,IAAI,MAAM,EAAE;AAC9B,QAAM,SAAS,OAAO,IAAI,UAAU,EAAE;AACtC,MAAI,CAAC,GAAI,QAAO,EAAE,IAAI,OAAO,QAAQ,KAAK,OAAO,YAAY;AAC7D,MAAI,MAAM,WAAW,YAAY,WAAW,cAAc,CAAC,WAAW,QAAQ,IAAI,QAAQ,QAAQ,GAAG;AACnG,WAAO,EAAE,IAAI,OAAO,QAAQ,KAAK,OAAO,+BAA+B,MAAM,IAAI;AAAA,EACnF;AACA,MAAI,MAAM,WAAW,oBAAoB;AACvC,QAAI,OAAO,IAAI,sBAAsB,SAAU,QAAO,EAAE,IAAI,OAAO,QAAQ,KAAK,OAAO,4BAA4B;AACnH,QAAI,WAAW,cAAc,CAAC,cAAc,QAAQ,YAAY,IAAI,QAAQ,QAAQ,GAAG;AACrF,aAAO,EAAE,IAAI,OAAO,QAAQ,KAAK,OAAO,+BAA+B,MAAM,IAAI;AAAA,IACnF;AAAA,EACF;AACA,QAAM,QAAQ,MAAM,GAAG;AAAA,IACrB,CAAC,EAAE,GAAG,UAAU,IAAI,gBAAgB,IAAI,OAAO,EAAE,QAAQ,WAAW,EAAE,CAAC;AAAA,IACvE,EAAE,YAAY,WAAW,EAAE,GAAG;AAAA,EAChC;AACA,QAAM,WAAW,EAAE,GAAG,KAAK,QAAQ,WAAW;AAC9C,QAAM,qBAAqB,QAAQ,IAAI,GAAG,GAAG,EAAE,KAAK,UAAU,OAAO,WAAW,CAAC,EAAE,MAAM,MAAM,MAAS;AAExG,QAAM,EAAE,WAAW,KAAK,IAAI,IAAI,QAAQ,WAAW;AACnD,MAAI,eAAe;AACnB,QAAM,SAAS,MAAM,eAAe,IAAI,kBAAkB;AAC1D,MAAI,cAAc,SAAS,QAAQ;AACjC,QAAI,SAAS,OAAO,IAAI,gBAAgB,WAAW,IAAI,cAAc;AACrE,QAAI,CAAC,UAAU,OAAO,IAAI,UAAU,UAAU;AAC5C,YAAM,QAAQ,MAAM,oBAAoB,QAAQ,IAAI,KAAK;AACzD,eAAS,OAAO,MAAM;AACtB,UAAI,OAAQ,OAAM,GAAG,SAAS,CAAC,EAAE,GAAG,UAAU,IAAI,gBAAgB,IAAI,OAAO,EAAE,aAAa,OAAO,EAAE,CAAC,CAAC;AAAA,IACzG;AACA,QAAI,OAAQ,gBAAe,MAAM,aAAa,QAAQ,QAAQ,SAAS;AAAA,EACzE;AAEA,MAAI,cAAc;AAClB,QAAM,UAAU,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,OAAO,IAAI,WAAW,IAAI,QAAQ,EAAE,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG;AACvH,QAAM,QAAQ,MAAM,QAAQ,MAAM,IAAI,OAAO,CAAC,IAAI;AAClD,MAAI,SAAS,SAAS,SAAS,OAAO,IAAI,UAAU,UAAU;AAC5D,UAAM,SAAS,MAAM;AAAA,MACnB,EAAE,IAAI,SAAS,IAAI,UAAU,QAAQ,IAAI,YAAY,MAAM,IAAI,YAAY,KAAK,MAAM,KAAK,IAAI,GAAG,OAAO,MAAM,OAAO,WAAW,EAAE;AAAA,MACnI;AAAA,QACE,OAAO,eAAe,KAAK;AAAA,QAC3B,UAAU;AAAA,QACV,IAAI,IAAI;AAAA,QACR,MAAM,EAAE,WAAW,OAAO,IAAI,aAAa,EAAE,GAAG,YAAY,GAAG,MAAM,MAAM,YAAY;AAAA,QACvF,eAAe;AAAA,QACf,WAAW,WAAW,EAAE;AAAA,MAC1B;AAAA,IACF;AACA,kBAAc,OAAO;AAAA,EACvB;AACA,SAAO,EAAE,IAAI,MAAM,QAAQ,KAAK,cAAc,aAAa,WAAW,MAAM,UAAU;AACxF;;;AC5EO,SAAS,wBAAwB,OAOZ;AAC1B,MAAI,MAAM,WAAW,WAAY,QAAO;AACxC,MAAI,MAAM,iBAAiB;AACzB,QAAI,CAAC,MAAM,QAAS,QAAO;AAC3B,QAAI,MAAM,WAAW,MAAM,eAAe;AACxC,aAAO,MAAM,sBAAsB,mBAAmB;AAAA,IACxD;AACA,WAAO;AAAA,EACT;AACA,MAAI,CAAC,MAAM,QAAS,QAAO;AAC3B,MAAI,MAAM,WAAW,MAAM,eAAe;AACxC,WAAO,MAAM,sBAAsB,mBAAmB;AAAA,EACxD;AACA,MAAI,QAAQ,MAAM,QAAQ,MAAM,QAAQ,EAAG,QAAO;AAClD,SAAO;AACT;;;ACpBA,eAAsB,aACpB,IACA,KACA,KACA,QACA,KACA,OACgF;AAChF,MAAI,OAAO,IAAI,gBAAgB,UAAU;AACvC,QAAI,OAAO,IAAI,gBAAgB,SAAU,QAAO;AAChD,WAAO,OAAO,IAAI,0BAA0B,WAAW,mBAAmB;AAAA,EAC5E;AACA,QAAM,YAAY,MAAM,eAAe,IAAI,mBAAmB;AAC9D,QAAM,UAAU,MAAM,mBAAmB,IAAI,OAAgB,QAAQ,SAAS,CAAC;AAC/E,QAAM,OAAO,SAAS,SAAS,OAAO,IAAI,WAAW,WAAW,IAAI,SAAS,IAAI;AACjF,QAAM,UAAU,QAAQ,IAAI,KAAK,CAAC,WAAW,IAAK,KAAK,YAAY,MAAO,OAAgB,QAAQ,SAAS,CAAC;AAC5G,QAAM,QAAQ,wBAAwB;AAAA,IACpC,QAAQ,OAAO,IAAI,UAAU,EAAE;AAAA,IAAG,eAAe,IAAI,QAAQ,SAAS;AAAA,IACtE,UAAU,IAAI,QAAQ;AAAA,IAAU;AAAA,IAChC,qBAAqB,OAAO,IAAI,yBAAyB,YAAY,IAAI,yBAAyB;AAAA,IAClG,iBAAiB,OAAO,IAAI,sBAAsB;AAAA,EACpD,CAAC;AACD,MAAI,UAAU,UAAW,QAAO;AAChC,QAAM,WAAW,MAAM,mBAAmB,EAAE,IAAI,KAAK,KAAK,KAAK,QAAQ,QAAQ,mBAAmB,CAAC;AACnG,SAAO,SAAS,KAAK,aAAa;AACpC;;;ACjBA,SAAS,SAAS,KAAsE;AACtF,MAAI,CAAC,OAAO,OAAO,IAAI,aAAa,YAAY,IAAI,aAAa,KAAM,QAAO;AAC9E,SAAO;AACT;AAEA,eAAe,iBACb,IACA,UACA,aACA,QACkB;AAClB,QAAM,QAAQ,EAAE,UAAU,aAAa,GAAI,SAAS,EAAE,QAAQ,KAAK,IAAI,CAAC,EAAG;AAC3E,MAAI,GAAG,WAAW;AAChB,WAAO,QAAQ,MAAM,GAAG,UAAU,kBAAkB,EAAE,OAAO,KAAK,GAAG,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI;AAAA,EACjG;AAGA,QAAMC,SAAQ,MAAM,GAAG,MAAM,EAAE,gBAAgB,CAAC,EAAE,CAAC,GAAG;AACtD,SAAO,MAAM,QAAQA,KAAI,KAAKA,MAAK,KAAK,CAAC,QACvC,IAAI,aAAa,YAAY,IAAI,gBAAgB,gBAAgB,CAAC,UAAU,IAAI,WAAW,KAAK;AACpG;AAEA,eAAsB,wBACpB,IACA,UACA,aACqC;AAIrC,MAAI,CAAC,MAAM,iBAAiB,IAAI,UAAU,WAAW,EAAG,QAAO;AAC/D,QAAMA,SAAQ,MAAM,GAAG,MAAM,EAAE,gBAAgB,EAAE,GAAG;AAAA,IAClD,OAAO,EAAE,UAAU,YAAY;AAAA,IAAG,OAAO,EAAE,UAAU,OAAO;AAAA,IAAG,OAAO;AAAA,EACxE,EAAE,EAAE,CAAC,GAAG;AACR,QAAM,SAAS,MAAM,QAAQA,KAAI,IAC7B,CAAC,GAAGA,KAAI,EAAE,KAAK,CAAC,GAAG,MAAM,OAAO,EAAE,YAAY,CAAC,IAAI,OAAO,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,IAC7E;AACJ,SAAO,SAAS,MAAM;AACxB;AAEA,eAAsB,wBACpB,IACA,UACA,aACqC;AACrC,MAAI,CAAC,MAAM,iBAAiB,IAAI,UAAU,aAAa,IAAI,EAAG,QAAO;AACrE,QAAMA,SAAQ,MAAM,GAAG,MAAM,EAAE,gBAAgB,EAAE,GAAG;AAAA,IAClD,OAAO,EAAE,UAAU,aAAa,QAAQ,KAAK;AAAA,IAAG,OAAO,EAAE,UAAU,OAAO;AAAA,IAAG,OAAO;AAAA,EACtF,EAAE,EAAE,CAAC,GAAG;AACR,QAAM,SAAS,MAAM,QAAQA,KAAI,IAC7B,CAAC,GAAGA,KAAI,EAAE,KAAK,CAAC,GAAG,MAAM,OAAO,EAAE,YAAY,CAAC,IAAI,OAAO,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,IAC7E;AACJ,SAAO,SAAS,MAAM;AACxB;AAGO,SAAS,sBACd,MACA,UACqB;AACrB,QAAM,YAAY,UAAU;AAC5B,SAAO,YACH,EAAE,GAAG,MAAM,UAAU,UAAU,UAAU,UAAU,UAAU,UAAU,YAAY,EAAE,GAAI,UAAU,cAAc,CAAC,EAAG,EAAE,IACvH;AACN;AAEO,SAAS,8BAA8B,SAAkB,UAA2C;AACzG,MAAI,CAAC,SAAS,YAAa,QAAO,CAAC;AACnC,QAAM,WAAW,oBAAI,IAAI,CAAC,GAAG,QAAQ,YAAY,UAAU,GAAG,QAAQ,YAAY,QAAQ,CAAC;AAC3F,SAAO,CAAC,GAAG,SAAS,YAAY,UAAU,GAAG,SAAS,YAAY,QAAQ,EACvE,OAAO,CAAC,UAAU,CAAC,SAAS,IAAI,KAAK,CAAC,EACtC,IAAI,CAAC,UAAU,+BAA+B,KAAK,0CAA0C;AAClG;AAEA,SAAS,WAAW,UAA0D;AAC5E,QAAMC,SAAQ,CAAC,GAAG,SAAS,KAAK,EAAE,OAAO,CAAC,SAAS,KAAK,SAAS,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;AAC9G,QAAM,YAAY,CAAC,GAAG,SAAS,KAAK,EAAE,KAAK,CAAC,SAAS,KAAK,aAAa,KAAK,aAAa,CAAC;AAC1F,SAAO;AAAA,IACL,GAAIA,SAAQ,EAAE,oBAAoBA,OAAM,WAAW,IAAI,CAAC;AAAA,IACxD,uBAAuB;AAAA,IACvB,GAAI,WAAW,gBAAgB,EAAE,eAAe,UAAU,cAAc,IAAI,CAAC;AAAA,IAC7E,GAAI,SAAS,UAAU,CAAC;AAAA,IACxB,GAAI,SAAS,aAAa,EAAE,gBAAgB,SAAS,WAAW,IAAI,CAAC;AAAA,EACvE;AACF;AAEA,IAAM,aAAa,CAAC,IAAwB,WAA6B;AAAA,EACvE;AAAA,EACA,MAAM;AAAA,EACN;AACF;AAGA,eAAsB,yBACpB,IACA,UACA,UACA,YACe;AACf,QAAM,EAAE,UAAU,OAAO,IAAI;AAC7B,QAAM,eAAe,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG;AAAA,IAChD,OAAO,EAAE,SAAS,SAAS,OAAO,UAAU;AAAA,IAAG,OAAO;AAAA,EACxD,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC;AAClB,QAAM,WAAW,IAAI,IAAI,SAAS,MAAM,IAAI,CAAC,SAAS,KAAK,EAAE,CAAC;AAC9D,QAAM,MAAiC,CAAC;AACxC,MAAI,UAAU,OAAQ,KAAI,KAAK,EAAE,GAAG,UAAU,IAAI,kBAAkB,IAAI,SAAS,IAAI,OAAO,EAAE,QAAQ,MAAM,EAAE,CAAC;AAC/G,aAAW,OAAO,aAAa;AAC7B,UAAMC,MAAK,OAAO,IAAI,MAAM,EAAE;AAC9B,QAAIA,OAAM,CAAC,SAAS,IAAIA,GAAE,GAAG;AAC3B,UAAI,KAAK,EAAE,GAAG,UAAU,IAAI,SAAS,IAAI,WAAW,SAASA,GAAE,GAAG,OAAO,EAAE,QAAQ,MAAM,EAAE,CAAC;AAAA,IAC9F;AAAA,EACF;AACA,aAAW,QAAQ,SAAS,OAAO;AACjC,UAAM,UAAU,WAAW,SAAS,KAAK,EAAE;AAC3C,QAAI,KAAK,EAAE,GAAG,UAAU,IAAI,SAAS,IAAI,SAAS,OAAO;AAAA,MACvD,IAAI,KAAK;AAAA,MACT,SAAS,SAAS,OAAO;AAAA,MACzB,MAAM,KAAK;AAAA,MACX,YAAY,KAAK;AAAA,MACjB,GAAI,KAAK,gBAAgB,EAAE,eAAe,KAAK,cAAc,IAAI,CAAC;AAAA,MAClE,GAAI,KAAK,QAAQ,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;AAAA,MAC1C,WAAW,KAAK;AAAA,MAChB,QAAQ,KAAK;AAAA,MACb,WAAW;AAAA,IACb,EAAE,CAAC;AACH,UAAM,UAAU;AAAA,MACd,GAAI,CAAC,KAAK,gBAAgB,CAAC,eAAe,IAAI,CAAC;AAAA,MAC/C,GAAI,CAAC,KAAK,QAAQ,CAAC,OAAO,IAAI,CAAC;AAAA,IACjC;AACA,QAAI,QAAQ,OAAQ,KAAI,KAAK,EAAE,GAAG,WAAW,IAAI,SAAS,IAAI,SAAS,OAAO,QAAQ,CAAC;AAAA,EACzF;AACA,QAAM,WAAW,WAAW,UAAU,SAAS,OAAO,SAAS;AAC/D,QAAM,QAAQ,WAAW,QAAQ;AACjC,MAAI,KAAK;AAAA,IACP,GAAG;AAAA,IACH,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ;AAAA,EACF,CAAC;AACD,MAAI,EAAE,mBAAmB,QAAQ;AAC/B,QAAI,KAAK,EAAE,GAAG,WAAW,IAAI,UAAU,IAAI,UAAU,OAAO,CAAC,eAAe,EAAE,CAAC;AAAA,EACjF;AACA,QAAM,KAAK,kBAAkB,SAAS,OAAO,WAAW,IAAI,SAAS,QAAQ;AAC7E,MAAI,KAAK,EAAE,GAAG,UAAU,IAAI,kBAAkB,IAAI,OAAO;AAAA,IACvD;AAAA,IACA,UAAU,SAAS,OAAO;AAAA,IAC1B,UAAU,SAAS,OAAO;AAAA,IAC1B,aAAa,SAAS,OAAO;AAAA,IAC7B,UAAU,SAAS;AAAA,IACnB;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,EACF,EAAE,CAAC;AACH,QAAM,GAAG,SAAS,KAAK,EAAE,YAAY,kBAAkB,SAAS,OAAO,WAAW,IAAI,SAAS,QAAQ,IAAI,MAAM,GAAG,CAAC;AACvH;;;AClGO,SAAS,mBAAmB,KAA4C;AAC7E,SAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,WAAW,IAAI,aAAa;AAAA,IAC5B,UAAU,IAAI,YAAY;AAAA,IAC1B,OAAO,IAAI,SAAS;AAAA,IACpB,QAAQ,IAAI;AAAA,IACZ,WAAW,IAAI,aAAa;AAAA,IAC5B,aAAa,IAAI,eAAe;AAAA,IAChC,MAAM,QAAQ,IAAI,oBAAoB,KAAK,IAAI,WAAW;AAAA,IAC1D,WAAW,IAAI,aAAa;AAAA,IAC5B,UAAU,IAAI,aAAa;AAAA,IAC3B,QAAQ,IAAI,UAAU;AAAA,EACxB;AACF;AAKO,SAAS,kBACd,KACA,SACA,iBACmB;AACnB,QAAM,UAAU,mBAAmB,GAAG;AACtC,MAAI,YAAY,IAAI,aAAa;AACjC,MAAI,UAAyB;AAC7B,MAAI,WAAW;AACf,MAAI,SAAS;AACX,eAAW,QAAQ,YAAY;AAC/B,QAAI,QAAQ,WAAW,aAAa;AAClC,kBAAY,QAAQ,WAAW;AAC/B,gBAAU,QAAQ,WAAW;AAAA,IAC/B,OAAO;AACL,kBAAY;AAAA,IACd;AAAA,EACF;AACA,SAAO,EAAE,GAAG,SAAS,WAAW,SAAS,SAAS;AACpD;;;AC3FA,IAAM,OAAO,CAAC,WACZ,WAAW,MAAM,EAAE,IAAI,MAAM,QAAQ,SAAS,KAAK,IAAI,EAAE,IAAI,OAAO,OAAO;AAetE,SAAS,mBAAmB,OAA0E;AAC3G,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,MACJ,eAAe,MAAM;AAAA,MACrB,QAAQ;AAAA,MACR,GAAI,MAAM,cAAc,EAAE,cAAc,MAAM,YAAY,IAAI,CAAC;AAAA,MAC/D,GAAI,MAAM,iBAAiB,EAAE,iBAAiB,MAAM,eAAe,IAAI,CAAC;AAAA,IAC1E;AAAA,EACF;AACF;AAKA,eAAsB,sBACpB,WACA,OACA,YAA0B,OACJ;AACtB,QAAM,EAAE,MAAM,KAAK,IAAI,mBAAmB,KAAK;AAC/C,QAAM,MAAM,MAAM,UAAU,wBAAwB,IAAI,IAAI;AAAA,IAC1D,QAAQ;AAAA,IACR,SAAS,EAAE,eAAe,UAAU,SAAS,IAAI,gBAAgB,mBAAmB;AAAA,IACpF,MAAM,KAAK,UAAU,IAAI;AAAA,EAC3B,CAAC;AACD,SAAO,IAAI,KAAK,EAAE,IAAI,MAAM,QAAQ,IAAI,OAAO,IAAI,KAAK,IAAI,MAAM;AACpE;AAoBO,SAAS,iBAAiB,OAAwE;AACvG,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,MACJ,eAAe,CAAC,MAAM,KAAK;AAAA,MAC3B,2BAA2B;AAAA,MAC3B,GAAI,MAAM,YAAY,EAAE,YAAY,MAAM,UAAU,IAAI,CAAC;AAAA,MACzD,GAAI,MAAM,WAAW,EAAE,WAAW,MAAM,SAAS,IAAI,CAAC;AAAA,MACtD,GAAI,MAAM,mBAAmB,SAAY,EAAE,iBAAiB,MAAM,eAAe,IAAI,CAAC;AAAA,MACtF,GAAI,MAAM,oBAAoB,SAAY,EAAE,kBAAkB,MAAM,gBAAgB,IAAI,CAAC;AAAA,IAC3F;AAAA,EACF;AACF;AAWA,eAAsB,wBACpB,WACA,QACA,OACA,YAA0B,OACR;AAClB,QAAM,MAAM,MAAM,UAAU,kCAAkC,mBAAmB,MAAM,CAAC,aAAa;AAAA,IACnG,QAAQ;AAAA,IACR,SAAS,EAAE,eAAe,UAAU,SAAS,IAAI,gBAAgB,mBAAmB;AAAA,IACpF,MAAM,KAAK,UAAU;AAAA,MACnB,GAAI,MAAM,mBAAmB,SAAY,EAAE,iBAAiB,MAAM,eAAe,IAAI,CAAC;AAAA,MACtF,GAAI,MAAM,oBAAoB,SAAY,EAAE,kBAAkB,MAAM,gBAAgB,IAAI,CAAC;AAAA,IAC3F,CAAC;AAAA,EACH,CAAC;AACD,SAAO,IAAI;AACb;AAQA,eAAsB,+BACpB,WACA,OACA,OACA,YAA0B,OACR;AAClB,QAAM,OAAO,EAAE,eAAe,UAAU,SAAS,GAAG;AACpD,QAAM,QAAQ,MAAM,UAAU,gDAAgD,mBAAmB,KAAK,CAAC,YAAY,EAAE,SAAS,KAAK,CAAC;AACpI,MAAI,CAAC,MAAM,GAAI,QAAO;AACtB,QAAM,QAAS,MAAM,MAAM,KAAK,EAAE,MAAM,MAAM,IAAI;AAClD,QAAM,KAAK,MAAM,QAAQ,KAAK,KAAK,OAAO,MAAM,CAAC,GAAG,OAAO,WAAW,MAAM,CAAC,EAAE,KAAK;AACpF,MAAI,CAAC,GAAI,QAAO;AAChB,SAAO,wBAAwB,WAAW,IAAI,OAAO,SAAS;AAChE;AAOA,eAAsB,gBACpB,WACA,OACA,YAA0B,OACJ;AACtB,QAAM,EAAE,MAAM,KAAK,IAAI,iBAAiB,KAAK;AAC7C,QAAM,MAAM,MAAM,UAAU,wBAAwB,IAAI,IAAI;AAAA,IAC1D,QAAQ;AAAA,IACR,SAAS,EAAE,eAAe,UAAU,SAAS,IAAI,gBAAgB,mBAAmB;AAAA,IACpF,MAAM,KAAK,UAAU,IAAI;AAAA,EAC3B,CAAC;AACD,MAAI,IAAI,GAAI,QAAO,EAAE,IAAI,MAAM,QAAQ,IAAI,OAAO;AAClD,QAAM,SAAS,KAAK,IAAI,MAAM;AAC9B,QAAM,SAAS,MAAM,kBAAkB;AAAA,IACrC,GAAI,MAAM,mBAAmB,SAAY,EAAE,gBAAgB,MAAM,eAAe,IAAI,CAAC;AAAA,IACrF,GAAI,MAAM,oBAAoB,SAAY,EAAE,iBAAiB,MAAM,gBAAgB,IAAI,CAAC;AAAA,EAC1F;AACA,MACE,CAAC,OAAO,WACP,OAAO,mBAAmB,UAAa,OAAO,oBAAoB,OACnE,QAAO;AACT,QAAM,YAAY,MAAM,+BAA+B,WAAW,MAAM,OAAO;AAAA,IAC7E,GAAI,OAAO,mBAAmB,SAAY,EAAE,gBAAgB,OAAO,eAAe,IAAI,CAAC;AAAA,IACvF,GAAI,OAAO,oBAAoB,SAAY,EAAE,iBAAiB,OAAO,gBAAgB,IAAI,CAAC;AAAA,EAC5F,GAAG,SAAS,EAAE,MAAM,MAAM,KAAK;AAC/B,SAAO,EAAE,GAAG,QAAQ,UAAU;AAChC;;;ACnKO,IAAM,2BAA2B,CACtC,SACA,eACA,QACA,uBAAuB,UACK;AAC5B,QAAM,UAAU,iBAAiB,SAAS,MAAM;AAChD,SAAO;AAAA,IACL;AAAA,IACA,GAAI,UAAU,EAAE,QAAQ,IAAI,uBAAuB,EAAE,SAAS,KAAK,IAAI,CAAC;AAAA,EAC1E;AACF;AAKO,IAAM,uBAAuB,EAAE,eAAe,MAAM,SAAS,KAAK;AAEzE,eAAsB,0BACpB,IACA,eACA,aACe;AACf,QAAM,GAAG,SAAS,CAAC;AAAA,IACjB,GAAG;AAAA,IACH,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,OAAO;AAAA,MACL,8BAA8B,KAAK,IAAI;AAAA,MACvC,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;AAAA,IACvC;AAAA,EACF,CAAC,CAAC;AACJ;AAMA,eAAsB,6BACpB,IACA,SACA,eACA,QACA,aACkB;AAClB,MAAI,QAAQ,YAAY,OAAQ,QAAO;AACvC,MAAI;AACF,UAAM,SAAS,MAAM,eAAe,IAAI,kBAAkB;AAC1D,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,KAAK,MAAM,wBAAwB,QAAQ,aAAa;AAAA,MAC5D,gBAAgB;AAAA,MAChB,iBAAiB,yBAAyB,SAAS,eAAe,QAAQ,IAAI;AAAA,IAChF,CAAC;AACD,QAAI,CAAC,GAAI,QAAO;AAChB,UAAM,0BAA0B,IAAI,eAAe,WAAW;AAC9D,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAIA,eAAsB,mBACpB,IACA,SACA,eACA,QACe;AACf,QAAM,QAAQ,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ;AAChE,MAAI,CAAC,MAAO;AACZ,QAAM,cAAc,CAAC,UACnB,OAAO,UAAU,WAAW,QAAQ;AACtC,QAAM,QAAiC,CAAC;AACxC,aAAW,SAAS,QAAQ,YAAY,WAAW;AACjD,QAAI,OAAO,KAAK,MAAM,OAAW,OAAM,KAAK,IAAI,OAAO,KAAK;AAAA,EAC9D;AACA,MAAI;AACF,UAAM;AAAA,MACJ,EAAE,KAAK,QAAQ,KAAK,IAAI,KAAK,MAAM,KAAK,IAAI,GAAG,OAAO,MAAM,OAAO,WAAW,EAAE;AAAA,MAChF;AAAA,QACE;AAAA,QACA;AAAA,QACA,WAAW,YAAY,OAAO,SAAS;AAAA,QACvC,UAAU,YAAY,OAAO,QAAQ;AAAA,QACrC,OAAO,YAAY,OAAO,KAAK;AAAA,QAC/B,UAAU,YAAY,OAAO,QAAQ;AAAA,QACrC;AAAA,MACF;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AACA,MAAI,QAAQ,YAAY,OAAQ;AAChC,MAAI;AACF,UAAM,SAAS,MAAM,eAAe,IAAI,kBAAkB;AAC1D,QAAI,CAAC,OAAQ;AACb,UAAM,kBAAkB,yBAAyB,SAAS,eAAe,MAAM;AAC/E,QAAI,QAAQ,YAAY,UAAU;AAChC,YAAM,SAAS,MAAM,gBAAgB,QAAQ;AAAA,QAC3C;AAAA,QACA,WAAW,YAAY,OAAO,SAAS;AAAA,QACvC,UAAU,YAAY,OAAO,QAAQ;AAAA,QACrC;AAAA,QACA,gBAAgB;AAAA,UACd,gBAAgB;AAAA,UAChB,iBAAiB,yBAAyB,SAAS,eAAe,QAAQ,IAAI;AAAA,QAChF;AAAA,MACF,CAAC;AACD,UAAI,OAAO,OAAO,CAAC,OAAO,WAAW,OAAO,YAAY;AACtD,cAAM,0BAA0B,IAAI,aAAa;AAAA,MACnD;AAAA,IACF,OAAO;AAIL,YAAM,SAAS,MAAM,sBAAsB,QAAQ,EAAE,MAAM,CAAC;AAC5D,UAAI,OAAO,SAAS;AAClB,cAAM,YAAY,MAAM,+BAA+B,QAAQ,OAAO;AAAA,UACpE,gBAAgB;AAAA,UAChB,iBAAiB,yBAAyB,SAAS,eAAe,QAAQ,IAAI;AAAA,QAChF,CAAC;AACD,YAAI,UAAW,OAAM,0BAA0B,IAAI,aAAa;AAAA,MAClE;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AACF;AAIA,eAAsB,yBACpB,IACA,KACA,WACA,eACA,QACe;AACf,MAAI;AACF,UAAM,UACJ,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,UAAU,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,GACxE;AACF,UAAM,QAAQ,MAAM,QAAQ,MAAM,IAAI,OAAO,CAAC,IAAI;AAClD,QAAI,CAAC,SAAS,OAAO,MAAM,sBAAsB,YAAY,CAAC,MAAM,kBAAmB;AACvF,UAAM,cAAc,CAAC,UAA2B,OAAO,UAAU,WAAW,QAAQ;AACpF,UAAM;AAAA,MACJ;AAAA,QACE;AAAA,QACA,SAAS,IAAI;AAAA,QACb,QAAQ,IAAI;AAAA,QACZ,MAAM,IAAI;AAAA,QACV,KAAK,MAAM,KAAK,IAAI;AAAA,QACpB,OAAO,MAAM,OAAO,WAAW;AAAA,MACjC;AAAA,MACA;AAAA,QACE,OAAO,eAAe,KAAK;AAAA,QAC3B,UAAU;AAAA,QACV,IAAI,MAAM;AAAA,QACV,MAAM;AAAA,UACJ,WAAW,YAAY,OAAO,SAAS;AAAA,UACvC,UAAU,YAAY,OAAO,QAAQ;AAAA,UACrC,OAAO,YAAY,OAAO,KAAK;AAAA,UAC/B,OAAO,YAAY,OAAO,KAAK;AAAA,UAC/B,OAAO,YAAY,OAAO,KAAK;AAAA,QACjC;AAAA,QACA,WAAW,SAAS,aAAa;AAAA,QACjC;AAAA,MACF;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AACF;;;A1BzJA,eAAe,yBACb,IACA,WACA,OACqF;AACrF,MAAI,QAAQ,MAAM,GAAG,MAAM,EAAE,cAAc,EAAE,GAAG;AAAA,IAC9C,OAAO,EAAE,iBAAiB,sBAAsB,KAAK,EAAE;AAAA,IAAG,OAAO;AAAA,EACnE,EAAE,EAAE,CAAC,GAAG;AACR,MAAI,CAAC,MAAM,OAAQ,SAAQ,MAAM,GAAG,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,GAAG,EAAE,EAAE,CAAC,GAAG;AACrG,QAAM,MAAM,MAAM,QAAQ,IAAI,IAAI,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,MAAM,OAAO,EAAE,aAAa,CAAC,IAAI,OAAO,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,IAAI;AACrH,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,YACJ,MAAM,GAAG,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,eAAe,IAAI,IAAI,QAAQ,YAAY,GAAG,OAAO,EAAE,WAAW,OAAO,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,GACrI;AACF,QAAM,UAAU,MAAM,QAAQ,QAAQ,IAAI,SAAS,CAAC,IAAI;AACxD,QAAM,UAAU,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,UAAU,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG;AAC3F,QAAM,QAAQ,MAAM,QAAQ,MAAM,IAAI,OAAO,CAAC,IAAI;AAClD,QAAM,WAAW,kBAAkB,OAAO,cAA+C,EAAE;AAC3F,SAAO;AAAA,IACL,aAAa,kBAAkB,KAAqC,SAAiD,QAAQ;AAAA,IAC7H,QAAQ;AAAA,EACV;AACF;AAGO,IAAM,eAAsB,OAAO,MAAM,QAAS,IAAI,aAAa,gBAAgB,KAAK,EAAE,IAAI,KAAK,CAAC,IAAI;AAGxG,IAAM,eAAsB,OAAO,MAAM,KAAK,KAAK,QAAQ;AAChE,MAAI,IAAI,aAAa,cAAe,QAAO;AAC3C,MAAI;AACF,UAAM,EAAE,oBAAoB,IAAI,MAAM,IAAI,gBAAgB,GAAG;AAC7D,WAAO,KAAK,EAAE,qBAAqB,uBAAuB,MAAM,KAAK,IAAI,SAAS,CAAC;AAAA,EACrF,QAAQ;AACN,WAAO,KAAK,EAAE,qBAAqB,MAAM,KAAK,IAAI,SAAS,CAAC;AAAA,EAC9D;AACF;AAKO,IAAM,WAAkB,OAAO,KAAK,KAAK,KAAK,QAAQ;AAC3D,MAAI,IAAI,aAAa,UAAW,QAAO;AACvC,QAAM,IAAI,MAAM,IAAI,WAAW,KAAK,GAAG;AACvC,MAAI,CAAC,EAAG,QAAO,KAAK,EAAE,YAAY,MAAM,GAAG,GAAG;AAC9C,QAAM,KAAK,IAAI,OAAO,GAAG;AACzB,QAAM,OAAO,MAAM,IAAI,QAAQ,IAAI,CAAC;AACpC,QAAM,aAAa,MAAM,IAAI,kBAAkB,IAAI,EAAE,KAAK;AAC1D,QAAM,OAAO,EAAE,YAAY,YAAY,MAAM,IAAI,IAAI,GAAG,MAAM,YAAY,OAAO,EAAE,SAAS,KAAK;AACjG,MAAI,IAAI,QAAQ,SAAS,aAAa,CAAC,EAAE,MAAO,QAAO,KAAK,IAAI;AAChE,QAAM,SAAS,MAAM,yBAAyB,IAA4B,IAAI,QAAQ,IAAI,EAAE,KAAK;AACjG,MAAI,wBAAwB;AAC5B,MACE,UACA,IAAI,QAAQ,YAAY,UACxB,OAAO,OAAO,OAAO,iCAAiC,UACtD;AAKA,4BAAwB,MAAM;AAAA,MAC5B;AAAA,MACA,IAAI;AAAA,MACJ,OAAO,OAAO,OAAO,EAAE;AAAA,MACvB,OAAO;AAAA,MACP,EAAE;AAAA,IACJ;AAAA,EACF;AACA,MAAI,UAAU,CAAC,yBAAyB,OAAO,OAAO,gBAAgB,EAAE,QAAQ;AAK9E,UAAO,GAA4B,SAAS,CAAC;AAAA,MAC3C,GAAG;AAAA,MACH,IAAI;AAAA,MACJ,IAAI,OAAO,OAAO,OAAO,EAAE;AAAA,MAC3B,OAAO,EAAE,aAAa,EAAE,OAAO;AAAA,IACjC,CAAC,CAAC,EAAE,MAAM,MAAM,MAAS;AAAA,EAC3B;AACA,SAAO,KAAK,EAAE,GAAG,MAAM,aAAa,QAAQ,eAAe,KAAK,CAAC;AACnE;AAGO,IAAM,YAAmB,OAAO,KAAK,KAAK,KAAK,QAAQ;AAC5D,QAAM,UAAU,IAAI;AACpB,MAAI,IAAI,aAAa,WAAW,CAAC,IAAI,SAAS,WAAW,UAAU,GAAG,EAAG,QAAO;AAChF,QAAM,KAAK,IAAI,OAAO,GAAG;AACzB,QAAM,SAAS,gBAAgB;AAAA,IAC7B,KAAK,IAAI,QAAQ;AAAA,IACjB;AAAA,IACA,WAAW,OAAO,MAAe;AAC/B,YAAM,IAAI,MAAM,IAAI,WAAW,GAAG,GAAG;AACrC,UAAI,CAAC,KAAK,CAAE,MAAM,IAAI,QAAQ,IAAI,CAAC,EAAI,QAAO;AAC9C,aAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,OAAO,EAAE,MAAM,IAAI,EAAE,QAAQ,EAAE,OAAO;AAAA,IAC7E;AAAA,IACA,+BAA+B,CAAC,MAC9B,gCAAgC,GAAG,GAAG;AAAA,IACxC,QAAQ,IAAI,UAAU,GAAG;AAAA,IACzB,MAAM,IAAI;AAAA,IACV,SAAS,IAAI;AAAA,IACb,SAAS,IAAI;AAAA,IACb,UAAU;AAAA,EACZ,CAAC;AACD,QAAM,MAAM,MAAM,OAAO,GAAG;AAC5B,MAAI,IAAK,QAAO;AAChB,SAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AACzC;AAIO,IAAM,eAAsB,OAAO,KAAK,KAAK,KAAK,QAAQ;AAC/D,QAAM,UAAU,IAAI;AACpB,MAAI,QAAQ,SAAS,UAAW,QAAO;AAGvC,MAAI,IAAI,WAAW,SAAS,IAAI,aAAa,oBAAoB;AAC/D,UAAM,KAAK,IAAI,OAAO,GAAG;AACzB,UAAM,UAAU,IAAI,aAAa,IAAI,OAAO,KAAK,QAAQ;AACzD,UAAM,EAAE,OAAO,IAAI,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,QAAQ,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC;AACzF,UAAM,QAAQ,MAAM,QAAQ,MAAM,IAAI,OAAO,CAAC,IAAI;AAClD,QAAI,CAAC,MAAO,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AACnD,UAAM,YAAY,MAAM,eAAe,IAA4B,mBAAmB;AACtF,UAAM,gBAAgB,QAAQ,MAAM,wBAAwB,MAAM,iBAAiB,SAAS;AAC5F,UAAM,UAAU,MAAM;AAAA,MACpB;AAAA,MAA4B;AAAA,MAAgB,QAAQ,SAAS;AAAA,IAC/D;AACA,UAAM,gBAAgB,QAAQ,gBAC1B,MAAM,wBAAwB,IAA4B,QAAQ,IAAI,IAAI,QAAQ,IAClF;AACJ,UAAM,cAAc,sBAAsB,QAAQ,aAAa,eAAe,QAAQ;AACtF,WAAO,KAAK;AAAA,MACV,GAAG,WAAW,OAAgB,eAAe,gBAAgB,OAAO,GAAG,YAAY,UAAU;AAAA,MAC7F,eAAe,yBAAyB,SAAS,QAAQ,WAAW;AAAA,MACpE,MAAM,EAAE,GAAG,QAAQ,KAAK,MAAM,GAAI,eAAe,SAAS,aAAa,QAAQ,CAAC,EAAG;AAAA,MACnF,GAAI,gBAAgB,EAAE,eAAe;AAAA,QACnC,UAAU,cAAc;AAAA,QACxB,QAAQ,cAAc;AAAA,QACtB,gBAAgB,cAAc,SAAS;AAAA,QACvC,aAAa,cAAc,SAAS;AAAA,QACpC,OAAO,cAAc,SAAS;AAAA,MAChC,EAAE,IAAI,CAAC;AAAA,MACP,YAAY,iBAAiB,eAAe,SAAS,YAAY,KAAK,IAAI,CAAC;AAAA,IAC7E,CAAC;AAAA,EACH;AAKA,MAAI,IAAI,WAAW,SAAS,IAAI,aAAa,oBAAoB;AAC/D,UAAM,gBAAgB,IAAI,aAAa,IAAI,aAAa,KAAK;AAC7D,QAAI,CAAC,cAAe,QAAO,KAAK,EAAE,OAAO,0BAA0B,GAAG,GAAG;AACzE,UAAM,KAAK,IAAI,OAAO,GAAG;AACzB,UAAM,QAAQ,MAAM,GAAG,MAAM;AAAA,MAC3B,cAAc,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,cAAc,GAAG,OAAO,EAAE,EAAE;AAAA,IAChE,CAAC,GAAG;AACJ,UAAM,MAAM,MAAM,QAAQ,IAAI,IAAI,KAAK,CAAC,IAAI;AAC5C,QAAI,CAAC,OAAO,OAAO,IAAI,WAAW,EAAE,MAAM,QAAQ,GAAI,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AAE7F,UAAM,YAAY,MAAM,GAAG,MAAM;AAAA,MAC/B,UAAU;AAAA,QACR,GAAG;AAAA,UACD,OAAO,EAAE,eAAe,QAAQ,YAAY;AAAA,UAC5C,OAAO,EAAE,WAAW,OAAO;AAAA,UAC3B,OAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF,CAAC,GAAG;AACJ,UAAM,UAAU,MAAM,QAAQ,QAAQ,IAAI,SAAS,CAAC,IAAI;AACxD,QAAI,WAAW,OAAO,QAAQ,YAAY,UAAU;AAClD,YAAMC,WAAU,MAAM,GAAG,MAAM;AAAA,QAC7B,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,QAAQ,GAAG,GAAG,OAAO,EAAE,EAAE;AAAA,MACvD,CAAC,GAAG;AACJ,YAAMC,SAAQ,MAAM,QAAQD,OAAM,IAAIA,QAAO,CAAC,IAAI;AAClD,YAAM,WAAW,kBAAkBC,QAAO,cAA+C,EAAE;AAC3F,aAAO,KAAK;AAAA,QACV,OAAO;AAAA,QACP;AAAA,QACA,QAAQ,EAAE,SAAS,QAAQ,SAAS,SAAS;AAAA,MAC/C,CAAC;AAAA,IACH;AAEA,UAAM,UAAU,MAAM,GAAG,MAAM;AAAA,MAC7B,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,QAAQ,GAAG,GAAG,OAAO,EAAE,EAAE;AAAA,IACvD,CAAC,GAAG;AACJ,UAAM,QAAQ,MAAM,QAAQ,MAAM,IAAI,OAAO,CAAC,IAAI;AAClD,QAAI,CAAC,MAAO,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AACnD,UAAM,QAAQ,MAAM,aAAa,IAAI,KAAK,KAAK,IAAI,QAAQ,KAAK,KAAK;AACrE,QAAI,MAAO,QAAO,KAAK,EAAE,OAAO,eAAe,GAAI,UAAU,SAAS,EAAE,SAAS,IAAI,YAAY,IAAI,CAAC,EAAG,CAAC;AAC1G,WAAO,KAAK,EAAE,OAAO,0CAA0C,OAAO,IAAI,UAAU,EAAE,CAAC,IAAI,GAAG,GAAG;AAAA,EACnG;AAGA,MAAI,IAAI,WAAW,UAAU,IAAI,aAAa,qBAAqB;AACjE,UAAM,MAAM,MAAM,IAAI,KAAK;AAC3B,QAAI,IAAI,SAAS,QAAQ,YAAY,QAAS,QAAO,KAAK,EAAE,OAAO,yBAAyB,GAAG,GAAG;AAClG,QAAI;AACJ,QAAI;AACF,eAAS,KAAK,MAAM,GAAG;AAAA,IACzB,QAAQ;AACN,aAAO,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;AAAA,IACjD;AACA,UAAM,eAAe,OAAO,OAAO,iBAAiB,WAAW,OAAO,eAAe;AACrF,UAAM,KAAK,IAAI,OAAO,GAAG;AACzB,UAAM,gBAAgB,QAAQ,gBAC1B,MAAM,wBAAwB,IAAI,QAAQ,IAAI,IAAI,QAAQ,IAC1D;AACJ,UAAM,mBAAmB,gBACrB,EAAE,GAAG,SAAS,aAAa,sBAAsB,QAAQ,aAAa,cAAc,QAAQ,EAAE,IAC9F;AAGJ,UAAM,iBAAiB,OAAO,OAAO,WAAW,YAAY,OAAO,UAC9D,MAAM,UAAU,IAAI,EAAE,IAAI,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,KAAK,EAAE,IAC/D;AACJ,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,kBAAkB,OAAO,OAAO,gBAAgB,WAAW,OAAO,cAAc;AACtF,UAAM,YAAY,kBAAkB,cAAc,eAAe,SAAS,YAAY,iBAAiB,GAAG,IAAI;AAC9G,QAAI,mBAAmB,CAAC,UAAW,QAAO,KAAK,EAAE,OAAO,4BAA4B,GAAG,GAAG;AAC1F,UAAM,iBAAiB,CAAC,aAAa,OAAO,OAAO,UAAU,WACzD,MAAM,mBAAmB,IAAI,QAAQ,IAAI,OAAO,OAAO,GAAG,IAC1D;AACJ,UAAM,SAAS,MAAM,kBAAkB,IAAI,kBAAkB,QAAQ;AAAA,MACnE;AAAA,MACA,SAAS,QAAQ;AAAA,MACjB;AAAA,MACA,OAAO,MAAM,OAAO,WAAW;AAAA,MAC/B,GAAI,iBAAiB,EAAE,SAAS,eAAe,IAAI,CAAC;AAAA,MACpD,GAAI,gBAAgB,aAAa,oBAAoB,EAAE,gBAAgB,eAAe,IAAI,CAAC;AAAA,MAC3F,GAAI,YAAY,EAAE,aAAa,UAAU,GAAG,IAAI,CAAC;AAAA,IACnD,CAAC;AACD,QAAI,CAAC,OAAO,GAAI,QAAO,KAAK,EAAE,OAAO,OAAO,MAAM,GAAG,GAAG;AACxD,QAAI,CAAC,OAAO,WAAW;AAGrB,UAAI,iBAAiB,MAAM,sBAAsB,UAAU;AACzD,cAAM,yBAAyB,IAAI,KAAK,QAAQ,IAAI,OAAO,IAAI,MAAM;AAAA,MACvE;AACA,YAAM,mBAAmB,IAAI,kBAAkB,OAAO,IAAI,MAAM;AAAA,IAClE;AACA,UAAM,QAAQ,MAAM,GAAG,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,OAAO,GAAG,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG;AAC/F,UAAMC,aAAY,MAAM,QAAQ,IAAI,IAAI,KAAK,CAAC,IAAI;AAClD,UAAM,UAAU,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,QAAQ,GAAG,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG;AAC5F,UAAM,QAAQ,MAAM,QAAQ,MAAM,IAAI,OAAO,CAAC,IAAI;AAClD,UAAM,QAAQA,cAAa,QACvB,MAAM,aAAa,IAAI,KAAK,KAAK,IAAI,QAAQA,YAAW,KAAK,IAC7D;AACJ,WAAO,KAAK;AAAA,MACV,IAAI,OAAO;AAAA,MACX,WAAW,OAAO;AAAA,MAClB,QAAQ,OAAO;AAAA,MACf,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA;AAAA;AAAA,MAGzB,iBAAiB,OAAO;AAAA,IAC1B,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;A2BnSA,SAAS,oBAAoB,8BAA8B;AAQpD,IAAM,sBAA6B,OAAO,KAAK,KAAK,KAAK,QAAQ;AACtE,MAAI,IAAI,WAAW,UAAU,IAAI,aAAa,sBAAuB,QAAO;AAC5E,QAAM,KAAK,IAAI,OAAO,GAAG;AACzB,QAAM,SAAS,MAAM,eAAe,IAA4B,sBAAsB;AACtF,MAAI,CAAC,OAAQ,QAAO,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG;AAEvD,MAAI;AACJ,MAAI;AACJ,MAAI,IAAI,QAAQ,IAAI,mBAAmB,OAAO,GAAG;AAC/C,UAAM,WAAW,MAAM,uBAAuB,KAAK,EAAE,OAAO,CAAC;AAC7D,QAAI,CAAC,SAAS,GAAI,QAAO,KAAK,EAAE,OAAO,gBAAgB,QAAQ,SAAS,OAAO,GAAG,GAAG;AACrF,UAAM,SAAS;AACf,eAAW,SAAS;AAAA,EACtB,OAAO;AAGL,UAAM,YAAY,IAAI,QAAQ,IAAI,eAAe,KAAK,IAAI,QAAQ,YAAY,EAAE;AAChF,QAAI,SAAS,WAAW,OAAO,UAAU,aAAa,QAAQ;AAC5D,aAAO,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG;AAAA,IAC5C;AACA,UAAM,MAAM,IAAI,KAAK;AAAA,EACvB;AACA,MAAI;AACJ,MAAI;AACF,cAAU,KAAK,MAAM,GAAG;AAAA,EAC1B,QAAQ;AACN,WAAO,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;AAAA,EACjD;AACA,MAAI,WAAW,SAAS;AACtB,UAAM,KAAK,QAAQ,YAAY,KAAK,OAAO,QAAQ,gBAAgB,YAAY,QAAQ,YAAY,KAAK;AACxG,UAAM,SAAS,QAAQ;AACvB,UAAM,KAAK,QAAQ,YAAY,KAC7B,UACA,OAAO,OAAO,WAAW,YACzB,OAAO,OAAO,KAAK,KACnB,OAAO,OAAO,aAAa,YAC3B,OAAO,SAAS,KAAK;AACvB,QAAK,CAAC,MAAM,CAAC,MACX,OAAO,QAAQ,SAAS,YACxB,CAAC,QAAQ,KAAK,KAAK,KACnB,CAAC,QAAQ,SACT,OAAO,QAAQ,UAAU,YACzB,MAAM,QAAQ,QAAQ,KAAK,GAC3B;AACA,aAAO,KAAK,EAAE,OAAO,mEAAmE,GAAG,GAAG;AAAA,IAChG;AAAA,EACF,WAAW,OAAO,QAAQ,gBAAgB,YAAY,CAAC,QAAQ,YAAY,KAAK,GAAG;AACjF,WAAO,KAAK,EAAE,OAAO,0BAA0B,GAAG,GAAG;AAAA,EACvD,WAAW,QAAQ,SAAS,aAAa,OAAO,QAAQ,UAAU,UAAU;AAC1E,WAAO,KAAK,EAAE,OAAO,qCAAqC,GAAG,GAAG;AAAA,EAClE,WAAW,QAAQ,SAAS,aAAa,OAAO,QAAQ,SAAS,UAAU;AACzE,WAAO,KAAK,EAAE,OAAO,+BAA+B,GAAG,GAAG;AAAA,EAC5D;AACA,MAAI;AACF,UAAM,EAAE,SAAS,IAAI,MAAM;AAAA,MACzB,EAAE,KAAK,IAAI,QAAQ,KAAK,IAAgC,KAAK,MAAM,KAAK,IAAI,GAAG,OAAO,MAAM,OAAO,WAAW,EAAE;AAAA,MAChH;AAAA,MACA,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,IAC7B;AACA,UAAMC,UAAS,sBAAsB,SAAkB,QAAQ;AAC/D,WAAO,KAAK,EAAE,UAAU,MAAMA,QAAO,KAAK,CAAC;AAAA,EAC7C,SAAS,OAAO;AACd,WAAO,KAAK;AAAA,MACV,OAAO,iBAAiB,QAAQ,MAAM,UAAU;AAAA,IAClD,GAAG,GAAG;AAAA,EACR;AACF;;;AC5EA,SAAS,0BAAAC,+BAA8B;;;ACQhC,IAAM,sBAAsB;;;ACP5B,IAAM,2BAA2B;AAgExC,IAAM,UAAU;AAChB,IAAM,WAAW,oBAAI,IAA2B,CAAC,YAAY,YAAY,YAAY,CAAC;AACtF,IAAM,YAAY,oBAAI,IAAI,CAAC,iBAAiB,YAAY,SAAS,kBAAkB,CAAC;AACpF,IAAM,YAAY,oBAAI,IAAI;AAAA,EACxB;AAAA,EAAU;AAAA,EAAW;AAAA,EAAS;AAAA,EAAmB;AAAA,EACjD;AAAA,EAAuB;AAAA,EAAgB;AAAA,EAAqB;AAAA,EAC5D;AAAA,EAAY;AAAA,EAAW;AACzB,CAAC;AACD,IAAM,eAAe,oBAAI,IAAI,CAAC,SAAS,cAAc,CAAC;AACtD,IAAM,gBAAgB,oBAAI,IAAI,CAAC,SAAS,OAAO,CAAC;AAChD,IAAM,YAAY;AAClB,IAAM,eAAe;AACrB,IAAM,eAAe;AACrB,IAAM,YAAY;AAElB,IAAM,eAAe,CAAC,UACpB,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IAC/D,QACA;AAEN,SAAS,kBACP,OACAC,UACA,MACA,QACM;AACN,aAAW,OAAO,OAAO,KAAK,KAAK,GAAG;AACpC,QAAI,CAACA,SAAQ,IAAI,GAAG,EAAG,QAAO,KAAK,GAAG,IAAI,IAAI,GAAG,mBAAmB;AAAA,EACtE;AACF;AAEA,SAAS,cACP,OACA,MACA,QACA,KACA,WAAW,OACS;AACpB,MAAI,UAAU,QAAW;AACvB,QAAI,SAAU,QAAO,KAAK,GAAG,IAAI,cAAc;AAC/C,WAAO;AAAA,EACT;AACA,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,KAAK,GAAG,IAAI,mBAAmB;AACtC,WAAO;AAAA,EACT;AACA,QAAMC,QAAO,MAAM,KAAK;AACxB,MAAI,YAAY,CAACA,MAAM,QAAO,KAAK,GAAG,IAAI,cAAc;AACxD,MAAIA,MAAK,SAAS,IAAK,QAAO,KAAK,GAAG,IAAI,oBAAoB,IAAI,eAAe,OAAO,CAAC,aAAa;AACtG,SAAOA;AACT;AAOO,SAAS,+BACd,OACA,UAA2C,CAAC,GACZ;AAChC,QAAM,SAAmB,CAAC;AAC1B,QAAM,OAAO,aAAa,KAAK;AAC/B,MAAI,CAAC,KAAM,QAAO,EAAE,IAAI,OAAO,QAAQ,CAAC,4BAA4B,EAAE;AACtE,oBAAkB,MAAM,WAAW,YAAY,MAAM;AACrD,MAAI,KAAK,kBAAkB,EAAG,QAAO,KAAK,kCAAkC;AAC5E,MAAI,KAAK,aAAa,0BAA0B;AAC9C,WAAO,KAAK,8BAA+B,wBAAwB,GAAI;AAAA,EACzE;AACA,MAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,EAAG,QAAO,KAAK,iCAAiC;AAC7E,QAAM,WAAW,MAAM,QAAQ,KAAK,KAAK,IAAI,KAAK,QAAQ,CAAC;AAC3D,MAAI,MAAM,QAAQ,KAAK,KAAK,KAAK,SAAS,WAAW,EAAG,QAAO,KAAK,+CAA+C;AACnH,MAAI,SAAS,SAAS,UAAW,QAAO,KAAK,mCAAmC,SAAS,UAAU;AAEnG,QAAM,YAAY,IAAI,KAAK,QAAQ,SAAS,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC;AAC9E,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,QAAsC,CAAC;AAC7C,aAAW,CAAC,OAAO,GAAG,KAAK,SAAS,MAAM,GAAG,SAAS,EAAE,QAAQ,GAAG;AACjE,UAAM,OAAO,kBAAkB,KAAK;AACpC,UAAM,OAAO,aAAa,GAAG;AAC7B,QAAI,CAAC,MAAM;AACT,aAAO,KAAK,GAAG,IAAI,oBAAoB;AACvC;AAAA,IACF;AACA,sBAAkB,MAAM,WAAW,MAAM,MAAM;AAC/C,UAAM,SAAS,cAAc,KAAK,QAAQ,GAAG,IAAI,WAAW,QAAQ,IAAI,IAAI,KAAK;AACjF,QAAI,UAAU,CAAC,QAAQ,KAAK,MAAM,EAAG,QAAO,KAAK,GAAG,IAAI,2CAA2C;AACnG,QAAI,KAAK,IAAI,MAAM,EAAG,QAAO,KAAK,GAAG,IAAI,uBAAwB,MAAM,GAAI;AAC3E,SAAK,IAAI,MAAM;AACf,QAAI,UAAU,QAAQ,CAAC,UAAU,IAAI,MAAM,EAAG,QAAO,KAAK,GAAG,IAAI,YAAa,MAAM,0BAA2B;AAE/G,UAAM,UAAU,KAAK;AACrB,QAAI,YAAY,WAAc,OAAO,YAAY,YAAY,CAAC,SAAS,IAAI,OAAgC,IAAI;AAC7G,aAAO,KAAK,GAAG,IAAI,oDAAoD;AAAA,IACzE;AACA,UAAM,YAAY,KAAK;AACvB,QAAI,cAAc,WAAc,CAAC,OAAO,UAAU,SAAS,KAAK,OAAO,SAAS,IAAI,KAAK,OAAO,SAAS,IAAI,MAAc;AACzH,aAAO,KAAK,GAAG,IAAI,+DAA+D;AAAA,IACpF;AACA,UAAM,SAAS,UAAU,IAAI,MAAM,GAAG;AACtC,QAAI,OAAO,UAAU,SAAS,KAAK,WAAW,UAAa,OAAO,SAAS,KAAK,QAAQ;AACtF,aAAO,KAAK,GAAG,IAAI,wEAAwE;AAAA,IAC7F;AAEA,QAAI;AACJ,QAAI,KAAK,aAAa,QAAW;AAC/B,UAAI,CAAC,MAAM,QAAQ,KAAK,QAAQ,EAAG,QAAO,KAAK,GAAG,IAAI,4BAA4B;AAAA,WAC7E;AACH,YAAI,KAAK,SAAS,SAAS,aAAc,QAAO,KAAK,GAAG,IAAI,8BAA8B,YAAY,UAAU;AAChH,mBAAW,KAAK,SAAS,MAAM,GAAG,YAAY,EAAE,QAAQ,CAAC,SAAS,iBAAiB;AACjF,gBAAMA,QAAO,cAAc,SAAS,GAAG,IAAI,aAAa,YAAY,KAAK,QAAQ,KAAO,IAAI;AAC5F,iBAAOA,QAAO,CAACA,KAAI,IAAI,CAAC;AAAA,QAC1B,CAAC;AAAA,MACH;AAAA,IACF;AAEA,QAAI;AACJ,QAAI,KAAK,YAAY,QAAW;AAC9B,YAAM,aAAa,aAAa,KAAK,OAAO;AAC5C,UAAI,CAAC,WAAY,QAAO,KAAK,GAAG,IAAI,4BAA4B;AAAA,WAC3D;AACH,0BAAkB,YAAY,cAAc,GAAG,IAAI,YAAY,MAAM;AACrE,cAAM,eAAe,cAAc,WAAW,cAAc,GAAG,IAAI,yBAAyB,QAAQ,cAAc,IAAI;AACtH,cAAM,QAAQ,cAAc,WAAW,OAAO,GAAG,IAAI,kBAAkB,QAAQ,SAAS;AACxF,YAAI,aAAc,WAAU,EAAE,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC,GAAI,aAAa;AAAA,MAC1E;AAAA,IACF;AAEA,QAAI;AACJ,QAAI,KAAK,aAAa,QAAW;AAC/B,YAAM,cAAc,aAAa,KAAK,QAAQ;AAC9C,UAAI,CAAC,YAAa,QAAO,KAAK,GAAG,IAAI,6BAA6B;AAAA,WAC7D;AACH,0BAAkB,aAAa,eAAe,GAAG,IAAI,aAAa,MAAM;AACxE,cAAM,QAAQ,YAAY;AAC1B,YAAI,CAAC,OAAO,UAAU,KAAK,KAAK,OAAO,KAAK,IAAI,KAAK,OAAO,KAAK,IAAI,KAAW;AAC9E,iBAAO,KAAK,GAAG,IAAI,wDAAwD;AAAA,QAC7E;AACA,cAAM,QAAQ,cAAc,YAAY,OAAO,GAAG,IAAI,mBAAmB,QAAQ,SAAS;AAC1F,YAAI,OAAO,UAAU,KAAK,KAAK,OAAO,KAAK,KAAK,KAAK,OAAO,KAAK,KAAK,KAAW;AAC/E,qBAAW,EAAE,OAAO,OAAO,KAAK,GAAG,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC,EAAG;AAAA,QACjE;AAAA,MACF;AAAA,IACF;AAEA,UAAM,QAAQ,cAAc,KAAK,OAAO,GAAG,IAAI,UAAU,QAAQ,SAAS;AAC1E,UAAM,kBAAkB,cAAc,KAAK,iBAAiB,GAAG,IAAI,oBAAoB,QAAQ,YAAY;AAC3G,UAAM,eAAe,cAAc,KAAK,cAAc,GAAG,IAAI,iBAAiB,QAAQ,SAAS;AAC/F,UAAM,eAAe,cAAc,KAAK,cAAc,GAAG,IAAI,iBAAiB,QAAQ,SAAS;AAC/F,UAAM,oBAAoB,cAAc,KAAK,mBAAmB,GAAG,IAAI,sBAAsB,QAAQ,YAAY;AACjH,UAAM,WAAW,cAAc,KAAK,UAAU,GAAG,IAAI,aAAa,QAAQ,SAAS;AACnF,UAAM,KAAK;AAAA,MACT;AAAA,MACA,GAAI,OAAO,YAAY,YAAY,SAAS,IAAI,OAAgC,IAAI,EAAE,QAA0C,IAAI,CAAC;AAAA,MACrI,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,MACzB,GAAI,kBAAkB,EAAE,gBAAgB,IAAI,CAAC;AAAA,MAC7C,GAAI,eAAe,EAAE,aAAa,IAAI,CAAC;AAAA,MACvC,GAAI,OAAO,UAAU,SAAS,IAAI,EAAE,qBAAqB,OAAO,SAAS,EAAE,IAAI,CAAC;AAAA,MAChF,GAAI,eAAe,EAAE,aAAa,IAAI,CAAC;AAAA,MACvC,GAAI,oBAAoB,EAAE,kBAAkB,IAAI,CAAC;AAAA,MACjD,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,MAC/B,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,MAC/B,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,MAC7B,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,IACjC,CAAC;AAAA,EACH;AACA,MAAI,UAAU,MAAM;AAClB,eAAW,UAAU,UAAU,KAAK,GAAG;AACrC,UAAI,CAAC,KAAK,IAAI,MAAM,EAAG,QAAO,KAAK,2CAA4C,MAAM,GAAI;AAAA,IAC3F;AAAA,EACF;AACA,QAAM,mBAAmB,cAAc,KAAK,kBAAkB,6BAA6B,QAAQ,YAAY;AAC/G,MAAI,OAAO,OAAQ,QAAO,EAAE,IAAI,OAAO,OAAO;AAC9C,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,OAAO;AAAA,MACL,eAAe;AAAA,MACf,UAAU;AAAA,MACV;AAAA,MACA,GAAI,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;AAAA,IACjD;AAAA,EACF;AACF;;;AC1OA,IAAM,OAAO;AACb,IAAM,cAAc;AACpB,IAAM,OAAO;AACb,IAAMC,SAAQ;AACd,IAAMC,aAAY,oBAAI,IAAI;AAAA,EACxB;AAAA,EAAiB;AAAA,EAAY;AAAA,EAAe;AAAA,EAAU;AAAA,EAAU;AAAA,EAChE;AAAA,EAAkB;AAAA,EAAe;AAAA,EAAU;AAAA,EAAc;AAAA,EAAS;AACpE,CAAC;AACD,IAAMC,aAAY,oBAAI,IAAI,CAAC,MAAM,QAAQ,aAAa,aAAa,cAAc,iBAAiB,OAAO,CAAC;AAE1G,IAAM,WAAW,CAAC,UAChB,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IAC/D,QACA;AAEN,SAAS,YAAY,OAAgCC,UAA8B,MAAc,QAAwB;AACvH,aAAW,OAAO,OAAO,KAAK,KAAK,EAAG,KAAI,CAACA,SAAQ,IAAI,GAAG,EAAG,QAAO,KAAK,GAAG,IAAI,IAAI,GAAG,mBAAmB;AAC5G;AAEA,SAASC,MAAK,OAAgB,MAAc,QAAkB,MAAM,OAAgB;AAClF,MAAI,OAAO,UAAU,YAAY,CAAC,MAAM,KAAK,GAAG;AAC9C,WAAO,KAAK,GAAG,IAAI,cAAc;AACjC,WAAO;AAAA,EACT;AACA,MAAI,MAAM,SAAS,IAAK,QAAO,KAAK,GAAG,IAAI,oBAAoB,GAAG,aAAa;AAC/E,SAAO,MAAM,KAAK;AACpB;AAEA,SAAS,QAAQ,OAAgB,QAAuC;AACtE,MAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,CAAC,MAAM,QAAQ;AAC1C,WAAO,KAAK,0CAA0C;AACtD,WAAO,CAAC;AAAA,EACV;AACA,MAAI,MAAM,SAAS,GAAI,QAAO,KAAK,4CAA4C;AAC/E,QAAM,OAAO,oBAAI,IAAY;AAC7B,SAAO,MAAM,MAAM,GAAG,EAAE,EAAE,QAAQ,CAAC,KAAK,UAAU;AAChD,UAAM,OAAO,kBAAkB,KAAK;AACpC,UAAM,OAAO,SAAS,GAAG;AACzB,QAAI,CAAC,MAAM;AACT,aAAO,KAAK,GAAG,IAAI,oBAAoB;AACvC,aAAO,CAAC;AAAA,IACV;AACA,gBAAY,MAAMF,YAAW,MAAM,MAAM;AACzC,UAAM,KAAKE,MAAK,KAAK,IAAI,GAAG,IAAI,OAAO,QAAQ,EAAE;AACjD,QAAI,MAAM,CAAC,KAAK,KAAK,EAAE,EAAG,QAAO,KAAK,GAAG,IAAI,uCAAuC;AACpF,QAAI,KAAK,IAAI,EAAE,EAAG,QAAO,KAAK,GAAG,IAAI,mBAAmB,EAAE,GAAG;AAC7D,SAAK,IAAI,EAAE;AACX,UAAM,OAAOA,MAAK,KAAK,MAAM,GAAG,IAAI,SAAS,QAAQ,GAAG;AACxD,QAAI,OAAO,KAAK,cAAc,UAAW,QAAO,KAAK,GAAG,IAAI,4BAA4B;AACxF,QAAI,CAAC,OAAO,UAAU,KAAK,SAAS,KAAK,OAAO,KAAK,SAAS,IAAI,EAAG,QAAO,KAAK,GAAG,IAAI,2CAA2C;AACnI,QAAI,CAAC,OAAO,UAAU,KAAK,UAAU,KAAK,OAAO,KAAK,UAAU,IAAI,KAAK,OAAO,KAAK,UAAU,IAAI,KAAa;AAC9G,aAAO,KAAK,GAAG,IAAI,sDAAsD;AAAA,IAC3E;AACA,QAAI,KAAK,kBAAkB,WAAc,OAAO,KAAK,kBAAkB,YAAY,CAACJ,OAAM,KAAK,KAAK,aAAa,IAAI;AACnH,aAAO,KAAK,GAAG,IAAI,+CAA+C;AAAA,IACpE;AACA,QAAI,KAAK,cAAc,QAAQ,OAAO,KAAK,UAAU,IAAI,KAAK,CAAC,KAAK,eAAe;AACjF,aAAO,KAAK,GAAG,IAAI,uDAAuD;AAAA,IAC5E;AACA,UAAM,QAAQ,KAAK,UAAU,SAAY,SAAYI,MAAK,KAAK,OAAO,GAAG,IAAI,UAAU,QAAQ,GAAK;AACpG,WAAO,CAAC;AAAA,MACN;AAAA,MAAI;AAAA,MAAM,WAAW,KAAK,cAAc;AAAA,MACxC,WAAW,OAAO,KAAK,SAAS,KAAK;AAAA,MACrC,YAAY,OAAO,KAAK,UAAU,KAAK;AAAA,MACvC,GAAI,OAAO,KAAK,kBAAkB,WAAW,EAAE,eAAe,KAAK,cAAc,IAAI,CAAC;AAAA,MACtF,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,IAC3B,CAAC;AAAA,EACH,CAAC;AACH;AAEA,SAAS,cAAc,OAAgB,QAAwD;AAC7F,MAAI,UAAU,OAAW,QAAO;AAChC,QAAM,QAAQ,SAAS,KAAK;AAC5B,MAAI,CAAC,OAAO;AACV,WAAO,KAAK,wCAAwC;AACpD,WAAO;AAAA,EACT;AACA,cAAY,OAAO,oBAAI,IAAI,CAAC,YAAY,YAAY,cAAc,MAAM,CAAC,GAAG,wBAAwB,MAAM;AAC1G,MAAI;AACF,UAAM,WAAW,mBAAmB,KAAK;AACzC,UAAM,OAAO,SAAS,MAAM,IAAI;AAChC,QAAI,MAAM,SAAS,WAAc,CAAC,QAAQ,OAAO,OAAO,IAAI,EAAE,KAAK,CAAC,SAAS,OAAO,SAAS,QAAQ,IAAI;AACvG,aAAO,KAAK,2DAA2D;AAAA,IACzE;AACA,WAAO;AAAA,MACL,UAAU,SAAS;AAAA,MACnB,UAAU,SAAS;AAAA,MACnB,GAAI,OAAO,KAAK,SAAS,UAAU,EAAE,SAAS,EAAE,YAAY,SAAS,WAAW,IAAI,CAAC;AAAA,MACrF,GAAI,OAAO,EAAE,KAAqC,IAAI,CAAC;AAAA,IACzD;AAAA,EACF,SAAS,OAAO;AACd,WAAO,KAAK,iBAAiB,QAAQ,MAAM,UAAU,iCAAiC;AACtF,WAAO;AAAA,EACT;AACF;AAEA,SAAS,SAAS,OAAgB,QAAmD;AACnF,MAAI,UAAU,OAAW,QAAO;AAChC,QAAM,QAAQ,SAAS,KAAK;AAC5B,MAAI,CAAC,OAAO;AACV,WAAO,KAAK,mCAAmC;AAC/C,WAAO;AAAA,EACT;AACA,QAAMD,WAAU,oBAAI,IAAI,CAAC,kBAAkB,oBAAoB,aAAa,kBAAkB,WAAW,CAAC;AAC1G,cAAY,OAAOA,UAAS,mBAAmB,MAAM;AACrD,QAAM,SAAS,CAAC;AAChB,aAAW,OAAOA,UAAS;AACzB,QAAI,MAAM,GAAG,MAAM,UAAa,QAAQ,oBAAoB,QAAQ,mBAAoB;AACxF,WAAO,GAAG,IAAIC,MAAK,MAAM,GAAG,GAAG,mBAAmB,GAAG,IAAI,MAAM;AAAA,EACjE;AACA,SAAO;AACT;AAEA,SAAS,QAAQ,OAAgB,QAAkD;AACjF,MAAI,UAAU,OAAW,QAAO;AAChC,QAAM,QAAQ,SAAS,KAAK;AAC5B,QAAM,SAAS,SAAS,OAAO,MAAM;AACrC,MAAI,CAAC,SAAS,CAAC,QAAQ;AACrB,WAAO,KAAK,yCAAyC;AACrD,WAAO;AAAA,EACT;AACA,cAAY,OAAO,oBAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,kBAAkB,MAAM;AAChE,MAAI,OAAO,KAAK,MAAM,EAAE,SAAS,IAAK,QAAO,KAAK,oDAAoD;AACtG,MAAI,mBAAmB;AACvB,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,QAAI,CAAC,iCAAiC,KAAK,GAAG,GAAG;AAC/C,aAAO,KAAK,yBAAyB,GAAG,gDAAgD;AAAA,IAC1F;AACA,UAAM,WAAW,OAAO,KAAK,EAAE,KAAK;AACpC,wBAAoB,IAAI,SAAS,SAAS,SAAS;AACnD,QAAK,OAAO,UAAU,YAAY,OAAO,UAAU,YAC9C,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,KACpD,CAAC,YAAY,SAAS,SAAS,OAC/B,sFAAsF,KAAK,QAAQ,GAAG;AACxG,aAAO,KAAK,yBAAyB,GAAG,4CAA4C;AAAA,IACtF;AAAA,EACF;AACA,MAAI,mBAAmB,MAAQ,QAAO,KAAK,yDAAyD;AACpG,SAAO,EAAE,OAAkD;AAC7D;AAGO,SAAS,8BAA8B,OAAyC;AACrF,QAAM,SAAmB,CAAC;AAC1B,QAAM,OAAO,SAAS,KAAK;AAC3B,MAAI,CAAC,KAAM,QAAO,EAAE,IAAI,OAAO,QAAQ,CAAC,4BAA4B,EAAE;AACtE,cAAY,MAAMH,YAAW,YAAY,MAAM;AAC/C,MAAI,KAAK,kBAAkB,EAAG,QAAO,KAAK,kCAAkC;AAC5E,MAAI,CAAC,OAAO,cAAc,KAAK,QAAQ,KAAK,OAAO,KAAK,QAAQ,IAAI,EAAG,QAAO,KAAK,8CAA8C;AACjI,MAAI,CAAC,OAAO,cAAc,KAAK,WAAW,KAAK,OAAO,KAAK,WAAW,IAAI,EAAG,QAAO,KAAK,iDAAiD;AAC1I,QAAM,SAAS,SAAS,KAAK,MAAM;AACnC,QAAM,SAAS,SAAS,KAAK,MAAM;AACnC,QAAM,QAAQG,MAAK,QAAQ,OAAO,yBAAyB,QAAQ,EAAE;AACrE,QAAM,YAAYA,MAAK,QAAQ,WAAW,6BAA6B,QAAQ,EAAE;AACjF,QAAM,cAAcA,MAAK,QAAQ,aAAa,+BAA+B,QAAQ,EAAE;AACvF,MAAI,SAAS,CAAC,KAAK,KAAK,KAAK,EAAG,QAAO,KAAK,oDAAoD;AAChG,MAAI,aAAa,CAAC,KAAK,KAAK,SAAS,EAAG,QAAO,KAAK,wDAAwD;AAC5G,MAAI,eAAe,CAAC,YAAY,KAAK,WAAW,EAAG,QAAO,KAAK,wCAAwC;AACvG,MAAI,QAAQ,eAAe,UAAU,QAAQ,eAAe,OAAQ,QAAO,KAAK,iDAAiD;AACjI,QAAM,QAAQ,QAAQ,KAAK,OAAO,MAAM;AACxC,QAAM,YAAY,MAAM,OAAO,CAAC,SAAS,KAAK,SAAS,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS;AACjG,QAAM,OAAO,+BAA+B,KAAK,gBAAgB,EAAE,OAAO,UAAU,CAAC;AACrF,MAAI,CAAC,KAAK,GAAI,QAAO,KAAK,GAAG,KAAK,MAAM;AAAA,WAC/B,KAAK,MAAM,MAAM,KAAK,CAAC,MAAM,UAAU,KAAK,WAAW,UAAU,KAAK,GAAG,EAAE,GAAG;AACrF,WAAO,KAAK,4EAA4E;AAAA,EAC1F;AACA,QAAM,cAAc,cAAc,KAAK,aAAa,MAAM;AAC1D,QAAM,SAAS,SAAS,KAAK,QAAQ,MAAM;AAC3C,MAAI;AACJ,MAAI,KAAK,eAAe,QAAW;AACjC,UAAM,UAAU,mBAAmB,KAAK,UAAmB;AAC3D,QAAI,CAAC,QAAQ,GAAI,QAAO,KAAK,GAAG,OAAO,QAAQ,QAAQ,MAAM,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,uBAAuB,GAAG,KAAK,KAAK,EAAE,CAAC;AAAA,QACvH,cAAa,KAAK;AAAA,EACzB;AACA,QAAM,QAAQ,QAAQ,KAAK,OAAO,MAAM;AACxC,QAAM,aAAa,KAAK,eAAe,SACnC,SACA,yBAAyB,KAAK,YAAY,IAAI,IAAI,MAAM,IAAI,CAAC,SAAS,KAAK,EAAE,CAAC,CAAC;AACnF,MAAI,cAAc,CAAC,WAAW,GAAI,QAAO,KAAK,GAAG,WAAW,MAAM;AAClE,MAAI,OAAO,UAAU,CAAC,KAAK,GAAI,QAAO,EAAE,IAAI,OAAO,OAAO;AAC1D,SAAO,EAAE,IAAI,MAAM,OAAO;AAAA,IACxB,eAAe;AAAA,IACf,UAAU,OAAO,KAAK,QAAQ;AAAA,IAC9B,aAAa,OAAO,KAAK,WAAW;AAAA,IACpC,QAAQ,EAAE,MAAM;AAAA,IAChB,QAAQ,EAAE,WAAW,aAAa,YAAY,QAAQ,WAA8B;AAAA,IACpF;AAAA,IACA,gBAAgB,KAAK;AAAA,IACrB,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;AAAA,IACrC,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,IAC3B,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC;AAAA,IACnC,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,IACzB,GAAI,YAAY,KAAK,EAAE,YAAY,WAAW,MAAM,IAAI,CAAC;AAAA,EAC3D,EAAE;AACJ;;;AH7LA,IAAM,SAAS,CAAC,QAAgC,QAAgB,WAC9D,KAAK,EAAE,IAAI,OAAO,QAAQ,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC,EAAG,GAAG,MAAM;AAG5D,IAAM,sBAA6B,OAAO,KAAK,KAAK,KAAK,QAAQ;AACtE,MAAI,IAAI,WAAW,UAAU,IAAI,aAAa,oBAAqB,QAAO;AAC1E,QAAM,YAAY,IAAI,QAAQ;AAC9B,MAAI,CAAC,UAAW,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AACvD,QAAM,KAAK,IAAI,OAAO,GAAG;AACzB,QAAM,SAAS,MAAM,eAAe,IAAI,UAAU,UAAU;AAC5D,MAAI,CAAC,OAAQ,QAAO,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG;AACvD,QAAM,WAAW,MAAMC,wBAAuB,KAAK,EAAE,QAAQ,SAAS,CAAC,UAAU,QAAQ,EAAE,CAAC;AAC5F,MAAI,CAAC,SAAS,GAAI,QAAO,KAAK,EAAE,OAAO,gBAAgB,QAAQ,SAAS,OAAO,GAAG,GAAG;AACrF,MAAI;AACJ,MAAI;AACF,YAAQ,KAAK,MAAM,SAAS,IAAI;AAAA,EAClC,QAAQ;AACN,WAAO,OAAO,oBAAoB,KAAK,CAAC,2BAA2B,CAAC;AAAA,EACtE;AACA,QAAM,SAAS,OAAO,MAAM,WAAW,WAAW,MAAM,SAAS;AACjE,QAAM,UAAU,8BAA8B,MAAM,QAAQ;AAC5D,MAAI,CAAC,QAAQ,GAAI,QAAO,OAAO,oBAAoB,KAAK,QAAQ,MAAM;AACtE,QAAM,WAAW,QAAQ;AACzB,MAAI,SAAS,OAAO,UAAU,UAAU,SAAU,QAAO,OAAO,gBAAgB,GAAG;AACnF,MAAI,SAAS,OAAO,cAAc,IAAI,QAAQ,GAAI,QAAO,OAAO,gBAAgB,GAAG;AACnF,MAAI,SAAS,OAAO,gBAAgB,IAAI,SAAU,QAAO,OAAO,qBAAqB,GAAG;AACxF,MAAI,SAAS,OAAO,eAAe,UAAU,WAAY,QAAO,OAAO,qBAAqB,GAAG;AAC/F,QAAM,oBAAoB,8BAA8B,IAAI,SAAS,QAAQ;AAC7E,MAAI,kBAAkB,OAAQ,QAAO,OAAO,oBAAoB,KAAK,iBAAiB;AACtF,MAAI,CAAC,UAAU,MAAM,oBAAoB,QAAQ,MAAM,OAAQ,QAAO,OAAO,kBAAkB,GAAG;AAClG,QAAM,SAAS,MAAM,wBAAwB,IAAI,IAAI,QAAQ,IAAI,IAAI,QAAQ;AAC7E,MAAI,UAAU,SAAS,WAAW,OAAO,SAAU,QAAO,OAAO,kBAAkB,GAAG;AACtF,MAAI,UAAU,SAAS,aAAa,OAAO,UAAU;AACnD,QAAI,OAAO,WAAW,OAAQ,QAAO,OAAO,wBAAwB,GAAG;AACvE,WAAO,KAAK;AAAA,MACV,IAAI;AAAA,MACJ,QAAQ,EAAE,WAAW,IAAI,QAAQ,IAAI,aAAa,IAAI,SAAS;AAAA,MAC/D,UAAU,OAAO;AAAA,MACjB,QAAQ,OAAO;AAAA,MACf,QAAQ;AAAA,MACR,gBAAgB,OAAO;AAAA,IACzB,CAAC;AAAA,EACH;AACA,QAAM,aAAa,KAAK,IAAI;AAC5B,MAAI;AACF,UAAM,yBAAyB,IAAI,EAAE,QAAQ,SAAS,GAA4B,QAAQ,UAAU;AAAA,EACtG,QAAQ;AACN,WAAO,OAAO,0BAA0B,GAAG;AAAA,EAC7C;AACA,SAAO,KAAK;AAAA,IACV,IAAI;AAAA,IACJ,QAAQ,EAAE,WAAW,IAAI,QAAQ,IAAI,aAAa,IAAI,SAAS;AAAA,IAC/D,UAAU,SAAS;AAAA,IACnB;AAAA,IACA,QAAQ;AAAA,IACR,gBAAgB;AAAA,EAClB,CAAC;AACH;;;AI3EA,SAAS,0BAAAC,+BAA8B;;;ACAvC,IAAMC,WAAU,IAAI,YAAY;AAEhC,SAASC,gBAAe,OAAwB;AAC9C,MAAI,UAAU,QAAQ,OAAO,UAAU,aAAa,OAAO,UAAU,YAAY,OAAO,UAAU,UAAU;AAC1G,WAAO,KAAK,UAAU,KAAK;AAAA,EAC7B;AACA,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,IAAI,MAAM,IAAIA,eAAc,EAAE,KAAK,GAAG,CAAC;AACxE,MAAI,OAAO,UAAU,SAAU,OAAM,IAAI,UAAU,8CAA8C;AACjG,QAAMC,UAAS;AACf,QAAM,UAAU,OAAO,KAAKA,OAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,QAAQ;AAC1D,UAAM,OAAOA,QAAO,GAAG;AACvB,WAAO,SAAS,SAAY,CAAC,IAAI,CAAC,GAAG,KAAK,UAAU,GAAG,CAAC,IAAID,gBAAe,IAAI,CAAC,EAAE;AAAA,EACpF,CAAC;AACD,SAAO,IAAI,QAAQ,KAAK,GAAG,CAAC;AAC9B;AAGO,SAAS,uBAAuB,OAAwB;AAC7D,SAAOA,gBAAe,KAAK;AAC7B;AAGA,eAAsB,oBAAoB,UAAoC;AAC5E,QAAM,SAAS,MAAM,OAAO,OAAO,OAAO,WAAWD,SAAQ,OAAO,uBAAuB,QAAQ,CAAC,CAAC;AACrG,SAAO,UAAU,MAAM,KAAK,IAAI,WAAW,MAAM,GAAG,CAAC,SAAS,KAAK,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC;AAC5G;;;ACvBO,IAAMG,MAAK;AACX,IAAMC,QAAO;AACb,IAAMC,aAAY,oBAAI,IAAI,CAAC,iBAAiB,YAAY,eAAe,UAAU,UAAU,SAAS,iBAAiB,CAAC;AACtH,IAAM,cAAc,oBAAI,IAAI,CAAC,QAAQ,OAAO,CAAC;AAC7C,IAAM,cAAc,oBAAI,IAAI,CAAC,aAAa,aAAa,CAAC;AACxD,IAAM,YAAY,oBAAI,IAAI,CAAC,MAAM,QAAQ,SAAS,WAAW,cAAc,YAAY,kBAAkB,gBAAgB,QAAQ,CAAC;AAClI,IAAM,WAAW,oBAAI,IAAI,CAAC,WAAW,SAAS,UAAU,CAAC;AACzD,IAAM,gBAAgB,oBAAI,IAAI,CAAC,QAAQ,SAAS,CAAC;AACjD,IAAM,cAAc,oBAAI,IAAI,CAAC,SAAS,OAAO,CAAC;AAC9C,IAAM,aAAa,oBAAI,IAAI,CAAC,UAAU,SAAS,gBAAgB,UAAU,CAAC;AAC1E,IAAM,gBAAgB,oBAAI,IAAI,CAAC,UAAU,OAAO,CAAC;AACjD,IAAM,YAAY;AAClB,IAAMC,gBAAe;AACrB,IAAM,WAAW;AAEjB,IAAMC,UAAS,CAAC,UACrB,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IAC/D,QACA;AAEC,SAASC,aAAY,OAAgCC,UAA8B,MAAc,QAAwB;AAC9H,aAAW,OAAO,OAAO,KAAK,KAAK,EAAG,KAAI,CAACA,SAAQ,IAAI,GAAG,EAAG,QAAO,KAAK,GAAG,IAAI,IAAI,GAAG,mBAAmB;AAC5G;AAEO,SAAS,UAAU,OAAgB,MAAc,QAAkB,MAAM,UAAU,WAAW,OAA2B;AAC9H,MAAI,UAAU,QAAW;AACvB,QAAI,SAAU,QAAO,KAAK,GAAG,IAAI,cAAc;AAC/C,WAAO;AAAA,EACT;AACA,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,KAAK,GAAG,IAAI,mBAAmB;AACtC,WAAO;AAAA,EACT;AACA,QAAM,YAAY,MAAM,KAAK;AAC7B,MAAI,YAAY,CAAC,UAAW,QAAO,KAAK,GAAG,IAAI,cAAc;AAC7D,MAAI,UAAU,SAAS,IAAK,QAAO,KAAK,GAAG,IAAI,oBAAoB,IAAI,eAAe,OAAO,CAAC,aAAa;AAC3G,SAAO;AACT;AAEO,SAAS,WACd,OACA,MACA,QACA,OACA,UACmC;AACnC,QAAM,MAAMF,QAAO,KAAK;AACxB,MAAI,CAAC,KAAK;AACR,WAAO,KAAK,GAAG,IAAI,oBAAoB;AACvC,WAAO;AAAA,EACT;AACA,EAAAC,aAAY,KAAK,YAAY,MAAM,MAAM;AACzC,QAAM,SAAS,UAAU,IAAI,QAAQ,GAAG,IAAI,WAAW,QAAQ,IAAI,IAAI,KAAK;AAC5E,MAAI,UAAU,CAACL,IAAG,KAAK,MAAM,EAAG,QAAO,KAAK,GAAG,IAAI,2CAA2C;AAC9F,MAAI,MAAM,QAAQ,CAAC,MAAM,IAAI,MAAM,EAAG,QAAO,KAAK,GAAG,IAAI,wCAAwC;AACjG,MAAI,UAAU,SAAS,WAAW,UAAU,CAAC,SAAS,QAAQ,SAAS,MAAM,GAAG;AAC9E,WAAO,KAAK,GAAG,IAAI,wCAAwC;AAAA,EAC7D;AACA,QAAM,QAAQ,UAAU,IAAI,OAAO,GAAG,IAAI,UAAU,MAAM;AAC1D,QAAM,eAAe,UAAU,IAAI,cAAc,GAAG,IAAI,iBAAiB,QAAQG,aAAY;AAC7F,QAAM,WAAW,UAAU,IAAI,UAAU,GAAG,IAAI,aAAa,MAAM;AACnE,SAAO;AAAA,IACL;AAAA,IACA,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,IACzB,GAAI,eAAe,EAAE,aAAa,IAAI,CAAC;AAAA,IACvC,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,EACjC;AACF;;;ACnCO,SAAS,8BACd,OACA,UAA0C,CAAC,GACZ;AAC/B,QAAM,SAAmB,CAAC;AAC1B,QAAM,OAAOI,QAAO,KAAK;AACzB,MAAI,CAAC,KAAM,QAAO,EAAE,IAAI,OAAO,QAAQ,CAAC,4BAA4B,EAAE;AACtE,EAAAC,aAAY,MAAMC,YAAW,YAAY,MAAM;AAC/C,MAAI,KAAK,kBAAkB,8BAA+B,QAAO,KAAK,kCAAkC;AACxG,MAAI,CAAC,OAAO,UAAU,KAAK,QAAQ,KAAK,OAAO,KAAK,QAAQ,IAAI,EAAG,QAAO,KAAK,8CAA8C;AAC7H,MAAI,CAAC,OAAO,UAAU,KAAK,WAAW,KAAK,OAAO,KAAK,WAAW,IAAI,EAAG,QAAO,KAAK,+DAA+D;AAEpJ,QAAM,YAAYF,QAAO,KAAK,MAAM;AACpC,MAAI,SAA8B,EAAE,MAAM,WAAW,OAAO,UAAU;AACtE,MAAI,CAAC,UAAW,QAAO,KAAK,mCAAmC;AAAA,OAC1D;AACH,IAAAC,aAAY,WAAW,aAAa,mBAAmB,MAAM;AAC7D,UAAM,OAAO,UAAU;AACvB,UAAM,QAAQ,UAAU,UAAU,OAAO,yBAAyB,QAAQ,IAAI,IAAI,KAAK;AACvF,QAAI,SAAS,YAAY,SAAS,UAAW,QAAO,KAAK,gDAAgD;AACzG,QAAI,SAAS,CAACE,IAAG,KAAK,KAAK,EAAG,QAAO,KAAK,oDAAoD;AAC9F,QAAI,QAAQ,cAAc,SAAS,QAAQ,WAAY,QAAO,KAAK,gCAAgC,QAAQ,UAAU,EAAE;AACvH,QAAI,QAAQ,eAAe,UAAU,QAAQ,YAAa,QAAO,KAAK,iCAAiC,QAAQ,WAAW,EAAE;AAC5H,QAAI,SAAS,YAAY,SAAS,UAAW,UAAS,EAAE,MAAM,MAAM;AAAA,EACtE;AAEA,MAAI;AACJ,MAAI,KAAK,WAAW,QAAW;AAC7B,UAAM,YAAYH,QAAO,KAAK,MAAM;AACpC,QAAI,CAAC,UAAW,QAAO,KAAK,mCAAmC;AAAA,SAC1D;AACH,MAAAC,aAAY,WAAW,aAAa,mBAAmB,MAAM;AAC7D,YAAM,YAAY,UAAU,UAAU,WAAW,6BAA6B,QAAQ,IAAI,IAAI,KAAK;AACnG,YAAM,cAAc,UAAU,UAAU,aAAa,+BAA+B,QAAQ,IAAI,IAAI,KAAK;AACzG,eAAS,EAAE,WAAW,YAAY;AAAA,IACpC;AAAA,EACF;AACA,MAAI,OAAO,SAAS,YAAY,CAAC,OAAQ,QAAO,KAAK,gDAAgD;AACrG,MAAI,OAAO,SAAS,aAAa,OAAQ,QAAO,KAAK,sDAAsD;AAE3G,MAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,EAAG,QAAO,KAAK,iCAAiC;AAC7E,QAAM,WAAW,MAAM,QAAQ,KAAK,KAAK,IAAI,KAAK,QAAQ,CAAC;AAC3D,MAAI,SAAS,SAAS,UAAW,QAAO,KAAK,mCAAmC,SAAS,UAAU;AACnG,QAAM,UAAU,IAAI,KAAK,QAAQ,SAAS,CAAC,GAAG,IAAI,CAAC,SAAS,KAAK,EAAE,CAAC;AACpE,QAAM,iBAAiB,IAAI,KAAK,QAAQ,eAAe,CAAC,GAAG,IAAI,CAAC,SAAS,KAAK,EAAE,CAAC;AACjF,QAAM,MAAM,oBAAI,IAAY;AAC5B,QAAM,QAAQ,oBAAI,IAAY;AAC9B,QAAM,QAA6B,CAAC;AACpC,aAAW,CAAC,OAAO,KAAK,KAAK,SAAS,MAAM,GAAG,SAAS,EAAE,QAAQ,GAAG;AACnE,UAAM,OAAO,kBAAkB,KAAK;AACpC,UAAM,MAAMD,QAAO,KAAK;AACxB,QAAI,CAAC,KAAK;AACR,aAAO,KAAK,GAAG,IAAI,oBAAoB;AACvC;AAAA,IACF;AACA,IAAAC,aAAY,KAAK,WAAW,MAAM,MAAM;AACxC,UAAM,KAAK,UAAU,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,IAAI,IAAI,KAAK;AAChE,UAAM,OAAO,UAAU,IAAI,MAAM,GAAG,IAAI,SAAS,QAAQ,KAAK,IAAI,KAAK;AACvE,UAAM,QAAQ,UAAU,IAAI,OAAO,GAAG,IAAI,UAAU,QAAQ,UAAU,IAAI,KAAK;AAC/E,QAAI,MAAM,CAACE,IAAG,KAAK,EAAE,EAAG,QAAO,KAAK,GAAG,IAAI,uCAAuC;AAClF,QAAI,QAAQ,CAACC,MAAK,KAAK,IAAI,EAAG,QAAO,KAAK,GAAG,IAAI,oCAAoC;AACrF,QAAI,IAAI,IAAI,EAAE,KAAK,eAAe,IAAI,EAAE,EAAG,QAAO,KAAK,GAAG,IAAI,wBAAwB,EAAE,GAAG;AAC3F,QAAI,MAAM,IAAI,IAAI,MAAM,QAAQ,eAAe,CAAC,GAAG,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,EAAG,QAAO,KAAK,GAAG,IAAI,qBAAqB,IAAI,GAAG;AACtI,QAAI,IAAI,EAAE;AACV,UAAM,IAAI,IAAI;AAEd,UAAM,SAASJ,QAAO,IAAI,UAAU;AACpC,QAAI,aAAmC,EAAE,SAAS,WAAW,OAAO,MAAM;AAC1E,QAAI,CAAC,OAAQ,QAAO,KAAK,GAAG,IAAI,+BAA+B;AAAA,SAC1D;AACH,MAAAC,aAAY,QAAQ,UAAU,GAAG,IAAI,eAAe,MAAM;AAC1D,YAAM,UAAU,UAAU,OAAO,SAAS,GAAG,IAAI,uBAAuB,QAAQ,KAAK,IAAI,KAAK;AAC9F,YAAM,QAAQ,OAAO;AACrB,UAAI,CAAC,OAAO,UAAU,KAAK,KAAK,OAAO,KAAK,IAAI,KAAK,OAAO,KAAK,IAAI,KAAW;AAC9E,eAAO,KAAK,GAAG,IAAI,0DAA0D;AAAA,MAC/E;AACA,YAAM,WAAW,UAAU,OAAO,UAAU,GAAG,IAAI,wBAAwB,QAAQ,EAAE;AACrF,mBAAa,EAAE,SAAS,OAAO,OAAO,UAAU,KAAK,IAAI,OAAO,KAAK,IAAI,OAAO,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC,EAAG;AAAA,IACpH;AAEA,UAAM,cAAcD,QAAO,IAAI,QAAQ;AACvC,QAAI,WAA+B,EAAE,MAAM,cAAc;AACzD,QAAI,CAAC,YAAa,QAAO,KAAK,GAAG,IAAI,6BAA6B;AAAA,SAC7D;AACH,MAAAC,aAAY,aAAa,eAAe,GAAG,IAAI,aAAa,MAAM;AAClE,UAAI,YAAY,SAAS,eAAe;AACtC,YAAI,YAAY,YAAY,OAAW,QAAO,KAAK,GAAG,IAAI,oDAAoD;AAAA,MAChH,WAAW,YAAY,SAAS,SAAS;AACvC,YAAI,CAAC,MAAM,QAAQ,YAAY,OAAO,KAAK,YAAY,QAAQ,WAAW,GAAG;AAC3E,iBAAO,KAAK,GAAG,IAAI,6CAA6C;AAAA,QAClE;AACA,cAAM,SAAS,MAAM,QAAQ,YAAY,OAAO,IAAI,YAAY,UAAU,CAAC;AAC3E,cAAM,aAAuB,CAAC;AAC9B,mBAAW,CAAC,WAAWI,MAAK,KAAK,OAAO,QAAQ,GAAG;AACjD,gBAAM,OAAO,UAAUA,QAAO,GAAG,IAAI,qBAAqB,SAAS,KAAK,QAAQ,IAAI,IAAI,KAAK;AAC7F,cAAI,WAAW,SAAS,IAAI,EAAG,QAAO,KAAK,GAAG,IAAI,iCAAiC,IAAI,GAAG;AAC1F,cAAI,QAAQ,QAAQ,CAAC,QAAQ,IAAI,IAAI,EAAG,QAAO,KAAK,GAAG,IAAI,iDAAiD,IAAI,GAAG;AACnH,qBAAW,KAAK,IAAI;AAAA,QACtB;AACA,mBAAW,EAAE,MAAM,SAAS,SAAS,WAAW;AAAA,MAClD,MAAO,QAAO,KAAK,GAAG,IAAI,6CAA6C;AAAA,IACzE;AAEA,UAAM,UAAU,UAAU,IAAI,SAAS,GAAG,IAAI,YAAY,QAAQ,GAAK;AACvE,UAAM,iBAAiB,UAAU,IAAI,gBAAgB,GAAG,IAAI,mBAAmB,QAAQC,aAAY;AACnG,UAAM,eAAe,UAAU,IAAI,cAAc,GAAG,IAAI,iBAAiB,QAAQA,eAAc,IAAI,KAAK;AACxG,QAAI;AACJ,QAAI,IAAI,WAAW,QAAW;AAC5B,YAAM,YAAYN,QAAO,IAAI,MAAM;AACnC,UAAI,CAAC,UAAW,QAAO,KAAK,GAAG,IAAI,2BAA2B;AAAA,WACzD;AACH,QAAAC,aAAY,WAAW,aAAa,GAAG,IAAI,WAAW,MAAM;AAC5D,cAAM,QAAQ,UAAU;AACxB,YAAI,UAAU,YAAY,UAAU,UAAW,QAAO,KAAK,GAAG,IAAI,yCAAyC;AAC3G,YAAI,OAAO,SAAS,aAAa,UAAU,SAAU,QAAO,KAAK,GAAG,IAAI,kDAAkD;AAC1H,YAAI,OAAO,SAAS,YAAY,UAAU,YAAY,UAAU,UAAU,OAAW,QAAO,KAAK,GAAG,IAAI,0DAA0D;AAClK,YAAI,OAAO,SAAS,YAAY,UAAU,aAAa,UAAU,UAAU,OAAW,QAAO,KAAK,GAAG,IAAI,2DAA2D;AACpK,cAAM,QAAQ,UAAU,UAAU,SAAY,SAAY,WAAW,UAAU,OAAO,GAAG,IAAI,iBAAiB,QAAQ,SAAS,QAAQ;AACvI,YAAI,UAAU,SAAU,UAAS,EAAE,OAAO,OAAO,SAAS,EAAE,QAAQ,GAAG,EAAE;AAAA,iBAChE,UAAU,UAAW,UAAS,EAAE,OAAO,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC,EAAG;AAAA,MAC9E;AAAA,IACF;AACA,UAAM,KAAK,EAAE,IAAI,MAAM,OAAO,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC,GAAI,YAAY,UAAU,GAAI,iBAAiB,EAAE,eAAe,IAAI,CAAC,GAAI,cAAc,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC,EAAG,CAAC;AAAA,EACnL;AAEA,QAAM,SAAS,oBAAI,IAAI,CAAC,GAAG,gBAAgB,GAAG,GAAG,CAAC;AAClD,aAAW,CAAC,OAAO,IAAI,KAAK,MAAM,QAAQ,GAAG;AAC3C,UAAM,WAAW,KAAK,WAAW;AACjC,QAAI,YAAY,CAAC,OAAO,IAAI,QAAQ,EAAG,QAAO,KAAK,kBAAkB,KAAK,kDAAkD,QAAQ,GAAG;AACvI,QAAI,aAAa,KAAK,GAAI,QAAO,KAAK,kBAAkB,KAAK,+CAA+C;AAAA,EAC9G;AACA,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,oBAAI,IAAI,CAAC,KAAK,EAAE,CAAC;AAC9B,QAAI,WAAW,KAAK,WAAW;AAC/B,WAAO,UAAU;AACf,UAAI,KAAK,IAAI,QAAQ,GAAG;AACtB,eAAO,KAAK,kDAAkD,KAAK,EAAE,GAAG;AACxE;AAAA,MACF;AACA,WAAK,IAAI,QAAQ;AACjB,iBAAW,MAAM,KAAK,CAAC,cAAc,UAAU,OAAO,QAAQ,GAAG,WAAW;AAAA,IAC9E;AAAA,EACF;AAEA,MAAI;AACJ,MAAI,KAAK,oBAAoB,QAAW;AACtC,QAAI,OAAO,SAAS,UAAW,QAAO,KAAK,gEAAgE;AAC3G,QAAI,CAAC,MAAM,QAAQ,KAAK,eAAe,EAAG,QAAO,KAAK,2CAA2C;AACjG,UAAM,SAAS,MAAM,QAAQ,KAAK,eAAe,IAAI,KAAK,kBAAkB,CAAC;AAC7E,UAAM,OAAO,oBAAI,IAAY;AAC7B,sBAAkB,CAAC;AACnB,eAAW,CAAC,OAAO,KAAK,KAAK,OAAO,QAAQ,GAAG;AAC7C,YAAM,OAAO,4BAA4B,KAAK;AAC9C,YAAM,MAAMD,QAAO,KAAK;AACxB,UAAI,CAAC,KAAK;AACR,eAAO,KAAK,GAAG,IAAI,oBAAoB;AACvC;AAAA,MACF;AACA,MAAAC,aAAY,KAAK,eAAe,MAAM,MAAM;AAC5C,YAAM,SAAS,UAAU,IAAI,QAAQ,GAAG,IAAI,WAAW,QAAQ,IAAI,IAAI,KAAK;AAC5E,UAAI,KAAK,IAAI,MAAM,EAAG,QAAO,KAAK,GAAG,IAAI,uBAAuB,MAAM,GAAG;AACzE,WAAK,IAAI,MAAM;AACf,YAAM,cAAc,QAAQ,eAAe,CAAC,GAAG,KAAK,CAAC,SAAS,KAAK,OAAO,MAAM;AAChF,UAAI,CAAC,WAAY,QAAO,KAAK,GAAG,IAAI,sCAAsC;AAAA,eACjE,WAAW,QAAQ,UAAU,UAAW,QAAO,KAAK,GAAG,IAAI,2DAA2D;AAC/H,YAAM,QAAQ,WAAW,IAAI,OAAO,GAAG,IAAI,UAAU,QAAQ,SAAS,YAAY,QAAQ;AAC1F,UAAI,MAAO,iBAAgB,KAAK,EAAE,QAAQ,MAAM,CAAC;AAAA,IACnD;AAAA,EACF;AACA,MAAI,OAAO,OAAQ,QAAO,EAAE,IAAI,OAAO,OAAO;AAC9C,SAAO,EAAE,IAAI,MAAM,OAAO;AAAA,IACxB,eAAe;AAAA,IACf,UAAU,OAAO,KAAK,QAAQ;AAAA,IAC9B,aAAa,OAAO,KAAK,WAAW;AAAA,IACpC;AAAA,IACA,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,IAC3B;AAAA,IACA,GAAI,kBAAkB,EAAE,gBAAgB,IAAI,CAAC;AAAA,EAC/C,EAAE;AACJ;;;ACpNO,IAAM,gCAAgC;AAEtC,IAAM,sBAAsB;AAE5B,IAAM,8BAA8B;AAgJ3C,IAAM,YAAY,CAAC,GAA+B,MAChD,EAAE,WAAW,QAAQ,cAAc,EAAE,WAAW,OAAO,KACpD,EAAE,WAAW,QAAQ,EAAE,WAAW,SAClC,EAAE,MAAM,cAAc,EAAE,KAAK,KAC7B,EAAE,GAAG,cAAc,EAAE,EAAE;AAGrB,SAAS,qBACd,QACA,SACwB;AACxB,QAAM,QAAsC,CAAC;AAC7C,QAAM,cAAc,oBAAI,IAAwC;AAChE,aAAW,QAAQ,QAAQ,SAAS,CAAC,GAAG;AACtC,UAAM,YAAY,EAAE,GAAG,MAAM,QAAQ,OAAQ,OAAO;AACpD,gBAAY,IAAI,KAAK,IAAI,SAAS;AAClC,UAAM,KAAK,SAAS;AAAA,EACtB;AACA,aAAW,YAAY,SAAS,mBAAmB,CAAC,GAAG;AACrD,UAAM,OAAO,YAAY,IAAI,SAAS,MAAM;AAC5C,QAAI,MAAM,QAAQ,UAAU,UAAW,MAAK,SAAS,EAAE,OAAO,WAAW,OAAO,SAAS,MAAM;AAAA,EACjG;AACA,aAAW,QAAQ,SAAS,SAAS,CAAC,GAAG;AACvC,QAAI,YAAY,IAAI,KAAK,EAAE,KAAK,MAAM,KAAK,CAAC,cAAc,UAAU,SAAS,KAAK,IAAI,GAAG;AACvF,YAAM,IAAI,UAAU,wBAAwB,KAAK,EAAE,iCAAiC;AAAA,IACtF;AACA,UAAM,KAAK,EAAE,GAAG,MAAM,QAAQ,QAAS,OAAO,CAAC;AAAA,EACjD;AACA,SAAO;AAAA,IACL,OAAO,MAAM,KAAK,SAAS;AAAA,IAC3B,gBAAgB,QAAQ,YAAY;AAAA,IACpC,iBAAiB,SAAS,YAAY;AAAA,EACxC;AACF;AAEA,IAAM,UAAU,CAAC,MAAyB,WACxC,OAAO,SACJ,KAAK,SAAS,SAAS,iBACtB,OAAO,WAAW,QAAQ,KAAK,SAAS,QAAQ,SAAS,OAAO,MAAM;AAGrE,SAAS,qBACd,SACA,QACA,OACyB;AACzB,QAAM,YAAY,IAAI,IAAI,MAAM,OAAO,CAAC,SAAS,KAAK,WAAW,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC;AACtG,SAAO;AAAA,IACL,QAAQ,EAAE,GAAG,OAAO;AAAA,IACpB,WAAW,EAAE,QAAQ,QAAQ,gBAAgB,SAAS,QAAQ,gBAAgB;AAAA,IAC9E,OAAO,QAAQ,MAAM,IAAI,CAAC,SAAS;AACjC,YAAM,UAAU,QAAQ,MAAM,MAAM;AACpC,YAAM,QAAQ,CAAC,UAAU,KAAK,QAAQ,QAAQ;AAC9C,YAAM,OAAO,QAAQ,UAAU,IAAI,MAAM,MAAM,IAAI;AACnD,YAAM,SAAS,SAAS,QAAQ,OAAO,KAAK,SAAS,YAAY,OAAO,KAAK,eAAe,WACxF,EAAE,GAAG,OAAO,UAAU,KAAK,MAAM,YAAY,KAAK,WAAW,IAC7D;AACJ,aAAO;AAAA,QACL,IAAI,KAAK;AAAA,QACT,MAAM,KAAK;AAAA,QACX,OAAO,KAAK;AAAA,QACZ,GAAI,KAAK,UAAU,EAAE,SAAS,KAAK,QAAQ,IAAI,CAAC;AAAA,QAChD,YAAY,KAAK;AAAA,QACjB,UAAU,KAAK;AAAA,QACf,QAAQ,KAAK;AAAA,QACb,QAAQ,UAAU,YAAqB;AAAA,QACvC,GAAI,KAAK,iBAAiB,EAAE,gBAAgB,KAAK,eAAe,IAAI,CAAC;AAAA,QACrE,GAAI,UAAU,EAAE,cAAc,KAAK,aAAa,IAAI,CAAC;AAAA,QACrD,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,MAC7B;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;ACpMA,IAAM,UAAU,CAAC,QACf,OAAO,IAAI,YAAY,OAAO,IAAI,aAAa,WAAW,MAA+C;AAE3G,IAAM,QAAQ,CAAC,QACb,OAAO,IAAI,YAAY,OAAO,IAAI,aAAa,WAAW,MAA6C;AAEzG,eAAe,OAAO,IAAe,IAAY,OAAkD;AACjG,MAAI,GAAG,UAAW,QAAO,QAAQ,MAAM,GAAG,UAAU,IAAI,EAAE,OAAO,KAAK,GAAG,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI;AACnG,QAAMM,SAAQ,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC;AACpD,SAAOA,MAAK,KAAK,CAAC,QAAQ,OAAO,QAAQ,KAAK,EAAE,MAAM,CAAC,CAAC,KAAK,KAAK,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC;AAC7F;AAEA,eAAsB,+BACpB,IACA,UACA,aAC4C;AAC5C,QAAM,QAAQ,EAAE,UAAU,aAAa,QAAQ,KAAK;AACpD,MAAI,CAAC,MAAM,OAAO,IAAI,yBAAyB,KAAK,EAAG,QAAO;AAC9D,QAAMA,SAAQ,MAAM,GAAG,MAAM,EAAE,uBAAuB,EAAE,GAAG;AAAA,IACzD;AAAA,IACA,OAAO,EAAE,UAAU,OAAO;AAAA,IAC1B,OAAO;AAAA,EACT,EAAE,EAAE,CAAC,GAAG;AACR,SAAO,QAAQ,MAAM,QAAQA,KAAI,IAAI,CAAC,GAAGA,KAAI,EAAE,KAAK,CAAC,GAAG,MAAM,OAAO,EAAE,QAAQ,IAAI,OAAO,EAAE,QAAQ,CAAC,EAAE,CAAC,IAAI,MAAS;AACvH;AAEA,eAAsB,+BACpB,IACA,UACA,aAC4C;AAC5C,QAAM,QAAQ,EAAE,UAAU,YAAY;AACtC,MAAI,CAAC,MAAM,OAAO,IAAI,yBAAyB,KAAK,EAAG,QAAO;AAC9D,QAAMA,SAAQ,MAAM,GAAG,MAAM,EAAE,uBAAuB,EAAE,GAAG;AAAA,IACzD;AAAA,IACA,OAAO,EAAE,UAAU,OAAO;AAAA,IAC1B,OAAO;AAAA,EACT,EAAE,EAAE,CAAC,GAAG;AACR,SAAO,QAAQ,MAAM,QAAQA,KAAI,IAAI,CAAC,GAAGA,KAAI,EAAE,KAAK,CAAC,GAAG,MAAM,OAAO,EAAE,QAAQ,IAAI,OAAO,EAAE,QAAQ,CAAC,EAAE,CAAC,IAAI,MAAS;AACvH;AAEA,eAAsB,uBACpB,IACA,WACA,aAC0C;AAC1C,QAAM,KAAK,wBAAwB,WAAW;AAC9C,QAAMA,SAAQ,MAAM,GAAG,MAAM,EAAE,oBAAoB,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG;AAC1F,SAAO,MAAM,MAAM,QAAQA,KAAI,IAAIA,MAAK,CAAC,IAAI,MAAS;AACxD;AAGA,eAAsB,gCACpB,IACA,UACA,UACA,YACe;AACf,QAAM,EAAE,UAAU,OAAO,IAAI;AAC7B,QAAM,SAAS,SAAS;AACxB,QAAM,KAAK,0BAA0B,OAAO,WAAW,IAAI,SAAS,QAAQ;AAC5E,QAAM,MAAc,CAAC;AACrB,MAAI,UAAU,QAAQ;AACpB,QAAI,KAAK,EAAE,GAAG,UAAU,IAAI,yBAAyB,IAAI,SAAS,IAAI,OAAO,EAAE,QAAQ,MAAM,EAAE,CAAC;AAAA,EAClG;AACA,MAAI,KAAK,EAAE,GAAG,UAAU,IAAI,yBAAyB,IAAI,OAAO;AAAA,IAC9D;AAAA,IACA,UAAU,SAAS,OAAO;AAAA,IAC1B,UAAU,OAAO;AAAA,IACjB,aAAa,OAAO;AAAA,IACpB,UAAU,SAAS;AAAA,IACnB;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,EACF,EAAE,CAAC;AACH,QAAM,GAAG,SAAS,KAAK,EAAE,YAAY,0BAA0B,OAAO,WAAW,IAAI,SAAS,QAAQ,IAAI,MAAM,GAAG,CAAC;AACtH;AAGA,eAAsB,uBACpB,IACA,UACA,aACA,kBACA,WACA,WACmC;AACnC,QAAM,KAAK,wBAAwB,WAAW;AAC9C,QAAM,UAAU,MAAM,uBAAuB,IAAI,SAAS,OAAO,OAAO,WAAW;AACnF,OAAK,SAAS,YAAY,OAAO,iBAAkB,OAAM,IAAI,MAAM,kCAAkC;AACrG,QAAM,MAAgC;AAAA,IACpC;AAAA,IACA,WAAW,SAAS,OAAO;AAAA,IAC3B;AAAA,IACA,UAAU,SAAS;AAAA,IACnB;AAAA,IACA;AAAA,IACA,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,EACnC;AACA,QAAM,GAAG,SAAS,CAAC,EAAE,GAAG,UAAU,IAAI,sBAAsB,IAAI,OAAO,IAA0C,CAAC,GAAG;AAAA,IACnH,YAAY,wBAAwB,WAAW,IAAI,SAAS,QAAQ;AAAA,IACpE,QAAQ,UACJ,CAAC,EAAE,IAAI,sBAAsB,IAAI,QAAQ,MAAM,QAAQ,EAAE,UAAU,iBAAiB,EAAE,CAAC,IACvF,CAAC,EAAE,IAAI,sBAAsB,IAAI,QAAQ,MAAM,CAAC;AAAA,EACtD,CAAC;AACD,SAAO;AACT;;;AL3GA,IAAM,aAAa;AACnB,IAAM,WAAW;AAEjB,IAAMC,UAAS,CAAC,QAAgC,QAAgB,WAC9D,KAAK,EAAE,IAAI,OAAO,QAAQ,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC,EAAG,GAAG,MAAM;AAEnE,eAAe,cAAc,IAAe,WAAmB;AAC7D,QAAM,UAAU,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,UAAU,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG;AAC3F,QAAM,QAAQ,MAAM,QAAQ,MAAM,IAAI,OAAO,CAAC,IAAI;AAClD,MAAI,CAAC,MAAO,QAAO,EAAE,OAAO,MAAM,OAAO,CAAC,EAAE;AAC5C,SAAO,EAAE,OAAO,OAAO,MAAM,UAAU,IAAI,KAAc,EAAE;AAC7D;AAEA,eAAe,aAAa,IAAe,WAAmB,OAAmD;AAC/G,MAAI,CAAC,MAAO,QAAO;AACnB,MAAIC,SAAQ,MAAM,GAAG,MAAM,EAAE,cAAc,EAAE,GAAG;AAAA,IAC9C,OAAO,EAAE,iBAAiB,wBAAwB,KAAK,EAAE;AAAA,IAAG,OAAO;AAAA,EACrE,EAAE,EAAE,CAAC,GAAG;AACR,MAAI,CAACA,OAAM,OAAQ,CAAAA,SAAQ,MAAM,GAAG,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,GAAG,EAAE,EAAE,CAAC,GAAG;AACrG,QAAM,SAAS,MAAM,QAAQA,KAAI,IAC7B,CAAC,GAAGA,KAAI,EACP,OAAO,CAAC,QAAQ,OAAO,IAAI,WAAW,SAAS,MAAM,SAAS,EAC9D,KAAK,CAAC,GAAG,MAAM,OAAO,EAAE,aAAa,CAAC,IAAI,OAAO,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,IACtE;AACJ,SAAO,OAAO,QAAQ,WAAW,YAAY,OAAO,SAAS,OAAO,SAAS;AAC/E;AAEA,eAAe,gBAAgB,IAAe,WAAmB,aAAqB;AACpF,QAAM,CAAC,QAAQ,OAAO,IAAI,MAAM,QAAQ,IAAI;AAAA,IAC1C,+BAA+B,IAAI,WAAW,WAAW;AAAA,IACzD,uBAAuB,IAAI,WAAW,WAAW;AAAA,EACnD,CAAC;AACD,SAAO,EAAE,QAAQ,QAAQ;AAC3B;AAGO,IAAM,6BAAoC,OAAO,KAAK,KAAK,KAAK,QAAQ;AAC7E,MAAI,IAAI,WAAW,UAAU,IAAI,aAAa,4BAA6B,QAAO;AAClF,QAAM,WAAW,IAAI,QAAQ,eAAe;AAC5C,MAAI,CAAC,SAAU,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AACtD,QAAM,KAAK,IAAI,OAAO,GAAG;AACzB,QAAM,SAAS,MAAM,eAAe,IAAI,SAAS,UAAU;AAC3D,MAAI,CAAC,OAAQ,QAAO,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG;AACvD,QAAM,WAAW,MAAMC,wBAAuB,KAAK,EAAE,QAAQ,SAAS,CAAC,SAAS,QAAQ,EAAE,CAAC;AAC3F,MAAI,CAAC,SAAS,GAAI,QAAO,KAAK,EAAE,OAAO,gBAAgB,QAAQ,SAAS,OAAO,GAAG,GAAG;AACrF,MAAI;AACJ,MAAI;AACF,YAAQ,KAAK,MAAM,SAAS,IAAI;AAAA,EAClC,QAAQ;AACN,WAAOF,QAAO,oBAAoB,KAAK,CAAC,2BAA2B,CAAC;AAAA,EACtE;AACA,QAAM,SAAS,OAAO,MAAM,WAAW,WAAW,MAAM,SAAS;AACjE,QAAM,UAAU,8BAA8B,MAAM,UAAU;AAAA,IAC5D,YAAY;AAAA,EACd,CAAC;AACD,MAAI,CAAC,QAAQ,GAAI,QAAOA,QAAO,oBAAoB,KAAK,QAAQ,MAAM;AACtE,QAAM,WAAW,QAAQ;AACzB,MAAI,SAAS,OAAO,UAAU,SAAS,SAAU,QAAOA,QAAO,gBAAgB,GAAG;AAClF,MAAI,SAAS,QAAQ,cAAc,IAAI,QAAQ,GAAI,QAAOA,QAAO,gBAAgB,GAAG;AACpF,MAAI,SAAS,OAAO,gBAAgB,IAAI,SAAU,QAAOA,QAAO,qBAAqB,GAAG;AACxF,QAAM,EAAE,MAAM,IAAI,MAAM,cAAc,IAAI,IAAI,QAAQ,EAAE;AACxD,QAAM,UAAU,8BAA8B,UAAU;AAAA,IACtD,YAAY;AAAA,IACZ,aAAa,SAAS;AAAA,IACtB;AAAA,EACF,CAAC;AACD,MAAI,CAAC,QAAQ,GAAI,QAAOA,QAAO,oBAAoB,KAAK,QAAQ,MAAM;AACtE,QAAMG,SAAQ,MAAM,uBAAuB,IAAI,IAAI,QAAQ,IAAI,IAAI,QAAQ;AAC3E,MAAIA,QAAO;AACT,UAAM,aAAa,8BAA8BA,OAAM,UAAU;AAAA,MAC/D,YAAY;AAAA,MACZ,aAAa,IAAI,QAAQ;AAAA,MACzB;AAAA,MACA,aAAa,SAAS;AAAA,IACxB,CAAC;AACD,QAAI,CAAC,WAAW,IAAI;AAClB,aAAOH,QAAO,oBAAoB,KAAK,WAAW,OAAO,IAAI,CAAC,UAAU,6BAA6B,KAAK,EAAE,CAAC;AAAA,IAC/G;AAAA,EACF;AACA,MAAI,CAAC,UAAU,MAAM,oBAAoB,QAAQ,MAAM,OAAQ,QAAOA,QAAO,kBAAkB,GAAG;AAClG,QAAM,SAAS,MAAM,+BAA+B,IAAI,IAAI,QAAQ,IAAI,IAAI,QAAQ;AACpF,MAAI,UAAU,SAAS,WAAW,OAAO,SAAU,QAAOA,QAAO,kBAAkB,GAAG;AACtF,MAAI,UAAU,SAAS,aAAa,OAAO,UAAU;AACnD,QAAI,OAAO,WAAW,OAAQ,QAAOA,QAAO,wBAAwB,GAAG;AACvE,WAAO,KAAK;AAAA,MACV,IAAI;AAAA,MACJ,QAAQ,SAAS;AAAA,MACjB,UAAU,OAAO;AAAA,MACjB,QAAQ,OAAO;AAAA,MACf,QAAQ;AAAA,MACR,gBAAgB,OAAO;AAAA,IACzB,CAAC;AAAA,EACH;AACA,QAAM,aAAa,KAAK,IAAI;AAC5B,MAAI;AACF,UAAM,gCAAgC,IAAI,EAAE,QAAQ,SAAS,GAA4B,QAAQ,UAAU;AAAA,EAC7G,QAAQ;AACN,WAAOA,QAAO,0BAA0B,GAAG;AAAA,EAC7C;AACA,SAAO,KAAK;AAAA,IACV,IAAI;AAAA,IACJ,QAAQ,SAAS;AAAA,IACjB,UAAU,SAAS;AAAA,IACnB;AAAA,IACA,QAAQ;AAAA,IACR,gBAAgB;AAAA,EAClB,CAAC;AACH;AAGO,IAAM,sBAA6B,OAAO,KAAK,KAAK,KAAK,QAAQ;AACtE,MAAI,IAAI,WAAW,SAAS,IAAI,aAAa,oBAAqB,QAAO;AACzE,MAAI,CAAC,IAAI,QAAQ,cAAe,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AACvE,QAAM,OAAO,MAAM,IAAI,WAAW,KAAK,GAAG;AAC1C,MAAI,CAAC,KAAM,QAAO,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG;AACrD,QAAM,KAAK,IAAI,OAAO,GAAG;AACzB,QAAM,OAAO,MAAM,IAAI,QAAQ,IAAa,IAAI;AAChD,QAAM,QAAQ,MAAM,IAAI,QAAQ,IAAa,IAAI;AACjD,QAAM,YAAY,IAAI,QAAQ,KAAK,OAAO,QAAQ,IAAI;AACtD,QAAM,cAAc,KAAK,IAAI,GAAG,IAAI,QAAQ,KAAK,OAAO,SAAS,CAAC;AAClE,MAAI,CAAC,SAAS,YAAY,YAAa,QAAO,KAAK,EAAE,OAAO,yBAAyB,GAAG,GAAG;AAC3F,QAAM,CAAC,EAAE,QAAQ,QAAQ,GAAG,EAAE,OAAO,MAAM,GAAG,MAAM,IAAI,MAAM,QAAQ,IAAI;AAAA,IACxE,gBAAgB,IAAI,IAAI,QAAQ,IAAI,IAAI,QAAQ;AAAA,IAChD,cAAc,IAAI,IAAI,QAAQ,EAAE;AAAA,IAChC,aAAa,IAAI,IAAI,QAAQ,IAAI,KAAK,KAAK;AAAA,EAC7C,CAAC;AACD,QAAM,YAAY,qBAAqB,QAAQ,UAAU,SAAS,QAAQ;AAC1E,MAAI,YAAY;AAChB,MAAI,OAAO;AACT,UAAM,eAAe,MAAM,eAAe,IAAI,mBAAmB;AACjE,gBAAY,MAAM,mBAAmB,IAAI,OAAgB,QAAQ,YAAY,CAAC;AAAA,EAChF;AACA,SAAO,KAAK,qBAAqB,WAAW,EAAE,QAAQ,MAAM,GAAG,SAAS,CAAC;AAC3E;AAGO,IAAM,2BAAkC,OAAO,KAAK,KAAK,KAAK,QAAQ;AAC3E,MAAI,IAAI,aAAa,WAAY,QAAO;AACxC,MAAI,CAAC,IAAI,QAAQ,cAAe,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AACvE,QAAM,OAAO,MAAM,IAAI,WAAW,KAAK,GAAG;AAC1C,MAAI,CAAC,KAAM,QAAO,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG;AACrD,QAAM,KAAK,IAAI,OAAO,GAAG;AACzB,MAAI,CAAC,MAAM,IAAI,QAAQ,IAAa,IAAI,EAAG,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AAClF,QAAM,CAAC,EAAE,QAAQ,QAAQ,GAAG,EAAE,MAAM,CAAC,IAAI,MAAM,QAAQ,IAAI;AAAA,IACzD,gBAAgB,IAAI,IAAI,QAAQ,IAAI,IAAI,QAAQ;AAAA,IAChD,cAAc,IAAI,IAAI,QAAQ,EAAE;AAAA,EAClC,CAAC;AACD,MAAI,IAAI,WAAW,OAAO;AACxB,UAAM,YAAY,qBAAqB,QAAQ,UAAU,SAAS,QAAQ;AAC1E,WAAO,KAAK;AAAA,MACV,QAAQ,SAAS,EAAE,UAAU,OAAO,UAAU,QAAQ,OAAO,QAAQ,UAAU,OAAO,SAAS,IAAI;AAAA,MACnG,SAAS,UAAU,EAAE,UAAU,QAAQ,UAAU,UAAU,QAAQ,SAAS,IAAI;AAAA,MAChF;AAAA,MACA,OAAO,MAAM,IAAI,CAAC,EAAE,IAAI,MAAM,YAAY,OAAO,OAAO,EAAE,IAAI,MAAM,YAAY,OAAO,EAAE;AAAA,MACzF,gBAAgB,IAAI,QAAQ,cAAc;AAAA,IAC5C,CAAC;AAAA,EACH;AACA,MAAI,IAAI,WAAW,MAAO,QAAO,KAAK,EAAE,OAAO,qBAAqB,GAAG,GAAG;AAC1E,MAAI,CAAC,IAAI,QAAQ,cAAc,eAAgB,QAAO,KAAK,EAAE,OAAO,8BAA8B,GAAG,GAAG;AACxG,QAAM,MAAM,MAAM,IAAI,KAAK;AAC3B,MAAI,IAAI,SAAS,SAAU,QAAO,KAAK,EAAE,OAAO,yBAAyB,GAAG,GAAG;AAC/E,MAAI;AACJ,MAAI;AACF,YAAQ,KAAK,MAAM,GAAG;AAAA,EACxB,QAAQ;AACN,WAAO,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;AAAA,EACjD;AACA,QAAM,mBAAmB,OAAO,MAAM,gBAAgB;AACtD,MAAI,CAAC,OAAO,UAAU,gBAAgB,KAAK,mBAAmB,GAAG;AAC/D,WAAO,KAAK,EAAE,OAAO,kDAAkD,GAAG,GAAG;AAAA,EAC/E;AACA,QAAM,MAAM,KAAK,IAAI;AACrB,QAAM,gBAAgB,mBAAmB,MAAM,UAAU,mBAAmB,GAAG,KAAK,IAAI,QAAQ,EAAE;AAClG,QAAM,UAAU,8BAA8B,eAAe;AAAA,IAC3D,YAAY;AAAA,IACZ,aAAa,IAAI,QAAQ;AAAA,IACzB;AAAA,IACA,aAAa,QAAQ,SAAS,SAAS,CAAC;AAAA,EAC1C,CAAC;AACD,MAAI,CAAC,QAAQ,GAAI,QAAO,KAAK,EAAE,OAAO,0BAA0B,QAAQ,QAAQ,OAAO,GAAG,GAAG;AAC7F,MAAI;AACF,UAAM,QAAQ,MAAM;AAAA,MAClB;AAAA,MACA,QAAQ;AAAA,MACR,IAAI;AAAA,MACJ;AAAA,MACA;AAAA,MACA,KAAK,SAAS,KAAK;AAAA,IACrB;AACA,WAAO,KAAK,EAAE,IAAI,MAAM,UAAU,MAAM,UAAU,UAAU,MAAM,SAAS,CAAC;AAAA,EAC9E,SAAS,OAAO;AACd,QAAI,iBAAiB,SAAS,MAAM,YAAY,oCAAoC;AAClF,aAAO,KAAK,EAAE,OAAO,+CAA+C,GAAG,GAAG;AAAA,IAC5E;AACA,WAAO,KAAK,EAAE,OAAO,oCAAoC,GAAG,GAAG;AAAA,EACjE;AACF;AAEA,SAAS,mBAAmB,OAAgB,UAAkB,aAAqB,OAAwB;AACzG,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,EAAG,QAAO;AACxE,SAAO;AAAA,IACL,GAAI;AAAA,IACJ,eAAe;AAAA,IACf;AAAA,IACA;AAAA,IACA,QAAQ,EAAE,MAAM,WAAW,MAAM;AAAA,EACnC;AACF;;;AMzOA,SAAS,0BAAAI,+BAA8B;AAiBvC,IAAMC,UAAS,CAAC,QAAiC,QAAgB,WAC/D,KAAK,EAAE,IAAI,OAAO,QAAQ,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC,EAAG,GAAG,MAAM;AAG5D,IAAM,wBAA+B,OAAO,KAAK,KAAK,KAAK,QAAQ;AACxE,MAAI,IAAI,WAAW,UAAU,IAAI,aAAa,sBAAuB,QAAO;AAC5E,QAAM,YAAY,IAAI,QAAQ;AAC9B,MAAI,CAAC,UAAW,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AACvD,QAAM,KAAK,IAAI,OAAO,GAAG;AACzB,QAAM,SAAS,MAAM,eAAe,IAAI,UAAU,UAAU;AAC5D,MAAI,CAAC,OAAQ,QAAO,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG;AACvD,QAAM,WAAW,MAAMC,wBAAuB,KAAK,EAAE,QAAQ,SAAS,CAAC,UAAU,QAAQ,EAAE,CAAC;AAC5F,MAAI,CAAC,SAAS,GAAI,QAAO,KAAK,EAAE,OAAO,gBAAgB,QAAQ,SAAS,OAAO,GAAG,GAAG;AACrF,MAAI;AACJ,MAAI;AACF,YAAQ,KAAK,MAAM,SAAS,IAAI;AAAA,EAClC,QAAQ;AACN,WAAOD,QAAO,oBAAoB,KAAK,CAAC,2BAA2B,CAAC;AAAA,EACtE;AACA,QAAM,SAAS,OAAO,MAAM,WAAW,WAAW,MAAM,SAAS;AACjE,QAAM,UAAU,+BAA+B,MAAM,QAAQ;AAC7D,MAAI,CAAC,QAAQ,GAAI,QAAOA,QAAO,oBAAoB,KAAK,QAAQ,MAAM;AACtE,QAAM,WAAW,QAAQ;AACzB,MAAI,SAAS,OAAO,UAAU,UAAU,SAAU,QAAOA,QAAO,gBAAgB,GAAG;AACnF,MAAI,SAAS,OAAO,cAAc,IAAI,QAAQ,GAAI,QAAOA,QAAO,gBAAgB,GAAG;AACnF,MAAI,SAAS,OAAO,gBAAgB,IAAI,SAAU,QAAOA,QAAO,qBAAqB,GAAG;AACxF,MAAI,CAAC,UAAU,MAAM,oBAAoB,QAAQ,MAAM,OAAQ,QAAOA,QAAO,kBAAkB,GAAG;AAClG,QAAM,SAAS,MAAM,4BAA4B,IAAI,UAAU,UAAU,IAAI,QAAQ,IAAI,IAAI,QAAQ;AACrG,MAAI,UAAU,SAAS,WAAW,OAAO,SAAU,QAAOA,QAAO,kBAAkB,GAAG;AACtF,MAAI,UAAU,SAAS,aAAa,OAAO,UAAU;AACnD,QAAI,OAAO,WAAW,OAAQ,QAAOA,QAAO,wBAAwB,GAAG;AACvE,WAAO,KAAK;AAAA,MACV,IAAI;AAAA,MACJ,QAAQ,EAAE,WAAW,IAAI,QAAQ,IAAI,aAAa,IAAI,SAAS;AAAA,MAC/D,UAAU,OAAO;AAAA,MACjB,QAAQ,OAAO;AAAA,MACf,QAAQ;AAAA,MACR,gBAAgB,OAAO;AAAA,IACzB,CAAC;AAAA,EACH;AACA,QAAM,aAAa,KAAK,IAAI;AAC5B,MAAI;AACF,UAAM,2BAA2B,IAAI,EAAE,QAAQ,SAAS,GAA6B,QAAQ,UAAU;AAAA,EACzG,QAAQ;AACN,WAAOA,QAAO,0BAA0B,GAAG;AAAA,EAC7C;AACA,SAAO,KAAK;AAAA,IACV,IAAI;AAAA,IACJ,QAAQ,EAAE,WAAW,IAAI,QAAQ,IAAI,aAAa,IAAI,SAAS;AAAA,IAC/D,UAAU,SAAS;AAAA,IACnB;AAAA,IACA,QAAQ;AAAA,IACR,gBAAgB;AAAA,EAClB,CAAC;AACH;;;ACjEA,eAAe,KAAK,KAAc,KAA2B,KAA2B;AACtF,QAAM,QAAQ,IAAI,OAAO,GAAG;AAC5B,QAAM,OAAO,MAAM,IAAI,WAAW,KAAK,GAAG;AAC1C,MAAI,CAAC,KAAM,QAAO,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG;AACrD,MAAI,CAAE,MAAM,IAAI,QAAQ,OAAO,IAAI,EAAI,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AAC9E,SAAO,EAAE,IAAI,OAA+B,KAAK;AACnD;AAGO,IAAM,6BAAoC,OAAO,KAAK,KAAK,KAAK,QAAQ;AAC7E,MAAI,IAAI,aAAa,iCAAiC,IAAI,WAAW,OAAO;AAC1E,UAAM,OAAO,MAAM,KAAK,KAAK,KAAK,GAAG;AACrC,QAAI,gBAAgB,SAAU,QAAO;AACrC,UAAM,SAAS,MAAM,KAAK,GAAG,MAAM,EAAE,iBAAiB,EAAE,GAAG;AAAA,MACzD,OAAO,EAAE,UAAU,IAAI,QAAQ,GAAG;AAAA,MAAG,OAAO,EAAE,WAAW,OAAO;AAAA,MAAG,OAAO;AAAA,IAC5E,EAAE,EAAE,CAAC;AACL,UAAM,SAAS,MAAM,QAAQ,OAAO,eAAe,IAC/C,OAAO,gBAAgB,IAAI,CAAC,SAAS,EAAE,GAAG,KAAK,iBAAiB,OAAU,EAAE,IAC5E,CAAC;AACL,WAAO,KAAK,EAAE,OAAO,CAAC;AAAA,EACxB;AAEA,MAAI,IAAI,aAAa,iCAAiC,IAAI,WAAW,QAAQ;AAC3E,UAAM,OAAO,MAAM,KAAK,KAAK,KAAK,GAAG;AACrC,QAAI,gBAAgB,SAAU,QAAO;AACrC,QAAI;AACJ,QAAI;AACF,aAAO,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC;AAAA,IACpC,QAAQ;AACN,aAAO,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;AAAA,IACjD;AACA,UAAM,QAAQ,OAAO,KAAK,UAAU,WAAW,KAAK,MAAM,KAAK,IAAI;AACnE,UAAM,kBAAkB,sBAAsB,KAAK;AACnD,QAAI,CAAC,aAAa,eAAe,EAAG,QAAO,KAAK,EAAE,OAAO,sBAAsB,GAAG,GAAG;AACrF,UAAM,WAAW,KAAK,YAAY;AAClC,QAAI,aAAa,qBAAqB,aAAa,qBAAqB;AACtE,aAAO,KAAK,EAAE,OAAO,wDAAwD,GAAG,GAAG;AAAA,IACrF;AACA,UAAM,OAAO,OAAO,KAAK,SAAS,WAAW,KAAK,KAAK,KAAK,IAAI;AAChE,QAAI,KAAK,SAAS,IAAO,QAAO,KAAK,EAAE,OAAO,mBAAmB,GAAG,GAAG;AACvE,UAAM,YAAY,KAAK,cAAc,UAAa,KAAK,cAAc,OACjE,SACA,OAAO,KAAK,SAAS;AACzB,QAAI,cAAc,WAAc,CAAC,OAAO,SAAS,SAAS,KAAK,aAAa,KAAK,IAAI,IAAI;AACvF,aAAO,KAAK,EAAE,OAAO,6CAA6C,GAAG,GAAG;AAAA,IAC1E;AACA,UAAM,gBAAgB,OAAO,WAAW;AACxC,UAAM,KAAK,mBAAmB,IAAI,QAAQ,EAAE,IAAI,aAAa;AAC7D,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,QAAQ,KAAK,KAAK,SAAS,KAAK,KAAK;AAC3C,UAAM,KAAK,GAAG,SAAS,CAAC,EAAE,GAAG,UAAU,IAAI,mBAAmB,IAAI,OAAO;AAAA,MACvE;AAAA,MACA;AAAA,MACA,aAAa;AAAA,MACb,UAAU,IAAI,QAAQ;AAAA,MACtB,UAAU,IAAI,QAAQ;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,MACvB,GAAI,cAAc,SAAY,EAAE,UAAU,IAAI,CAAC;AAAA,MAC/C,QAAQ;AAAA,MACR;AAAA,MACA,WAAW;AAAA,MACX,WAAW;AAAA,MACX,WAAW;AAAA,IACb,EAAE,CAAC,GAAG,EAAE,YAAY,0BAA0B,aAAa,GAAG,CAAC;AAC/D,WAAO,KAAK,EAAE,OAAO,EAAE,IAAI,eAAe,aAAa,SAAS,OAAO,UAAU,QAAQ,MAAM,WAAW,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC,GAAI,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC,EAAG,EAAE,GAAG,GAAG;AAAA,EACnL;AAEA,QAAM,SAAS;AACf,MAAI,WAAW;AACf,MAAI,IAAI,SAAS,WAAW,MAAM,GAAG;AACnC,QAAI;AACF,iBAAW,mBAAmB,IAAI,SAAS,MAAM,OAAO,MAAM,CAAC;AAAA,IACjE,QAAQ;AACN,iBAAW;AAAA,IACb;AAAA,EACF;AACA,MAAI,0CAA0C,KAAK,QAAQ,KAAK,IAAI,WAAW,UAAU;AACvF,UAAM,OAAO,MAAM,KAAK,KAAK,KAAK,GAAG;AACrC,QAAI,gBAAgB,SAAU,QAAO;AACrC,UAAM,KAAK;AACX,UAAM,QAAQ,MAAM,KAAK,GAAG,MAAM,EAAE,iBAAiB,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC;AACzF,UAAM,MAAM,MAAM,QAAQ,MAAM,eAAe,IAAI,MAAM,gBAAgB,CAAC,IAAI;AAC9E,QAAI,CAAC,OAAO,IAAI,aAAa,IAAI,QAAQ,MAAM,IAAI,gBAAgB,QAAS,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AACnH,QAAI,IAAI,WAAW,KAAM,QAAO,KAAK,EAAE,IAAI,MAAM,UAAU,KAAK,CAAC;AACjE,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,QAAQ,KAAK,KAAK,SAAS,KAAK,KAAK;AAC3C,UAAM,KAAK,GAAG,SAAS,CAAC,EAAE,GAAG,UAAU,IAAI,mBAAmB,IAAI,OAAO;AAAA,MACvE,QAAQ;AAAA,MACR;AAAA,MACA,WAAW;AAAA,MACX,WAAW;AAAA,MACX,WAAW;AAAA,IACb,EAAE,CAAC,GAAG,EAAE,YAAY,0BAA0B,EAAE,GAAG,CAAC;AACpD,WAAO,KAAK,EAAE,IAAI,MAAM,UAAU,MAAM,CAAC;AAAA,EAC3C;AACA,SAAO;AACT;;;ACjGA,SAAS,sBAAsB,oBAAoB;AAyBnD,SAAS,QAAQ,KAAsB;AACrC,MAAI,OAAO,OAAO,QAAQ,UAAU;AAClC,UAAM,OAAQ,IAA2B;AACzC,QAAI,OAAO,SAAS,SAAU,QAAO;AAAA,EACvC;AACA,SAAO;AACT;AAEA,SAAS,aAAa,KAAsB;AAG1C,SAAO,aAAa,EAAE,OAAO,IAAI,aAAa,KAAK,IAAI,UAAU,YAAY,IAAI,cAAc,UAAU,IAAI,cAAc,CAAC;AAC9H;AAEA,eAAe,SAAS,IAAe,IAAY,GAAsD;AACvG,QAAM,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC;AAC7C,QAAME,QAAO,IAAI,EAAE;AACnB,SAAO,MAAM,QAAQA,KAAI,IAAIA,MAAK,CAAC,IAAI;AACzC;AAEA,eAAe,aAAa,KAAU,KAA6E;AACjH,QAAM,EAAE,MAAM,GAAG,IAAI,WAAW,KAAK,IAAI,GAAG,IAAI,UAAU;AAC1D,QAAM,KAAK,MAAM,IAAI,aAAa,SAAS,EAAE,SAAS,MAAM,SAAS,GAAG,CAAC;AACzE,SAAO,qBAAqB,GAAG,MAAM;AAAA,IACnC,MAAM,GAAG;AAAA,IACT,IAAI,GAAG;AAAA,IACP,UAAU,IAAI;AAAA,IACd,aAAa,IAAI;AAAA,IACjB,eAAe,EAAE,MAAM,CAAC,GAAG,IAAI,IAAI,GAAG,WAAW,IAAI,WAAW,SAAS,IAAI,QAAQ;AAAA,IACrF,aAAa,IAAI,iBAAiB;AAAA,EACpC,CAAC;AACH;AAEA,eAAe,SAAS,KAAc,KAAiB,KAAuC;AAC5F,MAAI;AACJ,MAAI;AACF,WAAO,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC;AAAA,EACpC,QAAQ;AACN,WAAO,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;AAAA,EACjD;AACA,QAAM,gBAAgB,OAAO,KAAK,kBAAkB,WAAW,KAAK,gBAAgB;AACpF,QAAM,UAAU,OAAO,KAAK,OAAO;AACnC,MAAI,CAAC,iBAAiB,CAAC,OAAO,SAAS,OAAO,EAAG,QAAO,KAAK,EAAE,OAAO,qCAAqC,GAAG,GAAG;AAEjH,QAAM,KAAK,IAAI,OAAO,GAAG;AACzB,QAAM,MAAM,MAAM,SAAS,IAAI,gBAAgB,EAAE,OAAO,EAAE,IAAI,cAAc,GAAG,OAAO,EAAE,CAAC;AACzF,MAAI,CAAC,IAAK,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AACjD,QAAM,SAAS,OAAO,IAAI,UAAU,EAAE;AACtC,MAAI,CAAC,QAAQ,QAAQ,IAAI,QAAQ,QAAQ,EAAG,QAAO,KAAK,EAAE,OAAO,4BAA4B,MAAM,IAAI,GAAG,GAAG;AAE7G,QAAM,QAAQ,MAAM,SAAS,IAAI,UAAU,EAAE,OAAO,EAAE,IAAI,OAAO,IAAI,WAAW,IAAI,QAAQ,EAAE,EAAE,GAAG,OAAO,EAAE,CAAC;AAC7G,MAAI,CAAC,MAAO,QAAO,KAAK,EAAE,OAAO,kBAAkB,GAAG,GAAG;AACzD,QAAM,MAAM,kBAAkB,MAAM,cAA+C;AACnF,QAAM,QAAQ,WAAW,SAAS,IAAI,WAAW;AACjD,QAAM,MAAM,aAAa,GAAG;AAG5B,MAAI;AACJ,MAAI;AACF,YAAQ,MAAM,aAAa,KAAK,GAAG;AAAA,EACrC,SAAS,KAAK;AACZ,WAAO,KAAK,EAAE,OAAO,0BAA0B,MAAM,QAAQ,GAAG,EAAE,GAAG,GAAG;AAAA,EAC1E;AACA,MAAI,CAAC,gBAAgB,OAAO,OAAO,EAAG,QAAO,KAAK,EAAE,OAAO,4BAA4B,MAAM,4BAA4B,GAAG,GAAG;AAE/H,QAAM,UAAU,cAAc,IAAI,iBAAiB,EAAE,WAAW,IAAI,WAAqB,UAAU,IAAI,SAAmB,CAAC;AAC3H,QAAM,WAAY,MAAM,SAAS,IAAI,YAAY;AAAA,IAC/C,OAAO,EAAE,eAAe,QAAQ,YAAY;AAAA,IAC5C,OAAO,EAAE,WAAW,OAAO;AAAA,IAC3B,OAAO;AAAA,EACT,CAAC;AACD,QAAM,WAAW,gBAAgB,QAAQ;AAEzC,MAAI,UAAyB;AAC7B,MAAI,WAA0B;AAC9B,MAAI;AACJ,MAAI;AACF,QAAI,SAAS,cAAc,SAAS,SAAS;AAE3C,YAAM,IAAI,QAAQ,WAAW,SAAS,SAAS;AAAA,QAC7C,gBAAgB,WAAW,OAAO,UAAU,EAAE,CAAC,eAAe,OAAO,IAAI,KAAK;AAAA,QAC9E;AAAA,QACA;AAAA,MACF,CAAC;AACD,gBAAW,UAAU,WAAkC;AACvD,iBAAY,UAAU,YAAmC;AACzD,kBAAY,EAAE,GAAG,UAAU,IAAI,YAAY,IAAI,OAAO,UAAU,EAAE,GAAG,OAAO,wBAAwB,SAAS,KAAK,EAAE;AAAA,IACtH,OAAO;AACL,YAAM,EAAE,QAAQ,IAAI,MAAM,IAAI,QAAQ;AAAA,QACpC,EAAE,SAAS,SAAS,OAAO,WAAW,CAAC,OAAO,IAAI,KAAK,CAAC,GAAG,UAAU,IAAI,UAAU,MAAM,KAAK;AAAA,QAC9F,EAAE,gBAAgB,oBAAoB,aAAa,EAAE;AAAA,MACvD;AACA,gBAAU,QAAQ,WAAW;AAC7B,iBAAW,QAAQ,YAAY;AAC/B,YAAM,YAAY,OAAO,WAAW;AACpC,kBAAY;AAAA,QACV,GAAG;AAAA,QACH,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,OAAO,iBAAiB;AAAA,UACtB;AAAA,UACA;AAAA,UACA,SAAS,OAAO,MAAM,EAAE;AAAA,UACxB;AAAA,UACA;AAAA,UACA,UAAU,IAAI;AAAA,UACd,eAAe,QAAQ;AAAA,UACvB,SAAS,QAAQ;AAAA,UACjB,UAAU,QAAQ;AAAA,UAClB,WAAW,KAAK,IAAI;AAAA,QACtB,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,OAAO,QAAQ,GAAG;AAExB,QAAI,SAAS,4BAA6B,QAAO,KAAK,EAAE,OAAO,4BAA4B,KAAK,GAAG,GAAG;AACtG,WAAO,KAAK,EAAE,OAAO,kBAAkB,KAAK,GAAG,GAAG;AAAA,EACpD;AAGA,QAAM,eAAe,yBAAyB,QAAQ,SAAS,QAAQ;AACvE,QAAM,QAAc,EAAE,GAAG,UAAU,IAAI,gBAAgB,IAAI,eAAe,OAAO,aAAa;AAC9F,QAAM,GAAG,SAAS,CAAC,WAAW,KAAK,CAAC;AAMpC,QAAM,SAAS,EAAE,GAAG,KAAK,GAAG,aAAa;AACzC,QAAM,qBAAqB,QAAQ,IAAI,GAAG,GAAG,EAAE,KAAK,QAAQ,OAAO,OAAO,OAAO,UAAU,EAAE,EAAE,CAAC,EAAE,MAAM,MAAM,MAAS;AAGvH,MAAI,OAAO,IAAI,UAAU,YAAY,IAAI,OAAO;AAC9C,UAAM;AAAA,MACJ,EAAE,IAAI,SAAS,IAAI,UAAU,QAAQ,IAAI,YAAY,MAAM,IAAI,YAAY,KAAK,MAAM,KAAK,IAAI,GAAG,OAAO,MAAM,OAAO,WAAW,EAAE;AAAA,MACnI,EAAE,OAAO,eAAe,KAAK,GAAG,UAAU,aAAa,IAAI,IAAI,OAAO,MAAM,EAAE,WAAW,OAAO,IAAI,aAAa,EAAE,EAAE,GAAG,WAAW,QAAQ,aAAa,IAAI,cAAc;AAAA,IAC5K,EAAE,MAAM,MAAM,MAAS;AAAA,EACzB;AAEA,SAAO,KAAK,EAAE,IAAI,MAAM,SAAS,OAAO,SAAS,aAAa,SAAS,WAAW,CAAC;AACrF;AAGO,IAAM,iBAAwB,OAAO,KAAK,KAAK,KAAK,QAAQ;AACjE,MAAI,IAAI,QAAQ,SAAS,UAAW,QAAO;AAE3C,MAAI,IAAI,WAAW,SAAS,IAAI,aAAa,uBAAuB;AAClE,UAAM,KAAK,IAAI,OAAO,GAAG;AACzB,UAAM,QAAQ,MAAM,SAAS,IAAI,UAAU,EAAE,OAAO,EAAE,IAAI,IAAI,aAAa,IAAI,OAAO,KAAK,IAAI,QAAQ,GAAG,GAAG,OAAO,EAAE,CAAC;AACvH,QAAI,CAAC,MAAO,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AACnD,UAAM,MAAM,kBAAkB,MAAM,cAA+C;AACnF,QAAI;AACF,YAAM,QAAQ,MAAM,aAAa,aAAa,GAAG,GAAG,GAAG;AACvD,aAAO,KAAK,EAAE,iBAAiB,MAAM,UAAU,IAAI,UAAU,aAAa,IAAI,aAAa,MAAM,CAAC;AAAA,IACpG,SAAS,KAAK;AACZ,aAAO,KAAK,EAAE,iBAAiB,OAAO,MAAM,QAAQ,GAAG,EAAE,CAAC;AAAA,IAC5D;AAAA,EACF;AAEA,MAAI,IAAI,WAAW,UAAU,IAAI,aAAa,sBAAsB;AAClE,WAAO,SAAS,KAAK,KAAK,GAAG;AAAA,EAC/B;AAEA,SAAO;AACT;;;AClMA,SAAS,YAAY,6BAA6B;AAyB3C,SAAS,kBAAkB,SAAyB;AACzD,SAAO,UAAU,OAAO;AAC1B;AAyBO,SAAS,mBAAmB,KAA+E;AAChH,QAAM,SAAS,CAAC,MACd,KAAK,OAAO,MAAM,WAAa,EAA8B,YAAwC,CAAC,IAAI,CAAC;AAC7G,QAAM,OAAO,CAAC,MACZ,OAAO,EAAE,kBAAkB,WAAW,EAAE,gBAAgB;AAC1D,QAAM,gBACJ,KAAK,OAAO,GAAG,CAAC,KAAK,KAAK,OAAO,IAAI,oBAAoB,CAAC,KAAK,KAAK,OAAQ,IAAI,QAAgD,oBAAoB,CAAC;AACvJ,QAAM,aAAa,OAAO,IAAI,aAAa,WAAW,IAAI,WAAW;AACrE,SAAO,EAAE,GAAI,gBAAgB,EAAE,cAAc,IAAI,CAAC,GAAI,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC,EAAG;AAC9F;AAGO,SAAS,YAAY,KAAmF;AAC7G,QAAM,SAAS,CAAC,UACd,SAAS,OAAO,UAAU,WAAa,MAAkC,YAAwC,CAAC,IAAI,CAAC;AACzH,QAAM,OAAO,CAAC,aACZ,OAAO,SAAS,iBAAiB,WAAW,SAAS,eAAe;AACtE,QAAM,SAAS,IAAI;AACnB,QAAM,eAAe,IAAI,wBAAwB,QAAQ;AACzD,QAAM,eAAe,KAAK,OAAO,GAAG,CAAC,KAAK,KAAK,OAAO,YAAY,CAAC;AACnE,QAAM,iBAAiB,OAAO,IAAI,iBAAiB,WAC/C,IAAI,eACJ,OAAQ,cAAsD,iBAAiB,WAC7E,OAAQ,aAAyC,YAAY,IAC7D;AACN,SAAO,EAAE,GAAI,eAAe,EAAE,aAAa,IAAI,CAAC,GAAI,kBAAkB,kBAAkB,OAAO,IAAI,MAAM,EAAE,EAAE;AAC/G;AAKO,SAAS,sBAAsB,OAAkC;AACtE,QAAM,MAAM,MAAM,MAAM,UAAU,CAAC;AACnC,QAAM,OAAO,YAAY,GAAG;AAC5B,MAAI,KAAK,cAAc;AACrB,QAAI,MAAM,SAAS,8BACd,MAAM,SAAS,kBAAkB,IAAI,mBAAmB,uBAAwB;AACnF,aAAO,EAAE,MAAM,aAAa,cAAc,KAAK,cAAc,kBAAkB,KAAK,iBAAiB;AAAA,IACvG;AACA,QAAI,MAAM,SAAS,kBAAmB,QAAO,EAAE,MAAM,gBAAgB,cAAc,KAAK,cAAc,QAAQ,WAAW;AACzH,QAAI,MAAM,SAAS,gCAAiC,QAAO,EAAE,MAAM,gBAAgB,cAAc,KAAK,cAAc,QAAQ,WAAW;AACvI,WAAO,EAAE,MAAM,WAAW,MAAM,MAAM,KAAK;AAAA,EAC7C;AACA,QAAM,MAAM,mBAAmB,GAAG;AAClC,UAAQ,MAAM,MAAM;AAAA,IAClB,KAAK,gBAAgB;AACnB,YAAM,QAAU,IAAI,OAA+C,QAAuD,CAAC;AAC3H,YAAM,YAAa,MAAM,CAAC,GAAG,QAAgD;AAC7E,YAAM,YAAY,OAAO,cAAc,WAAW,YAAY,MAAO;AACrE,YAAM,OAAO,IAAI,mBAAmB,wBAAwB,kBAAkB;AAC9E,aAAO,EAAE,MAAM,GAAG,KAAK,GAAI,cAAc,SAAY,EAAE,UAAU,IAAI,CAAC,EAAG;AAAA,IAC3E;AAAA,IACA,KAAK;AACH,aAAO,EAAE,MAAM,YAAY,GAAG,IAAI;AAAA,IACpC,KAAK;AACH,aAAO,EAAE,MAAM,YAAY,GAAG,IAAI;AAAA,IACpC;AACE,aAAO,EAAE,MAAM,WAAW,MAAM,MAAM,KAAK;AAAA,EAC/C;AACF;AAOO,SAAS,kBAAkB,eAAuB,WAA6E;AACpI,SAAO;AAAA,IACL,GAAI,kBAAkB,cAAc,EAAE,QAAQ,uBAAgC,IAAI,CAAC;AAAA,IACnF,GAAI,cAAc,SAAY,EAAE,UAAU,IAAI,CAAC;AAAA,EACjD;AACF;AAGO,SAAS,aAAa,WAA0C;AACrE,SAAO,EAAE,UAAU;AACrB;AAIO,SAAS,gBAAwC;AACtD,SAAO,EAAE,QAAQ,WAAW;AAC9B;AAGO,SAAS,gBAAoC;AAClD,SAAO,EAAE,UAAU,KAAK;AAC1B;;;AC1IA,SAAS,eAAe,yBAAAC,8BAAuD;AA2C/E,eAAsB,WACpB,IACA,QACA,MACA,QACA,gBACuB;AACvB,SAAO;AAAA,IACL,EAAE,WAAW,GAAG;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA,iBAAiB,EAAE,eAAe,IAAI,CAAC;AAAA,EACzC;AACF;AAEA,SAAS,KAAK,IAAY,GAAwB;AAChD,QAAM,MAAM,IAAI,MAAM,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE;AACxD,MAAI,OAAO;AACX,QAAM;AACR;AAEA,SAAS,eAAe,KAAkD;AACxE,QAAM,MAAM,IAAI;AAChB,QAAM,eAAe,KAAK;AAC1B,QAAM,SAAS,KAAK;AACpB,QAAM,SAAS,cAAc,iBAAiB,QAAQ;AACtD,SAAO,OAAO,WAAW,WAAW,SAAS;AAC/C;AAEA,SAAS,cAAc,WAAuC;AAC5D,MAAI,CAAC,WAAW;AACd,UAAM,MAAM,IAAI,MAAM,2BAA2B;AACjD,QAAI,OAAO;AACX,UAAM;AAAA,EACR;AACA,SAAO;AACT;AAKO,SAAS,qBAAqB,QAA0E;AAC7G,QAAM,EAAE,WAAW,cAAc,IAAI;AACrC,SAAO;AAAA,IACL,MAAM,mBAAmB,OAAO;AAC9B,YAAM,KAAK,cAAc,SAAS;AAClC,YAAM,OAAO,EAAE,eAAe,MAAM,eAAe,SAAS,MAAM,SAAS,OAAO,MAAM,MAAM;AAC9F,UAAI,aAAa,MAAM;AACvB,UAAI,CAAC,YAAY;AACf,cAAM,OAAO,MAAM;AAAA,UACjB;AAAA,UACA;AAAA,UACA;AAAA,UACA,EAAE,OAAO,MAAM,OAAO,MAAM,MAAM,MAAM,UAAU,KAAK;AAAA,UACvD,OAAO,MAAM,aAAa;AAAA,QAC5B;AACA,YAAI,CAAC,KAAK,GAAI,MAAK,mBAAmB,IAAI;AAC1C,qBAAa,OAAO,KAAK,KAAK,EAAE;AAAA,MAClC;AACA,YAAM,MAAM,MAAM;AAAA,QAChB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,UACE,UAAU;AAAA,UACV,mBAAmB,MAAM;AAAA,UACzB,kBAAkB;AAAA,UAClB,iDAAiD;AAAA,UACjD,6CAA6C;AAAA,UAC7C,aAAa;AAAA,UACb,UAAU;AAAA,QACZ;AAAA;AAAA;AAAA,QAGA,OAAO,MAAM,aAAa;AAAA,MAC5B;AACA,UAAI,CAAC,IAAI,GAAI,MAAK,uBAAuB,GAAG;AAC5C,YAAMC,gBAAe,eAAe,IAAI,IAAI;AAC5C,UAAI,CAACA,cAAc,MAAK,4CAA4C,GAAG;AACvE,aAAO,EAAE,YAAY,gBAAgB,OAAO,IAAI,KAAK,EAAE,GAAG,cAAAA,cAAa;AAAA,IACzE;AAAA,IAEA,MAAM,cAAc,SAAS,WAAW;AACtC,UAAI,CAAC,iBAAiB,CAAE,MAAMC,uBAAsB,SAAS,WAAW,aAAa,GAAI;AACvF,eAAO,EAAE,IAAI,OAAO,QAAQ,gBAAgB;AAAA,MAC9C;AACA,YAAM,QAAQ,KAAK,MAAM,OAAO;AAChC,aAAO,EAAE,IAAI,MAAM,SAAS,MAAM,IAAI,OAAO,sBAAsB,KAAK,EAAE;AAAA,IAC5E;AAAA,IAEA,MAAM,OAAO,OAAO;AAClB,YAAM,KAAK,cAAc,SAAS;AAClC,YAAM,UAAU,MAAM,WAAW,IAAI,OAAO,eAAe,EAAE,UAAU,MAAM,YAAY,OAAO,IAAI,CAAC;AACrG,UAAI,CAAC,QAAQ,GAAI,MAAK,gBAAgB,OAAO;AAC7C,YAAMC,QAAQ,QAAQ,KAAK,QAAuD,CAAC;AACnF,YAAM,OAAOA,MAAK,OAAO,CAAC,MAAM,EAAE,WAAW,eAAe,EAAE,aAAa,IAAI;AAC/E,YAAM,SAAS,KAAK,KAAK,SAAS,CAAC;AACnC,UAAI,CAAC,QAAQ;AACX,cAAM,MAAM,IAAI,MAAM,0BAA0B;AAChD,YAAI,OAAO;AACX,cAAM;AAAA,MACR;AACA,YAAM,SAAS,MAAM,WAAW,IAAI,QAAQ,eAAe,EAAE,QAAQ,OAAO,OAAO,EAAE,EAAE,CAAC;AACxF,UAAI,CAAC,OAAO,GAAI,MAAK,UAAU,MAAM;AACrC,YAAM,SAAS,MAAM,WAAW,IAAI,UAAU,qBAAqB,MAAM,cAAc,EAAE;AACzF,YAAM,SAAS,OAAO,KAAK;AAC3B,aAAO,EAAE,eAAe,OAAO,WAAW,WAAW,SAAS,MAAM,sBAAsB,OAAO,GAAG;AAAA,IACtG;AAAA,EACF;AACF;;;AC7JO,IAAM,oBAAoB;AAC1B,IAAM,kBAAkB;AAE/B,IAAM,YAAY,CAAC,UAA8B;AAC/C,MAAI,SAAS;AACb,aAAW,QAAQ,MAAO,WAAU,OAAO,aAAa,IAAI;AAC5D,SAAO,KAAK,MAAM,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,QAAQ,EAAE;AAChF;AAGO,SAAS,iBAAyB;AACvC,QAAM,QAAQ,IAAI,WAAW,eAAe;AAC5C,SAAO,gBAAgB,KAAK;AAC5B,SAAO,OAAO,iBAAiB,IAAI,UAAU,KAAK,CAAC;AACrD;AAGA,eAAsB,aAAa,WAAmB,MAAc,UAAU,mBAAoC;AAChH,QAAM,QAAQ,IAAI,YAAY,EAAE,OAAO,aAAa,OAAO,IAAI,SAAS,IAAI,IAAI,EAAE;AAClF,SAAO,UAAU,IAAI,WAAW,MAAM,OAAO,OAAO,OAAO,WAAW,KAAK,CAAC,CAAC;AAC/E;AAGA,eAAsB,oBAAoB,WAAmB,WAAoC;AAC/F,QAAM,QAAQ,IAAI,YAAY,EAAE,OAAO,kBAAkB,SAAS,IAAI,SAAS,EAAE;AACjF,SAAO,UAAU,IAAI,WAAW,MAAM,OAAO,OAAO,OAAO,WAAW,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,EAAE;AAC5F;;;ACrBA,IAAM,QAAQ,CAAC,UAAoC,MAAM,QAAQ,KAAK,IAAI,MAAM,CAAC,IAAuB;AAiBxG,eAAsB,gBAAgB,WAAqF;AACzH,QAAM,OAAO,eAAe;AAC5B,SAAO,EAAE,MAAM,UAAU,MAAM,aAAa,WAAW,IAAI,GAAG,aAAa,kBAAkB;AAC/F;AAGA,eAAsB,eACpB,IACA,QACA,UACA,KACmE;AACnE,QAAM,WAAW,OAAO,MAAM,GAAG,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,OAAO,GAAG,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG,UAAU;AACvH,MAAI,SAAU,QAAO,EAAE,SAAS,OAAO,SAAS,EAAE,GAAG,SAAS,OAAO,SAAS,OAAO,GAAG,WAAW,KAAK;AACxG,QAAM,QAAQ,OAAO;AACrB,QAAM,UAAU,cAAc,OAAO,EAAE;AACvC,QAAM,UAAU,cAAc,OAAO,EAAE;AACvC,QAAM,SAAS;AAAA,IACb,WAAW,OAAO;AAAA,IAAW,SAAS,OAAO;AAAA,IAC7C,GAAI,OAAO,yBAAyB,EAAE,wBAAwB,OAAO,uBAAuB,IAAI,CAAC;AAAA,IACjG,GAAI,OAAO,kBAAkB,EAAE,iBAAiB,OAAO,gBAAgB,IAAI,CAAC;AAAA,IAC5E,0BAA0B,OAAO;AAAA,EACnC;AACA,QAAM,MAAc;AAAA,IAClB,EAAE,GAAG,UAAU,IAAI,cAAc,IAAI,SAAS,OAAO;AAAA,MACnD,IAAI;AAAA,MAAS,UAAU,OAAO;AAAA,MAAI,GAAG;AAAA,MAAQ,aAAa,OAAO;AAAA,MACjE,eAAe;AAAA,MAAO,eAAe,OAAO;AAAA,MAAe,iBAAiB,SAAS;AAAA,MACrF,kBAAkB,SAAS;AAAA,MAAU,aAAa,MAAM;AAAA,MAAY,UAAU,MAAM;AAAA,MACpF,aAAa,MAAM;AAAA,MAAa,WAAW;AAAA,IAC7C,EAAE;AAAA,IACF,EAAE,GAAG,UAAU,IAAI,cAAc,IAAI,SAAS,OAAO;AAAA,MACnD,IAAI;AAAA,MAAS;AAAA,MAAS,UAAU,OAAO;AAAA,MAAI,GAAG;AAAA,MAAQ,QAAQ,MAAM;AAAA,MACpE,UAAU,OAAO;AAAA,MAAU,aAAa,OAAO;AAAA,MAAa,eAAe;AAAA,MAAG,cAAc,OAAO;AAAA,MACnG,eAAe,MAAM,MAAM,0BAA0B;AAAA,MACrD,cAAc;AAAA,MAAG,wBAAwB;AAAA,MAAK,QAAQ;AAAA,MAAW,WAAW;AAAA,IAC9E,EAAE;AAAA,IACF,EAAE,GAAG,UAAU,IAAI,uBAAuB,IAAI,OAAO,IAAI,OAAO,EAAE,QAAQ,QAAQ,QAAQ,KAAK,SAAS,WAAW,IAAI,EAAE;AAAA,EAC3H;AACA,MAAI,OAAO,uBAAwB,KAAI,KAAK;AAAA,IAC1C,GAAG;AAAA,IAAU,IAAI;AAAA,IAAgB,IAAI,OAAO;AAAA,IAC5C,OAAO,EAAE,YAAY,KAAK,aAAa,QAAQ;AAAA,EACjD,CAAC;AACD,MAAI;AACF,UAAM,SAAS,MAAM,GAAG,SAAS,KAAK;AAAA,MACpC,YAAY,aAAa,SAAS,OAAO;AAAA,MACzC,QAAQ,CAAC,EAAE,IAAI,uBAAuB,IAAI,OAAO,IAAI,QAAQ,MAAM,QAAQ,EAAE,QAAQ,iBAAiB,EAAE,CAAC;AAAA,IAC3G,CAAC;AACD,WAAO,EAAE,SAAS,SAAS,WAAW,OAAO,UAAU;AAAA,EACzD,QAAQ;AACN,UAAM,QAAQ,OAAO,MAAM,GAAG,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,OAAO,GAAG,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG,UAAU;AACpH,QAAI,MAAO,QAAO,EAAE,SAAS,OAAO,MAAM,EAAE,GAAG,SAAS,OAAO,MAAM,OAAO,GAAG,WAAW,KAAK;AAC/F,UAAM,IAAI,MAAM,wBAAwB;AAAA,EAC1C;AACF;AAGO,SAAS,gBAAgBC,OAAsB,KAA+B;AACnF,SAAOA,MAAK,IAAI,CAAC,QAAQ;AACvB,UAAM,SAAS,OAAO,IAAI,UAAU,SAAS;AAC7C,UAAM,SAAS,WAAW,aAAa,OAAO,IAAI,aAAa,KAAK,MAAM,YAAY;AACtF,WAAO;AAAA,MACL,IAAI,OAAO,IAAI,EAAE;AAAA,MAAG,SAAS,OAAO,IAAI,OAAO;AAAA,MAAG;AAAA,MAClD,WAAW,OAAO,IAAI,SAAS;AAAA,MAAG,eAAe,OAAO,IAAI,aAAa;AAAA,MACzE,GAAI,OAAO,IAAI,eAAe,WAAW,EAAE,YAAY,IAAI,WAAW,IAAI,CAAC;AAAA,MAC3E,GAAI,OAAO,IAAI,cAAc,WAAW,EAAE,WAAW,IAAI,UAAU,IAAI,CAAC;AAAA,IAC1E;AAAA,EACF,CAAC;AACH;AAGA,eAAsB,gBAAgB,IAAe,OAAY,KAA+C;AAC9G,MAAI,MAAM,WAAW,aAAa,OAAO,MAAM,aAAa,KAAK,IAAK,QAAO;AAC7E,QAAM,WAAW,MAAM,gBAAgB,OAAO,MAAM,SAAS,CAAC;AAC9D,QAAM,kBAAkB,OAAO,MAAM,iBAAiB,CAAC;AACvD,MAAI;AACF,UAAM,QAAQ,MAAM,GAAG,SAAS,CAAC,EAAE,GAAG,UAAU,IAAI,cAAc,IAAI,OAAO,MAAM,EAAE,GAAG,OAAO;AAAA,MAC7F,UAAU,SAAS;AAAA,MAAU,aAAa,SAAS;AAAA,MAAa,eAAe,kBAAkB;AAAA,MAAG,cAAc;AAAA,MAClH,WAAW;AAAA,MAAK,cAAc;AAAA,MAAG,wBAAwB;AAAA,IAC3D,EAAE,CAAC,GAAG;AAAA,MACJ,YAAY,eAAe,OAAO,MAAM,EAAE,CAAC,IAAI,kBAAkB,CAAC;AAAA,MAClE,QAAQ,CAAC,EAAE,IAAI,cAAc,IAAI,OAAO,MAAM,EAAE,GAAG,QAAQ,MAAM,QAAQ,EAAE,QAAQ,WAAW,eAAe,gBAAgB,EAAE,CAAC;AAAA,IAClI,CAAC;AACD,WAAO,MAAM,YAAY,OAAO,EAAE,MAAM,SAAS,KAAK;AAAA,EACxD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,eAAsB,gBACpB,IACA,OACA,aACA,KACkC;AAClC,MAAI,MAAM,WAAW,aAAa,OAAO,MAAM,aAAa,KAAK,IAAK,QAAO;AAC7E,QAAM,YAAY,OAAO,MAAM,SAAS;AACxC,QAAM,kBAAkB,sBAAsB,YAAY,KAAK;AAC/D,QAAM,SAAS,MAAM;AACrB,QAAM,MAAc,CAAC;AACrB,MAAI;AACJ,MAAI,OAAO,SAAS,QAAQ;AAC1B,UAAM,QAAQ,MAAM,GAAG,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,GAAG,EAAE,EAAE,CAAC,GAAG;AAClG,UAAM,WAAW,MAAM,OAAO,CAAC,QAAQ,IAAI,YAAY,SAAS,EAC7D,KAAK,CAAC,GAAG,MAAM,OAAO,EAAE,aAAa,CAAC,IAAI,OAAO,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC;AACxE,UAAM,KAAK,WAAW,OAAO,SAAS,EAAE,IAAI,oBAAoB,OAAO,MAAM,EAAE,CAAC;AAChF,UAAM,SAAS,YAAY,SAAS,WAAW,cAAc,OAAO,SAAS,MAAM,IAAI;AACvF,QAAI,KAAK,EAAE,GAAG,UAAU,IAAI,gBAAgB,IAAI,OAAO;AAAA,MACrD;AAAA,MAAI,SAAS;AAAA,MAAW,OAAO,YAAY;AAAA,MAAO;AAAA,MAAiB,QAAQ,OAAO;AAAA,MAClF;AAAA,MAAQ,aAAa,OAAO,MAAM,EAAE;AAAA,MAAG,aAAa,OAAO,MAAM,OAAO;AAAA,MACxE,aAAa,YAAY;AAAA,MAAQ,GAAI,WAAW,CAAC,IAAI,EAAE,WAAW,IAAI;AAAA,IACxE,EAAE,CAAC;AACH,aAAS,EAAE,MAAM,eAAe,GAAG;AAAA,EACrC,OAAO;AACL,UAAM,KAAK,oBAAoB,OAAO,MAAM,EAAE,CAAC;AAC/C,QAAI,KAAK,EAAE,GAAG,UAAU,IAAI,oBAAoB,IAAI,OAAO;AAAA,MACzD;AAAA,MAAI,SAAS,OAAO,MAAM,EAAE;AAAA,MAAG,SAAS,OAAO,MAAM,OAAO;AAAA,MAAG;AAAA,MAC/D,gBAAgB,OAAO;AAAA,MAAgB,4BAA4B;AAAA,MACnE,mBAAmB,YAAY;AAAA,MAAQ,QAAQ;AAAA,MAAM,WAAW;AAAA,IAClE,EAAE,CAAC;AACH,aAAS,EAAE,MAAM,eAAe,GAAG;AAAA,EACrC;AACA,MAAI,QAAQ,EAAE,GAAG,UAAU,IAAI,cAAc,IAAI,OAAO,MAAM,EAAE,GAAG,OAAO;AAAA,IACxE,QAAQ;AAAA,IAAY,YAAY;AAAA,IAAK,4BAA4B;AAAA,IACjE,mBAAmB,YAAY;AAAA,IAC/B,GAAI,OAAO,SAAS,gBAAgB,EAAE,eAAe,OAAO,GAAG,IAAI,EAAE,eAAe,OAAO,GAAG;AAAA,IAC9F,cAAc,OAAO,MAAM,gBAAgB,CAAC,IAAI;AAAA,EAClD,EAAE,CAAC;AACH,MAAI;AACF,UAAM,GAAG,SAAS,KAAK;AAAA,MACrB,YAAY,eAAe,OAAO,MAAM,EAAE,CAAC,IAAI,YAAY,MAAM;AAAA,MACjE,QAAQ,CAAC,EAAE,IAAI,cAAc,IAAI,OAAO,MAAM,EAAE,GAAG,QAAQ,MAAM,QAAQ;AAAA,QACvE,QAAQ;AAAA,QAAW,aAAa,OAAO,MAAM,WAAW;AAAA,QAAG,UAAU,OAAO,MAAM,QAAQ;AAAA,MAC5F,EAAE,CAAC;AAAA,IACL,CAAC;AACD,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,eAAsB,gBAAgB,IAAe,OAAY,QAAiC,KAA+B;AAC/H,MAAI,MAAM,WAAW,UAAW,QAAO;AACvC,QAAM,MAAc,CAAC,EAAE,GAAG,UAAU,IAAI,cAAc,IAAI,OAAO,MAAM,EAAE,GAAG,OAAO;AAAA,IACjF,QAAQ;AAAA,IAAW,WAAW;AAAA,IAAK,eAAe;AAAA,EACpD,EAAE,CAAC;AACH,MAAI,MAAM,cAAe,KAAI,KAAK,EAAE,GAAG,UAAU,IAAI,oBAAoB,IAAI,OAAO,MAAM,aAAa,GAAG,OAAO,EAAE,QAAQ,OAAO,WAAW,IAAI,EAAE,CAAC;AACpJ,MAAI,MAAM,cAAe,KAAI,KAAK,EAAE,GAAG,UAAU,IAAI,gBAAgB,IAAI,OAAO,MAAM,aAAa,GAAG,OAAO;AAAA,IAC3G,eAAe;AAAA,IAAK,GAAI,WAAW,aAAa,EAAE,QAAQ,WAAW,IAAI,EAAE,UAAU,KAAK;AAAA,EAC5F,EAAE,CAAC;AACH,MAAI;AACF,UAAM,GAAG,SAAS,KAAK;AAAA,MACrB,YAAY,eAAe,OAAO,MAAM,EAAE,CAAC,IAAI,MAAM;AAAA,MACrD,QAAQ,CAAC,EAAE,IAAI,cAAc,IAAI,OAAO,MAAM,EAAE,GAAG,QAAQ,MAAM,QAAQ,EAAE,QAAQ,OAAO,MAAM,MAAM,EAAE,EAAE,CAAC;AAAA,IAC7G,CAAC;AACD,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AChLA,IAAM,eAAe,CAAC,UAAkD;AACtE,QAAM,SAAS,MAAM;AACrB,MAAI,OAAO,WAAW,YAAY,OAAQ,QAAO;AACjD,QAAM,UAAU,MAAM;AACtB,QAAM,eAAe,SAAS;AAC9B,QAAM,SAAS,SAAS;AACxB,QAAM,SAAS,cAAc,iBAAiB,QAAQ;AACtD,SAAO,OAAO,WAAW,YAAY,SAAS,SAAS;AACzD;AAGA,eAAsB,0BACpB,WACA,QACA,OACA,oBAC6B;AAC7B,QAAM,QAAQ,OAAO;AACrB,QAAM,WAAW;AAAA,IACf,cAAc,OAAO;AAAA,IACrB,WAAW,OAAO;AAAA,IAClB,aAAa,OAAO;AAAA,IACpB,SAAS,OAAO;AAAA,EAClB;AACA,MAAI,aAAa;AACjB,MAAI,CAAC,YAAY;AACf,UAAM,WAAW,MAAM,WAAW,WAAW,QAAQ,iBAAiB,EAAE,OAAO,SAAS,GAAG,iBAAiB,OAAO,EAAE,EAAE;AACvH,QAAI,CAAC,SAAS,GAAI,OAAM,IAAI,MAAM,gCAAgC,SAAS,MAAM,GAAG;AACpF,iBAAa,OAAO,SAAS,KAAK,EAAE;AAAA,EACtC;AACA,MAAI,MAAM,gBAAgB,gBAAgB;AACxC,UAAMC,WAAU,MAAM,WAAW,WAAW,QAAQ,qBAAqB;AAAA,MACvE,UAAU;AAAA,MACV,mBAAmB,MAAM;AAAA,MACzB,kBAAkB;AAAA,MAClB,iDAAiD;AAAA,MACjD,6CAA6C;AAAA,MAC7C,aAAa;AAAA,MACb;AAAA,IACF,GAAG,qBAAqB,OAAO,EAAE,EAAE;AACnC,UAAMC,UAASD,SAAQ,KAAK,aAAaA,SAAQ,IAAI,IAAI;AACzD,QAAI,CAACA,SAAQ,MAAM,CAACC,QAAQ,OAAM,IAAI,MAAM,oCAAoCD,SAAQ,MAAM,GAAG;AACjG,WAAO,EAAE,cAAcC,SAAQ,kBAAkB,OAAOD,SAAQ,KAAK,EAAE,GAAG,WAAW;AAAA,EACvF;AACA,QAAM,QAAQ,MAAM,WAAW,WAAW,OAAO,cAAc,mBAAmB,MAAM,aAAa,CAAC,EAAE;AACxG,MAAI,CAAC,MAAM,MAAM,MAAM,KAAK,WAAW,SAAS,MAAM,KAAK,gBAAgB,MAAM,cAAc,MAAM,KAAK,aAAa,MAAM,UAAU;AACrI,UAAM,IAAI,MAAM,4CAA4C;AAAA,EAC9D;AACA,QAAM,UAAU,MAAM,WAAW,WAAW,QAAQ,uBAAuB;AAAA,IACzE,UAAU;AAAA,IACV,QAAQ,MAAM;AAAA,IACd,UAAU,MAAM;AAAA,IAChB,sCAAsC;AAAA,IACtC;AAAA,EACF,GAAG,gBAAgB,OAAO,EAAE,EAAE;AAC9B,QAAM,SAAS,QAAQ,KAAK,aAAa,QAAQ,IAAI,IAAI;AACzD,MAAI,CAAC,QAAQ,MAAM,CAAC,OAAQ,OAAM,IAAI,MAAM,+BAA+B,QAAQ,MAAM,GAAG;AAC5F,SAAO,EAAE,cAAc,QAAQ,kBAAkB,OAAO,QAAQ,KAAK,EAAE,GAAG,WAAW;AACvF;;;AC9DA,IAAME,SAAQ,CAAC,UAAwD,MAAM,QAAQ,KAAK,IAAI,MAAM,CAAC,IAAI;AA4BzG,eAAsB,gBAAgB,IAAe,OAAyD;AAC5G,MAAI,SAASA,QAAO,MAAM,GAAG,MAAM,EAAE,qBAAqB,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,MAAM,GAAG,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG,mBAAmB;AAC9H,MAAI;AACJ,MAAI,CAAC,QAAQ;AACX,UAAM,WAAW,MAAM,gBAAgB,MAAM,SAAS;AACtD,UAAM,QAAQ;AAAA,MACZ,IAAI,MAAM;AAAA,MAAI,WAAW,MAAM;AAAA,MAAW,aAAa,MAAM;AAAA,MAC7D,eAAe,MAAM;AAAA,MAAe,0BAA0B,MAAM;AAAA,MACpE,GAAI,MAAM,yBAAyB,EAAE,wBAAwB,MAAM,uBAAuB,IAAI,CAAC;AAAA,MAC/F,GAAI,MAAM,kBAAkB,EAAE,iBAAiB,MAAM,gBAAgB,IAAI,CAAC;AAAA,MAC1E,SAAS,MAAM,MAAM;AAAA,MAAI,eAAe,MAAM;AAAA,MAAO,QAAQ;AAAA,MAC7D,UAAU,SAAS;AAAA,MAAU,aAAa,SAAS;AAAA,MAAa,cAAc,MAAM;AAAA,MACpF,WAAW,MAAM;AAAA,MAAK,WAAW,MAAM;AAAA,IACzC;AACA,UAAM,QAAQ,MAAM,GAAG,SAAS,CAAC,EAAE,GAAG,UAAU,IAAI,uBAAuB,IAAI,MAAM,IAAI,MAAM,CAAC,GAAG;AAAA,MACjG,YAAY,eAAe,MAAM,EAAE;AAAA,IACrC,CAAC;AACD,aAAS,MAAM,YACXA,QAAO,MAAM,GAAG,MAAM,EAAE,qBAAqB,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,MAAM,GAAG,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG,mBAAmB,IACjH;AACJ,QAAI,CAAC,MAAM,UAAW,YAAW,SAAS;AAAA,EAC5C;AACA,MAAI,CAAC,UAAU,OAAO,cAAc,MAAM,aAAa,OAAO,gBAAgB,MAAM,eAChF,OAAO,YAAY,MAAM,MAAM,MAAM,OAAO,6BAA6B,MAAM,0BAA0B;AAC3G,UAAM,IAAI,MAAM,mDAAmD;AAAA,EACrE;AACA,MAAI,OAAO,WAAW,OAAQ,OAAM,IAAI,MAAM,+BAA+B;AAC7E,QAAM,WAAW,MAAM;AAAA,IACrB,MAAM;AAAA,IACN;AAAA,IACA,MAAM;AAAA,IACN,OAAO,OAAO,uBAAuB,WAAW,OAAO,qBAAqB,MAAM;AAAA,EACpF;AACA,QAAM,GAAG,SAAS,CAAC,EAAE,GAAG,UAAU,IAAI,uBAAuB,IAAI,MAAM,IAAI,OAAO;AAAA,IAChF,QAAQ;AAAA,IAAkB,kBAAkB,SAAS;AAAA,IACrD,GAAI,SAAS,aAAa,EAAE,oBAAoB,SAAS,WAAW,IAAI,CAAC;AAAA,IACzE,mBAAmB,MAAM;AAAA,IAAK,WAAW,MAAM;AAAA,EACjD,EAAE,CAAC,GAAG,EAAE,YAAY,uBAAuB,MAAM,EAAE,IAAI,SAAS,gBAAgB,GAAG,CAAC;AACpF,SAAO;AAAA,IACL,MAAM;AAAA,IAAM,UAAU,MAAM;AAAA,IAAI,cAAc,SAAS;AAAA,IAAc,gBAAgB,MAAM;AAAA,IAC3F,WAAW,EAAE,eAAe,MAAM,MAAM,YAAY,eAAe,GAAG,eAAe,MAAM,MAAM,WAAW;AAAA,IAC5G,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,EACjC;AACF;;;ACjDA,IAAM,SAAS,CAAC,QACd,OAAO,OAAO,QAAQ,YAAY,OAAQ,IAA2B,SAAS,WAAY,IAAyB,OAAO;AAE5H,eAAeC,UAAS,IAAe,IAAY,GAAsD;AACvG,QAAM,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC;AAC7C,QAAMC,QAAO,IAAI,EAAE;AACnB,SAAO,MAAM,QAAQA,KAAI,IAAIA,MAAK,CAAC,IAAI;AACzC;AAEA,SAAS,UAAU,OAAqF;AACtG,QAAM,WAAW,OAAO,MAAM,sBAAsB,CAAC;AACrD,QAAM,WAAW,OAAO,MAAM,yBAAyB,CAAC;AACxD,SAAO,EAAE,eAAe,UAAU,eAAe,UAAU,eAAe,WAAW,SAAS;AAChG;AAIA,eAAe,gBAAgB,IAAe,OAA+C;AAC3F,MAAI,mBAAmB,SAAS,MAAM,eAAe;AACnD,WAAOD,UAAS,IAAI,gBAAgB,EAAE,OAAO,EAAE,IAAI,MAAM,cAAc,GAAG,OAAO,EAAE,CAAC;AAAA,EACtF;AACA,MAAI,gBAAgB,SAAS,MAAM,YAAY;AAC7C,WAAOA,UAAS,IAAI,gBAAgB,EAAE,OAAO,EAAE,kBAAkB,MAAM,WAAW,GAAG,OAAO,EAAE,WAAW,OAAO,GAAG,OAAO,EAAE,CAAC;AAAA,EAC/H;AACA,SAAO;AACT;AAIA,eAAe,uBAAuB,IAAe,KAAiB,SAAiB,KAAyB;AAC9G,MAAI;AACF,QAAI,OAAO,IAAI,UAAU,YAAY,CAAC,IAAI,MAAO;AACjD,UAAM,QAAQ,MAAMA,UAAS,IAAI,UAAU,EAAE,OAAO,EAAE,IAAI,OAAO,IAAI,WAAW,EAAE,EAAE,GAAG,OAAO,EAAE,CAAC;AACjG,QAAI,CAAC,MAAO;AACZ,UAAM;AAAA,MACJ,EAAE,IAAI,SAAS,IAAI,UAAU,QAAQ,IAAI,YAAY,MAAM,IAAI,YAAY,KAAK,MAAM,KAAK,IAAI,GAAG,OAAO,MAAM,OAAO,WAAW,EAAE;AAAA,MACnI;AAAA,QACE,OAAO,eAAe,KAAK;AAAA,QAC3B,UAAU;AAAA,QACV,IAAI,IAAI;AAAA,QACR,MAAM,EAAE,WAAW,OAAO,IAAI,cAAc,WAAW,IAAI,YAAY,GAAG;AAAA,QAC1E,WAAW,GAAG,OAAO;AAAA,QACrB,eAAe,OAAO,IAAI,EAAE;AAAA,MAC9B;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AACF;AAKA,eAAe,qBAAqB,IAAe,KAAiB,SAAiB,KAAyB;AAC5G,MAAI;AACF,UAAM,QAAQ,MAAMA,UAAS,IAAI,UAAU,EAAE,OAAO,EAAE,IAAI,OAAO,IAAI,WAAW,EAAE,EAAE,GAAG,OAAO,EAAE,CAAC;AACjG,QAAI,CAAC,SAAS,OAAO,MAAM,sBAAsB,YAAY,CAAC,MAAM,kBAAmB;AACvF,UAAM,IAAI,CAAC,MAAwB,OAAO,MAAM,WAAW,IAAI;AAC/D,UAAM;AAAA,MACJ,EAAE,IAAI,SAAS,IAAI,UAAU,QAAQ,IAAI,YAAY,MAAM,IAAI,YAAY,KAAK,MAAM,KAAK,IAAI,GAAG,OAAO,MAAM,OAAO,WAAW,EAAE;AAAA,MACnI;AAAA,QACE,OAAO,eAAe,KAAK;AAAA,QAC3B,UAAU;AAAA,QACV,IAAI,MAAM;AAAA,QACV,MAAM,EAAE,WAAW,EAAE,IAAI,SAAS,GAAG,UAAU,EAAE,IAAI,QAAQ,GAAG,OAAO,EAAE,IAAI,KAAK,GAAG,OAAO,EAAE,IAAI,KAAK,GAAG,OAAO,EAAE,IAAI,KAAK,EAAE;AAAA,QAC9H,WAAW,GAAG,OAAO;AAAA,QACrB,eAAe,OAAO,IAAI,EAAE;AAAA,MAC9B;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AACF;AAGA,SAAS,aAAa,OAAqB,QAAyC;AAClF,UAAQ,MAAM,MAAM;AAAA,IAClB,KAAK;AACH,aAAO,kBAAkB,QAAQ,MAAM,SAAS;AAAA,IAClD,KAAK;AACH,aAAO,MAAM,cAAc,SAAY,aAAa,MAAM,SAAS,IAAI,CAAC;AAAA,IAC1E,KAAK;AACH,aAAO,cAAc;AAAA,IACvB,KAAK;AACH,aAAO,cAAc;AAAA,IACvB;AACE,aAAO,CAAC;AAAA,EACZ;AACF;AAEA,eAAe,kBAAkB,KAAc,KAAiB,KAAuC;AACrG,MAAI;AACJ,MAAI;AACF,WAAO,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC;AAAA,EACpC,QAAQ;AACN,WAAO,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;AAAA,EACjD;AACA,QAAM,gBAAgB,OAAO,KAAK,kBAAkB,WAAW,KAAK,gBAAgB;AACpF,MAAI,CAAC,cAAe,QAAO,KAAK,EAAE,OAAO,yBAAyB,GAAG,GAAG;AACxE,MAAI,KAAK,oBAAoB,KAAM,QAAO,KAAK,EAAE,OAAO,2BAA2B,GAAG,GAAG;AAEzF,QAAM,KAAK,IAAI,OAAO,GAAG;AACzB,QAAM,MAAM,MAAMA,UAAS,IAAI,gBAAgB,EAAE,OAAO,EAAE,IAAI,cAAc,GAAG,OAAO,EAAE,CAAC;AACzF,MAAI,CAAC,IAAK,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AAEjD,MAAI,IAAI,WAAW,YAAa,QAAO,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;AAE/E,QAAM,QAAQ,MAAMA,UAAS,IAAI,UAAU,EAAE,OAAO,EAAE,IAAI,OAAO,IAAI,WAAW,IAAI,QAAQ,EAAE,EAAE,GAAG,OAAO,EAAE,CAAC;AAC7G,QAAM,YAAY,MAAM,eAAe,IAAI,mBAAmB;AAC9D,MAAI,CAAC,SAAS,CAAC,UAAW,QAAO,KAAK,EAAE,OAAO,0BAA0B,GAAG,GAAG;AAC/E,MAAI,OAAO,IAAI,gBAAgB,UAAU;AACvC,UAAME,WAAU,MAAM,wBAAwB,IAAI,IAAI,QAAQ,IAAI,IAAI,QAAQ;AAC9E,UAAM,QAAQ,cAAcA,UAAS,SAAS,YAAY,IAAI,aAAa,KAAK,IAAI,CAAC;AACrF,QAAI,CAAC,SAAS,OAAO,MAAM,yBAAyB,YAAY,CAAC,MAAM,sBAAsB;AAC3F,aAAO,KAAK,EAAE,OAAO,4BAA4B,GAAG,GAAG;AAAA,IACzD;AACA,QAAI;AACF,YAAM,UAAU,MAAM,gBAAgB,IAAI;AAAA,QACxC,IAAI,OAAO,IAAI,iBAAiB,WAAW,IAAI,eAAe,eAAe,aAAa;AAAA,QAC1F,WAAW,IAAI,QAAQ;AAAA,QAAI,aAAa,IAAI;AAAA,QAAU;AAAA,QACtD,eAAe;AAAA,QAAe,gBAAgB,OAAO,IAAI,SAAS,EAAE;AAAA,QACpE,0BAA0B,sBAAsB,OAAO,IAAI,SAAS,EAAE,CAAC;AAAA,QACvE,wBAAwB;AAAA,QAAe,cAAc;AAAA,QACrD,gBAAgB,MAAM;AAAA,QAAsB,KAAK,KAAK,IAAI;AAAA,MAC5D,CAAC;AACD,YAAM,GAAG,SAAS,CAAC,EAAE,GAAG,UAAU,IAAI,gBAAgB,IAAI,eAAe,OAAO;AAAA,QAC9E,cAAc,QAAQ;AAAA,QAAU,uBAAuB,KAAK,IAAI;AAAA,QAAG,mBAAmB,KAAK,IAAI;AAAA,MACjG,EAAE,CAAC,CAAC;AACJ,aAAO,KAAK,OAAO;AAAA,IACrB,SAAS,OAAO;AACd,aAAO,KAAK,EAAE,OAAO,iBAAiB,QAAQ,MAAM,UAAU,uBAAuB,GAAG,GAAG;AAAA,IAC7F;AAAA,EACF;AAGA,QAAM,OAAO;AAAA,IACX,MAAM,UAAU,IAAI,KAAc;AAAA,IAClC,OAAO,IAAI,WAAW,WAAW,IAAI,SAAS;AAAA,EAChD;AACA,MAAI,CAAC,KAAM,QAAO,KAAK,EAAE,OAAO,kBAAkB,MAAM,kBAAkB,GAAG,GAAG;AAGhF,MAAI,WAAW,IAAI,EAAG,QAAO,KAAK,EAAE,OAAO,gBAAgB,MAAM,mBAAmB,GAAG,GAAG;AAC1F,QAAM,UAAU,KAAK;AACrB,MAAI,CAAC,QAAS,QAAO,KAAK,EAAE,OAAO,0BAA0B,GAAG,GAAG;AAEnE,QAAM,WAAW,qBAAqB,EAAE,UAAU,CAAC;AACnD,MAAI;AACJ,MAAI;AACF,aAAS,MAAM,SAAS,mBAAmB;AAAA,MACzC;AAAA,MACA,SAAS,OAAO,MAAM,EAAE;AAAA,MACxB,OAAO,OAAO,IAAI,SAAS,EAAE;AAAA,MAC7B,MAAM,GAAG,IAAI,aAAa,EAAE,IAAI,IAAI,YAAY,EAAE,GAAG,KAAK;AAAA,MAC1D,SAAS,OAAO,OAAO;AAAA,MACvB,oBAAoB,OAAO,IAAI,qBAAqB,WAAW,IAAI,mBAAmB;AAAA,IACxF,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,WAAO,KAAK,EAAE,OAAO,wBAAwB,MAAM,OAAO,GAAG,EAAE,GAAG,GAAG;AAAA,EACvE;AAEA,QAAM,GAAG,SAAS;AAAA,IAChB;AAAA,MACE,GAAG;AAAA,MACH,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,OAAO,EAAE,kBAAkB,OAAO,YAAY,sBAAsB,OAAO,gBAAgB,mBAAmB,KAAK,IAAI,EAAE;AAAA,IAC3H;AAAA,EACF,CAAC;AACD,SAAO,KAAK,EAAE,cAAc,OAAO,cAAc,gBAAgB,MAAM,wBAAwB,MAAM,WAAW,UAAU,KAAK,EAAE,CAAC;AACpI;AAEA,eAAe,cAAc,KAAc,KAAiB,KAAuC;AACjG,QAAM,KAAK,IAAI,OAAO,GAAG;AACzB,QAAM,gBAAgB,MAAM,eAAe,IAAI,uBAAuB;AACtE,MAAI,CAAC,cAAe,QAAO,KAAK,EAAE,OAAO,yBAAyB,GAAG,GAAG;AAExE,QAAM,UAAU,MAAM,IAAI,KAAK;AAC/B,QAAM,SAAS,MAAM,qBAAqB,EAAE,cAAc,CAAC,EAAE,cAAc,SAAS,IAAI,QAAQ,IAAI,kBAAkB,KAAK,EAAE;AAC7H,MAAI,CAAC,OAAO,GAAI,QAAO,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;AAC/D,QAAM,EAAE,SAAS,MAAM,IAAI;AAC3B,MAAI,MAAM,SAAS,UAAW,QAAO,KAAK,EAAE,IAAI,MAAM,SAAS,MAAM,KAAK,CAAC;AAE3E,MAAI,MAAM,SAAS,eAAe,MAAM,SAAS,gBAAgB;AAC/D,UAAM,SAAS,MAAMF,UAAS,IAAI,uBAAuB,EAAE,OAAO,EAAE,IAAI,MAAM,aAAa,GAAG,OAAO,EAAE,CAAC;AACxG,QAAI,CAAC,UAAU,OAAO,cAAc,IAAI,QAAQ,MAAM,OAAO,gBAAgB,IAAI,UAAU;AACzF,aAAO,KAAK,EAAE,IAAI,MAAM,SAAS,MAAM,CAAC;AAAA,IAC1C;AACA,QAAI,MAAM,SAAS,aAAa;AAC9B,UAAI,OAAO,qBAAqB,MAAM,iBAAkB,QAAO,KAAK,EAAE,IAAI,MAAM,SAAS,MAAM,CAAC;AAChG,UAAI,OAAO,WAAW,cAAc,OAAO,WAAW,WAAY,QAAO,KAAK,EAAE,IAAI,MAAM,SAAS,MAAM,CAAC;AAC1G,UAAI;AACF,cAAM,SAAS,MAAM,eAAe,IAAI,QAAyB;AAAA,UAC/D;AAAA,UAAS,UAAU,MAAM;AAAA,QAC3B,GAAG,KAAK,IAAI,CAAC;AACb,eAAO,KAAK,EAAE,IAAI,MAAM,SAAS,MAAM,SAAS,OAAO,QAAQ,CAAC;AAAA,MAClE,QAAQ;AACN,eAAO,KAAK,EAAE,OAAO,uBAAuB,GAAG,GAAG;AAAA,MACpD;AAAA,IACF;AACA,UAAM,GAAG,SAAS,CAAC,EAAE,GAAG,UAAU,IAAI,uBAAuB,IAAI,MAAM,cAAc,OAAO;AAAA,MAC1F,QAAQ,MAAM;AAAA,MAAQ,WAAW,KAAK,IAAI;AAAA,IAC5C,EAAE,CAAC,GAAG,EAAE,YAAY,uBAAuB,OAAO,GAAG,CAAC;AACtD,UAAM,QAAQ,MAAMA,UAAS,IAAI,cAAc,EAAE,OAAO,EAAE,UAAU,MAAM,aAAa,GAAG,OAAO,EAAE,CAAC;AACpG,QAAI,MAAO,OAAM,gBAAgB,IAAI,OAAO,MAAM,QAAQ,KAAK,IAAI,CAAC;AACpE,WAAO,KAAK,EAAE,IAAI,MAAM,SAAS,QAAQ,KAAK,EAAE,CAAC;AAAA,EACnD;AAEA,QAAM,MAAM,MAAM,gBAAgB,IAAI,KAAK;AAC3C,MAAI,CAAC,IAAK,QAAO,KAAK,EAAE,IAAI,MAAM,SAAS,MAAM,CAAC;AAElD,QAAM,QAAQ,aAAa,OAAO,OAAO,IAAI,UAAU,EAAE,CAAC;AAC1D,MAAI,OAAO;AACX,MAAI,OAAO,KAAK,KAAK,EAAE,QAAQ;AAC7B,UAAM,GAAG,SAAS,CAAC,EAAE,GAAG,UAAU,IAAI,gBAAgB,IAAI,OAAO,IAAI,EAAE,GAAG,OAAO,MAAM,CAAC,GAAG,EAAE,YAAY,kBAAkB,OAAO,EAAE,CAAC;AAOrI,WAAO,EAAE,GAAG,KAAK,GAAG,MAAM;AAC1B,UAAM,qBAAqB,QAAQ,IAAI,GAAG,GAAG,EAAE,KAAK,MAAM,OAAO,OAAO,KAAK,UAAU,EAAE,EAAE,CAAC,EAAE,MAAM,MAAM,MAAS;AAAA,EACrH;AACA,MAAI,MAAM,SAAS,iBAAiB;AAClC,UAAM,uBAAuB,IAAI,KAAK,SAAS,GAAG;AAClD,QAAI,IAAI,QAAQ,MAAM,sBAAsB,UAAW,OAAM,qBAAqB,IAAI,KAAK,SAAS,GAAG;AACvG,QAAI,OAAO,KAAK,sBAAsB,UAAU;AAC9C,YAAM,mBAAmB;AAAA,QACvB;AAAA,QACA;AAAA,QACA;AAAA,QACA,KAAK;AAAA,QACL,QAAQ,IAAI,IAAI,IAAI,GAAG,EAAE;AAAA,QACzB,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO,KAAK,EAAE,IAAI,KAAK,CAAC;AAC1B;AAIO,IAAM,iBAAwB,OAAO,KAAK,KAAK,KAAK,QAAQ;AACjE,MAAI,IAAI,QAAQ,SAAS,UAAW,QAAO;AAC3C,MAAI,IAAI,WAAW,UAAU,IAAI,aAAa,6BAA8B,QAAO,kBAAkB,KAAK,KAAK,GAAG;AAClH,MAAI,IAAI,WAAW,UAAU,IAAI,aAAa,uBAAwB,QAAO,cAAc,KAAK,KAAK,GAAG;AACxG,SAAO;AACT;;;ACxQA,IAAMG,SAAQ,CAAC,UAAwD,MAAM,QAAQ,KAAK,IAAI,MAAM,CAAC,IAAI;AACzG,IAAMC,QAAO,CAAC,UAAmD,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC;AACjG,IAAM,UAAU,MAAM,KAAK,EAAE,OAAO,sCAAsC,GAAG,GAAG;AAChF,IAAM,UAAU,OAAO,KAAc,KAA2B,QAA8B;AAC5F,QAAM,OAAO,MAAM,IAAI,WAAW,KAAK,GAAG;AAC1C,SAAO,MAAM,QAAQ,OAAO;AAC9B;AACA,IAAM,YAAY,OAAO,IAAe,OACtCD,QAAO,MAAM,GAAG,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG,UAAU;AAEvF,eAAe,iBAAiB,IAAe,WAAmB,WAAmB,KAA+B;AAClH,QAAM,SAAS,MAAM,oBAAoB,WAAW,SAAS;AAC7D,QAAM,KAAK,aAAa,SAAS,IAAI,MAAM;AAC3C,QAAM,UAAUA,QAAO,MAAM,GAAG,MAAM,EAAE,wBAAwB,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG,sBAAsB;AAC7H,QAAM,SAAS,QAAQ,WAAW,MAAM,OAAO,QAAQ,eAAe,IAAI,KAAK,GAAM;AACrF,QAAM,eAAe,SAAS,OAAO,SAAS,gBAAgB,CAAC,IAAI,IAAI;AACvE,MAAI,eAAe,GAAI,QAAO;AAC9B,QAAM,GAAG,SAAS,CAAC,EAAE,GAAG,UAAU,IAAI,0BAA0B,IAAI,OAAO;AAAA,IACzE;AAAA,IAAI;AAAA,IAAW;AAAA,IAAQ;AAAA,IAAc,iBAAiB,SAAS,OAAO,SAAS,eAAe,IAAI;AAAA,IAAK,WAAW;AAAA,EACpH,EAAE,CAAC,CAAC;AACJ,SAAO;AACT;AAGO,IAAM,cAAqB,OAAO,KAAK,KAAK,KAAK,QAAQ;AAC9D,MAAI,IAAI,QAAQ,SAAS,aAAa,CAAC,IAAI,SAAS,WAAW,YAAY,EAAG,QAAO;AACrF,QAAM,KAAK,IAAI,OAAO,GAAG;AACzB,MAAI,IAAI,WAAW,SAAS,IAAI,aAAa,cAAc;AACzD,UAAM,OAAO,MAAM,QAAQ,KAAK,KAAK,GAAG;AACxC,QAAI,CAAC,KAAM,QAAO,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG;AACrD,UAAME,WAAU,MAAM,wBAAwB,IAAI,IAAI,QAAQ,IAAI,IAAI,QAAQ;AAC9E,UAAM,QAAQ,MAAM,GAAG,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,OAAO;AAAA,MACvD,0BAA0B,sBAAsB,KAAK,KAAM;AAAA,MAAG,WAAW,IAAI,QAAQ;AAAA,IACvF,GAAG,OAAO,IAAI,EAAE,EAAE,CAAC;AACnB,UAAM,QAAQF,QAAO,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,IAAI,QAAQ,GAAG,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG,MAAM;AAC3G,WAAO,KAAK;AAAA,MACV,QAAQ,iBAAiBE,UAAS,SAAS,YAAY,KAAK,IAAI,CAAC;AAAA,MACjE,QAAQ,gBAAgBD,MAAK,MAAM,UAAU,EAAE,KAAK,CAAC,GAAG,MAAM,OAAO,EAAE,SAAS,IAAI,OAAO,EAAE,SAAS,CAAC,GAAG,KAAK,IAAI,CAAC;AAAA,MACpH,kBAAkB,OAAO,OAAO,qBAAqB,WAAW,MAAM,mBAAmB;AAAA,IAC3F,CAAC;AAAA,EACH;AACA,MAAI,IAAI,WAAW,UAAU,IAAI,aAAa,uBAAuB;AACnE,UAAM,OAAO,MAAM,QAAQ,KAAK,KAAK,GAAG;AACxC,QAAI,CAAC,KAAM,QAAO,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG;AACrD,QAAI;AACJ,QAAI;AAAE,aAAO,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC;AAAA,IAA8B,QAChE;AAAE,aAAO,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;AAAA,IAAG;AAC1D,UAAM,aAAa,OAAO,KAAK,eAAe,WAAW,KAAK,aAAa;AAC3E,QAAI,CAAC,0BAA0B,KAAK,UAAU,EAAG,QAAO,KAAK,EAAE,OAAO,wBAAwB,GAAG,GAAG;AACpG,UAAMC,WAAU,MAAM,wBAAwB,IAAI,IAAI,QAAQ,IAAI,IAAI,QAAQ;AAC9E,UAAM,QAAQ,cAAcA,UAAS,SAAS,YAAY,OAAO,KAAK,YAAY,WAAW,KAAK,UAAU,IAAI,KAAK,IAAI,CAAC;AAC1H,QAAI,CAAC,MAAO,QAAO,KAAK,EAAE,OAAO,4BAA4B,GAAG,GAAG;AACnE,UAAM,QAAQF,QAAO,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,IAAI,QAAQ,GAAG,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG,MAAM;AAC3G,UAAM,eAAe,MAAM,eAAe,IAAI,mBAAmB;AACjE,QAAI,CAAC,SAAS,CAAC,gBAAgB,OAAO,MAAM,yBAAyB,SAAU,QAAO,KAAK,EAAE,OAAO,0BAA0B,GAAG,GAAG;AACpI,UAAM,kBAAkB,sBAAsB,KAAK,KAAM;AACzD,UAAM,eAAeC,OAAM,MAAM,GAAG,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,GAAG,EAAE,EAAE,CAAC,GAAG,YAAY;AAC3H,UAAM,MAAM,aAAa,KAAK,CAAC,GAAG,MAAM,OAAO,EAAE,aAAa,CAAC,IAAI,OAAO,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC;AAC9F,QAAI;AACF,aAAO,KAAK,MAAM,gBAAgB,IAAI;AAAA,QACpC,IAAI,eAAe,IAAI,QAAQ,EAAE,IAAI,UAAU;AAAA,QAAI,WAAW,IAAI,QAAQ;AAAA,QAC1E,aAAa,IAAI;AAAA,QAAU;AAAA,QAAO,eAAe;AAAA,QAAU,gBAAgB,KAAK;AAAA,QAChF,0BAA0B;AAAA,QAAiB,iBAAiB,KAAK;AAAA,QACjE,GAAI,OAAO,KAAK,qBAAqB,WAAW,EAAE,oBAAoB,IAAI,iBAAiB,IAAI,CAAC;AAAA,QAChG;AAAA,QAAc,gBAAgB,MAAM;AAAA,QAAsB,KAAK,KAAK,IAAI;AAAA,MAC1E,CAAC,CAAC;AAAA,IACJ,SAAS,OAAO;AACd,aAAO,KAAK,EAAE,OAAO,iBAAiB,QAAQ,MAAM,UAAU,uBAAuB,GAAG,GAAG;AAAA,IAC7F;AAAA,EACF;AACA,QAAM,cAAc,IAAI,SAAS,MAAM,iCAAiC;AACxE,MAAI,IAAI,WAAW,UAAU,aAAa;AACxC,QAAI,UAAU;AACd,QAAI;AAAE,gBAAU,mBAAmB,YAAY,CAAC,CAAW;AAAA,IAAG,QAAQ;AAAE,aAAO,QAAQ;AAAA,IAAG;AAC1F,QAAI,CAAC,QAAQ,WAAW,aAAa,EAAG,QAAO,QAAQ;AACvD,UAAM,QAAQ,MAAM,UAAU,IAAI,OAAO;AACzC,QAAI,CAAC,SAAS,MAAM,cAAc,IAAI,QAAQ,MAAM,OAAO,MAAM,iBAAiB,CAAC,KAAK,GAAI,QAAO,QAAQ;AAC3G,UAAM,OAAO,MAAM,QAAQ,KAAK,KAAK,GAAG;AACxC,QAAI,gBAAgB;AACpB,QAAI,CAAC,MAAM;AACT,UAAI;AAAE,wBAAgB,OAAQ,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,EAA8B,iBAAiB,EAAE;AAAA,MAAG,QACvG;AAAE,eAAO,QAAQ;AAAA,MAAG;AAAA,IAC5B;AACA,UAAM,OAAO,OACT,MAAM,6BAA6B,sBAAsB,KAAK,KAAM,IACpE,MAAM,2BAA2B;AACrC,QAAI,CAAC,KAAM,QAAO,QAAQ;AAC1B,UAAM,UAAU,MAAM,gBAAgB,IAAI,OAAO,KAAK,IAAI,CAAC;AAC3D,WAAO,UAAU,KAAK,OAAO,IAAI,QAAQ;AAAA,EAC3C;AACA,MAAI,IAAI,WAAW,UAAU,IAAI,aAAa,qBAAqB;AACjE,UAAM,OAAO,MAAM,QAAQ,KAAK,KAAK,GAAG;AACxC,QAAI,CAAC,KAAM,QAAO,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG;AACrD,UAAM,MAAM,KAAK,IAAI;AACrB,QAAI,CAAC,MAAM,iBAAiB,IAAI,IAAI,QAAQ,IAAI,GAAG,KAAK,MAAM,IAAI,IAAI,QAAQ,IAAI,kBAAkB,KAAK,OAAO,IAAI,GAAG,GAAG;AACxH,aAAO,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;AAAA,IACjD;AACA,QAAI,OAAO;AACX,QAAI;AAAE,aAAO,OAAQ,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,EAA8B,QAAQ,EAAE,EAAE,KAAK;AAAA,IAAG,QAC5F;AAAE,aAAO,QAAQ;AAAA,IAAG;AAC1B,QAAI,CAAC,4BAA4B,KAAK,IAAI,EAAG,QAAO,QAAQ;AAC5D,UAAM,WAAW,MAAM,aAAa,IAAI,QAAQ,IAAI,IAAI;AACxD,UAAM,QAAQD,QAAO,MAAM,GAAG,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG,UAAU;AACzG,QAAI,CAAC,SAAS,MAAM,cAAc,IAAI,QAAQ,GAAI,QAAO,QAAQ;AACjE,QAAI,MAAM,WAAW,aAAa,OAAO,MAAM,aAAa,KAAK,KAAK;AACpE,YAAM,GAAG,SAAS,CAAC,EAAE,GAAG,UAAU,IAAI,cAAc,IAAI,OAAO,MAAM,EAAE,GAAG,OAAO;AAAA,QAC/E,cAAc,OAAO,MAAM,gBAAgB,CAAC,IAAI;AAAA,QAChD,GAAI,MAAM,WAAW,YAAY,EAAE,QAAQ,UAAU,IAAI,CAAC;AAAA,MAC5D,EAAE,CAAC,CAAC,EAAE,MAAM,MAAM,MAAS;AAC3B,aAAO,QAAQ;AAAA,IACjB;AACA,UAAM,WAAW,MAAM,gBAAgB,IAAI,OAAO,EAAE,OAAO,KAAK,OAAQ,QAAQ,KAAK,OAAO,GAAG,GAAG;AAClG,WAAO,WAAW,KAAK,EAAE,IAAI,MAAM,GAAG,SAAS,CAAC,IAAI,QAAQ;AAAA,EAC9D;AACA,SAAO;AACT;;;ACxHA,SAAS,gBAAAG,qBAAoB;;;ACkCtB,SAAS,eAAe,SAA8B,KAAsB;AACjF,SAAO,QAAQ,WAAW,eAAe,QAAQ,QAAQ,aAAa,MAAM,QAAQ,WAAW,KAAK,MAAM;AAC5G;AAUO,SAAS,kBACd,UACA,QACA,KACqB;AACrB,QAAM,UAAU,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;AACzD,QAAM,YAAiC,CAAC;AACxC,aAAW,KAAK,UAAU;AACxB,QAAI,CAAC,eAAe,GAAG,GAAG,KAAK,CAAC,EAAE,cAAe;AACjD,UAAM,IAAI,QAAQ,IAAI,EAAE,aAAa;AACrC,QAAI,CAAC,KAAK,EAAE,WAAW,aAAa;AAClC,gBAAU,KAAK;AAAA,QACb,WAAW,EAAE;AAAA,QACb,eAAe,EAAE;AAAA,QACjB,MAAM;AAAA,QACN,cAAc,EAAE,QAAQ,aAAa,OAAO,QAAQ,qBAAqB,IAAI;AAAA,QAC7E,kBAAkB,EAAE,WAAW,GAAG,aAAa,GAAG;AAAA,MACpD,CAAC;AAAA,IACH,WAAW,EAAE,YAAY,UAAa,EAAE,YAAY,EAAE,SAAS;AAC7D,YAAM,YAAY,EAAE,SAAS,MAAM,EAAE,WAAW;AAChD,gBAAU,KAAK;AAAA,QACb,WAAW,EAAE;AAAA,QACb,eAAe,EAAE;AAAA,QACjB,MAAM;AAAA,QACN,cAAc,EAAE,SAAS,EAAE,SAAS,OAAO,EAAE,SAAS,EAAE,UAAU,UAAU,OAAO,QAAQ,qBAAqB,IAAI;AAAA,QACpH,kBAAkB,EAAE,WAAW,EAAE,QAAQ;AAAA,MAC3C,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;;;ADjEA,eAAe,WACb,KACA,KACA,KACA,KACuE;AACvE,QAAM,QAAQ,IAAI,OAAO,GAAG;AAC5B,QAAM,IAAI,MAAM,IAAI,WAAW,KAAK,GAAG;AACvC,MAAI,CAAC,EAAG,QAAO,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG;AAClD,MAAI,CAAE,MAAM,IAAI,QAAQ,OAAO,CAAC,EAAI,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AAC3E,QAAM,KAAK;AACX,QAAM,UAAU,IAAI,aAAa,IAAI,OAAO,KAAK,IAAI,QAAQ;AAC7D,QAAM,SAAS,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,QAAQ,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC;AAClG,MAAI,CAAC,MAAO,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AACnD,SAAO,EAAE,IAAI,MAAM;AACrB;AAKO,IAAM,wBAA+B,OAAO,KAAK,KAAK,KAAK,QAAQ;AACxE,MAAI,IAAI,aAAa,2BAA4B,IAAI,WAAW,SAAS,IAAI,WAAW,MAAQ,QAAO;AACvG,QAAM,MAAM,MAAM,WAAW,KAAK,KAAK,KAAK,GAAG;AAC/C,MAAI,eAAe,SAAU,QAAO;AACpC,QAAM,EAAE,IAAI,MAAM,IAAI;AAEtB,MAAI,IAAI,WAAW,OAAO;AACxB,WAAO,KAAK,EAAE,YAAY,kBAAkB,MAAM,cAA+C,EAAE,CAAC;AAAA,EACtG;AACA,MAAI;AACJ,MAAI;AACF,WAAO,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC;AAAA,EACpC,QAAQ;AACN,WAAO,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;AAAA,EACjD;AAGA,QAAM,UAAU,mBAAmB,IAAyB;AAC5D,MAAI,CAAC,QAAQ,GAAI,QAAO,KAAK,EAAE,OAAO,6BAA6B,QAAQ,QAAQ,OAAO,GAAG,GAAG;AAChG,QAAM,GAAG,SAAS,CAAC,EAAE,GAAG,UAAU,IAAI,UAAU,IAAI,OAAO,MAAM,EAAE,GAAG,OAAO,EAAE,gBAAgB,QAAQ,MAAM,EAAE,CAAC,CAAC;AACjH,SAAO,KAAK,EAAE,YAAY,QAAQ,MAAM,CAAC;AAC3C;AAEA,eAAe,eAAe,KAAuC;AACnE,QAAM,MAAMC,cAAa,EAAE,OAAO,IAAI,aAAa,KAAK,IAAI,UAAU,YAAY,IAAI,cAAc,UAAU,IAAI,cAAc,CAAC;AACjI,QAAM,MAAM,MAAM,IAAI,aAAa,SAAS;AAC5C,SAAO,IAAI,OAAO,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,QAAQ,EAAE,QAAQ,SAAS,EAAE,SAAS,OAAO,EAAE,MAAM,EAAE;AAC7G;AAEA,SAAS,YAAYC,OAA6D;AAChF,SAAOA,MAAK,IAAI,CAAC,OAAO;AAAA,IACtB,IAAI,OAAO,EAAE,EAAE;AAAA,IACf,eAAe,OAAO,EAAE,aAAa;AAAA,IACrC,eAAe,OAAO,EAAE,kBAAkB,WAAW,EAAE,gBAAgB;AAAA,IACvE,QAAQ,OAAO,EAAE,UAAU,EAAE;AAAA,IAC7B,SAAS,OAAO,EAAE,YAAY,WAAW,EAAE,UAAU;AAAA,IACrD,OAAO,OAAO,EAAE,UAAU,WAAW,EAAE,QAAQ;AAAA,EACjD,EAAE;AACJ;AAIO,IAAM,sBAA6B,OAAO,KAAK,KAAK,KAAK,QAAQ;AACtE,MAAI,IAAI,WAAW,SAAS,IAAI,aAAa,sBAAuB,QAAO;AAC3E,QAAM,QAAQ,IAAI,OAAO,GAAG;AAC5B,QAAM,IAAI,MAAM,IAAI,WAAW,KAAK,GAAG;AACvC,MAAI,CAAC,EAAG,QAAO,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG;AAClD,MAAI,CAAE,MAAM,IAAI,QAAQ,OAAO,CAAC,EAAI,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AAC3E,QAAM,KAAK;AAGX,QAAM,MAAM,IAAI,aAAa,IAAI,KAAK,MAAM;AAC5C,QAAM,OAAO,OAAO,IAAI,aAAa,IAAI,MAAM,CAAC;AAChD,QAAM,KAAK,OAAO,IAAI,aAAa,IAAI,IAAI,CAAC;AAE5C,QAAM,QAAQ,MAAM,GAAG,MAAM;AAAA,IAC3B,UAAU,EAAE,GAAG,EAAE,OAAO,MAAM,CAAC,IAAI,EAAE,QAAQ,YAAY,GAAG,OAAO,EAAE,SAAS,MAAM,GAAG,OAAO,IAAI,EAAE;AAAA,EACtG,CAAC;AACD,MAAIA,QAAQ,MAAM,QAAQ,MAAM,QAAQ,IAAI,MAAM,WAAW,CAAC;AAC9D,MAAI,OAAO,SAAS,IAAI,EAAG,CAAAA,QAAOA,MAAK,OAAO,CAAC,MAAM,OAAO,EAAE,WAAW,CAAC,KAAK,IAAI;AACnF,MAAI,OAAO,SAAS,EAAE,EAAG,CAAAA,QAAOA,MAAK,OAAO,CAAC,MAAM,OAAO,EAAE,WAAW,CAAC,KAAK,EAAE;AAE/E,MAAI,YAAiC,CAAC;AACtC,MAAI;AACF,gBAAY,kBAAkB,YAAYA,KAAI,GAAG,MAAM,eAAe,GAAG,GAAG,KAAK,IAAI,CAAC;AAAA,EACxF,QAAQ;AAAA,EAER;AAGA,QAAM,UAAU,oBAAI,IAAqC;AACzD,aAAW,KAAK,WAAW;AACzB,UAAM,MAAc;AAAA,MAClB,EAAE,GAAG,UAAU,IAAI,YAAY,IAAI,EAAE,WAAW,OAAO,EAAE,aAAa;AAAA,MACtE,EAAE,GAAG,UAAU,IAAI,gBAAgB,IAAI,EAAE,eAAe,OAAO,EAAE,iBAAiB;AAAA,IACpF;AACA,QAAI;AACF,YAAM,GAAG,SAAS,GAAG;AACrB,cAAQ,IAAI,EAAE,WAAW,EAAE,YAAY;AAAA,IACzC,QAAQ;AAAA,IAER;AAAA,EACF;AAKA,QAAM,WAAW,MAAM,GAAG,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,OAAO,IAAK,EAAE,EAAE,CAAC;AACxE,QAAM,OAAO,oBAAI,IAAqC;AACtD,aAAW,KAAK,MAAM,QAAQ,SAAS,YAAY,IAAI,SAAS,eAAe,CAAC,GAAG;AACjF,SAAK,IAAI,OAAO,EAAE,EAAE,GAAG,CAAC;AAAA,EAC1B;AACA,QAAM,cAAc,CAAC,MAA+D;AAClF,UAAM,IAAI,KAAK,IAAI,OAAO,EAAE,aAAa,CAAC;AAC1C,QAAI,CAAC,EAAG,QAAO;AACf,WAAO,EAAE,IAAI,EAAE,IAAI,WAAW,EAAE,WAAW,UAAU,EAAE,UAAU,OAAO,EAAE,OAAO,QAAQ,EAAE,OAAO;AAAA,EACpG;AAEA,QAAM,SAAS,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,IAAI,QAAQ,GAAG,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC;AACzG,QAAM,WAAW,kBAAkB,OAAO,cAA+C,EAAE;AAI3F,QAAM,WAAWA,MACd,IAAI,CAAC,OAAgC,EAAE,GAAG,GAAG,GAAI,QAAQ,IAAI,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,GAAI,WAAW,YAAY,CAAC,EAAE,EAAE,EAC/G,OAAO,CAAC,MAAM,OAAO,EAAE,WAAW,WAAW;AAChD,SAAO,KAAK,EAAE,UAAU,SAAS,UAAU,QAAQ,SAAS,CAAC;AAC/D;;;AElIA,eAAe,UACb,KACA,KACA,KACkF;AAClF,QAAM,QAAQ,IAAI,OAAO,GAAG;AAC5B,QAAM,IAAI,MAAM,IAAI,WAAW,KAAK,GAAG;AACvC,MAAI,CAAC,EAAG,QAAO,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG;AAClD,MAAI,CAAE,MAAM,IAAI,QAAQ,OAAO,CAAC,EAAI,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AAC3E,SAAO,EAAE,IAAI,OAA+B,OAAO,EAAE,QAAQ,EAAE,QAAQ,OAAO,EAAE,SAAS,OAAU,EAAE;AACvG;AAEA,IAAMC,WAAU,CAAC,IAAe,SAAwB;AAAA,EACtD,KAAK,IAAI,QAAQ;AAAA,EACjB;AAAA,EACA,KAAK,MAAM,KAAK,IAAI;AAAA,EACpB,OAAO,MAAM,OAAO,WAAW;AAAA,EAC/B,SAAS,IAAI;AACf;AAIO,IAAM,qBAA4B,OAAO,KAAK,KAAK,KAAK,QAAQ;AACrE,MAAI,IAAI,WAAW,UAAU,IAAI,aAAa,sBAAuB,QAAO;AAC5E,QAAMC,QAAO,MAAM,UAAU,KAAK,KAAK,GAAG;AAC1C,MAAIA,iBAAgB,SAAU,QAAOA;AACrC,QAAM,SAAS,MAAM,YAAYD,SAAQC,MAAK,IAAI,GAAG,CAAC;AACtD,SAAO,KAAK,EAAE,IAAI,MAAM,GAAG,OAAO,CAAC;AACrC;AAKO,IAAM,oBAA2B,OAAO,KAAK,KAAK,KAAK,QAAQ;AACpE,MAAI,IAAI,WAAW,SAAS,IAAI,aAAa,oBAAqB,QAAO;AACzE,QAAMA,QAAO,MAAM,UAAU,KAAK,KAAK,GAAG;AAC1C,MAAIA,iBAAgB,SAAU,QAAOA;AACrC,QAAM,EAAE,GAAG,IAAIA;AAEf,QAAM,KAAK,MAAM,eAAe,IAAI,kBAAkB;AACtD,QAAM,CAAC,MAAM,QAAQ,IAAI,MAAM,QAAQ,IAAI;AAAA,IACzC,GAAG,MAAM;AAAA,MACP,cAAc,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,OAAO,GAAG,OAAO,IAAI,EAAE;AAAA,MAChE,QAAQ,EAAE,GAAG,EAAE,OAAO,IAAI,EAAE;AAAA,IAC9B,CAAC;AAAA,IACD,KAAK,eAAe,EAAE,EAAE,MAAM,MAAM,CAAC,CAAC,IAAI,QAAQ,QAAQ,CAAC,CAAC;AAAA,EAC9D,CAAC;AACD,QAAM,gBAAgB,IAAI,IAAI,SAAS,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAW5D,QAAM,SAAS,oBAAI,IAAuB;AAE1C,aAAW,KAAM,KAAK,UAAU,CAAC,GAAsC;AACrE,QAAI,EAAE,YAAY,KAAM;AACxB,UAAM,QAAQ,OAAO,EAAE,UAAU,WAAW,EAAE,QAAQ;AACtD,QAAI,CAAC,MAAO;AACZ,UAAM,QAAQ,cAAc,IAAI,OAAO,EAAE,EAAE,CAAC;AAC5C,WAAO,IAAI,MAAM,YAAY,GAAG;AAAA,MAC9B;AAAA,MACA,MAAM,OAAO,EAAE,SAAS,WAAW,EAAE,OAAO;AAAA,MAC5C,QAAQ,OAAO,EAAE,OAAO,WAAW,EAAE,KAAK;AAAA,MAC1C,MAAM,OAAO,QAAQ;AAAA,MACrB,SAAS,QAAQ,MAAM,UAAU;AAAA,MACjC,oBAAoB,OAAO,iBAAiB;AAAA,MAC5C,aAAa;AAAA,IACf,CAAC;AAAA,EACH;AACA,aAAW,KAAM,KAAK,gBAAgB,CAAC,GAAsC;AAC3E,UAAM,MAAM,OAAO,EAAE,SAAS,EAAE,EAAE,YAAY;AAC9C,QAAI,CAAC,IAAK;AACV,UAAM,OAAO,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,KAAK;AAC7D,UAAM,MAAM,OAAO,IAAI,GAAG;AAC1B,QAAI,KAAK;AACP,UAAI,CAAC,IAAI,YAAa,KAAI,cAAc,mBAAmB,CAAwD;AACnH,UAAI,CAAC,IAAI,KAAM,KAAI,OAAO;AAAA,IAC5B,OAAO;AACL,aAAO,IAAI,KAAK;AAAA,QACd,OAAO,OAAO,EAAE,KAAK;AAAA,QACrB;AAAA,QACA,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,SAAS;AAAA,QACT,oBAAoB;AAAA,QACpB,aAAa,mBAAmB,CAAwD;AAAA,MAC1F,CAAC;AAAA,IACH;AAAA,EACF;AACA,QAAMC,QAAO,CAAC,GAAG,OAAO,OAAO,CAAC,EAAE;AAAA,IAChC,CAAC,GAAG,OAAQ,EAAE,aAAa,aAAwB,OAAQ,EAAE,aAAa,aAAwB;AAAA,EACpG;AACA,SAAO,KAAK,EAAE,QAAQA,MAAK,CAAC;AAC9B;AAIO,IAAM,0BAAiC,OAAO,KAAK,KAAK,KAAK,QAAQ;AAC1E,MAAI,IAAI,WAAW,SAAS,IAAI,aAAa,2BAA4B,QAAO;AAChF,QAAMD,QAAO,MAAM,UAAU,KAAK,KAAK,GAAG;AAC1C,MAAIA,iBAAgB,SAAU,QAAOA;AACrC,QAAM,EAAE,GAAG,IAAIA;AACf,QAAM,WAAW,IAAI,aAAa,IAAI,QAAQ,KAAK;AACnD,MAAI,CAAC,SAAS,WAAW,OAAO,EAAG,QAAO,KAAK,EAAE,OAAO,iBAAiB,GAAG,GAAG;AAC/E,QAAM,KAAK,MAAM,eAAe,IAAI,kBAAkB;AACtD,MAAI,CAAC,GAAI,QAAO,KAAK,EAAE,OAAO,mEAAmE,GAAG,GAAG;AACvG,QAAM,OAAO,MAAM,aAAa,IAAI,QAAQ;AAC5C,MAAI,CAAC,KAAM,QAAO,KAAK,EAAE,OAAO,0BAA0B,GAAG,GAAG;AAChE,SAAO,KAAK,EAAE,QAAQ,UAAU,MAAM,KAAK,MAAM,OAAO,KAAK,SAAS,MAAM,YAAY,MAAM,IAAI,kBAAkB,IAAa,KAAK,KAAK,EAAE,CAAC;AAChJ;AAKO,IAAM,wBAA+B,OAAO,KAAK,KAAK,KAAK,QAAQ;AACxE,MAAI,IAAI,WAAW,UAAU,IAAI,aAAa,yBAA0B,QAAO;AAC/E,QAAMA,QAAO,MAAM,UAAU,KAAK,KAAK,GAAG;AAC1C,MAAIA,iBAAgB,SAAU,QAAOA;AACrC,QAAM,EAAE,IAAI,MAAM,IAAIA;AAEtB,MAAI;AACJ,MAAI;AACF,WAAQ,MAAM,IAAI,KAAK;AAAA,EACzB,QAAQ;AACN,WAAO,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;AAAA,EACjD;AACA,QAAM,WAAW,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS;AACjE,QAAM,UAAU,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO;AAC5D,MAAI,CAAC,SAAS,WAAW,OAAO,EAAG,QAAO,KAAK,EAAE,OAAO,iBAAiB,GAAG,GAAG;AAE/E,QAAM,KAAK,MAAM,eAAe,IAAI,kBAAkB;AACtD,MAAI,CAAC,GAAI,QAAO,KAAK,EAAE,OAAO,mEAAmE,GAAG,GAAG;AACvG,QAAM,SAAS,MAAM,aAAa,IAAI,QAAQ;AAE9C,QAAM,QAAQ,cAAc;AAAA,IAC1B,SAAS,MAAM;AAAA,IACf,cAAc,MAAM,IAAI,kBAAkB,IAAa,MAAM,KAAK;AAAA,IAClE;AAAA,IACA,mBAAmB,QAAQ,QAAQ;AAAA,IACnC,eAAe,MAAM,IAAI,kBAAkB,IAAa,QAAQ,KAAK;AAAA,IACrE;AAAA,IACA,MAAM,IAAI,QAAQ;AAAA,EACpB,CAAC;AACD,MAAI,CAAC,MAAM,GAAI,QAAO,KAAK,EAAE,OAAO,MAAM,MAAM,GAAG,MAAM,MAAM;AAE/D,MAAI,CAAE,MAAM,aAAa,IAAI,UAAU,OAAO,EAAI,QAAO,KAAK,EAAE,OAAO,8BAA8B,GAAG,GAAG;AAC3G,SAAO,KAAK,EAAE,IAAI,KAAK,CAAC;AAC1B;;;ACvJA,IAAM,MAAM,CAAC,OAAgC,QAC3C,OAAO,UAAU,eAAe,KAAK,OAAO,GAAG;AAEjD,SAAS,UAAU,OAAwB;AACzC,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,IAAI,MAAM,IAAI,SAAS,EAAE,KAAK,GAAG,CAAC;AACnE,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,WAAO,IAAI,OAAO,QAAQ,KAAgC,EACvD,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,EACrC,IAAI,CAAC,CAAC,KAAK,IAAI,MAAM,GAAG,KAAK,UAAU,GAAG,CAAC,IAAI,UAAU,IAAI,CAAC,EAAE,EAChE,KAAK,GAAG,CAAC;AAAA,EACd;AACA,SAAO,KAAK,UAAU,KAAK,KAAK;AAClC;AAEA,SAAS,YAAY,KAAoB,UAAkB,KAAqB;AAC9E,QAAM,SAAS,OAAO,GAAG;AACzB,SAAO,OAAO,cAAc,MAAM,KAAK,UAAU,IAC7C,KAAK,IAAI,QAAQ,GAAG,IACpB;AACN;AAOO,IAAM,qCAA4C,OAAO,KAAK,KAAK,KAAK,QAAQ;AACrF,MAAI,IAAI,WAAW,UAAU,IAAI,aAAa,yCAA0C,QAAO;AAC/F,QAAM,QAAQ,IAAI,OAAO,GAAG;AAC5B,QAAM,QAAQ,MAAM,IAAI,WAAW,KAAK,GAAG;AAC3C,MAAI,CAAC,MAAO,QAAO,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG;AACtD,MAAI,CAAE,MAAM,IAAI,QAAQ,OAAO,KAAK,EAAI,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AAC/E,MAAI,IAAI,QAAQ,SAAS,aAAa,IAAI,QAAQ,YAAY,QAAQ;AACpE,WAAO,KAAK,EAAE,OAAO,uEAAuE,GAAG,GAAG;AAAA,EACpG;AACA,QAAM,KAAK;AACX,QAAM,SAAS,MAAM,eAAe,IAAI,kBAAkB;AAC1D,MAAI,CAAC,OAAQ,QAAO,KAAK,EAAE,OAAO,sCAAsC,GAAG,GAAG;AAE9E,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,eAAe,MAAM;AAAA,EACnC,QAAQ;AACN,WAAO,KAAK,EAAE,OAAO,4BAA4B,GAAG,GAAG;AAAA,EACzD;AACA,QAAM,SAAS,YAAY,IAAI,aAAa,IAAI,QAAQ,GAAG,GAAG,OAAO,gBAAgB;AACrF,QAAM,QAAQ,YAAY,IAAI,aAAa,IAAI,OAAO,GAAG,IAAI,GAAG,KAAK;AACrE,QAAM,QAAQ,IAAI,MAAM,QAAQ,SAAS,KAAK;AAC9C,QAAM,SAAS,EAAE,SAAS,GAAG,gBAAgB,GAAG,eAAe,GAAG,QAAQ,EAAE;AAE5E,aAAW,QAAQ,OAAO;AACxB,QAAI,CAAC,KAAK,OAAO;AACf,aAAO,iBAAiB;AACxB;AAAA,IACF;AACA,UAAM,QAAQ,MAAM,GAAG,MAAM;AAAA,MAC3B,cAAc,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,KAAK,MAAM,GAAG,OAAO,EAAE,WAAW,OAAO,GAAG,OAAO,EAAE,EAAE;AAAA,IAC9F,CAAC,GAAG;AACJ,UAAM,MAAM,MAAM,QAAQ,IAAI,IAAI,KAAK,CAAC,IAAI;AAC5C,QAAI,CAAC,OAAO,OAAO,IAAI,OAAO,UAAU;AACtC,aAAO,iBAAiB;AACxB;AAAA,IACF;AAEA,UAAM,UAAU,yBAAyB,IAAI,SAAS,IAAI,IAAI,GAAG;AACjE,UAAM,iBAAiB,QAAQ,WAAW,CAAC;AAC3C,UAAM,eAAe,IAAI,KAAK,gBAAgB,eAAe,KAAK,IAAI,KAAK,gBAAgB,SAAS;AACpG,UAAM,UAAU,KAAK,kBAAkB,IAAI,MAAM,UAAU,KAAK,OAAO,MAAM,UAAU,cAAc;AACrG,QAAI;AACF,UAAI,UAAU;AACd,UAAI,CAAC,WAAW,cAAc;AAC5B,cAAM,KAAK,MAAM,wBAAwB,QAAQ,KAAK,IAAI;AAAA,UACxD,gBAAgB;AAAA,UAChB,iBAAiB,yBAAyB,IAAI,SAAS,IAAI,IAAI,KAAK,IAAI;AAAA,QAC1E,CAAC;AACD,YAAI,CAAC,IAAI;AACP,iBAAO,UAAU;AACjB;AAAA,QACF;AACA,kBAAU;AAAA,MACZ;AACA,YAAM,0BAA0B,IAAI,IAAI,IAAI,KAAK,EAAE;AACnD,UAAI,QAAS,QAAO,WAAW;AAAA,UAC1B,QAAO,kBAAkB;AAAA,IAChC,QAAQ;AACN,aAAO,UAAU;AAAA,IACnB;AAAA,EACF;AAEA,QAAM,aAAa,SAAS,MAAM,SAAS,IAAI,SAC3C,SAAS,MAAM,SACf;AACJ,SAAO,KAAK;AAAA,IACV,YAAY,IAAI;AAAA,IAChB;AAAA,IACA,WAAW,MAAM;AAAA,IACjB;AAAA,IACA,GAAG;AAAA,EACL,CAAC;AACH;;;AC3EA,SAAS,aACP,QACA,KACA,OACA,UACuB;AACvB,QAAM,QAAQ,MAAM,QAAQ;AAC5B,QAAM,gBAAgB,QAAQ,QAAQ;AACtC,QAAM,UAAU,MAAM,KAAK,EAAE,QAAQ,MAAM,GAAG,MAAM,CAAC;AACrD,QAAM,WAAW,MAAM,KAAK,EAAE,QAAQ,MAAM,GAAG,MAAM,CAAC;AACtD,aAAW,SAAS,QAAQ;AAC1B,QAAI,CAAC,OAAO,SAAS,MAAM,CAAC,KAAK,CAAC,OAAO,SAAS,MAAM,CAAC,EAAG;AAC5D,QAAI,MAAM,KAAK,SAAS,MAAM,KAAK,KAAK;AACtC,YAAM,QAAQ,KAAK,IAAI,QAAQ,GAAG,KAAK,OAAO,MAAM,IAAI,SAAS,QAAQ,CAAC;AAC1E,cAAQ,KAAK,KAAK,QAAQ,KAAK,KAAK,KAAK,MAAM;AAAA,IACjD,WAAW,MAAM,KAAK,iBAAiB,MAAM,IAAI,OAAO;AACtD,YAAM,QAAQ,KAAK,IAAI,QAAQ,GAAG,KAAK,OAAO,MAAM,IAAI,iBAAiB,QAAQ,CAAC;AAClF,eAAS,KAAK,KAAK,SAAS,KAAK,KAAK,KAAK,MAAM;AAAA,IACnD;AAAA,EACF;AACA,QAAM,SAAS,QAAQ,IAAI,CAAC,GAAG,UAC7B,IAAI,KAAK,QAAQ,QAAQ,QAAQ,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AAC/D,SAAO,EAAE,QAAQ,SAAS,SAAS;AACrC;AAGO,SAAS,oBACd,QACA,KACqB;AACrB,QAAM,MAAM;AACZ,SAAO;AAAA,IACL,KAAK,aAAa,QAAQ,KAAK,GAAG,GAAG;AAAA,IACrC,KAAK,aAAa,QAAQ,KAAK,GAAG,IAAI,GAAG;AAAA,EAC3C;AACF;AAKO,SAAS,eAAe,KAAsC;AACnE,QAAM,QAAU,IAAI,OAAiE,QAAQ,CAAC;AAC9F,MAAI,QAAQ;AACZ,aAAW,MAAM,OAAO;AACtB,UAAM,QAAS,GAAG,SAAS,CAAC;AAC5B,UAAM,OAAO,MAAM,eAAe,MAAO,GAAG,YAAuB;AACnE,aAAS,MAAM,WAAW,aAAa,UAAU,MAAM,KAAK;AAAA,EAC9D;AACA,SAAO;AACT;;;AC3EA,eAAeE,MAAK,KAAc,KAAiB,KAAmD;AACpG,QAAM,QAAQ,IAAI,OAAO,GAAG;AAC5B,QAAM,IAAI,MAAM,IAAI,WAAW,KAAK,GAAG;AACvC,MAAI,CAAC,EAAG,QAAO,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG;AAClD,MAAI,CAAE,MAAM,IAAI,QAAQ,OAAO,CAAC,EAAI,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AAC3E,SAAO;AACT;AAEA,IAAMC,QAAO,CAA8B,MAAqB,MAAM,QAAQ,CAAC,IAAK,IAAY,CAAC;AAK1F,IAAM,uBAA8B,OAAO,KAAK,KAAK,KAAK,QAAQ;AACvE,MAAI,IAAI,WAAW,SAAS,IAAI,aAAa,uBAAwB,QAAO;AAC5E,QAAM,MAAM,MAAMD,MAAK,KAAK,KAAK,GAAG;AACpC,MAAI,eAAe,SAAU,QAAO;AACpC,QAAM,KAAK;AAEX,QAAM,MAAM,KAAK,IAAI;AACrB,QAAM,KAAK,MAAM,IAAI;AACrB,QAAM,MAAM,MAAM,KAAK;AACvB,QAAM,OAAO,MAAM,GAAG,MAAM;AAAA,IAC1B,cAAc,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,OAAO,GAAG,OAAO,IAAK,EAAE;AAAA,IACjE,UAAU;AAAA,MACR,GAAG;AAAA,QACD,OAAO,EAAE,QAAQ,YAAY;AAAA,QAC7B,OAAO,EAAE,SAAS,MAAM;AAAA,QACxB,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,YAAY,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,SAAS,GAAG,OAAO,IAAK,EAAE;AAAA,IAC5D,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,IAAI,QAAQ,GAAG,GAAG,OAAO,EAAE,EAAE;AAAA,EAC3D,CAAC;AACD,QAAM,OAAOC,MAAK,KAAK,YAAY;AACnC,QAAM,eAAe;AAAA,IACnB,OAAO,KAAK;AAAA,IACZ,OAAO,KAAK,OAAO,CAAC,MAAO,EAAE,aAAwB,EAAE,EAAE;AAAA,IACzD,QAAQ,KAAK,OAAO,CAAC,MAAO,EAAE,aAAwB,GAAG,EAAE;AAAA,EAC7D;AACA,QAAM,WAAmC,CAAC;AAC1C,QAAM,gBAAwC,CAAC;AAC/C,aAAW,KAAK,IAAI,QAAQ,SAAS,QAAQ;AAC3C,aAAS,CAAC,IAAI;AACd,kBAAc,CAAC,IAAI;AAAA,EACrB;AACA,aAAW,KAAKA,MAAK,KAAK,UAAU,GAAG;AACrC,UAAM,IAAI,EAAE;AACZ,QAAI,KAAK,UAAU;AACjB,eAAS,CAAC,KAAK,SAAS,CAAC,KAAK,KAAK;AACnC,YAAM,KAAK,OAAO,EAAE,mBAAmB,WAAW,EAAE,iBAAiB,KAAK,MAAM,OAAO,EAAE,cAAc,CAAC;AACxG,UAAI,OAAO,SAAS,EAAE,KAAK,MAAM,GAAI,eAAc,CAAC,KAAK,cAAc,CAAC,KAAK,KAAK;AAAA,IACpF;AAAA,EACF;AAEA,QAAM,WAAWA,MAAK,KAAK,QAAQ;AACnC,QAAM,UAAU,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAClD,QAAM,WAAW,SAAS,OAAO,CAAC,MAAO,EAAE,WAAsB,MAAM,IAAS;AAChF,QAAM,QAAQ,EAAE,UAAU,SAAS,QAAQ,gBAAgB,SAAS,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,MAAM,EAAE,OAAO;AACxH,QAAM,SAAS,SAAS,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM;AAC7C,UAAM,IAAI,QAAQ,IAAI,EAAE,aAAa;AACrC,WAAO;AAAA,MACL,IAAI,EAAE;AAAA,MACN,SAAS,EAAE;AAAA,MACX,SAAS,EAAE,WAAW;AAAA,MACtB,UAAU,EAAE,YAAY;AAAA,MACxB,OAAO,EAAE,SAAS;AAAA,MAClB,MAAM,IAAI,GAAG,EAAE,SAAS,IAAI,EAAE,QAAQ,KAAK;AAAA,MAC3C,OAAQ,GAAG,SAAoB;AAAA,IACjC;AAAA,EACF,CAAC;AACD,QAAM,QAAQ,KAAK,SAAS,CAAC;AAC7B,QAAM,WAAW,kBAAkB,OAAO,cAA+C,EAAE;AAE3F,MAAI,UAAmC,EAAE,cAAc,MAAM;AAC7D,MAAI,gBAAyB;AAC7B,MAAI,gBAAyB;AAC7B,QAAM,KAAK,MAAM,eAAe,IAAI,mBAAmB;AACvD,MAAI,IAAI;AACN,UAAM,UAAU,MAAM,WAAW,IAAI,OAAO,qBAAqB,EAAE,OAAO,KAAK,QAAQ,MAAM,CAAC;AAC9F,QAAI,QAAQ,IAAI;AACd,YAAM,OAAOA,MAAK,QAAQ,KAAK,IAAI;AACnC,YAAM,QAAQ,CAAC,OAAiC,EAAE,WAAsB,KAAK;AAC7E,sBAAgB,oBAAoB,KAAK,IAAI,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,GAAG,GAAG,EAAE,EAAE,GAAG,GAAG;AACjF,sBAAgB,oBAAoB,KAAK,IAAI,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,GAAG,GAAG,eAAe,CAAC,EAAE,EAAE,GAAG,GAAG;AACjG,YAAM,SAAS,KAAK,OAAO,CAAC,MAAM,EAAE,WAAW,QAAQ;AACvD,gBAAU;AAAA,QACR,cAAc;AAAA,QACd,UAAU,OAAO,OAAO,wBAAwB,EAAE,EAAE,WAAW,SAAS;AAAA,QACxE,aAAa,OAAO;AAAA,QACpB,oBAAoB,OAAO,OAAO,CAAC,KAAK,MAAM,MAAM,eAAe,CAAC,GAAG,CAAC;AAAA,QACxE,UAAU,KAAK,OAAO,CAAC,MAAM,MAAM,CAAC,KAAK,EAAE,EAAE;AAAA,QAC7C,WAAW,KAAK,OAAO,CAAC,MAAM,MAAM,CAAC,KAAK,GAAG,EAAE;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AACA,QAAM,qBAAqB,oBAAoB,KAAK,IAAI,CAAC,OAAO,EAAE,GAAI,EAAE,aAAwB,GAAG,GAAG,EAAE,EAAE,GAAG,GAAG;AAChH,SAAO,KAAK,EAAE,cAAc,oBAAoB,UAAU,eAAe,OAAO,QAAQ,UAAU,SAAS,eAAe,cAAc,CAAC;AAC3I;AAWO,IAAM,qBAA4B,OAAO,KAAK,KAAK,KAAK,QAAQ;AACrE,MAAI,IAAI,WAAW,SAAS,IAAI,aAAa,qBAAsB,QAAO;AAC1E,QAAM,MAAM,MAAMD,MAAK,KAAK,KAAK,GAAG;AACpC,MAAI,eAAe,SAAU,QAAO;AACpC,QAAM,KAAK;AAEX,QAAM,KAAK,MAAM,eAAe,IAAI,mBAAmB;AACvD,MAAI,CAAC,GAAI,QAAO,KAAK,EAAE,cAAc,OAAO,MAAM,CAAC,GAAG,SAAS,KAAK,CAAC;AACrE,QAAM,CAAC,MAAM,OAAO,IAAI,MAAM,QAAQ,IAAI;AAAA,IACxC,GAAG,MAAM;AAAA,MACP,cAAc,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,OAAO,GAAG,OAAO,IAAI,EAAE;AAAA,MAChE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,IAAI,QAAQ,GAAG,GAAG,OAAO,EAAE,EAAE;AAAA,IAC3D,CAAC;AAAA,IACD,WAAW,IAAI,OAAO,qBAAqB,EAAE,OAAO,KAAK,QAAQ,MAAM,CAAC;AAAA,EAC1E,CAAC;AACD,QAAM,WAAW,OAAO,KAAK,SAAS,CAAC,GAAG,wBAAwB,EAAE,EAAE,WAAW,SAAS;AAC1F,MAAI,CAAC,QAAQ,GAAI,QAAO,KAAK,EAAE,OAAO,iCAAiC,GAAG,GAAG;AAC7E,QAAM,UAAU,IAAI,IAAIC,MAAK,QAAQ,KAAK,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,IAAc,CAAC,CAAC,CAAC;AAE/E,QAAM,cAAc,CAAC;AACrB,aAAW,KAAKA,MAAK,KAAK,YAAY,GAAG;AACvC,QAAI,CAAC,EAAE,oBAAoB,CAAC,EAAE,qBAAsB;AACpD,UAAM,MAAM,EAAE,uBAAuB,QAAQ,IAAI,EAAE,oBAA8B,IAAI;AACrF,UAAM,QAAS,KAAK,OAA4C,QAAQ,CAAC;AACzE,QAAI,cAAc;AAClB,QAAI,WAAW;AACf,eAAW,MAAM,OAAO;AACtB,sBAAgB,GAAG,OAAO,eAAe,MAAM,GAAG,YAAY;AAC9D,iBAAW,GAAG,OAAO,WAAW,YAAY;AAAA,IAC9C;AACA,UAAM,YAAa,KAAK,sBAA6C,MAAM,CAAC,GAAG;AAC/E,gBAAY,KAAK;AAAA,MACf,IAAI,EAAE;AAAA,MACN,MAAM,GAAG,EAAE,SAAS,IAAI,EAAE,QAAQ;AAAA,MAClC,OAAO,EAAE;AAAA,MACT,mBAAmB,EAAE;AAAA,MACrB,oBAAqB,KAAK,UAAqB;AAAA,MAC/C,mBAAmB,KAAK,yBAAyB;AAAA,MACjD;AAAA,MACA;AAAA,MACA,WAAW,YAAY,YAAY,MAAS,EAAE,aAAwB;AAAA,IACxE,CAAC;AAAA,EACH;AACA,QAAM,WAAW,YAAY,OAAO,CAAC,MAAM,EAAE,uBAAuB,YAAY,CAAC,EAAE,iBAAiB;AACpG,QAAM,aAAa,KAAK,IAAI,IAAI,KAAK;AACrC,QAAM,UAAU;AAAA,IACd,aAAa,YAAY,OAAO,CAAC,MAAM,EAAE,uBAAuB,QAAQ,EAAE;AAAA,IAC1E,iBAAiB,SAAS,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,eAAe,EAAE,aAAa,UAAU,KAAK,IAAI,CAAC;AAAA,IACnG,mBAAmB,SAAS,OAAO,CAAC,MAAM,EAAE,aAAa,EAAE,YAAY,UAAU,EAAE;AAAA,IACnF,cAAc,YAAY,OAAO,CAAC,MAAM,EAAE,uBAAuB,UAAU,EAAE;AAAA,IAC7E,eAAe,YAAY,OAAO,CAAC,MAAM,EAAE,uBAAuB,cAAc,EAAE,iBAAiB,EAAE;AAAA,IACrG,eAAe,YAAY,OAAO,CAAC,MAAM,EAAE,sBAAsB,UAAU,EAAE;AAAA,EAC/E;AACA,SAAO,KAAK;AAAA,IACV,cAAc;AAAA,IACd;AAAA,IACA,WAAW,QAAQ,KAAK,aAAa;AAAA,IACrC,MAAM;AAAA,IACN;AAAA,EACF,CAAC;AACH;;;AClLA,SAAS,wBAAAC,uBAAsB,gBAAAC,qBAAoB;AAYnD,eAAeC,MAAK,KAAc,KAAiB,KAAmD;AACpG,QAAM,QAAQ,IAAI,OAAO,GAAG;AAC5B,QAAM,IAAI,MAAM,IAAI,WAAW,KAAK,GAAG;AACvC,MAAI,CAAC,EAAG,QAAO,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG;AAClD,MAAI,CAAE,MAAM,IAAI,QAAQ,OAAO,CAAC,EAAI,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AAC3E,SAAO;AACT;AAEA,IAAM,SAAS,CAAC,QACdC,cAAa,EAAE,OAAO,IAAI,aAAa,KAAK,IAAI,UAAU,YAAY,IAAI,cAAc,UAAU,IAAI,cAAc,CAAC;AACvH,IAAM,WAAW,OAAO,QAA0D;AAChF,MAAI;AACF,WAAQ,MAAM,IAAI,KAAK;AAAA,EACzB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AACA,eAAe,QAAQ,IAAe,IAAqD;AACzF,QAAM,EAAE,aAAa,IAAI,MAAM,GAAG,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC;AAC5F,SAAO,eAAe,CAAC,KAAK;AAC9B;AACA,eAAe,UAAU,IAAe,IAAqD;AAC3F,QAAM,EAAE,OAAO,IAAI,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC;AAChF,SAAO,SAAS,CAAC,KAAK;AACxB;AAIO,IAAM,+BAAsC,OAAO,KAAK,KAAK,KAAK,QAAQ;AAC/E,QAAM,IAAI,IAAI,SAAS,MAAM,oDAAoD;AACjF,MAAI,IAAI,WAAW,UAAU,CAAC,EAAG,QAAO;AACxC,QAAM,MAAM,MAAMD,MAAK,KAAK,KAAK,GAAG;AACpC,MAAI,eAAe,SAAU,QAAO;AACpC,QAAM,KAAK;AACX,QAAM,OAAO,MAAM,SAAS,GAAG;AAC/B,QAAM,UAAU,OAAO,MAAM,OAAO;AACpC,MAAI,CAAC,OAAO,SAAS,OAAO,EAAG,QAAO,KAAK,EAAE,OAAO,mBAAmB,GAAG,GAAG;AAE7E,QAAM,EAAE,SAAS,IAAI,MAAM,GAAG,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC;AAC1F,QAAM,UAAU,WAAW,CAAC;AAC5B,MAAI,CAAC,QAAS,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AACrD,MAAI,QAAQ,WAAW,YAAa,QAAO,KAAK,EAAE,OAAO,uBAAuB,GAAG,GAAG;AACtF,MAAI,CAAC,QAAQ,cAAe,QAAO,KAAK,EAAE,OAAO,4BAA4B,GAAG,GAAG;AAEnF,QAAM,MAAM,mBAAmB,MAAM,UAAU,IAAI,OAAO,QAAQ,WAAW,IAAI,QAAQ,EAAE,CAAC,IAAI,cAA+C;AAC/I,QAAM,QAAQ,WAAW,SAAS,IAAI,WAAW;AACjD,QAAM,MAAM,OAAO,GAAG;AACtB,MAAI;AACF,UAAM,EAAE,MAAM,GAAG,IAAI,WAAW,KAAK,IAAI,GAAG,IAAI,UAAU;AAC1D,UAAM,KAAK,MAAM,IAAI,aAAa,SAAS,EAAE,SAAS,MAAM,SAAS,GAAG,CAAC;AACzE,UAAM,QAAQE,sBAAqB,GAAG,MAAM;AAAA,MAC1C,MAAM,GAAG;AAAA,MACT,IAAI,GAAG;AAAA,MACP,UAAU,IAAI;AAAA,MACd,aAAa,IAAI;AAAA,MACjB,eAAe,EAAE,MAAM,CAAC,GAAG,IAAI,IAAI,GAAG,WAAW,IAAI,WAAW,SAAS,IAAI,QAAQ;AAAA,MACrF,aAAa,IAAI,iBAAiB;AAAA,IACpC,CAAC;AACD,QAAI,CAAC,gBAAgB,OAAO,OAAO,EAAG,QAAO,KAAK,EAAE,OAAO,4BAA4B,MAAM,4BAA4B,GAAG,GAAG;AAC/H,UAAM,IAAI,QAAQ,WAAW,OAAO,QAAQ,aAAa,GAAG;AAAA,MAC1D,gBAAgB,WAAW,OAAO,QAAQ,EAAE,CAAC,eAAe,OAAO,IAAI,KAAK;AAAA,MAC5E;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,QAAQ;AACN,WAAO,KAAK,EAAE,OAAO,6BAA6B,GAAG,GAAG;AAAA,EAC1D;AACA,QAAM,GAAG,SAAS,CAAC,EAAE,GAAG,UAAU,IAAI,YAAY,IAAI,OAAO,QAAQ,EAAE,GAAG,OAAO,wBAAwB,SAAS,KAAK,EAAE,CAAC,CAAC;AAC3H,QAAM,GAAG,SAAS,CAAC,EAAE,GAAG,UAAU,IAAI,gBAAgB,IAAI,OAAO,QAAQ,aAAa,GAAG,OAAO,EAAE,WAAW,QAAQ,EAAE,CAAC,CAAC;AACzH,SAAO,KAAK,EAAE,IAAI,MAAM,SAAS,MAAM,CAAC;AAC1C;AAIO,IAAM,2BAAkC,OAAO,KAAK,KAAK,KAAK,QAAQ;AAC3E,QAAM,IAAI,IAAI,SAAS,MAAM,gDAAgD;AAC7E,MAAI,IAAI,WAAW,UAAU,CAAC,EAAG,QAAO;AACxC,QAAM,MAAM,MAAMF,MAAK,KAAK,KAAK,GAAG;AACpC,MAAI,eAAe,SAAU,QAAO;AACpC,QAAM,KAAK;AAEX,QAAM,EAAE,SAAS,IAAI,MAAM,GAAG,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC;AAC1F,QAAM,UAAU,WAAW,CAAC;AAC5B,MAAI,CAAC,QAAS,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AACrD,MAAI,QAAQ,WAAW,YAAa,QAAO,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;AACnF,MAAI,QAAQ,eAAe;AACzB,QAAI;AACF,YAAM,OAAO,GAAG,EAAE,QAAQ,OAAO,OAAO,QAAQ,aAAa,GAAG;AAAA,QAC9D,gBAAgB,WAAW,OAAO,QAAQ,EAAE,CAAC;AAAA,MAC/C,CAAC;AAAA,IACH,QAAQ;AACN,aAAO,KAAK,EAAE,OAAO,yBAAyB,GAAG,GAAG;AAAA,IACtD;AAAA,EACF;AACA,QAAM,GAAG,SAAS,CAAC,EAAE,GAAG,UAAU,IAAI,YAAY,IAAI,OAAO,QAAQ,EAAE,GAAG,OAAO,EAAE,QAAQ,aAAa,OAAO,OAAO,EAAE,CAAC,CAAC;AAC1H,QAAM,GAAG,SAAS,CAAC,EAAE,GAAG,UAAU,IAAI,gBAAgB,IAAI,OAAO,QAAQ,aAAa,GAAG,OAAO,EAAE,WAAW,GAAG,aAAa,GAAG,EAAE,CAAC,CAAC;AACpI,SAAO,KAAK,EAAE,IAAI,KAAK,CAAC;AAC1B;AAKO,IAAM,qBAA4B,OAAO,KAAK,KAAK,KAAK,QAAQ;AACrE,QAAM,IAAI,IAAI,SAAS,MAAM,qDAAqD;AAClF,MAAI,IAAI,WAAW,UAAU,CAAC,EAAG,QAAO;AACxC,QAAM,MAAM,MAAMA,MAAK,KAAK,KAAK,GAAG;AACpC,MAAI,eAAe,SAAU,QAAO;AACpC,QAAM,KAAK;AACX,QAAM,KAAK,EAAE,CAAC;AAEd,QAAM,MAAM,MAAM,QAAQ,IAAI,EAAE;AAChC,MAAI,CAAC,IAAK,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AACjD,QAAM,SAAS,MAAM,mBAAmB,EAAE,IAAI,KAAK,KAAK,KAAK,QAAQ,IAAI,QAAQ,QAAQ,SAAS,CAAC;AACnG,MAAI,CAAC,OAAO,GAAI,QAAO,KAAK,EAAE,OAAO,OAAO,MAAM,GAAG,OAAO,MAAM;AAClE,SAAO,KAAK,EAAE,IAAI,MAAM,QAAQ,YAAY,cAAc,OAAO,cAAc,aAAa,OAAO,YAAY,CAAC;AAClH;AAKO,IAAM,oBAA2B,OAAO,KAAK,KAAK,KAAK,QAAQ;AACpE,QAAM,IAAI,IAAI,SAAS,MAAM,oDAAoD;AACjF,MAAI,IAAI,WAAW,UAAU,CAAC,EAAG,QAAO;AACxC,QAAM,MAAM,MAAMA,MAAK,KAAK,KAAK,GAAG;AACpC,MAAI,eAAe,SAAU,QAAO;AACpC,QAAM,KAAK;AAEX,QAAM,MAAM,MAAM,QAAQ,IAAI,EAAE,CAAC,CAAW;AAC5C,MAAI,CAAC,IAAK,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AACjD,MAAI,IAAI,WAAW,WAAY,QAAO,KAAK,EAAE,OAAO,mBAAmB,GAAG,GAAG;AAC7E,QAAM,cAAc,IAAI,QAAQ,WAAW,OAAO;AAClD,MAAI,eAAe,CAAC,YAAY,SAAS,OAAO,IAAI,MAAM,CAAC,GAAG;AAC5D,WAAO,KAAK,EAAE,OAAO,8BAA8B,OAAO,IAAI,MAAM,CAAC,IAAI,GAAG,GAAG;AAAA,EACjF;AACA,QAAM,iBAAiB,IAAI;AAC3B,QAAM,aAAa,IAAI;AACvB,MAAI,CAAC,WAAY,QAAO,KAAK,EAAE,OAAO,sBAAsB,GAAG,GAAG;AAClE,QAAM,KAAK,MAAM,eAAe,IAAI,mBAAmB;AACvD,MAAI,CAAC,GAAI,QAAO,KAAK,EAAE,OAAO,0BAA0B,GAAG,GAAG;AAE9D,QAAM,UAAU,MAAM,WAAW,IAAI,OAAO,eAAe,EAAE,UAAU,YAAY,OAAO,IAAI,CAAC;AAC/F,MAAI,CAAC,QAAQ,GAAI,QAAO,KAAK,EAAE,OAAO,yBAAyB,GAAG,GAAG;AACrE,QAAM,aAAc,QAAQ,KAAK,QAA2C,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,WAAW,eAAe,EAAE,aAAa,IAAI;AAC7I,QAAM,cAAc,UAAU,UAAU,SAAS,CAAC;AAClD,MAAI,CAAC,YAAa,QAAO,KAAK,EAAE,OAAO,2BAA2B,GAAG,GAAG;AAExE,QAAM,SAAS,MAAM,WAAW,IAAI,QAAQ,eAAe,EAAE,QAAQ,OAAO,YAAY,EAAE,EAAE,CAAC;AAC7F,MAAI,CAAC,OAAO,GAAI,QAAO,KAAK,EAAE,OAAO,yBAAyB,GAAG,GAAG;AACpE,MAAI,uBAAuB;AAC3B,MAAI,IAAI,QAAQ,WAAW,OAAO,sBAAsB,gBAAgB;AACtE,UAAM,SAAS,MAAM,WAAW,IAAI,UAAU,qBAAqB,cAAc,EAAE;AACnF,2BAAuB,OAAO;AAAA,EAChC;AACA,SAAO,KAAK,EAAE,IAAI,MAAM,eAAgB,OAAO,KAAK,UAAqB,MAAM,qBAAqB,CAAC;AACvG;AAKO,IAAM,8BAAqC,OAAO,KAAK,KAAK,KAAK,QAAQ;AAC9E,QAAM,IAAI,IAAI,SAAS,MAAM,4CAA4C;AACzE,MAAI,IAAI,WAAW,WAAW,CAAC,EAAG,QAAO;AACzC,QAAM,MAAM,MAAMA,MAAK,KAAK,KAAK,GAAG;AACpC,MAAI,eAAe,SAAU,QAAO;AACpC,QAAM,KAAK;AACX,QAAM,KAAK,EAAE,CAAC;AACd,QAAM,OAAO,MAAM,SAAS,GAAG;AAC/B,MAAI,CAAC,KAAM,QAAO,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;AAE1D,QAAM,MAAM,MAAM,QAAQ,IAAI,EAAE;AAChC,MAAI,CAAC,IAAK,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AAEjD,QAAM,QAAiC,CAAC;AACxC,MAAI,KAAK,WAAW,QAAW;AAC7B,UAAM,KAAK,OAAO,KAAK,MAAM;AAC7B,QAAI,CAAC,IAAI,QAAQ,SAAS,OAAO,SAAS,EAAE,EAAG,QAAO,KAAK,EAAE,OAAO,0BAA0B,IAAI,QAAQ,SAAS,OAAO,KAAK,IAAI,CAAC,GAAG,GAAG,GAAG;AAC7I,QAAI,CAAC,cAAc,OAAO,IAAI,MAAM,GAAG,IAAI,IAAI,QAAQ,QAAQ,EAAG,QAAO,KAAK,EAAE,OAAO,qBAAqB,OAAO,IAAI,MAAM,CAAC,SAAS,EAAE,IAAI,GAAG,GAAG;AACnJ,UAAM,SAAS;AAAA,EACjB;AACA,MAAI,KAAK,cAAc,QAAW;AAChC,QAAI,OAAO,KAAK,cAAc,YAAY,CAAC,OAAO,SAAS,KAAK,SAAS,EAAG,QAAO,KAAK,EAAE,OAAO,uCAAuC,GAAG,GAAG;AAC9I,UAAM,YAAY,KAAK;AAAA,EACzB;AACA,MAAI,OAAO,KAAK,KAAK,EAAE,WAAW,EAAG,QAAO,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;AAEpF,QAAM,GAAG,SAAS,CAAC,EAAE,GAAG,UAAU,IAAI,gBAAgB,IAAI,MAAM,CAAC,CAAC;AAClE,MAAI,MAAM,WAAW,QAAW;AAC9B,UAAM,qBAAqB,QAAQ,IAAI,GAAG,GAAG,EAAE,KAAK,EAAE,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,OAAO,MAAM,MAAM,EAAE,CAAC,EAAE,MAAM,MAAM,MAAS;AAAA,EAChI;AACA,SAAO,KAAK,EAAE,IAAI,KAAK,CAAC;AAC1B;;;ACpMA,eAAeG,MAAK,KAAc,KAAiB,KAAmD;AACpG,QAAM,QAAQ,IAAI,OAAO,GAAG;AAC5B,QAAM,IAAI,MAAM,IAAI,WAAW,KAAK,GAAG;AACvC,MAAI,CAAC,EAAG,QAAO,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG;AAClD,MAAI,CAAE,MAAM,IAAI,QAAQ,OAAO,CAAC,EAAI,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AAC3E,SAAO;AACT;AACA,eAAeC,WAAU,IAAe,IAAqD;AAC3F,QAAM,EAAE,OAAO,IAAI,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC;AAChF,SAAO,SAAS,CAAC,KAAK;AACxB;AACA,IAAMC,OAAM,CAAC,GAAY,IAAI,OAAgB,OAAO,MAAM,WAAW,IAAI;AACzE,IAAM,aAAa,CAAC,IAAe,SAAqB;AAAA,EACtD;AAAA,EACA,SAAS,IAAI;AAAA,EACb,QAAQ,IAAI;AAAA,EACZ,MAAM,IAAI;AAAA,EACV,KAAK,MAAM,KAAK,IAAI;AAAA,EACpB,OAAO,MAAM,OAAO,WAAW;AACjC;AAIO,IAAM,wBAA+B,OAAO,KAAK,KAAK,KAAK,QAAQ;AACxE,MAAI,IAAI,aAAa,4BAA6B,IAAI,WAAW,SAAS,IAAI,WAAW,MAAQ,QAAO;AACxG,QAAM,MAAM,MAAMF,MAAK,KAAK,KAAK,GAAG;AACpC,MAAI,eAAe,SAAU,QAAO;AACpC,QAAM,KAAK;AACX,QAAM,QAAQ,MAAMC,WAAU,IAAI,IAAI,QAAQ,EAAE;AAChD,MAAI,CAAC,MAAO,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AAEnD,MAAI,IAAI,WAAW,OAAO;AACxB,UAAM,SAAU,MAAM,kBAAkB,CAAC;AACzC,UAAM,iBAAsF,CAAC;AAC7F,eAAW,OAAO,sBAAsB;AACtC,YAAM,IAAI,OAAO,GAAG;AACpB,UAAI,EAAG,gBAAe,GAAG,IAAI,EAAE,SAASC,KAAI,EAAE,OAAO,GAAG,MAAMA,KAAI,EAAE,IAAI,GAAG,SAAS,EAAE,YAAY,MAAM;AAAA,IAC1G;AACA,WAAO,KAAK;AAAA,MACV,SAAS,MAAM;AAAA,MACf,MAAM,MAAM;AAAA,MACZ,SAASA,KAAI,MAAM,OAAO;AAAA,MAC1B,mBAAmBA,KAAI,MAAM,iBAAiB;AAAA,MAC9C,YAAYA,KAAI,MAAM,UAAU;AAAA,MAChC;AAAA,MACA,gBAAgBA,KAAI,MAAM,cAAc;AAAA,MACxC,WAAWA,KAAI,MAAM,SAAS;AAAA,MAC9B,kBAAkBA,KAAI,MAAM,gBAAgB;AAAA;AAAA;AAAA,MAG5C,SAAS,IAAI;AAAA,MACb,WAAW,IAAI,cAAc,IAAI,aAAa,eAAe;AAAA,MAC7D,WAAW,IAAI,cAAc;AAAA,IAC/B,CAAC;AAAA,EACH;AAEA,MAAI;AACJ,MAAI;AACF,WAAQ,MAAM,IAAI,KAAK;AAAA,EACzB,QAAQ;AACN,WAAO,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;AAAA,EACjD;AACA,QAAM,YAAY,KAAK;AACvB,MAAI,CAAC,aAAa,OAAO,cAAc,SAAU,QAAO,KAAK,EAAE,OAAO,iCAAiC,GAAG,GAAG;AAC7G,QAAM,QAA6E,CAAC;AACpF,aAAW,OAAO,sBAAsB;AACtC,UAAM,IAAK,UAAuF,GAAG;AACrG,UAAM,UAAU,OAAO,GAAG,YAAY,WAAW,EAAE,QAAQ,KAAK,IAAI;AACpE,UAAMC,QAAO,OAAO,GAAG,SAAS,WAAW,EAAE,OAAO;AACpD,QAAI,CAAC,WAAW,CAACA,MAAK,KAAK,EAAG,QAAO,KAAK,EAAE,OAAO,aAAa,GAAG,+BAA+B,GAAG,GAAG;AACxG,QAAI,SAAS,KAAK,OAAO,KAAK,QAAQ,SAAS,IAAK,QAAO,KAAK,EAAE,OAAO,aAAa,GAAG,uDAAuD,GAAG,GAAG;AACtJ,QAAIA,MAAK,SAAS,IAAQ,QAAO,KAAK,EAAE,OAAO,aAAa,GAAG,qBAAqB,GAAG,GAAG;AAC1F,UAAM,GAAG,IAAI,EAAE,SAAS,MAAAA,OAAM,SAAS,GAAG,YAAY,MAAM;AAAA,EAC9D;AACA,QAAM,WAAW;AACjB,QAAM,oBAAoBD,KAAI,KAAK,iBAAiB,EAAE,KAAK;AAC3D,QAAM,UAAUA,KAAI,KAAK,OAAO,EAAE,KAAK;AACvC,QAAM,aAAaA,KAAI,KAAK,UAAU,EAAE,KAAK;AAC7C,MAAI,CAAC,SAAS,KAAK,iBAAiB,EAAG,QAAO,KAAK,EAAE,OAAO,6CAA6C,GAAG,GAAG;AAC/G,MAAI,CAAC,SAAS,KAAK,OAAO,EAAG,QAAO,KAAK,EAAE,OAAO,yCAAyC,GAAG,GAAG;AACjG,MAAI,cAAc,CAAC,SAAS,KAAK,UAAU,EAAG,QAAO,KAAK,EAAE,OAAO,sCAAsC,GAAG,GAAG;AAC/G,QAAM,iBAAiBA,KAAI,KAAK,cAAc;AAC9C,QAAM,YAAYA,KAAI,KAAK,SAAS;AACpC,MAAI,eAAe,SAAS,OAAQ,UAAU,SAAS,IAAM,QAAO,KAAK,EAAE,OAAO,oCAAoC,GAAG,GAAG;AAE5H,QAAM,GAAG,SAAS,CAAC,EAAE,GAAG,UAAU,IAAI,UAAU,IAAI,IAAI,QAAQ,IAAI,OAAO,EAAE,gBAAgB,OAAO,gBAAgB,WAAW,mBAAmB,SAAS,WAAW,EAAE,CAAC,CAAC;AAC1K,SAAO,KAAK,EAAE,IAAI,KAAK,CAAC;AAC1B;AAGO,IAAM,sBAA6B,OAAO,KAAK,KAAK,KAAK,QAAQ;AACtE,MAAI,IAAI,WAAW,SAAS,IAAI,aAAa,uBAAwB,QAAO;AAC5E,QAAM,MAAM,MAAMF,MAAK,KAAK,KAAK,GAAG;AACpC,MAAI,eAAe,SAAU,QAAO;AACpC,QAAM,EAAE,SAAS,IAAI,MAAM,IAAI,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,OAAO,GAAG,OAAO,GAAG,EAAE,EAAE,CAAC;AAClG,QAAM,SAAU,YAAY,CAAC,GAAsC,IAAI,CAAC,OAAO;AAAA,IAC7E,IAAI,EAAE;AAAA,IACN,UAAU,EAAE;AAAA,IACZ,IAAI,EAAE;AAAA,IACN,SAAS,EAAE;AAAA,IACX,WAAW,EAAE;AAAA,IACb,YAAY,EAAE,eAAe;AAAA,IAC7B,OAAQ,EAAE,SAAoB;AAAA,IAC9B,QAAQ,EAAE;AAAA,EACZ,EAAE;AACF,SAAO,KAAK,EAAE,MAAM,CAAC;AACvB;AAIO,IAAM,uBAA8B,OAAO,KAAK,KAAK,KAAK,QAAQ;AACvE,MAAI,IAAI,WAAW,UAAU,IAAI,aAAa,wBAAyB,QAAO;AAC9E,QAAM,MAAM,MAAMA,MAAK,KAAK,KAAK,GAAG;AACpC,MAAI,eAAe,SAAU,QAAO;AACpC,QAAM,KAAK;AACX,MAAI;AACJ,MAAI;AACF,WAAQ,MAAM,IAAI,KAAK;AAAA,EACzB,QAAQ;AACN,WAAO,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;AAAA,EACjD;AACA,QAAM,WAAWE,KAAI,KAAK,QAAQ;AAClC,MAAI,CAAE,qBAA2C,SAAS,QAAQ,GAAG;AACnE,WAAO,KAAK,EAAE,OAAO,4BAA4B,qBAAqB,KAAK,IAAI,CAAC,GAAG,GAAG,GAAG;AAAA,EAC3F;AACA,QAAM,QAAQ,MAAMD,WAAU,IAAI,IAAI,QAAQ,EAAE;AAChD,MAAI,CAAC,MAAO,QAAO,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG;AACnD,QAAM,MAAM,MAAM,cAAc,WAAW,IAAI,GAAG,GAAG;AAAA,IACnD,OAAO,eAAe,KAAK;AAAA,IAC3B;AAAA,IACA,IAAIC,KAAI,MAAM,iBAAiB;AAAA,IAC/B,MAAM,EAAE,WAAW,UAAU,UAAU,UAAU,OAAO,sBAAsB,OAAO,kBAAkB,OAAO,MAAM,UAAU,GAAG,IAAI,MAAM,WAAW,YAAY,GAAG,IAAI,MAAM,YAAY;AAAA,IAC3L,WAAW,QAAQ,QAAQ,IAAI,KAAK,IAAI,CAAC;AAAA,IACzC,OAAO;AAAA,EACT,CAAC;AACD,SAAO,KAAK,EAAE,IAAI,IAAI,MAAM,QAAQ,IAAI,UAAU,MAAM,IAAIA,KAAI,MAAM,iBAAiB,GAAG,YAAY,IAAI,aAAa,UAAU,CAAC,CAAC,MAAM,WAAW,CAAC;AACvJ;AAKO,IAAM,mBAA0B,OAAO,KAAK,KAAK,KAAK,QAAQ;AACnE,QAAM,IAAI,IAAI,SAAS,MAAM,gDAAgD;AAC7E,MAAI,IAAI,WAAW,SAAS,CAAC,EAAG,QAAO;AACvC,QAAM,MAAM,MAAMF,MAAK,KAAK,KAAK,GAAG;AACpC,MAAI,eAAe,SAAU,QAAO;AACpC,QAAM,KAAK;AACX,QAAM,QAAQ,EAAE,CAAC;AAEjB,QAAM,OAAO,MAAM,GAAG,MAAM;AAAA,IAC1B,UAAU;AAAA,MACR,GAAG;AAAA,QACD,OAAO,EAAE,eAAe,MAAM;AAAA,QAC9B,OAAO,EAAE,QAAQ,OAAO;AAAA,QACxB,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,eAAe,MAAM,EAAE,EAAE;AAAA,IACnD,cAAc,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,MAAM,GAAG,OAAO,EAAE,EAAE;AAAA,EACxD,CAAC;AACD,QAAM,MAAM,KAAK,eAAe,CAAC,KAAK;AACtC,QAAM,QAAQ,MAAMC,WAAU,IAAIC,KAAI,KAAK,SAAS,IAAI,QAAQ,EAAE,CAAC;AACnE,QAAM,OAAsC,MACxC,EAAE,WAAWA,KAAI,IAAI,SAAS,GAAG,UAAUA,KAAI,IAAI,QAAQ,GAAG,OAAOA,KAAI,IAAI,KAAK,GAAG,OAAOA,KAAI,IAAI,KAAK,GAAG,OAAOA,KAAI,IAAI,KAAK,GAAG,UAAU,GAAG,IAAI,MAAM,WAAW,YAAY,GAAG,IAAI,MAAM,YAAY,IAC1M;AAEJ,QAAM,UAAW,KAAK,YAAY,CAAC,GAChC,OAAO,CAAC,MAAM,EAAE,aAAa,mBAAmB,EAChD,IAAI,CAAC,MAA+B;AACnC,QAAI,WAA0B,OAAO,EAAE,SAAS,WAAW,EAAE,OAAO;AACpE,QAAI,CAAC,YAAY,SAAS,KAAM,YAAW,mBAAmB,eAAe,KAAK,GAAG,OAAO,EAAE,QAAQ,GAAG,IAAI;AAC7G,UAAM,UAAU,EAAE,QAAQ,mBAAmB,EAAE,aAAa,2BAA2B,EAAE,cAAc,aAAa,0BAA0B;AAC9I,WAAO,EAAE,MAAM,SAAS,SAAS,OAAO,OAAO,EAAE,QAAQ,GAAG,SAASA,KAAI,EAAE,OAAO,GAAG,IAAK,EAAE,MAAiB,MAAM,MAAM,UAAU,IAAI,EAAE,QAAkB,OAAQ,EAAE,SAAoB,KAAK;AAAA,EAChM,CAAC;AACH,QAAM,YAAa,KAAK,YAAY,CAAC,GAAsC,IAAI,CAAC,QAAiC;AAAA,IAC/G,MAAM;AAAA,IACN,SAAS;AAAA,IACT,OAAO,GAAG,WAAW,cAAc,sCAAsC;AAAA,IACzE,SAAS;AAAA,IACT,IAAI;AAAA,IACJ,IAAK,GAAG,aAAyB,GAAG;AAAA,IACpC,OAAO;AAAA,EACT,EAAE;AACF,QAAM,QAAQ,CAAC,GAAG,QAAQ,GAAG,QAAQ,EAAE,KAAK,CAAC,GAAG,OAAQ,EAAE,MAAiB,MAAO,EAAE,MAAiB,EAAE;AACvG,SAAO,KAAK,EAAE,MAAM,CAAC;AACvB;;;ACjMA,SAAS,WAAW,mBAAmB;AACvC,SAAS,wBAAAE,uBAAsB,0BAAAC,+BAA8B;;;ACG7D,SAAS,cACP,KACA,QACuB;AACvB,MAAI,CAAC,OAAO,QAAS,QAAO;AAC5B,QAAM,YAAa,IAA2C,OAAO,OAAO;AAC5E,MACE,OAAO,cAAc,YACrB,cAAc,QACd,EAAE,WAAW,cACb,OAAO,UAAU,UAAU,YAC3B;AACA,UAAM,IAAI,MAAM,oBAAoB,OAAO,OAAO,kBAAkB;AAAA,EACtE;AACA,SAAO;AACT;AAEO,SAAS,mBACd,KACA,QACA,aACA,MACmB;AACnB,QAAM,UAAU,cAAc,KAAK,MAAM;AACzC,SAAO,UACH,QAAQ,MAAM,IAAI,QAAQ,aAAa,IAAI,CAAC,IAC5C,WAAW,MAAM,aAAa,IAAI;AACxC;;;AClCA,SAAS,6BAA6B;AAEtC,SAAS,4BAA4B;AAgBrC,eAAsB,kBACpB,IACA,KACA,KACA,QACAC,SAC4B;AAC5B,QAAM,SAAS,MAAM,eAAe,IAAI,OAAO,UAAU;AACzD,QAAMC,WAAU;AAAA,IACd,KAAK,IAAI,QAAQ;AAAA,IACjB;AAAA,IACA,KAAK,MAAM,KAAK,IAAI;AAAA,IACpB,OAAO,MAAM,OAAO,WAAW;AAAA,EACjC;AACA,MAAI,CAAC,QAAQ;AACX,UAAM,QAAQ,iBAAiB,OAAO,UAAU;AAChD,UAAM,sBAAsBA,UAAS;AAAA,MACnC,UAAUD,QAAO;AAAA,MACjB,UAAU,OAAO;AAAA,MACjB,QAAQ;AAAA,MACR,gBAAgB;AAAA,MAChB;AAAA,IACF,CAAC;AACD,WAAO,EAAE,IAAI,OAAO,IAAI,MAAM,OAAO,MAAM,IAAI,OAAO,MAAM;AAAA,EAC9D;AACA,MAAI;AACJ,MAAI;AACF,cAAU,oBAAoB,IAAI,QAAQ,KAAKA,SAAQ,QAAQ,IAAI,QAAQ,EAAE;AAAA,EAC/E,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,IAAI,OAAO;AAAA,MACX,MAAM,OAAO;AAAA,MACb,IAAI;AAAA,MACJ,OAAO,eAAe,QAAQ,IAAI,UAAU;AAAA,IAC9C;AAAA,EACF;AACA,QAAM,cAAc,KAAK,UAAU,OAAO;AAC1C,QAAM,cAAc,IAAI,IAAI,uBAAuB,OAAO,GAAG;AAC7D,MAAI;AACF,UAAM,SAAS,MAAM,qBAAqB;AAAA,MACxC;AAAA,MACA,QAAQ,IAAI,QAAQ;AAAA,MACpB,QAAQ;AAAA,MACR,KAAK;AAAA,MACL,MAAM;AAAA,IACR,CAAC;AACD,UAAM,MAAM,MAAM,mBAAmB,KAAK,QAAQ,aAAa;AAAA,MAC7D,QAAQ;AAAA,MACR,SAAS,EAAE,GAAG,QAAQ,gBAAgB,mBAAmB;AAAA,MACzD,MAAM;AAAA,MACN,QAAQ,YAAY,QAAQ,GAAM;AAAA,IACpC,CAAC;AACD,UAAM,eAAgB,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AAIvD,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,QAAQ,aAAa,SAAS;AACpC,YAAM,sBAAsBC,UAAS;AAAA,QACnC,UAAUD,QAAO;AAAA,QACjB,UAAU,OAAO;AAAA,QACjB,QAAQ;AAAA,QACR,gBAAgB;AAAA,QAChB;AAAA,MACF,CAAC;AACD,aAAO;AAAA,QACL,IAAI,OAAO;AAAA,QACX,MAAM,OAAO;AAAA,QACb,IAAI;AAAA,QACJ,QAAQ,IAAI;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AACA,UAAM,sBAAsBC,UAAS;AAAA,MACnC,UAAUD,QAAO;AAAA,MACjB,UAAU,OAAO;AAAA,MACjB,QAAQ;AAAA,MACR,gBAAgB;AAAA,MAChB,GAAI,aAAa,WAAW,EAAE,gBAAgB,aAAa,SAAS,IAAI,CAAC;AAAA,IAC3E,CAAC;AACD,WAAO;AAAA,MACL,IAAI,OAAO;AAAA,MACX,MAAM,OAAO;AAAA,MACb,IAAI;AAAA,MACJ,QAAQ,IAAI;AAAA,MACZ,UAAU,aAAa;AAAA,IACzB;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,QAAQ,eAAe,QAAQ,IAAI,UAAU;AACnD,UAAM,sBAAsBC,UAAS;AAAA,MACnC,UAAUD,QAAO;AAAA,MACjB,UAAU,OAAO;AAAA,MACjB,QAAQ;AAAA,MACR,gBAAgB;AAAA,MAChB;AAAA,IACF,CAAC;AACD,WAAO,EAAE,IAAI,OAAO,IAAI,MAAM,OAAO,MAAM,IAAI,OAAO,MAAM;AAAA,EAC9D;AACF;;;AFtGA,eAAeE,MACb,KACA,KACA,KAC8D;AAC9D,QAAM,KAAK,IAAI,OAAO,GAAG;AACzB,QAAM,OAAO,MAAM,IAAI,WAAW,KAAK,GAAG;AAC1C,MAAI,CAAC,KAAM,QAAO,EAAE,UAAU,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG,EAAE;AACnE,MAAI,CAAE,MAAM,IAAI,QAAQ,IAAI,IAAI,EAAI,QAAO,EAAE,UAAU,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG,EAAE;AACzF,SAAO,EAAE,IAAI,KAAK;AACpB;AAGO,IAAM,4BAAmC,OAAO,KAAK,KAAK,KAAK,QAAQ;AAC5E,MAAI,IAAI,WAAW,SAAS,IAAI,aAAa,6BAA8B,QAAO;AAClF,QAAM,MAAM,MAAMA,MAAK,KAAK,KAAK,GAAG;AACpC,MAAI,cAAc,IAAK,QAAO,IAAI;AAClC,SAAO,KAAK;AAAA,IACV,SAAS,IAAI,QAAQ,QAAQ,QAAQ,IAAI,CAAC,EAAE,IAAI,MAAM,KAAK,WAAW,QAAQ,YAAY,OAAO;AAAA,MAC/F;AAAA,MACA;AAAA,MACA,KAAK;AAAA,MACL,OAAO,OAAO,KAAK,UAAU,oBAAoB;AAAA,MACjD;AAAA,IACF,EAAE;AAAA,EACJ,CAAC;AACH;AAIO,IAAM,wBAA+B,OAAO,KAAK,KAAK,KAAK,QAAQ;AACxE,MAAI,IAAI,WAAW,SAAS,IAAI,aAAa,wBAAyB,QAAO;AAC7E,QAAM,KAAK,IAAI,OAAO,GAAG;AACzB,QAAM,SAAS,MAAM,eAAe,IAA4B,sBAAsB;AACtF,MAAI,CAAC,OAAQ,QAAO,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG;AACvD,QAAM,WAAW,MAAMC,wBAAuB,KAAK,EAAE,OAAO,CAAC;AAC7D,MAAI,CAAC,SAAS,GAAI,QAAO,KAAK,EAAE,OAAO,gBAAgB,QAAQ,SAAS,OAAO,GAAG,GAAG;AACrF,QAAM,QAAQ,MAAM,QAAQ;AAAA,IAC1B,OAAO,KAAK,IAAI,QAAQ,IAAI,OAAO,KAAK,EAAE,IAAI,CAAC,SAC7C,YAAY,EAAE,KAAK,IAAI,QAAQ,KAAK,GAAgB,GAAG,IAAI,CAAC;AAAA,EAChE;AACA,QAAM,WAA4B;AAAA,IAChC,SAAS;AAAA,IACT,MAAM,EAAE,IAAI,IAAI,QAAQ,IAAI,MAAM,IAAI,QAAQ,MAAM,MAAM,IAAI,QAAQ,KAAK;AAAA,IAC3E,aAAa,KAAK,IAAI;AAAA,IACtB;AAAA,EACF;AACA,SAAO,KAAK,QAAQ;AACtB;AAEA,eAAe,YACb,IACA,KACA,KACA,QAC8B;AAC9B,QAAM,SAAS,MAAM,eAAe,IAAI,OAAO,UAAU;AACzD,MAAI,CAAC,OAAQ,QAAO,EAAE,IAAI,OAAO,IAAI,MAAM,OAAO,MAAM,KAAK,OAAO,KAAK,WAAW,OAAO,OAAO,yBAAyB;AAC3H,QAAM,cAAc,IAAI,IAAI,yBAAyB,OAAO,GAAG;AAC/D,MAAI;AACF,UAAM,UAAU,MAAMC,sBAAqB;AAAA,MACzC;AAAA,MACA,QAAQ,IAAI,QAAQ;AAAA,MACpB,QAAQ;AAAA,MACR,KAAK;AAAA,IACP,CAAC;AACD,UAAM,WAAW,MAAM,mBAAmB,KAAK,QAAQ,aAAa;AAAA,MAClE;AAAA,MACA,QAAQ,YAAY,QAAQ,GAAM;AAAA,IACpC,CAAC;AACD,UAAM,OAAQ,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,IAAI;AACpD,QACE,CAAC,SAAS,MACV,CAAC,QACD,EAAE,aAAa,SACf,KAAK,YAAY,KACjB,EAAE,UAAU,SACZ,KAAK,KAAK,OAAO,OAAO,MACxB,CAAC,MAAM,QAAQ,KAAK,KAAK,GACzB;AACA,YAAM,WAAW,QAAQ,WAAW,QAAQ,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ;AAC1F,aAAO;AAAA,QACL,IAAI,OAAO;AAAA,QACX,MAAM,OAAO;AAAA,QACb,KAAK,OAAO;AAAA,QACZ,WAAW;AAAA,QACX,OAAO,aAAa,SAAS,KAAK,8BAA8B,qBAAqB,SAAS,MAAM;AAAA,MACtG;AAAA,IACF;AACA,WAAO;AAAA,MACL,IAAI,OAAO;AAAA,MACX,MAAM,OAAO;AAAA,MACb,KAAK,OAAO;AAAA,MACZ,WAAW;AAAA,MACX,aAAa,KAAK;AAAA,MAClB,OAAO,KAAK;AAAA,IACd;AAAA,EACF,SAAS,OAAO;AACd,WAAO;AAAA,MACL,IAAI,OAAO;AAAA,MACX,MAAM,OAAO;AAAA,MACb,KAAK,OAAO;AAAA,MACZ,WAAW;AAAA,MACX,OAAO,iBAAiB,QAAQ,MAAM,UAAU;AAAA,IAClD;AAAA,EACF;AACF;AAIO,IAAM,2BAAkC,OAAO,KAAK,KAAK,KAAK,QAAQ;AAC3E,MAAI,IAAI,WAAW,SAAS,IAAI,aAAa,4BAA6B,QAAO;AACjF,QAAM,MAAM,MAAMF,MAAK,KAAK,KAAK,GAAG;AACpC,MAAI,cAAc,IAAK,QAAO,IAAI;AAClC,QAAM,UAAU,MAAM,QAAQ;AAAA,IAC5B,IAAI,QAAQ,QAAQ,QAAQ,IAAI,CAAC,WAC/B,YAAY,IAAI,IAA4B,KAAK,KAAK,MAAM,CAAC;AAAA,EACjE;AACA,QAAM,SAAS,oBAAI,IAA6E;AAChG,aAAW,UAAU,SAAS;AAC5B,eAAW,QAAQ,OAAO,SAAS,CAAC,GAAG;AACrC,YAAM,YAAY,OAAO,IAAI,KAAK,IAAI,KAAK,EAAE,MAAM,KAAK,MAAM,OAAO,GAAG,QAAQ,CAAC,EAAE;AACnF,gBAAU,SAAS,KAAK;AACxB,iBAAW,CAAC,OAAO,KAAK,KAAK,OAAO,QAAQ,KAAK,MAAM,GAAG;AACxD,kBAAU,OAAO,KAAK,KAAK,UAAU,OAAO,KAAK,KAAK,KAAK;AAAA,MAC7D;AACA,aAAO,IAAI,KAAK,MAAM,SAAS;AAAA,IACjC;AAAA,EACF;AACA,QAAM,SAAwB;AAAA,IAC5B,YAAY,QAAQ;AAAA,IACpB,WAAW,QAAQ,OAAO,CAAC,WAAW,OAAO,SAAS,EAAE;AAAA,IACxD,cAAc,CAAC,GAAG,OAAO,OAAO,CAAC,EAAE,OAAO,CAAC,KAAK,SAAS,MAAM,KAAK,OAAO,CAAC;AAAA,IAC5E,OAAO,CAAC,GAAG,OAAO,OAAO,CAAC;AAAA,IAC1B;AAAA,EACF;AACA,SAAO,KAAK,MAAM;AACpB;AAKO,IAAM,yBAAgC,OAAO,KAAK,KAAK,KAAK,QAAQ;AACzE,MAAI,IAAI,WAAW,UAAU,IAAI,aAAa,0BAA2B,QAAO;AAChF,QAAM,MAAM,MAAMA,MAAK,KAAK,KAAK,GAAG;AACpC,MAAI,cAAc,IAAK,QAAO,IAAI;AAClC,MAAI;AACJ,MAAI;AACF,WAAQ,MAAM,IAAI,KAAK;AAAA,EACzB,QAAQ;AACN,WAAO,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;AAAA,EACjD;AACA,MAAI,OAAO,KAAK,aAAa,YAAY,CAAC,MAAM,QAAQ,KAAK,SAAS,KAAK,KAAK,UAAU,WAAW,GAAG;AACtG,WAAO,KAAK,EAAE,OAAO,wDAAwD,GAAG,GAAG;AAAA,EACrF;AACA,QAAM,YAAY,IAAI,IAAI,KAAK,UAAU,OAAO,CAAC,OAAqB,OAAO,OAAO,QAAQ,CAAC;AAC7F,MAAI,UAAU,SAAS,KAAK,UAAU,OAAQ,QAAO,KAAK,EAAE,OAAO,wCAAwC,GAAG,GAAG;AACjH,QAAM,UAAU,IAAI,QAAQ,QAAQ,QAAQ,OAAO,CAAC,WAAW,UAAU,IAAI,OAAO,EAAE,CAAC;AACvF,MAAI,QAAQ,WAAW,UAAU,KAAM,QAAO,KAAK,EAAE,OAAO,2CAA2C,GAAG,GAAG;AAE7G,QAAMG,UAAS,MAAM,UAAU,EAAE,KAAK,IAAI,QAAQ,KAAK,IAAI,IAAI,GAAY,GAAG,KAAK,QAAQ;AAC3F,MAAI,CAACA,QAAQ,QAAO,KAAK,EAAE,OAAO,mBAAmB,GAAG,GAAG;AAC3D,QAAM,UAAU,MAAM,QAAQ;AAAA,IAC5B,QAAQ,IAAI,CAAC,WACX,kBAAkB,IAAI,IAA4B,KAAK,KAAK,QAAQA,OAAM,CAAC;AAAA,EAC/E;AACA,SAAO,KAAK,EAAE,IAAI,QAAQ,MAAM,CAAC,WAAW,OAAO,EAAE,GAAG,QAAQ,CAAC;AACnE;;;AGrLA,SAAS,mBAAmB;AAC5B,SAAS,wBAAAC,uBAAsB,0BAAAC,+BAA8B;AAiB7D,IAAM,aAAa;AACnB,IAAM,WAAW;AACjB,IAAM,aAAa;AACnB,IAAM,aAAa;AAEnB,eAAeC,MACb,KACA,KACA,KAC8D;AAC9D,QAAM,KAAK,IAAI,OAAO,GAAG;AACzB,QAAM,OAAO,MAAM,IAAI,WAAW,KAAK,GAAG;AAC1C,MAAI,CAAC,KAAM,QAAO,EAAE,UAAU,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG,EAAE;AACnE,MAAI,CAAE,MAAM,IAAI,QAAQ,IAAI,IAAI,EAAI,QAAO,EAAE,UAAU,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG,EAAE;AACzF,SAAO,EAAE,IAAI,KAAK;AACpB;AAEA,SAAS,QACP,OACA,UACA,KACA,KACe;AACf,MAAI,SAAS,QAAQ,UAAU,GAAI,QAAO;AAC1C,MAAI,CAAC,QAAQ,KAAK,KAAK,EAAG,QAAO;AACjC,QAAM,SAAS,OAAO,KAAK;AAC3B,SAAO,OAAO,cAAc,MAAM,KAAK,UAAU,OAAO,UAAU,MAAM,SAAS;AACnF;AAEA,SAAS,cACPC,SACAC,UACe;AACf,QAAM,SAAS,OAAO;AAAA,IACpBA,SAAQ,QAAQ,CAAC,SACf,OAAO,UAAU,eAAe,KAAKD,QAAO,QAAQ,IAAI,IACpD,CAAC,CAAC,MAAMA,QAAO,OAAO,IAAI,CAAC,CAAC,IAC5B,CAAC,CAAC;AAAA,EACV;AACA,SAAO;AAAA,IACL,IAAIA,QAAO;AAAA,IACX,MAAMA,QAAO;AAAA,IACb,MAAMA,QAAO;AAAA,IACb,GAAIA,QAAO,QAAQ,EAAE,OAAOA,QAAO,MAAM,IAAI,CAAC;AAAA,IAC9C;AAAA,IACA,WAAWA,QAAO;AAAA,IAClB,WAAWA,QAAO;AAAA,EACpB;AACF;AAKO,IAAM,uBAA8B,OAAO,KAAK,KAAK,KAAK,QAAQ;AACvE,MAAI,IAAI,WAAW,SAAS,IAAI,aAAa,uBAAwB,QAAO;AAC5E,QAAM,KAAK,IAAI,OAAO,GAAG;AACzB,QAAM,SAAS,MAAM,eAAe,IAA4B,sBAAsB;AACtF,QAAM,UAAU,IAAI,QAAQ,QAAQ;AACpC,MAAI,CAAC,UAAU,QAAQ,WAAW,EAAG,QAAO,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG;AAC/E,QAAM,WAAW,MAAME,wBAAuB,KAAK;AAAA,IACjD;AAAA,IACA,SAAS,QAAQ,IAAI,CAACC,YAAWA,QAAO,EAAE;AAAA,EAC5C,CAAC;AACD,MAAI,CAAC,SAAS,GAAI,QAAO,KAAK,EAAE,OAAO,gBAAgB,QAAQ,SAAS,OAAO,GAAG,GAAG;AACrF,QAAM,SAAS,QAAQ,KAAK,CAAC,cAAc,UAAU,OAAO,SAAS,MAAM;AAC3E,QAAM,OAAO,IAAI,aAAa,IAAI,MAAM,KAAK;AAC7C,QAAMF,WAAU,QAAQ,OAAO,IAAI;AACnC,MAAI,CAAC,WAAW,KAAK,IAAI,KAAK,CAACA,SAAS,QAAO,KAAK,EAAE,OAAO,6CAA6C,GAAG,GAAG;AAChH,QAAM,QAAQ,QAAQ,IAAI,aAAa,IAAI,OAAO,GAAG,IAAI,GAAG,QAAQ;AACpE,QAAM,SAAS,QAAQ,IAAI,aAAa,IAAI,QAAQ,GAAG,GAAG,GAAG,UAAU;AACvE,QAAM,UAAU,IAAI,aAAa,IAAI,QAAQ,KAAK,IAAI,KAAK;AAC3D,MAAI,SAAS,QAAQ,UAAU,QAAQ,OAAO,SAAS,YAAY;AACjE,WAAO,KAAK,EAAE,OAAO,0CAA0C,GAAG,GAAG;AAAA,EACvE;AACA,QAAM,OAAO,MAAM;AAAA,IACjB,EAAE,KAAK,IAAI,QAAQ,KAAK,GAAgB;AAAA,IACxC;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,MAC3B,MAAM,EAAE,OAAO,aAAa,KAAK,OAAO;AAAA,IAC1C;AAAA,EACF;AACA,QAAM,WAA8B;AAAA,IAClC,SAAS;AAAA,IACT,MAAM,EAAE,IAAI,IAAI,QAAQ,IAAI,MAAM,IAAI,QAAQ,KAAK;AAAA,IACnD;AAAA,IACA,SAAS,KAAK,QAAQ,IAAI,CAACD,YAAW,cAAcA,SAAQC,QAAO,CAAC;AAAA,IACpE,OAAO,KAAK;AAAA,IACZ,OAAO,KAAK;AAAA,IACZ,QAAQ,KAAK;AAAA,EACf;AACA,SAAO,KAAK,QAAQ;AACtB;AAEA,SAAS,UAAU,KAAoB,IAA+C;AACpF,SAAO,IAAI,QAAQ,QAAQ,QAAQ,KAAK,CAAC,WAAW,OAAO,OAAO,EAAE;AACtE;AAEA,eAAe,kBACb,IACA,KACA,KACA,QACA,OAC+E;AAC/E,QAAM,SAAS,MAAM,eAAe,IAAI,OAAO,UAAU;AACzD,MAAI,CAAC,OAAQ,QAAO,EAAE,IAAI,OAAO,OAAO,yBAAyB;AACjE,QAAM,cAAc,IAAI,IAAI,wBAAwB,OAAO,GAAG;AAC9D,cAAY,SAAS,MAAM,SAAS;AACpC,MAAI;AACF,UAAM,UAAU,MAAMG,sBAAqB;AAAA,MACzC;AAAA,MACA,QAAQ,IAAI,QAAQ;AAAA,MACpB,QAAQ;AAAA,MACR,KAAK;AAAA,IACP,CAAC;AACD,UAAM,WAAW,MAAM,mBAAmB,KAAK,QAAQ,aAAa;AAAA,MAClE;AAAA,MACA,QAAQ,YAAY,QAAQ,GAAM;AAAA,IACpC,CAAC;AACD,UAAM,OAAQ,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,IAAI;AACpD,QACE,CAAC,SAAS,MACV,CAAC,QACD,EAAE,aAAa,SACf,KAAK,YAAY,KACjB,EAAE,UAAU,SACZ,KAAK,KAAK,OAAO,OAAO,MACxB,CAAC,MAAM,QAAQ,KAAK,OAAO,GAC3B;AACA,YAAM,WAAW,QAAQ,WAAW,QAAQ,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ;AAC1F,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAO,aAAa,SAAS,KAAK,qCAAqC,qBAAqB,SAAS,MAAM;AAAA,MAC7G;AAAA,IACF;AACA,WAAO,EAAE,IAAI,MAAM,MAAM,KAAK;AAAA,EAChC,SAAS,OAAO;AACd,WAAO,EAAE,IAAI,OAAO,OAAO,iBAAiB,QAAQ,MAAM,UAAU,qBAAqB;AAAA,EAC3F;AACF;AAIO,IAAM,4BAAmC,OAAO,KAAK,KAAK,KAAK,QAAQ;AAC5E,MAAI,IAAI,WAAW,SAAS,IAAI,aAAa,6BAA8B,QAAO;AAClF,QAAM,MAAM,MAAML,MAAK,KAAK,KAAK,GAAG;AACpC,MAAI,cAAc,IAAK,QAAO,IAAI;AAClC,QAAM,WAAW,IAAI,aAAa,IAAI,UAAU,KAAK;AACrD,QAAM,OAAO,IAAI,aAAa,IAAI,MAAM,KAAK;AAC7C,QAAM,SAAS,UAAU,KAAK,QAAQ;AACtC,MAAI,CAAC,UAAU,CAAC,WAAW,KAAK,IAAI,EAAG,QAAO,KAAK,EAAE,OAAO,mDAAmD,GAAG,GAAG;AACrH,QAAM,QAAQ,QAAQ,IAAI,aAAa,IAAI,OAAO,GAAG,IAAI,GAAG,QAAQ;AACpE,QAAM,SAAS,QAAQ,IAAI,aAAa,IAAI,QAAQ,GAAG,GAAG,GAAG,UAAU;AACvE,QAAM,UAAU,IAAI,aAAa,IAAI,QAAQ,KAAK,IAAI,KAAK;AAC3D,MAAI,SAAS,QAAQ,UAAU,QAAQ,OAAO,SAAS,YAAY;AACjE,WAAO,KAAK,EAAE,OAAO,0CAA0C,GAAG,GAAG;AAAA,EACvE;AACA,QAAM,QAAQ,IAAI,gBAAgB,EAAE,MAAM,OAAO,OAAO,KAAK,GAAG,QAAQ,OAAO,MAAM,EAAE,CAAC;AACxF,MAAI,OAAQ,OAAM,IAAI,UAAU,MAAM;AACtC,QAAM,SAAS,MAAM;AAAA,IACnB,IAAI;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,SAAO,OAAO,KAAK,KAAK,OAAO,IAAI,IAAI,KAAK,EAAE,OAAO,OAAO,MAAM,GAAG,GAAG;AAC1E;;;ACxLA,IAAMM,cAAa;AACnB,IAAM,YAAY;AAClB,IAAMC,YAAW;AAEjB,eAAeC,MACb,KACA,KACA,KAC8D;AAC9D,QAAM,KAAK,IAAI,OAAO,GAAG;AACzB,QAAM,OAAO,MAAM,IAAI,WAAW,KAAK,GAAG;AAC1C,MAAI,CAAC,KAAM,QAAO,EAAE,UAAU,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG,EAAE;AACnE,MAAI,CAAE,MAAM,IAAI,QAAQ,IAAI,IAAI,EAAI,QAAO,EAAE,UAAU,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG,EAAE;AACzF,SAAO,EAAE,IAAI,KAAK;AACpB;AAEA,SAAS,aAAa,KAAU,KAAoB;AAClD,QAAM,WAAW,IAAI,aAAa,IAAI,UAAU,KAAK;AACrD,QAAM,aAAa,IAAI,aAAa,IAAI,MAAM,KAAK;AACnD,QAAM,WAAW,IAAI,aAAa,IAAI,UAAU,KAAK;AACrD,QAAM,aAAa,IAAI,QAAQ,QAAQ,QAAQ,KAAK,CAAC,WAAW,OAAO,OAAO,QAAQ;AACtF,MAAI,CAAC,cAAc,CAACF,YAAW,KAAK,UAAU,KAAK,CAAC,UAAU,KAAK,QAAQ,EAAG,QAAO;AACrF,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,GAAG,QAAQ,IAAI,UAAU,IAAI,QAAQ;AAAA,EAClD;AACF;AAEA,SAAS,OAAO,KAAiD;AAC/D,SAAO;AAAA,IACL,IAAI,OAAO,IAAI,EAAE;AAAA,IACjB,UAAU,OAAO,IAAI,QAAQ;AAAA,IAC7B,YAAY,OAAO,IAAI,UAAU;AAAA,IACjC,UAAU,OAAO,IAAI,QAAQ;AAAA,IAC7B,MAAM,OAAO,IAAI,IAAI;AAAA,IACrB,UAAU,OAAO,IAAI,QAAQ;AAAA,IAC7B,GAAI,OAAO,IAAI,gBAAgB,WAAW,EAAE,aAAa,IAAI,YAAY,IAAI,CAAC;AAAA,IAC9E,WAAW,OAAO,IAAI,SAAS;AAAA,EACjC;AACF;AAIO,IAAM,0BAAiC,OAAO,KAAK,KAAK,KAAK,QAAQ;AAC1E,MAAI,IAAI,aAAa,8BAA+B,IAAI,WAAW,SAAS,IAAI,WAAW,OAAS,QAAO;AAC3G,QAAM,MAAM,MAAME,MAAK,KAAK,KAAK,GAAG;AACpC,MAAI,cAAc,IAAK,QAAO,IAAI;AAClC,QAAM,WAAW,aAAa,KAAK,GAAG;AACtC,MAAI,CAAC,SAAU,QAAO,KAAK,EAAE,OAAO,kDAAkD,GAAG,GAAG;AAC5F,MAAI,IAAI,WAAW,OAAO;AACxB,UAAM,SAAS,MAAM,IAAI,GAAG,MAAM;AAAA,MAChC,cAAc;AAAA,QACZ,GAAG;AAAA,UACD,OAAO,EAAE,WAAW,SAAS,UAAU;AAAA,UACvC,OAAO,EAAE,WAAW,OAAO;AAAA,UAC3B,OAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF,CAAC;AACD,WAAO,KAAK,EAAE,QAAQ,OAAO,gBAAgB,CAAC,GAAG,IAAI,CAAC,QAAQ,OAAO,GAA8B,CAAC,EAAE,CAAC;AAAA,EACzG;AACA,QAAM,gBAAgB,OAAO,IAAI,QAAQ,IAAI,gBAAgB,KAAK,CAAC;AACnE,MAAI,gBAAgBD,YAAW,EAAG,QAAO,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;AACjF,MAAI;AACJ,MAAI;AACF,YAAS,MAAM,IAAI,KAAK;AAAA,EAC1B,QAAQ;AACN,WAAO,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;AAAA,EACjD;AACA,QAAM,OAAO,OAAO,MAAM,SAAS,WAAW,MAAM,KAAK,KAAK,IAAI;AAClE,MAAI,CAAC,QAAQ,KAAK,SAASA,UAAU,QAAO,KAAK,EAAE,OAAO,uBAAkBA,SAAQ,cAAc,GAAG,GAAG;AACxG,QAAM,KAAK,OAAO,WAAW;AAC7B,QAAM,OAA0B;AAAA,IAC9B;AAAA,IACA,UAAU,SAAS;AAAA,IACnB,YAAY,SAAS;AAAA,IACrB,UAAU,SAAS;AAAA,IACnB;AAAA,IACA,UAAU,IAAI,KAAK;AAAA,IACnB,GAAI,IAAI,KAAK,QAAQ,EAAE,aAAa,IAAI,KAAK,MAAM,IAAI,CAAC;AAAA,IACxD,WAAW,KAAK,IAAI;AAAA,EACtB;AACA,QAAM,IAAI,GAAG,SAAS,CAAC;AAAA,IACrB,GAAG;AAAA,IACH,IAAI;AAAA,IACJ;AAAA,IACA,OAAO,EAAE,GAAG,MAAM,WAAW,SAAS,UAAU;AAAA,EAClD,CAAC,CAAC;AACF,SAAO,KAAK,EAAE,KAAK,GAAG,GAAG;AAC3B;;;AC/FA;AAAA,EACE;AAAA,EACA;AAAA,EACA,aAAAE;AAAA,OAEK;AACP,SAAS,wBAAAC,uBAAsB,0BAAAC,+BAA8B;AAc7D,IAAMC,cAAa;AACnB,IAAMC,aAAY;AAClB,IAAM,cAAc;AACpB,IAAMC,YAAW;AACjB,IAAM,eAAe;AAErB,eAAeC,MACb,KACA,KACA,KAC8D;AAC9D,QAAM,KAAK,IAAI,OAAO,GAAG;AACzB,QAAM,OAAO,MAAM,IAAI,WAAW,KAAK,GAAG;AAC1C,MAAI,CAAC,KAAM,QAAO,EAAE,UAAU,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG,EAAE;AACnE,MAAI,CAAE,MAAM,IAAI,QAAQ,IAAI,IAAI,EAAI,QAAO,EAAE,UAAU,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG,EAAE;AACzF,SAAO,EAAE,IAAI,KAAK;AACpB;AAEA,SAAS,WAAW,UAAuB,UAA4C;AACrF,QAAM,OAAO,SAAS,OAAO,YAAY;AACzC,MAAI,CAAC,QAAQ,OAAO,SAAS,YAAY,MAAM,QAAQ,IAAI,EAAG,QAAO;AACrE,QAAM,QAAQ;AACd,MAAI,MAAM,YAAY,KAAK,MAAM,aAAa,YAAY,OAAO,MAAM,SAAS,SAAU,QAAO;AACjG,SAAO;AAAA,IACL,IAAI,SAAS;AAAA,IACb;AAAA,IACA,YAAY,OAAO,MAAM,cAAc,EAAE;AAAA,IACzC,UAAU,SAAS;AAAA,IACnB,MAAM,MAAM;AAAA,IACZ,WAAW,SAAS;AAAA,EACtB;AACF;AAEA,eAAe,gBAAgB,IAAe,UAAkB,UAAgD;AAC9G,QAAM,SAAS,MAAM,GAAG,MAAM;AAAA,IAC5B,CAAC,OAAO,QAAQ,GAAG;AAAA,MACjB,GAAG;AAAA,QACD,OAAO;AAAA,UACL,KAAK;AAAA,YACH,EAAE,SAAS;AAAA,YACX,EAAE,UAAU,WAAW,QAAQ,GAAG;AAAA,UACpC;AAAA,QACF;AAAA,QACA,OAAO,EAAE,WAAW,OAAO;AAAA,QAC3B,OAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF,CAAC;AACD,UAAS,OAAO,OAAO,QAAQ,KAAK,CAAC,GAClC,QAAQ,CAAC,aAAa;AACrB,UAAM,OAAO,WAAW,UAAU,QAAQ;AAC1C,WAAO,OAAO,CAAC,IAAI,IAAI,CAAC;AAAA,EAC1B,CAAC;AACL;AAEA,SAAS,YAAY,UAA0B;AAC7C,SAAO,SAAS,MAAM,GAAG,EAAE,IAAI,CAAC,SAC9B,OAAO,GAAG,KAAK,CAAC,GAAG,YAAY,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC,KAAK,IAAI,EAAE,KAAK,GAAG;AACvE;AAKO,IAAM,2BAAkC,OAAO,KAAK,KAAK,KAAK,QAAQ;AAC3E,MAAI,IAAI,aAAa,+BAAgC,IAAI,WAAW,SAAS,IAAI,WAAW,OAAS,QAAO;AAC5G,MAAI,IAAI,WAAW,UAAU,OAAO,IAAI,QAAQ,IAAI,gBAAgB,KAAK,CAAC,IAAID,YAAW,GAAG;AAC1F,WAAO,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;AAAA,EACjD;AACA,QAAM,KAAK,IAAI,OAAO,GAAG;AACzB,QAAM,SAAS,MAAM,eAAe,IAA4B,sBAAsB;AACtF,QAAM,UAAU,IAAI,QAAQ,QAAQ;AACpC,MAAI,CAAC,UAAU,QAAQ,WAAW,EAAG,QAAO,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG;AAC/E,QAAM,WAAW,MAAME,wBAAuB,KAAK;AAAA,IACjD;AAAA,IACA,SAAS,QAAQ,IAAI,CAACC,YAAWA,QAAO,EAAE;AAAA,EAC5C,CAAC;AACD,MAAI,CAAC,SAAS,GAAI,QAAO,KAAK,EAAE,OAAO,gBAAgB,QAAQ,SAAS,OAAO,GAAG,GAAG;AACrF,QAAM,SAAS,QAAQ,KAAK,CAAC,cAAc,UAAU,OAAO,SAAS,MAAM;AAC3E,QAAM,aAAa,IAAI,aAAa,IAAI,MAAM,KAAK;AACnD,QAAM,WAAW,IAAI,aAAa,IAAI,UAAU,KAAK;AACrD,MAAI,CAACL,YAAW,KAAK,UAAU,KAAK,CAACC,WAAU,KAAK,QAAQ,KAAK,CAAC,QAAQ,YAAY,SAAS,UAAU,GAAG;AAC1G,WAAO,KAAK,EAAE,OAAO,+DAA+D,GAAG,GAAG;AAAA,EAC5F;AACA,QAAMK,UAAS,MAAMC,WAAU,EAAE,KAAK,IAAI,QAAQ,KAAK,GAAgB,GAAG,QAAQ;AAClF,MAAI,CAACD,WAAUA,QAAO,SAAS,WAAY,QAAO,KAAK,EAAE,OAAO,mBAAmB,GAAG,GAAG;AACzF,MAAI,IAAI,WAAW,OAAO;AACxB,WAAO,KAAK;AAAA,MACV,SAAS;AAAA,MACT,MAAM,EAAE,IAAI,IAAI,QAAQ,IAAI,MAAM,IAAI,QAAQ,KAAK;AAAA,MACnD,OAAO,MAAM,gBAAgB,IAA4B,SAAS,QAAQ,QAAQ;AAAA,IACpF,CAAC;AAAA,EACH;AACA,MAAI;AACJ,MAAI;AACF,YAAQ,KAAK,MAAM,SAAS,IAAI;AAAA,EAClC,QAAQ;AACN,WAAO,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;AAAA,EACjD;AACA,QAAM,OAAO,OAAO,MAAM,SAAS,WAAW,MAAM,KAAK,KAAK,IAAI;AAClE,QAAM,aAAa,OAAO,MAAM,eAAe,WAAW,MAAM,aAAa;AAC7E,MAAI,CAAC,QAAQ,KAAK,SAASJ,aAAY,CAAC,YAAY,KAAK,UAAU,GAAG;AACpE,WAAO,KAAK,EAAE,OAAO,uBAAkBA,SAAQ,2CAA2C,GAAG,GAAG;AAAA,EAClG;AACA,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,KAAK,WAAW,SAAS,MAAM,IAAI,UAAU;AACnD,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,MACE,KAAK,IAAI,QAAQ;AAAA,MACjB;AAAA,MACA,KAAK,MAAM;AAAA,MACX,OAAO,MAAM;AAAA,IACf;AAAA,IACA;AAAA,MACE;AAAA,MACA,MAAM;AAAA,MACN,MAAM,aAAa,YAAY,SAAS,MAAM,CAAC,KAAK,IAAI;AAAA,MACxD,UAAU,WAAW,SAAS,MAAM;AAAA,MACpC,MAAM;AAAA,QACJ,CAAC,YAAY,GAAG;AAAA,UACd,SAAS;AAAA,UACT,UAAU,SAAS;AAAA,UACnB;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,MACA,YAAY;AAAA,IACd;AAAA,EACF;AACA,QAAM,OAA0B;AAAA,IAC9B;AAAA,IACA,UAAU,SAAS;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,SAAO,KAAK,EAAE,SAAS,GAAG,MAAM,EAAE,IAAI,IAAI,QAAQ,IAAI,MAAM,IAAI,QAAQ,KAAK,GAAG,MAAM,WAAW,OAAO,UAAU,GAAG,GAAG;AAC1H;AAEA,SAASM,WAAU,KAAoB,IAA+C;AACpF,SAAO,IAAI,QAAQ,QAAQ,QAAQ,KAAK,CAAC,WAAW,OAAO,OAAO,EAAE;AACtE;AAIO,IAAM,gCAAuC,OAAO,KAAK,KAAK,KAAK,QAAQ;AAChF,MAAI,IAAI,aAAa,qCAAsC,IAAI,WAAW,SAAS,IAAI,WAAW,OAAS,QAAO;AAClH,QAAM,MAAM,MAAML,MAAK,KAAK,KAAK,GAAG;AACpC,MAAI,cAAc,IAAK,QAAO,IAAI;AAClC,QAAM,WAAW,IAAI,aAAa,IAAI,UAAU,KAAK;AACrD,QAAM,aAAa,IAAI,aAAa,IAAI,MAAM,KAAK;AACnD,QAAM,WAAW,IAAI,aAAa,IAAI,UAAU,KAAK;AACrD,QAAM,SAASK,WAAU,KAAK,QAAQ;AACtC,MAAI,CAAC,UAAU,CAAC,OAAO,YAAY,SAAS,UAAU,KAAK,CAACR,YAAW,KAAK,UAAU,KAAK,CAACC,WAAU,KAAK,QAAQ,GAAG;AACpH,WAAO,KAAK,EAAE,OAAO,uDAAuD,GAAG,GAAG;AAAA,EACpF;AACA,MAAI,OAAO;AACX,MAAI,IAAI,WAAW,QAAQ;AACzB,QAAI;AACJ,QAAI;AACF,cAAS,MAAM,IAAI,KAAK;AAAA,IAC1B,QAAQ;AACN,aAAO,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;AAAA,IACjD;AACA,UAAM,OAAO,OAAO,MAAM,SAAS,WAAW,MAAM,KAAK,KAAK,IAAI;AAClE,QAAI,CAAC,QAAQ,KAAK,SAASC,UAAU,QAAO,KAAK,EAAE,OAAO,uBAAkBA,SAAQ,cAAc,GAAG,GAAG;AACxG,WAAO,KAAK,UAAU,EAAE,MAAM,MAAM,YAAY,OAAO,WAAW,EAAE,CAAC;AAAA,EACvE;AACA,QAAM,SAAS,MAAM,eAAe,IAAI,IAA4B,OAAO,UAAU;AACrF,MAAI,CAAC,OAAQ,QAAO,KAAK,EAAE,OAAO,yBAAyB,GAAG,GAAG;AACjE,QAAM,cAAc,IAAI,IAAI,6BAA6B,OAAO,GAAG;AACnE,cAAY,SAAS,IAAI,gBAAgB,EAAE,MAAM,YAAY,SAAS,CAAC,EAAE,SAAS;AAClF,MAAI;AACF,UAAM,UAAU,MAAMO,sBAAqB;AAAA,MACzC;AAAA,MACA,QAAQ,IAAI,QAAQ;AAAA,MACpB,QAAQ,IAAI;AAAA,MACZ,KAAK;AAAA,MACL,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,IACzB,CAAC;AACD,UAAM,WAAW,MAAM,mBAAmB,KAAK,QAAQ,aAAa;AAAA,MAClE,QAAQ,IAAI;AAAA,MACZ,SAAS,EAAE,GAAG,SAAS,GAAI,OAAO,EAAE,gBAAgB,mBAAmB,IAAI,CAAC,EAAG;AAAA,MAC/E,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,MACvB,QAAQ,YAAY,QAAQ,GAAM;AAAA,IACpC,CAAC;AACD,UAAM,UAAU,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,IAAI;AACtD,UAAM,OAAO,SAAS;AACtB,QAAI,CAAC,SAAS,MAAM,CAAC,WAAW,MAAM,OAAO,OAAO,IAAI;AACtD,aAAO,KAAK;AAAA,QACV,OAAO,OAAO,SAAS,UAAU,WAAW,QAAQ,QAAQ,qBAAqB,SAAS,MAAM;AAAA,MAClG,GAAG,GAAG;AAAA,IACR;AACA,WAAO,KAAK,SAAS,IAAI,WAAW,SAAS,MAAM,GAAG;AAAA,EACxD,SAAS,OAAO;AACd,WAAO,KAAK,EAAE,OAAO,iBAAiB,QAAQ,MAAM,UAAU,6BAA6B,GAAG,GAAG;AAAA,EACnG;AACF;;;ACtNA,SAAS,gBAAAC,qBAAoB;AAM7B,IAAM,aAAa;AAGZ,IAAM,kBAAyB,OAAO,KAAK,KAAK,KAAK,QAAQ;AAClE,QAAM,YAAY,IAAI,QAAQ;AAC9B,MAAI,CAAC,UAAU,QAAS,QAAO;AAE/B,MAAI,IAAI,WAAW,SAAS,IAAI,aAAa,yBAAyB;AACpE,UAAM,gBAAgB,yBAAyB,IAAI,SAAS,WAAW;AACvE,WAAO,KAAK;AAAA,MACV,MAAM,UAAU;AAAA,MAChB;AAAA;AAAA,MAEA,QAAQ,cAAc;AAAA,IACxB,CAAC;AAAA,EACH;AACA,MAAI,IAAI,WAAW,UAAU,IAAI,aAAa,8BAA+B,QAAO;AAEpF,QAAM,MAAM,MAAM,IAAI,KAAK;AAC3B,MAAI,IAAI,SAAS,UAAU,QAAS,QAAO,KAAK,EAAE,OAAO,yBAAyB,GAAG,GAAG;AACxF,MAAI;AACJ,MAAI;AACF,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB,QAAQ;AACN,WAAO,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;AAAA,EACjD;AACA,MAAI,CAAC,QAAQ,OAAO,SAAS,YAAY,MAAM,QAAQ,IAAI,EAAG,QAAO,KAAK,EAAE,OAAO,8BAA8B,GAAG,GAAG;AAEvH,QAAM,eAAe,OAAO,KAAK,iBAAiB,WAAW,KAAK,eAAe;AACjF,MAAI,gBAAgB,CAAC,WAAW,KAAK,YAAY,GAAG;AAClD,WAAO,KAAK,EAAE,OAAO,+DAA0D,GAAG,GAAG;AAAA,EACvF;AACA,QAAMC,WAAU,oBAAI,IAAI,CAAC,GAAG,UAAU,UAAU,GAAG,UAAU,QAAQ,CAAC;AACtE,QAAM,UAAU,OAAO,KAAK,IAAI,EAAE,OAAO,CAAC,UAAU,UAAU,kBAAkB,CAACA,SAAQ,IAAI,KAAK,CAAC;AACnG,MAAI,QAAQ,OAAQ,QAAO,KAAK,EAAE,OAAO,UAAU,QAAQ,CAAC,CAAC,oBAAoB,GAAG,GAAG;AACvF,aAAW,SAAS,UAAU,UAAU;AACtC,UAAM,QAAQ,KAAK,KAAK;AACxB,QAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,GAAI,QAAO,KAAK,EAAE,OAAO,GAAG,KAAK,eAAe,GAAG,GAAG;AAAA,EAC1G;AACA,QAAM,QAAiC,CAAC;AACxC,aAAW,SAASA,UAAS;AAC3B,UAAM,QAAQ,KAAK,KAAK;AACxB,QAAI,UAAU,OAAW;AACzB,UAAM,MAAM,UAAU,OAAO,KAAK,KAAK,UAAU;AACjD,QAAI,OAAO,UAAU,UAAU;AAC7B,UAAI,MAAM,SAAS,IAAK,QAAO,KAAK,EAAE,OAAO,GAAG,KAAK,YAAY,GAAG,cAAc,GAAG,GAAG;AACxF,YAAM,KAAK,IAAI,MAAM,KAAK;AAAA,IAC5B,WAAW,MAAM,QAAQ,KAAK,GAAG;AAC/B,YAAM,KAAK,IAAI,MAAM,MAAM,GAAG,GAAG;AAAA,IACnC,OAAO;AACL,YAAM,KAAK,IAAI;AAAA,IACjB;AAAA,EACF;AAEA,QAAM,KAAK,IAAI,OAAO,GAAG;AACzB,QAAM,KAAK,eACP,MAAM,2BAA2B,aAAa,IAAI,QAAQ,EAAE,IAAI,YAAY,EAAE,IAC9E,OAAO,WAAW;AACtB,MAAI;AACF,UAAM,UAAU,MAAMC;AAAA,MACpB;AAAA,QACE,KAAK,IAAI,QAAQ;AAAA,QACjB;AAAA,QACA,KAAK,MAAM,KAAK,IAAI;AAAA,QACpB,OAAO,MAAM;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM,UAAU;AAAA,QAChB;AAAA,QACA,GAAI,eAAe,EAAE,YAAY,aAAa,IAAI,QAAQ,EAAE,IAAI,YAAY,GAAG,IAAI,CAAC;AAAA,MACtF;AAAA,IACF;AACA,WAAO,KAAK;AAAA,MACV;AAAA,MACA,WAAW,QAAQ;AAAA,MACnB,QAAQ,QAAQ,OAAO,SAAS;AAAA,IAClC,GAAG,QAAQ,YAAY,MAAM,GAAG;AAAA,EAClC,SAAS,OAAO;AACd,UAAM,SAAS,SAAS,OAAO,UAAU,YAAY,YAAY,QAC5D,MAA+B,SAChC;AACJ,WAAO,KAAK;AAAA,MACV,OAAO,iBAAiB,QAAQ,MAAM,UAAU;AAAA,MAChD,GAAI,SAAS,EAAE,QAAQ,OAAO,IAAI,CAAC;AAAA,IACrC,GAAG,GAAG;AAAA,EACR;AACF;;;AC/FA,SAAS,wBAAAC,6BAA4B;AAiBrC,eAAsB,qBAAqB,SAAsE;AAC/G,QAAM,cAAc,IAAI,IAAI,qBAAqB,QAAQ,SAAS;AAClE,QAAM,OAAO,KAAK,UAAU,QAAQ,QAAQ;AAC5C,QAAM,SAAS,MAAMC,sBAAqB;AAAA,IACxC,QAAQ,QAAQ;AAAA,IAChB,QAAQ,QAAQ;AAAA,IAChB,QAAQ;AAAA,IACR,KAAK;AAAA,IACL;AAAA,EACF,CAAC;AACD,QAAM,WAAW,OAAO,QAAQ,SAAS,WAAW,OAAO,aAAa;AAAA,IACtE,QAAQ;AAAA,IACR,SAAS,EAAE,GAAG,QAAQ,gBAAgB,mBAAmB;AAAA,IACzD;AAAA,EACF,CAAC;AACD,QAAM,SAAS,MAAM,SAAS,KAAK;AACnC,MAAI,CAAC,SAAS,OAAO,EAAE,QAAQ,WAAW,OAAO,OAAO,OAAO;AAC7D,UAAM,YAAY;AAClB,UAAM,IAAI,MAAM,4BAA4B,SAAS,MAAM,MAAM,UAAU,UAAU,UAAU,SAAS,SAAS,EAAE;AAAA,EACrH;AACA,SAAO;AACT;;;ACtCA,SAAS,wBAAAC,6BAA4B;AAiBrC,eAAsB,qBAAqB,SAAsE;AAC/G,QAAM,cAAc,IAAI,IAAI,6BAA6B,QAAQ,SAAS;AAC1E,QAAM,OAAO,KAAK,UAAU,QAAQ,QAAQ;AAC5C,QAAM,SAAS,MAAMC,sBAAqB;AAAA,IACxC,QAAQ,QAAQ;AAAA,IAChB,QAAQ,QAAQ;AAAA,IAChB,QAAQ;AAAA,IACR,KAAK;AAAA,IACL;AAAA,EACF,CAAC;AACD,QAAM,WAAW,OAAO,QAAQ,SAAS,WAAW,OAAO,aAAa;AAAA,IACtE,QAAQ;AAAA,IACR,SAAS,EAAE,GAAG,QAAQ,gBAAgB,mBAAmB;AAAA,IACzD;AAAA,EACF,CAAC;AACD,QAAM,SAAS,MAAM,SAAS,KAAK;AACnC,MAAI,CAAC,SAAS,MAAM,EAAE,QAAQ,WAAW,OAAO,OAAO,MAAM;AAC3D,UAAM,UAAU;AAChB,UAAM,IAAI,MAAM,4BAA4B,SAAS,MAAM,MAAM,QAAQ,UAAU,QAAQ,SAAS,SAAS,EAAE;AAAA,EACjH;AACA,SAAO;AACT;;;ACtCA,SAAS,wBAAAC,6BAA4B;AAiBrC,eAAsB,uBAAuB,SAAwE;AACnH,QAAM,cAAc,IAAI,IAAI,uBAAuB,QAAQ,SAAS;AACpE,QAAM,OAAO,KAAK,UAAU,QAAQ,QAAQ;AAC5C,QAAM,SAAS,MAAMC,sBAAqB;AAAA,IACxC,QAAQ,QAAQ;AAAA,IAChB,QAAQ,QAAQ;AAAA,IAChB,QAAQ;AAAA,IACR,KAAK;AAAA,IACL;AAAA,EACF,CAAC;AACD,QAAM,WAAW,OAAO,QAAQ,SAAS,WAAW,OAAO,aAAa;AAAA,IACtE,QAAQ;AAAA,IACR,SAAS,EAAE,GAAG,QAAQ,gBAAgB,mBAAmB;AAAA,IACzD;AAAA,EACF,CAAC;AACD,QAAM,SAAS,MAAM,SAAS,KAAK;AACnC,MAAI,CAAC,SAAS,MAAM,EAAE,QAAQ,WAAW,OAAO,OAAO,MAAM;AAC3D,UAAM,UAAU;AAChB,UAAM,IAAI,MAAM,8BAA8B,SAAS,MAAM,MAAM,QAAQ,UAAU,QAAQ,SAAS,SAAS,EAAE;AAAA,EACnH;AACA,SAAO;AACT;;;ACnCO,IAAM,8BAA8B;AAEpC,IAAM,gCAAgC;AAE7C,IAAM,aAAa;AACnB,IAAM,SAAS;AACf,IAAM,eAAe;AACrB,IAAM,aAAa;AACnB,IAAM,mBAAmB;AACzB,IAAM,wBAAwB;AAuC9B,SAAS,gBACP,OACkC;AAClC,QAAM,UAAU,OAAO,QAAQ,SAAS,CAAC,CAAC;AAC1C,MAAI,QAAQ,SAAS,YAAY;AAC/B,UAAM,IAAI,UAAU,yCAAyC,UAAU,SAAS;AAAA,EAClF;AACA,QAAM,SAAiC,CAAC;AACxC,MAAI,mBAAmB;AACvB,aAAW,CAAC,MAAM,GAAG,KAAK,QAAQ,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,MAAM,KAAK,cAAc,KAAK,CAAC,GAAG;AACtF,QAAI,CAAC,WAAW,KAAK,IAAI,GAAG;AAC1B,YAAM,IAAI,UAAU,+BAA+B,IAAI,0CAA0C;AAAA,IACnG;AACA,QAAK,OAAO,QAAQ,YAAY,OAAO,QAAQ,YAC1C,OAAO,QAAQ,YAAY,CAAC,OAAO,SAAS,GAAG,GAAI;AACtD,YAAM,IAAI,UAAU,+BAA+B,IAAI,qCAAqC;AAAA,IAC9F;AACA,UAAM,QAAQ,OAAO,GAAG,EAAE,KAAK;AAC/B,QAAI,CAAC,SAAS,MAAM,SAAS,oBAAoB,aAAa,KAAK,KAAK,GAAG;AACzE,YAAM,IAAI,UAAU,+BAA+B,IAAI,oCAAoC;AAAA,IAC7F;AACA,wBAAoB,KAAK,SAAS,MAAM,SAAS;AACjD,QAAI,mBAAmB,uBAAuB;AAC5C,YAAM,IAAI,UAAU,wDAAwD;AAAA,IAC9E;AACA,WAAO,IAAI,IAAI;AAAA,EACjB;AACA,SAAO;AACT;AAEA,SAAS,OAAO,QAAkD;AAChE,QAAM,eAAe,OAAO,QAAQ,MAAM,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,KAAK,IAAI,KAAK,KAAK,GAAG;AACzF,SAAO,aAAa,SAAS;AAAA,EAAY,aAAa,KAAK,IAAI,CAAC;AAAA,KAAQ;AAC1E;AAEA,SAAS,SACP,UACA,SACuD;AACvD,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,MACL,KAAK,OAAO,gBAAgB,QAAQ,eAAe,CAAC;AAAA,MACpD,UAAU,EAAE,QAAQ,aAAa,UAAU,MAAM,QAAQ,MAAM,UAAU,2BAA2B;AAAA,IACtG;AAAA,EACF;AACA,MAAI,CAAC,OAAO,cAAc,SAAS,QAAQ,KAAK,SAAS,WAAW,KAAK,CAAC,OAAO,KAAK,SAAS,MAAM,GAAG;AACtG,UAAM,IAAI,UAAU,mDAAmD;AAAA,EACzE;AACA,SAAO;AAAA,IACL,KAAK,OAAO,gBAAgB,SAAS,OAAO,MAAM,CAAC;AAAA,IACnD,UAAU;AAAA,MACR,QAAQ;AAAA,MACR,UAAU,SAAS;AAAA,MACnB,QAAQ,SAAS;AAAA,MACjB,UAAU,kBAAkB,SAAS,MAAM;AAAA,IAC7C;AAAA,EACF;AACF;AAEA,SAAS,WAAW,UAA8C;AAChE,SAAO;AAAA,IACL,OAAO,6BAA6B;AAAA,IACpC,+BAA+B,SAAS,MAAM;AAAA,IAC9C,kCAAkC,SAAS,QAAQ;AAAA,IACnD,GAAI,SAAS,aAAa,OAAO,CAAC,IAAI,CAAC,iCAAiC,SAAS,QAAQ,GAAG;AAAA,IAC5F,GAAI,SAAS,WAAW,OAAO,CAAC,IAAI,CAAC,+BAA+B,SAAS,MAAM,GAAG;AAAA,EACxF,EAAE,KAAK,GAAG;AACZ;AAMO,SAAS,6BACd,UACA,UAAqC,CAAC,GACd;AACxB,QAAM,EAAE,KAAK,SAAS,IAAI,SAAS,UAAU,OAAO;AACpD,SAAO,EAAE,KAAK,UAAU,MAAM,UAAU,WAAW,QAAQ,CAAC,IAAI,GAAG,WAAW;AAChF;AAMO,SAAS,6BACd,MACA,UACA,SAAiB,6BACT;AACR,QAAM,WAAW;AACjB,QAAM,iBAAiB,KAAK,MAAM,QAAQ,KAAK,CAAC;AAChD,MAAI,eAAe,SAAS,GAAG;AAC7B,UAAM,IAAI,UAAU,2DAA2D;AAAA,EACjF;AACA,MAAI,eAAe,WAAW,EAAG,QAAO,KAAK,QAAQ,UAAU,SAAS,IAAI;AAC5E,QAAM,cAAc,KAAK,QAAQ,MAAM;AACvC,MAAI,eAAe,GAAG;AACpB,QAAI,KAAK,QAAQ,QAAQ,cAAc,OAAO,MAAM,KAAK,GAAG;AAC1D,YAAM,IAAI,UAAU,sDAAsD;AAAA,IAC5E;AACA,WAAO,GAAG,KAAK,MAAM,GAAG,WAAW,CAAC,GAAG,SAAS,IAAI,GAAG,KAAK,MAAM,cAAc,OAAO,MAAM,CAAC;AAAA,EAChG;AACA,QAAM,cAAc,KAAK,OAAO,cAAc;AAC9C,MAAI,cAAc,EAAG,OAAM,IAAI,UAAU,4CAA4C;AACrF,SAAO,GAAG,KAAK,MAAM,GAAG,WAAW,CAAC,GAAG,SAAS,IAAI,GAAG,KAAK,MAAM,WAAW,CAAC;AAChF;;;ACjIA,eAAe,YAAY,SAAsF;AAC/G,QAAM,SAAS,MAAM,wBAAwB,QAAQ,IAAI,QAAQ,WAAW,QAAQ,WAAW;AAC/F,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,UAAU,8BAA8B,OAAO,QAAQ;AAC7D,MAAI,CAAC,QAAQ,GAAI,OAAM,IAAI,UAAU,8CAA8C,QAAQ,OAAO,KAAK,IAAI,CAAC,EAAE;AAC9G,QAAM,WAAW,QAAQ;AACzB,MAAI,SAAS,aAAa,OAAO,YAAY,SAAS,OAAO,cAAc,QAAQ,aAC/E,SAAS,OAAO,gBAAgB,QAAQ,eAAe,OAAO,WAAW,MAAM,oBAAoB,QAAQ,GAAG;AAChH,UAAM,IAAI,UAAU,8DAA8D;AAAA,EACpF;AACA,SAAO,EAAE,UAAU,OAAO,UAAU,QAAQ,OAAO,QAAQ,OAAO,SAAS,MAAM;AACnF;AAOA,eAAsB,8BACpB,MACA,SACkC;AAClC,QAAM,QAAQ,6BAA6B,MAAM,YAAY,OAAO,GAAG;AAAA,IACrE,iBAAiB,QAAQ;AAAA,EAC3B,CAAC;AACD,SAAO,EAAE,MAAM,6BAA6B,MAAM,OAAO,QAAQ,MAAM,GAAG,MAAM;AAClF;AAEA,eAAe,YAAY,MAA+B;AACxD,QAAM,QAAQ,MAAM,OAAO,OAAO,OAAO,WAAW,IAAI,YAAY,EAAE,OAAO,IAAI,CAAC;AAClF,QAAM,MAAM,MAAM,KAAK,IAAI,WAAW,KAAK,GAAG,CAAC,SAAS,KAAK,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE;AACnG,SAAO,aAAa,GAAG;AACzB;AAQA,eAAsB,6BACpB,UACA,SACmB;AACnB,MAAI,CAAC,SAAS,MAAM,EAAE,SAAS,QAAQ,IAAI,cAAc,KAAK,IAAI,YAAY,EAAE,SAAS,WAAW,GAAG;AACrG,UAAM,IAAI,UAAU,oEAAoE;AAAA,EAC1F;AACA,QAAM,WAAW,MAAM,8BAA8B,MAAM,SAAS,KAAK,GAAG,OAAO;AACnF,QAAM,UAAU,IAAI,QAAQ,SAAS,OAAO;AAC5C,UAAQ,OAAO,gBAAgB;AAC/B,UAAQ,IAAI,iBAAiB,UAAU;AACvC,UAAQ,IAAI,QAAQ,MAAM,YAAY,SAAS,IAAI,CAAC;AACpD,UAAQ,IAAI,gCAAgC,SAAS,MAAM,SAAS,UAAU,WAAW;AACzF,MAAI,SAAS,MAAM,SAAS,aAAa,KAAM,SAAQ,OAAO,gCAAgC;AAAA,MACzF,SAAQ,IAAI,kCAAkC,OAAO,SAAS,MAAM,SAAS,QAAQ,CAAC;AAC3F,SAAO,IAAI,SAAS,SAAS,MAAM,EAAE,QAAQ,SAAS,QAAQ,YAAY,SAAS,YAAY,QAAQ,CAAC;AAC1G;;;ACRA,IAAM,iBAA0B;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA,EAIA,OAAO,MAAM,QAAQ,IAAI,SAAS,WAAW,OAAO,IAChD,KAAK,EAAE,OAAO,YAAY,GAAG,GAAG,IAChC;AACN;AAoBO,SAAS,cAAc,SAA+B;AAC3D,QAAM,MAAM,oBAAoB,OAAO;AACvC,QAAM,SAAkB,CAAC,GAAI,QAAQ,UAAU,CAAC,GAAI,GAAG,cAAc;AACrE,SAAO;AAAA,IACL,MAAM,MAAM,KAAc,KAAoC;AAC5D,YAAM,MAAM,IAAI,IAAI,IAAI,GAAG;AAC3B,iBAAW,SAAS,QAAQ;AAC1B,cAAM,MAAM,MAAM,MAAM,KAAK,KAAK,KAAK,GAAG;AAC1C,YAAI,IAAK,QAAO;AAAA,MAClB;AAEA,aAAO,IAAI,OAAO,MAAM,GAAG;AAAA,IAC7B;AAAA,EACF;AACF;","names":["allowed","rows","rows","record","EMAIL_RE","text","ID","allowed","record","createRecord","updateRecord","record","crmDeps","updateRecord","createRecord","text","str","rows","first","id","groups","group","canonical","record","verifyFederatedRequest","allowed","text","PRICE","ROOT_KEYS","TIER_KEYS","allowed","text","verifyFederatedRequest","verifyFederatedRequest","encoder","canonicalValue","record","ID","SLUG","ROOT_KEYS","MAX_MARKDOWN","record","unknownKeys","allowed","record","unknownKeys","ROOT_KEYS","ID","SLUG","value","MAX_MARKDOWN","rows","reject","rows","verifyFederatedRequest","local","verifyFederatedRequest","reject","verifyFederatedRequest","rows","verifyStripeSignature","clientSecret","verifyStripeSignature","rows","rows","created","secret","first","firstRow","rows","control","first","rows","control","initCalendar","initCalendar","rows","crmDeps","gate","rows","gate","rows","computeBookableSlots","initCalendar","gate","initCalendar","computeBookableSlots","gate","loadGroup","str","text","signFederatedRequest","verifyFederatedRequest","record","crmDeps","gate","verifyFederatedRequest","signFederatedRequest","record","signFederatedRequest","verifyFederatedRequest","gate","record","allowed","verifyFederatedRequest","reader","signFederatedRequest","IDENTIFIER","MAX_NOTE","gate","getRecord","signFederatedRequest","verifyFederatedRequest","IDENTIFIER","RECORD_ID","MAX_NOTE","gate","verifyFederatedRequest","reader","record","getRecord","targetFor","signFederatedRequest","createRecord","allowed","createRecord","signFederatedRequest","signFederatedRequest","signFederatedRequest","signFederatedRequest","signFederatedRequest","signFederatedRequest"]}
1
+ {"version":3,"sources":["../../src/worker-context.ts","../../src/auth.ts","../../src/worker-routes.ts","../../src/discussion-reference-security.ts","../../src/member.ts","../../src/application-id.ts","../../src/email-identity.ts","../../src/tiers.ts","../../src/tiers-store.ts","../../src/scheduling.ts","../../src/admission-grants-contract.ts","../../src/signup-control-canonical.ts","../../src/admission-grants.ts","../../src/flow-fields.ts","../../src/gift-offers.ts","../../src/clerk-roles.ts","../../src/crm-sync.ts","../../src/network.ts","../../src/network-contract.ts","../../src/email.ts","../../src/notify.ts","../../src/pipeline.ts","../../src/approve-application.ts","../../src/join-continuation.ts","../../src/join-continuation-server.ts","../../src/signup-control-store.ts","../../src/session.ts","../../src/clerk.ts","../../src/worker-provisioning.ts","../../src/worker-routes-network-receive.ts","../../src/worker-routes-signup-control.ts","../../src/signup-control-contract.ts","../../src/membership-page.ts","../../src/signup-control-validate.ts","../../src/worker-routes-member-content.ts","../../src/member-content-canonical.ts","../../src/member-content-validation-helpers.ts","../../src/member-content-validation.ts","../../src/member-content.ts","../../src/member-content-store.ts","../../src/worker-routes-admission-grants.ts","../../src/worker-routes-admin-admission.ts","../../src/worker-routes-schedule.ts","../../src/payments.ts","../../src/payments-stripe.ts","../../src/gift-codes.ts","../../src/gift-store.ts","../../src/gift-checkout.ts","../../src/gift-intents.ts","../../src/worker-routes-payments.ts","../../src/worker-routes-gifts.ts","../../src/worker-routes-admin.ts","../../src/reconcile.ts","../../src/worker-routes-admin-people.ts","../../src/worker-routes-admin-clerk.ts","../../src/series.ts","../../src/worker-routes-admin-dashboard.ts","../../src/worker-routes-admin-lifecycle.ts","../../src/worker-routes-admin-comms.ts","../../src/worker-routes-network.ts","../../src/worker-network-fetch.ts","../../src/worker-network-push.ts","../../src/worker-routes-network-records.ts","../../src/worker-routes-network-notes.ts","../../src/worker-routes-network-shared-notes.ts","../../src/worker-routes-formation.ts","../../src/worker-routes-builder-library.ts","../../src/builder-library-validation.ts","../../src/builder-library.ts","../../src/builder-library-canonical.ts","../../src/builder-library-store.ts","../../src/signup-control-delivery.ts","../../src/member-content-delivery.ts","../../src/builder-library-delivery.ts","../../src/admission-grants-delivery.ts","../../src/signup-control-theme.ts","../../src/signup-control-theme-worker.ts","../../src/worker.ts"],"sourcesContent":["// Shared context for the chapter Worker: env typing, the odla-db admin client,\n// Clerk-JWT verification, and the source-aware auth helpers. Split out of\n// worker.ts so the route modules share ONE construction of the caches (public\n// config + JWKS) per site, and the worker entry stays a thin composer under the\n// per-file LOC cap. Nothing here is re-exported from the worker entry, so the\n// public `@odla-ai/chapter/worker` surface is unchanged by the split.\nimport { initAdmin } from \"@odla-ai/db\";\nimport { createRemoteJWKSet, jwtVerify } from \"jose\";\nimport { isAdminRole, roleFromClaim } from \"./auth\";\nimport type { Chapter } from \"./types\";\n\n/** The Cloudflare SEND_EMAIL binding payload. */\nexport interface EmailPayload {\n from: string;\n to: string[];\n subject: string;\n text?: string;\n html?: string;\n replyTo?: string;\n headers?: Record<string, string>;\n}\n\n/** The Worker env a chapter site provides (wrangler vars + the ODLA_API_KEY\n * secret pushed by provision). */\nexport interface ChapterEnv {\n ASSETS: { fetch(req: Request): Promise<Response> };\n ODLA_ENDPOINT: string;\n ODLA_TENANT: string;\n ODLA_PLATFORM: string;\n ODLA_APP_ID: string;\n /** Registry lifetime for this exact app/database. Discussion reference\n * reads fail closed when it is absent or stale. */\n ODLA_APP_INCARNATION?: string;\n ODLA_ENV: string;\n ODLA_API_KEY: string;\n SEND_EMAIL?: { send(payload: EmailPayload): Promise<{ messageId: string }> };\n EMAIL_FROM?: string;\n}\n\n/** Options for `chapterWorker`. */\nexport interface ChapterWorkerOptions {\n chapter: Chapter;\n /** CRM mount point. Default \"/api/crm\". */\n crmBasePath?: string;\n /** Host routes, tried BEFORE the built-ins — so a wrapping site can add its own\n * routes (or override/alias a built-in path) and reuse chapter's auth via the\n * shared {@link WorkerContext}, instead of re-verifying JWTs itself. */\n routes?: Route[];\n}\n\n/** The registry public-config a site reads to boot Clerk sign-in. */\nexport type PublicConfig = { env?: string; clerkPublishableKey?: string | null; issuer?: string | null };\n/** The odla-db admin client type. */\nexport type Db = ReturnType<typeof initAdmin>;\n\n/** A verified session: the Clerk `sub`, optional email, and the raw JWT payload\n * (so the role claim can be read for auth source \"claim\"). */\nexport interface Verified {\n userId: string;\n email?: string;\n payload: Record<string, unknown>;\n}\n\n/** JSON response helper. */\nexport const json = (body: unknown, status = 200): Response =>\n new Response(JSON.stringify(body), { status, headers: { \"content-type\": \"application/json\" } });\n\n/**\n * Build the per-site Worker context: env-independent helpers closing over the\n * public-config and JWKS caches, plus the source-aware auth gate (JWT claim or\n * the odla-db `admins` allowlist). Constructed once per `chapterWorker` and\n * shared by every route module.\n */\nexport function createWorkerContext(options: ChapterWorkerOptions) {\n const { chapter } = options;\n const auth = chapter.auth;\n const crmBase = options.crmBasePath ?? \"/api/crm\";\n\n let publicConfigCache: { value: PublicConfig; at: number } | null = null;\n const jwksByIssuer = new Map<string, ReturnType<typeof createRemoteJWKSet>>();\n\n async function getPublicConfig(env: ChapterEnv): Promise<PublicConfig> {\n if (publicConfigCache && Date.now() - publicConfigCache.at < 5 * 60_000) return publicConfigCache.value;\n const res = await fetch(`${env.ODLA_PLATFORM}/registry/apps/${env.ODLA_APP_ID}/public-config?env=${env.ODLA_ENV}`);\n if (!res.ok) throw new Error(`public-config fetch failed: ${res.status}`);\n const value = (await res.json()) as PublicConfig;\n publicConfigCache = { value, at: Date.now() };\n return value;\n }\n\n async function verifyUser(req: Request, env: ChapterEnv): Promise<Verified | null> {\n const header = req.headers.get(\"authorization\") ?? \"\";\n if (!header.startsWith(\"Bearer \")) return null;\n const token = header.slice(7);\n const { issuer } = await getPublicConfig(env);\n if (!issuer) return null;\n let jwks = jwksByIssuer.get(issuer);\n if (!jwks) {\n jwks = createRemoteJWKSet(new URL(`${issuer}/.well-known/jwks.json`));\n jwksByIssuer.set(issuer, jwks);\n }\n try {\n const { payload } = await jwtVerify(token, jwks, { issuer });\n if (!payload.sub) return null;\n return {\n userId: payload.sub,\n email: typeof payload.email === \"string\" ? payload.email : undefined,\n payload: payload as Record<string, unknown>,\n };\n } catch {\n return null;\n }\n }\n\n function makeDb(env: ChapterEnv): Db {\n return initAdmin({ appId: env.ODLA_TENANT, adminToken: env.ODLA_API_KEY, endpoint: env.ODLA_ENDPOINT });\n }\n\n // The `admins` allowlist gate (auth source \"table\"): no route ever writes it, so\n // membership can only be granted by a human in odla Studio.\n async function isAdminEmail(db: Db, email: string | undefined): Promise<boolean> {\n if (!email) return false;\n const { admins } = await db.query({ admins: { $: { where: { email: email.toLowerCase() }, limit: 1 } } });\n return Array.isArray(admins) && admins.length > 0;\n }\n\n // The read-only `superAdmins` tier — queried, never written (Studio-only).\n async function isSuperAdminEmail(db: Db, email: string | undefined): Promise<boolean> {\n if (!auth.superAdmins || !email) return false;\n const { superAdmins } = await db.query({ superAdmins: { $: { where: { email: email.toLowerCase() }, limit: 1 } } });\n return Array.isArray(superAdmins) && superAdmins.length > 0;\n }\n\n // The user's role, resolved per the auth source: a JWT claim, or the `admins`\n // allowlist synthesized to the admin rung / the lowest one.\n async function roleFor(db: Db, u: Verified): Promise<string> {\n if (auth.source === \"claim\") return roleFromClaim(u.payload, auth);\n return (await isAdminEmail(db, u.email)) ? auth.adminRole : (auth.ladder[0] as string);\n }\n\n // Admin authorization — the boolean gate used by /api/me and the CRM surface.\n async function isAdmin(db: Db, u: Verified): Promise<boolean> {\n if (auth.source === \"claim\") return isAdminRole(roleFromClaim(u.payload, auth), auth);\n return isAdminEmail(db, u.email);\n }\n\n function crmSender(env: ChapterEnv) {\n if (!env.SEND_EMAIL || !env.EMAIL_FROM) return undefined;\n const binding = env.SEND_EMAIL;\n return {\n async send(payload: EmailPayload): Promise<{ messageId: string }> {\n return binding.send(payload);\n },\n };\n }\n\n return { chapter, auth, crmBase, getPublicConfig, verifyUser, makeDb, isAdminEmail, isSuperAdminEmail, roleFor, isAdmin, crmSender };\n}\n\n/** The value returned by {@link createWorkerContext}, threaded to every route. */\nexport type WorkerContext = ReturnType<typeof createWorkerContext>;\n\n/** A worker route handler: owns the request (returns a Response) or falls through\n * (returns null). Host routes passed to `chapterWorker` compose against the same\n * {@link WorkerContext} the built-ins receive. */\nexport type Route = (req: Request, url: URL, env: ChapterEnv, ctx: WorkerContext) => Promise<Response | null>;\n","// Identity + authorization for a chapter/hub site — the pieces every membership\n// site needs and none should re-derive: a resolved role policy, role resolution\n// from a JWT claim, the privilege-escalation guard, and a tenant-vault read.\n// Everything here is pure or structural (no runtime @odla-ai/db import), so it is\n// trivially testable and the worker stays the only thing that talks to odla-db.\nimport type { ChapterAuth, ChapterMode, ResolvedAuth } from \"./types\";\n\n/**\n * Apply defaults + validate the auth config into a {@link ResolvedAuth}. Defaults\n * by mode: `chapter` → the `provisional/member/admin` claim ladder with the\n * `superAdmins` tier; `hub` → the `admins` allowlist table with no super tier.\n * Throws at import on a bad policy.\n */\nexport function resolveAuth(mode: ChapterMode, auth: ChapterAuth | undefined): ResolvedAuth {\n const a = auth ?? {};\n const source = a.source ?? (mode === \"hub\" ? \"table\" : \"claim\");\n if (source !== \"claim\" && source !== \"table\") {\n throw new Error(`defineChapter.auth.source: must be \"claim\" or \"table\" — got ${JSON.stringify(a.source)}`);\n }\n const claim = a.claim ?? \"role\";\n if (typeof claim !== \"string\" || claim === \"\") {\n throw new Error(\"defineChapter.auth.claim: must be a non-empty string\");\n }\n const ladder = a.ladder ?? [\"provisional\", \"member\", \"admin\"];\n if (!Array.isArray(ladder) || ladder.length === 0 || !ladder.every((r) => typeof r === \"string\" && r !== \"\")) {\n throw new Error(\"defineChapter.auth.ladder: must be a non-empty array of role strings\");\n }\n const adminRole = ladder[ladder.length - 1] as string;\n const superAdmins = a.superAdmins ?? source === \"claim\";\n return { source, claim, ladder, adminRole, superAdmins };\n}\n\n/** The role from a verified JWT payload, per the resolved policy. An unknown or\n * missing claim falls back to the lowest ladder rung (fail safe, never admin). */\nexport function roleFromClaim(payload: Record<string, unknown>, auth: ResolvedAuth): string {\n const raw = payload[auth.claim];\n return typeof raw === \"string\" && auth.ladder.includes(raw) ? raw : (auth.ladder[0] as string);\n}\n\n/** Does a role meet the admin bar (the highest ladder rung)? */\nexport function isAdminRole(role: string, auth: ResolvedAuth): boolean {\n return role === auth.adminRole;\n}\n\n/** Inputs to the role-change guard — resolved by the caller (route) from the\n * identity provider + the read-only `superAdmins` table. */\nexport interface RoleChangeContext {\n actorId: string;\n actorIsSuper: boolean;\n targetId: string;\n targetCurrentRole: string;\n targetIsSuper: boolean;\n newRole: string;\n auth: ResolvedAuth;\n}\n\n/** The result of {@link canChangeRole}: allow, or deny with the HTTP status +\n * message the route should return. */\nexport type GuardResult = { ok: true } | { ok: false; status: number; error: string };\n\n/**\n * The privilege-escalation guard — package-enforced so every site gets it and\n * none re-derives it. Denies: an out-of-ladder role; changing your own role;\n * touching a super-admin unless you are one; and (when a `superAdmins` tier\n * exists) creating or altering an admin unless you are a super-admin. Note the\n * super-admin tier itself is never writable here — it lives in the read-only\n * `superAdmins` table, set only in odla Studio.\n */\nexport function canChangeRole(ctx: RoleChangeContext): GuardResult {\n const { auth } = ctx;\n if (!auth.ladder.includes(ctx.newRole)) {\n return { ok: false, status: 400, error: `role must be one of: ${auth.ladder.join(\", \")}` };\n }\n if (ctx.actorId === ctx.targetId) {\n return { ok: false, status: 400, error: \"you cannot change your own role\" };\n }\n if (ctx.targetIsSuper && !ctx.actorIsSuper) {\n return { ok: false, status: 403, error: \"this person is a super-admin; their access is managed in odla Studio\" };\n }\n const touchesAdmin = ctx.newRole === auth.adminRole || ctx.targetCurrentRole === auth.adminRole;\n if (auth.superAdmins && touchesAdmin && !ctx.actorIsSuper) {\n return { ok: false, status: 403, error: `only super-admins can create or change an ${auth.adminRole}` };\n }\n return { ok: true };\n}\n\n/** Structural view of odla-db's tenant-vault read, so chapter takes no runtime\n * dependency on @odla-ai/db. The worker's admin client satisfies this. */\nexport interface SecretStore {\n secrets: { get(name: string): Promise<string> };\n}\n\n/**\n * Read a tenant-vault secret by name; `undefined` when it is absent or the vault\n * errors, so callers degrade gracefully (e.g. `paymentsReady: false`) rather than\n * throwing. Never logs the value.\n */\nexport async function getVaultSecret(db: SecretStore, name: string): Promise<string | undefined> {\n try {\n const value = await db.secrets.get(name);\n return typeof value === \"string\" && value !== \"\" ? value : undefined;\n } catch {\n return undefined;\n }\n}\n","// Route handlers for the chapter Worker. Each returns a Response when it owns the\n// request, or null to fall through to the next handler (finally ASSETS). Split\n// out of worker.ts so the entry stays a thin composer under the per-file LOC cap;\n// behaviour and route order are unchanged from the original single-file handler.\nimport { createCrmRoutes } from \"@odla-ai/crm\";\nimport { authorizeCrmDiscussionReference } from \"./discussion-reference-security\";\nimport { getVaultSecret, isAdminRole } from \"./auth\";\nimport { joinConfig, submitApplication } from \"./member\";\nimport { joinConfigTiers } from \"./tiers\";\nimport { loadOfferableTiers, loadTiers } from \"./tiers-store\";\nimport { resolveScheduling } from \"./scheduling\";\nimport { findAdmissionGrant } from \"./admission-grants\";\nimport { normalizeChapterEmail } from \"./email-identity\";\nimport { chapterFlowFieldContract } from \"./flow-fields\";\nimport { findGiftOffer, publicGiftOffers } from \"./gift-offers\";\nimport { continueJoin } from \"./join-continuation-server\";\nimport { controlledApplication, loadActiveSignupControl } from \"./signup-control-store\";\nimport { memberApplication } from \"./session\";\nimport type { ApplicationRecord, MeetingRecord, MemberApplication } from \"./session\";\nimport { json } from \"./worker-context\";\nimport type { Route } from \"./worker-context\";\nimport type { ChapterDb, ChapterScheduling } from \"./types\";\nimport {\n notifyAdminOfApplication,\n provisionApplicant,\n syncApplicantPrivateMetadata,\n} from \"./worker-provisioning\";\n\nexport type { Route };\n\n// The signed-in member's own application (chapter mode): the latest by email,\n// folded with its latest scheduled meeting and rendered in the group's timezone.\n// The meetings row is canonical, so no live-calendar reconcile is needed here.\nasync function memberSessionApplication(\n db: ChapterDb,\n chapterId: string,\n email: string,\n): Promise<{ application: MemberApplication; source: Record<string, unknown> } | null> {\n let apps = (await db.query({ applications: { $: {\n where: { emailNormalized: normalizeChapterEmail(email) }, limit: 20,\n } } })).applications;\n if (!apps?.length) apps = (await db.query({ applications: { $: { where: { email }, limit: 20 } } })).applications;\n const app = Array.isArray(apps) ? [...apps].sort((a, b) => Number(b.createdAt ?? 0) - Number(a.createdAt ?? 0))[0] : undefined;\n if (!app) return null;\n const meetings = (\n await db.query({ meetings: { $: { where: { applicationId: app.id, status: \"scheduled\" }, order: { createdAt: \"desc\" }, limit: 1 } } })\n ).meetings;\n const meeting = Array.isArray(meetings) ? meetings[0] : undefined;\n const groups = (await db.query({ groups: { $: { where: { id: chapterId }, limit: 1 } } })).groups;\n const group = Array.isArray(groups) ? groups[0] : undefined;\n const timezone = resolveScheduling(group?.schedulingJson as ChapterScheduling | undefined).timezone;\n return {\n application: memberApplication(app as unknown as ApplicationRecord, meeting as unknown as MeetingRecord | undefined, timezone),\n source: app,\n };\n}\n\n/** GET /api/health — a public liveness probe (what deploy checks hit). */\nexport const handleHealth: Route = async (_req, url) => (url.pathname === \"/api/health\" ? json({ ok: true }) : null);\n\n/** GET /api/config — the public Clerk publishable key, so the SPA can boot sign-in. */\nexport const handleConfig: Route = async (_req, url, env, ctx) => {\n if (url.pathname !== \"/api/config\") return null;\n try {\n const { clerkPublishableKey } = await ctx.getPublicConfig(env);\n return json({ clerkPublishableKey: clerkPublishableKey ?? null, env: env.ODLA_ENV });\n } catch {\n return json({ clerkPublishableKey: null, env: env.ODLA_ENV });\n }\n};\n\n/** GET /api/me — the signed-in user's role, admin authorization, and super-admin\n * tier. In chapter mode it also carries the member's own `application` (their\n * status + booked call), so the member area renders from one call. */\nexport const handleMe: Route = async (req, url, env, ctx) => {\n if (url.pathname !== \"/api/me\") return null;\n const u = await ctx.verifyUser(req, env);\n if (!u) return json({ authorized: false }, 401);\n const db = ctx.makeDb(env);\n const role = await ctx.roleFor(db, u);\n const superAdmin = await ctx.isSuperAdminEmail(db, u.email);\n const base = { authorized: isAdminRole(role, ctx.auth), role, superAdmin, email: u.email ?? null };\n if (ctx.chapter.mode !== \"chapter\" || !u.email) return json(base);\n const member = await memberSessionApplication(db as unknown as ChapterDb, ctx.chapter.id, u.email);\n let privateMetadataSynced = false;\n if (\n member &&\n ctx.chapter.account !== \"none\" &&\n typeof member.source.clerkPrivateMetadataSyncedAt !== \"number\"\n ) {\n // Invitation metadata cannot be private. Complete that write after the\n // accepted account first authenticates; the marker makes later /api/me\n // reads database-only. Existing pre-private-metadata accounts take the same\n // path once, which also removes Chapter's former public profile keys.\n privateMetadataSynced = await syncApplicantPrivateMetadata(\n db as unknown as ChapterDb,\n ctx.chapter,\n String(member.source.id),\n member.source,\n u.userId,\n );\n }\n if (member && !privateMetadataSynced && member.source.clerkUserId !== u.userId) {\n // Identity linking is independent of the best-effort metadata mirror. A\n // failed Clerk PATCH must not hide a verified application↔account match,\n // and a directly-created account may already be marked synced before its\n // first session reveals the user id.\n await (db as unknown as ChapterDb).transact([{\n t: \"update\",\n ns: \"applications\",\n id: String(member.source.id),\n attrs: { clerkUserId: u.userId },\n }]).catch(() => undefined);\n }\n return json({ ...base, application: member?.application ?? null });\n};\n\n/** /api/crm/* — the CRM admin surface (mounted at ctx.crmBase). */\nexport const handleCrm: Route = async (req, url, env, ctx) => {\n const crmBase = ctx.crmBase;\n if (url.pathname !== crmBase && !url.pathname.startsWith(crmBase + \"/\")) return null;\n const db = ctx.makeDb(env);\n const routes = createCrmRoutes({\n crm: ctx.chapter.crm,\n db: db as never,\n authorize: async (r: Request) => {\n const u = await ctx.verifyUser(r, env);\n if (!u || !(await ctx.isAdmin(db, u))) return null;\n return u.email ? { userId: u.userId, email: u.email } : { userId: u.userId };\n },\n authorizeDiscussionReferences: (r: Request) =>\n authorizeCrmDiscussionReference(r, env),\n sender: ctx.crmSender(env),\n from: env.EMAIL_FROM,\n envName: env.ODLA_ENV,\n baseUrl: url.origin,\n basePath: crmBase,\n });\n const res = await routes(req);\n if (res) return res;\n return json({ error: \"not found\" }, 404);\n};\n\n/** Chapter-mode public member surface: GET /api/join-config, POST /api/applications.\n * Returns null in hub mode so those paths fall through to ASSETS. */\nexport const handleMember: Route = async (req, url, env, ctx) => {\n const chapter = ctx.chapter;\n if (chapter.mode !== \"chapter\") return null;\n\n // Public join config: prices + policy copy + payment readiness (B1/C2).\n if (req.method === \"GET\" && url.pathname === \"/api/join-config\") {\n const db = ctx.makeDb(env);\n const groupId = url.searchParams.get(\"group\") ?? chapter.id;\n const { groups } = await db.query({ groups: { $: { where: { id: groupId }, limit: 1 } } });\n const group = Array.isArray(groups) ? groups[0] : undefined;\n if (!group) return json({ error: \"not found\" }, 404);\n const stripeKey = await getVaultSecret(db as unknown as ChapterDb, \"stripe_secret_key\");\n const paymentsReady = Boolean(group.stripePublishableKey && group.stripePriceId && stripeKey);\n const offered = await loadOfferableTiers(\n db as unknown as ChapterDb, group as never, Boolean(stripeKey),\n );\n const activeControl = chapter.signupControl\n ? await loadActiveSignupControl(db as unknown as ChapterDb, chapter.id, env.ODLA_ENV)\n : null;\n const application = controlledApplication(chapter.application, activeControl?.document);\n return json({\n ...joinConfig(group as never, paymentsReady, joinConfigTiers(offered), application.conditions),\n fieldContract: chapterFlowFieldContract(chapter, \"join\", application),\n copy: { ...chapter.copy.join, ...(activeControl?.document.application?.copy ?? {}) },\n ...(activeControl ? { signupControl: {\n revision: activeControl.revision,\n digest: activeControl.digest,\n membershipPage: activeControl.document.membershipPage,\n application: activeControl.document.application,\n theme: activeControl.document.theme,\n } } : {}),\n giftOffers: publicGiftOffers(activeControl?.document.giftOffers, Date.now()),\n });\n }\n\n // Resume a redirect-interrupted join flow from canonical database state. The\n // application id is the existing unguessable capability used by payment and\n // booking routes; this response exposes no applicant fields.\n if (req.method === \"GET\" && url.pathname === \"/api/join/resume\") {\n const applicationId = url.searchParams.get(\"application\") ?? \"\";\n if (!applicationId) return json({ error: \"application is required\" }, 400);\n const db = ctx.makeDb(env) as unknown as ChapterDb;\n const apps = (await db.query({\n applications: { $: { where: { id: applicationId }, limit: 1 } },\n })).applications;\n const app = Array.isArray(apps) ? apps[0] : undefined;\n if (!app || String(app.groupId ?? \"\") !== chapter.id) return json({ error: \"not found\" }, 404);\n\n const meetings = (await db.query({\n meetings: {\n $: {\n where: { applicationId, status: \"scheduled\" },\n order: { createdAt: \"desc\" },\n limit: 1,\n },\n },\n })).meetings;\n const meeting = Array.isArray(meetings) ? meetings[0] : undefined;\n if (meeting && typeof meeting.startAt === \"number\") {\n const groups = (await db.query({\n groups: { $: { where: { id: chapter.id }, limit: 1 } },\n })).groups;\n const group = Array.isArray(groups) ? groups[0] : undefined;\n const timezone = resolveScheduling(group?.schedulingJson as ChapterScheduling | undefined).timezone;\n return json({\n state: \"done\",\n applicationId,\n booked: { startAt: meeting.startAt, timezone },\n });\n }\n\n const groups = (await db.query({\n groups: { $: { where: { id: chapter.id }, limit: 1 } },\n })).groups;\n const group = Array.isArray(groups) ? groups[0] : undefined;\n if (!group) return json({ error: \"not found\" }, 404);\n const state = await continueJoin(db, ctx, env, url.origin, app, group);\n if (state) return json({ state, applicationId, ...(state === \"gift\" ? { claimId: app.giftClaimId } : {}) });\n return json({ error: `application cannot resume from status \"${String(app.status ?? \"\")}\"` }, 409);\n }\n\n // Public application submit — validated, body-capped, idempotent (B2/B3).\n if (req.method === \"POST\" && url.pathname === \"/api/applications\") {\n const raw = await req.text();\n if (raw.length > chapter.application.bodyCap) return json({ error: \"request body too large\" }, 413);\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n const submissionId = typeof parsed.submissionId === \"string\" ? parsed.submissionId : undefined;\n const db = ctx.makeDb(env) as unknown as ChapterDb;\n const activeControl = chapter.signupControl\n ? await loadActiveSignupControl(db, chapter.id, env.ODLA_ENV)\n : null;\n const effectiveChapter = activeControl\n ? { ...chapter, application: controlledApplication(chapter.application, activeControl.document) }\n : chapter;\n // Resolve the offered tiers only when the applicant claims one, so a\n // chapter that never uses tiers pays for no extra read.\n const offeredTierIds = typeof parsed.tierId === \"string\" && parsed.tierId\n ? (await loadTiers(db, { id: chapter.id })).map((tier) => tier.id)\n : undefined;\n const now = Date.now();\n const requestedGiftId = typeof parsed.giftOfferId === \"string\" ? parsed.giftOfferId : \"\";\n const giftOffer = requestedGiftId ? findGiftOffer(activeControl?.document.giftOffers, requestedGiftId, now) : null;\n if (requestedGiftId && !giftOffer) return json({ error: \"gift offer is unavailable\" }, 400);\n const effectiveGrant = !giftOffer && typeof parsed.email === \"string\"\n ? await findAdmissionGrant(db, chapter.id, parsed.email, now)\n : null;\n const result = await submitApplication(db, effectiveChapter, parsed, {\n submissionId,\n groupId: chapter.id,\n now,\n newId: () => crypto.randomUUID(),\n ...(offeredTierIds ? { tierIds: offeredTierIds } : {}),\n ...(effectiveGrant?.decision === \"waive_interview\" ? { admissionGrant: effectiveGrant } : {}),\n ...(giftOffer ? { giftOfferId: giftOffer.id } : {}),\n });\n if (!result.ok) return json({ error: result.error }, 400);\n if (!result.duplicate) {\n // The trigger is declarative (sends.adminNotification); addressing + copy\n // stay owner-editable on the group row.\n if (effectiveChapter.sends.adminNotification === \"submit\") {\n await notifyAdminOfApplication(db, env, chapter.id, result.id, parsed);\n }\n await provisionApplicant(db, effectiveChapter, result.id, parsed);\n }\n const apps = (await db.query({ applications: { $: { where: { id: result.id }, limit: 1 } } })).applications;\n const canonical = Array.isArray(apps) ? apps[0] : undefined;\n const groups = (await db.query({ groups: { $: { where: { id: chapter.id }, limit: 1 } } })).groups;\n const group = Array.isArray(groups) ? groups[0] : undefined;\n const state = canonical && group\n ? await continueJoin(db, ctx, env, url.origin, canonical, group)\n : null;\n return json({\n id: result.id,\n duplicate: result.duplicate,\n status: result.status,\n ...(state ? { state } : {}),\n // Echoed so a site can see (and assert in an integration test) whether its\n // join page actually posted the ack. Absent consent is otherwise invisible.\n disclaimerAckAt: result.disclaimerAckAt,\n });\n }\n\n return null;\n};\n","import type { CrmDiscussionReferenceActor } from \"@odla-ai/crm\";\nimport type { ChapterEnv } from \"./worker-context\";\n\ninterface Verification {\n actor?: { id?: unknown; kind?: unknown; email?: unknown };\n authority?: {\n appId?: unknown;\n appIncarnation?: unknown;\n appEnv?: unknown;\n capability?: unknown;\n product?: unknown;\n projectCapability?: unknown;\n audience?: unknown;\n };\n}\n\n/**\n * Verify Registry's short-lived CRM reference assertion. This deliberately\n * grants only product reference reads; CRM mutations retain Chapter's Clerk\n * admin gate and never accept this token.\n */\nexport async function authorizeCrmDiscussionReference(\n req: Request,\n env: ChapterEnv,\n fetcher: typeof fetch = fetch,\n): Promise<CrmDiscussionReferenceActor | null> {\n const match = req.headers.get(\"authorization\")?.match(/^Bearer ([^\\s]+)$/);\n const appIncarnation = env.ODLA_APP_INCARNATION;\n const expectedTenant = env.ODLA_ENV === \"prod\"\n ? env.ODLA_APP_ID\n : `${env.ODLA_APP_ID}--${env.ODLA_ENV}`;\n if (\n !match ||\n env.ODLA_TENANT !== expectedTenant ||\n typeof appIncarnation !== \"string\" ||\n !/^[a-f0-9]{32}$/.test(appIncarnation)\n ) return null;\n const requestUrl = new URL(req.url);\n requestUrl.search = \"\";\n requestUrl.hash = \"\";\n const audience = requestUrl.href;\n try {\n const url = new URL(\n \"/registry/discuss/reference-authority/verify\",\n env.ODLA_PLATFORM,\n );\n const response = await fetcher(url, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({\n token: match[1],\n appId: env.ODLA_APP_ID,\n appIncarnation,\n env: env.ODLA_ENV,\n product: \"crm\",\n projectCapability: \"crm.read\",\n audience,\n }),\n redirect: \"manual\",\n });\n if (!response.ok) return null;\n const value = await response.json() as Verification;\n if (\n value.authority?.appId !== env.ODLA_APP_ID ||\n value.authority.appIncarnation !== appIncarnation ||\n value.authority.appEnv !== env.ODLA_ENV ||\n value.authority.capability !== \"product.reference.read\" ||\n value.authority.product !== \"crm\" ||\n value.authority.projectCapability !== \"crm.read\" ||\n value.authority.audience !== audience ||\n typeof value.actor?.id !== \"string\" ||\n (value.actor.kind !== \"human\" && value.actor.kind !== \"agent\") ||\n (value.actor.email !== undefined &&\n typeof value.actor.email !== \"string\")\n ) return null;\n return {\n userId: value.actor.id,\n discussionReferenceScope: \"all\",\n ...(value.actor.email ? { email: value.actor.email } : {}),\n };\n } catch {\n return null;\n }\n}\n","// The public member surface logic: the join config a site's join page reads (B1)\n// and the idempotent application submit (B2 validation + B3 exactly-once). Both\n// take the structural ChapterDb, so they're tested against an in-memory fake and\n// carry no runtime @odla-ai/db import. The worker builds the real db client, does\n// Clerk verification, enforces the body cap, and mounts these on chapter routes.\nimport type { Chapter, ChapterApplication, ChapterDb, ResolvedApplication } from \"./types\";\nimport { assertFieldCondition, resolveFieldStates } from \"@odla-ai/crm\";\nimport type { FieldConditions } from \"@odla-ai/crm\";\nimport { applicationIdForSubmission } from \"./application-id\";\nimport type { JoinConfigTier } from \"./tiers\";\nimport type { AdmissionGrantRow } from \"./admission-grants\";\nimport { normalizeChapterEmail } from \"./email-identity\";\n\n// The reference join form. `focus` (a json field) is always accepted.\nconst DEFAULT_REQUIRED = [\"firstName\", \"lastName\", \"email\", \"referral\", \"whoYouAre\", \"message\"];\nconst DEFAULT_OPTIONAL = [\"referralName\", \"linkedin\", \"phone\", \"state\"];\nconst SCHEMA_FIELD = /^[A-Za-z_][A-Za-z0-9_-]*$/;\n\n/** Apply defaults + validate the application config. Throws at import on bad shape. */\nexport function resolveApplication(a: ChapterApplication | undefined): ResolvedApplication {\n const required = a?.required ?? DEFAULT_REQUIRED;\n const optional = a?.optional ?? DEFAULT_OPTIONAL;\n for (const [name, arr] of [[\"required\", required], [\"optional\", optional]] as const) {\n if (!Array.isArray(arr) || !arr.every((f) => typeof f === \"string\" && f !== \"\")) {\n throw new Error(`defineChapter.application.${name}: must be an array of field-name strings`);\n }\n const unsafe = arr.find((field) => !SCHEMA_FIELD.test(field));\n if (unsafe) {\n throw new Error(`defineChapter.application.${name}: field \"${unsafe}\" must match ${SCHEMA_FIELD.source}`);\n }\n }\n const duplicate = [...required, ...optional].find((field, index, fields) => fields.indexOf(field) !== index);\n if (duplicate) {\n throw new Error(`defineChapter.application: duplicate field \"${duplicate}\" across required/optional lists`);\n }\n if (a?.profileFields !== undefined && (!Array.isArray(a.profileFields) || !a.profileFields.every((f) => typeof f === \"string\" && f !== \"\"))) {\n throw new Error(\"defineChapter.application.profileFields: must be an array of field-name strings\");\n }\n if (a?.crmFields !== undefined && (!Array.isArray(a.crmFields) || !a.crmFields.every((f) => typeof f === \"string\" && f !== \"\"))) {\n throw new Error(\"defineChapter.application.crmFields: must be an array of field-name strings\");\n }\n // Conditions are checked when the chapter is defined, so a typo fails at\n // startup rather than quietly misbehaving on a live join page. Fields that\n // fail open at runtime are the deliberate second line of defence, not this.\n const conditions = a?.conditions ?? {};\n for (const [field, declared] of Object.entries(conditions)) {\n for (const key of [\"visibleWhen\", \"requiredWhen\"] as const) {\n const expression = declared?.[key];\n if (expression === undefined) continue;\n if (typeof expression !== \"string\" || !expression.trim()) {\n throw new Error(`defineChapter.application.conditions.${field}.${key}: must be a non-empty CEL condition`);\n }\n assertFieldCondition(expression, `defineChapter.application.conditions.${field}.${key}`);\n }\n }\n return {\n required,\n optional,\n conditions,\n maxLen: a?.maxLen ?? {},\n defaultMaxLen: a?.defaultMaxLen ?? 2000,\n bodyCap: a?.bodyCap ?? 32768,\n requireDisclaimerAck: a?.requireDisclaimerAck ?? true,\n profileFields: a?.profileFields ?? [],\n crmFields: a?.crmFields ?? [],\n maxArrayLen: a?.maxArrayLen ?? 100,\n validateEmail: a?.validateEmail ?? true,\n };\n}\n\n// A permissive email shape check: one @, a dot-bearing domain, no whitespace.\n// Deliberately not RFC-exhaustive — the goal is to reject \"notanemail\" before it\n// fails the downstream Clerk create, not to adjudicate exotic-but-valid addresses.\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\n/** Whether a string looks like an email address (see {@link EMAIL_RE}). Exported\n * so a site building its own submit path applies the same rule chapter does. */\nexport function isValidEmail(value: unknown): boolean {\n return typeof value === \"string\" && EMAIL_RE.test(value);\n}\n\n/** Bound an array-valued field: drop non-primitive elements and cap the length,\n * so a client cannot post an unbounded array. Non-arrays pass through unchanged. */\nexport function clampArray(value: unknown, max: number): unknown {\n if (!Array.isArray(value)) return value;\n return value.filter((x) => typeof x === \"string\" || typeof x === \"number\" || typeof x === \"boolean\").slice(0, max);\n}\n\n/** Whether a submit body carries a genuine disclaimer acknowledgement. Accepts\n * the boolean an API client sends and the string a plain HTML form posts. */\nexport function hasDisclaimerAck(fields: Record<string, unknown>): boolean {\n return fields.disclaimerAck === true || fields.disclaimerAck === \"true\";\n}\n\n// Clerk carries these as first-class user fields, so repeating them in\n// public_metadata would be duplicated state that can drift.\nconst IDENTITY_FIELDS = new Set([\"email\", \"firstName\", \"lastName\"]);\n\n/**\n * The applicant profile written to the Clerk account's backend-only\n * `private_metadata.profile`. Projects each configured non-identity field, plus\n * `focus` (clamped), but ONLY those in `application.profileFields`. Derived\n * from config, so a site's own field names project without this package knowing\n * them. Pure; returns `undefined` when there is nothing to write.\n */\nexport function applicantProfile(\n chapter: Chapter,\n fields: Record<string, unknown>,\n): Record<string, unknown> | undefined {\n const app = chapter.application;\n const allowed = (f: string): boolean => app.profileFields.includes(f);\n const profile: Record<string, unknown> = {};\n for (const f of [...app.required, ...app.optional]) {\n if (IDENTITY_FIELDS.has(f) || !allowed(f)) continue;\n const v = fields[f];\n if (typeof v === \"string\" && v.trim() !== \"\") profile[f] = v.trim();\n }\n if (fields.focus !== undefined && allowed(\"focus\")) profile.focus = clampArray(fields.focus, app.maxArrayLen);\n return Object.keys(profile).length > 0 ? profile : undefined;\n}\n\n/** A validated submission, or a 400-worthy validation error the route returns.\n * `disclaimerAckAt` reports what THIS request recorded — a number when consent\n * was stamped, `null` when none was supplied. It is always present so a missing\n * consent record is visible in the response rather than silently absent from a\n * row nobody reads until an audit. */\nexport type SubmitResult =\n | { ok: true; id: string; duplicate: boolean; status: string; disclaimerAckAt: number | null }\n | { ok: false; error: string };\n\n/**\n * Submit a membership application (B2 + B3). Validates the configured required\n * fields + max lengths, writes the `applications` row at the pipeline's initial\n * status, and — when the client supplies a `submissionId` — stamps it as the\n * transaction's mutationId (`join:${submissionId}`) so a double-tap can never\n * create two applications. The application id is derived from that same stable\n * input, so the duplicate response returns the first request's canonical id\n * rather than a fresh, nonexistent one. Idempotency is package-enforced.\n * `now`/`newId` are injected (deterministic in tests).\n */\nexport async function submitApplication(\n db: ChapterDb,\n chapter: Chapter,\n fields: Record<string, unknown>,\n opts: {\n submissionId?: string;\n groupId?: string;\n now: number;\n newId: () => string;\n /** Tier ids this chapter offers. A posted `tierId` outside it is refused;\n * omit to accept any (pre-tier callers). */\n tierIds?: readonly string[];\n /** Effective one-use waiver selected by the server, never by the client. */\n admissionGrant?: AdmissionGrantRow;\n /** Server-validated gift offer selected from active signed control. */\n giftOfferId?: string;\n },\n): Promise<SubmitResult> {\n const app = chapter.application;\n // Requiredness is resolved against the answers, not read off a static list,\n // so a conditionally-hidden field is not demanded and a conditionally-\n // required one cannot be skipped by posting straight to this route. The\n // renderer calls the same resolver, so the form and the validator cannot\n // disagree. With no conditions declared this is exactly the old static loop.\n const fieldStates = resolveFieldStates(app.conditions ?? {}, fields, app.required);\n for (const [f, state] of Object.entries(fieldStates)) {\n if (!state.required) continue;\n const v = fields[f];\n if (typeof v !== \"string\" || v.trim() === \"\") return { ok: false, error: `${f} is required` };\n }\n for (const f of [...app.required, ...app.optional]) {\n const v = fields[f];\n const cap = app.maxLen[f] ?? app.defaultMaxLen;\n if (typeof v === \"string\" && v.length > cap) return { ok: false, error: `${f} exceeds ${cap} characters` };\n }\n // A malformed email can only fail the downstream Clerk create; reject it here\n // as a clean 400. A valid application always has a valid email, so no genuine\n // submission is newly rejected.\n if (app.validateEmail && typeof fields.email === \"string\" && !isValidEmail(fields.email.trim())) {\n return { ok: false, error: \"email must be a valid email address\" };\n }\n\n const acked = hasDisclaimerAck(fields);\n if (app.requireDisclaimerAck && !acked) {\n return { ok: false, error: \"disclaimerAck is required\" };\n }\n\n const id = opts.submissionId\n ? await applicationIdForSubmission(opts.submissionId)\n : opts.newId();\n const row: Record<string, unknown> = { id, status: chapter.pipeline.initial, createdAt: opts.now };\n for (const f of [...app.required, ...app.optional]) {\n // A field the conditions hid was never asked, so a value for it is stale\n // or forged. Storing it would answer a question on the applicant's behalf.\n if (fieldStates[f]?.visible === false) continue;\n if (typeof fields[f] === \"string\") row[f] = (fields[f] as string).trim();\n }\n if (fields.focus !== undefined) row.focus = clampArray(fields.focus, app.maxArrayLen);\n if (opts.groupId) row.groupId = opts.groupId;\n if (typeof fields.email === \"string\" && isValidEmail(fields.email.trim())) {\n row.emailNormalized = normalizeChapterEmail(fields.email);\n }\n if (opts.admissionGrant?.decision === \"waive_interview\") {\n row.admissionGrantId = opts.admissionGrant.id;\n row.admissionSource = opts.admissionGrant.sourceScope;\n row.interviewWaivedAt = opts.now;\n }\n if (opts.giftOfferId) row.giftOfferId = opts.giftOfferId;\n // A tier decides what this member is charged, so the posted id is checked\n // against what the chapter actually offers rather than trusted. An unknown\n // id is refused instead of silently dropped: dropping it would bill the\n // applicant whatever the fallback tier costs.\n if (typeof fields.tierId === \"string\" && fields.tierId) {\n if (opts.tierIds && !opts.tierIds.includes(fields.tierId)) {\n return { ok: false, error: \"tierId is not an offered tier\" };\n }\n row.tierId = fields.tierId;\n }\n // The disclaimer acknowledgement is a compliance record, so it is stamped from\n // the server clock on a genuine ack and left absent otherwise — a client-supplied\n // timestamp would be forgeable, and a row that always carries one would record\n // consent nobody gave.\n if (acked) row.disclaimerAckAt = opts.now;\n\n const ops: Parameters<ChapterDb[\"transact\"]>[0] = [\n { t: \"update\", ns: \"applications\", id, attrs: row },\n ];\n if (opts.admissionGrant?.decision === \"waive_interview\") {\n ops.push({ t: \"update\", ns: \"admissionGrants\", id: opts.admissionGrant.id, attrs: {\n consumedAt: opts.now,\n consumedApplicationId: id,\n } });\n }\n const { duplicate } = await db.transact(\n ops,\n opts.submissionId ? { mutationId: `join:${opts.submissionId}` } : undefined,\n );\n return { ok: true, id, duplicate, status: chapter.pipeline.initial, disclaimerAckAt: acked ? opts.now : null };\n}\n\n/** The `groups`-row fields the join config exposes. */\nexport interface JoinConfigGroup {\n id: string;\n name: string;\n standardPriceCents?: number;\n foundingDiscountCents?: number;\n disclaimerText?: string;\n refundPolicyText?: string;\n trustCopy?: string;\n commitmentText?: string;\n normsText?: string;\n}\n\n/**\n * The public join config (B1) a site's join page reads: copy + prices from the\n * group row plus `paymentsReady`. When payments aren't wired the join flow drops\n * the payment step (C2) — the worker computes `paymentsReady` from the group's\n * Stripe keys + vault secret. Pure.\n *\n * `tiers` carries the offerable membership tiers. It is additive: the legacy\n * `standardPriceCents`/`foundingDiscountCents` fields still describe the first\n * tier, so a join page written before tiers keeps rendering unchanged. A free\n * tier appears here with `free: true` even when Stripe is unconfigured, because\n * nothing needs charging for it.\n */\nexport function joinConfig(\n group: JoinConfigGroup,\n paymentsReady: boolean,\n tiers: readonly JoinConfigTier[] = [],\n conditions: Readonly<Record<string, FieldConditions>> = {},\n): Record<string, unknown> {\n return {\n id: group.id,\n name: group.name,\n standardPriceCents: group.standardPriceCents ?? 0,\n foundingDiscountCents: group.foundingDiscountCents ?? 0,\n tiers: [...tiers],\n // The browser evaluates the same conditions the server enforces.\n conditions,\n disclaimerText: group.disclaimerText ?? \"\",\n refundPolicyText: group.refundPolicyText ?? \"\",\n trustCopy: group.trustCopy ?? \"\",\n commitmentText: group.commitmentText ?? \"\",\n normsText: group.normsText ?? \"\",\n paymentsReady,\n };\n}\n","// Application creates use a caller-stable submission id as their database\n// mutation id. The entity id must be derived from that same stable input: if a\n// committed request is retried, the database correctly skips the new ops and\n// Chapter must still return the id of the row written by the first request.\n\nconst APPLICATION_ID_DOMAIN = \"odla-ai/chapter/application/v1:\";\n\n/**\n * Derive the UUID-shaped capability for an idempotent application submission.\n * SHA-256 prevents a caller from choosing a submission id that overwrites a\n * known application id; UUIDv8 bits preserve the identifier shape consumers\n * already expect.\n */\nexport async function applicationIdForSubmission(submissionId: string): Promise<string> {\n const input = new TextEncoder().encode(`${APPLICATION_ID_DOMAIN}${submissionId}`);\n const bytes = new Uint8Array(await crypto.subtle.digest(\"SHA-256\", input)).slice(0, 16);\n bytes[6] = (bytes[6]! & 0x0f) | 0x80;\n bytes[8] = (bytes[8]! & 0x3f) | 0x80;\n const hex = [...bytes].map((byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n}\n","/**\n * Normalize an email address for Chapter identity lookups.\n *\n * Chapter treats the address literally: surrounding whitespace and ASCII case\n * are insignificant, but the local part is otherwise preserved. In\n * particular, provider-specific aliases are never collapsed, so\n * `foo+bar@gmail.com` and `foo@gmail.com` remain distinct applicants,\n * admission decisions, purchasers, and beneficiaries.\n */\nexport function normalizeChapterEmail(email: string): string {\n return email.trim().toLowerCase();\n}\n","// Membership tiers. A chapter offers one or more tiers, and a tier — not the\n// group — decides what a member pays. Keeping the price on the tier is what\n// makes a free tier expressible: `paymentsReady` used to gate the whole join\n// flow on the group holding a Stripe price, so a £0 membership was unjoinable.\n//\n// Everything here is pure so the join page, the checkout route and the seeder\n// agree about which tiers exist and which of them can actually be bought.\n\n/** One membership tier a chapter offers. `priceCents: 0` means free. */\nexport interface ChapterTier {\n /** Stable slug, referenced by `applications.tierId`. Never renumbered. */\n id: string;\n /** The group this tier belongs to. */\n groupId: string;\n /** Display name, e.g. \"Founding\". */\n name: string;\n /** Price in minor units. `0` is free and needs no Stripe price. */\n priceCents: number;\n /** Stripe price to subscribe. Required only when `priceCents > 0`. */\n stripePriceId?: string | null;\n /** Short description shown beside the tier on the join page. */\n blurb?: string;\n /** Ascending display order; ties fall back to `id` for a stable sort. */\n sortOrder: number;\n /** An inactive tier is retained for existing members but never offered. */\n active: boolean;\n}\n\n/**\n * A tier as declared in `defineChapter`, before it becomes a row.\n *\n * `groupId` is absent here because the chapter owns exactly one group at seed\n * time; the seeder fills it in.\n */\nexport interface ChapterTierConfig {\n id: string;\n name: string;\n priceCents: number;\n stripePriceId?: string;\n blurb?: string;\n /** Defaults to declaration order when omitted. */\n sortOrder?: number;\n /** Defaults to true; set false to retire a tier without deleting it. */\n active?: boolean;\n}\n\n/** Build the seed rows for a chapter's declared tiers. */\nexport function buildTierSeeds(\n groupId: string,\n configured: readonly ChapterTierConfig[] = [],\n now = 0,\n): Array<Record<string, unknown>> {\n return configured.map((tier, index) => ({\n id: tier.id,\n groupId,\n name: tier.name,\n priceCents: tier.priceCents,\n ...(tier.stripePriceId ? { stripePriceId: tier.stripePriceId } : {}),\n ...(tier.blurb ? { blurb: tier.blurb } : {}),\n sortOrder: tier.sortOrder ?? index,\n active: tier.active !== false,\n createdAt: now,\n }));\n}\n\n/** The `groups`-row fields tier payability depends on. */\nexport interface TierGroup {\n id?: string;\n stripePublishableKey?: string | null;\n /** Legacy single price, used only to synthesize an implicit tier. */\n stripePriceId?: string | null;\n standardPriceCents?: number;\n foundingDiscountCents?: number;\n}\n\n/**\n * Whether this tier costs nothing. A free tier never touches Stripe.\n *\n * Free means both no price AND no Stripe price to charge against. The second\n * half matters for chapters that predate tiers: a group can carry a real\n * `stripePriceId` while `standardPriceCents` is 0, because the cents field is\n * display copy and the amount actually lives in Stripe. Reading such a group as\n * free would silently stop charging an existing paying chapter.\n */\nexport function tierIsFree(\n tier: Pick<ChapterTier, \"priceCents\"> & { stripePriceId?: string | null },\n): boolean {\n return !(tier.priceCents > 0) && !tier.stripePriceId;\n}\n\n/**\n * Whether a tier can actually be joined right now.\n *\n * A free tier is always joinable — there is nothing to charge, so Stripe being\n * unconfigured is irrelevant to it. A paid tier needs the group's publishable\n * key, its own Stripe price, and the vault secret; missing any of those drops\n * the tier rather than half-charging for it.\n */\nexport function tierPayable(\n tier: Pick<ChapterTier, \"priceCents\" | \"stripePriceId\">,\n group: TierGroup,\n hasSecretKey: boolean,\n): boolean {\n if (tierIsFree(tier)) return true;\n return Boolean(group.stripePublishableKey && tier.stripePriceId && hasSecretKey);\n}\n\n/** Sort by `sortOrder`, then `id`, so a page never reorders between reads. */\nfunction byOrder(a: ChapterTier, b: ChapterTier): number {\n return a.sortOrder - b.sortOrder || a.id.localeCompare(b.id);\n}\n\n/**\n * The tiers a chapter offers, given the stored rows.\n *\n * A chapter that predates tiers has no rows, and must keep working untouched:\n * one implicit `\"standard\"` tier is synthesized from the group's legacy\n * `standardPriceCents`/`stripePriceId` columns. That is why there is no\n * migration — an existing chapter reads exactly as it did before, and writing\n * its first real tier row takes over.\n */\nexport function resolveTiers(group: TierGroup, rows: readonly ChapterTier[] = []): ChapterTier[] {\n const stored = rows.filter((tier) => tier.active);\n if (stored.length) return [...stored].sort(byOrder);\n return [{\n id: \"standard\",\n groupId: String(group.id ?? \"\"),\n name: \"Membership\",\n priceCents: group.standardPriceCents ?? 0,\n ...(group.stripePriceId ? { stripePriceId: group.stripePriceId } : {}),\n sortOrder: 0,\n active: true,\n }];\n}\n\n/** The tiers to show on the join page: active, and joinable as configured. */\nexport function offerableTiers(\n tiers: readonly ChapterTier[],\n group: TierGroup,\n hasSecretKey: boolean,\n): ChapterTier[] {\n return tiers.filter((tier) => tier.active && tierPayable(tier, group, hasSecretKey));\n}\n\n/**\n * Resolve the tier an application chose.\n *\n * An absent `tierId` is the pre-tier case and selects the only offered tier\n * when exactly one exists; with several it is genuinely ambiguous and returns\n * `null`, because guessing would charge someone the wrong price.\n */\nexport function findTier(\n tiers: readonly ChapterTier[],\n tierId: string | null | undefined,\n): ChapterTier | null {\n if (!tierId) return tiers.length === 1 ? tiers[0]! : null;\n return tiers.find((tier) => tier.id === tierId) ?? null;\n}\n\n/** The public shape of a tier on the join config. Never exposes Stripe ids. */\nexport interface JoinConfigTier {\n id: string;\n name: string;\n priceCents: number;\n blurb: string;\n free: boolean;\n}\n\n/** Project tiers for the public join config, dropping provider identifiers. */\nexport function joinConfigTiers(tiers: readonly ChapterTier[]): JoinConfigTier[] {\n return tiers.map((tier) => ({\n id: tier.id,\n name: tier.name,\n priceCents: tier.priceCents,\n blurb: tier.blurb ?? \"\",\n free: tierIsFree(tier),\n }));\n}\n","// Reading tiers out of the database. Kept apart from tiers.ts so the decision\n// logic there stays pure and directly testable, and apart from the route\n// modules so both the join config and the checkout resolve tiers identically —\n// a page that offers a tier the checkout would refuse is the bug this prevents.\nimport type { ChapterDb } from \"./types\";\nimport { offerableTiers, resolveTiers, type ChapterTier, type TierGroup } from \"./tiers\";\n\n/** A `groups` row as the tier loader needs it. */\nexport type TierGroupRow = TierGroup & { id?: string };\n\nfunction rowToTier(row: Record<string, unknown>, groupId: string): ChapterTier {\n return {\n id: String(row.id ?? \"\"),\n groupId: String(row.groupId ?? groupId),\n name: String(row.name ?? \"\"),\n priceCents: typeof row.priceCents === \"number\" ? row.priceCents : 0,\n ...(typeof row.stripePriceId === \"string\" && row.stripePriceId\n ? { stripePriceId: row.stripePriceId }\n : {}),\n ...(typeof row.blurb === \"string\" ? { blurb: row.blurb } : {}),\n sortOrder: typeof row.sortOrder === \"number\" ? row.sortOrder : 0,\n // A row that never set `active` is offered; only an explicit false retires\n // a tier, so a half-seeded row cannot silently hide a membership.\n active: row.active !== false,\n };\n}\n\n/**\n * Every tier a group offers, ordered, including the implicit tier synthesized\n * for a chapter that predates tiers. Never throws on a missing namespace: a\n * deployment whose schema has not been pushed yet reads as \"no rows\", which\n * resolves to the legacy single tier.\n */\nexport async function loadTiers(db: ChapterDb, group: TierGroupRow): Promise<ChapterTier[]> {\n const groupId = String(group.id ?? \"\");\n let rows: unknown;\n try {\n rows = (await db.query({\n tiers: { $: { where: { groupId }, order: { sortOrder: \"asc\" }, limit: 100 } },\n }) as Record<string, unknown>).tiers;\n } catch {\n rows = undefined;\n }\n const list = Array.isArray(rows)\n ? rows.map((row) => rowToTier(row as Record<string, unknown>, groupId))\n : [];\n return resolveTiers(group, list);\n}\n\n/** The tiers a join page may show: active, and joinable as configured. */\nexport async function loadOfferableTiers(\n db: ChapterDb,\n group: TierGroupRow,\n hasSecretKey: boolean,\n): Promise<ChapterTier[]> {\n return offerableTiers(await loadTiers(db, group), group, hasSecretKey);\n}\n","// Scheduling core — config resolution + the booking invariants, ported from the\n// proven production worker. Everything here is PURE (no @odla-ai/calendar, no\n// db), so the correctness properties are unit-testable and package-enforced; the\n// worker route owns only the I/O (FreeBusy, computeBookableSlots, calendar\n// create/reschedule, the db writes) and calls these.\n//\n// Package-enforced invariants:\n// - the `meetings` row is canonical; applications.meetingAt and the calendar\n// event are projections written from it.\n// - one intro event per application, forever: a rebooking RESCHEDULES the\n// existing event (preserving its Meet link + invite thread), never creates a\n// second — see {@link bookingDecision} + {@link introIdempotencyKey}.\n// - status never moves backward on booking; you can only book from a pipeline\n// stage in `bookableFrom` — see `canBook` in ./pipeline + applicationBookingUpdate.\n// - endAt is always derived server-side, never client-supplied — see\n// {@link endForSlot}.\nimport type { ChapterScheduling } from \"./types\";\n\n/** A fully-resolved scheduling config (every field present). */\nexport interface ResolvedScheduling {\n slotMinutes: number;\n days: readonly number[];\n startHour: number;\n endHour: number;\n timezone: string;\n minNoticeHours: number;\n windowDays: number;\n summaryTemplate: string;\n}\n\n/** Proven defaults: 45-minute weekday slots, 9–5 Pacific, 24h notice,\n * a 14-day window. The summary is generic (a chapter's group seed supplies a\n * name-branded one). */\nexport const SCHEDULING_DEFAULTS: ResolvedScheduling = {\n slotMinutes: 45,\n days: [1, 2, 3, 4, 5],\n startHour: 9,\n endHour: 17,\n timezone: \"America/Los_Angeles\",\n minNoticeHours: 24,\n windowDays: 14,\n summaryTemplate: \"Introduction call with {{firstName}} {{lastName}}\",\n};\n\nfunction isValidTimeZone(tz: string): boolean {\n try {\n new Intl.DateTimeFormat(undefined, { timeZone: tz });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Resolve a group's scheduling config against the defaults, validating every\n * bound at config-write time (throws on a bad config, so a\n * misconfiguration surfaces immediately rather than yielding empty slots).\n * `windowDays` is capped at 62 because Google FreeBusy is.\n */\nexport function resolveScheduling(config?: ChapterScheduling): ResolvedScheduling {\n const result = validateScheduling(config);\n if (result.ok) return result.value;\n const detail = Object.entries(result.errors)\n .map(([field, message]) => `${field}: ${message}`)\n .join(\" \");\n throw new Error(`scheduling: ${detail}`);\n}\n\n/** Validation messages keyed by form field. */\nexport type SchedulingErrors = Record<string, string>;\n\n/**\n * Validate a scheduling config field by field, collecting owner-readable messages\n * rather than throwing on the first problem. An admin settings form needs to say\n * *which* field is wrong and why — \"pick at least one day\" beats a stack trace —\n * so the admin route returns these directly. {@link resolveScheduling} is the\n * throwing wrapper for internal/config-time use.\n */\nexport function validateScheduling(\n config?: ChapterScheduling,\n): { ok: true; value: ResolvedScheduling } | { ok: false; errors: SchedulingErrors } {\n const d = config ?? {};\n const c: ResolvedScheduling = {\n slotMinutes: d.slotMinutes ?? SCHEDULING_DEFAULTS.slotMinutes,\n days: d.days ?? SCHEDULING_DEFAULTS.days,\n startHour: d.startHour ?? SCHEDULING_DEFAULTS.startHour,\n endHour: d.endHour ?? SCHEDULING_DEFAULTS.endHour,\n timezone: d.timezone ?? SCHEDULING_DEFAULTS.timezone,\n minNoticeHours: d.minNoticeHours ?? SCHEDULING_DEFAULTS.minNoticeHours,\n windowDays: d.windowDays ?? SCHEDULING_DEFAULTS.windowDays,\n summaryTemplate: d.summaryTemplate ?? SCHEDULING_DEFAULTS.summaryTemplate,\n };\n const errors: SchedulingErrors = {};\n if (!(c.slotMinutes >= 15 && c.slotMinutes <= 240)) {\n errors.slotMinutes = \"Slot length must be between 15 and 240 minutes.\";\n }\n if (!(c.windowDays >= 1 && c.windowDays <= 62)) {\n errors.windowDays = \"Booking window must be between 1 and 62 days (the calendar caps look-ahead at 62).\";\n }\n if (!(c.minNoticeHours >= 0 && c.minNoticeHours <= 336)) {\n errors.minNoticeHours = \"Minimum notice must be between 0 and 336 hours.\";\n }\n if (!(c.startHour >= 0 && c.startHour < c.endHour && c.endHour <= 24)) {\n errors.hours = \"Hours must satisfy 0 ≤ start < end ≤ 24.\";\n }\n const days = [...c.days];\n if (!days.length) errors.days = \"Pick at least one day.\";\n else if (!days.every((n) => Number.isInteger(n) && n >= 0 && n <= 6)) {\n errors.days = \"Days must be weekday numbers, 0 (Sunday) through 6 (Saturday).\";\n }\n if (typeof c.timezone !== \"string\" || !isValidTimeZone(c.timezone)) {\n errors.timezone = `\"${String(c.timezone)}\" is not a valid IANA timezone (for example \"America/Los_Angeles\").`;\n }\n if (typeof c.summaryTemplate !== \"string\") errors.summaryTemplate = \"Calendar summary template must be text.\";\n return Object.keys(errors).length > 0 ? { ok: false, errors } : { ok: true, value: { ...c, days } };\n}\n\n/** Statuses a member may book/reschedule from (early pipeline only). */\n// Booking eligibility is answered by the configured pipeline — canBook(status,\n// pipeline) in ./pipeline — not a hardcoded status list, so a chapter that\n// customizes its stages gets one consistent answer.\n\n/** The availability window: `[now, now + windowDays]` in epoch ms. */\nexport function slotWindow(now: number, windowDays: number): { from: number; to: number } {\n return { from: now, to: now + windowDays * 86_400_000 };\n}\n\n/** The slot's end instant, always derived from its start (never client-supplied). */\nexport function endForSlot(startAt: number, slotMinutes: number): number {\n return startAt + slotMinutes * 60_000;\n}\n\n/** Double-book pre-check: the requested start must land exactly on a currently\n * bookable slot boundary. */\nexport function isSlotAvailable(slots: readonly { startAt: number }[], startAt: number): boolean {\n return slots.some((s) => s.startAt === startAt);\n}\n\n/** Render a meeting summary from its template (`{{firstName}}`/`{{lastName}}`). */\nexport function renderSummary(template: string, app: { firstName?: string | null; lastName?: string | null }): string {\n return template.replace(\"{{firstName}}\", app.firstName ?? \"\").replace(\"{{lastName}}\", app.lastName ?? \"\");\n}\n\n/** The prior scheduled meeting for an application, as far as booking cares. */\nexport interface ExistingMeeting {\n id: string;\n googleEventId?: string | null;\n meetUrl?: string | null;\n htmlLink?: string | null;\n}\n\n/** Decide reschedule-vs-create: reschedule iff there's an existing event to move,\n * so the Meet link + invite thread survive and no second event is minted. */\nexport function bookingDecision(existing: ExistingMeeting | null | undefined): { reschedule: boolean; eventId: string | null } {\n const eventId = existing?.googleEventId ?? null;\n return { reschedule: Boolean(eventId), eventId };\n}\n\n/** The create idempotency key — one intro event per application, forever, so a\n * retried create returns the same booking rather than a duplicate. */\nexport function introIdempotencyKey(applicationId: string): string {\n return `application:${applicationId}:intro`;\n}\n\n/** The canonical `meetings` row for a first booking. A `type` (not `interface`)\n * so it stays assignable to a db op's `attrs` (Record<string, unknown>). */\nexport type NewMeetingRow = {\n id: string;\n applicationId: string;\n groupId: string;\n startAt: number;\n endAt: number;\n timezone: string;\n status: \"scheduled\";\n googleEventId: string;\n meetUrl?: string;\n htmlLink?: string;\n drift: \"none\";\n createdAt: number;\n};\n\n/** Build the new `meetings` row after the calendar created the event. Optional\n * scalars are omitted (never null), per the odla-db porting rule. */\nexport function meetingCreateRow(i: {\n meetingId: string;\n applicationId: string;\n groupId: string;\n startAt: number;\n endAt: number;\n timezone: string;\n googleEventId: string;\n meetUrl?: string | null;\n htmlLink?: string | null;\n createdAt: number;\n}): NewMeetingRow {\n return {\n id: i.meetingId,\n applicationId: i.applicationId,\n groupId: i.groupId,\n startAt: i.startAt,\n endAt: i.endAt,\n timezone: i.timezone,\n status: \"scheduled\",\n googleEventId: i.googleEventId,\n ...(i.meetUrl ? { meetUrl: i.meetUrl } : {}),\n ...(i.htmlLink ? { htmlLink: i.htmlLink } : {}),\n drift: \"none\",\n createdAt: i.createdAt,\n };\n}\n\n/** The `meetings`-row patch for a reschedule (same row id, moved in place). */\nexport type MeetingReschedulePatch = {\n startAt: number;\n endAt: number;\n drift: \"none\";\n};\n\n/** Patch to move an existing meeting to a new window. */\nexport function meetingRescheduleUpdate(startAt: number, endAt: number): MeetingReschedulePatch {\n return { startAt, endAt, drift: \"none\" };\n}\n\n/** The `applications`-row patch after a booking. */\nexport type ApplicationBookingPatch = {\n meetingAt: number;\n meetingLink?: string;\n status?: \"call_scheduled\";\n};\n\n/** Project the booking onto the application row: cache the time, adopt the\n * calendar link if any, and advance the status to `call_scheduled` unless it is\n * already there (never backward). */\nexport function applicationBookingUpdate(\n currentStatus: string,\n startAt: number,\n htmlLink?: string | null,\n): ApplicationBookingPatch {\n return {\n meetingAt: startAt,\n ...(htmlLink ? { meetingLink: htmlLink } : {}),\n ...(currentStatus !== \"call_scheduled\" ? { status: \"call_scheduled\" as const } : {}),\n };\n}\n","/** Current wire version for parent-authored admission decisions. */\nexport const ADMISSION_GRANTS_SCHEMA_VERSION = 1 as const;\n/** Dedicated signed Parent → Chapter delivery endpoint. */\nexport const ADMISSION_GRANTS_PATH = \"/api/admission-grants\" as const;\n\n/** Whether an exact email can skip or must retain the Chapter interview. */\nexport type AdmissionDecision = \"waive_interview\" | \"require_interview\";\n\n/** One bounded admission decision. Email is PII and never enters public config. */\nexport interface AdmissionGrantInput {\n id: string;\n email: string;\n decision: AdmissionDecision;\n note?: string;\n expiresAt?: number;\n}\n\n/** Complete desired Parent state for one Chapter and environment. */\nexport interface AdmissionGrantDocument {\n schemaVersion: typeof ADMISSION_GRANTS_SCHEMA_VERSION;\n revision: number;\n generatedAt: number;\n source: { appId: string; actor: string };\n target: { chapterId: string; environment: string };\n grants: readonly AdmissionGrantInput[];\n}\n\n/** Canonical desired-state document paired with its integrity digest. */\nexport interface AdmissionGrantEnvelope {\n digest: string;\n document: AdmissionGrantDocument;\n}\n\n/** Chapter acknowledgement for an accepted or idempotently replayed revision. */\nexport interface AdmissionGrantReceipt {\n ok: true;\n target: { chapterId: string; environment: string };\n revision: number;\n digest: string;\n status: \"accepted\" | \"replayed\";\n acknowledgedAt: number;\n}\n\n/** Stable machine-readable rejection reasons returned by a Chapter receiver. */\nexport type AdmissionGrantRejection =\n | \"invalid_document\"\n | \"invalid_digest\"\n | \"wrong_source\"\n | \"wrong_target\"\n | \"wrong_environment\"\n | \"stale_revision\"\n | \"conflicting_revision\"\n | \"materialization_failed\";\n","const encoder = new TextEncoder();\n\nfunction canonicalValue(value: unknown): string {\n if (value === null || typeof value === \"boolean\" || typeof value === \"number\" || typeof value === \"string\") {\n return JSON.stringify(value);\n }\n if (Array.isArray(value)) return `[${value.map(canonicalValue).join(\",\")}]`;\n if (typeof value !== \"object\") throw new TypeError(\"signup control contains an unsupported value\");\n const record = value as Record<string, unknown>;\n const entries = Object.keys(record).sort().flatMap((key) => {\n const item = record[key];\n return item === undefined ? [] : [`${JSON.stringify(key)}:${canonicalValue(item)}`];\n });\n return `{${entries.join(\",\")}}`;\n}\n\n/** Serialize JSON-like signup state with recursively sorted object keys. */\nexport function canonicalSignupControl(value: unknown): string {\n return canonicalValue(value);\n}\n\n/** Compute the protocol's canonical SHA-256 digest for desired signup state. */\nexport async function signupControlDigest(document: unknown): Promise<string> {\n const digest = await crypto.subtle.digest(\"SHA-256\", encoder.encode(canonicalSignupControl(document)));\n return `sha256:${Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\")}`;\n}\n\n/** Pair one desired-state document with its canonical digest for delivery. */\nexport async function createSignupControlEnvelope(document: import(\"./signup-control-contract\").SignupControlDocument) {\n return { document, digest: await signupControlDigest(document) };\n}\n","import type {\n AdmissionDecision,\n AdmissionGrantDocument,\n AdmissionGrantEnvelope,\n AdmissionGrantInput,\n} from \"./admission-grants-contract\";\nimport { ADMISSION_GRANTS_SCHEMA_VERSION } from \"./admission-grants-contract\";\nimport type { ChapterDb, DbOp } from \"./types\";\nimport { signupControlDigest } from \"./signup-control-canonical\";\nimport { normalizeChapterEmail } from \"./email-identity\";\n\nconst ID = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,127}$/;\nconst MAX_GRANTS = 2_000;\nconst MAX_NOTE = 2_000;\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nconst isAdmissionEmail = (value: string): boolean => EMAIL_RE.test(value);\n\n/** Exact email natural key: trim and lowercase, with no provider alias rules. */\nexport function normalizeAdmissionEmail(email: string): string {\n return normalizeChapterEmail(email);\n}\n\n/** Validated normalized admission document or all contract errors. */\nexport type AdmissionGrantValidation =\n | { ok: true; value: AdmissionGrantDocument }\n | { ok: false; errors: readonly string[] };\n\n/** Validate and normalize a complete Parent admission document. */\nexport function validateAdmissionGrantDocument(input: unknown): AdmissionGrantValidation {\n const errors: string[] = [];\n const root = input && typeof input === \"object\" ? input as Record<string, unknown> : {};\n if (root.schemaVersion !== ADMISSION_GRANTS_SCHEMA_VERSION) errors.push(\"document.schemaVersion must be 1\");\n const revision = Number(root.revision);\n const generatedAt = Number(root.generatedAt);\n if (!Number.isSafeInteger(revision) || revision < 1) errors.push(\"document.revision must be a positive integer\");\n if (!Number.isFinite(generatedAt) || generatedAt <= 0) errors.push(\"document.generatedAt must be epoch milliseconds\");\n const source = root.source && typeof root.source === \"object\" ? root.source as Record<string, unknown> : {};\n const target = root.target && typeof root.target === \"object\" ? root.target as Record<string, unknown> : {};\n const sourceId = typeof source.appId === \"string\" ? source.appId : \"\";\n const sourceActor = typeof source.actor === \"string\" ? source.actor.trim() : \"\";\n const chapterId = typeof target.chapterId === \"string\" ? target.chapterId : \"\";\n const environment = typeof target.environment === \"string\" ? target.environment : \"\";\n if (!ID.test(sourceId)) errors.push(\"document.source.appId must be an identifier\");\n if (!sourceActor || sourceActor.length > 256) errors.push(\"document.source.actor must be 1-256 characters\");\n if (!ID.test(chapterId)) errors.push(\"document.target.chapterId must be an identifier\");\n if (!ID.test(environment)) errors.push(\"document.target.environment must be an identifier\");\n if (!Array.isArray(root.grants)) errors.push(\"document.grants must be an array\");\n const rawGrants = Array.isArray(root.grants) ? root.grants : [];\n if (rawGrants.length > MAX_GRANTS) errors.push(`document.grants supports at most ${MAX_GRANTS} entries`);\n const grants: AdmissionGrantInput[] = [];\n const seenIds = new Set<string>();\n const seenEmails = new Set<string>();\n for (const [index, raw] of rawGrants.slice(0, MAX_GRANTS).entries()) {\n const grant = raw && typeof raw === \"object\" ? raw as Record<string, unknown> : {};\n const id = typeof grant.id === \"string\" ? grant.id : \"\";\n const email = typeof grant.email === \"string\" ? grant.email.trim() : \"\";\n const normalized = normalizeAdmissionEmail(email);\n const decision = grant.decision;\n const note = typeof grant.note === \"string\" ? grant.note.trim() : undefined;\n const expiresAt = grant.expiresAt === undefined ? undefined : Number(grant.expiresAt);\n if (!ID.test(id)) errors.push(`document.grants[${index}].id must be an identifier`);\n if (seenIds.has(id)) errors.push(`document.grants repeats id \"${id}\"`);\n if (!isAdmissionEmail(normalized)) errors.push(`document.grants[${index}].email must be valid`);\n if (seenEmails.has(normalized)) errors.push(`document.grants repeats email \"${normalized}\"`);\n if (decision !== \"waive_interview\" && decision !== \"require_interview\") {\n errors.push(`document.grants[${index}].decision is invalid`);\n }\n if (note && note.length > MAX_NOTE) errors.push(`document.grants[${index}].note is too long`);\n if (expiresAt !== undefined && (!Number.isFinite(expiresAt) || expiresAt <= 0)) {\n errors.push(`document.grants[${index}].expiresAt must be epoch milliseconds`);\n }\n seenIds.add(id);\n seenEmails.add(normalized);\n grants.push({\n id,\n email,\n decision: decision as AdmissionDecision,\n ...(note ? { note } : {}),\n ...(expiresAt !== undefined ? { expiresAt } : {}),\n });\n }\n if (errors.length) return { ok: false, errors };\n return {\n ok: true,\n value: {\n schemaVersion: ADMISSION_GRANTS_SCHEMA_VERSION,\n revision,\n generatedAt,\n source: { appId: sourceId, actor: sourceActor },\n target: { chapterId, environment },\n grants,\n },\n };\n}\n\n/** Pair a validated desired-state document with its canonical digest. */\nexport async function createAdmissionGrantEnvelope(document: AdmissionGrantDocument): Promise<AdmissionGrantEnvelope> {\n const checked = validateAdmissionGrantDocument(document);\n if (!checked.ok) throw new TypeError(`Invalid admission grant document: ${checked.errors.join(\"; \")}`);\n return { document: checked.value, digest: await signupControlDigest(checked.value) };\n}\n\n/** Materialized local or Parent admission decision stored by a Chapter. */\nexport interface AdmissionGrantRow {\n id: string;\n sourceGrantId: string;\n sourceScope: \"local\" | \"parent\";\n sourceId: string;\n targetId: string;\n email: string;\n emailNormalized: string;\n decision: AdmissionDecision;\n active: boolean;\n createdAt: number;\n note?: string;\n expiresAt?: number;\n revokedAt?: number;\n consumedAt?: number;\n consumedApplicationId?: string;\n}\n\nconst rows = (value: unknown): Array<Record<string, unknown>> => Array.isArray(value) ? value : [];\n\nfunction asGrant(row: Record<string, unknown>): AdmissionGrantRow | null {\n if (typeof row.id !== \"string\" || typeof row.emailNormalized !== \"string\") return null;\n if (row.sourceScope !== \"local\" && row.sourceScope !== \"parent\") return null;\n if (row.decision !== \"waive_interview\" && row.decision !== \"require_interview\") return null;\n return row as unknown as AdmissionGrantRow;\n}\n\n/** Resolve the effective current decision. Local rows always outrank Parent rows. */\nexport async function findAdmissionGrant(\n db: ChapterDb,\n targetId: string,\n email: string,\n now: number,\n): Promise<AdmissionGrantRow | null> {\n const emailNormalized = normalizeAdmissionEmail(email);\n if (!isAdmissionEmail(emailNormalized)) return null;\n const result = await db.query({ admissionGrants: { $: { where: { emailNormalized }, limit: 100 } } });\n const active = rows(result.admissionGrants)\n .map(asGrant)\n .filter((grant): grant is AdmissionGrantRow => Boolean(\n grant && grant.targetId === targetId && grant.active === true && !grant.revokedAt &&\n (!grant.expiresAt || grant.expiresAt > now) && !grant.consumedApplicationId,\n ))\n .sort((a, b) => {\n const scope = Number(b.sourceScope === \"local\") - Number(a.sourceScope === \"local\");\n return scope || b.createdAt - a.createdAt;\n });\n return active[0] ?? null;\n}\n\n/** Stored receipt for one signed Parent admission revision. */\nexport interface AdmissionGrantRevisionRow {\n id: string;\n sourceId: string;\n targetId: string;\n environment: string;\n revision: number;\n digest: string;\n active: boolean;\n receivedAt: number;\n}\n\nasync function hasAdmissionRevision(\n db: ChapterDb,\n sourceId: string,\n targetId: string,\n environment: string,\n): Promise<boolean> {\n const where = { sourceId, targetId, environment };\n if (db.aggregate) {\n return Number((await db.aggregate(\"admissionGrantRevisions\", { count: true }, { where })).count ?? 0) > 0;\n }\n const found = await db.query({ admissionGrantRevisions: {} });\n return rows(found.admissionGrantRevisions).some((row) =>\n row.sourceId === sourceId && row.targetId === targetId && row.environment === environment);\n}\n\n/** Read the newest received revision without issuing an ordered query over empty history. */\nexport async function loadLatestAdmissionRevision(\n db: ChapterDb,\n sourceId: string,\n targetId: string,\n environment: string,\n): Promise<AdmissionGrantRevisionRow | null> {\n if (!await hasAdmissionRevision(db, sourceId, targetId, environment)) return null;\n const result = await db.query({ admissionGrantRevisions: { $: {\n where: { sourceId, targetId, environment }, order: { revision: \"desc\" }, limit: 1,\n } } });\n const row = rows(result.admissionGrantRevisions)\n .sort((a, b) => Number(b.revision ?? 0) - Number(a.revision ?? 0))[0];\n return row ? row as unknown as AdmissionGrantRevisionRow : null;\n}\n\n/** Replace only Parent-authored rows; local Chapter decisions remain untouched. */\nexport async function materializeAdmissionGrants(\n db: ChapterDb,\n envelope: AdmissionGrantEnvelope,\n previous: AdmissionGrantRevisionRow | null,\n receivedAt: number,\n): Promise<void> {\n const { document, digest } = envelope;\n const current = rows((await db.query({ admissionGrants: { $: {\n where: { sourceScope: \"parent\", sourceId: document.source.appId, targetId: document.target.chapterId },\n limit: MAX_GRANTS,\n } } })).admissionGrants);\n const incomingIds = new Set(document.grants.map((grant) => `admission:parent:${document.source.appId}:${grant.id}`));\n const ops: DbOp[] = [];\n for (const row of current) {\n const id = String(row.id ?? \"\");\n if (id && !incomingIds.has(id)) ops.push({ t: \"update\", ns: \"admissionGrants\", id, attrs: {\n active: false, revokedAt: receivedAt, revokedBy: document.source.actor,\n updatedAt: receivedAt, updatedBy: document.source.actor,\n } });\n }\n for (const grant of document.grants) {\n const id = `admission:parent:${document.source.appId}:${grant.id}`;\n const existing = current.find((row) => row.id === id);\n ops.push({ t: \"update\", ns: \"admissionGrants\", id, attrs: {\n id,\n sourceGrantId: grant.id,\n sourceScope: \"parent\",\n sourceId: document.source.appId,\n targetId: document.target.chapterId,\n email: grant.email,\n emailNormalized: normalizeAdmissionEmail(grant.email),\n decision: grant.decision,\n ...(grant.note ? { note: grant.note } : {}),\n ...(grant.expiresAt ? { expiresAt: grant.expiresAt } : {}),\n active: true,\n sourceRevision: document.revision,\n createdAt: Number(existing?.createdAt ?? receivedAt),\n createdBy: String(existing?.createdBy ?? document.source.actor),\n updatedAt: receivedAt,\n updatedBy: document.source.actor,\n } });\n const retract = [\n ...(!grant.note && existing?.note !== undefined ? [\"note\"] : []),\n ...(grant.expiresAt === undefined && existing?.expiresAt !== undefined ? [\"expiresAt\"] : []),\n ];\n if (retract.length) ops.push({ t: \"retract\", ns: \"admissionGrants\", id, attrs: retract });\n }\n if (previous?.active) ops.push({ t: \"update\", ns: \"admissionGrantRevisions\", id: previous.id, attrs: { active: false } });\n const revisionId = `admission-revision:${document.source.appId}:${document.target.environment}:${document.revision}`;\n ops.push({ t: \"update\", ns: \"admissionGrantRevisions\", id: revisionId, attrs: {\n id: revisionId,\n sourceId: document.source.appId,\n targetId: document.target.chapterId,\n environment: document.target.environment,\n revision: document.revision,\n digest,\n active: true,\n receivedAt,\n } });\n await db.transact(ops, { mutationId: `admission-grants:${document.source.appId}:${document.target.environment}:${document.revision}:${digest}` });\n}\n","import type { Crm, FieldConditions, FieldDef, FieldType } from \"@odla-ai/crm\";\nimport type { Chapter, ResolvedApplication, ResolvedLeaderFormation } from \"./types\";\n\n/** Current public schema version for Chapter flow-field contracts. */\nexport const CHAPTER_FLOW_FIELDS_SCHEMA_VERSION = 1 as const;\n\n/** Configurable Chapter intake journeys that publish field contracts. */\nexport type ChapterFieldFlow = \"join\" | \"formation\";\n\n/** Email comparison policy advertised by an email field. */\nexport type ChapterEmailIdentity = \"literal\";\n\n/**\n * One effective field in a Chapter intake journey.\n *\n * IDs, value types, and options come from the follower-declared schema. A hub\n * or CMS may select, order, and configure only those declared fields; it cannot\n * use this presentation document to add storage or widen follower authority.\n */\nexport interface ChapterFlowField {\n id: string;\n label: string;\n type: FieldType;\n required: boolean;\n order: number;\n maxLength?: number;\n options?: readonly string[];\n conditions?: FieldConditions;\n /** Present only for an email identity field. Aliases such as `+tag` remain significant. */\n emailIdentity?: ChapterEmailIdentity;\n}\n\n/** Ordered, versioned effective field state for one Chapter journey. */\nexport interface ChapterFlowFieldContract {\n schemaVersion: typeof CHAPTER_FLOW_FIELDS_SCHEMA_VERSION;\n flow: ChapterFieldFlow;\n fields: readonly ChapterFlowField[];\n}\n\nconst APPLICATION_LABELS: Readonly<Record<string, string>> = {\n firstName: \"First name\",\n lastName: \"Last name\",\n email: \"Email\",\n referral: \"Referral source\",\n referralName: \"Referral name\",\n whoYouAre: \"Who you are\",\n linkedin: \"LinkedIn\",\n message: \"Intro message\",\n phone: \"Phone\",\n state: \"State\",\n};\n\nfunction humanize(id: string): string {\n const text = id.replace(/([a-z0-9])([A-Z])/g, \"$1 $2\").replace(/[_-]+/g, \" \").trim();\n return text ? `${text[0]!.toUpperCase()}${text.slice(1)}` : id;\n}\n\nfunction applicationDefs(chapter: Chapter): Record<string, FieldDef> {\n try {\n return chapter.crm.type(\"person\").fields;\n } catch {\n return {};\n }\n}\n\nfunction applicationType(id: string, def: FieldDef | undefined): FieldType {\n // Application rows accept configurable strings. Preserve the richer\n // string-like CRM hints without claiming that a numeric/date/json CRM field\n // changes the application storage contract.\n if (def && [\"string\", \"email\", \"url\", \"enum\"].includes(def.type)) return def.type;\n return id === \"email\" ? \"email\" : id === \"linkedin\" ? \"url\" : \"string\";\n}\n\n/** Resolve the exact ordered fields accepted by the membership application flow. */\nexport function applicationFlowFields(\n chapter: Chapter,\n application: ResolvedApplication = chapter.application,\n): ChapterFlowField[] {\n const defs = applicationDefs(chapter);\n return [...application.required, ...application.optional].map((id, order) => {\n const def = defs[id];\n const conditions = application.conditions[id];\n const type = applicationType(id, def);\n return {\n id,\n label: def?.label ?? APPLICATION_LABELS[id] ?? humanize(id),\n type,\n required: application.required.includes(id),\n order,\n maxLength: application.maxLen[id] ?? application.defaultMaxLen,\n ...(type === \"enum\" && def?.options ? { options: [...def.options] } : {}),\n ...(conditions ? { conditions: { ...conditions } } : {}),\n ...(type === \"email\" ? { emailIdentity: \"literal\" as const } : {}),\n };\n });\n}\n\n/** Common resolver retained separately so the legacy formationFields helper cannot drift. */\nexport function resolveFormationFlowFields(\n crm: Crm,\n formation: ResolvedLeaderFormation,\n): ChapterFlowField[] {\n if (!formation.enabled) return [];\n const def = crm.type(formation.type);\n return [...formation.required, ...formation.optional].map((id, order) => {\n const field = def.fields[id]!;\n return {\n id,\n label: field.label ?? humanize(id),\n type: field.type,\n required: formation.required.includes(id),\n order,\n maxLength: formation.maxLen[id] ?? formation.defaultMaxLen,\n ...(field.options ? { options: [...field.options] } : {}),\n ...(id === def.emailField || field.type === \"email\" ? { emailIdentity: \"literal\" as const } : {}),\n };\n });\n}\n\n/** Resolve the exact ordered fields accepted by the chapter-formation flow. */\nexport function formationFlowFields(\n chapter: Chapter,\n formation: ResolvedLeaderFormation = chapter.formation,\n): ChapterFlowField[] {\n return resolveFormationFlowFields(chapter.crm, formation);\n}\n\n/**\n * Build the public field contract consumed by follower forms and CMS previews.\n * The optional application is the already-authorized effective selection from\n * signup control; it never expands the follower's declared application schema.\n */\nexport function chapterFlowFieldContract(\n chapter: Chapter,\n flow: ChapterFieldFlow,\n application: ResolvedApplication = chapter.application,\n): ChapterFlowFieldContract {\n return {\n schemaVersion: CHAPTER_FLOW_FIELDS_SCHEMA_VERSION,\n flow,\n fields: flow === \"join\"\n ? applicationFlowFields(chapter, application)\n : formationFlowFields(chapter),\n };\n}\n","/** Current nested gift-catalog version inside signup-control. */\nexport const GIFT_OFFER_CATALOG_VERSION = 1 as const;\n/** Maximum signed gift SKUs accepted in one catalog revision. */\nexport const MAX_GIFT_OFFERS = 20;\n\n/** Membership tier or standalone entitlement fulfilled by redemption. */\nexport type GiftOfferTarget =\n | { type: \"tier\"; tierId: string }\n | { type: \"entitlement\"; entitlementKey: string };\n\n/** Server-authored gift SKU; provider identifiers never reach public config. */\nexport interface GiftOffer {\n id: string;\n target: GiftOfferTarget;\n billingMode: \"one_time\" | \"subscription\";\n stripePriceId: string;\n priceCents: number;\n currency: string;\n redemptionLifetimeHours: number;\n activeFrom?: number;\n activeUntil?: number;\n title: string;\n description: string;\n ctaLabel: string;\n}\n\n/** Versioned bounded collection delegated through signed signup control. */\nexport interface GiftOfferCatalog {\n schemaVersion: typeof GIFT_OFFER_CATALOG_VERSION;\n offers: readonly GiftOffer[];\n}\n\n/** Provider-free gift offer shape rendered by Chapter and exact CMS previews. */\nexport type PublicGiftOffer = Omit<GiftOffer, \"stripePriceId\" | \"target\">;\n\n/** Result of validating and normalizing an untrusted gift catalog. */\nexport type GiftOfferValidation =\n | { ok: true; value: GiftOfferCatalog }\n | { ok: false; errors: readonly string[] };\n\nconst ID = /^[a-z][a-z0-9-]{1,79}$/;\nconst PRICE = /^price_[A-Za-z0-9]{12,}$/;\nconst CURRENCY = /^[a-z]{3}$/;\nconst record = (value: unknown): Record<string, unknown> | null =>\n value && typeof value === \"object\" && !Array.isArray(value) ? value as Record<string, unknown> : null;\nconst text = (value: unknown, path: string, errors: string[], max: number): string => {\n if (typeof value !== \"string\" || !value.trim()) { errors.push(`${path} is required`); return \"\"; }\n if (value.trim().length > max) errors.push(`${path} must be at most ${max} characters`);\n return value.trim();\n};\n\n/** Validate and normalize gift offers against the same document's tier ids. */\nexport function validateGiftOfferCatalog(input: unknown, tierIds: ReadonlySet<string>): GiftOfferValidation {\n const errors: string[] = [];\n const root = record(input);\n if (!root) return { ok: false, errors: [\"document.giftOffers must be an object\"] };\n for (const key of Object.keys(root)) if (key !== \"schemaVersion\" && key !== \"offers\") errors.push(`document.giftOffers.${key} is not supported`);\n if (root.schemaVersion !== GIFT_OFFER_CATALOG_VERSION) errors.push(\"document.giftOffers.schemaVersion must be 1\");\n if (!Array.isArray(root.offers)) errors.push(\"document.giftOffers.offers must be an array\");\n const rawOffers = Array.isArray(root.offers) ? root.offers : [];\n if (rawOffers.length > MAX_GIFT_OFFERS) errors.push(`document.giftOffers.offers supports at most ${MAX_GIFT_OFFERS} entries`);\n const ids = new Set<string>();\n const offers: GiftOffer[] = [];\n for (const [index, raw] of rawOffers.slice(0, MAX_GIFT_OFFERS).entries()) {\n const path = `document.giftOffers.offers[${index}]`;\n const item = record(raw);\n if (!item) { errors.push(`${path} must be an object`); continue; }\n const allowed = new Set([\"id\", \"target\", \"billingMode\", \"stripePriceId\", \"priceCents\", \"currency\", \"redemptionLifetimeHours\", \"activeFrom\", \"activeUntil\", \"title\", \"description\", \"ctaLabel\"]);\n for (const key of Object.keys(item)) if (!allowed.has(key)) errors.push(`${path}.${key} is not supported`);\n const id = text(item.id, `${path}.id`, errors, 80);\n if (id && !ID.test(id)) errors.push(`${path}.id must be a lowercase kebab-case id`);\n if (ids.has(id)) errors.push(`${path}.id duplicates \"${id}\"`);\n ids.add(id);\n const targetRaw = record(item.target);\n let target: GiftOfferTarget = { type: \"entitlement\", entitlementKey: \"invalid\" };\n if (targetRaw?.type === \"tier\") {\n const tierId = text(targetRaw.tierId, `${path}.target.tierId`, errors, 80);\n if (!tierIds.has(tierId)) errors.push(`${path}.target.tierId must reference a declared tier`);\n target = { type: \"tier\", tierId };\n } else if (targetRaw?.type === \"entitlement\") {\n const entitlementKey = text(targetRaw.entitlementKey, `${path}.target.entitlementKey`, errors, 80);\n if (entitlementKey && !ID.test(entitlementKey)) errors.push(`${path}.target.entitlementKey must be a lowercase kebab-case id`);\n target = { type: \"entitlement\", entitlementKey };\n } else errors.push(`${path}.target.type must be tier or entitlement`);\n if (item.billingMode !== \"one_time\" && item.billingMode !== \"subscription\") errors.push(`${path}.billingMode must be one_time or subscription`);\n const stripePriceId = text(item.stripePriceId, `${path}.stripePriceId`, errors, 128);\n if (stripePriceId && !PRICE.test(stripePriceId)) errors.push(`${path}.stripePriceId must be a real Stripe Price id`);\n if (!Number.isSafeInteger(item.priceCents) || Number(item.priceCents) < 1 || Number(item.priceCents) > 100_000_000) errors.push(`${path}.priceCents must be an integer from 1 to 100,000,000`);\n const currency = typeof item.currency === \"string\" ? item.currency.trim().toLowerCase() : \"\";\n if (!CURRENCY.test(currency)) errors.push(`${path}.currency must be a lowercase ISO currency code`);\n const lifetime = Number(item.redemptionLifetimeHours);\n if (!Number.isSafeInteger(lifetime) || lifetime < 1 || lifetime > 8_760) errors.push(`${path}.redemptionLifetimeHours must be an integer from 1 to 8760`);\n const activeFrom = item.activeFrom === undefined ? undefined : Number(item.activeFrom);\n const activeUntil = item.activeUntil === undefined ? undefined : Number(item.activeUntil);\n if (activeFrom !== undefined && (!Number.isSafeInteger(activeFrom) || activeFrom < 1)) errors.push(`${path}.activeFrom must be epoch milliseconds`);\n if (activeUntil !== undefined && (!Number.isSafeInteger(activeUntil) || activeUntil < 1)) errors.push(`${path}.activeUntil must be epoch milliseconds`);\n if (activeFrom !== undefined && activeUntil !== undefined && activeUntil <= activeFrom) errors.push(`${path}.activeUntil must follow activeFrom`);\n offers.push({\n id, target, billingMode: item.billingMode as GiftOffer[\"billingMode\"], stripePriceId,\n priceCents: Number(item.priceCents), currency, redemptionLifetimeHours: lifetime,\n ...(activeFrom !== undefined ? { activeFrom } : {}), ...(activeUntil !== undefined ? { activeUntil } : {}),\n title: text(item.title, `${path}.title`, errors, 160), description: text(item.description, `${path}.description`, errors, 2_000),\n ctaLabel: text(item.ctaLabel, `${path}.ctaLabel`, errors, 120),\n });\n }\n return errors.length ? { ok: false, errors } : { ok: true, value: { schemaVersion: 1, offers } };\n}\n\n/** Whether an offer is active at an exact server time. */\nexport const giftOfferActive = (offer: GiftOffer, now: number): boolean =>\n (!offer.activeFrom || offer.activeFrom <= now) && (!offer.activeUntil || offer.activeUntil > now);\n\n/** Public provider-free active catalog projection. */\nexport function publicGiftOffers(catalog: GiftOfferCatalog | undefined, now: number): PublicGiftOffer[] {\n return (catalog?.offers ?? []).filter((offer) => giftOfferActive(offer, now)).map(({ stripePriceId: _stripe, target: _target, ...offer }) => offer);\n}\n\n/** Resolve one currently active server-authoritative offer. */\nexport function findGiftOffer(catalog: GiftOfferCatalog | undefined, offerId: string, now: number): GiftOffer | null {\n return catalog?.offers.find((offer) => offer.id === offerId && giftOfferActive(offer, now)) ?? null;\n}\n","// The odla->Clerk write half: server-side Clerk role read/list/write, the gap\n// beside clerk.ts's create/invite/heal. Roles live in `public_metadata.role`; an\n// absent role means the lowest rung (\"provisional\") — chapter never writes it at\n// create. Account profile signals live in backend-only `private_metadata`; the\n// role write is a MERGE-PATCH of only `{ role }`, so it cannot clobber them.\n// Chapter calls the Clerk Backend API over fetch with the vault\n// `clerk_secret_key`.\n\nconst CLERK_API = \"https://api.clerk.com\";\nconst DEFAULT_ROLE = \"provisional\";\nconst PAGE = 100;\n\n/** A Clerk user as chapter's role layer sees it. `role` defaults to the lowest\n * rung when `public_metadata` carries none. Raw public/private metadata is\n * returned only from this backend helper; `profile` and `applicationId` are the\n * normalized Chapter-owned private signals. */\nexport interface ClerkUserRecord {\n id: string;\n email?: string;\n role: string;\n publicMetadata: Record<string, unknown>;\n privateMetadata: Record<string, unknown>;\n profile: Record<string, unknown>;\n applicationId?: string;\n}\n\n// The Clerk Backend API user object — only the fields chapter reads.\ninterface ClerkApiUser {\n id?: unknown;\n email_addresses?: Array<{ email_address?: unknown }>;\n public_metadata?: Record<string, unknown>;\n private_metadata?: Record<string, unknown>;\n}\n\nfunction toRecord(u: ClerkApiUser): ClerkUserRecord | null {\n if (typeof u.id !== \"string\") return null;\n const pm = (u.public_metadata ?? {}) as Record<string, unknown>;\n const privateMetadata = (u.private_metadata ?? {}) as Record<string, unknown>;\n const rawProfile = privateMetadata.profile;\n const profile = rawProfile && typeof rawProfile === \"object\" && !Array.isArray(rawProfile)\n ? rawProfile as Record<string, unknown>\n : {};\n const applicationId = typeof privateMetadata.applicationId === \"string\"\n ? privateMetadata.applicationId\n : undefined;\n const role = typeof pm.role === \"string\" && pm.role ? pm.role : DEFAULT_ROLE;\n const email = u.email_addresses?.[0]?.email_address;\n return {\n id: u.id,\n email: typeof email === \"string\" ? email : undefined,\n role,\n publicMetadata: pm,\n privateMetadata,\n profile,\n ...(applicationId ? { applicationId } : {}),\n };\n}\n\nasync function clerkGet(path: string, secretKey: string, fetchImpl: typeof fetch): Promise<unknown> {\n const res = await fetchImpl(`${CLERK_API}${path}`, { headers: { authorization: `Bearer ${secretKey}` } });\n if (!res.ok) throw new Error(`clerk GET ${path} → ${res.status}`);\n return res.json();\n}\n\n/** Look a Clerk user up by email. `null` when no such user — or when the lookup\n * fails (a role gate treats an unresolvable user as absent, matching the site's\n * own fallback). Role defaults to provisional when unset. */\nexport async function clerkGetUserByEmail(secretKey: string, email: string, fetchImpl: typeof fetch = fetch): Promise<ClerkUserRecord | null> {\n const data = await clerkGet(`/v1/users?email_address=${encodeURIComponent(email)}&limit=1`, secretKey, fetchImpl).catch(() => null);\n const user = Array.isArray(data) ? (data[0] as ClerkApiUser | undefined) : undefined;\n return user ? toRecord(user) : null;\n}\n\n/** Fetch a Clerk user by id, for role-change gating. `null` when missing or on a\n * failed lookup. Role defaults to provisional when unset. */\nexport async function clerkGetUser(secretKey: string, id: string, fetchImpl: typeof fetch = fetch): Promise<ClerkUserRecord | null> {\n const data = await clerkGet(`/v1/users/${encodeURIComponent(id)}`, secretKey, fetchImpl).catch(() => null);\n return data ? toRecord(data as ClerkApiUser) : null;\n}\n\n/** List ALL Clerk users with their roles, auto-paginating. A membership community\n * outgrows one page, and a fixed `limit=100` would silently drop members from the\n * admin roster with no error — so this pages (offset in steps of {@link PAGE})\n * until a short page. A page fetch that fails THROWS rather than returning a\n * partial list, so the caller never mistakes a truncated roster for the whole. */\nexport async function clerkListUsers(secretKey: string, fetchImpl: typeof fetch = fetch): Promise<ClerkUserRecord[]> {\n const out: ClerkUserRecord[] = [];\n for (let offset = 0; ; offset += PAGE) {\n const data = await clerkGet(`/v1/users?limit=${PAGE}&offset=${offset}`, secretKey, fetchImpl);\n const page = Array.isArray(data) ? (data as ClerkApiUser[]) : [];\n for (const u of page) {\n const record = toRecord(u);\n if (record) out.push(record);\n }\n if (page.length < PAGE) break;\n }\n return out;\n}\n\n/** Write a user's role: a MERGE-PATCH of only `{ role }` on `public_metadata`.\n * The backend-only profile lives in `private_metadata`, so the two signals\n * cannot overwrite each other. Returns whether the role write stuck. */\nexport async function clerkSetRole(secretKey: string, id: string, role: string, fetchImpl: typeof fetch = fetch): Promise<boolean> {\n const res = await fetchImpl(`${CLERK_API}/v1/users/${encodeURIComponent(id)}/metadata`, {\n method: \"PATCH\",\n headers: { authorization: `Bearer ${secretKey}`, \"content-type\": \"application/json\" },\n body: JSON.stringify({ public_metadata: { role } }),\n });\n return res.ok;\n}\n","// The OPERATIONAL slice of the one-way person projection: applications + $users\n// -> crm_record, mirroring pipeline stage, a billing snapshot, and the Clerk\n// identity link. `network.ts` projects identity/contact on submit; this adds the\n// operational state the admin surface and the hub read from, so the pipeline\n// stays authoritative in `applications.status` while the CRM carries one\n// relationship surface over the person. Fired AFTER the authoritative write and\n// wrapped in `.catch` at every call site: a CRM hiccup never 5xxs a lifecycle op.\n//\n// Idempotent by construction — every sync resolves the person by lowercased\n// primary email first, so re-running (including the backfill route) updates in\n// place. Generalized from the reference site: the field set is the site's\n// configured `crmFields`, not a hardcoded list.\nimport { createRecord, updateRecord, setStage, linkIdentity } from \"@odla-ai/crm\";\nimport { sharedPersonInput } from \"./network\";\nimport type { ProjectionDeps } from \"./network\";\nimport type { Chapter, ChapterDb } from \"./types\";\n\nconst str = (v: unknown): string => (typeof v === \"string\" ? v : v == null ? \"\" : String(v));\n\n/** Build the projection deps from a worker request's db + context.\n *\n * Shared so every route that writes `applications.status` mirrors it the same\n * way. Status is written from four places (admin approve, admin PATCH, the\n * Stripe webhook, and booking) and the admin dashboard reads its pipeline from\n * `crm_record.stage`, so a route that skips the mirror silently reports the\n * wrong funnel. */\nexport const crmDeps = (\n db: ChapterDb,\n ctx: { chapter: Chapter },\n): ProjectionDeps & { chapter: Chapter } => ({\n crm: ctx.chapter.crm,\n db,\n now: () => Date.now(),\n newId: () => crypto.randomUUID(),\n chapter: ctx.chapter,\n});\n\n/** The crm `person` input for one application row: the built-in identity/contact\n * fields plus each configured `crmFields` value present on the row. */\nexport function personInputFromApp(chapter: Chapter, app: Record<string, unknown>): Record<string, unknown> {\n const input = sharedPersonInput({\n email: str(app.email),\n firstName: str(app.firstName) || undefined,\n lastName: str(app.lastName) || undefined,\n phone: str(app.phone) || undefined,\n linkedin: str(app.linkedin) || undefined,\n hubRecordId: str(app.id),\n });\n for (const f of chapter.application.crmFields) {\n if (app[f] !== undefined) input[f] = app[f];\n }\n if (app.id !== undefined) input.applicationId = str(app.id);\n return input;\n}\n\n// Promoted billing-facet columns derived from the application's Stripe fields +\n// status. Written directly (not through createRecord/updateRecord, which never\n// touch promoted columns), so they never clobber the person input.\nfunction billingColumns(app: Record<string, unknown>): Record<string, unknown> {\n const status = str(app.status);\n const paid = Boolean(app.stripeSubscriptionId) && status !== \"refunded\";\n const billingStatus = status === \"refunded\" ? \"refunded\" : app.canceled === true ? \"canceled\" : paid ? \"active\" : \"none\";\n const cols: Record<string, unknown> = { billingStatus };\n if (app.stripeCustomerId) cols.stripeCustomerId = str(app.stripeCustomerId);\n if (app.stripeSubscriptionId) cols.subscriptionId = str(app.stripeSubscriptionId);\n if (typeof app.renewalAt === \"number\") cols.renewalAt = app.renewalAt;\n return cols;\n}\n\n/** Upsert the person record for one application (or a synthetic `{ email,\n * firstName }` account row) and mirror its stage, billing snapshot, and Clerk\n * identity. `stage` is the `applications.status` to mirror — omit for\n * account-only rows not in the pipeline. Throws on failure (the backfill route\n * counts; the operational call sites wrap in `.catch`). */\nexport async function syncApplicationToCrm(\n deps: ProjectionDeps & { chapter: Chapter },\n opts: { app: Record<string, unknown>; stage?: string },\n): Promise<string | null> {\n const emailKey = str(opts.app.email).toLowerCase();\n if (!emailKey) return null;\n // The narrower shape the crm record helpers take (no chapter).\n const recordDeps = { crm: deps.crm, db: deps.db as never, now: deps.now, newId: deps.newId };\n const input = personInputFromApp(deps.chapter, opts.app);\n\n const { crm_record } = await deps.db.query({\n crm_record: { $: { where: { type: \"person\", primaryEmail: emailKey }, limit: 1 } },\n });\n const existing = crm_record?.[0] ?? null;\n const stage = opts.stage || undefined;\n\n let recordId: string;\n if (existing && typeof existing.id === \"string\") {\n recordId = existing.id;\n await updateRecord(recordDeps, { id: recordId, input });\n } else {\n const created = await createRecord(recordDeps, { type: \"person\", input, ...(stage ? { stage } : {}) });\n recordId = created.id;\n }\n\n // Stage mirror: move only on an actual change, under a stable mutationId so a\n // replay never piles up duplicate stage_change activities. Best-effort — a\n // stage not on the crm person type must not fail the whole sync.\n if (existing && stage && existing.stage !== stage) {\n await setStage(recordDeps, { id: recordId, to: stage, authorId: \"system\", mutationId: `crm:stage:${recordId}:${stage}` }).catch(() => undefined);\n }\n\n await deps.db.transact([{ t: \"update\", ns: \"crm_record\", id: recordId, attrs: billingColumns(opts.app) }]);\n\n // Identity link: stamps clerkUserId when a $users row matches the email; a\n // no-op until the person has an account. Best-effort — a just-created record\n // can briefly lag the read, and the link retries on the next sync.\n await linkIdentity(recordDeps, { recordId, email: emailKey, mutationId: `crm:link:${recordId}:${emailKey}` }).catch(() => undefined);\n\n return recordId;\n}\n\n/** Backfill / repair: project every application (newest per person) and every\n * account-only `$users` row into the CRM. Idempotent (safe to re-run). Dev\n * volumes fit one 1000-row page. Returns `{ synced, errors }`. */\nexport async function backfillCrm(deps: ProjectionDeps & { chapter: Chapter }): Promise<{ synced: number; errors: Array<{ email: string; error: string }> }> {\n const data = await deps.db.query({\n applications: { $: { order: { createdAt: \"desc\" }, limit: 1000 } },\n $users: { $: { limit: 1000 } },\n });\n const seen = new Set<string>();\n let synced = 0;\n const errors: Array<{ email: string; error: string }> = [];\n\n const run = async (app: Record<string, unknown>, stage?: string): Promise<void> => {\n const key = str(app.email).toLowerCase();\n if (!key || seen.has(key)) return; // newest-first: one record per person\n seen.add(key);\n try {\n await syncApplicationToCrm(deps, { app, stage });\n synced += 1;\n } catch (err) {\n errors.push({ email: key, error: err instanceof Error ? err.message : String(err) });\n }\n };\n\n for (const a of (data.applications ?? []) as Array<Record<string, unknown>>) await run(a, str(a.status));\n for (const u of (data.$users ?? []) as Array<Record<string, unknown>>) {\n if (u.deleted === true) continue;\n await run({ email: u.email, firstName: str(u.name) });\n }\n return { synced, errors };\n}\n","// Leader → follower projection of a deliberately allowlisted CRM field set.\n//\n// Invariants (package-enforced so no site re-derives them):\n// - One-way: the chapter never writes back to the hub through this path.\n// - Idempotent: every received record carries the leader's stable site +\n// record identity. A structured crm_record_origin row maps that identity to\n// the local CRM record, so a re-share updates instead of duplicating even\n// after an email/domain changes. Legacy tags remain as a migration bridge.\n// - Natural-key convergence: a person unifies by primary email and a business\n// by its configured domain slot (then name), so an arriving applicant and a\n// prior leader share compose into one person.\n// - Operational state stays local. Pipeline/account/billing state is not copied\n// into another site's authority; the push transfers the shared record fields.\n//\n// Reuses @odla-ai/crm's record ops (full validation via crm.prepare), driven by\n// the resolved chapter CRM engine + the structural ChapterDb.\nimport {\n createRecord,\n getRecordByOrigin,\n updateRecord,\n upsertRecordOrigin,\n} from \"@odla-ai/crm\";\nimport type { Crm, CrmRecord } from \"@odla-ai/crm\";\nimport type { ChapterDb, ResolvedNetworkTarget } from \"./types\";\nimport {\n DEFAULT_SHARE_FIELDS,\n type NormalizedSharedRecord,\n type ProjectionDeps,\n type SharedBusiness,\n type SharedPerson,\n type SharedRecord,\n} from \"./network-contract\";\nexport { DEFAULT_SHARE_FIELDS } from \"./network-contract\";\nexport type {\n NetworkRollup, NetworkRollupTarget,\n NetworkSnapshot,\n ProjectionDeps,\n SharedBusiness,\n SharedPerson,\n SharedRecord,\n SharedRecordV1,\n SharedRecordV2,\n} from \"./network-contract\";\n\n/** Map a shared prospect to a crm `person` input (only the fields the default\n * person type accepts). Name falls back to first+last, then the email. */\nexport function sharedPersonInput(person: SharedPerson): Record<string, unknown> {\n const email = person.email.toLowerCase();\n const fullName = [person.firstName, person.lastName].filter(Boolean).join(\" \").trim();\n const input: Record<string, unknown> = { name: person.name ?? fullName ?? email, email };\n if (input.name === \"\") input.name = email;\n if (person.firstName) input.firstName = person.firstName;\n if (person.lastName) input.lastName = person.lastName;\n if (person.phone) input.phone = person.phone;\n if (person.linkedin) input.linkedin = person.linkedin;\n return input;\n}\n\nfunction shortHash(value: string): string {\n let a = 0x811c9dc5;\n let b = 0x9e3779b9;\n for (let i = 0; i < value.length; i += 1) {\n const n = value.charCodeAt(i);\n a = Math.imul(a ^ n, 0x01000193);\n b = Math.imul(b ^ n, 0x85ebca6b);\n }\n return `${(a >>> 0).toString(36)}${(b >>> 0).toString(36)}`;\n}\n\n/** Backward-compatible display tag retained while structured origin rows are\n * the durable leader-id → local-record mapping. */\nexport function networkSourceTag(type: string, hubRecordId: string, sourceId?: string): string {\n const typeKey = type.toLowerCase();\n const readable = /^[a-z0-9_-]+$/.test(hubRecordId);\n const prefix = sourceId ? `network:${sourceId.toLowerCase()}:${typeKey}` : `network:${typeKey}`;\n const raw = `${prefix}:${hubRecordId}`;\n if (readable && raw.length <= 64) return raw;\n return `network:${typeKey.slice(0, 16)}:${shortHash(`${sourceId ?? \"\"}\\u0000${type}\\u0000${hubRecordId}`)}`;\n}\n\n/** Normalize the backwards-compatible person/business shapes into the versioned\n * generic record envelope the receiver writes. */\nexport function normalizeSharedRecord(\n record: SharedPerson | SharedBusiness | SharedRecord,\n fallbackSourceId = \"legacy-source\",\n): NormalizedSharedRecord {\n if (\"input\" in record && record.version === 2) {\n return {\n version: 2,\n sourceId: record.source.siteId,\n sourceRecordId: record.source.recordId,\n type: record.type,\n input: record.input,\n };\n }\n if (\"input\" in record) {\n return {\n version: 1,\n sourceId: fallbackSourceId,\n sourceRecordId: record.hubRecordId,\n type: record.type,\n input: record.input,\n };\n }\n if (\"type\" in record && record.type === \"company\") {\n const input: Record<string, unknown> = { name: record.name };\n for (const key of [\"domain\", \"industry\", \"location\", \"linkedin\", \"notes\"] as const) {\n if (record[key]) input[key] = record[key];\n }\n return {\n version: 1,\n sourceId: fallbackSourceId,\n sourceRecordId: record.hubRecordId,\n type: \"company\",\n input,\n };\n }\n return {\n version: 1,\n sourceId: fallbackSourceId,\n sourceRecordId: record.hubRecordId,\n type: \"person\",\n input: sharedPersonInput(record),\n };\n}\n\n/** Build the allowlisted payload sent from one leader CRM record to a target.\n * A target with an explicit `fields` map only accepts the types it lists. */\nexport function sharedRecordFromCrm(\n crm: Crm,\n record: CrmRecord,\n target: ResolvedNetworkTarget,\n sourceId?: string,\n): SharedRecord {\n if (target.fields && !target.fields[record.type]) {\n throw new Error(`${target.name} does not accept \"${record.type}\" records`);\n }\n const def = crm.type(record.type);\n const fields = target.fields?.[record.type] ?? DEFAULT_SHARE_FIELDS[record.type];\n if (!fields) {\n throw new Error(`${target.name} requires an explicit field allowlist for \"${record.type}\" records`);\n }\n const nameField = def.nameField ?? \"name\";\n const input: Record<string, unknown> = {};\n for (const field of new Set([nameField, ...fields])) {\n const value = record.fields?.[field];\n if (value !== undefined) input[field] = value;\n }\n if (input[nameField] === undefined) input[nameField] = record.name;\n return sourceId\n ? { version: 2, source: { siteId: sourceId, recordId: record.id }, type: record.type, input }\n : { version: 1, type: record.type, hubRecordId: record.id, input };\n}\n\n// Resolve an existing crm_record person by lowercased primaryEmail and update it,\n// else create one under the given mutationId. The shared core of every one-way\n// person projection (hub share, arriving applicant).\nasync function upsertPerson(\n deps: ProjectionDeps,\n opts: { email: string; input: Record<string, unknown>; mutationId: string },\n): Promise<{ recordId: string }> {\n const email = opts.email.toLowerCase();\n const crmDeps = { crm: deps.crm, db: deps.db as never, now: deps.now, newId: deps.newId };\n const { crm_record } = await deps.db.query({ crm_record: { $: { where: { type: \"person\", primaryEmail: email }, limit: 1 } } });\n const existing = crm_record?.[0];\n if (existing && typeof existing.id === \"string\") {\n await updateRecord(crmDeps, { id: existing.id, input: opts.input });\n return { recordId: existing.id };\n }\n const created = await createRecord(crmDeps, { type: \"person\", input: opts.input, mutationId: opts.mutationId });\n return { recordId: created.id };\n}\n\nasync function findSharedRecord(\n deps: ProjectionDeps,\n record: NormalizedSharedRecord,\n tag: string,\n): Promise<Record<string, unknown> | undefined> {\n const structured = await getRecordByOrigin(\n { crm: deps.crm, db: deps.db as never, now: deps.now, newId: deps.newId },\n record.sourceId,\n record.sourceRecordId,\n );\n if (structured) return structured as unknown as Record<string, unknown>;\n const mapped = await deps.db.query({ crm_tag: { $: { where: { tag }, limit: 1 } } });\n const mappedId = mapped.crm_tag?.[0]?.recordId;\n if (typeof mappedId === \"string\") {\n const found = await deps.db.query({ crm_record: { $: { where: { id: mappedId }, limit: 1 } } });\n if (found.crm_record?.[0]) return found.crm_record[0];\n }\n const def = deps.crm.type(record.type);\n const emailField = def.emailField;\n if (emailField && typeof record.input[emailField] === \"string\") {\n const primaryEmail = record.input[emailField].toLowerCase();\n const found = await deps.db.query({\n crm_record: { $: { where: { type: record.type, primaryEmail }, limit: 1 } },\n });\n if (found.crm_record?.[0]) return found.crm_record[0];\n }\n const domain = record.input.domain;\n const domainSlot = def.fields.domain?.slot;\n if (typeof domain === \"string\" && domainSlot) {\n const found = await deps.db.query({\n crm_record: { $: { where: { type: record.type, [domainSlot]: domain }, limit: 1 } },\n });\n if (found.crm_record?.[0]) return found.crm_record[0];\n }\n const nameField = def.nameField ?? \"name\";\n const name = record.input[nameField];\n if (record.type === \"company\" && typeof name === \"string\" && name.trim()) {\n const found = await deps.db.query({\n crm_record: { $: { where: { type: record.type, name: name.trim() }, limit: 1 } },\n });\n if (found.crm_record?.[0]) return found.crm_record[0];\n }\n return undefined;\n}\n\n/**\n * Upsert a leader-shared CRM record into this follower. Accepts the original\n * person wire shape plus the versioned generic shape. Re-shares resolve through\n * a durable provenance tag; people/businesses also converge by natural key.\n */\nexport async function projectSharedRecord(\n deps: ProjectionDeps,\n shared: SharedPerson | SharedBusiness | SharedRecord,\n options: { sourceId?: string; sourceUrl?: string } = {},\n): Promise<{ recordId: string }> {\n const record = normalizeSharedRecord(shared, options.sourceId);\n if (!record.type.trim() || !record.sourceId.trim() || !record.sourceRecordId.trim()) {\n throw new Error(\"type, source site id, and source record id must be non-empty\");\n }\n if (options.sourceId && options.sourceId !== record.sourceId) {\n throw new Error(\"signed sender does not match payload source\");\n }\n const tag = networkSourceTag(record.type, record.sourceRecordId, record.version === 2 ? record.sourceId : undefined);\n const crmDeps = { crm: deps.crm, db: deps.db as never, now: deps.now, newId: deps.newId };\n const existing = await findSharedRecord(deps, record, tag);\n let recordId: string;\n if (existing && typeof existing.id === \"string\") {\n // Do not use one permanent mutation id for updates: a later leader edit is a\n // new desired state and must not be mistaken for a retry of an older push.\n await updateRecord(crmDeps, { id: existing.id, input: record.input });\n recordId = existing.id;\n } else {\n // A deterministic id makes concurrent first deliveries converge even when\n // both requests observe no provenance row before either transaction lands.\n recordId = `network_${shortHash(`${record.sourceId}\\u0000${record.type}\\u0000${record.sourceRecordId}`)}`;\n await createRecord({ ...crmDeps, newId: () => recordId }, {\n type: record.type,\n input: record.input,\n mutationId: `share-create:${tag}`,\n });\n }\n await deps.db.transact(\n [{ t: \"update\", ns: \"crm_tag\", id: tag, attrs: { key: `${recordId}:${tag}`, recordId, tag, createdAt: deps.now() } }],\n { mutationId: `share-map:${tag}:${recordId}` },\n );\n await upsertRecordOrigin(crmDeps, {\n recordId,\n sourceId: record.sourceId,\n sourceRecordId: record.sourceRecordId,\n ...(options.sourceUrl ? { sourceUrl: options.sourceUrl } : {}),\n payloadVersion: record.version,\n });\n return { recordId };\n}\n\n/** An arriving applicant, as far as the CRM projection cares. `extra` carries the\n * site-configured `crmFields` (values from the application), merged on top of the\n * built-in identity/contact set. */\nexport interface Applicant {\n applicationId: string;\n email: string;\n firstName?: string;\n lastName?: string;\n phone?: string;\n linkedin?: string;\n extra?: Record<string, unknown>;\n}\n\n/**\n * Project an arriving applicant into this chapter's `crm_record`, so a new\n * application shows up in the CRM immediately, unified by email with any prior\n * record. Idempotent per application (`apply:${applicationId}`). Best-effort at\n * the call site — a projection failure never fails the application.\n *\n * `extra` fields (a site's `crmFields`) are merged on top of the base person. If\n * an extra field is not on the crm person type, crm validation throws — so the\n * projection retries with the base person alone, ensuring a misconfigured\n * enrichment never silently drops the applicant from the CRM entirely.\n */\nexport async function projectApplicant(deps: ProjectionDeps, applicant: Applicant): Promise<{ recordId: string }> {\n const base = sharedPersonInput({\n email: applicant.email,\n firstName: applicant.firstName,\n lastName: applicant.lastName,\n phone: applicant.phone,\n linkedin: applicant.linkedin,\n hubRecordId: applicant.applicationId,\n });\n const mutationId = `apply:${applicant.applicationId}`;\n const extra = applicant.extra ?? {};\n if (Object.keys(extra).length === 0) return upsertPerson(deps, { email: applicant.email, input: base, mutationId });\n try {\n return await upsertPerson(deps, { email: applicant.email, input: { ...base, ...extra }, mutationId });\n } catch {\n return upsertPerson(deps, { email: applicant.email, input: base, mutationId });\n }\n}\n","import type { Crm, TypeSummary } from \"@odla-ai/crm\";\nimport type { ChapterDb } from \"./types\";\n\n/** The contact data the hub shares for a prospect. `hubRecordId` is the stable\n * idempotency key (the hub's crm_record id). */\nexport interface SharedPerson {\n email: string;\n name?: string;\n firstName?: string;\n lastName?: string;\n phone?: string;\n linkedin?: string;\n hubRecordId: string;\n}\n\n/** Convenience wire shape for sharing the default `company` CRM type. */\nexport interface SharedBusiness {\n type: \"company\";\n name: string;\n domain?: string;\n industry?: string;\n location?: string;\n linkedin?: string;\n notes?: string;\n hubRecordId: string;\n}\n\n/** Versioned generic wire shape. `input` is validated against the follower's\n * own CRM type before any write, so a leader cannot smuggle undeclared fields. */\nexport interface SharedRecordV1 {\n version: 1;\n type: string;\n hubRecordId: string;\n input: Record<string, unknown>;\n}\n\n/** Current wire envelope. `source.siteId` prevents records from two leaders\n * with the same local id from colliding in a follower CRM. */\nexport interface SharedRecordV2 {\n version: 2;\n source: { siteId: string; recordId: string };\n type: string;\n input: Record<string, unknown>;\n}\n\n/** Accepted generic share envelopes. Version 1 remains readable for migration. */\nexport type SharedRecord = SharedRecordV1 | SharedRecordV2;\n\n/** Privacy-bounded follower status returned to an authenticated leader. */\nexport interface NetworkSnapshot {\n version: 1;\n site: { id: string; name: string; mode: string };\n generatedAt: number;\n types: TypeSummary[];\n}\n\n/** One configured target's latest live result in a leader rollup. */\nexport interface NetworkRollupTarget {\n id: string;\n name: string;\n url: string;\n available: boolean;\n generatedAt?: number;\n types?: TypeSummary[];\n error?: string;\n}\n\n/** Cross-target totals returned to the local leader admin. */\nexport interface NetworkRollup {\n configured: number;\n available: number;\n totalRecords: number;\n types: Array<{ type: string; total: number; stages: Record<string, number> }>;\n targets: NetworkRollupTarget[];\n}\n\n/** Privacy-bounded CRM record returned by a follower to one configured,\n * authenticated reader. */\nexport interface NetworkRecord {\n id: string;\n type: string;\n name: string;\n stage?: string;\n fields: Record<string, unknown>;\n createdAt: number;\n updatedAt: number;\n}\n\n/** One bounded, offset-paged follower record window. */\nexport interface NetworkRecordPage {\n version: 1;\n site: { id: string; name: string };\n type: string;\n records: NetworkRecord[];\n total: number;\n limit: number;\n offset: number;\n}\n\n/** Leader-private note attached to a stable remote record identity. */\nexport interface NetworkRecordNote {\n id: string;\n targetId: string;\n recordType: string;\n recordId: string;\n body: string;\n authorId: string;\n authorEmail?: string;\n createdAt: number;\n}\n\n/** A note deliberately shared across the federation edge and stored in the\n * follower CRM activity feed. Unlike NetworkRecordNote, this is visible to\n * the follower's own CRM admins. */\nexport interface NetworkSharedNote {\n id: string;\n sourceId: string;\n recordType: string;\n recordId: string;\n body: string;\n createdAt: number;\n}\n\nexport interface NormalizedSharedRecord {\n version: 1 | 2;\n sourceId: string;\n sourceRecordId: string;\n type: string;\n input: Record<string, unknown>;\n}\n\n/** Dependencies for applying a shared projection. */\nexport interface ProjectionDeps {\n crm: Crm;\n db: ChapterDb;\n now: () => number;\n newId: () => string;\n}\n\n/** Safe defaults when a target does not declare an explicit field allowlist. */\nexport const DEFAULT_SHARE_FIELDS: Readonly<Record<string, readonly string[]>> = {\n person: [\"name\", \"email\", \"firstName\", \"lastName\", \"phone\", \"linkedin\"],\n company: [\"name\", \"domain\", \"industry\", \"location\", \"linkedin\", \"notes\"],\n};\n","// The chapter email pipeline: exactly-once delivery, a non-production fail-safe,\n// and template rendering. Every property here is easy to get wrong and expensive\n// to get wrong, so the correctness-critical decisions — the dedupe check (E1),\n// the dev-redirect / log-only fail-safe (E2), and template rendering (E4) — are\n// PURE and fully tested in this module. The worker supplies the transport +\n// odla-db and performs the actual send + emailLog write around these decisions.\n//\n// Chapter's operational templates ({ subject, text, enabled? }) are\n// transactional lifecycle mail by construction — a site owner edits the copy in\n// Settings but cannot reclassify one as marketing. Consent-gated marketing blasts\n// go through @odla-ai/crm, which owns the transactional-vs-marketing template\n// class as code (E3), so relabeling copy can never bypass the consent gate.\n\n/** One owner-editable template row on the group. `enabled` absent = enabled. */\nexport interface EmailTemplateRow {\n subject: string;\n text: string;\n enabled?: boolean;\n}\n\n/** The `groups`-row fields the email pipeline reads. */\nexport interface EmailGroup {\n id: string;\n name: string;\n replyTo: string;\n /** Non-prod debug inbox: all mail redirects here outside prod (E2). */\n debugEmail?: string;\n refundPolicyText?: string;\n commitmentText?: string;\n normsText?: string;\n emailTemplates: Record<string, EmailTemplateRow>;\n}\n\n/** `{{placeholder}}` substitution; unknown placeholders render empty. */\nexport function render(template: string, vars: Record<string, string>): string {\n return template.replace(/\\{\\{(\\w+)\\}\\}/g, (_, key: string) => vars[key] ?? \"\");\n}\n\n/** Group-level vars every template receives, under the caller's vars. */\nfunction groupVars(group: EmailGroup, vars: Record<string, string>): Record<string, string> {\n return {\n ...vars,\n refundPolicyText: group.refundPolicyText ?? \"\",\n commitmentText: group.commitmentText ?? \"\",\n normsText: group.normsText ?? \"\",\n };\n}\n\n/**\n * Re-render a template's body for history/preview (E4): the CRM comms history\n * reads back emails whose body predates `emailLog.body` by rendering the current\n * template with the recipient's vars. Same substitution + group vars as the send\n * path. `null` for an unknown template. Reflects the copy as it reads today, not\n * necessarily the exact bytes originally sent (only `emailLog.body` is byte-exact).\n */\nexport function renderTemplateBody(group: EmailGroup, template: string, vars: Record<string, string>): string | null {\n const tpl = group.emailTemplates?.[template];\n if (!tpl) return null;\n return render(tpl.text, groupVars(group, vars));\n}\n\n/**\n * E1 (exactly-once): given the prior `emailLog` rows for a `dedupeKey`, has the\n * mail already been delivered? A prior row with **no error** means yes — the\n * caller short-circuits the resend. Failure rows (which carry an `error` and are\n * written without the dedupe mutationId) do not count, so a retry after a failure\n * can still succeed.\n */\nexport function isAlreadySent(priorRows: ReadonlyArray<{ error?: unknown }>): boolean {\n return priorRows.some((row) => !row.error);\n}\n\n/** The pure delivery decision produced by {@link planDelivery}. */\nexport type DeliveryDecision =\n | { deliver: false; reason: \"template-missing\" | \"disabled\" }\n | {\n deliver: true;\n /** Which transport to use — `log-only` records the send but delivers nothing. */\n transport: \"cloudflare\" | \"log-only\";\n to: string;\n subject: string;\n text: string;\n /** True when redirected to the non-prod debug inbox. */\n redirected: boolean;\n };\n\n/**\n * The pure delivery decision (E2 fail-safe + E3 enabled). Given the env, group,\n * template, recipient, and whether a real Cloudflare transport is wired:\n * - missing template → not delivered (`template-missing`);\n * - disabled template and not forced → not delivered (`disabled`);\n * - **non-prod with a debug inbox** → REDIRECT to it, `\"[dev] \"` subject prefix,\n * a dev-redirect note in the body, so test applicants never receive real mail;\n * - **non-prod with NO debug inbox** → force `log-only` (deliver nothing) — the\n * fail-safe that protects every site's test data;\n * - prod → deliver via the real transport (`cloudflare` if wired, else `log-only`).\n */\nexport function planDelivery(input: {\n envName: string;\n group: EmailGroup;\n template: string;\n to: string;\n vars: Record<string, string>;\n /** Whether a Cloudflare Email Service transport (binding + verified from) is wired. */\n cloudflareReady: boolean;\n /** The admin test route may send a disabled template. */\n force?: boolean;\n}): DeliveryDecision {\n const tpl = input.group.emailTemplates?.[input.template];\n if (!tpl) return { deliver: false, reason: \"template-missing\" };\n if (tpl.enabled === false && !input.force) return { deliver: false, reason: \"disabled\" };\n\n const vars = groupVars(input.group, input.vars);\n const isProd = input.envName === \"prod\";\n const redirect = !isProd && !!input.group.debugEmail;\n const transport: \"cloudflare\" | \"log-only\" =\n !isProd && !redirect ? \"log-only\" : input.cloudflareReady ? \"cloudflare\" : \"log-only\";\n const to = redirect ? (input.group.debugEmail as string) : input.to;\n const subject = (redirect ? \"[dev] \" : \"\") + render(tpl.subject, vars);\n const text = redirect\n ? `(dev redirect; original recipient: ${input.to})\\n\\n` + render(tpl.text, vars)\n : render(tpl.text, vars);\n return { deliver: true, transport, to, subject, text, redirected: redirect };\n}\n","// sendTemplated — the operational-email orchestration that wires the pure email\n// decisions (./email: isAlreadySent E1, planDelivery E2/E3) to odla-db + a\n// transport. Structural (takes a ChapterDb + a sender), so it's FakeDb-testable\n// like submitApplication/projectSharedRecord. The worker's lifecycle routes call\n// it to send the prep / payment-confirmation / admin-alert mail.\n//\n// Exactly-once is enforced twice: a prior successful emailLog row short-circuits\n// the resend (query + isAlreadySent), AND the success row is written under the\n// `email:${dedupeKey}` mutationId so a racing double-send dedupes at the db layer.\n// Failure rows omit the mutationId, so a retry after a transient failure can send.\nimport { isAlreadySent, planDelivery } from \"./email\";\nimport type { EmailGroup } from \"./email\";\nimport type { ChapterDb } from \"./types\";\n\n/** The canonical lifecycle email templates chapter fires, in send-order. Owner-\n * editable copy lives on the group row; this is the fixed set the admin email\n * editor + test route iterate. */\nexport const EMAIL_TEMPLATE_NAMES = [\"adminNotification\", \"paymentConfirmation\", \"prepEmail\", \"onboardingInvite\"] as const;\n\n/** One of {@link EMAIL_TEMPLATE_NAMES}. */\nexport type EmailTemplateName = (typeof EMAIL_TEMPLATE_NAMES)[number];\n\n/** The mail transport (the worker's Cloudflare SEND_EMAIL binding). */\nexport interface MailSender {\n send(payload: { from: string; to: string[]; subject: string; text?: string; replyTo?: string }): Promise<{ messageId: string }>;\n}\n\n/** Deps for {@link sendTemplated} — the db, the env name (drives the fail-safe),\n * the transport + from (absent ⇒ log-only), and injected clock/id. */\nexport interface NotifyDeps {\n db: ChapterDb;\n envName: string;\n sender?: MailSender;\n from?: string;\n now: () => number;\n newId: () => string;\n}\n\n/** One templated send. `dedupeKey` is the exactly-once key. */\nexport interface NotifyInput {\n group: EmailGroup;\n template: string;\n to: string;\n vars: Record<string, string>;\n dedupeKey: string;\n applicationId?: string;\n /** The admin test route may send a disabled template. */\n force?: boolean;\n}\n\n/** The outcome. `sent:true` includes the already-sent short-circuit. */\nexport interface NotifyResult {\n sent: boolean;\n reason?: string;\n}\n\n/**\n * Send a templated lifecycle email exactly once. Short-circuits on a prior\n * successful send; otherwise plans delivery (dev fail-safe applies), sends via the\n * transport when one is wired and the plan calls for it, and records an emailLog\n * row either way (success keyed for exactly-once, failure unkeyed for retry).\n */\nexport async function sendTemplated(deps: NotifyDeps, input: NotifyInput): Promise<NotifyResult> {\n const { emailLog } = await deps.db.query({ emailLog: { $: { where: { dedupeKey: input.dedupeKey } } } });\n const prior = (Array.isArray(emailLog) ? emailLog : []) as Array<{ error?: unknown }>;\n if (isAlreadySent(prior)) return { sent: true, reason: \"already-sent\" };\n\n const cloudflareReady = Boolean(deps.sender && deps.from);\n const decision = planDelivery({\n envName: deps.envName,\n group: input.group,\n template: input.template,\n to: input.to,\n vars: input.vars,\n cloudflareReady,\n force: input.force,\n });\n if (!decision.deliver) return { sent: false, reason: decision.reason };\n\n let error: string | undefined;\n let messageId: string | undefined;\n if (decision.transport === \"cloudflare\" && deps.sender && deps.from) {\n try {\n const res = await deps.sender.send({\n from: deps.from,\n to: [decision.to],\n subject: decision.subject,\n text: decision.text,\n replyTo: input.group.replyTo,\n });\n messageId = res.messageId;\n } catch (e) {\n error = e instanceof Error ? e.message : String(e);\n }\n }\n\n const id = deps.newId();\n const row: Record<string, unknown> = {\n id,\n groupId: input.group.id,\n to: decision.to,\n template: input.template,\n subject: decision.subject,\n body: decision.text,\n transport: decision.transport,\n redirected: decision.redirected,\n dedupeKey: input.dedupeKey,\n sentAt: deps.now(),\n ...(input.applicationId ? { applicationId: input.applicationId } : {}),\n ...(messageId ? { messageId } : {}),\n ...(error ? { error } : {}),\n };\n await deps.db.transact([{ t: \"update\", ns: \"emailLog\", id, attrs: row }], error ? undefined : { mutationId: `email:${input.dedupeKey}` });\n return error ? { sent: false, reason: error } : { sent: true };\n}\n\n/** Project a `groups` row into the {@link EmailGroup} the email pipeline reads. */\nexport function emailGroupFrom(row: Record<string, unknown>): EmailGroup {\n const str = (v: unknown): string | undefined => (typeof v === \"string\" ? v : undefined);\n const templates = row.emailTemplates && typeof row.emailTemplates === \"object\" ? row.emailTemplates : {};\n return {\n id: String(row.id),\n name: String(row.name ?? \"\"),\n replyTo: str(row.replyTo) ?? \"\",\n debugEmail: str(row.debugEmail),\n refundPolicyText: str(row.refundPolicyText),\n commitmentText: str(row.commitmentText),\n normsText: str(row.normsText),\n emailTemplates: templates as EmailGroup[\"emailTemplates\"],\n };\n}\n","// The application status pipeline — config, not code. Which statuses exist, which\n// a member can book an intro call from, and which an admin can approve from\n// differ per site; the one invariant every site wants is that status never moves\n// backwards. All of this is pure + tested here; the worker enforces it on every\n// status write, and the CRM record.stage mirrors application.status (never the\n// reverse). Defaults reproduce the proven membership pipeline exactly.\nimport type { ChapterPipeline, ResolvedPipeline } from \"./types\";\n\nconst DEFAULT_STAGES = [\n \"submitted\",\n \"paid_pending_vetting\",\n \"call_scheduled\",\n \"interviewed\",\n \"approved\",\n \"declined\",\n \"refunded\",\n] as const;\nconst DEFAULT_BOOKABLE = [\"submitted\", \"paid_pending_vetting\", \"call_scheduled\"] as const;\nconst DEFAULT_APPROVABLE = [\"paid_pending_vetting\", \"call_scheduled\", \"interviewed\"] as const;\n\n/**\n * Apply defaults + validate the pipeline config. With no config, the complete\n * reference pipeline. With `stages` given but the subsets omitted, the subsets\n * default to empty (a site opts in to bookable/approvable states explicitly).\n * Throws at import on a bad pipeline (empty/duplicate stages, an initial or a\n * subset entry not on the ladder).\n */\nexport function resolvePipeline(p: ChapterPipeline | undefined): ResolvedPipeline {\n const usingDefaults = !p?.stages;\n const stages = p?.stages ?? [...DEFAULT_STAGES];\n if (!Array.isArray(stages) || stages.length === 0 || !stages.every((s) => typeof s === \"string\" && s !== \"\")) {\n throw new Error(\"defineChapter.pipeline.stages: must be a non-empty array of status strings\");\n }\n if (new Set(stages).size !== stages.length) {\n throw new Error(\"defineChapter.pipeline.stages: statuses must be unique\");\n }\n const initial = p?.initial ?? (stages[0] as string);\n if (!stages.includes(initial)) {\n throw new Error(`defineChapter.pipeline.initial: \"${initial}\" is not one of the stages`);\n }\n const bookableFrom = p?.bookableFrom ?? (usingDefaults ? [...DEFAULT_BOOKABLE] : []);\n const approvableFrom = p?.approvableFrom ?? (usingDefaults ? [...DEFAULT_APPROVABLE] : []);\n for (const [name, subset] of [\n [\"bookableFrom\", bookableFrom],\n [\"approvableFrom\", approvableFrom],\n ] as const) {\n for (const s of subset) {\n if (!stages.includes(s)) throw new Error(`defineChapter.pipeline.${name}: \"${s}\" is not one of the stages`);\n }\n }\n return { stages, bookableFrom, approvableFrom, initial };\n}\n\n/** The ordinal of a status in the ladder, or -1 if unknown. */\nexport function stageIndex(status: string, p: ResolvedPipeline): number {\n return p.stages.indexOf(status);\n}\n\n/**\n * The status-never-moves-backwards invariant: a transition is allowed only when\n * both statuses are on the ladder and `to` is at or ahead of `from`. The worker\n * calls this before every status write; a violation is a 409, never a silent\n * downgrade.\n */\nexport function canTransition(from: string, to: string, p: ResolvedPipeline): boolean {\n const fi = p.stages.indexOf(from);\n const ti = p.stages.indexOf(to);\n return fi >= 0 && ti >= 0 && ti >= fi;\n}\n\n/** May an intro call be booked from this status? */\nexport function canBook(status: string, p: ResolvedPipeline): boolean {\n return p.bookableFrom.includes(status);\n}\n\n/** May an application be approved (→ member) from this status? */\nexport function canApprove(status: string, p: ResolvedPipeline): boolean {\n return p.approvableFrom.includes(status);\n}\n","import { getVaultSecret } from \"./auth\";\nimport { clerkGetUserByEmail, clerkSetRole } from \"./clerk-roles\";\nimport { crmDeps, syncApplicationToCrm } from \"./crm-sync\";\nimport { emailGroupFrom, sendTemplated } from \"./notify\";\nimport { canApprove, canTransition } from \"./pipeline\";\nimport type { ChapterDb } from \"./types\";\nimport type { ChapterEnv, WorkerContext } from \"./worker-context\";\n\ntype Row = Record<string, unknown>;\n\nexport interface ApproveApplicationResult {\n ok: boolean;\n status: number;\n error?: string;\n rolePromoted?: boolean;\n emailLogged?: boolean;\n duplicate?: boolean;\n}\n/**\n * Converge one application on approved state and repair every external effect.\n * Manual and waiver-driven approval use this exact operation. Database and\n * email idempotency keys are stable, while Clerk role and CRM writes are safe\n * to repeat after an ambiguous response.\n */\nexport async function approveApplication(input: {\n db: ChapterDb;\n env: ChapterEnv;\n ctx: WorkerContext;\n app: Row;\n origin: string;\n reason: \"manual\" | \"interview_waiver\";\n}): Promise<ApproveApplicationResult> {\n const { db, env, ctx, app } = input;\n const id = String(app.id ?? \"\");\n const status = String(app.status ?? \"\");\n if (!id) return { ok: false, status: 404, error: \"not found\" };\n if (input.reason === \"manual\" && status !== \"approved\" && !canApprove(status, ctx.chapter.pipeline)) {\n return { ok: false, status: 409, error: `cannot approve from status \"${status}\"` };\n }\n if (input.reason === \"interview_waiver\") {\n if (typeof app.interviewWaivedAt !== \"number\") return { ok: false, status: 409, error: \"interview waiver required\" };\n if (status !== \"approved\" && !canTransition(status, \"approved\", ctx.chapter.pipeline)) {\n return { ok: false, status: 409, error: `cannot approve from status \"${status}\"` };\n }\n }\n const write = await db.transact(\n [{ t: \"update\", ns: \"applications\", id, attrs: { status: \"approved\" } }],\n { mutationId: `approve:${id}` },\n );\n const approved = { ...app, status: \"approved\" };\n await syncApplicationToCrm(crmDeps(db, ctx), { app: approved, stage: \"approved\" }).catch(() => undefined);\n\n const { promoteTo, send } = ctx.chapter.operations.onApprove;\n let rolePromoted = false;\n const secret = await getVaultSecret(db, \"clerk_secret_key\");\n if (promoteTo !== false && secret) {\n let userId = typeof app.clerkUserId === \"string\" ? app.clerkUserId : null;\n if (!userId && typeof app.email === \"string\") {\n const found = await clerkGetUserByEmail(secret, app.email);\n userId = found?.id ?? null;\n if (userId) await db.transact([{ t: \"update\", ns: \"applications\", id, attrs: { clerkUserId: userId } }]);\n }\n if (userId) rolePromoted = await clerkSetRole(secret, userId, promoteTo);\n }\n\n let emailLogged = false;\n const groups = (await db.query({ groups: { $: { where: { id: String(app.groupId ?? ctx.chapter.id) }, limit: 1 } } })).groups;\n const group = Array.isArray(groups) ? groups[0] : undefined;\n if (send !== false && group && typeof app.email === \"string\") {\n const result = await sendTemplated(\n { db, envName: env.ODLA_ENV, sender: env.SEND_EMAIL, from: env.EMAIL_FROM, now: () => Date.now(), newId: () => crypto.randomUUID() },\n {\n group: emailGroupFrom(group),\n template: send,\n to: app.email,\n vars: { firstName: String(app.firstName ?? \"\"), membersUrl: `${input.origin}/members/` },\n applicationId: id,\n dedupeKey: `approve:${id}`,\n },\n );\n emailLogged = result.sent;\n }\n return { ok: true, status: 200, rolePromoted, emailLogged, duplicate: write.duplicate };\n}\n","import { canBook } from \"./pipeline\";\nimport type { ResolvedPipeline } from \"./types\";\n\n/** Canonical next action or browser-visible step after application submission. */\nexport type JoinContinuation = \"payment\" | \"paymentPending\" | \"booking\" | \"approve\" | \"accepted\";\n\n/** One server-side decision for submit, resume, and payment completion. */\nexport function resolveJoinContinuation(input: {\n status: string;\n initialStatus: string;\n pipeline: ResolvedPipeline;\n payable: boolean;\n subscriptionStarted: boolean;\n interviewWaived: boolean;\n}): JoinContinuation | null {\n if (input.status === \"approved\") return \"accepted\";\n if (input.interviewWaived) {\n if (!input.payable) return \"approve\";\n if (input.status === input.initialStatus) {\n return input.subscriptionStarted ? \"paymentPending\" : \"payment\";\n }\n return \"approve\";\n }\n if (!input.payable) return \"booking\";\n if (input.status === input.initialStatus) {\n return input.subscriptionStarted ? \"paymentPending\" : \"payment\";\n }\n if (canBook(input.status, input.pipeline)) return \"booking\";\n return null;\n}\n","import { findTier, tierIsFree, tierPayable } from \"./tiers\";\nimport { loadOfferableTiers } from \"./tiers-store\";\nimport { getVaultSecret } from \"./auth\";\nimport { approveApplication } from \"./approve-application\";\nimport { resolveJoinContinuation } from \"./join-continuation\";\nimport type { ChapterDb } from \"./types\";\nimport type { Route } from \"./worker-context\";\n\n/** Resolve and, when eligible, execute the canonical post-signup continuation. */\nexport async function continueJoin(\n db: ChapterDb,\n ctx: Parameters<Route>[3],\n env: Parameters<Route>[2],\n origin: string,\n app: Record<string, unknown>,\n group: Record<string, unknown>,\n): Promise<\"payment\" | \"paymentPending\" | \"booking\" | \"accepted\" | \"gift\" | null> {\n if (typeof app.giftOfferId === \"string\") {\n if (typeof app.giftClaimId === \"string\") return \"gift\";\n return typeof app.giftCheckoutStartedAt === \"number\" ? \"paymentPending\" : \"payment\";\n }\n const stripeKey = await getVaultSecret(db, \"stripe_secret_key\");\n const offered = await loadOfferableTiers(db, group as never, Boolean(stripeKey));\n const tier = findTier(offered, typeof app.tierId === \"string\" ? app.tierId : null);\n const payable = Boolean(tier) && !tierIsFree(tier!) && tierPayable(tier!, group as never, Boolean(stripeKey));\n const state = resolveJoinContinuation({\n status: String(app.status ?? \"\"), initialStatus: ctx.chapter.pipeline.initial,\n pipeline: ctx.chapter.pipeline, payable,\n subscriptionStarted: typeof app.stripeSubscriptionId === \"string\" && app.stripeSubscriptionId !== \"\",\n interviewWaived: typeof app.interviewWaivedAt === \"number\",\n });\n if (state !== \"approve\") return state;\n const approved = await approveApplication({ db, env, ctx, app, origin, reason: \"interview_waiver\" });\n return approved.ok ? \"accepted\" : null;\n}\n","import type { SignupControlDocument, SignupControlEnvelope } from \"./signup-control-contract\";\nimport type { Chapter, ChapterDb, DbOp, ResolvedApplication } from \"./types\";\n\ntype DbLookup = { ns: string; attr: string; value: string | number | boolean };\n\nexport interface StoredSignupControl {\n id: string;\n sourceId: string;\n targetId: string;\n environment: string;\n revision: number;\n digest: string;\n document: SignupControlDocument;\n active: boolean;\n receivedAt: number;\n}\n\nfunction asStored(row: Record<string, unknown> | undefined): StoredSignupControl | null {\n if (!row || typeof row.document !== \"object\" || row.document === null) return null;\n return row as unknown as StoredSignupControl;\n}\n\nasync function hasSignupControl(\n db: ChapterDb,\n targetId: string,\n environment: string,\n active?: true,\n): Promise<boolean> {\n const where = { targetId, environment, ...(active ? { active: true } : {}) };\n if (db.aggregate) {\n return Number((await db.aggregate(\"signupControls\", { count: true }, { where })).count ?? 0) > 0;\n }\n // Compatibility for structural test doubles that predate aggregate(). This\n // deliberately uses the empty-safe query shape and filters locally.\n const rows = (await db.query({ signupControls: {} })).signupControls;\n return Array.isArray(rows) && rows.some((row) =>\n row.targetId === targetId && row.environment === environment && (!active || row.active === true));\n}\n\nexport async function loadLatestSignupControl(\n db: ChapterDb,\n targetId: string,\n environment: string,\n): Promise<StoredSignupControl | null> {\n // Some deployed data planes do not terminate an ordered+filtered query when\n // the namespace has no matching rows. The count route is independently\n // bounded and empty-safe; only order a set we have proved is non-empty.\n if (!await hasSignupControl(db, targetId, environment)) return null;\n const rows = (await db.query({ signupControls: { $: {\n where: { targetId, environment }, order: { revision: \"desc\" }, limit: 1,\n } } })).signupControls;\n const latest = Array.isArray(rows)\n ? [...rows].sort((a, b) => Number(b.revision ?? 0) - Number(a.revision ?? 0))[0]\n : undefined;\n return asStored(latest);\n}\n\nexport async function loadActiveSignupControl(\n db: ChapterDb,\n targetId: string,\n environment: string,\n): Promise<StoredSignupControl | null> {\n if (!await hasSignupControl(db, targetId, environment, true)) return null;\n const rows = (await db.query({ signupControls: { $: {\n where: { targetId, environment, active: true }, order: { revision: \"desc\" }, limit: 1,\n } } })).signupControls;\n const active = Array.isArray(rows)\n ? [...rows].sort((a, b) => Number(b.revision ?? 0) - Number(a.revision ?? 0))[0]\n : undefined;\n return asStored(active);\n}\n\n/** Apply only field names the follower schema already declared. */\nexport function controlledApplication(\n base: ResolvedApplication,\n document: SignupControlDocument | undefined,\n): ResolvedApplication {\n const delegated = document?.application;\n return delegated\n ? { ...base, required: delegated.required, optional: delegated.optional, conditions: { ...(delegated.conditions ?? {}) } }\n : base;\n}\n\nexport function validateControlledApplication(chapter: Chapter, document: SignupControlDocument): string[] {\n if (!document.application) return [];\n const declared = new Set([...chapter.application.required, ...chapter.application.optional]);\n return [...document.application.required, ...document.application.optional]\n .filter((field) => !declared.has(field))\n .map((field) => `document.application field \"${field}\" is not declared by this chapter schema`);\n}\n\nfunction groupAttrs(document: SignupControlDocument): Record<string, unknown> {\n const first = [...document.tiers].filter((tier) => tier.available).sort((a, b) => a.sortOrder - b.sortOrder)[0];\n const firstPaid = [...document.tiers].find((tier) => tier.available && tier.priceCents > 0);\n return {\n ...(first ? { standardPriceCents: first.priceCents } : {}),\n foundingDiscountCents: 0,\n ...(firstPaid?.stripePriceId ? { stripePriceId: firstPaid.stripePriceId } : {}),\n ...(document.policy ?? {}),\n ...(document.scheduling ? { schedulingJson: document.scheduling } : {}),\n };\n}\n\nconst byPublicId = (ns: \"groups\" | \"tiers\", value: string): DbLookup => ({\n ns,\n attr: \"id\",\n value,\n});\n\n/** Transactionally activate one revision and materialize the tables checkout already reads. */\nexport async function materializeSignupControl(\n db: ChapterDb,\n envelope: SignupControlEnvelope,\n previous: StoredSignupControl | null,\n receivedAt: number,\n): Promise<void> {\n const { document, digest } = envelope;\n const currentRows = (await db.query({ tiers: { $: {\n where: { groupId: document.target.chapterId }, limit: 100,\n } } })).tiers ?? [];\n const incoming = new Set(document.tiers.map((tier) => tier.id));\n const ops: DbOp<string | DbLookup>[] = [];\n if (previous?.active) ops.push({ t: \"update\", ns: \"signupControls\", id: previous.id, attrs: { active: false } });\n for (const row of currentRows) {\n const id = String(row.id ?? \"\");\n if (id && !incoming.has(id)) {\n ops.push({ t: \"update\", ns: \"tiers\", id: byPublicId(\"tiers\", id), attrs: { active: false } });\n }\n }\n for (const tier of document.tiers) {\n const tierRef = byPublicId(\"tiers\", tier.id);\n ops.push({ t: \"update\", ns: \"tiers\", id: tierRef, attrs: {\n id: tier.id,\n groupId: document.target.chapterId,\n name: tier.name,\n priceCents: tier.priceCents,\n ...(tier.stripePriceId ? { stripePriceId: tier.stripePriceId } : {}),\n ...(tier.blurb ? { blurb: tier.blurb } : {}),\n sortOrder: tier.sortOrder,\n active: tier.available,\n createdAt: receivedAt,\n } });\n const retract = [\n ...(!tier.stripePriceId ? [\"stripePriceId\"] : []),\n ...(!tier.blurb ? [\"blurb\"] : []),\n ];\n if (retract.length) ops.push({ t: \"retract\", ns: \"tiers\", id: tierRef, attrs: retract });\n }\n const groupRef = byPublicId(\"groups\", document.target.chapterId);\n const attrs = groupAttrs(document);\n ops.push({\n t: \"update\",\n ns: \"groups\",\n id: groupRef,\n attrs,\n });\n if (!(\"stripePriceId\" in attrs)) {\n ops.push({ t: \"retract\", ns: \"groups\", id: groupRef, attrs: [\"stripePriceId\"] });\n }\n const id = `signup-control:${document.target.environment}:${document.revision}`;\n ops.push({ t: \"update\", ns: \"signupControls\", id, attrs: {\n id,\n sourceId: document.source.appId,\n targetId: document.target.chapterId,\n environment: document.target.environment,\n revision: document.revision,\n digest,\n document,\n active: true,\n receivedAt,\n } });\n await db.transact(ops, { mutationId: `signup-control:${document.target.environment}:${document.revision}:${digest}` });\n}\n","// The member session — what GET /api/me returns to a signed-in applicant/member.\n// Ported from the reference application's summary + /api/me reconciliation. The\n// SHAPING is pure and package-enforced so no site re-derives it; the worker owns\n// only the I/O around it (locating the application by email, reconciling the\n// meeting against the calendar) and hands the resolved rows here.\n//\n// Two invariants live here, not in a site:\n// - `paid` is DERIVED, never a stored flag: a subscription exists and the\n// application wasn't refunded. Sites can't drift a stale boolean out of sync\n// with Stripe.\n// - the live meeting row wins: its startAt/meetUrl/timezone override whatever\n// the application row cached, and a non-scheduled meeting (a cancellation\n// adopted from the calendar) forces meetingAt back to null.\n\n/** An application row, as far as the session cares about it. */\nexport interface ApplicationRecord {\n id: string;\n firstName?: string | null;\n lastName?: string | null;\n email?: string | null;\n status: string;\n meetingAt?: number | null;\n meetingLink?: string | null;\n createdAt?: number | null;\n stripeSubscriptionId?: string | null;\n renewalAt?: number | null;\n canceled?: boolean;\n tierId?: string | null;\n}\n\n/** The reconciled meeting row (already adopted against the calendar), or null. */\nexport interface MeetingRecord {\n status: string;\n startAt?: number | null;\n meetUrl?: string | null;\n timezone?: string | null;\n}\n\n/** The stable, non-meeting fields of an application (safe to expose to its own\n * owner). */\nexport interface ApplicationSummary {\n id: string;\n firstName: string | null;\n lastName: string | null;\n email: string | null;\n status: string;\n createdAt: number | null;\n meetingLink: string | null;\n paid: boolean;\n renewalAt: number | null;\n canceled: boolean;\n /** Server-authoritative membership tier selected on this application. */\n tierId: string | null;\n}\n\n/** A summary plus the reconciled meeting fields — the `application` the member\n * area renders. */\nexport interface MemberApplication extends ApplicationSummary {\n meetingAt: number | null;\n meetUrl: string | null;\n timezone: string;\n}\n\n/** The full GET /api/me payload for a signed-in user. */\nexport interface MemberSession {\n userId: string;\n email: string | null;\n role: string;\n superAdmin: boolean;\n application: MemberApplication | null;\n}\n\n/** Derive the summary fields from an application row. `paid` is computed, not\n * read, so it can never contradict Stripe. */\nexport function applicationSummary(app: ApplicationRecord): ApplicationSummary {\n return {\n id: app.id,\n firstName: app.firstName ?? null,\n lastName: app.lastName ?? null,\n email: app.email ?? null,\n status: app.status,\n createdAt: app.createdAt ?? null,\n meetingLink: app.meetingLink ?? null,\n paid: Boolean(app.stripeSubscriptionId) && app.status !== \"refunded\",\n renewalAt: app.renewalAt ?? null,\n canceled: app.canceled === true,\n tierId: app.tierId ?? null,\n };\n}\n\n/** Fold a (possibly absent, already-reconciled) meeting into the application the\n * member area renders. The live meeting overrides the application's cached\n * meeting fields; a non-`scheduled` meeting clears the booking. */\nexport function memberApplication(\n app: ApplicationRecord,\n meeting: MeetingRecord | null | undefined,\n defaultTimezone: string,\n): MemberApplication {\n const summary = applicationSummary(app);\n let meetingAt = app.meetingAt ?? null;\n let meetUrl: string | null = null;\n let timezone = defaultTimezone;\n if (meeting) {\n timezone = meeting.timezone ?? timezone;\n if (meeting.status === \"scheduled\") {\n meetingAt = meeting.startAt ?? null;\n meetUrl = meeting.meetUrl ?? null;\n } else {\n meetingAt = null;\n }\n }\n return { ...summary, meetingAt, meetUrl, timezone };\n}\n\n/** Identity of the signed-in user, from the verified session. */\nexport interface SessionUser {\n userId: string;\n email?: string | null;\n role: string;\n}\n\n/** Assemble the GET /api/me payload. `application` is null when the user has no\n * application on file (an admin who never applied, or a brand-new account). */\nexport function memberSession(\n user: SessionUser,\n opts: { application: MemberApplication | null; superAdmin: boolean },\n): MemberSession {\n return {\n userId: user.userId,\n email: user.email ?? null,\n role: user.role,\n superAdmin: opts.superAdmin,\n application: opts.application,\n };\n}\n","// Apply-time account provisioning. When an application arrives, the worker mints\n// a Clerk invitation so the applicant gets a path into their member area — the\n// generalized server-side account step. Chapter calls the Clerk\n// Backend API directly over fetch (vault clerk_secret_key), mirroring\n// @odla-ai/auth-clerk's createInvitation but self-contained, so it never pulls the\n// auth-clerk UI package into the worker bundle. Best-effort at the call site: a\n// provisioning failure never fails the application.\n\n/** The outcome of a Clerk provisioning call. `existed` marks the heal case: Clerk\n * rejected it because the account/invitation is already there, which is the end\n * state we wanted anyway. */\nexport interface ClerkResult {\n ok: boolean;\n status: number;\n existed?: boolean;\n /** Set when an `existed` heal also refreshed the account's metadata. */\n refreshed?: boolean;\n}\n\n// Clerk answers 422 when the email already has a user (or a pending invitation).\n// For apply-time provisioning that's success, not failure — the account exists.\nconst heal = (status: number): ClerkResult =>\n status === 422 ? { ok: true, status, existed: true } : { ok: false, status };\n\n/** Inputs for a Clerk invitation. */\nexport interface ClerkInviteInput {\n email: string;\n /** Where the accept-invitation link lands (usually the member area). */\n redirectUrl?: string;\n /** Written to the invitation's `public_metadata`. Clerk application\n * invitations cannot carry private metadata, so never put applicant profile\n * fields here. Chapter completes that backend-only write after acceptance. */\n publicMetadata?: Record<string, unknown>;\n}\n\n/** Build the Clerk Backend API invitation request (path + JSON body). Pure, so\n * the wire shape is testable without a network call. */\nexport function clerkInviteRequest(input: ClerkInviteInput): { path: string; body: Record<string, unknown> } {\n return {\n path: \"/v1/invitations\",\n body: {\n email_address: input.email,\n notify: true,\n ...(input.redirectUrl ? { redirect_url: input.redirectUrl } : {}),\n ...(input.publicMetadata ? { public_metadata: input.publicMetadata } : {}),\n },\n };\n}\n\n/** POST the invitation to the Clerk Backend API. A repeat invite for an\n * already-invited email heals to `{ ok: true, existed: true }` rather than\n * reporting a failure the caller would have to special-case. */\nexport async function createClerkInvitation(\n secretKey: string,\n input: ClerkInviteInput,\n fetchImpl: typeof fetch = fetch,\n): Promise<ClerkResult> {\n const { path, body } = clerkInviteRequest(input);\n const res = await fetchImpl(`https://api.clerk.com${path}`, {\n method: \"POST\",\n headers: { authorization: `Bearer ${secretKey}`, \"content-type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n return res.ok ? { ok: true, status: res.status } : heal(res.status);\n}\n\n/** Inputs for a server-side Clerk user create. */\nexport interface ClerkUserInput {\n email: string;\n firstName?: string;\n lastName?: string;\n /** Backend-authored, browser-readable claims such as `role`. */\n publicMetadata?: Record<string, unknown>;\n /** Backend-only account signals and profile data. */\n privateMetadata?: Record<string, unknown>;\n /** Optional metadata merge used only when create returns 422 for an existing\n * account. This lets migrations remove legacy keys without putting tombstone\n * values on a newly-created user. Defaults to the create metadata. */\n repairMetadata?: ClerkMetadataInput;\n}\n\n/** Build the Clerk Backend API user-create request. The account is created\n * passwordless (the member signs in via the site's Clerk flow), so join step 3\n * can say the account is ready — the \"create\" alternative to an invitation. */\nexport function clerkUserRequest(input: ClerkUserInput): { path: string; body: Record<string, unknown> } {\n return {\n path: \"/v1/users\",\n body: {\n email_address: [input.email],\n skip_password_requirement: true,\n ...(input.firstName ? { first_name: input.firstName } : {}),\n ...(input.lastName ? { last_name: input.lastName } : {}),\n ...(input.publicMetadata !== undefined ? { public_metadata: input.publicMetadata } : {}),\n ...(input.privateMetadata !== undefined ? { private_metadata: input.privateMetadata } : {}),\n },\n };\n}\n\n/** One merge-PATCH to the metadata fields Clerk exposes on its Backend API. */\nexport interface ClerkMetadataInput {\n publicMetadata?: Record<string, unknown>;\n privateMetadata?: Record<string, unknown>;\n}\n\n/** Merge metadata into an existing Clerk user. Nested `null` values remove old\n * keys, which Chapter uses to migrate its former public profile into private\n * metadata without disturbing the public `role` claim. */\nexport async function updateClerkUserMetadata(\n secretKey: string,\n userId: string,\n input: ClerkMetadataInput,\n fetchImpl: typeof fetch = fetch,\n): Promise<boolean> {\n const res = await fetchImpl(`https://api.clerk.com/v1/users/${encodeURIComponent(userId)}/metadata`, {\n method: \"PATCH\",\n headers: { authorization: `Bearer ${secretKey}`, \"content-type\": \"application/json\" },\n body: JSON.stringify({\n ...(input.publicMetadata !== undefined ? { public_metadata: input.publicMetadata } : {}),\n ...(input.privateMetadata !== undefined ? { private_metadata: input.privateMetadata } : {}),\n }),\n });\n return res.ok;\n}\n\n/** Look a Clerk account up by email and merge its metadata.\n *\n * Returns `false` when no matching user can be resolved or Clerk rejects the\n * lookup or update. Chapter uses this for create-healing and invitation\n * adoption so a repeated application repairs the private account snapshot.\n */\nexport async function updateClerkUserMetadataByEmail(\n secretKey: string,\n email: string,\n input: ClerkMetadataInput,\n fetchImpl: typeof fetch = fetch,\n): Promise<boolean> {\n const auth = { authorization: `Bearer ${secretKey}` };\n const found = await fetchImpl(`https://api.clerk.com/v1/users?email_address=${encodeURIComponent(email)}&limit=1`, { headers: auth });\n if (!found.ok) return false;\n const users = (await found.json().catch(() => null)) as Array<{ id?: unknown }> | null;\n const id = Array.isArray(users) && typeof users[0]?.id === \"string\" ? users[0].id : undefined;\n if (!id) return false;\n return updateClerkUserMetadata(secretKey, id, input, fetchImpl);\n}\n\n/** Create the applicant's Clerk account server-side. A repeat for an email that\n * already has an account heals to `{ ok: true, existed: true }` — the account\n * exists, which is the state apply-time provisioning wanted — and refreshes\n * supplied public/private metadata on the existing account so a re-application\n * repairs a previously missed create (`refreshed: true`). */\nexport async function createClerkUser(\n secretKey: string,\n input: ClerkUserInput,\n fetchImpl: typeof fetch = fetch,\n): Promise<ClerkResult> {\n const { path, body } = clerkUserRequest(input);\n const res = await fetchImpl(`https://api.clerk.com${path}`, {\n method: \"POST\",\n headers: { authorization: `Bearer ${secretKey}`, \"content-type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n if (res.ok) return { ok: true, status: res.status };\n const healed = heal(res.status);\n const repair = input.repairMetadata ?? {\n ...(input.publicMetadata !== undefined ? { publicMetadata: input.publicMetadata } : {}),\n ...(input.privateMetadata !== undefined ? { privateMetadata: input.privateMetadata } : {}),\n };\n if (\n !healed.existed ||\n (repair.publicMetadata === undefined && repair.privateMetadata === undefined)\n ) return healed;\n const refreshed = await updateClerkUserMetadataByEmail(secretKey, input.email, {\n ...(repair.publicMetadata !== undefined ? { publicMetadata: repair.publicMetadata } : {}),\n ...(repair.privateMetadata !== undefined ? { privateMetadata: repair.privateMetadata } : {}),\n }, fetchImpl).catch(() => false);\n return { ...healed, refreshed };\n}\n","import { getVaultSecret } from \"./auth\";\nimport {\n createClerkInvitation,\n createClerkUser,\n updateClerkUserMetadata,\n updateClerkUserMetadataByEmail,\n} from \"./clerk\";\nimport { applicantProfile } from \"./member\";\nimport { projectApplicant } from \"./network\";\nimport { emailGroupFrom, sendTemplated } from \"./notify\";\nimport type { Chapter, ChapterDb } from \"./types\";\nimport type { ChapterEnv } from \"./worker-context\";\n\nexport const applicantPrivateMetadata = (\n chapter: Chapter,\n applicationId: string,\n fields: Record<string, unknown>,\n removeMissingProfile = false,\n): Record<string, unknown> => {\n const profile = applicantProfile(chapter, fields);\n return {\n applicationId,\n ...(profile ? { profile } : removeMissingProfile ? { profile: null } : {}),\n };\n};\n\n// The previous Chapter contract wrote these keys into browser-readable public\n// metadata. A private-profile sync removes only those Chapter-owned keys while\n// preserving `public_metadata.role` and any host-owned public claims.\nexport const publicProfileRemoval = { applicationId: null, profile: null };\n\nexport async function markPrivateMetadataSynced(\n db: ChapterDb,\n applicationId: string,\n clerkUserId?: string,\n): Promise<void> {\n await db.transact([{\n t: \"update\",\n ns: \"applications\",\n id: applicationId,\n attrs: {\n clerkPrivateMetadataSyncedAt: Date.now(),\n ...(clerkUserId ? { clerkUserId } : {}),\n },\n }]);\n}\n\n/** Complete or repair the backend-only Clerk snapshot once an invited/manual\n * account exists. This is called on first member-session load and is idempotent:\n * Clerk deep-merges the private keys and removes only Chapter's former public\n * profile keys. */\nexport async function syncApplicantPrivateMetadata(\n db: ChapterDb,\n chapter: Chapter,\n applicationId: string,\n fields: Record<string, unknown>,\n clerkUserId: string,\n): Promise<boolean> {\n if (chapter.account === \"none\") return false;\n try {\n const secret = await getVaultSecret(db, \"clerk_secret_key\");\n if (!secret) return false;\n const ok = await updateClerkUserMetadata(secret, clerkUserId, {\n publicMetadata: publicProfileRemoval,\n privateMetadata: applicantPrivateMetadata(chapter, applicationId, fields, true),\n });\n if (!ok) return false;\n await markPrivateMetadataSynced(db, applicationId, clerkUserId);\n return true;\n } catch {\n return false;\n }\n}\n\n// Apply-time provisioning is best-effort: project the applicant into crm_record\n// and optionally mint a Clerk account or invitation.\nexport async function provisionApplicant(\n db: ChapterDb,\n chapter: Chapter,\n applicationId: string,\n fields: Record<string, unknown>,\n): Promise<void> {\n const email = typeof fields.email === \"string\" ? fields.email : \"\";\n if (!email) return;\n const stringValue = (value: unknown): string | undefined =>\n typeof value === \"string\" ? value : undefined;\n const extra: Record<string, unknown> = {};\n for (const field of chapter.application.crmFields) {\n if (fields[field] !== undefined) extra[field] = fields[field];\n }\n try {\n await projectApplicant(\n { crm: chapter.crm, db, now: () => Date.now(), newId: () => crypto.randomUUID() },\n {\n applicationId,\n email,\n firstName: stringValue(fields.firstName),\n lastName: stringValue(fields.lastName),\n phone: stringValue(fields.phone),\n linkedin: stringValue(fields.linkedin),\n extra,\n },\n );\n } catch {\n // CRM projection is best-effort.\n }\n if (chapter.account === \"none\") return;\n try {\n const secret = await getVaultSecret(db, \"clerk_secret_key\");\n if (!secret) return;\n const privateMetadata = applicantPrivateMetadata(chapter, applicationId, fields);\n if (chapter.account === \"create\") {\n const result = await createClerkUser(secret, {\n email,\n firstName: stringValue(fields.firstName),\n lastName: stringValue(fields.lastName),\n privateMetadata,\n repairMetadata: {\n publicMetadata: publicProfileRemoval,\n privateMetadata: applicantPrivateMetadata(chapter, applicationId, fields, true),\n },\n });\n if (result.ok && (!result.existed || result.refreshed)) {\n await markPrivateMetadataSynced(db, applicationId);\n }\n } else {\n // Clerk application invitations only transfer public metadata. Send no\n // applicant data with the invite; if the account already exists, repair it\n // now, otherwise /api/me completes the private write after acceptance.\n const result = await createClerkInvitation(secret, { email });\n if (result.existed) {\n const refreshed = await updateClerkUserMetadataByEmail(secret, email, {\n publicMetadata: publicProfileRemoval,\n privateMetadata: applicantPrivateMetadata(chapter, applicationId, fields, true),\n });\n if (refreshed) await markPrivateMetadataSynced(db, applicationId);\n }\n }\n } catch {\n // Account provisioning is best-effort.\n }\n}\n\n// Notify a human when an application arrives. The dedupe key makes the\n// best-effort send exactly-once per application.\nexport async function notifyAdminOfApplication(\n db: ChapterDb,\n env: ChapterEnv,\n chapterId: string,\n applicationId: string,\n fields: Record<string, unknown>,\n): Promise<void> {\n try {\n const groups = (\n await db.query({ groups: { $: { where: { id: chapterId }, limit: 1 } } })\n ).groups;\n const group = Array.isArray(groups) ? groups[0] : undefined;\n if (!group || typeof group.notificationEmail !== \"string\" || !group.notificationEmail) return;\n const stringValue = (value: unknown): string => typeof value === \"string\" ? value : \"\";\n await sendTemplated(\n {\n db,\n envName: env.ODLA_ENV,\n sender: env.SEND_EMAIL,\n from: env.EMAIL_FROM,\n now: () => Date.now(),\n newId: () => crypto.randomUUID(),\n },\n {\n group: emailGroupFrom(group),\n template: \"adminNotification\",\n to: group.notificationEmail,\n vars: {\n firstName: stringValue(fields.firstName),\n lastName: stringValue(fields.lastName),\n email: stringValue(fields.email),\n phone: stringValue(fields.phone),\n state: stringValue(fields.state),\n },\n dedupeKey: `apply:${applicationId}:admin`,\n applicationId,\n },\n );\n } catch {\n // Never fail the application on a notification error.\n }\n}\n","// Follower-side receiver for one allowlisted CRM projection. Kept separate\n// from member routes and leader fan-out so each security boundary stays small.\nimport { FEDERATION_HEADERS, verifyFederatedRequest } from \"@odla-ai/db\";\nimport { getVaultSecret } from \"./auth\";\nimport { normalizeSharedRecord, projectSharedRecord } from \"./network\";\nimport { json } from \"./worker-context\";\nimport type { Route } from \"./worker-context\";\nimport type { ChapterDb } from \"./types\";\n\n/** POST /api/network/shared — signed leader projection into this site's CRM. */\nexport const handleNetworkShared: Route = async (req, url, env, ctx) => {\n if (req.method !== \"POST\" || url.pathname !== \"/api/network/shared\") return null;\n const db = ctx.makeDb(env);\n const secret = await getVaultSecret(db as unknown as ChapterDb, \"network_share_secret\");\n if (!secret) return json({ error: \"unauthorized\" }, 401);\n\n let raw: string;\n let sourceId: string | undefined;\n if (req.headers.has(FEDERATION_HEADERS.version)) {\n const verified = await verifyFederatedRequest(req, { secret });\n if (!verified.ok) return json({ error: \"unauthorized\", reason: verified.reason }, 401);\n raw = verified.body;\n sourceId = verified.sender;\n } else {\n // Version-1 migration path. New leaders sign requests; the bearer path\n // remains readable while a follower upgrades in place.\n const provided = (req.headers.get(\"authorization\") ?? \"\").replace(/^Bearer /, \"\");\n if (provided.length !== secret.length || provided !== secret) {\n return json({ error: \"unauthorized\" }, 401);\n }\n raw = await req.text();\n }\n let payload: Record<string, unknown>;\n try {\n payload = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n if (\"input\" in payload) {\n const v1 = payload.version === 1 && typeof payload.hubRecordId === \"string\" && payload.hubRecordId.trim();\n const source = payload.source as { siteId?: unknown; recordId?: unknown } | undefined;\n const v2 = payload.version === 2 &&\n source &&\n typeof source.siteId === \"string\" &&\n source.siteId.trim() &&\n typeof source.recordId === \"string\" &&\n source.recordId.trim();\n if ((!v1 && !v2) ||\n typeof payload.type !== \"string\" ||\n !payload.type.trim() ||\n !payload.input ||\n typeof payload.input !== \"object\" ||\n Array.isArray(payload.input)\n ) {\n return json({ error: \"a supported version, source record, type, and input are required\" }, 400);\n }\n } else if (typeof payload.hubRecordId !== \"string\" || !payload.hubRecordId.trim()) {\n return json({ error: \"hubRecordId is required\" }, 400);\n } else if (payload.type !== \"company\" && typeof payload.email !== \"string\") {\n return json({ error: \"legacy person shares require email\" }, 400);\n } else if (payload.type === \"company\" && typeof payload.name !== \"string\") {\n return json({ error: \"business shares require name\" }, 400);\n }\n try {\n const { recordId } = await projectSharedRecord(\n { crm: ctx.chapter.crm, db: db as unknown as ChapterDb, now: () => Date.now(), newId: () => crypto.randomUUID() },\n payload as never,\n sourceId ? { sourceId } : {},\n );\n const record = normalizeSharedRecord(payload as never, sourceId);\n return json({ recordId, type: record.type });\n } catch (error) {\n return json({\n error: error instanceof Error ? error.message : \"invalid shared record\",\n }, 400);\n }\n};\n","import { verifyFederatedRequest } from \"@odla-ai/db\";\nimport { getVaultSecret } from \"./auth\";\nimport { signupControlDigest } from \"./signup-control-canonical\";\nimport {\n SIGNUP_CONTROL_PATH,\n type SignupControlEnvelope,\n type SignupControlRejection,\n} from \"./signup-control-contract\";\nimport { validateSignupControlDocument } from \"./signup-control-validate\";\nimport {\n loadLatestSignupControl,\n materializeSignupControl,\n validateControlledApplication,\n} from \"./signup-control-store\";\nimport { json } from \"./worker-context\";\nimport type { Route } from \"./worker-context\";\nimport type { ChapterDb } from \"./types\";\n\nconst reject = (reason: SignupControlRejection, status: number, errors?: readonly string[]) =>\n json({ ok: false, reason, ...(errors ? { errors } : {}) }, status);\n\n/** Dedicated signed receiver for complete signup configuration. */\nexport const handleSignupControl: Route = async (req, url, env, ctx) => {\n if (req.method !== \"POST\" || url.pathname !== SIGNUP_CONTROL_PATH) return null;\n const authority = ctx.chapter.signupControl;\n if (!authority) return json({ error: \"not found\" }, 404);\n const db = ctx.makeDb(env) as unknown as ChapterDb;\n const secret = await getVaultSecret(db, authority.secretName);\n if (!secret) return json({ error: \"unauthorized\" }, 401);\n const verified = await verifyFederatedRequest(req, { secret, senders: [authority.sourceId] });\n if (!verified.ok) return json({ error: \"unauthorized\", reason: verified.reason }, 401);\n let input: Record<string, unknown>;\n try {\n input = JSON.parse(verified.body) as Record<string, unknown>;\n } catch {\n return reject(\"invalid_document\", 400, [\"request body must be JSON\"]);\n }\n const digest = typeof input.digest === \"string\" ? input.digest : \"\";\n const checked = validateSignupControlDocument(input.document);\n if (!checked.ok) return reject(\"invalid_document\", 400, checked.errors);\n const document = checked.value;\n if (document.source.appId !== authority.sourceId) return reject(\"wrong_source\", 403);\n if (document.target.chapterId !== ctx.chapter.id) return reject(\"wrong_target\", 409);\n if (document.target.environment !== env.ODLA_ENV) return reject(\"wrong_environment\", 409);\n if (document.target.stripeMode !== authority.stripeMode) return reject(\"wrong_stripe_mode\", 409);\n const applicationErrors = validateControlledApplication(ctx.chapter, document);\n if (applicationErrors.length) return reject(\"invalid_document\", 400, applicationErrors);\n if (!digest || await signupControlDigest(document) !== digest) return reject(\"invalid_digest\", 400);\n const latest = await loadLatestSignupControl(db, ctx.chapter.id, env.ODLA_ENV);\n if (latest && document.revision < latest.revision) return reject(\"stale_revision\", 409);\n if (latest && document.revision === latest.revision) {\n if (latest.digest !== digest) return reject(\"conflicting_revision\", 409);\n return json({\n ok: true,\n target: { chapterId: ctx.chapter.id, environment: env.ODLA_ENV },\n revision: latest.revision,\n digest: latest.digest,\n status: \"replayed\",\n acknowledgedAt: latest.receivedAt,\n });\n }\n const receivedAt = Date.now();\n try {\n await materializeSignupControl(db, { digest, document } as SignupControlEnvelope, latest, receivedAt);\n } catch {\n return reject(\"materialization_failed\", 503);\n }\n return json({\n ok: true,\n target: { chapterId: ctx.chapter.id, environment: env.ODLA_ENV },\n revision: document.revision,\n digest,\n status: \"accepted\",\n acknowledgedAt: receivedAt,\n });\n};\n","import type { FieldConditions } from \"@odla-ai/crm\";\nimport type { MembershipPageDocument } from \"./membership-page\";\nimport type { ChapterScheduling } from \"./types\";\nimport type { GiftOfferCatalog } from \"./gift-offers\";\n\n/** Current wire-format version for complete signup-control documents. */\nexport const SIGNUP_CONTROL_SCHEMA_VERSION = 1 as const;\n/** Package-owned follower endpoint for signed signup-control delivery. */\nexport const SIGNUP_CONTROL_PATH = \"/api/signup-control\" as const;\n\n/** One authoritative membership tier in a signup-control revision. */\nexport interface SignupControlTier {\n id: string;\n name: string;\n available: boolean;\n sortOrder: number;\n priceCents: number;\n stripePriceId?: string;\n blurb?: string;\n}\n\n/** A bounded application contract. Fields must already exist in the follower schema. */\nexport interface SignupControlApplication {\n required: readonly string[];\n optional: readonly string[];\n conditions?: Readonly<Record<string, FieldConditions>>;\n copy?: Readonly<Record<string, string>>;\n}\n\n/** Delegated legal and trust copy used by the packaged join journey. */\nexport interface SignupControlPolicy {\n disclaimerText: string;\n refundPolicyText: string;\n trustCopy?: string;\n commitmentText?: string;\n normsText?: string;\n}\n\n/** Bounded semantic design tokens delegated to the chapter signup surface. */\nexport interface SignupControlTheme {\n /** Includes color, spacing, and typography tokens such as font families. */\n tokens: Readonly<Record<string, string | number>>;\n}\n\n/** Complete desired state delivered by a controlling hub. */\nexport interface SignupControlDocument {\n schemaVersion: typeof SIGNUP_CONTROL_SCHEMA_VERSION;\n revision: number;\n generatedAt: number;\n source: { appId: string };\n target: { chapterId: string; environment: string; stripeMode: \"test\" | \"live\" };\n tiers: readonly SignupControlTier[];\n membershipPage: MembershipPageDocument;\n application?: SignupControlApplication;\n policy?: SignupControlPolicy;\n scheduling?: ChapterScheduling;\n theme?: SignupControlTheme;\n giftOffers?: GiftOfferCatalog;\n}\n\n/** Digest travels beside the document so the exact desired state is attestable. */\nexport interface SignupControlEnvelope {\n digest: string;\n document: SignupControlDocument;\n}\n\n/** Exact follower acknowledgement for one accepted or replayed revision. */\nexport interface SignupControlReceipt {\n ok: true;\n target: { chapterId: string; environment: string };\n revision: number;\n digest: string;\n status: \"accepted\" | \"replayed\";\n acknowledgedAt: number;\n}\n\n/** Stable reason codes returned when a follower refuses desired state. */\nexport type SignupControlRejection =\n | \"invalid_document\"\n | \"invalid_digest\"\n | \"wrong_source\"\n | \"wrong_target\"\n | \"wrong_environment\"\n | \"wrong_stripe_mode\"\n | \"stale_revision\"\n | \"conflicting_revision\"\n | \"materialization_failed\";\n\n/** Normalized document result returned by the package validator. */\nexport type SignupControlValidation =\n | { ok: true; value: SignupControlDocument }\n | { ok: false; errors: readonly string[] };\n","/** The first stable, shared Chapter membership-page renderer contract. */\nexport const MEMBERSHIP_PAGE_RENDERER = \"membership-cards-v1\" as const;\n\n/** Fixed visual emphasis choices supported by the versioned card renderer. */\nexport type MembershipTierVariant = \"standard\" | \"featured\" | \"supporting\";\n\n/** A bounded, token-rendered aside within one membership card. */\nexport interface MembershipTierCallout {\n label?: string;\n bodyMarkdown: string;\n}\n\n/** Scarcity copy displayed without changing tier availability or checkout. */\nexport interface MembershipTierCapacity {\n total: number;\n label?: string;\n}\n\n/**\n * Presentation attached to one server-authoritative membership tier.\n *\n * Price, free/paid state, identity, and application targeting deliberately do\n * not live here. They are resolved from the public Chapter join config so\n * authored marketing copy can never change what checkout charges.\n */\nexport interface MembershipTierPresentation {\n tierId: string;\n variant?: MembershipTierVariant;\n badge?: string;\n summaryMarkdown?: string;\n priceEyebrow?: string;\n compareAtPriceCents?: number;\n billingLabel?: string;\n priceNoteMarkdown?: string;\n capacity?: MembershipTierCapacity;\n benefits?: readonly string[];\n callout?: MembershipTierCallout;\n ctaLabel?: string;\n}\n\n/** A bounded document that can be reviewed once and rendered by any Chapter host. */\nexport interface MembershipPageDocument {\n schemaVersion: 1;\n renderer: typeof MEMBERSHIP_PAGE_RENDERER;\n tiers: readonly MembershipTierPresentation[];\n footnoteMarkdown?: string;\n}\n\n/** Minimal server-authoritative tier identity and charged amount used during validation. */\nexport interface MembershipTierAuthority {\n id: string;\n priceCents: number;\n}\n\n/** Live tier authority used to reject missing, unknown, or misleading presentation. */\nexport interface MembershipPageValidationOptions {\n /** When supplied, every live tier must occur exactly once in the document. */\n tiers?: readonly MembershipTierAuthority[];\n}\n\n/** A normalized document or the complete actionable list of validation failures. */\nexport type MembershipPageValidationResult =\n | { ok: true; value: MembershipPageDocument }\n | { ok: false; errors: readonly string[] };\n\nconst TIER_ID = /^[a-z][a-z0-9-]{0,79}$/;\nconst VARIANTS = new Set<MembershipTierVariant>([\"standard\", \"featured\", \"supporting\"]);\nconst ROOT_KEYS = new Set([\"schemaVersion\", \"renderer\", \"tiers\", \"footnoteMarkdown\"]);\nconst TIER_KEYS = new Set([\n \"tierId\", \"variant\", \"badge\", \"summaryMarkdown\", \"priceEyebrow\",\n \"compareAtPriceCents\", \"billingLabel\", \"priceNoteMarkdown\", \"capacity\",\n \"benefits\", \"callout\", \"ctaLabel\",\n]);\nconst CALLOUT_KEYS = new Set([\"label\", \"bodyMarkdown\"]);\nconst CAPACITY_KEYS = new Set([\"total\", \"label\"]);\nconst MAX_TIERS = 20;\nconst MAX_BENEFITS = 24;\nconst MAX_MARKDOWN = 65_536;\nconst MAX_LABEL = 160;\n\nconst objectRecord = (value: unknown): Record<string, unknown> | null =>\n value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? value as Record<string, unknown>\n : null;\n\nfunction rejectUnknownKeys(\n value: Record<string, unknown>,\n allowed: ReadonlySet<string>,\n path: string,\n errors: string[],\n): void {\n for (const key of Object.keys(value)) {\n if (!allowed.has(key)) errors.push(`${path}.${key} is not supported`);\n }\n}\n\nfunction boundedString(\n value: unknown,\n path: string,\n errors: string[],\n max: number,\n required = false,\n): string | undefined {\n if (value === undefined) {\n if (required) errors.push(`${path} is required`);\n return undefined;\n }\n if (typeof value !== \"string\") {\n errors.push(`${path} must be a string`);\n return undefined;\n }\n const text = value.trim();\n if (required && !text) errors.push(`${path} is required`);\n if (text.length > max) errors.push(`${path} must be at most ${max.toLocaleString(\"en-US\")} characters`);\n return text;\n}\n\n/**\n * Validate and normalize a membership-page document without evaluating code,\n * accepting HTML, or allowing authored links/styles. Markdown slots are later\n * rendered by @odla-ai/ui's bounded safe Markdown component.\n */\nexport function validateMembershipPageDocument(\n input: unknown,\n options: MembershipPageValidationOptions = {},\n): MembershipPageValidationResult {\n const errors: string[] = [];\n const root = objectRecord(input);\n if (!root) return { ok: false, errors: [\"document must be an object\"] };\n rejectUnknownKeys(root, ROOT_KEYS, \"document\", errors);\n if (root.schemaVersion !== 1) errors.push(\"document.schemaVersion must be 1\");\n if (root.renderer !== MEMBERSHIP_PAGE_RENDERER) {\n errors.push(`document.renderer must be \\\"${MEMBERSHIP_PAGE_RENDERER}\\\"`);\n }\n if (!Array.isArray(root.tiers)) errors.push(\"document.tiers must be an array\");\n const rawTiers = Array.isArray(root.tiers) ? root.tiers : [];\n if (Array.isArray(root.tiers) && rawTiers.length === 0) errors.push(\"document.tiers must include at least one tier\");\n if (rawTiers.length > MAX_TIERS) errors.push(`document.tiers supports at most ${MAX_TIERS} entries`);\n\n const authority = new Map((options.tiers ?? []).map((tier) => [tier.id, tier]));\n const seen = new Set<string>();\n const tiers: MembershipTierPresentation[] = [];\n for (const [index, raw] of rawTiers.slice(0, MAX_TIERS).entries()) {\n const path = `document.tiers[${index}]`;\n const item = objectRecord(raw);\n if (!item) {\n errors.push(`${path} must be an object`);\n continue;\n }\n rejectUnknownKeys(item, TIER_KEYS, path, errors);\n const tierId = boundedString(item.tierId, `${path}.tierId`, errors, 80, true) ?? \"\";\n if (tierId && !TIER_ID.test(tierId)) errors.push(`${path}.tierId must be a lowercase kebab-case id`);\n if (seen.has(tierId)) errors.push(`${path}.tierId duplicates \\\"${tierId}\\\"`);\n seen.add(tierId);\n if (authority.size && !authority.has(tierId)) errors.push(`${path}.tierId \\\"${tierId}\\\" is not an offered tier`);\n\n const variant = item.variant;\n if (variant !== undefined && (typeof variant !== \"string\" || !VARIANTS.has(variant as MembershipTierVariant))) {\n errors.push(`${path}.variant must be standard, featured, or supporting`);\n }\n const compareAt = item.compareAtPriceCents;\n if (compareAt !== undefined && (!Number.isInteger(compareAt) || Number(compareAt) < 0 || Number(compareAt) > 100_000_000)) {\n errors.push(`${path}.compareAtPriceCents must be an integer from 0 to 100,000,000`);\n }\n const actual = authority.get(tierId)?.priceCents;\n if (Number.isInteger(compareAt) && actual !== undefined && Number(compareAt) <= actual) {\n errors.push(`${path}.compareAtPriceCents must be greater than the authoritative tier price`);\n }\n\n let benefits: string[] | undefined;\n if (item.benefits !== undefined) {\n if (!Array.isArray(item.benefits)) errors.push(`${path}.benefits must be an array`);\n else {\n if (item.benefits.length > MAX_BENEFITS) errors.push(`${path}.benefits supports at most ${MAX_BENEFITS} entries`);\n benefits = item.benefits.slice(0, MAX_BENEFITS).flatMap((benefit, benefitIndex) => {\n const text = boundedString(benefit, `${path}.benefits[${benefitIndex}]`, errors, 2_000, true);\n return text ? [text] : [];\n });\n }\n }\n\n let callout: MembershipTierCallout | undefined;\n if (item.callout !== undefined) {\n const rawCallout = objectRecord(item.callout);\n if (!rawCallout) errors.push(`${path}.callout must be an object`);\n else {\n rejectUnknownKeys(rawCallout, CALLOUT_KEYS, `${path}.callout`, errors);\n const bodyMarkdown = boundedString(rawCallout.bodyMarkdown, `${path}.callout.bodyMarkdown`, errors, MAX_MARKDOWN, true);\n const label = boundedString(rawCallout.label, `${path}.callout.label`, errors, MAX_LABEL);\n if (bodyMarkdown) callout = { ...(label ? { label } : {}), bodyMarkdown };\n }\n }\n\n let capacity: MembershipTierCapacity | undefined;\n if (item.capacity !== undefined) {\n const rawCapacity = objectRecord(item.capacity);\n if (!rawCapacity) errors.push(`${path}.capacity must be an object`);\n else {\n rejectUnknownKeys(rawCapacity, CAPACITY_KEYS, `${path}.capacity`, errors);\n const total = rawCapacity.total;\n if (!Number.isInteger(total) || Number(total) < 1 || Number(total) > 1_000_000) {\n errors.push(`${path}.capacity.total must be an integer from 1 to 1,000,000`);\n }\n const label = boundedString(rawCapacity.label, `${path}.capacity.label`, errors, MAX_LABEL);\n if (Number.isInteger(total) && Number(total) >= 1 && Number(total) <= 1_000_000) {\n capacity = { total: Number(total), ...(label ? { label } : {}) };\n }\n }\n }\n\n const badge = boundedString(item.badge, `${path}.badge`, errors, MAX_LABEL);\n const summaryMarkdown = boundedString(item.summaryMarkdown, `${path}.summaryMarkdown`, errors, MAX_MARKDOWN);\n const priceEyebrow = boundedString(item.priceEyebrow, `${path}.priceEyebrow`, errors, MAX_LABEL);\n const billingLabel = boundedString(item.billingLabel, `${path}.billingLabel`, errors, MAX_LABEL);\n const priceNoteMarkdown = boundedString(item.priceNoteMarkdown, `${path}.priceNoteMarkdown`, errors, MAX_MARKDOWN);\n const ctaLabel = boundedString(item.ctaLabel, `${path}.ctaLabel`, errors, MAX_LABEL);\n tiers.push({\n tierId,\n ...(typeof variant === \"string\" && VARIANTS.has(variant as MembershipTierVariant) ? { variant: variant as MembershipTierVariant } : {}),\n ...(badge ? { badge } : {}),\n ...(summaryMarkdown ? { summaryMarkdown } : {}),\n ...(priceEyebrow ? { priceEyebrow } : {}),\n ...(Number.isInteger(compareAt) ? { compareAtPriceCents: Number(compareAt) } : {}),\n ...(billingLabel ? { billingLabel } : {}),\n ...(priceNoteMarkdown ? { priceNoteMarkdown } : {}),\n ...(capacity ? { capacity } : {}),\n ...(benefits ? { benefits } : {}),\n ...(callout ? { callout } : {}),\n ...(ctaLabel ? { ctaLabel } : {}),\n });\n }\n if (authority.size) {\n for (const tierId of authority.keys()) {\n if (!seen.has(tierId)) errors.push(`document.tiers is missing offered tier \\\"${tierId}\\\"`);\n }\n }\n const footnoteMarkdown = boundedString(root.footnoteMarkdown, \"document.footnoteMarkdown\", errors, MAX_MARKDOWN);\n if (errors.length) return { ok: false, errors };\n return {\n ok: true,\n value: {\n schemaVersion: 1,\n renderer: MEMBERSHIP_PAGE_RENDERER,\n tiers,\n ...(footnoteMarkdown ? { footnoteMarkdown } : {}),\n },\n };\n}\n\n/** Validate a document or fail closed with all actionable validation errors. */\nexport function membershipPageDocument(\n input: unknown,\n options: MembershipPageValidationOptions = {},\n): MembershipPageDocument {\n const result = validateMembershipPageDocument(input, options);\n if (!result.ok) throw new TypeError(`Invalid membership page document: ${result.errors.join(\"; \")}`);\n return result.value;\n}\n","import { resolveApplication } from \"./member\";\nimport { validateMembershipPageDocument } from \"./membership-page\";\nimport { validateScheduling } from \"./scheduling\";\nimport { validateGiftOfferCatalog } from \"./gift-offers\";\nimport type {\n SignupControlApplication,\n SignupControlDocument,\n SignupControlPolicy,\n SignupControlTheme,\n SignupControlTier,\n SignupControlValidation,\n} from \"./signup-control-contract\";\n\nconst SLUG = /^[a-z0-9][a-z0-9-]{1,62}$/;\nconst ENVIRONMENT = /^[a-z][a-z0-9_-]{0,62}$/;\nconst TIER = /^[a-z][a-z0-9-]{0,79}$/;\nconst PRICE = /^price_[A-Za-z0-9]{12,}$/;\nconst ROOT_KEYS = new Set([\n \"schemaVersion\", \"revision\", \"generatedAt\", \"source\", \"target\", \"tiers\",\n \"membershipPage\", \"application\", \"policy\", \"scheduling\", \"theme\", \"giftOffers\",\n]);\nconst TIER_KEYS = new Set([\"id\", \"name\", \"available\", \"sortOrder\", \"priceCents\", \"stripePriceId\", \"blurb\"]);\n\nconst recordOf = (value: unknown): Record<string, unknown> | null =>\n value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? value as Record<string, unknown>\n : null;\n\nfunction unknownKeys(value: Record<string, unknown>, allowed: ReadonlySet<string>, path: string, errors: string[]): void {\n for (const key of Object.keys(value)) if (!allowed.has(key)) errors.push(`${path}.${key} is not supported`);\n}\n\nfunction text(value: unknown, path: string, errors: string[], max = 65_536): string {\n if (typeof value !== \"string\" || !value.trim()) {\n errors.push(`${path} is required`);\n return \"\";\n }\n if (value.length > max) errors.push(`${path} must be at most ${max} characters`);\n return value.trim();\n}\n\nfunction tiersOf(value: unknown, errors: string[]): SignupControlTier[] {\n if (!Array.isArray(value) || !value.length) {\n errors.push(\"document.tiers must be a non-empty array\");\n return [];\n }\n if (value.length > 20) errors.push(\"document.tiers supports at most 20 entries\");\n const seen = new Set<string>();\n return value.slice(0, 20).flatMap((raw, index) => {\n const path = `document.tiers[${index}]`;\n const item = recordOf(raw);\n if (!item) {\n errors.push(`${path} must be an object`);\n return [];\n }\n unknownKeys(item, TIER_KEYS, path, errors);\n const id = text(item.id, `${path}.id`, errors, 80);\n if (id && !TIER.test(id)) errors.push(`${path}.id must be a lowercase kebab-case id`);\n if (seen.has(id)) errors.push(`${path}.id duplicates \"${id}\"`);\n seen.add(id);\n const name = text(item.name, `${path}.name`, errors, 160);\n if (typeof item.available !== \"boolean\") errors.push(`${path}.available must be boolean`);\n if (!Number.isInteger(item.sortOrder) || Number(item.sortOrder) < 0) errors.push(`${path}.sortOrder must be a non-negative integer`);\n if (!Number.isInteger(item.priceCents) || Number(item.priceCents) < 0 || Number(item.priceCents) > 100_000_000) {\n errors.push(`${path}.priceCents must be an integer from 0 to 100,000,000`);\n }\n if (item.stripePriceId !== undefined && (typeof item.stripePriceId !== \"string\" || !PRICE.test(item.stripePriceId))) {\n errors.push(`${path}.stripePriceId must be a real Stripe Price id`);\n }\n if (item.available === true && Number(item.priceCents) > 0 && !item.stripePriceId) {\n errors.push(`${path}.stripePriceId is required for an available paid tier`);\n }\n const blurb = item.blurb === undefined ? undefined : text(item.blurb, `${path}.blurb`, errors, 4_000);\n return [{\n id, name, available: item.available === true,\n sortOrder: Number(item.sortOrder) || 0,\n priceCents: Number(item.priceCents) || 0,\n ...(typeof item.stripePriceId === \"string\" ? { stripePriceId: item.stripePriceId } : {}),\n ...(blurb ? { blurb } : {}),\n }];\n });\n}\n\nfunction applicationOf(value: unknown, errors: string[]): SignupControlApplication | undefined {\n if (value === undefined) return undefined;\n const input = recordOf(value);\n if (!input) {\n errors.push(\"document.application must be an object\");\n return undefined;\n }\n unknownKeys(input, new Set([\"required\", \"optional\", \"conditions\", \"copy\"]), \"document.application\", errors);\n try {\n const resolved = resolveApplication(input);\n const copy = recordOf(input.copy);\n if (input.copy !== undefined && (!copy || Object.values(copy).some((item) => typeof item !== \"string\"))) {\n errors.push(\"document.application.copy must contain only string values\");\n }\n return {\n required: resolved.required,\n optional: resolved.optional,\n ...(Object.keys(resolved.conditions).length ? { conditions: resolved.conditions } : {}),\n ...(copy ? { copy: copy as Record<string, string> } : {}),\n };\n } catch (error) {\n errors.push(error instanceof Error ? error.message : \"document.application is invalid\");\n return undefined;\n }\n}\n\nfunction policyOf(value: unknown, errors: string[]): SignupControlPolicy | undefined {\n if (value === undefined) return undefined;\n const input = recordOf(value);\n if (!input) {\n errors.push(\"document.policy must be an object\");\n return undefined;\n }\n const allowed = new Set([\"disclaimerText\", \"refundPolicyText\", \"trustCopy\", \"commitmentText\", \"normsText\"]);\n unknownKeys(input, allowed, \"document.policy\", errors);\n const result = {} as Record<string, string>;\n for (const key of allowed) {\n if (input[key] === undefined && key !== \"disclaimerText\" && key !== \"refundPolicyText\") continue;\n result[key] = text(input[key], `document.policy.${key}`, errors);\n }\n return result as unknown as SignupControlPolicy;\n}\n\nfunction themeOf(value: unknown, errors: string[]): SignupControlTheme | undefined {\n if (value === undefined) return undefined;\n const input = recordOf(value);\n const tokens = recordOf(input?.tokens);\n if (!input || !tokens) {\n errors.push(\"document.theme.tokens must be an object\");\n return undefined;\n }\n unknownKeys(input, new Set([\"tokens\"]), \"document.theme\", errors);\n if (Object.keys(tokens).length > 256) errors.push(\"document.theme.tokens supports at most 256 entries\");\n let serializedLength = 0;\n for (const [key, token] of Object.entries(tokens)) {\n if (!/^--ui-[a-z0-9][a-z0-9-]{0,94}$/.test(key)) {\n errors.push(`document.theme.tokens.${key} must be an allowlisted --ui-* custom property`);\n }\n const rendered = String(token).trim();\n serializedLength += key.length + rendered.length + 4;\n if ((typeof token !== \"string\" && typeof token !== \"number\") ||\n (typeof token === \"number\" && !Number.isFinite(token)) ||\n !rendered || rendered.length > 1_000 ||\n /[\\u0000-\\u001f\\u007f\\\\<>{};]|\\/\\*|\\*\\/|(?:^|[^a-z])(?:url|expression)\\s*\\(|@import/i.test(rendered)) {\n errors.push(`document.theme.tokens.${key} must be a bounded breakout-safe CSS value`);\n }\n }\n if (serializedLength > 65_536) errors.push(\"document.theme.tokens exceeds the serialized size bound\");\n return { tokens: tokens as Record<string, string | number> };\n}\n\n/** Validate and normalize one complete desired signup state. */\nexport function validateSignupControlDocument(input: unknown): SignupControlValidation {\n const errors: string[] = [];\n const root = recordOf(input);\n if (!root) return { ok: false, errors: [\"document must be an object\"] };\n unknownKeys(root, ROOT_KEYS, \"document\", errors);\n if (root.schemaVersion !== 1) errors.push(\"document.schemaVersion must be 1\");\n if (!Number.isSafeInteger(root.revision) || Number(root.revision) < 1) errors.push(\"document.revision must be a positive integer\");\n if (!Number.isSafeInteger(root.generatedAt) || Number(root.generatedAt) < 1) errors.push(\"document.generatedAt must be epoch milliseconds\");\n const source = recordOf(root.source);\n const target = recordOf(root.target);\n const appId = text(source?.appId, \"document.source.appId\", errors, 63);\n const chapterId = text(target?.chapterId, \"document.target.chapterId\", errors, 63);\n const environment = text(target?.environment, \"document.target.environment\", errors, 63);\n if (appId && !SLUG.test(appId)) errors.push(\"document.source.appId must be a lowercase app slug\");\n if (chapterId && !SLUG.test(chapterId)) errors.push(\"document.target.chapterId must be a lowercase app slug\");\n if (environment && !ENVIRONMENT.test(environment)) errors.push(\"document.target.environment is invalid\");\n if (target?.stripeMode !== \"test\" && target?.stripeMode !== \"live\") errors.push(\"document.target.stripeMode must be test or live\");\n const tiers = tiersOf(root.tiers, errors);\n const available = tiers.filter((tier) => tier.available).sort((a, b) => a.sortOrder - b.sortOrder);\n const page = validateMembershipPageDocument(root.membershipPage, { tiers: available });\n if (!page.ok) errors.push(...page.errors);\n else if (page.value.tiers.some((tier, index) => tier.tierId !== available[index]?.id)) {\n errors.push(\"document.membershipPage.tiers must follow the available tier display order\");\n }\n const application = applicationOf(root.application, errors);\n const policy = policyOf(root.policy, errors);\n let scheduling;\n if (root.scheduling !== undefined) {\n const checked = validateScheduling(root.scheduling as never);\n if (!checked.ok) errors.push(...Object.entries(checked.errors).map(([key, value]) => `document.scheduling.${key}: ${value}`));\n else scheduling = root.scheduling;\n }\n const theme = themeOf(root.theme, errors);\n const giftOffers = root.giftOffers === undefined\n ? undefined\n : validateGiftOfferCatalog(root.giftOffers, new Set(tiers.map((tier) => tier.id)));\n if (giftOffers && !giftOffers.ok) errors.push(...giftOffers.errors);\n if (errors.length || !page.ok) return { ok: false, errors };\n return { ok: true, value: {\n schemaVersion: 1,\n revision: Number(root.revision),\n generatedAt: Number(root.generatedAt),\n source: { appId },\n target: { chapterId, environment, stripeMode: target?.stripeMode as \"test\" | \"live\" },\n tiers,\n membershipPage: page.value,\n ...(application ? { application } : {}),\n ...(policy ? { policy } : {}),\n ...(scheduling ? { scheduling } : {}),\n ...(theme ? { theme } : {}),\n ...(giftOffers?.ok ? { giftOffers: giftOffers.value } : {}),\n } };\n}\n","import { verifyFederatedRequest } from \"@odla-ai/db\";\nimport { getVaultSecret } from \"./auth\";\nimport { normalizeAdmissionEmail } from \"./admission-grants\";\nimport { memberContentDigest } from \"./member-content-canonical\";\nimport {\n MEMBER_CONTENT_CONTROL_PATH,\n MEMBER_CONTENT_PATH,\n composeMemberContent,\n projectMemberContent,\n validateMemberContentDocument,\n type MemberContentDocument,\n type MemberContentEnvelope,\n type MemberContentRejection,\n} from \"./member-content\";\nimport {\n loadActiveMemberContentControl,\n loadLatestMemberContentControl,\n loadLocalMemberContent,\n materializeMemberContentControl,\n saveLocalMemberContent,\n} from \"./member-content-store\";\nimport { loadOfferableTiers, loadTiers } from \"./tiers-store\";\nimport { json } from \"./worker-context\";\nimport type { Route } from \"./worker-context\";\nimport type { ChapterDb } from \"./types\";\n\nconst ADMIN_PATH = \"/api/admin/member-content\";\nconst BODY_CAP = 1_000_000;\n\nconst reject = (reason: MemberContentRejection, status: number, errors?: readonly string[]) =>\n json({ ok: false, reason, ...(errors ? { errors } : {}) }, status);\n\nasync function groupAndTiers(db: ChapterDb, chapterId: string) {\n const groups = (await db.query({ groups: { $: { where: { id: chapterId }, limit: 1 } } })).groups;\n const group = Array.isArray(groups) ? groups[0] : undefined;\n if (!group) return { group: null, tiers: [] };\n return { group, tiers: await loadTiers(db, group as never) };\n}\n\nasync function memberTierId(db: ChapterDb, chapterId: string, email: string | undefined): Promise<string | null> {\n if (!email) return null;\n let rows = (await db.query({ applications: { $: {\n where: { emailNormalized: normalizeAdmissionEmail(email) }, limit: 20,\n } } })).applications;\n if (!rows?.length) rows = (await db.query({ applications: { $: { where: { email }, limit: 20 } } })).applications;\n const latest = Array.isArray(rows)\n ? [...rows]\n .filter((row) => String(row.groupId ?? chapterId) === chapterId)\n .sort((a, b) => Number(b.createdAt ?? 0) - Number(a.createdAt ?? 0))[0]\n : undefined;\n return typeof latest?.tierId === \"string\" && latest.tierId ? latest.tierId : null;\n}\n\nasync function activeDocuments(db: ChapterDb, chapterId: string, environment: string) {\n const [parent, chapter] = await Promise.all([\n loadActiveMemberContentControl(db, chapterId, environment),\n loadLocalMemberContent(db, chapterId, environment),\n ]);\n return { parent, chapter };\n}\n\n/** Signed, replay-safe receiver for inherited Parent member content. */\nexport const handleMemberContentControl: Route = async (req, url, env, ctx) => {\n if (req.method !== \"POST\" || url.pathname !== MEMBER_CONTENT_CONTROL_PATH) return null;\n const settings = ctx.chapter.memberContent?.parent;\n if (!settings) return json({ error: \"not found\" }, 404);\n const db = ctx.makeDb(env) as unknown as ChapterDb;\n const secret = await getVaultSecret(db, settings.secretName);\n if (!secret) return json({ error: \"unauthorized\" }, 401);\n const verified = await verifyFederatedRequest(req, { secret, senders: [settings.sourceId] });\n if (!verified.ok) return json({ error: \"unauthorized\", reason: verified.reason }, 401);\n let input: Record<string, unknown>;\n try {\n input = JSON.parse(verified.body) as Record<string, unknown>;\n } catch {\n return reject(\"invalid_document\", 400, [\"request body must be JSON\"]);\n }\n const digest = typeof input.digest === \"string\" ? input.digest : \"\";\n const initial = validateMemberContentDocument(input.document, {\n sourceType: \"parent\",\n });\n if (!initial.ok) return reject(\"invalid_document\", 400, initial.errors);\n const document = initial.value;\n if (document.source.appId !== settings.sourceId) return reject(\"wrong_source\", 403);\n if (document.target?.chapterId !== ctx.chapter.id) return reject(\"wrong_target\", 409);\n if (document.target.environment !== env.ODLA_ENV) return reject(\"wrong_environment\", 409);\n const { tiers } = await groupAndTiers(db, ctx.chapter.id);\n const checked = validateMemberContentDocument(document, {\n sourceType: \"parent\",\n sourceAppId: settings.sourceId,\n tiers,\n });\n if (!checked.ok) return reject(\"invalid_document\", 400, checked.errors);\n const local = await loadLocalMemberContent(db, ctx.chapter.id, env.ODLA_ENV);\n if (local) {\n const localCheck = validateMemberContentDocument(local.document, {\n sourceType: \"chapter\",\n sourceAppId: ctx.chapter.id,\n tiers,\n parentPages: document.pages,\n });\n if (!localCheck.ok) {\n return reject(\"invalid_document\", 409, localCheck.errors.map((error) => `existing chapter content: ${error}`));\n }\n }\n if (!digest || await memberContentDigest(document) !== digest) return reject(\"invalid_digest\", 400);\n const latest = await loadLatestMemberContentControl(db, ctx.chapter.id, env.ODLA_ENV);\n if (latest && document.revision < latest.revision) return reject(\"stale_revision\", 409);\n if (latest && document.revision === latest.revision) {\n if (latest.digest !== digest) return reject(\"conflicting_revision\", 409);\n return json({\n ok: true,\n target: document.target,\n revision: latest.revision,\n digest: latest.digest,\n status: \"replayed\",\n acknowledgedAt: latest.receivedAt,\n });\n }\n const receivedAt = Date.now();\n try {\n await materializeMemberContentControl(db, { digest, document } as MemberContentEnvelope, latest, receivedAt);\n } catch {\n return reject(\"materialization_failed\", 503);\n }\n return json({\n ok: true,\n target: document.target,\n revision: document.revision,\n digest,\n status: \"accepted\",\n acknowledgedAt: receivedAt,\n });\n};\n\n/** Authenticated, server-filtered member catalog. */\nexport const handleMemberContent: Route = async (req, url, env, ctx) => {\n if (req.method !== \"GET\" || url.pathname !== MEMBER_CONTENT_PATH) return null;\n if (!ctx.chapter.memberContent) return json({ error: \"not found\" }, 404);\n const user = await ctx.verifyUser(req, env);\n if (!user) return json({ error: \"unauthorized\" }, 401);\n const db = ctx.makeDb(env) as unknown as ChapterDb;\n const role = await ctx.roleFor(db as never, user);\n const admin = await ctx.isAdmin(db as never, user);\n const roleIndex = ctx.chapter.auth.ladder.indexOf(role);\n const memberIndex = Math.max(0, ctx.chapter.auth.ladder.length - 2);\n if (!admin && roleIndex < memberIndex) return json({ error: \"member access required\" }, 403);\n const [{ parent, chapter }, { group, tiers }, tierId] = await Promise.all([\n activeDocuments(db, ctx.chapter.id, env.ODLA_ENV),\n groupAndTiers(db, ctx.chapter.id),\n memberTierId(db, ctx.chapter.id, user.email),\n ]);\n const effective = composeMemberContent(parent?.document, chapter?.document);\n let offerable = tiers;\n if (group) {\n const stripeSecret = await getVaultSecret(db, \"stripe_secret_key\");\n offerable = await loadOfferableTiers(db, group as never, Boolean(stripeSecret));\n }\n return json(projectMemberContent(effective, { tierId, admin }, offerable));\n};\n\n/** Admin read/write surface. Parent pages remain read-only; only the local document is replaced. */\nexport const handleAdminMemberContent: Route = async (req, url, env, ctx) => {\n if (url.pathname !== ADMIN_PATH) return null;\n if (!ctx.chapter.memberContent) return json({ error: \"not found\" }, 404);\n const user = await ctx.verifyUser(req, env);\n if (!user) return json({ error: \"unauthorized\" }, 401);\n const db = ctx.makeDb(env) as unknown as ChapterDb;\n if (!await ctx.isAdmin(db as never, user)) return json({ error: \"forbidden\" }, 403);\n const [{ parent, chapter }, { tiers }] = await Promise.all([\n activeDocuments(db, ctx.chapter.id, env.ODLA_ENV),\n groupAndTiers(db, ctx.chapter.id),\n ]);\n if (req.method === \"GET\") {\n const effective = composeMemberContent(parent?.document, chapter?.document);\n return json({\n parent: parent ? { revision: parent.revision, digest: parent.digest, document: parent.document } : null,\n chapter: chapter ? { revision: chapter.revision, document: chapter.document } : null,\n effective,\n tiers: tiers.map(({ id, name, priceCents, active }) => ({ id, name, priceCents, active })),\n localAuthoring: ctx.chapter.memberContent.localAuthoring,\n });\n }\n if (req.method !== \"PUT\") return json({ error: \"method not allowed\" }, 405);\n if (!ctx.chapter.memberContent.localAuthoring) return json({ error: \"local authoring is disabled\" }, 403);\n const raw = await req.text();\n if (raw.length > BODY_CAP) return json({ error: \"request body too large\" }, 413);\n let input: Record<string, unknown>;\n try {\n input = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n const expectedRevision = Number(input.expectedRevision);\n if (!Number.isInteger(expectedRevision) || expectedRevision < 0) {\n return json({ error: \"expectedRevision must be a non-negative integer\" }, 400);\n }\n const now = Date.now();\n const documentInput = withLocalAuthority(input.document, expectedRevision + 1, now, ctx.chapter.id);\n const checked = validateMemberContentDocument(documentInput, {\n sourceType: \"chapter\",\n sourceAppId: ctx.chapter.id,\n tiers,\n parentPages: parent?.document.pages ?? [],\n });\n if (!checked.ok) return json({ error: \"invalid member content\", errors: checked.errors }, 400);\n try {\n const saved = await saveLocalMemberContent(\n db,\n checked.value,\n env.ODLA_ENV,\n expectedRevision,\n now,\n user.email ?? user.userId,\n );\n return json({ ok: true, revision: saved.revision, document: saved.document });\n } catch (error) {\n if (error instanceof Error && error.message === \"member_content_revision_conflict\") {\n return json({ error: \"member content changed; reload before saving\" }, 409);\n }\n return json({ error: \"member content could not be saved\" }, 503);\n }\n};\n\nfunction withLocalAuthority(value: unknown, revision: number, generatedAt: number, appId: string): unknown {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return value;\n return {\n ...(value as Record<string, unknown>),\n schemaVersion: 1,\n revision,\n generatedAt,\n source: { type: \"chapter\", appId },\n };\n}\n","const encoder = new TextEncoder();\n\nfunction canonicalValue(value: unknown): string {\n if (value === null || typeof value === \"boolean\" || typeof value === \"number\" || typeof value === \"string\") {\n return JSON.stringify(value);\n }\n if (Array.isArray(value)) return `[${value.map(canonicalValue).join(\",\")}]`;\n if (typeof value !== \"object\") throw new TypeError(\"member content contains an unsupported value\");\n const record = value as Record<string, unknown>;\n const entries = Object.keys(record).sort().flatMap((key) => {\n const item = record[key];\n return item === undefined ? [] : [`${JSON.stringify(key)}:${canonicalValue(item)}`];\n });\n return `{${entries.join(\",\")}}`;\n}\n\n/** Serialize JSON-like member content with recursively sorted object keys. */\nexport function canonicalMemberContent(value: unknown): string {\n return canonicalValue(value);\n}\n\n/** Compute the canonical SHA-256 digest for one Parent content revision. */\nexport async function memberContentDigest(document: unknown): Promise<string> {\n const digest = await crypto.subtle.digest(\"SHA-256\", encoder.encode(canonicalMemberContent(document)));\n return `sha256:${Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\")}`;\n}\n\n/** Pair one content document with the exact digest the follower acknowledges. */\nexport async function createMemberContentEnvelope(document: import(\"./member-content\").MemberContentDocument) {\n return { document, digest: await memberContentDigest(document) };\n}\n","import type { MemberPageAudience, MemberPageUpsellOffer } from \"./member-content\";\n\nexport const ID = /^[a-z][a-z0-9-]{0,79}$/;\nexport const SLUG = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\nexport const ROOT_KEYS = new Set([\"schemaVersion\", \"revision\", \"generatedAt\", \"source\", \"target\", \"pages\", \"upsellOverrides\"]);\nexport const SOURCE_KEYS = new Set([\"type\", \"appId\"]);\nexport const TARGET_KEYS = new Set([\"chapterId\", \"environment\"]);\nexport const PAGE_KEYS = new Set([\"id\", \"slug\", \"title\", \"summary\", \"navigation\", \"audience\", \"teaserMarkdown\", \"bodyMarkdown\", \"upsell\"]);\nexport const NAV_KEYS = new Set([\"section\", \"order\", \"parentId\"]);\nexport const AUDIENCE_KEYS = new Set([\"kind\", \"tierIds\"]);\nexport const UPSELL_KEYS = new Set([\"owner\", \"offer\"]);\nexport const OFFER_KEYS = new Set([\"tierId\", \"label\", \"bodyMarkdown\", \"ctaLabel\"]);\nexport const OVERRIDE_KEYS = new Set([\"pageId\", \"offer\"]);\nexport const MAX_PAGES = 100;\nexport const MAX_MARKDOWN = 65_536;\nexport const MAX_TEXT = 240;\n\nexport const record = (value: unknown): Record<string, unknown> | null =>\n value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? value as Record<string, unknown>\n : null;\n\nexport function unknownKeys(value: Record<string, unknown>, allowed: ReadonlySet<string>, path: string, errors: string[]): void {\n for (const key of Object.keys(value)) if (!allowed.has(key)) errors.push(`${path}.${key} is not supported`);\n}\n\nexport function textValue(value: unknown, path: string, errors: string[], max = MAX_TEXT, required = false): string | undefined {\n if (value === undefined) {\n if (required) errors.push(`${path} is required`);\n return undefined;\n }\n if (typeof value !== \"string\") {\n errors.push(`${path} must be a string`);\n return undefined;\n }\n const valueText = value.trim();\n if (required && !valueText) errors.push(`${path} is required`);\n if (valueText.length > max) errors.push(`${path} must be at most ${max.toLocaleString(\"en-US\")} characters`);\n return valueText;\n}\n\nexport function offerValue(\n value: unknown,\n path: string,\n errors: string[],\n tiers: ReadonlySet<string>,\n audience?: MemberPageAudience,\n): MemberPageUpsellOffer | undefined {\n const raw = record(value);\n if (!raw) {\n errors.push(`${path} must be an object`);\n return undefined;\n }\n unknownKeys(raw, OFFER_KEYS, path, errors);\n const tierId = textValue(raw.tierId, `${path}.tierId`, errors, 80, true) ?? \"\";\n if (tierId && !ID.test(tierId)) errors.push(`${path}.tierId must be a lowercase kebab-case id`);\n if (tiers.size && !tiers.has(tierId)) errors.push(`${path}.tierId must reference a declared tier`);\n if (audience?.kind === \"tiers\" && tierId && !audience.tierIds.includes(tierId)) {\n errors.push(`${path}.tierId must grant access to this page`);\n }\n const label = textValue(raw.label, `${path}.label`, errors);\n const bodyMarkdown = textValue(raw.bodyMarkdown, `${path}.bodyMarkdown`, errors, MAX_MARKDOWN);\n const ctaLabel = textValue(raw.ctaLabel, `${path}.ctaLabel`, errors);\n return {\n tierId,\n ...(label ? { label } : {}),\n ...(bodyMarkdown ? { bodyMarkdown } : {}),\n ...(ctaLabel ? { ctaLabel } : {}),\n };\n}\n","import {\n MEMBER_CONTENT_SCHEMA_VERSION,\n type MemberContentDocument,\n type MemberContentPage,\n type MemberContentSource,\n type MemberContentTarget,\n type MemberContentValidationOptions,\n type MemberContentValidationResult,\n type MemberPageAudience,\n type MemberPageNavigation,\n type MemberPageUpsell,\n type MemberPageUpsellOverride,\n} from \"./member-content\";\nimport {\n AUDIENCE_KEYS,\n ID,\n MAX_MARKDOWN,\n MAX_PAGES,\n MAX_TEXT,\n NAV_KEYS,\n OVERRIDE_KEYS,\n PAGE_KEYS,\n ROOT_KEYS,\n SLUG,\n SOURCE_KEYS,\n TARGET_KEYS,\n UPSELL_KEYS,\n offerValue,\n record,\n textValue,\n unknownKeys,\n} from \"./member-content-validation-helpers\";\n\n/** Validate one complete parent or chapter authoring layer with actionable paths. */\nexport function validateMemberContentDocument(\n input: unknown,\n options: MemberContentValidationOptions = {},\n): MemberContentValidationResult {\n const errors: string[] = [];\n const root = record(input);\n if (!root) return { ok: false, errors: [\"document must be an object\"] };\n unknownKeys(root, ROOT_KEYS, \"document\", errors);\n if (root.schemaVersion !== MEMBER_CONTENT_SCHEMA_VERSION) errors.push(\"document.schemaVersion must be 1\");\n if (!Number.isInteger(root.revision) || Number(root.revision) < 1) errors.push(\"document.revision must be a positive integer\");\n if (!Number.isInteger(root.generatedAt) || Number(root.generatedAt) < 0) errors.push(\"document.generatedAt must be a non-negative integer timestamp\");\n\n const sourceRaw = record(root.source);\n let source: MemberContentSource = { type: \"chapter\", appId: \"invalid\" };\n if (!sourceRaw) errors.push(\"document.source must be an object\");\n else {\n unknownKeys(sourceRaw, SOURCE_KEYS, \"document.source\", errors);\n const type = sourceRaw.type;\n const appId = textValue(sourceRaw.appId, \"document.source.appId\", errors, 63, true) ?? \"\";\n if (type !== \"parent\" && type !== \"chapter\") errors.push(\"document.source.type must be parent or chapter\");\n if (appId && !ID.test(appId)) errors.push(\"document.source.appId must be a lowercase app slug\");\n if (options.sourceType && type !== options.sourceType) errors.push(`document.source.type must be ${options.sourceType}`);\n if (options.sourceAppId && appId !== options.sourceAppId) errors.push(`document.source.appId must be ${options.sourceAppId}`);\n if (type === \"parent\" || type === \"chapter\") source = { type, appId };\n }\n\n let target: MemberContentTarget | undefined;\n if (root.target !== undefined) {\n const targetRaw = record(root.target);\n if (!targetRaw) errors.push(\"document.target must be an object\");\n else {\n unknownKeys(targetRaw, TARGET_KEYS, \"document.target\", errors);\n const chapterId = textValue(targetRaw.chapterId, \"document.target.chapterId\", errors, 63, true) ?? \"\";\n const environment = textValue(targetRaw.environment, \"document.target.environment\", errors, 80, true) ?? \"\";\n target = { chapterId, environment };\n }\n }\n if (source.type === \"parent\" && !target) errors.push(\"document.target is required for parent content\");\n if (source.type === \"chapter\" && target) errors.push(\"document.target is not supported for chapter content\");\n\n if (!Array.isArray(root.pages)) errors.push(\"document.pages must be an array\");\n const rawPages = Array.isArray(root.pages) ? root.pages : [];\n if (rawPages.length > MAX_PAGES) errors.push(`document.pages supports at most ${MAX_PAGES} entries`);\n const tierIds = new Set((options.tiers ?? []).map((tier) => tier.id));\n const knownParentIds = new Set((options.parentPages ?? []).map((page) => page.id));\n const ids = new Set<string>();\n const slugs = new Set<string>();\n const pages: MemberContentPage[] = [];\n for (const [index, value] of rawPages.slice(0, MAX_PAGES).entries()) {\n const path = `document.pages[${index}]`;\n const raw = record(value);\n if (!raw) {\n errors.push(`${path} must be an object`);\n continue;\n }\n unknownKeys(raw, PAGE_KEYS, path, errors);\n const id = textValue(raw.id, `${path}.id`, errors, 80, true) ?? \"\";\n const slug = textValue(raw.slug, `${path}.slug`, errors, 120, true) ?? \"\";\n const title = textValue(raw.title, `${path}.title`, errors, MAX_TEXT, true) ?? \"\";\n if (id && !ID.test(id)) errors.push(`${path}.id must be a lowercase kebab-case id`);\n if (slug && !SLUG.test(slug)) errors.push(`${path}.slug must be a lowercase URL slug`);\n if (ids.has(id) || knownParentIds.has(id)) errors.push(`${path}.id duplicates page \"${id}\"`);\n if (slugs.has(slug) || (options.parentPages ?? []).some((page) => page.slug === slug)) errors.push(`${path}.slug duplicates \"${slug}\"`);\n ids.add(id);\n slugs.add(slug);\n\n const navRaw = record(raw.navigation);\n let navigation: MemberPageNavigation = { section: \"General\", order: index };\n if (!navRaw) errors.push(`${path}.navigation must be an object`);\n else {\n unknownKeys(navRaw, NAV_KEYS, `${path}.navigation`, errors);\n const section = textValue(navRaw.section, `${path}.navigation.section`, errors, 120, true) ?? \"\";\n const order = navRaw.order;\n if (!Number.isInteger(order) || Number(order) < 0 || Number(order) > 1_000_000) {\n errors.push(`${path}.navigation.order must be an integer from 0 to 1,000,000`);\n }\n const parentId = textValue(navRaw.parentId, `${path}.navigation.parentId`, errors, 80);\n navigation = { section, order: Number.isInteger(order) ? Number(order) : index, ...(parentId ? { parentId } : {}) };\n }\n\n const audienceRaw = record(raw.audience);\n let audience: MemberPageAudience = { kind: \"all-members\" };\n if (!audienceRaw) errors.push(`${path}.audience must be an object`);\n else {\n unknownKeys(audienceRaw, AUDIENCE_KEYS, `${path}.audience`, errors);\n if (audienceRaw.kind === \"all-members\") {\n if (audienceRaw.tierIds !== undefined) errors.push(`${path}.audience.tierIds is not supported for all-members`);\n } else if (audienceRaw.kind === \"tiers\") {\n if (!Array.isArray(audienceRaw.tierIds) || audienceRaw.tierIds.length === 0) {\n errors.push(`${path}.audience.tierIds must be a non-empty array`);\n }\n const values = Array.isArray(audienceRaw.tierIds) ? audienceRaw.tierIds : [];\n const normalized: string[] = [];\n for (const [tierIndex, value] of values.entries()) {\n const tier = textValue(value, `${path}.audience.tierIds[${tierIndex}]`, errors, 80, true) ?? \"\";\n if (normalized.includes(tier)) errors.push(`${path}.audience.tierIds duplicates \"${tier}\"`);\n if (tierIds.size && !tierIds.has(tier)) errors.push(`${path}.audience.tierIds references undeclared tier \"${tier}\"`);\n normalized.push(tier);\n }\n audience = { kind: \"tiers\", tierIds: normalized };\n } else errors.push(`${path}.audience.kind must be all-members or tiers`);\n }\n\n const summary = textValue(raw.summary, `${path}.summary`, errors, 2_000);\n const teaserMarkdown = textValue(raw.teaserMarkdown, `${path}.teaserMarkdown`, errors, MAX_MARKDOWN);\n const bodyMarkdown = textValue(raw.bodyMarkdown, `${path}.bodyMarkdown`, errors, MAX_MARKDOWN, true) ?? \"\";\n let upsell: MemberPageUpsell | undefined;\n if (raw.upsell !== undefined) {\n const upsellRaw = record(raw.upsell);\n if (!upsellRaw) errors.push(`${path}.upsell must be an object`);\n else {\n unknownKeys(upsellRaw, UPSELL_KEYS, `${path}.upsell`, errors);\n const owner = upsellRaw.owner;\n if (owner !== \"parent\" && owner !== \"chapter\") errors.push(`${path}.upsell.owner must be parent or chapter`);\n if (source.type === \"chapter\" && owner === \"parent\") errors.push(`${path}.upsell.owner cannot be parent on a chapter page`);\n if (source.type === \"parent\" && owner === \"parent\" && upsellRaw.offer === undefined) errors.push(`${path}.upsell.offer is required when the parent owns the offer`);\n if (source.type === \"parent\" && owner === \"chapter\" && upsellRaw.offer !== undefined) errors.push(`${path}.upsell.offer must be set by the chapter after delegation`);\n const offer = upsellRaw.offer === undefined ? undefined : offerValue(upsellRaw.offer, `${path}.upsell.offer`, errors, tierIds, audience);\n if (owner === \"parent\") upsell = { owner, offer: offer ?? { tierId: \"\" } };\n else if (owner === \"chapter\") upsell = { owner, ...(offer ? { offer } : {}) };\n }\n }\n pages.push({ id, slug, title, ...(summary ? { summary } : {}), navigation, audience, ...(teaserMarkdown ? { teaserMarkdown } : {}), bodyMarkdown, ...(upsell ? { upsell } : {}) });\n }\n\n const allIds = new Set([...knownParentIds, ...ids]);\n for (const [index, page] of pages.entries()) {\n const parentId = page.navigation.parentId;\n if (parentId && !allIds.has(parentId)) errors.push(`document.pages[${index}].navigation.parentId references unknown page \"${parentId}\"`);\n if (parentId === page.id) errors.push(`document.pages[${index}].navigation.parentId cannot reference itself`);\n }\n for (const page of pages) {\n const seen = new Set([page.id]);\n let parentId = page.navigation.parentId;\n while (parentId) {\n if (seen.has(parentId)) {\n errors.push(`document.pages contains a navigation cycle at \"${page.id}\"`);\n break;\n }\n seen.add(parentId);\n parentId = pages.find((candidate) => candidate.id === parentId)?.navigation.parentId;\n }\n }\n\n let upsellOverrides: MemberPageUpsellOverride[] | undefined;\n if (root.upsellOverrides !== undefined) {\n if (source.type !== \"chapter\") errors.push(\"document.upsellOverrides is supported only for chapter content\");\n if (!Array.isArray(root.upsellOverrides)) errors.push(\"document.upsellOverrides must be an array\");\n const values = Array.isArray(root.upsellOverrides) ? root.upsellOverrides : [];\n const seen = new Set<string>();\n upsellOverrides = [];\n for (const [index, value] of values.entries()) {\n const path = `document.upsellOverrides[${index}]`;\n const raw = record(value);\n if (!raw) {\n errors.push(`${path} must be an object`);\n continue;\n }\n unknownKeys(raw, OVERRIDE_KEYS, path, errors);\n const pageId = textValue(raw.pageId, `${path}.pageId`, errors, 80, true) ?? \"\";\n if (seen.has(pageId)) errors.push(`${path}.pageId duplicates \"${pageId}\"`);\n seen.add(pageId);\n const parentPage = (options.parentPages ?? []).find((page) => page.id === pageId);\n if (!parentPage) errors.push(`${path}.pageId must reference a parent page`);\n else if (parentPage.upsell?.owner !== \"chapter\") errors.push(`${path}.pageId does not delegate upsell authority to the chapter`);\n const offer = offerValue(raw.offer, `${path}.offer`, errors, tierIds, parentPage?.audience);\n if (offer) upsellOverrides.push({ pageId, offer });\n }\n }\n if (errors.length) return { ok: false, errors };\n return { ok: true, value: {\n schemaVersion: MEMBER_CONTENT_SCHEMA_VERSION,\n revision: Number(root.revision),\n generatedAt: Number(root.generatedAt),\n source,\n ...(target ? { target } : {}),\n pages,\n ...(upsellOverrides ? { upsellOverrides } : {}),\n } };\n}\n\n/** Validate or fail closed with every actionable document error. */\nexport function memberContentDocument(input: unknown, options: MemberContentValidationOptions = {}): MemberContentDocument {\n const result = validateMemberContentDocument(input, options);\n if (!result.ok) throw new TypeError(`Invalid member content document: ${result.errors.join(\"; \")}`);\n return result.value;\n}\n","/** Versioned contract for authenticated member content. */\nexport const MEMBER_CONTENT_SCHEMA_VERSION = 1 as const;\n/** Authenticated member projection endpoint. */\nexport const MEMBER_CONTENT_PATH = \"/api/member-content\" as const;\n/** Dedicated signed Parent → Chapter content-delivery endpoint. */\nexport const MEMBER_CONTENT_CONTROL_PATH = \"/api/member-content-control\" as const;\n\n/** Authority that authored one independently stored member-content layer. */\nexport type MemberContentSourceType = \"parent\" | \"chapter\";\n/** Stable author identity attached to every member-content document and page. */\nexport interface MemberContentSource { type: MemberContentSourceType; appId: string }\n/** Chapter deployment that a parent member-content revision is intended for. */\nexport interface MemberContentTarget { chapterId: string; environment: string }\n\n/** Navigation is data, so agents do not have to coordinate route code. */\nexport interface MemberPageNavigation {\n section: string;\n order: number;\n parentId?: string;\n}\n\n/** Explicit sets avoid unsafe assumptions that commercial tiers form a ladder. */\nexport type MemberPageAudience =\n | { kind: \"all-members\" }\n | { kind: \"tiers\"; tierIds: readonly string[] };\n\n/** Authored offer copy. Price and provider identity deliberately do not live here. */\nexport interface MemberPageUpsellOffer {\n tierId: string;\n label?: string;\n bodyMarkdown?: string;\n ctaLabel?: string;\n}\n\n/** Parent offer authority is explicit; a Chapter can edit only a delegated offer. */\nexport type MemberPageUpsell =\n | { owner: \"parent\"; offer: MemberPageUpsellOffer }\n | { owner: \"chapter\"; offer?: MemberPageUpsellOffer };\n\n/** Authored member page whose body is disclosed only after server-side projection. */\nexport interface MemberContentPage {\n id: string;\n slug: string;\n title: string;\n summary?: string;\n navigation: MemberPageNavigation;\n audience: MemberPageAudience;\n /** Safe Markdown shown while the body is withheld. */\n teaserMarkdown?: string;\n /** Never serialized to a viewer whose audience does not match. */\n bodyMarkdown: string;\n upsell?: MemberPageUpsell;\n}\n\n/** Chapter-owned offer attached to a Parent page that delegated offer authority. */\nexport interface MemberPageUpsellOverride { pageId: string; offer: MemberPageUpsellOffer }\n\n/** One complete source layer. Parent and Chapter layers are stored independently. */\nexport interface MemberContentDocument {\n schemaVersion: typeof MEMBER_CONTENT_SCHEMA_VERSION;\n revision: number;\n generatedAt: number;\n source: MemberContentSource;\n target?: MemberContentTarget;\n pages: readonly MemberContentPage[];\n upsellOverrides?: readonly MemberPageUpsellOverride[];\n}\n\n/** Provider-neutral tier facts used to validate access and resolve safe offers. */\nexport interface MemberContentTierAuthority {\n id: string;\n name?: string;\n priceCents?: number;\n active?: boolean;\n}\n\n/** Local authority supplied while validating a member-content document. */\nexport interface MemberContentValidationOptions {\n sourceType?: MemberContentSourceType;\n sourceAppId?: string;\n tiers?: readonly MemberContentTierAuthority[];\n parentPages?: readonly MemberContentPage[];\n}\n\n/** Validated document or an actionable collection of contract errors. */\nexport type MemberContentValidationResult =\n | { ok: true; value: MemberContentDocument }\n | { ok: false; errors: readonly string[] };\n\n/** Composed member page retaining the identity of its authoring layer. */\nexport interface EffectiveMemberContentPage extends MemberContentPage { source: MemberContentSource }\n/** Deterministically ordered parent and chapter layers with their source revisions. */\nexport interface EffectiveMemberContent {\n pages: readonly EffectiveMemberContentPage[];\n parentRevision: number | null;\n chapterRevision: number | null;\n}\n/** Server-authoritative identity facts used for member-content disclosure. */\nexport interface MemberContentViewer { tierId: string | null; admin: boolean }\n/** Authored upsell joined to active chapter tier name and price authority. */\nexport interface ResolvedMemberPageUpsell extends MemberPageUpsellOffer { tierName: string; priceCents: number }\n\n/** Viewer-safe page result; locked projections never carry bodyMarkdown. */\nexport interface MemberContentPageProjection {\n id: string;\n slug: string;\n title: string;\n summary?: string;\n navigation: MemberPageNavigation;\n audience: MemberPageAudience;\n source: MemberContentSource;\n access: \"allowed\" | \"locked\";\n teaserMarkdown?: string;\n bodyMarkdown?: string;\n upsell?: ResolvedMemberPageUpsell;\n}\n\n/** Complete viewer-safe member navigation and revision projection. */\nexport interface MemberContentProjection {\n pages: readonly MemberContentPageProjection[];\n viewer: { tierId: string | null; admin: boolean };\n revisions: { parent: number | null; chapter: number | null };\n}\n\n/** Canonical parent document and digest transmitted over the signed control edge. */\nexport interface MemberContentEnvelope { digest: string; document: MemberContentDocument }\n/** Durable Chapter acknowledgement for an accepted or idempotently replayed revision. */\nexport interface MemberContentReceipt {\n ok: true;\n target: MemberContentTarget;\n revision: number;\n digest: string;\n status: \"accepted\" | \"replayed\";\n acknowledgedAt: number;\n}\n\n/** Stable rejection reasons returned by the signed member-content control endpoint. */\nexport type MemberContentRejection =\n | \"invalid_document\"\n | \"invalid_digest\"\n | \"wrong_source\"\n | \"wrong_target\"\n | \"wrong_environment\"\n | \"stale_revision\"\n | \"conflicting_revision\"\n | \"materialization_failed\";\n\nexport { memberContentDocument, validateMemberContentDocument } from \"./member-content-validation\";\n\nconst pageOrder = (a: EffectiveMemberContentPage, b: EffectiveMemberContentPage): number =>\n a.navigation.section.localeCompare(b.navigation.section)\n || a.navigation.order - b.navigation.order\n || a.title.localeCompare(b.title)\n || a.id.localeCompare(b.id);\n\n/** Compose immutable Parent content with independently stored Chapter content. */\nexport function composeMemberContent(\n parent: MemberContentDocument | null | undefined,\n chapter: MemberContentDocument | null | undefined,\n): EffectiveMemberContent {\n const pages: EffectiveMemberContentPage[] = [];\n const parentPages = new Map<string, EffectiveMemberContentPage>();\n for (const page of parent?.pages ?? []) {\n const effective = { ...page, source: parent!.source };\n parentPages.set(page.id, effective);\n pages.push(effective);\n }\n for (const override of chapter?.upsellOverrides ?? []) {\n const page = parentPages.get(override.pageId);\n if (page?.upsell?.owner === \"chapter\") page.upsell = { owner: \"chapter\", offer: override.offer };\n }\n for (const page of chapter?.pages ?? []) {\n if (parentPages.has(page.id) || pages.some((candidate) => candidate.slug === page.slug)) {\n throw new TypeError(`Chapter member page \"${page.id}\" conflicts with parent content`);\n }\n pages.push({ ...page, source: chapter!.source });\n }\n return {\n pages: pages.sort(pageOrder),\n parentRevision: parent?.revision ?? null,\n chapterRevision: chapter?.revision ?? null,\n };\n}\n\nconst allowed = (page: MemberContentPage, viewer: MemberContentViewer): boolean =>\n viewer.admin\n || page.audience.kind === \"all-members\"\n || (viewer.tierId !== null && page.audience.tierIds.includes(viewer.tierId));\n\n/** Restricted bodies are omitted and authored offers are joined to live tier authority. */\nexport function projectMemberContent(\n content: EffectiveMemberContent,\n viewer: MemberContentViewer,\n tiers: readonly MemberContentTierAuthority[],\n): MemberContentProjection {\n const authority = new Map(tiers.filter((tier) => tier.active !== false).map((tier) => [tier.id, tier]));\n return {\n viewer: { ...viewer },\n revisions: { parent: content.parentRevision, chapter: content.chapterRevision },\n pages: content.pages.map((page) => {\n const canRead = allowed(page, viewer);\n const offer = !canRead ? page.upsell?.offer : undefined;\n const tier = offer ? authority.get(offer.tierId) : undefined;\n const upsell = offer && tier && typeof tier.name === \"string\" && typeof tier.priceCents === \"number\"\n ? { ...offer, tierName: tier.name, priceCents: tier.priceCents }\n : undefined;\n return {\n id: page.id,\n slug: page.slug,\n title: page.title,\n ...(page.summary ? { summary: page.summary } : {}),\n navigation: page.navigation,\n audience: page.audience,\n source: page.source,\n access: canRead ? \"allowed\" as const : \"locked\" as const,\n ...(page.teaserMarkdown ? { teaserMarkdown: page.teaserMarkdown } : {}),\n ...(canRead ? { bodyMarkdown: page.bodyMarkdown } : {}),\n ...(upsell ? { upsell } : {}),\n };\n }),\n };\n}\n","import type { ChapterDb, DbOp } from \"./types\";\nimport type { MemberContentDocument, MemberContentEnvelope } from \"./member-content\";\n\nexport interface StoredMemberContentControl {\n id: string;\n sourceId: string;\n targetId: string;\n environment: string;\n revision: number;\n digest: string;\n document: MemberContentDocument;\n active: boolean;\n receivedAt: number;\n}\n\nexport interface StoredLocalMemberContent {\n id: string;\n chapterId: string;\n environment: string;\n revision: number;\n document: MemberContentDocument;\n updatedAt: number;\n updatedBy?: string;\n}\n\nconst control = (row: Record<string, unknown> | undefined): StoredMemberContentControl | null =>\n row && row.document && typeof row.document === \"object\" ? row as unknown as StoredMemberContentControl : null;\n\nconst local = (row: Record<string, unknown> | undefined): StoredLocalMemberContent | null =>\n row && row.document && typeof row.document === \"object\" ? row as unknown as StoredLocalMemberContent : null;\n\nasync function exists(db: ChapterDb, ns: string, where: Record<string, unknown>): Promise<boolean> {\n if (db.aggregate) return Number((await db.aggregate(ns, { count: true }, { where })).count ?? 0) > 0;\n const rows = (await db.query({ [ns]: {} }))[ns] ?? [];\n return rows.some((row) => Object.entries(where).every(([key, value]) => row[key] === value));\n}\n\nexport async function loadActiveMemberContentControl(\n db: ChapterDb,\n targetId: string,\n environment: string,\n): Promise<StoredMemberContentControl | null> {\n const where = { targetId, environment, active: true };\n if (!await exists(db, \"memberContentControls\", where)) return null;\n const rows = (await db.query({ memberContentControls: { $: {\n where,\n order: { revision: \"desc\" },\n limit: 1,\n } } })).memberContentControls;\n return control(Array.isArray(rows) ? [...rows].sort((a, b) => Number(b.revision) - Number(a.revision))[0] : undefined);\n}\n\nexport async function loadLatestMemberContentControl(\n db: ChapterDb,\n targetId: string,\n environment: string,\n): Promise<StoredMemberContentControl | null> {\n const where = { targetId, environment };\n if (!await exists(db, \"memberContentControls\", where)) return null;\n const rows = (await db.query({ memberContentControls: { $: {\n where,\n order: { revision: \"desc\" },\n limit: 1,\n } } })).memberContentControls;\n return control(Array.isArray(rows) ? [...rows].sort((a, b) => Number(b.revision) - Number(a.revision))[0] : undefined);\n}\n\nexport async function loadLocalMemberContent(\n db: ChapterDb,\n chapterId: string,\n environment: string,\n): Promise<StoredLocalMemberContent | null> {\n const id = `member-content-local:${environment}`;\n const rows = (await db.query({ memberContentLocal: { $: { where: { id }, limit: 1 } } })).memberContentLocal;\n return local(Array.isArray(rows) ? rows[0] : undefined);\n}\n\n/** Activate a Parent revision without touching the independently owned local row. */\nexport async function materializeMemberContentControl(\n db: ChapterDb,\n envelope: MemberContentEnvelope,\n previous: StoredMemberContentControl | null,\n receivedAt: number,\n): Promise<void> {\n const { document, digest } = envelope;\n const target = document.target!;\n const id = `member-content-control:${target.environment}:${document.revision}`;\n const ops: DbOp[] = [];\n if (previous?.active) {\n ops.push({ t: \"update\", ns: \"memberContentControls\", id: previous.id, attrs: { active: false } });\n }\n ops.push({ t: \"update\", ns: \"memberContentControls\", id, attrs: {\n id,\n sourceId: document.source.appId,\n targetId: target.chapterId,\n environment: target.environment,\n revision: document.revision,\n digest,\n document,\n active: true,\n receivedAt,\n } });\n await db.transact(ops, { mutationId: `member-content-control:${target.environment}:${document.revision}:${digest}` });\n}\n\n/** Save a complete local layer under an optimistic revision guard. */\nexport async function saveLocalMemberContent(\n db: ChapterDb,\n document: MemberContentDocument,\n environment: string,\n expectedRevision: number,\n updatedAt: number,\n updatedBy?: string,\n): Promise<StoredLocalMemberContent> {\n const id = `member-content-local:${environment}`;\n const current = await loadLocalMemberContent(db, document.source.appId, environment);\n if ((current?.revision ?? 0) !== expectedRevision) throw new Error(\"member_content_revision_conflict\");\n const row: StoredLocalMemberContent = {\n id,\n chapterId: document.source.appId,\n environment,\n revision: document.revision,\n document,\n updatedAt,\n ...(updatedBy ? { updatedBy } : {}),\n };\n await db.transact([{ t: \"update\", ns: \"memberContentLocal\", id, attrs: row as unknown as Record<string, unknown> }], {\n mutationId: `member-content-local:${environment}:${document.revision}`,\n guards: current\n ? [{ ns: \"memberContentLocal\", id, exists: true, equals: { revision: expectedRevision } }]\n : [{ ns: \"memberContentLocal\", id, exists: false }],\n });\n return row;\n}\n","import { verifyFederatedRequest } from \"@odla-ai/db\";\nimport { getVaultSecret } from \"./auth\";\nimport {\n ADMISSION_GRANTS_PATH,\n type AdmissionGrantEnvelope,\n type AdmissionGrantRejection,\n} from \"./admission-grants-contract\";\nimport {\n loadLatestAdmissionRevision,\n materializeAdmissionGrants,\n validateAdmissionGrantDocument,\n} from \"./admission-grants\";\nimport { signupControlDigest } from \"./signup-control-canonical\";\nimport { json } from \"./worker-context\";\nimport type { Route } from \"./worker-context\";\nimport type { ChapterDb } from \"./types\";\n\nconst reject = (reason: AdmissionGrantRejection, status: number, errors?: readonly string[]) =>\n json({ ok: false, reason, ...(errors ? { errors } : {}) }, status);\n\n/** Signed Parent → Chapter desired-state receiver for admission decisions. */\nexport const handleAdmissionGrants: Route = async (req, url, env, ctx) => {\n if (req.method !== \"POST\" || url.pathname !== ADMISSION_GRANTS_PATH) return null;\n const authority = ctx.chapter.signupControl;\n if (!authority) return json({ error: \"not found\" }, 404);\n const db = ctx.makeDb(env) as unknown as ChapterDb;\n const secret = await getVaultSecret(db, authority.secretName);\n if (!secret) return json({ error: \"unauthorized\" }, 401);\n const verified = await verifyFederatedRequest(req, { secret, senders: [authority.sourceId] });\n if (!verified.ok) return json({ error: \"unauthorized\", reason: verified.reason }, 401);\n let input: Record<string, unknown>;\n try {\n input = JSON.parse(verified.body) as Record<string, unknown>;\n } catch {\n return reject(\"invalid_document\", 400, [\"request body must be JSON\"]);\n }\n const digest = typeof input.digest === \"string\" ? input.digest : \"\";\n const checked = validateAdmissionGrantDocument(input.document);\n if (!checked.ok) return reject(\"invalid_document\", 400, checked.errors);\n const document = checked.value;\n if (document.source.appId !== authority.sourceId) return reject(\"wrong_source\", 403);\n if (document.target.chapterId !== ctx.chapter.id) return reject(\"wrong_target\", 409);\n if (document.target.environment !== env.ODLA_ENV) return reject(\"wrong_environment\", 409);\n if (!digest || await signupControlDigest(document) !== digest) return reject(\"invalid_digest\", 400);\n const latest = await loadLatestAdmissionRevision(db, authority.sourceId, ctx.chapter.id, env.ODLA_ENV);\n if (latest && document.revision < latest.revision) return reject(\"stale_revision\", 409);\n if (latest && document.revision === latest.revision) {\n if (latest.digest !== digest) return reject(\"conflicting_revision\", 409);\n return json({\n ok: true,\n target: { chapterId: ctx.chapter.id, environment: env.ODLA_ENV },\n revision: latest.revision,\n digest: latest.digest,\n status: \"replayed\",\n acknowledgedAt: latest.receivedAt,\n });\n }\n const receivedAt = Date.now();\n try {\n await materializeAdmissionGrants(db, { digest, document } as AdmissionGrantEnvelope, latest, receivedAt);\n } catch {\n return reject(\"materialization_failed\", 503);\n }\n return json({\n ok: true,\n target: { chapterId: ctx.chapter.id, environment: env.ODLA_ENV },\n revision: document.revision,\n digest,\n status: \"accepted\",\n acknowledgedAt: receivedAt,\n });\n};\n","import { isValidEmail } from \"./member\";\nimport { normalizeChapterEmail } from \"./email-identity\";\nimport { json } from \"./worker-context\";\nimport type { Route } from \"./worker-context\";\nimport type { ChapterDb } from \"./types\";\n\nasync function gate(req: Request, env: Parameters<Route>[2], ctx: Parameters<Route>[3]) {\n const rawDb = ctx.makeDb(env);\n const user = await ctx.verifyUser(req, env);\n if (!user) return json({ error: \"unauthorized\" }, 401);\n if (!(await ctx.isAdmin(rawDb, user))) return json({ error: \"forbidden\" }, 403);\n return { db: rawDb as unknown as ChapterDb, user };\n}\n\n/** Chapter-admin list/create/revoke surface for local admission decisions. */\nexport const handleAdminAdmissionGrants: Route = async (req, url, env, ctx) => {\n if (url.pathname === \"/api/admin/admission-grants\" && req.method === \"GET\") {\n const auth = await gate(req, env, ctx);\n if (auth instanceof Response) return auth;\n const result = await auth.db.query({ admissionGrants: { $: {\n where: { targetId: ctx.chapter.id }, order: { createdAt: \"desc\" }, limit: 500,\n } } });\n const grants = Array.isArray(result.admissionGrants)\n ? result.admissionGrants.map((row) => ({ ...row, emailNormalized: undefined }))\n : [];\n return json({ grants });\n }\n\n if (url.pathname === \"/api/admin/admission-grants\" && req.method === \"POST\") {\n const auth = await gate(req, env, ctx);\n if (auth instanceof Response) return auth;\n let body: Record<string, unknown>;\n try {\n body = JSON.parse(await req.text()) as Record<string, unknown>;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n const email = typeof body.email === \"string\" ? body.email.trim() : \"\";\n const emailNormalized = normalizeChapterEmail(email);\n if (!isValidEmail(emailNormalized)) return json({ error: \"email must be valid\" }, 400);\n const decision = body.decision ?? \"waive_interview\";\n if (decision !== \"waive_interview\" && decision !== \"require_interview\") {\n return json({ error: \"decision must be waive_interview or require_interview\" }, 400);\n }\n const note = typeof body.note === \"string\" ? body.note.trim() : \"\";\n if (note.length > 2_000) return json({ error: \"note is too long\" }, 400);\n const expiresAt = body.expiresAt === undefined || body.expiresAt === null\n ? undefined\n : Number(body.expiresAt);\n if (expiresAt !== undefined && (!Number.isFinite(expiresAt) || expiresAt <= Date.now())) {\n return json({ error: \"expiresAt must be a future epoch timestamp\" }, 400);\n }\n const sourceGrantId = crypto.randomUUID();\n const id = `admission:local:${ctx.chapter.id}:${sourceGrantId}`;\n const createdAt = Date.now();\n const actor = auth.user.email ?? auth.user.userId;\n await auth.db.transact([{ t: \"update\", ns: \"admissionGrants\", id, attrs: {\n id,\n sourceGrantId,\n sourceScope: \"local\",\n sourceId: ctx.chapter.id,\n targetId: ctx.chapter.id,\n email,\n emailNormalized,\n decision,\n ...(note ? { note } : {}),\n ...(expiresAt !== undefined ? { expiresAt } : {}),\n active: true,\n createdAt,\n createdBy: actor,\n updatedAt: createdAt,\n updatedBy: actor,\n } }], { mutationId: `admission-local-create:${sourceGrantId}` });\n return json({ grant: { id, sourceGrantId, sourceScope: \"local\", email, decision, active: true, createdAt, ...(note ? { note } : {}), ...(expiresAt ? { expiresAt } : {}) } }, 201);\n }\n\n const prefix = \"/api/admin/admission-grants/\";\n let revokeId = \"\";\n if (url.pathname.startsWith(prefix)) {\n try {\n revokeId = decodeURIComponent(url.pathname.slice(prefix.length));\n } catch {\n revokeId = \"\";\n }\n }\n if (/^admission:local:[a-z0-9-]+:[0-9a-f-]+$/.test(revokeId) && req.method === \"DELETE\") {\n const auth = await gate(req, env, ctx);\n if (auth instanceof Response) return auth;\n const id = revokeId;\n const found = await auth.db.query({ admissionGrants: { $: { where: { id }, limit: 1 } } });\n const row = Array.isArray(found.admissionGrants) ? found.admissionGrants[0] : undefined;\n if (!row || row.targetId !== ctx.chapter.id || row.sourceScope !== \"local\") return json({ error: \"not found\" }, 404);\n if (row.active !== true) return json({ ok: true, replayed: true });\n const revokedAt = Date.now();\n const actor = auth.user.email ?? auth.user.userId;\n await auth.db.transact([{ t: \"update\", ns: \"admissionGrants\", id, attrs: {\n active: false,\n revokedAt,\n revokedBy: actor,\n updatedAt: revokedAt,\n updatedBy: actor,\n } }], { mutationId: `admission-local-revoke:${id}` });\n return json({ ok: true, replayed: false });\n }\n return null;\n};\n","// Scheduling routes: GET /api/schedule/slots + POST /api/schedule/book. This\n// file owns the I/O — Google FreeBusy, the pure computeBookableSlots, the\n// calendar create/reschedule, and the db writes — and delegates every\n// correctness rule to ./scheduling. Calendar is RUNTIME-optional: a chapter with\n// no connected calendar has freeBusy throw, so /slots answers\n// { schedulingReady: false } (200) and the join flow degrades to \"we'll reach\n// out by email\" rather than erroring.\nimport { crmDeps, syncApplicationToCrm } from \"./crm-sync\";\nimport { computeBookableSlots, initCalendar } from \"@odla-ai/calendar\";\nimport { emailGroupFrom, sendTemplated } from \"./notify\";\nimport { json } from \"./worker-context\";\nimport type { ChapterEnv, WorkerContext } from \"./worker-context\";\nimport type { Route } from \"./worker-routes\";\nimport type { ChapterDb, ChapterScheduling, DbOp } from \"./types\";\nimport { canBook } from \"./pipeline\";\nimport {\n applicationBookingUpdate,\n bookingDecision,\n endForSlot,\n introIdempotencyKey,\n isSlotAvailable,\n meetingCreateRow,\n meetingRescheduleUpdate,\n renderSummary,\n resolveScheduling,\n slotWindow,\n} from \"./scheduling\";\nimport type { ExistingMeeting, ResolvedScheduling } from \"./scheduling\";\n\ntype Cal = ReturnType<typeof initCalendar>;\ntype Row = Record<string, unknown>;\n\n/** The stable `.code` off an OdlaError/provider error, else a safe default. */\nfunction errCode(err: unknown): string {\n if (err && typeof err === \"object\") {\n const code = (err as { code?: unknown }).code;\n if (typeof code === \"string\") return code;\n }\n return \"calendar_unavailable\";\n}\n\nfunction makeCalendar(env: ChapterEnv): Cal {\n // Calendar uses ODLA_APP_ID + ODLA_PLATFORM — distinct from the db client's\n // ODLA_TENANT + ODLA_ENDPOINT.\n return initCalendar({ appId: env.ODLA_APP_ID, env: env.ODLA_ENV, adminToken: env.ODLA_API_KEY, endpoint: env.ODLA_PLATFORM });\n}\n\nasync function firstRow(db: ChapterDb, ns: string, q: Record<string, unknown>): Promise<Row | undefined> {\n const res = await db.query({ [ns]: { $: q } });\n const rows = res[ns];\n return Array.isArray(rows) ? rows[0] : undefined;\n}\n\nasync function computeSlots(cal: Cal, cfg: ResolvedScheduling): Promise<Array<{ startAt: number; endAt: number }>> {\n const { from, to } = slotWindow(Date.now(), cfg.windowDays);\n const fb = await cal.availability.freeBusy({ timeMin: from, timeMax: to });\n return computeBookableSlots(fb.busy, {\n from: fb.timeMin,\n to: fb.timeMax,\n timezone: cfg.timezone,\n slotMinutes: cfg.slotMinutes,\n businessHours: { days: [...cfg.days], startHour: cfg.startHour, endHour: cfg.endHour },\n minNoticeMs: cfg.minNoticeHours * 3_600_000,\n });\n}\n\nasync function bookSlot(req: Request, env: ChapterEnv, ctx: WorkerContext): Promise<Response> {\n let body: Row;\n try {\n body = JSON.parse(await req.text()) as Row;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n const applicationId = typeof body.applicationId === \"string\" ? body.applicationId : \"\";\n const startAt = Number(body.startAt);\n if (!applicationId || !Number.isFinite(startAt)) return json({ error: \"applicationId and startAt required\" }, 400);\n\n const db = ctx.makeDb(env) as unknown as ChapterDb;\n const app = await firstRow(db, \"applications\", { where: { id: applicationId }, limit: 1 });\n if (!app) return json({ error: \"not found\" }, 404);\n const status = String(app.status ?? \"\");\n if (!canBook(status, ctx.chapter.pipeline)) return json({ error: `cannot book from status \"${status}\"` }, 409);\n\n const group = await firstRow(db, \"groups\", { where: { id: String(app.groupId ?? ctx.chapter.id) }, limit: 1 });\n if (!group) return json({ error: \"group not found\" }, 500);\n const cfg = resolveScheduling(group.schedulingJson as ChapterScheduling | undefined);\n const endAt = endForSlot(startAt, cfg.slotMinutes);\n const cal = makeCalendar(env);\n\n // Double-book guard, layer 1: the requested start must still be a live slot.\n let slots: Array<{ startAt: number }>;\n try {\n slots = await computeSlots(cal, cfg);\n } catch (err) {\n return json({ error: \"scheduling unavailable\", code: errCode(err) }, 503);\n }\n if (!isSlotAvailable(slots, startAt)) return json({ error: \"slot no longer available\", code: \"calendar_slot_unavailable\" }, 409);\n\n const summary = renderSummary(cfg.summaryTemplate, { firstName: app.firstName as string, lastName: app.lastName as string });\n const existing = (await firstRow(db, \"meetings\", {\n where: { applicationId, status: \"scheduled\" },\n order: { createdAt: \"desc\" },\n limit: 1,\n })) as ExistingMeeting | undefined;\n const decision = bookingDecision(existing);\n\n let meetUrl: string | null = null;\n let htmlLink: string | null = null;\n let meetingOp: DbOp;\n try {\n if (decision.reschedule && decision.eventId) {\n // Reschedule the SAME event — the Meet link + invite thread survive.\n await cal.actions.reschedule(decision.eventId, {\n idempotencyKey: `meeting:${String(existing?.id)}:reschedule:${startAt}:${endAt}`,\n startAt,\n endAt,\n });\n meetUrl = (existing?.meetUrl as string | undefined) ?? null;\n htmlLink = (existing?.htmlLink as string | undefined) ?? null;\n meetingOp = { t: \"update\", ns: \"meetings\", id: String(existing?.id), attrs: meetingRescheduleUpdate(startAt, endAt) };\n } else {\n const { booking } = await cal.actions.create(\n { summary, startAt, endAt, attendees: [String(app.email)], timezone: cfg.timezone, meet: true },\n { idempotencyKey: introIdempotencyKey(applicationId) },\n );\n meetUrl = booking.meetUrl ?? null;\n htmlLink = booking.htmlLink ?? null;\n const meetingId = crypto.randomUUID();\n meetingOp = {\n t: \"update\",\n ns: \"meetings\",\n id: meetingId,\n attrs: meetingCreateRow({\n meetingId,\n applicationId,\n groupId: String(group.id),\n startAt,\n endAt,\n timezone: cfg.timezone,\n googleEventId: booking.eventId,\n meetUrl: booking.meetUrl,\n htmlLink: booking.htmlLink,\n createdAt: Date.now(),\n }),\n };\n }\n } catch (err) {\n const code = errCode(err);\n // Double-book guard, layer 2 (authoritative): the provider rejected under lease.\n if (code === \"calendar_slot_unavailable\") return json({ error: \"slot no longer available\", code }, 409);\n return json({ error: \"booking failed\", code }, 502);\n }\n\n // meetings row is canonical; the application row is the projection.\n const bookingAttrs = applicationBookingUpdate(status, startAt, htmlLink);\n const appOp: DbOp = { t: \"update\", ns: \"applications\", id: applicationId, attrs: bookingAttrs };\n await db.transact([meetingOp, appOp]);\n\n // Booking is the other status transition that happens with no admin present.\n // The console reads its pipeline from crm_record.stage, so skipping the\n // mirror here leaves a booked applicant reading as merely submitted.\n // Best-effort: the member has already seen the booking confirmed.\n const booked = { ...app, ...bookingAttrs };\n await syncApplicationToCrm(crmDeps(db, ctx), { app: booked, stage: String(booked.status ?? \"\") }).catch(() => undefined);\n\n // Prep email — best-effort, exactly-once per application (never fails the booking).\n if (typeof app.email === \"string\" && app.email) {\n await sendTemplated(\n { db, envName: env.ODLA_ENV, sender: env.SEND_EMAIL, from: env.EMAIL_FROM, now: () => Date.now(), newId: () => crypto.randomUUID() },\n { group: emailGroupFrom(group), template: \"prepEmail\", to: app.email, vars: { firstName: String(app.firstName ?? \"\") }, dedupeKey: `prep:${applicationId}`, applicationId },\n ).catch(() => undefined);\n }\n\n return json({ ok: true, startAt, endAt, meetUrl, rescheduled: decision.reschedule });\n}\n\n/** GET /api/schedule/slots + POST /api/schedule/book (chapter mode only). */\nexport const handleSchedule: Route = async (req, url, env, ctx) => {\n if (ctx.chapter.mode !== \"chapter\") return null;\n\n if (req.method === \"GET\" && url.pathname === \"/api/schedule/slots\") {\n const db = ctx.makeDb(env) as unknown as ChapterDb;\n const group = await firstRow(db, \"groups\", { where: { id: url.searchParams.get(\"group\") ?? ctx.chapter.id }, limit: 1 });\n if (!group) return json({ error: \"not found\" }, 404);\n const cfg = resolveScheduling(group.schedulingJson as ChapterScheduling | undefined);\n try {\n const slots = await computeSlots(makeCalendar(env), cfg);\n return json({ schedulingReady: true, timezone: cfg.timezone, slotMinutes: cfg.slotMinutes, slots });\n } catch (err) {\n return json({ schedulingReady: false, code: errCode(err) });\n }\n }\n\n if (req.method === \"POST\" && url.pathname === \"/api/schedule/book\") {\n return bookSlot(req, env, ctx);\n }\n\n return null;\n};\n","// Payments primitives. Generic Stripe form encoding and webhook authenticity\n// live in @odla-ai/stripe; Chapter keeps only membership-specific readiness,\n// event normalization, and write sets. This preserves Chapter's public exports\n// while making the provider plumbing reusable by every app.\nexport { stripeForm, verifyStripeSignature } from \"@odla-ai/stripe\";\n\n// ── readiness + Stripe wire helpers ──\n\n/** A group row's payment configuration, as far as readiness cares. */\nexport interface PaymentsGroup {\n stripePublishableKey?: string | null;\n stripePriceId?: string | null;\n}\n\n/** Whether a group can take payment: a publishable key + a price id (both on the\n * group row) AND a secret key (the vault). Anything missing drops the join\n * flow's payment step (paymentsReady:false) rather than half-charging. */\nexport function paymentsReady(group: PaymentsGroup, hasSecretKey: boolean): boolean {\n return Boolean(group.stripePublishableKey && group.stripePriceId && hasSecretKey);\n}\n\n/** The Stripe idempotency key for creating an application's subscription — one\n * per application, so a client retry can't orphan a second subscription. */\nexport function subscriptionIdempotencyKey(applicationId: string): string {\n return `sub:${applicationId}`;\n}\n\n/** The db mutationId for a webhook-driven write — exactly-once per Stripe event,\n * so replays are deduped at the db layer. */\nexport function webhookMutationId(eventId: string): string {\n return `stripe:${eventId}`;\n}\n\n// ── webhook normalization (pure; the worker owns the db lookup + writes) ──\n\n/** A raw Stripe event, as far as normalization cares. */\nexport interface StripeEvent {\n id: string;\n type: string;\n data?: { object?: Record<string, unknown> };\n}\n\n/** A normalized, provider-agnostic webhook event. `kind` drives the db write;\n * the application is resolved from `applicationId` (metadata) or `customerId`. */\nexport type WebhookEvent = (\n | { kind: \"gift_paid\"; giftIntentId: string; providerObjectId: string }\n | { kind: \"gift_revoked\"; giftIntentId: string; reason: \"refunded\" | \"canceled\" }\n | { kind: \"first_payment\"; applicationId?: string; customerId?: string; renewalAt?: number }\n | { kind: \"renewal\"; applicationId?: string; customerId?: string; renewalAt?: number }\n | { kind: \"refunded\"; applicationId?: string; customerId?: string }\n | { kind: \"canceled\"; applicationId?: string; customerId?: string }\n | { kind: \"ignored\"; type: string }\n) & { appId?: string; environment?: string };\n\n/** Resolve the application reference on a Stripe object: `applicationId` from\n * metadata (direct, then subscription_details, then nested\n * parent.subscription_details), plus the customer id for the db fallback. */\nexport function findApplicationRef(obj: Record<string, unknown>): {\n applicationId?: string;\n customerId?: string;\n appId?: string;\n environment?: string;\n} {\n const metaOf = (v: unknown): Record<string, unknown> =>\n v && typeof v === \"object\" ? ((v as Record<string, unknown>).metadata as Record<string, unknown>) ?? {} : {};\n const pick = (m: Record<string, unknown>): string | undefined =>\n typeof m.applicationId === \"string\" ? m.applicationId : undefined;\n const candidates = [\n metaOf(obj),\n metaOf(obj.subscription_details),\n metaOf((obj.parent as Record<string, unknown> | undefined)?.subscription_details),\n ];\n const applicationId = candidates.map(pick).find(Boolean);\n const appId = candidates.map((metadata) => typeof metadata.odlaAppId === \"string\" ? metadata.odlaAppId : undefined).find(Boolean);\n const environment = candidates.map((metadata) => typeof metadata.odlaEnvironment === \"string\" ? metadata.odlaEnvironment : undefined).find(Boolean);\n const customerId = typeof obj.customer === \"string\" ? obj.customer : undefined;\n return {\n ...(applicationId ? { applicationId } : {}),\n ...(customerId ? { customerId } : {}),\n ...(appId ? { appId } : {}),\n ...(environment ? { environment } : {}),\n };\n}\n\n/** Resolve gift purchase metadata from direct or invoice subscription metadata. */\nexport function findGiftRef(obj: Record<string, unknown>): { giftIntentId?: string; providerObjectId: string } {\n const metaOf = (value: unknown): Record<string, unknown> =>\n value && typeof value === \"object\" ? ((value as Record<string, unknown>).metadata as Record<string, unknown>) ?? {} : {};\n const pick = (metadata: Record<string, unknown>): string | undefined =>\n typeof metadata.giftIntentId === \"string\" ? metadata.giftIntentId : undefined;\n const parent = obj.parent as Record<string, unknown> | undefined;\n const subscription = obj.subscription_details ?? parent?.subscription_details;\n const giftIntentId = pick(metaOf(obj)) ?? pick(metaOf(subscription));\n const subscriptionId = typeof obj.subscription === \"string\"\n ? obj.subscription\n : typeof (subscription as Record<string, unknown> | undefined)?.subscription === \"string\"\n ? String((subscription as Record<string, unknown>).subscription)\n : undefined;\n return { ...(giftIntentId ? { giftIntentId } : {}), providerObjectId: subscriptionId ?? String(obj.id ?? \"\") };\n}\n\n/** Normalize a verified Stripe event into a {@link WebhookEvent}. `invoice.paid`\n * splits into first_payment vs renewal by `billing_reason`; refunds and\n * cancellations map directly; everything else is ignored (acked, not retried). */\nexport function normalizeWebhookEvent(event: StripeEvent): WebhookEvent {\n const obj = event.data?.object ?? {};\n const gift = findGiftRef(obj);\n if (gift.giftIntentId) {\n if (event.type === \"payment_intent.succeeded\" ||\n (event.type === \"invoice.paid\" && obj.billing_reason === \"subscription_create\")) {\n return { kind: \"gift_paid\", giftIntentId: gift.giftIntentId, providerObjectId: gift.providerObjectId };\n }\n if (event.type === \"charge.refunded\") return { kind: \"gift_revoked\", giftIntentId: gift.giftIntentId, reason: \"refunded\" };\n if (event.type === \"customer.subscription.deleted\") return { kind: \"gift_revoked\", giftIntentId: gift.giftIntentId, reason: \"canceled\" };\n return { kind: \"ignored\", type: event.type };\n }\n const ref = findApplicationRef(obj);\n switch (event.type) {\n case \"invoice.paid\": {\n const lines = ((obj.lines as Record<string, unknown> | undefined)?.data as Array<Record<string, unknown>> | undefined) ?? [];\n const periodEnd = (lines[0]?.period as Record<string, unknown> | undefined)?.end;\n const renewalAt = typeof periodEnd === \"number\" ? periodEnd * 1000 : undefined;\n const kind = obj.billing_reason === \"subscription_create\" ? \"first_payment\" : \"renewal\";\n return { kind, ...ref, ...(renewalAt !== undefined ? { renewalAt } : {}) };\n }\n case \"charge.refunded\":\n return { kind: \"refunded\", ...ref };\n case \"customer.subscription.deleted\":\n return { kind: \"canceled\", ...ref };\n default:\n return { kind: \"ignored\", type: event.type };\n }\n}\n\n// ── webhook write-set builders (the authoritative writers of paid/refunded) ──\n\n/** First-payment patch: advance submitted→paid_pending_vetting (never any other\n * transition) and record the renewal date. Empty when nothing changed, so the\n * caller can skip the write. */\nexport function firstPaymentPatch(currentStatus: string, renewalAt?: number): { status?: \"paid_pending_vetting\"; renewalAt?: number } {\n return {\n ...(currentStatus === \"submitted\" ? { status: \"paid_pending_vetting\" as const } : {}),\n ...(renewalAt !== undefined ? { renewalAt } : {}),\n };\n}\n\n/** Renewal-invoice patch: just the new renewal date. */\nexport function renewalPatch(renewalAt: number): { renewalAt: number } {\n return { renewalAt };\n}\n\n/** Refund patch — the SOLE writer of status \"refunded\" (the admin refund route\n * issues the Stripe refund but never sets this; the webhook does). */\nexport function refundedPatch(): { status: \"refunded\" } {\n return { status: \"refunded\" };\n}\n\n/** Subscription-cancellation patch. */\nexport function canceledPatch(): { canceled: true } {\n return { canceled: true };\n}\n","// The Stripe payments provider — the only I/O half of payments. Talks to the\n// Stripe REST API over @odla-ai/stripe's fetch transport, and maps 1:1 onto the\n// membership-specific event normalization in ./payments. The worker\n// resolves secrets from the vault per request and constructs this; the routes own\n// every db write so idempotency stays at the db layer.\nimport { stripeRequest, verifyStripeSignature, type StripeRequestResult } from \"@odla-ai/stripe\";\nimport { normalizeWebhookEvent } from \"./payments\";\nimport type { StripeEvent, WebhookEvent } from \"./payments\";\n\n/** Inputs to create an application's founding-member subscription. */\nexport interface CreateSubscriptionInput {\n appId: string;\n environment: string;\n applicationId: string;\n groupId: string;\n email: string;\n name: string;\n priceId: string;\n existingCustomerId?: string;\n}\n\n/** The client secret to confirm card entry, plus the ids to persist. */\nexport interface CreateSubscriptionResult {\n customerId: string;\n subscriptionId: string;\n clientSecret: string;\n}\n\n/** The outcome of a full refund. */\nexport interface RefundResult {\n refundedCents: number | null;\n subscriptionCanceled: boolean;\n}\n\n/** The capabilities the payment routes depend on — Stripe is one impl. */\nexport interface PaymentsProvider {\n createSubscription(input: CreateSubscriptionInput): Promise<CreateSubscriptionResult>;\n ingestWebhook(\n rawBody: string,\n sigHeader: string,\n ): Promise<{ ok: true; eventId: string; event: WebhookEvent } | { ok: false; reason: \"bad_signature\" }>;\n refund(input: { customerId: string; subscriptionId: string }): Promise<RefundResult>;\n}\n\n/** The result of a Stripe Backend API call: ok + status + parsed JSON body. */\nexport type StripeResult = StripeRequestResult<Record<string, unknown>>;\n\n/** Call the Stripe Backend API (form-encoded, Bearer sk_). Exposed so the admin\n * billing/dashboard reads and the refund route share one Stripe client instead\n * of each re-deriving the auth + encoding. */\nexport async function stripeCall(\n sk: string,\n method: \"GET\" | \"POST\" | \"DELETE\",\n path: string,\n params?: Record<string, unknown>,\n idempotencyKey?: string,\n): Promise<StripeResult> {\n return stripeRequest(\n { secretKey: sk },\n method,\n path,\n params,\n idempotencyKey ? { idempotencyKey } : {},\n );\n}\n\nfunction fail(op: string, r: StripeResult): never {\n const err = new Error(`stripe ${op} failed: ${r.status}`) as Error & { code: string };\n err.code = \"stripe_error\";\n throw err;\n}\n\nfunction clientSecretOf(sub: Record<string, unknown>): string | undefined {\n const inv = sub.latest_invoice as Record<string, unknown> | undefined;\n const confirmation = inv?.confirmation_secret as Record<string, unknown> | undefined;\n const intent = inv?.payment_intent as Record<string, unknown> | undefined;\n const secret = confirmation?.client_secret ?? intent?.client_secret;\n return typeof secret === \"string\" ? secret : undefined;\n}\n\nfunction requireSecret(secretKey: string | undefined): string {\n if (!secretKey) {\n const err = new Error(\"stripe secret key missing\") as Error & { code: string };\n err.code = \"not_configured\";\n throw err;\n }\n return secretKey;\n}\n\n/** Build the Stripe provider. `secretKey` powers charging/refunds; `webhookSecret`\n * powers webhook ingest. Each is resolved from the vault per request, so the\n * webhook route can construct an ingest-only provider without the secret key. */\nexport function createStripeProvider(config: { secretKey?: string; webhookSecret?: string }): PaymentsProvider {\n const { secretKey, webhookSecret } = config;\n return {\n async createSubscription(input) {\n const sk = requireSecret(secretKey);\n const meta = {\n applicationId: input.applicationId,\n groupId: input.groupId,\n email: input.email,\n odlaAppId: input.appId,\n odlaEnvironment: input.environment,\n };\n let customerId = input.existingCustomerId;\n if (!customerId) {\n const cust = await stripeCall(\n sk,\n \"POST\",\n \"/v1/customers\",\n { email: input.email, name: input.name, metadata: meta },\n `cus:${input.applicationId}`,\n );\n if (!cust.ok) fail(\"customer create\", cust);\n customerId = String(cust.body.id);\n }\n const sub = await stripeCall(\n sk,\n \"POST\",\n \"/v1/subscriptions\",\n {\n customer: customerId,\n \"items[0][price]\": input.priceId,\n payment_behavior: \"default_incomplete\",\n \"payment_settings[save_default_payment_method]\": \"on_subscription\",\n \"payment_settings[payment_method_types][0]\": \"card\",\n \"expand[0]\": \"latest_invoice.confirmation_secret\",\n metadata: meta,\n },\n // Hardening: one subscription per application, so a client\n // retry between create and the db write can't orphan a second one.\n `sub:${input.applicationId}`,\n );\n if (!sub.ok) fail(\"subscription create\", sub);\n const clientSecret = clientSecretOf(sub.body);\n if (!clientSecret) fail(\"subscription confirmation-secret missing\", sub);\n return { customerId, subscriptionId: String(sub.body.id), clientSecret };\n },\n\n async ingestWebhook(rawBody, sigHeader) {\n if (!webhookSecret || !(await verifyStripeSignature(rawBody, sigHeader, webhookSecret))) {\n return { ok: false, reason: \"bad_signature\" };\n }\n const event = JSON.parse(rawBody) as StripeEvent;\n return { ok: true, eventId: event.id, event: normalizeWebhookEvent(event) };\n },\n\n async refund(input) {\n const sk = requireSecret(secretKey);\n const charges = await stripeCall(sk, \"GET\", \"/v1/charges\", { customer: input.customerId, limit: 100 });\n if (!charges.ok) fail(\"charges list\", charges);\n const rows = (charges.body.data as Array<Record<string, unknown>> | undefined) ?? [];\n const paid = rows.filter((c) => c.status === \"succeeded\" && c.refunded !== true);\n const charge = paid[paid.length - 1]; // Stripe returns newest-first; refund the earliest.\n if (!charge) {\n const err = new Error(\"no paid charge to refund\") as Error & { code: string };\n err.code = \"no_charge\";\n throw err;\n }\n const refund = await stripeCall(sk, \"POST\", \"/v1/refunds\", { charge: String(charge.id) });\n if (!refund.ok) fail(\"refund\", refund);\n const cancel = await stripeCall(sk, \"DELETE\", `/v1/subscriptions/${input.subscriptionId}`);\n const amount = refund.body.amount;\n return { refundedCents: typeof amount === \"number\" ? amount : null, subscriptionCanceled: cancel.ok };\n },\n };\n}\n","/** Stored hash format version for high-entropy gift claim codes. */\nexport const GIFT_CODE_VERSION = 1 as const;\nexport const GIFT_CODE_BYTES = 32;\n\nconst base64url = (bytes: Uint8Array): string => {\n let binary = \"\";\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return btoa(binary).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/g, \"\");\n};\n\n/** Generate a 256-bit bearer code. Plaintext must be displayed once and discarded. */\nexport function createGiftCode(): string {\n const bytes = new Uint8Array(GIFT_CODE_BYTES);\n crypto.getRandomValues(bytes);\n return `gift${GIFT_CODE_VERSION}_${base64url(bytes)}`;\n}\n\n/** Hash a claim code with its Chapter and format version domain separation. */\nexport async function hashGiftCode(chapterId: string, code: string, version = GIFT_CODE_VERSION): Promise<string> {\n const bytes = new TextEncoder().encode(`odla-gift:${version}:${chapterId}:${code}`);\n return base64url(new Uint8Array(await crypto.subtle.digest(\"SHA-256\", bytes)));\n}\n\n/** Stable non-secret requester bucket hash used only for redemption rate limits. */\nexport async function giftRequesterBucket(chapterId: string, requester: string): Promise<string> {\n const bytes = new TextEncoder().encode(`odla-gift-rate:${chapterId}:${requester}`);\n return base64url(new Uint8Array(await crypto.subtle.digest(\"SHA-256\", bytes))).slice(0, 32);\n}\n","import type { GiftOffer, GiftOfferTarget } from \"./gift-offers\";\nimport { createGiftCode, GIFT_CODE_VERSION, hashGiftCode } from \"./gift-codes\";\nimport { normalizeChapterEmail } from \"./email-identity\";\nimport type { ChapterDb, DbOp } from \"./types\";\n\ntype Row = Record<string, unknown>;\nconst first = (value: unknown): Row | undefined => Array.isArray(value) ? value[0] as Row | undefined : undefined;\n\n/** Persisted purchase intent subset required by provider webhook issuance. */\nexport interface GiftIntentRow extends Row {\n id: string; chapterId: string; environment: string; offerId: string; offerSnapshot: GiftOffer;\n purchaserType: \"application\" | \"member\"; purchaserEmailNormalized: string;\n codeHash: string; codeVersion: number; codeIssuedAt: number; status: string;\n purchaserApplicationId?: string; purchaserUserId?: string; providerObjectId?: string;\n}\n\n/** Safe buyer-facing claim state; hashes and beneficiary identity are deliberately absent. */\nexport interface BuyerGiftClaim {\n id: string; offerId: string; status: \"pending\" | \"redeemed\" | \"expired\" | \"revoked\";\n createdAt: number; codeExpiresAt: number; redeemedAt?: number; revokedAt?: number;\n}\n\n/** Create a code/hash pair for a new or rotated claim. */\nexport async function prepareGiftCode(chapterId: string): Promise<{ code: string; codeHash: string; codeVersion: number }> {\n const code = createGiftCode();\n return { code, codeHash: await hashGiftCode(chapterId, code), codeVersion: GIFT_CODE_VERSION };\n}\n\n/** Issue exactly one immutable order and pending claim from a verified provider success. */\nexport async function issueGiftClaim(\n db: ChapterDb,\n intent: GiftIntentRow,\n provider: { eventId: string; objectId: string },\n now: number,\n): Promise<{ claimId: string; orderId: string; duplicate: boolean }> {\n const existing = first((await db.query({ giftClaims: { $: { where: { intentId: intent.id }, limit: 1 } } })).giftClaims);\n if (existing) return { claimId: String(existing.id), orderId: String(existing.orderId), duplicate: true };\n const offer = intent.offerSnapshot;\n const orderId = `gift-order:${intent.id}`;\n const claimId = `gift-claim:${intent.id}`;\n const shared = {\n chapterId: intent.chapterId, offerId: intent.offerId,\n ...(intent.purchaserApplicationId ? { purchaserApplicationId: intent.purchaserApplicationId } : {}),\n ...(intent.purchaserUserId ? { purchaserUserId: intent.purchaserUserId } : {}),\n purchaserEmailNormalized: intent.purchaserEmailNormalized,\n };\n const ops: DbOp[] = [\n { t: \"update\", ns: \"giftOrders\", id: orderId, attrs: {\n id: orderId, intentId: intent.id, ...shared, environment: intent.environment,\n offerSnapshot: offer, purchaserType: intent.purchaserType, providerEventId: provider.eventId,\n providerObjectId: provider.objectId, amountCents: offer.priceCents, currency: offer.currency,\n billingMode: offer.billingMode, createdAt: now,\n } },\n { t: \"update\", ns: \"giftClaims\", id: claimId, attrs: {\n id: claimId, orderId, intentId: intent.id, ...shared, target: offer.target,\n codeHash: intent.codeHash, codeVersion: intent.codeVersion, rotationCount: 0, codeIssuedAt: intent.codeIssuedAt,\n codeExpiresAt: now + offer.redemptionLifetimeHours * 3_600_000,\n attemptCount: 0, attemptWindowStartedAt: now, status: \"pending\", createdAt: now,\n } },\n { t: \"update\", ns: \"giftPurchaseIntents\", id: intent.id, attrs: { status: \"paid\", paidAt: now, claimId, updatedAt: now } },\n ];\n if (intent.purchaserApplicationId) ops.push({\n t: \"update\", ns: \"applications\", id: intent.purchaserApplicationId,\n attrs: { giftPaidAt: now, giftClaimId: claimId },\n });\n try {\n const result = await db.transact(ops, {\n mutationId: `gift-paid:${provider.eventId}`,\n guards: [{ ns: \"giftPurchaseIntents\", id: intent.id, exists: true, equals: { status: \"checkout_ready\" } }],\n });\n return { claimId, orderId, duplicate: result.duplicate };\n } catch {\n const raced = first((await db.query({ giftClaims: { $: { where: { intentId: intent.id }, limit: 1 } } })).giftClaims);\n if (raced) return { claimId: String(raced.id), orderId: String(raced.orderId), duplicate: true };\n throw new Error(\"gift issuance conflict\");\n }\n}\n\n/** Project claims for their buyer without code hashes or beneficiary PII. */\nexport function buyerGiftClaims(rows: readonly Row[], now: number): BuyerGiftClaim[] {\n return rows.map((row) => {\n const stored = String(row.status ?? \"pending\") as BuyerGiftClaim[\"status\"];\n const status = stored === \"pending\" && Number(row.codeExpiresAt) <= now ? \"expired\" : stored;\n return {\n id: String(row.id), offerId: String(row.offerId), status,\n createdAt: Number(row.createdAt), codeExpiresAt: Number(row.codeExpiresAt),\n ...(typeof row.redeemedAt === \"number\" ? { redeemedAt: row.redeemedAt } : {}),\n ...(typeof row.revokedAt === \"number\" ? { revokedAt: row.revokedAt } : {}),\n };\n });\n}\n\n/** Rotate only a pending unexpired claim with compare-and-set semantics. */\nexport async function rotateGiftClaim(db: ChapterDb, claim: Row, now: number): Promise<{ code: string } | null> {\n if (claim.status !== \"pending\" || Number(claim.codeExpiresAt) <= now) return null;\n const prepared = await prepareGiftCode(String(claim.chapterId));\n const currentRotation = Number(claim.rotationCount ?? 0);\n try {\n const write = await db.transact([{ t: \"update\", ns: \"giftClaims\", id: String(claim.id), attrs: {\n codeHash: prepared.codeHash, codeVersion: prepared.codeVersion, rotationCount: currentRotation + 1, codeIssuedAt: now,\n rotatedAt: now, attemptCount: 0, attemptWindowStartedAt: now,\n } }], {\n mutationId: `gift-rotate:${String(claim.id)}:${currentRotation + 1}`,\n guards: [{ ns: \"giftClaims\", id: String(claim.id), exists: true, equals: { status: \"pending\", rotationCount: currentRotation } }],\n });\n return write.duplicate ? null : { code: prepared.code };\n } catch {\n return null;\n }\n}\n\nexport interface RedeemGiftResult { kind: \"application\" | \"entitlement\"; id: string }\n\n/** Atomically consume one claim and bind its beneficiary application or entitlement. */\nexport async function redeemGiftClaim(\n db: ChapterDb,\n claim: Row,\n beneficiary: { email: string; userId: string },\n now: number,\n): Promise<RedeemGiftResult | null> {\n if (claim.status !== \"pending\" || Number(claim.codeExpiresAt) <= now) return null;\n const chapterId = String(claim.chapterId);\n const emailNormalized = normalizeChapterEmail(beneficiary.email);\n const target = claim.target as GiftOfferTarget;\n const ops: DbOp[] = [];\n let result: RedeemGiftResult;\n if (target.type === \"tier\") {\n const apps = (await db.query({ applications: { $: { where: { emailNormalized }, limit: 20 } } })).applications;\n const existing = apps?.filter((row) => row.groupId === chapterId)\n .sort((a, b) => Number(b.createdAt ?? 0) - Number(a.createdAt ?? 0))[0];\n const id = existing ? String(existing.id) : `gift-application:${String(claim.id)}`;\n const status = existing && existing.status !== \"submitted\" ? String(existing.status) : \"paid_pending_vetting\";\n ops.push({ t: \"update\", ns: \"applications\", id, attrs: {\n id, groupId: chapterId, email: beneficiary.email, emailNormalized, tierId: target.tierId,\n status, giftClaimId: String(claim.id), giftOrderId: String(claim.orderId),\n clerkUserId: beneficiary.userId, ...(existing ? {} : { createdAt: now }),\n } });\n result = { kind: \"application\", id };\n } else {\n const id = `gift-entitlement:${String(claim.id)}`;\n ops.push({ t: \"update\", ns: \"giftEntitlements\", id, attrs: {\n id, claimId: String(claim.id), orderId: String(claim.orderId), chapterId,\n entitlementKey: target.entitlementKey, beneficiaryEmailNormalized: emailNormalized,\n beneficiaryUserId: beneficiary.userId, active: true, createdAt: now,\n } });\n result = { kind: \"entitlement\", id };\n }\n ops.unshift({ t: \"update\", ns: \"giftClaims\", id: String(claim.id), attrs: {\n status: \"redeemed\", redeemedAt: now, beneficiaryEmailNormalized: emailNormalized,\n beneficiaryUserId: beneficiary.userId,\n ...(result.kind === \"application\" ? { applicationId: result.id } : { entitlementId: result.id }),\n attemptCount: Number(claim.attemptCount ?? 0) + 1,\n } });\n try {\n await db.transact(ops, {\n mutationId: `gift-redeem:${String(claim.id)}:${beneficiary.userId}`,\n guards: [{ ns: \"giftClaims\", id: String(claim.id), exists: true, equals: {\n status: \"pending\", codeVersion: Number(claim.codeVersion), codeHash: String(claim.codeHash),\n } }],\n });\n return result;\n } catch {\n return null;\n }\n}\n\n/** Revoke a claim and any redeemed access after provider refund or cancellation. */\nexport async function revokeGiftClaim(db: ChapterDb, claim: Row, reason: \"refunded\" | \"canceled\", now: number): Promise<boolean> {\n if (claim.status === \"revoked\") return false;\n const ops: DbOp[] = [{ t: \"update\", ns: \"giftClaims\", id: String(claim.id), attrs: {\n status: \"revoked\", revokedAt: now, revokedReason: reason,\n } }];\n if (claim.entitlementId) ops.push({ t: \"update\", ns: \"giftEntitlements\", id: String(claim.entitlementId), attrs: { active: false, revokedAt: now } });\n if (claim.applicationId) ops.push({ t: \"update\", ns: \"applications\", id: String(claim.applicationId), attrs: {\n giftRevokedAt: now, ...(reason === \"refunded\" ? { status: \"refunded\" } : { canceled: true }),\n } });\n try {\n await db.transact(ops, {\n mutationId: `gift-revoke:${String(claim.id)}:${reason}`,\n guards: [{ ns: \"giftClaims\", id: String(claim.id), exists: true, equals: { status: String(claim.status) } }],\n });\n return true;\n } catch {\n return false;\n }\n}\n","import { stripeCall } from \"./payments-stripe\";\nimport type { GiftIntentRow } from \"./gift-store\";\n\nexport interface GiftCheckoutResult {\n clientSecret: string;\n providerObjectId: string;\n customerId?: string;\n}\n\nconst clientSecret = (value: Record<string, unknown>): string | null => {\n const direct = value.client_secret;\n if (typeof direct === \"string\" && direct) return direct;\n const invoice = value.latest_invoice as Record<string, unknown> | undefined;\n const confirmation = invoice?.confirmation_secret as Record<string, unknown> | undefined;\n const intent = invoice?.payment_intent as Record<string, unknown> | undefined;\n const nested = confirmation?.client_secret ?? intent?.client_secret;\n return typeof nested === \"string\" && nested ? nested : null;\n};\n\n/** Create or idempotently recover Stripe checkout for one gift purchase intent. */\nexport async function startGiftProviderCheckout(\n secretKey: string,\n intent: GiftIntentRow,\n email: string,\n existingCustomerId?: string,\n): Promise<GiftCheckoutResult> {\n const offer = intent.offerSnapshot;\n const metadata = {\n giftIntentId: intent.id,\n chapterId: intent.chapterId,\n environment: intent.environment,\n offerId: intent.offerId,\n };\n let customerId = existingCustomerId;\n if (!customerId) {\n const customer = await stripeCall(secretKey, \"POST\", \"/v1/customers\", { email, metadata }, `gift-customer:${intent.id}`);\n if (!customer.ok) throw new Error(`gift customer create failed (${customer.status})`);\n customerId = String(customer.body.id);\n }\n if (offer.billingMode === \"subscription\") {\n const created = await stripeCall(secretKey, \"POST\", \"/v1/subscriptions\", {\n customer: customerId,\n \"items[0][price]\": offer.stripePriceId,\n payment_behavior: \"default_incomplete\",\n \"payment_settings[save_default_payment_method]\": \"on_subscription\",\n \"payment_settings[payment_method_types][0]\": \"card\",\n \"expand[0]\": \"latest_invoice.confirmation_secret\",\n metadata,\n }, `gift-subscription:${intent.id}`);\n const secret = created.ok ? clientSecret(created.body) : null;\n if (!created.ok || !secret) throw new Error(`gift subscription create failed (${created.status})`);\n return { clientSecret: secret, providerObjectId: String(created.body.id), customerId };\n }\n const price = await stripeCall(secretKey, \"GET\", `/v1/prices/${encodeURIComponent(offer.stripePriceId)}`);\n if (!price.ok || price.body.active === false || price.body.unit_amount !== offer.priceCents || price.body.currency !== offer.currency) {\n throw new Error(\"gift price does not match the signed offer\");\n }\n const created = await stripeCall(secretKey, \"POST\", \"/v1/payment_intents\", {\n customer: customerId,\n amount: offer.priceCents,\n currency: offer.currency,\n \"automatic_payment_methods[enabled]\": true,\n metadata,\n }, `gift-payment:${intent.id}`);\n const secret = created.ok ? clientSecret(created.body) : null;\n if (!created.ok || !secret) throw new Error(`gift payment create failed (${created.status})`);\n return { clientSecret: secret, providerObjectId: String(created.body.id), customerId };\n}\n","import type { GiftOffer } from \"./gift-offers\";\nimport { prepareGiftCode, type GiftIntentRow } from \"./gift-store\";\nimport { startGiftProviderCheckout } from \"./gift-checkout\";\nimport type { ChapterDb } from \"./types\";\n\nconst first = (value: unknown): Record<string, unknown> | undefined => Array.isArray(value) ? value[0] : undefined;\n\nexport interface StartGiftIntentInput {\n id: string;\n chapterId: string;\n environment: string;\n offer: GiftOffer;\n purchaserType: \"application\" | \"member\";\n purchaserEmail: string;\n purchaserEmailNormalized: string;\n purchaserApplicationId?: string;\n purchaserUserId?: string;\n existingCustomerId?: string;\n stripeSecret: string;\n publishableKey: string;\n now: number;\n}\n\nexport interface StartedGiftIntent {\n gift: true;\n intentId: string;\n clientSecret: string;\n publishableKey: string;\n lineItems: { standardCents: number; discountCents: number; dueTodayCents: number };\n giftCode?: string;\n}\n\n/** Persist hash-only intent state, then create an idempotent provider checkout. */\nexport async function startGiftIntent(db: ChapterDb, input: StartGiftIntentInput): Promise<StartedGiftIntent> {\n let stored = first((await db.query({ giftPurchaseIntents: { $: { where: { id: input.id }, limit: 1 } } })).giftPurchaseIntents);\n let giftCode: string | undefined;\n if (!stored) {\n const prepared = await prepareGiftCode(input.chapterId);\n const attrs = {\n id: input.id, chapterId: input.chapterId, environment: input.environment,\n purchaserType: input.purchaserType, purchaserEmailNormalized: input.purchaserEmailNormalized,\n ...(input.purchaserApplicationId ? { purchaserApplicationId: input.purchaserApplicationId } : {}),\n ...(input.purchaserUserId ? { purchaserUserId: input.purchaserUserId } : {}),\n offerId: input.offer.id, offerSnapshot: input.offer, status: \"created\",\n codeHash: prepared.codeHash, codeVersion: prepared.codeVersion, codeIssuedAt: input.now,\n createdAt: input.now, updatedAt: input.now,\n };\n const write = await db.transact([{ t: \"update\", ns: \"giftPurchaseIntents\", id: input.id, attrs }], {\n mutationId: `gift-intent:${input.id}`,\n });\n stored = write.duplicate\n ? first((await db.query({ giftPurchaseIntents: { $: { where: { id: input.id }, limit: 1 } } })).giftPurchaseIntents)\n : attrs;\n if (!write.duplicate) giftCode = prepared.code;\n }\n if (!stored || stored.chapterId !== input.chapterId || stored.environment !== input.environment ||\n stored.offerId !== input.offer.id || stored.purchaserEmailNormalized !== input.purchaserEmailNormalized) {\n throw new Error(\"gift purchase intent does not match this checkout\");\n }\n if (stored.status === \"paid\") throw new Error(\"gift purchase is already paid\");\n const checkout = await startGiftProviderCheckout(\n input.stripeSecret,\n stored as GiftIntentRow,\n input.purchaserEmail,\n typeof stored.providerCustomerId === \"string\" ? stored.providerCustomerId : input.existingCustomerId,\n );\n await db.transact([{ t: \"update\", ns: \"giftPurchaseIntents\", id: input.id, attrs: {\n status: \"checkout_ready\", providerObjectId: checkout.providerObjectId,\n ...(checkout.customerId ? { providerCustomerId: checkout.customerId } : {}),\n checkoutStartedAt: input.now, updatedAt: input.now,\n } }], { mutationId: `gift-checkout-ready:${input.id}:${checkout.providerObjectId}` });\n return {\n gift: true, intentId: input.id, clientSecret: checkout.clientSecret, publishableKey: input.publishableKey,\n lineItems: { standardCents: input.offer.priceCents, discountCents: 0, dueTodayCents: input.offer.priceCents },\n ...(giftCode ? { giftCode } : {}),\n };\n}\n","// Payment routes: POST /api/payments/subscription (start a founding-member\n// subscription), POST /api/webhooks/stripe (the AUTHORITATIVE writer of\n// paid/refunded/canceled, exactly-once per event id). Admin refund policy and\n// mechanics live in worker-routes-admin-lifecycle so exactly one built-in owns\n// that path. I/O only; the correctness rules live in ./payments and the provider\n// in ./payments-stripe.\nimport { getVaultSecret } from \"./auth\";\nimport { approveApplication } from \"./approve-application\";\nimport { crmDeps, syncApplicationToCrm } from \"./crm-sync\";\nimport { emailGroupFrom, sendTemplated } from \"./notify\";\nimport { canceledPatch, firstPaymentPatch, refundedPatch, renewalPatch, webhookMutationId } from \"./payments\";\nimport type { WebhookEvent } from \"./payments\";\nimport { createStripeProvider } from \"./payments-stripe\";\nimport { findTier, tierIsFree } from \"./tiers\";\nimport { loadTiers } from \"./tiers-store\";\nimport { loadActiveSignupControl } from \"./signup-control-store\";\nimport { findGiftOffer } from \"./gift-offers\";\nimport { normalizeChapterEmail } from \"./email-identity\";\nimport { startGiftIntent } from \"./gift-intents\";\nimport { issueGiftClaim, revokeGiftClaim, type GiftIntentRow } from \"./gift-store\";\nimport { json } from \"./worker-context\";\nimport type { ChapterEnv, WorkerContext } from \"./worker-context\";\nimport type { Route } from \"./worker-routes\";\nimport type { ChapterDb } from \"./types\";\n\ntype Row = Record<string, unknown>;\n\nconst codeOf = (err: unknown): string =>\n err && typeof err === \"object\" && typeof (err as { code?: unknown }).code === \"string\" ? (err as { code: string }).code : \"unknown\";\n\nasync function firstRow(db: ChapterDb, ns: string, q: Record<string, unknown>): Promise<Row | undefined> {\n const res = await db.query({ [ns]: { $: q } });\n const rows = res[ns];\n return Array.isArray(rows) ? rows[0] : undefined;\n}\n\nfunction lineItems(group: Row): { standardCents: number; discountCents: number; dueTodayCents: number } {\n const standard = Number(group.standardPriceCents ?? 0);\n const discount = Number(group.foundingDiscountCents ?? 0);\n return { standardCents: standard, discountCents: discount, dueTodayCents: standard - discount };\n}\n\n// Resolve the application an event targets: by metadata applicationId, else the\n// newest row for the Stripe customer.\nasync function findApplication(db: ChapterDb, event: WebhookEvent): Promise<Row | undefined> {\n if (\"applicationId\" in event && event.applicationId) {\n return firstRow(db, \"applications\", { where: { id: event.applicationId }, limit: 1 });\n }\n if (\"customerId\" in event && event.customerId) {\n return firstRow(db, \"applications\", { where: { stripeCustomerId: event.customerId }, order: { createdAt: \"desc\" }, limit: 1 });\n }\n return undefined;\n}\n\n// Best-effort payment-confirmation to the applicant on the first successful\n// invoice. Exactly-once per Stripe event via the dedupeKey.\nasync function notifyPaymentConfirmed(db: ChapterDb, env: ChapterEnv, eventId: string, app: Row): Promise<void> {\n try {\n if (typeof app.email !== \"string\" || !app.email) return;\n const group = await firstRow(db, \"groups\", { where: { id: String(app.groupId ?? \"\") }, limit: 1 });\n if (!group) return;\n await sendTemplated(\n { db, envName: env.ODLA_ENV, sender: env.SEND_EMAIL, from: env.EMAIL_FROM, now: () => Date.now(), newId: () => crypto.randomUUID() },\n {\n group: emailGroupFrom(group),\n template: \"paymentConfirmation\",\n to: app.email,\n vars: { firstName: typeof app.firstName === \"string\" ? app.firstName : \"\" },\n dedupeKey: `${eventId}:confirm`,\n applicationId: String(app.id),\n },\n );\n } catch {\n // never let a confirmation-email failure affect the webhook 200\n }\n}\n\n// Best-effort admin notification at PAYMENT time — the alternative trigger to\n// notifying on submit (sends.adminNotification: \"payment\"). Same template, same\n// exactly-once dedupe, different moment.\nasync function notifyAdminOfPayment(db: ChapterDb, env: ChapterEnv, eventId: string, app: Row): Promise<void> {\n try {\n const group = await firstRow(db, \"groups\", { where: { id: String(app.groupId ?? \"\") }, limit: 1 });\n if (!group || typeof group.notificationEmail !== \"string\" || !group.notificationEmail) return;\n const s = (v: unknown): string => (typeof v === \"string\" ? v : \"\");\n await sendTemplated(\n { db, envName: env.ODLA_ENV, sender: env.SEND_EMAIL, from: env.EMAIL_FROM, now: () => Date.now(), newId: () => crypto.randomUUID() },\n {\n group: emailGroupFrom(group),\n template: \"adminNotification\",\n to: group.notificationEmail,\n vars: { firstName: s(app.firstName), lastName: s(app.lastName), email: s(app.email), phone: s(app.phone), state: s(app.state) },\n dedupeKey: `${eventId}:admin`,\n applicationId: String(app.id),\n },\n );\n } catch {\n // never let a notification failure affect the webhook 200\n }\n}\n\n// The application-row patch for a resolved event (empty = skip the write).\nfunction webhookPatch(event: WebhookEvent, status: string): Record<string, unknown> {\n switch (event.kind) {\n case \"first_payment\":\n return firstPaymentPatch(status, event.renewalAt);\n case \"renewal\":\n return event.renewalAt !== undefined ? renewalPatch(event.renewalAt) : {};\n case \"refunded\":\n return refundedPatch();\n case \"canceled\":\n return canceledPatch();\n default:\n return {};\n }\n}\n\nasync function startSubscription(req: Request, env: ChapterEnv, ctx: WorkerContext): Promise<Response> {\n let body: Row;\n try {\n body = JSON.parse(await req.text()) as Row;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n const applicationId = typeof body.applicationId === \"string\" ? body.applicationId : \"\";\n if (!applicationId) return json({ error: \"applicationId required\" }, 400);\n if (body.refundPolicyAck !== true) return json({ error: \"refundPolicyAck required\" }, 400);\n\n const db = ctx.makeDb(env) as unknown as ChapterDb;\n const app = await firstRow(db, \"applications\", { where: { id: applicationId }, limit: 1 });\n if (!app) return json({ error: \"not found\" }, 404);\n // Single-charge guard: only from the initial state, so a re-post can't double-subscribe.\n if (app.status !== \"submitted\") return json({ error: \"already processed\" }, 409);\n\n const group = await firstRow(db, \"groups\", { where: { id: String(app.groupId ?? ctx.chapter.id) }, limit: 1 });\n const secretKey = await getVaultSecret(db, \"stripe_secret_key\");\n if (!group || !secretKey) return json({ error: \"payments not configured\" }, 503);\n if (typeof app.giftOfferId === \"string\") {\n const control = await loadActiveSignupControl(db, ctx.chapter.id, env.ODLA_ENV);\n const offer = findGiftOffer(control?.document.giftOffers, app.giftOfferId, Date.now());\n if (!offer || typeof group.stripePublishableKey !== \"string\" || !group.stripePublishableKey) {\n return json({ error: \"gift offer is unavailable\" }, 409);\n }\n try {\n const started = await startGiftIntent(db, {\n id: typeof app.giftIntentId === \"string\" ? app.giftIntentId : `gift-intent:${applicationId}`,\n chapterId: ctx.chapter.id, environment: env.ODLA_ENV, offer,\n purchaserType: \"application\", purchaserEmail: String(app.email ?? \"\"),\n purchaserEmailNormalized: normalizeChapterEmail(String(app.email ?? \"\")),\n purchaserApplicationId: applicationId, stripeSecret: secretKey,\n publishableKey: group.stripePublishableKey, now: Date.now(),\n });\n await db.transact([{ t: \"update\", ns: \"applications\", id: applicationId, attrs: {\n giftIntentId: started.intentId, giftCheckoutStartedAt: Date.now(), refundPolicyAckAt: Date.now(),\n } }]);\n return json(started);\n } catch (error) {\n return json({ error: error instanceof Error ? error.message : \"gift checkout failed\" }, 502);\n }\n }\n // The price comes from the tier the applicant chose, not the group, so a\n // chapter offering several tiers cannot charge everyone the first one.\n const tier = findTier(\n await loadTiers(db, group as never),\n typeof app.tierId === \"string\" ? app.tierId : null,\n );\n if (!tier) return json({ error: \"tier not found\", code: \"tier_unresolved\" }, 400);\n // A free tier has nothing to charge. Reaching checkout on one is a client\n // bug, and silently creating a zero subscription would hide it.\n if (tierIsFree(tier)) return json({ error: \"tier is free\", code: \"tier_not_payable\" }, 409);\n const priceId = tier.stripePriceId;\n if (!priceId) return json({ error: \"payments not configured\" }, 503);\n\n const provider = createStripeProvider({ secretKey });\n let result;\n try {\n result = await provider.createSubscription({\n appId: env.ODLA_APP_ID,\n environment: env.ODLA_ENV,\n applicationId,\n groupId: String(group.id),\n email: String(app.email ?? \"\"),\n name: `${app.firstName ?? \"\"} ${app.lastName ?? \"\"}`.trim(),\n priceId: String(priceId),\n existingCustomerId: typeof app.stripeCustomerId === \"string\" ? app.stripeCustomerId : undefined,\n });\n } catch (err) {\n return json({ error: \"payment setup failed\", code: codeOf(err) }, 502);\n }\n\n await db.transact([\n {\n t: \"update\",\n ns: \"applications\",\n id: applicationId,\n attrs: { stripeCustomerId: result.customerId, stripeSubscriptionId: result.subscriptionId, refundPolicyAckAt: Date.now() },\n },\n ]);\n return json({ clientSecret: result.clientSecret, publishableKey: group.stripePublishableKey ?? null, lineItems: lineItems(group) });\n}\n\nasync function ingestWebhook(req: Request, env: ChapterEnv, ctx: WorkerContext): Promise<Response> {\n const db = ctx.makeDb(env) as unknown as ChapterDb;\n const webhookSecret = await getVaultSecret(db, \"stripe_webhook_secret\");\n if (!webhookSecret) return json({ error: \"webhook not configured\" }, 503);\n\n const rawBody = await req.text();\n const ingest = await createStripeProvider({ webhookSecret }).ingestWebhook(rawBody, req.headers.get(\"stripe-signature\") ?? \"\");\n if (!ingest.ok) return json({ error: \"invalid signature\" }, 400);\n const { eventId, event } = ingest;\n if (event.kind === \"ignored\") return json({ ok: true, ignored: event.type });\n\n // One Stripe test account may fan every event to several developer Workers.\n // New payment objects carry their exact app/environment identity; sibling\n // endpoints acknowledge the delivery but must never apply it. Legacy Stripe\n // objects without identity metadata retain the established local-db lookup.\n const identifiedEnvironment = event.appId !== undefined || event.environment !== undefined;\n if (env.ODLA_APP_ID && identifiedEnvironment && (\n event.appId !== env.ODLA_APP_ID || event.environment !== env.ODLA_ENV\n )) {\n return json({ ok: true, matched: false });\n }\n\n if (event.kind === \"gift_paid\" || event.kind === \"gift_revoked\") {\n const intent = await firstRow(db, \"giftPurchaseIntents\", { where: { id: event.giftIntentId }, limit: 1 });\n if (!intent || intent.chapterId !== ctx.chapter.id || intent.environment !== env.ODLA_ENV) {\n return json({ ok: true, matched: false });\n }\n if (event.kind === \"gift_paid\") {\n if (intent.providerObjectId !== event.providerObjectId) return json({ ok: true, matched: false });\n if (intent.status === \"refunded\" || intent.status === \"canceled\") return json({ ok: true, matched: false });\n try {\n const issued = await issueGiftClaim(db, intent as GiftIntentRow, {\n eventId, objectId: event.providerObjectId,\n }, Date.now());\n return json({ ok: true, matched: true, claimId: issued.claimId });\n } catch {\n return json({ error: \"gift issuance failed\" }, 503);\n }\n }\n await db.transact([{ t: \"update\", ns: \"giftPurchaseIntents\", id: event.giftIntentId, attrs: {\n status: event.reason, updatedAt: Date.now(),\n } }], { mutationId: `gift-revoked-intent:${eventId}` });\n const claim = await firstRow(db, \"giftClaims\", { where: { intentId: event.giftIntentId }, limit: 1 });\n if (claim) await revokeGiftClaim(db, claim, event.reason, Date.now());\n return json({ ok: true, matched: Boolean(claim) });\n }\n\n const app = await findApplication(db, event);\n if (!app) return json({ ok: true, matched: false });\n\n const patch = webhookPatch(event, String(app.status ?? \"\"));\n let next = app;\n if (Object.keys(patch).length) {\n await db.transact([{ t: \"update\", ns: \"applications\", id: String(app.id), attrs: patch }], { mutationId: webhookMutationId(eventId) });\n // Payment is one of the two status transitions that happen with no admin\n // present, so without this the console's pipeline (which reads\n // crm_record.stage) shows every paying member as still unpaid. Also\n // refreshes the billing snapshot on a renewal, which carries no status\n // change. Best-effort: Stripe retries a failed webhook, and re-charging is\n // a far worse outcome than a stale mirror the next sync repairs.\n next = { ...app, ...patch };\n await syncApplicationToCrm(crmDeps(db, ctx), { app: next, stage: String(next.status ?? \"\") }).catch(() => undefined);\n }\n if (event.kind === \"first_payment\") {\n await notifyPaymentConfirmed(db, env, eventId, app);\n if (ctx.chapter.sends.adminNotification === \"payment\") await notifyAdminOfPayment(db, env, eventId, app);\n if (typeof next.interviewWaivedAt === \"number\") {\n await approveApplication({\n db,\n env,\n ctx,\n app: next,\n origin: new URL(req.url).origin,\n reason: \"interview_waiver\",\n });\n }\n }\n return json({ ok: true });\n}\n\n/** The payment routes (chapter mode). Webhook + subscription are public and\n * capability-guarded by the unguessable application id / signed payload. */\nexport const handlePayments: Route = async (req, url, env, ctx) => {\n if (ctx.chapter.mode !== \"chapter\") return null;\n if (req.method === \"POST\" && url.pathname === \"/api/payments/subscription\") return startSubscription(req, env, ctx);\n if (req.method === \"POST\" && url.pathname === \"/api/webhooks/stripe\") return ingestWebhook(req, env, ctx);\n return null;\n};\n","import { getVaultSecret } from \"./auth\";\nimport { normalizeChapterEmail } from \"./email-identity\";\nimport { findGiftOffer, publicGiftOffers } from \"./gift-offers\";\nimport { giftRequesterBucket, hashGiftCode } from \"./gift-codes\";\nimport { startGiftIntent } from \"./gift-intents\";\nimport { buyerGiftClaims, redeemGiftClaim, rotateGiftClaim } from \"./gift-store\";\nimport { loadActiveSignupControl } from \"./signup-control-store\";\nimport { json } from \"./worker-context\";\nimport type { ChapterDb } from \"./types\";\nimport type { Route } from \"./worker-context\";\n\nconst first = (value: unknown): Record<string, unknown> | undefined => Array.isArray(value) ? value[0] : undefined;\nconst rows = (value: unknown): Array<Record<string, unknown>> => Array.isArray(value) ? value : [];\nconst invalid = () => json({ error: \"gift code is invalid or unavailable\" }, 400);\nconst userFor = async (req: Request, env: Parameters<Route>[2], ctx: Parameters<Route>[3]) => {\n const user = await ctx.verifyUser(req, env);\n return user?.email ? user : null;\n};\nconst loadClaim = async (db: ChapterDb, id: string) =>\n first((await db.query({ giftClaims: { $: { where: { id }, limit: 1 } } })).giftClaims);\n\nasync function consumeRateLimit(db: ChapterDb, chapterId: string, requester: string, now: number): Promise<boolean> {\n const bucket = await giftRequesterBucket(chapterId, requester);\n const id = `gift-rate:${chapterId}:${bucket}`;\n const current = first((await db.query({ giftRedemptionAttempts: { $: { where: { id }, limit: 1 } } })).giftRedemptionAttempts);\n const within = Boolean(current && now - Number(current.windowStartedAt) < 15 * 60_000);\n const attemptCount = within ? Number(current?.attemptCount ?? 0) + 1 : 1;\n if (attemptCount > 10) return false;\n await db.transact([{ t: \"update\", ns: \"giftRedemptionAttempts\", id, attrs: {\n id, chapterId, bucket, attemptCount, windowStartedAt: within ? Number(current?.windowStartedAt) : now, updatedAt: now,\n } }]);\n return true;\n}\n\n/** Authenticated buyer checkout/list/rotation and beneficiary redemption routes. */\nexport const handleGifts: Route = async (req, url, env, ctx) => {\n if (ctx.chapter.mode !== \"chapter\" || !url.pathname.startsWith(\"/api/gifts\")) return null;\n const db = ctx.makeDb(env) as unknown as ChapterDb;\n if (req.method === \"GET\" && url.pathname === \"/api/gifts\") {\n const user = await userFor(req, env, ctx);\n if (!user) return json({ error: \"unauthorized\" }, 401);\n const control = await loadActiveSignupControl(db, ctx.chapter.id, env.ODLA_ENV);\n const found = await db.query({ giftClaims: { $: { where: {\n purchaserEmailNormalized: normalizeChapterEmail(user.email!), chapterId: ctx.chapter.id,\n }, limit: 200 } } });\n const group = first((await db.query({ groups: { $: { where: { id: ctx.chapter.id }, limit: 1 } } })).groups);\n return json({\n offers: publicGiftOffers(control?.document.giftOffers, Date.now()),\n claims: buyerGiftClaims(rows(found.giftClaims).sort((a, b) => Number(b.createdAt) - Number(a.createdAt)), Date.now()),\n refundPolicyText: typeof group?.refundPolicyText === \"string\" ? group.refundPolicyText : \"\",\n });\n }\n if (req.method === \"POST\" && url.pathname === \"/api/gifts/checkout\") {\n const user = await userFor(req, env, ctx);\n if (!user) return json({ error: \"unauthorized\" }, 401);\n let body: Record<string, unknown>;\n try { body = JSON.parse(await req.text()) as Record<string, unknown>; }\n catch { return json({ error: \"invalid JSON body\" }, 400); }\n const purchaseId = typeof body.purchaseId === \"string\" ? body.purchaseId : \"\";\n if (!/^[A-Za-z0-9_-]{16,128}$/.test(purchaseId)) return json({ error: \"purchaseId is invalid\" }, 400);\n const control = await loadActiveSignupControl(db, ctx.chapter.id, env.ODLA_ENV);\n const offer = findGiftOffer(control?.document.giftOffers, typeof body.offerId === \"string\" ? body.offerId : \"\", Date.now());\n if (!offer) return json({ error: \"gift offer is unavailable\" }, 409);\n const group = first((await db.query({ groups: { $: { where: { id: ctx.chapter.id }, limit: 1 } } })).groups);\n const stripeSecret = await getVaultSecret(db, \"stripe_secret_key\");\n if (!group || !stripeSecret || typeof group.stripePublishableKey !== \"string\") return json({ error: \"payments not configured\" }, 503);\n const emailNormalized = normalizeChapterEmail(user.email!);\n const applications = rows((await db.query({ applications: { $: { where: { emailNormalized }, limit: 20 } } })).applications);\n const app = applications.sort((a, b) => Number(b.createdAt ?? 0) - Number(a.createdAt ?? 0))[0];\n try {\n return json(await startGiftIntent(db, {\n id: `gift-intent:${ctx.chapter.id}:${purchaseId}`, chapterId: ctx.chapter.id,\n environment: env.ODLA_ENV, offer, purchaserType: \"member\", purchaserEmail: user.email!,\n purchaserEmailNormalized: emailNormalized, purchaserUserId: user.userId,\n ...(typeof app?.stripeCustomerId === \"string\" ? { existingCustomerId: app.stripeCustomerId } : {}),\n stripeSecret, publishableKey: group.stripePublishableKey, now: Date.now(),\n }));\n } catch (error) {\n return json({ error: error instanceof Error ? error.message : \"gift checkout failed\" }, 502);\n }\n }\n const rotateMatch = url.pathname.match(/^\\/api\\/gifts\\/([^/]+)\\/rotate$/);\n if (req.method === \"POST\" && rotateMatch) {\n let claimId = \"\";\n try { claimId = decodeURIComponent(rotateMatch[1] as string); } catch { return invalid(); }\n if (!claimId.startsWith(\"gift-claim:\")) return invalid();\n const claim = await loadClaim(db, claimId);\n if (!claim || claim.chapterId !== ctx.chapter.id || Number(claim.rotationCount ?? 0) >= 10) return invalid();\n const user = await userFor(req, env, ctx);\n let applicationId = \"\";\n if (!user) {\n try { applicationId = String((JSON.parse(await req.text()) as Record<string, unknown>).applicationId ?? \"\"); }\n catch { return invalid(); }\n }\n const owns = user\n ? claim.purchaserEmailNormalized === normalizeChapterEmail(user.email!)\n : claim.purchaserApplicationId === applicationId;\n if (!owns) return invalid();\n const rotated = await rotateGiftClaim(db, claim, Date.now());\n return rotated ? json(rotated) : invalid();\n }\n if (req.method === \"POST\" && url.pathname === \"/api/gifts/redeem\") {\n const user = await userFor(req, env, ctx);\n if (!user) return json({ error: \"unauthorized\" }, 401);\n const now = Date.now();\n if (!await consumeRateLimit(db, ctx.chapter.id, `${user.userId}:${req.headers.get(\"cf-connecting-ip\") ?? \"no-ip\"}`, now)) {\n return json({ error: \"too many attempts\" }, 429);\n }\n let code = \"\";\n try { code = String((JSON.parse(await req.text()) as Record<string, unknown>).code ?? \"\").trim(); }\n catch { return invalid(); }\n if (!/^gift1_[A-Za-z0-9_-]{43}$/.test(code)) return invalid();\n const codeHash = await hashGiftCode(ctx.chapter.id, code);\n const claim = first((await db.query({ giftClaims: { $: { where: { codeHash }, limit: 1 } } })).giftClaims);\n if (!claim || claim.chapterId !== ctx.chapter.id) return invalid();\n if (claim.status !== \"pending\" || Number(claim.codeExpiresAt) <= now) {\n await db.transact([{ t: \"update\", ns: \"giftClaims\", id: String(claim.id), attrs: {\n attemptCount: Number(claim.attemptCount ?? 0) + 1,\n ...(claim.status === \"pending\" ? { status: \"expired\" } : {}),\n } }]).catch(() => undefined);\n return invalid();\n }\n const redeemed = await redeemGiftClaim(db, claim, { email: user.email!, userId: user.userId }, now);\n return redeemed ? json({ ok: true, ...redeemed }) : invalid();\n }\n return null;\n};\n","// Admin operational routes. GET /api/admin/meetings is the admin agenda,\n// reconciled against the live platform calendar: it reads upcoming events through\n// @odla-ai/calendar (chapter never calls Google directly) and adopts any\n// owner-side move/cancel onto the canonical meetings row + the application\n// projection, via the pure ./reconcile logic. Admin-gated; the read still\n// succeeds (serving canonical rows) if the calendar is unavailable.\nimport { initCalendar } from \"@odla-ai/calendar\";\nimport { reconcileMeetings } from \"./reconcile\";\nimport type { LiveEvent, MeetingForReconcile, ReconcileDecision } from \"./reconcile\";\nimport { resolveScheduling, validateScheduling } from \"./scheduling\";\nimport { json } from \"./worker-context\";\nimport type { ChapterEnv, WorkerContext } from \"./worker-context\";\nimport type { Route } from \"./worker-routes\";\nimport type { ChapterDb, ChapterScheduling, DbOp } from \"./types\";\n\n// Load the admin's target group (query param `group`, else the chapter), gated on\n// an admin session. Returns [db, group] or a Response to short-circuit.\nasync function adminGroup(\n req: Request,\n env: ChapterEnv,\n ctx: WorkerContext,\n url: URL,\n): Promise<{ db: ChapterDb; group: Record<string, unknown> } | Response> {\n const rawDb = ctx.makeDb(env);\n const u = await ctx.verifyUser(req, env);\n if (!u) return json({ error: \"unauthorized\" }, 401);\n if (!(await ctx.isAdmin(rawDb, u))) return json({ error: \"forbidden\" }, 403);\n const db = rawDb as unknown as ChapterDb;\n const groupId = url.searchParams.get(\"group\") ?? ctx.chapter.id;\n const group = (await db.query({ groups: { $: { where: { id: groupId }, limit: 1 } } })).groups?.[0];\n if (!group) return json({ error: \"not found\" }, 404);\n return { db, group };\n}\n\n/** GET/PUT /api/admin/scheduling — read the group's booking rules, or replace\n * them (validated via resolveScheduling; a bad config is a 400, never persisted).\n * The backend for the availability-editor section. */\nexport const handleAdminScheduling: Route = async (req, url, env, ctx) => {\n if (url.pathname !== \"/api/admin/scheduling\" || (req.method !== \"GET\" && req.method !== \"PUT\")) return null;\n const got = await adminGroup(req, env, ctx, url);\n if (got instanceof Response) return got;\n const { db, group } = got;\n\n if (req.method === \"GET\") {\n return json({ scheduling: resolveScheduling(group.schedulingJson as ChapterScheduling | undefined) });\n }\n let body: unknown;\n try {\n body = JSON.parse(await req.text());\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n // Field-keyed messages, not a thrown string: an owner-facing settings form needs\n // to say which field is wrong and why.\n const checked = validateScheduling(body as ChapterScheduling);\n if (!checked.ok) return json({ error: \"invalid scheduling config\", errors: checked.errors }, 400);\n await db.transact([{ t: \"update\", ns: \"groups\", id: String(group.id), attrs: { schedulingJson: checked.value } }]);\n return json({ scheduling: checked.value });\n};\n\nasync function upcomingEvents(env: ChapterEnv): Promise<LiveEvent[]> {\n const cal = initCalendar({ appId: env.ODLA_APP_ID, env: env.ODLA_ENV, adminToken: env.ODLA_API_KEY, endpoint: env.ODLA_PLATFORM });\n const res = await cal.availability.upcoming();\n return res.events.map((e) => ({ eventId: e.eventId, status: e.status, startAt: e.startAt, endAt: e.endAt }));\n}\n\nfunction toReconcile(rows: Array<Record<string, unknown>>): MeetingForReconcile[] {\n return rows.map((m) => ({\n id: String(m.id),\n applicationId: String(m.applicationId),\n googleEventId: typeof m.googleEventId === \"string\" ? m.googleEventId : null,\n status: String(m.status ?? \"\"),\n startAt: typeof m.startAt === \"number\" ? m.startAt : null,\n endAt: typeof m.endAt === \"number\" ? m.endAt : null,\n }));\n}\n\n/** GET /api/admin/meetings — the scheduled agenda, reconciled against the live\n * calendar (adopts owner moves/cancellations onto the canonical rows). */\nexport const handleAdminMeetings: Route = async (req, url, env, ctx) => {\n if (req.method !== \"GET\" || url.pathname !== \"/api/admin/meetings\") return null;\n const rawDb = ctx.makeDb(env);\n const u = await ctx.verifyUser(req, env);\n if (!u) return json({ error: \"unauthorized\" }, 401);\n if (!(await ctx.isAdmin(rawDb, u))) return json({ error: \"forbidden\" }, 403);\n const db = rawDb as unknown as ChapterDb;\n\n // ?all=1 includes cancelled/past rows; from/to bound the window (epoch ms).\n const all = url.searchParams.get(\"all\") === \"1\";\n const from = Number(url.searchParams.get(\"from\"));\n const to = Number(url.searchParams.get(\"to\"));\n\n const query = await db.query({\n meetings: { $: { where: all ? {} : { status: \"scheduled\" }, order: { startAt: \"asc\" }, limit: 500 } },\n });\n let rows = (Array.isArray(query.meetings) ? query.meetings : []) as Array<Record<string, unknown>>;\n if (Number.isFinite(from)) rows = rows.filter((m) => Number(m.startAt ?? 0) >= from);\n if (Number.isFinite(to)) rows = rows.filter((m) => Number(m.startAt ?? 0) <= to);\n\n let decisions: ReconcileDecision[] = [];\n try {\n decisions = reconcileMeetings(toReconcile(rows), await upcomingEvents(env), Date.now());\n } catch {\n // Calendar unavailable — serve the canonical rows without adopting edits.\n }\n\n // Apply adopt decisions (best-effort; the read still succeeds if a write fails).\n const patched = new Map<string, Record<string, unknown>>();\n for (const d of decisions) {\n const ops: DbOp[] = [\n { t: \"update\", ns: \"meetings\", id: d.meetingId, attrs: d.meetingPatch },\n { t: \"update\", ns: \"applications\", id: d.applicationId, attrs: d.applicationPatch },\n ];\n try {\n await db.transact(ops);\n patched.set(d.meetingId, d.meetingPatch);\n } catch {\n // leave the row as-is if the write fails\n }\n }\n\n // Join the applicant onto each row, and return the group timezone, so an admin\n // console can label and render the agenda without a second round trip. One\n // query, indexed by id — not N+1.\n const appQuery = await db.query({ applications: { $: { limit: 1000 } } });\n const byId = new Map<string, Record<string, unknown>>();\n for (const a of Array.isArray(appQuery.applications) ? appQuery.applications : []) {\n byId.set(String(a.id), a);\n }\n const applicantOf = (m: Record<string, unknown>): Record<string, unknown> | null => {\n const a = byId.get(String(m.applicationId));\n if (!a) return null;\n return { id: a.id, firstName: a.firstName, lastName: a.lastName, email: a.email, status: a.status };\n };\n\n const group = (await db.query({ groups: { $: { where: { id: ctx.chapter.id }, limit: 1 } } })).groups?.[0];\n const timezone = resolveScheduling(group?.schedulingJson as ChapterScheduling | undefined).timezone;\n\n // Reflect adopted patches; the row carries drift (drift, driftGoogleStartAt,\n // adoptedFromGoogleAt) and the Meet/Calendar links (meetUrl, htmlLink) already.\n const meetings = rows\n .map((m): Record<string, unknown> => ({ ...m, ...(patched.get(String(m.id)) ?? {}), applicant: applicantOf(m) }))\n .filter((m) => all || m.status === \"scheduled\");\n return json({ meetings, adopted: decisions.length, timezone });\n};\n","// The Google → chapter half of the bidirectional calendar sync. Booking writes\n// events TO the platform calendar (0.4.0's create/reschedule); this ADOPTS edits\n// FROM it: when the owner moves or cancels the intro call directly in Google,\n// reconcile mirrors that onto our canonical `meetings` row and the `application`\n// projection. Chapter never calls Google — the worker reads live events through\n// @odla-ai/calendar's upcoming() (platform-brokered) and applies the ops this\n// returns. Pure + testable; adoption policy (owner edits win) matches the shipped\n// original production worker.\n\n/** A `meetings` row, as far as reconciliation cares. */\nexport interface MeetingForReconcile {\n id: string;\n applicationId: string;\n googleEventId?: string | null;\n status: string;\n startAt?: number | null;\n endAt?: number | null;\n}\n\n/** One live calendar event (a subset of @odla-ai/calendar's Booking). */\nexport interface LiveEvent {\n eventId: string;\n status?: string;\n startAt?: number;\n endAt?: number;\n}\n\n/** An adopt decision: mirror a Google move/cancel onto our rows. */\nexport interface ReconcileDecision {\n meetingId: string;\n applicationId: string;\n kind: \"cancelled\" | \"moved\";\n /** Attrs to write onto the `meetings` row. */\n meetingPatch: Record<string, unknown>;\n /** Attrs to write onto the `applications` row (the projection). */\n applicationPatch: Record<string, unknown>;\n}\n\n/** Meetings still worth reconciling: a scheduled booking with a Google event that\n * starts in the future (or within the last hour, to catch a just-passed edit). */\nexport function isReconcilable(meeting: MeetingForReconcile, now: number): boolean {\n return meeting.status === \"scheduled\" && Boolean(meeting.googleEventId) && (meeting.startAt ?? 0) > now - 3_600_000;\n}\n\n/**\n * Diff canonical `meetings` against the live calendar events and return the adopt\n * decisions — only for meetings that actually changed (a still-matching meeting\n * is omitted). A meeting whose event vanished or is `cancelled` in Google is\n * adopted as cancelled (application `meetingAt` zeroed — 0 means \"was booked,\n * then cancelled\"); a meeting whose event moved adopts the new window (duration\n * preserved when the event omits `endAt`).\n */\nexport function reconcileMeetings(\n meetings: readonly MeetingForReconcile[],\n events: readonly LiveEvent[],\n now: number,\n): ReconcileDecision[] {\n const byEvent = new Map(events.map((e) => [e.eventId, e]));\n const decisions: ReconcileDecision[] = [];\n for (const m of meetings) {\n if (!isReconcilable(m, now) || !m.googleEventId) continue;\n const g = byEvent.get(m.googleEventId);\n if (!g || g.status === \"cancelled\") {\n decisions.push({\n meetingId: m.id,\n applicationId: m.applicationId,\n kind: \"cancelled\",\n meetingPatch: { status: \"cancelled\", drift: \"none\", adoptedFromGoogleAt: now },\n applicationPatch: { meetingAt: 0, meetingLink: \"\" },\n });\n } else if (g.startAt !== undefined && g.startAt !== m.startAt) {\n const duration = (m.endAt ?? 0) - (m.startAt ?? 0);\n decisions.push({\n meetingId: m.id,\n applicationId: m.applicationId,\n kind: \"moved\",\n meetingPatch: { startAt: g.startAt, endAt: g.endAt ?? g.startAt + duration, drift: \"none\", adoptedFromGoogleAt: now },\n applicationPatch: { meetingAt: g.startAt },\n });\n }\n }\n return decisions;\n}\n","// Admin roster + identity routes: the union people list, one person's access,\n// role changes, and the CRM backfill. Role changes wire chapter's package-\n// enforced canChangeRole guard (super-admin tier + self-demotion lockout) rather\n// than re-deriving the rules per site. All admin-gated.\nimport { canChangeRole, getVaultSecret } from \"./auth\";\nimport { clerkGetUser, clerkListUsers, clerkSetRole } from \"./clerk-roles\";\nimport { backfillCrm } from \"./crm-sync\";\nimport { applicationSummary } from \"./session\";\nimport { json } from \"./worker-context\";\nimport type { ChapterEnv, WorkerContext } from \"./worker-context\";\nimport type { Route } from \"./worker-routes\";\nimport type { ChapterDb } from \"./types\";\n\n// Gate + shape the verified admin identity. Returns { db, actor } or a Response.\nasync function adminGate(\n req: Request,\n env: ChapterEnv,\n ctx: WorkerContext,\n): Promise<{ db: ChapterDb; actor: { userId: string; email?: string } } | Response> {\n const rawDb = ctx.makeDb(env);\n const u = await ctx.verifyUser(req, env);\n if (!u) return json({ error: \"unauthorized\" }, 401);\n if (!(await ctx.isAdmin(rawDb, u))) return json({ error: \"forbidden\" }, 403);\n return { db: rawDb as unknown as ChapterDb, actor: { userId: u.userId, email: u.email ?? undefined } };\n}\n\nconst crmDeps = (db: ChapterDb, ctx: WorkerContext) => ({\n crm: ctx.chapter.crm,\n db,\n now: () => Date.now(),\n newId: () => crypto.randomUUID(),\n chapter: ctx.chapter,\n});\n\n/** POST /api/admin/crm/sync — backfill/reproject every person into the CRM.\n * Idempotent by email, so it doubles as migration and repair. */\nexport const handleAdminCrmSync: Route = async (req, url, env, ctx) => {\n if (req.method !== \"POST\" || url.pathname !== \"/api/admin/crm/sync\") return null;\n const gate = await adminGate(req, env, ctx);\n if (gate instanceof Response) return gate;\n const result = await backfillCrm(crmDeps(gate.db, ctx));\n return json({ ok: true, ...result });\n};\n\n/** GET /api/admin/people — one row per person, joined by lowercased email: the\n * `$users` mirror (accounts), applications (pipeline), and Clerk roles.\n * Applications first (newest on top), account-only rows after. */\nexport const handleAdminPeople: Route = async (req, url, env, ctx) => {\n if (req.method !== \"GET\" || url.pathname !== \"/api/admin/people\") return null;\n const gate = await adminGate(req, env, ctx);\n if (gate instanceof Response) return gate;\n const { db } = gate;\n\n const sk = await getVaultSecret(db, \"clerk_secret_key\");\n const [data, roleList] = await Promise.all([\n db.query({\n applications: { $: { order: { createdAt: \"desc\" }, limit: 200 } },\n $users: { $: { limit: 200 } },\n }),\n sk ? clerkListUsers(sk).catch(() => []) : Promise.resolve([]),\n ]);\n const clerkByUserId = new Map(roleList.map((u) => [u.id, u]));\n\n type PersonRow = {\n email: string;\n name: string;\n userId: string | null;\n role: string | null;\n profile: Record<string, unknown> | null;\n clerkApplicationId: string | null;\n application: ReturnType<typeof applicationSummary> | null;\n };\n const people = new Map<string, PersonRow>();\n\n for (const u of (data.$users ?? []) as Array<Record<string, unknown>>) {\n if (u.deleted === true) continue; // tombstoned Clerk users are not accounts\n const email = typeof u.email === \"string\" ? u.email : \"\";\n if (!email) continue;\n const clerk = clerkByUserId.get(String(u.id));\n people.set(email.toLowerCase(), {\n email,\n name: typeof u.name === \"string\" ? u.name : \"\",\n userId: typeof u.id === \"string\" ? u.id : null,\n role: clerk?.role ?? \"provisional\",\n profile: clerk ? clerk.profile : null,\n clerkApplicationId: clerk?.applicationId ?? null,\n application: null,\n });\n }\n for (const a of (data.applications ?? []) as Array<Record<string, unknown>>) {\n const key = String(a.email ?? \"\").toLowerCase();\n if (!key) continue;\n const name = `${a.firstName ?? \"\"} ${a.lastName ?? \"\"}`.trim();\n const row = people.get(key);\n if (row) {\n if (!row.application) row.application = applicationSummary(a as unknown as Parameters<typeof applicationSummary>[0]); // newest-first: keep the latest\n if (!row.name) row.name = name;\n } else {\n people.set(key, {\n email: String(a.email),\n name,\n userId: null,\n role: null,\n profile: null,\n clerkApplicationId: null,\n application: applicationSummary(a as unknown as Parameters<typeof applicationSummary>[0]),\n });\n }\n }\n const rows = [...people.values()].sort(\n (x, y) => ((y.application?.createdAt as number) ?? -1) - ((x.application?.createdAt as number) ?? -1),\n );\n return json({ people: rows });\n};\n\n/** GET /api/admin/people/access?userId= — a person's Clerk role + super-admin\n * flag, for the record panel's Access card. */\nexport const handleAdminPeopleAccess: Route = async (req, url, env, ctx) => {\n if (req.method !== \"GET\" || url.pathname !== \"/api/admin/people/access\") return null;\n const gate = await adminGate(req, env, ctx);\n if (gate instanceof Response) return gate;\n const { db } = gate;\n const targetId = url.searchParams.get(\"userId\") ?? \"\";\n if (!targetId.startsWith(\"user_\")) return json({ error: \"invalid userId\" }, 400);\n const sk = await getVaultSecret(db, \"clerk_secret_key\");\n if (!sk) return json({ error: \"role management unavailable: clerk_secret_key missing from vault\" }, 503);\n const info = await clerkGetUser(sk, targetId);\n if (!info) return json({ error: \"user lookup unavailable\" }, 502);\n return json({ userId: targetId, role: info.role, email: info.email ?? null, superAdmin: await ctx.isSuperAdminEmail(db as never, info.email) });\n};\n\n/** POST /api/admin/people/role — change a person's Clerk role. The escalation\n * rules (super-admin tier, self-demotion lockout) are enforced by chapter's\n * canChangeRole, not re-derived here. */\nexport const handleAdminPeopleRole: Route = async (req, url, env, ctx) => {\n if (req.method !== \"POST\" || url.pathname !== \"/api/admin/people/role\") return null;\n const gate = await adminGate(req, env, ctx);\n if (gate instanceof Response) return gate;\n const { db, actor } = gate;\n\n let body: Record<string, unknown>;\n try {\n body = (await req.json()) as Record<string, unknown>;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n const targetId = typeof body.userId === \"string\" ? body.userId : \"\";\n const newRole = typeof body.role === \"string\" ? body.role : \"\";\n if (!targetId.startsWith(\"user_\")) return json({ error: \"invalid userId\" }, 400);\n\n const sk = await getVaultSecret(db, \"clerk_secret_key\");\n if (!sk) return json({ error: \"role management unavailable: clerk_secret_key missing from vault\" }, 503);\n const target = await clerkGetUser(sk, targetId);\n\n const guard = canChangeRole({\n actorId: actor.userId,\n actorIsSuper: await ctx.isSuperAdminEmail(db as never, actor.email),\n targetId,\n targetCurrentRole: target?.role ?? \"provisional\",\n targetIsSuper: await ctx.isSuperAdminEmail(db as never, target?.email),\n newRole,\n auth: ctx.chapter.auth,\n });\n if (!guard.ok) return json({ error: guard.error }, guard.status);\n\n if (!(await clerkSetRole(sk, targetId, newRole))) return json({ error: \"role update failed upstream\" }, 502);\n return json({ ok: true });\n};\n","// Explicit migration/repair for Chapter's Clerk account snapshot. This is a\n// bounded admin action rather than a side effect of a roster GET: it moves the\n// former public profile keys into backend-only private metadata, preserves the\n// public role and host-owned metadata, and records the application marker.\nimport { getVaultSecret } from \"./auth\";\nimport { updateClerkUserMetadata } from \"./clerk\";\nimport { clerkListUsers } from \"./clerk-roles\";\nimport {\n applicantPrivateMetadata,\n markPrivateMetadataSynced,\n publicProfileRemoval,\n} from \"./worker-provisioning\";\nimport { json } from \"./worker-context\";\nimport type { Route } from \"./worker-context\";\nimport type { ChapterDb } from \"./types\";\n\nconst own = (value: Record<string, unknown>, key: string): boolean =>\n Object.prototype.hasOwnProperty.call(value, key);\n\nfunction canonical(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(canonical).join(\",\")}]`;\n if (value && typeof value === \"object\") {\n return `{${Object.entries(value as Record<string, unknown>)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([key, item]) => `${JSON.stringify(key)}:${canonical(item)}`)\n .join(\",\")}}`;\n }\n return JSON.stringify(value) ?? \"undefined\";\n}\n\nfunction positiveInt(raw: string | null, fallback: number, max: number): number {\n const parsed = Number(raw);\n return Number.isSafeInteger(parsed) && parsed >= 0\n ? Math.min(parsed, max)\n : fallback;\n}\n\n/** POST /api/admin/clerk/private-profiles/sync?offset=0&limit=50\n *\n * Processes a bounded slice of Clerk users and returns `nextOffset` until the\n * migration is complete. Re-running a slice is safe: current snapshots perform\n * no Clerk write and only repair the local sync marker/link when needed. */\nexport const handleAdminClerkPrivateProfileSync: Route = async (req, url, env, ctx) => {\n if (req.method !== \"POST\" || url.pathname !== \"/api/admin/clerk/private-profiles/sync\") return null;\n const rawDb = ctx.makeDb(env);\n const actor = await ctx.verifyUser(req, env);\n if (!actor) return json({ error: \"unauthorized\" }, 401);\n if (!(await ctx.isAdmin(rawDb, actor))) return json({ error: \"forbidden\" }, 403);\n if (ctx.chapter.mode !== \"chapter\" || ctx.chapter.account === \"none\") {\n return json({ error: \"private profile sync requires a side-effecting chapter account model\" }, 409);\n }\n const db = rawDb as unknown as ChapterDb;\n const secret = await getVaultSecret(db, \"clerk_secret_key\");\n if (!secret) return json({ error: \"clerk_secret_key missing from vault\" }, 503);\n\n let all;\n try {\n all = await clerkListUsers(secret);\n } catch {\n return json({ error: \"Clerk user listing failed\" }, 502);\n }\n const offset = positiveInt(url.searchParams.get(\"offset\"), 0, Number.MAX_SAFE_INTEGER);\n const limit = positiveInt(url.searchParams.get(\"limit\"), 50, 100) || 50;\n const users = all.slice(offset, offset + limit);\n const result = { updated: 0, alreadyCurrent: 0, noApplication: 0, failed: 0 };\n\n for (const user of users) {\n if (!user.email) {\n result.noApplication += 1;\n continue;\n }\n const apps = (await db.query({\n applications: { $: { where: { email: user.email }, order: { createdAt: \"desc\" }, limit: 1 } },\n })).applications;\n const app = Array.isArray(apps) ? apps[0] : undefined;\n if (!app || typeof app.id !== \"string\") {\n result.noApplication += 1;\n continue;\n }\n\n const desired = applicantPrivateMetadata(ctx.chapter, app.id, app);\n const desiredProfile = desired.profile ?? {};\n const legacyPublic = own(user.publicMetadata, \"applicationId\") || own(user.publicMetadata, \"profile\");\n const current = user.applicationId === app.id && canonical(user.profile) === canonical(desiredProfile);\n try {\n let updated = false;\n if (!current || legacyPublic) {\n const ok = await updateClerkUserMetadata(secret, user.id, {\n publicMetadata: publicProfileRemoval,\n privateMetadata: applicantPrivateMetadata(ctx.chapter, app.id, app, true),\n });\n if (!ok) {\n result.failed += 1;\n continue;\n }\n updated = true;\n }\n await markPrivateMetadataSynced(db, app.id, user.id);\n if (updated) result.updated += 1;\n else result.alreadyCurrent += 1;\n } catch {\n result.failed += 1;\n }\n }\n\n const nextOffset = offset + users.length < all.length\n ? offset + users.length\n : null;\n return json({\n totalUsers: all.length,\n offset,\n processed: users.length,\n nextOffset,\n ...result,\n });\n};\n","// Pure aggregation helpers for the admin dashboard: a weekly time-series bucketer\n// and the annualized-run-rate math for a Stripe subscription. Kept out of the\n// route so both dashboard and billing share one definition and it is unit-tested\n// without a network call.\n\n/** Bucket `{ t, v }` points into the last `weeks` weekly buckets ending at `now`\n * (epoch ms), summing `v` per bucket. Returns oldest→newest `{ weekStart, value\n * }`, so a caller renders a sparkline directly. Points outside the window are\n * ignored. */\nexport function bucketSeries(\n points: Array<{ t: number; v: number }>,\n now: number,\n weeks = 12,\n): Array<{ weekStart: number; value: number }> {\n const WEEK = 7 * 86_400_000;\n const end = now;\n const start = end - weeks * WEEK;\n const buckets = Array.from({ length: weeks }, (_, i) => ({ weekStart: start + i * WEEK, value: 0 }));\n for (const p of points) {\n if (!Number.isFinite(p.t) || p.t < start || p.t > end) continue;\n const idx = Math.min(weeks - 1, Math.floor((p.t - start) / WEEK));\n const bucket = buckets[idx];\n if (bucket) bucket.value += Number.isFinite(p.v) ? p.v : 0;\n }\n return buckets;\n}\n\n/** Labels and current/previous values for one dashboard comparison window. */\nexport interface DashboardMetricSeries {\n labels: string[];\n current: number[];\n previous: number[];\n}\n\n/** Week-over-week and month-over-month series consumed by MetricWidget. */\nexport interface DashboardMetricData {\n wow: DashboardMetricSeries;\n mom: DashboardMetricSeries;\n}\n\nfunction periodSeries(\n points: Array<{ t: number; v: number }>,\n now: number,\n count: number,\n periodMs: number,\n): DashboardMetricSeries {\n const start = now - count * periodMs;\n const previousStart = start - count * periodMs;\n const current = Array.from({ length: count }, () => 0);\n const previous = Array.from({ length: count }, () => 0);\n for (const point of points) {\n if (!Number.isFinite(point.t) || !Number.isFinite(point.v)) continue;\n if (point.t >= start && point.t <= now) {\n const index = Math.min(count - 1, Math.floor((point.t - start) / periodMs));\n current[index] = (current[index] ?? 0) + point.v;\n } else if (point.t >= previousStart && point.t < start) {\n const index = Math.min(count - 1, Math.floor((point.t - previousStart) / periodMs));\n previous[index] = (previous[index] ?? 0) + point.v;\n }\n }\n const labels = current.map((_, index) =>\n new Date(start + index * periodMs).toISOString().slice(5, 10));\n return { labels, current, previous };\n}\n\n/** MetricWidget-ready daily and weekly comparison windows. */\nexport function dashboardMetricData(\n points: Array<{ t: number; v: number }>,\n now: number,\n): DashboardMetricData {\n const DAY = 86_400_000;\n return {\n wow: periodSeries(points, now, 7, DAY),\n mom: periodSeries(points, now, 4, 7 * DAY),\n };\n}\n\n/** Annualized cents for a Stripe subscription: sum each item's\n * `unit_amount * quantity`, ×12 for monthly intervals. A yearly interval is\n * taken as-is. Returns 0 for a shape with no priced items. */\nexport function subAnnualCents(sub: Record<string, unknown>): number {\n const items = ((sub.items as { data?: Array<Record<string, unknown>> } | undefined)?.data ?? []);\n let cents = 0;\n for (const it of items) {\n const price = (it.price ?? {}) as { unit_amount?: number; recurring?: { interval?: string } };\n const per = (price.unit_amount ?? 0) * ((it.quantity as number) ?? 1);\n cents += price.recurring?.interval === \"month\" ? per * 12 : per;\n }\n return cents;\n}\n","// Admin aggregation routes: the dashboard overview and the billing table. Both\n// join db rows with live Stripe reads (Stripe is the source of truth for money),\n// keyed by the vault stripe_secret_key, and degrade to `billingReady: false`\n// when no key is vaulted — so a hub that runs no membership billing simply drops\n// the section. Admin-gated.\nimport { getVaultSecret } from \"./auth\";\nimport { stripeCall } from \"./payments-stripe\";\nimport { resolveScheduling } from \"./scheduling\";\nimport { dashboardMetricData, subAnnualCents } from \"./series\";\nimport { json } from \"./worker-context\";\nimport type { ChapterEnv, WorkerContext } from \"./worker-context\";\nimport type { Route } from \"./worker-routes\";\nimport type { ChapterDb, ChapterScheduling } from \"./types\";\n\nasync function gate(req: Request, env: ChapterEnv, ctx: WorkerContext): Promise<ChapterDb | Response> {\n const rawDb = ctx.makeDb(env);\n const u = await ctx.verifyUser(req, env);\n if (!u) return json({ error: \"unauthorized\" }, 401);\n if (!(await ctx.isAdmin(rawDb, u))) return json({ error: \"forbidden\" }, 403);\n return rawDb as unknown as ChapterDb;\n}\n\nconst rows = <T = Record<string, unknown>>(v: unknown): T[] => (Array.isArray(v) ? (v as T[]) : []);\n\n/** GET /api/admin/dashboard — application flow counts, pipeline stage counts +\n * weekly delta, the upcoming call agenda, and (when billing is wired) live\n * revenue series. One call powers the overview. */\nexport const handleAdminDashboard: Route = async (req, url, env, ctx) => {\n if (req.method !== \"GET\" || url.pathname !== \"/api/admin/dashboard\") return null;\n const got = await gate(req, env, ctx);\n if (got instanceof Response) return got;\n const db = got;\n\n const now = Date.now();\n const d7 = now - 7 * 86_400_000;\n const d30 = now - 30 * 86_400_000;\n const data = await db.query({\n applications: { $: { order: { createdAt: \"desc\" }, limit: 1000 } },\n meetings: {\n $: {\n where: { status: \"scheduled\" },\n order: { startAt: \"asc\" },\n limit: 500,\n },\n },\n crm_record: { $: { where: { type: \"person\" }, limit: 1000 } },\n groups: { $: { where: { id: ctx.chapter.id }, limit: 1 } },\n });\n const apps = rows(data.applications);\n const applications = {\n total: apps.length,\n last7: apps.filter((a) => (a.createdAt as number) >= d7).length,\n last30: apps.filter((a) => (a.createdAt as number) >= d30).length,\n };\n const pipeline: Record<string, number> = {};\n const pipelineDelta: Record<string, number> = {};\n for (const s of ctx.chapter.pipeline.stages) {\n pipeline[s] = 0;\n pipelineDelta[s] = 0;\n }\n for (const r of rows(data.crm_record)) {\n const s = r.stage as string;\n if (s in pipeline) {\n pipeline[s] = (pipeline[s] ?? 0) + 1;\n const sc = typeof r.stageChangedAt === \"number\" ? r.stageChangedAt : Date.parse(String(r.stageChangedAt));\n if (Number.isFinite(sc) && sc >= d7) pipelineDelta[s] = (pipelineDelta[s] ?? 0) + 1;\n }\n }\n\n const meetings = rows(data.meetings);\n const appById = new Map(apps.map((a) => [a.id, a]));\n const upcoming = meetings.filter((m) => (m.startAt as number) >= now - 3_600_000);\n const calls = { upcoming: upcoming.length, needsAttention: meetings.filter((m) => m.drift && m.drift !== \"none\").length };\n const agenda = upcoming.slice(0, 8).map((m) => {\n const a = appById.get(m.applicationId);\n return {\n id: m.id,\n startAt: m.startAt,\n meetUrl: m.meetUrl ?? null,\n htmlLink: m.htmlLink ?? null,\n drift: m.drift ?? \"none\",\n name: a ? `${a.firstName} ${a.lastName}` : \"(unknown)\",\n email: (a?.email as string) ?? null,\n };\n });\n const group = data.groups?.[0];\n const timezone = resolveScheduling(group?.schedulingJson as ChapterScheduling | undefined).timezone;\n\n let revenue: Record<string, unknown> = { billingReady: false };\n let revenueSeries: unknown = null;\n let membersSeries: unknown = null;\n const sk = await getVaultSecret(db, \"stripe_secret_key\");\n if (sk) {\n const subsRes = await stripeCall(sk, \"GET\", \"/v1/subscriptions\", { limit: 100, status: \"all\" });\n if (subsRes.ok) {\n const subs = rows(subsRes.body.data);\n const subMs = (s: Record<string, unknown>) => ((s.created as number) ?? 0) * 1000;\n membersSeries = dashboardMetricData(subs.map((s) => ({ t: subMs(s), v: 1 })), now);\n revenueSeries = dashboardMetricData(subs.map((s) => ({ t: subMs(s), v: subAnnualCents(s) })), now);\n const active = subs.filter((s) => s.status === \"active\");\n revenue = {\n billingReady: true,\n testMode: String(group?.stripePublishableKey ?? \"\").startsWith(\"pk_test\"),\n activeCount: active.length,\n annualRunRateCents: active.reduce((sum, s) => sum + subAnnualCents(s), 0),\n newPaid7: subs.filter((s) => subMs(s) >= d7).length,\n newPaid30: subs.filter((s) => subMs(s) >= d30).length,\n };\n }\n }\n const applicationsSeries = dashboardMetricData(apps.map((a) => ({ t: (a.createdAt as number) || 0, v: 1 })), now);\n return json({ applications, applicationsSeries, pipeline, pipelineDelta, calls, agenda, timezone, revenue, revenueSeries, membersSeries });\n};\n\ninterface SubItem {\n price?: { unit_amount?: number; recurring?: { interval?: string } };\n quantity?: number;\n current_period_end?: number;\n}\n\n/** GET /api/admin/billing — applications joined with live Stripe subscription\n * state. `truncated` flags a >100-subscription page instead of silently losing\n * rows. `billingReady: false` when no stripe_secret_key is vaulted. */\nexport const handleAdminBilling: Route = async (req, url, env, ctx) => {\n if (req.method !== \"GET\" || url.pathname !== \"/api/admin/billing\") return null;\n const got = await gate(req, env, ctx);\n if (got instanceof Response) return got;\n const db = got;\n\n const sk = await getVaultSecret(db, \"stripe_secret_key\");\n if (!sk) return json({ billingReady: false, rows: [], summary: null });\n const [data, subsRes] = await Promise.all([\n db.query({\n applications: { $: { order: { createdAt: \"desc\" }, limit: 200 } },\n groups: { $: { where: { id: ctx.chapter.id }, limit: 1 } },\n }),\n stripeCall(sk, \"GET\", \"/v1/subscriptions\", { limit: 100, status: \"all\" }),\n ]);\n const testMode = String(data.groups?.[0]?.stripePublishableKey ?? \"\").startsWith(\"pk_test\");\n if (!subsRes.ok) return json({ error: \"billing lookup failed upstream\" }, 502);\n const subById = new Map(rows(subsRes.body.data).map((s) => [s.id as string, s]));\n\n const billingRows = [];\n for (const a of rows(data.applications)) {\n if (!a.stripeCustomerId && !a.stripeSubscriptionId) continue;\n const sub = a.stripeSubscriptionId ? subById.get(a.stripeSubscriptionId as string) : undefined;\n const items = (sub?.items as { data?: SubItem[] } | undefined)?.data ?? [];\n let amountCents = 0;\n let interval = \"year\";\n for (const it of items) {\n amountCents += (it.price?.unit_amount ?? 0) * (it.quantity ?? 1);\n interval = it.price?.recurring?.interval ?? interval;\n }\n const periodEnd = (sub?.current_period_end as number | undefined) ?? items[0]?.current_period_end;\n billingRows.push({\n id: a.id as string,\n name: `${a.firstName} ${a.lastName}`,\n email: a.email as string,\n applicationStatus: a.status as string,\n subscriptionStatus: (sub?.status as string) ?? null,\n cancelAtPeriodEnd: sub?.cancel_at_period_end === true,\n amountCents,\n interval,\n renewalAt: periodEnd ? periodEnd * 1000 : ((a.renewalAt as number) ?? null),\n });\n }\n const renewing = billingRows.filter((r) => r.subscriptionStatus === \"active\" && !r.cancelAtPeriodEnd);\n const soonCutoff = Date.now() + 60 * 86_400_000;\n const summary = {\n activeCount: billingRows.filter((r) => r.subscriptionStatus === \"active\").length,\n annualizedCents: renewing.reduce((s, r) => s + r.amountCents * (r.interval === \"month\" ? 12 : 1), 0),\n renewingSoonCount: renewing.filter((r) => r.renewalAt && r.renewalAt < soonCutoff).length,\n pastDueCount: billingRows.filter((r) => r.subscriptionStatus === \"past_due\").length,\n canceledCount: billingRows.filter((r) => r.subscriptionStatus === \"canceled\" || r.cancelAtPeriodEnd).length,\n refundedCount: billingRows.filter((r) => r.applicationStatus === \"refunded\").length,\n };\n return json({\n billingReady: true,\n testMode,\n truncated: subsRes.body.has_more === true,\n rows: billingRows,\n summary,\n });\n};\n","// Admin lifecycle routes: meeting reschedule/cancel and application\n// approve/refund/manual-patch. These are the operational actions; each wires a\n// chapter primitive (canApprove, meetingRescheduleUpdate, refundedPatch) and the\n// operations policy seams (onApprove.promoteTo/send, refund.allowedFrom/\n// cancelSubscription), and mirrors the change into the CRM. Admin-gated.\nimport { computeBookableSlots, initCalendar } from \"@odla-ai/calendar\";\nimport { getVaultSecret } from \"./auth\";\nimport { approveApplication } from \"./approve-application\";\nimport { crmDeps, syncApplicationToCrm } from \"./crm-sync\";\nimport { stripeCall } from \"./payments-stripe\";\nimport { canTransition } from \"./pipeline\";\nimport { resolveScheduling, endForSlot, isSlotAvailable, meetingRescheduleUpdate, slotWindow } from \"./scheduling\";\nimport { json } from \"./worker-context\";\nimport type { ChapterEnv, WorkerContext } from \"./worker-context\";\nimport type { Route } from \"./worker-routes\";\nimport type { ChapterDb, ChapterScheduling } from \"./types\";\n\nasync function gate(req: Request, env: ChapterEnv, ctx: WorkerContext): Promise<ChapterDb | Response> {\n const rawDb = ctx.makeDb(env);\n const u = await ctx.verifyUser(req, env);\n if (!u) return json({ error: \"unauthorized\" }, 401);\n if (!(await ctx.isAdmin(rawDb, u))) return json({ error: \"forbidden\" }, 403);\n return rawDb as unknown as ChapterDb;\n}\n\nconst calFor = (env: ChapterEnv) =>\n initCalendar({ appId: env.ODLA_APP_ID, env: env.ODLA_ENV, adminToken: env.ODLA_API_KEY, endpoint: env.ODLA_PLATFORM });\nconst readJson = async (req: Request): Promise<Record<string, unknown> | null> => {\n try {\n return (await req.json()) as Record<string, unknown>;\n } catch {\n return null;\n }\n};\nasync function loadApp(db: ChapterDb, id: string): Promise<Record<string, unknown> | null> {\n const { applications } = await db.query({ applications: { $: { where: { id }, limit: 1 } } });\n return applications?.[0] ?? null;\n}\nasync function loadGroup(db: ChapterDb, id: string): Promise<Record<string, unknown> | null> {\n const { groups } = await db.query({ groups: { $: { where: { id }, limit: 1 } } });\n return groups?.[0] ?? null;\n}\n\n/** POST /api/admin/meetings/:id/reschedule — move an intro call to an open slot;\n * the Google event moves (Meet link + invite thread survive). */\nexport const handleAdminMeetingReschedule: Route = async (req, url, env, ctx) => {\n const m = url.pathname.match(/^\\/api\\/admin\\/meetings\\/([0-9a-f-]+)\\/reschedule$/);\n if (req.method !== \"POST\" || !m) return null;\n const got = await gate(req, env, ctx);\n if (got instanceof Response) return got;\n const db = got;\n const body = await readJson(req);\n const startAt = Number(body?.startAt);\n if (!Number.isFinite(startAt)) return json({ error: \"startAt required\" }, 400);\n\n const { meetings } = await db.query({ meetings: { $: { where: { id: m[1] }, limit: 1 } } });\n const meeting = meetings?.[0];\n if (!meeting) return json({ error: \"not found\" }, 404);\n if (meeting.status !== \"scheduled\") return json({ error: \"meeting is cancelled\" }, 409);\n if (!meeting.googleEventId) return json({ error: \"no calendar event on file\" }, 409);\n\n const cfg = resolveScheduling((await loadGroup(db, String(meeting.groupId ?? ctx.chapter.id)))?.schedulingJson as ChapterScheduling | undefined);\n const endAt = endForSlot(startAt, cfg.slotMinutes);\n const cal = calFor(env);\n try {\n const { from, to } = slotWindow(Date.now(), cfg.windowDays);\n const fb = await cal.availability.freeBusy({ timeMin: from, timeMax: to });\n const slots = computeBookableSlots(fb.busy, {\n from: fb.timeMin,\n to: fb.timeMax,\n timezone: cfg.timezone,\n slotMinutes: cfg.slotMinutes,\n businessHours: { days: [...cfg.days], startHour: cfg.startHour, endHour: cfg.endHour },\n minNoticeMs: cfg.minNoticeHours * 3_600_000,\n });\n if (!isSlotAvailable(slots, startAt)) return json({ error: \"slot no longer available\", code: \"calendar_slot_unavailable\" }, 409);\n await cal.actions.reschedule(String(meeting.googleEventId), {\n idempotencyKey: `meeting:${String(meeting.id)}:reschedule:${startAt}:${endAt}`,\n startAt,\n endAt,\n });\n } catch {\n return json({ error: \"reschedule failed upstream\" }, 502);\n }\n await db.transact([{ t: \"update\", ns: \"meetings\", id: String(meeting.id), attrs: meetingRescheduleUpdate(startAt, endAt) }]);\n await db.transact([{ t: \"update\", ns: \"applications\", id: String(meeting.applicationId), attrs: { meetingAt: startAt } }]);\n return json({ ok: true, startAt, endAt });\n};\n\n/** POST /api/admin/meetings/:id/cancel — cancel an intro call; the Google event\n * is removed (Google notifies the attendee). */\nexport const handleAdminMeetingCancel: Route = async (req, url, env, ctx) => {\n const m = url.pathname.match(/^\\/api\\/admin\\/meetings\\/([0-9a-f-]+)\\/cancel$/);\n if (req.method !== \"POST\" || !m) return null;\n const got = await gate(req, env, ctx);\n if (got instanceof Response) return got;\n const db = got;\n\n const { meetings } = await db.query({ meetings: { $: { where: { id: m[1] }, limit: 1 } } });\n const meeting = meetings?.[0];\n if (!meeting) return json({ error: \"not found\" }, 404);\n if (meeting.status !== \"scheduled\") return json({ error: \"already cancelled\" }, 409);\n if (meeting.googleEventId) {\n try {\n await calFor(env).actions.cancel(String(meeting.googleEventId), {\n idempotencyKey: `meeting:${String(meeting.id)}:cancel`,\n });\n } catch {\n return json({ error: \"cancel failed upstream\" }, 502);\n }\n }\n await db.transact([{ t: \"update\", ns: \"meetings\", id: String(meeting.id), attrs: { status: \"cancelled\", drift: \"none\" } }]);\n await db.transact([{ t: \"update\", ns: \"applications\", id: String(meeting.applicationId), attrs: { meetingAt: 0, meetingLink: \"\" } }]);\n return json({ ok: true });\n};\n\n/** POST /api/admin/applications/:id/approve — the deliberate approval: advance to\n * the approvable target, promote the Clerk role (operations.onApprove.promoteTo),\n * and send the approve template (operations.onApprove.send). Mirrors to CRM. */\nexport const handleAdminApprove: Route = async (req, url, env, ctx) => {\n const m = url.pathname.match(/^\\/api\\/admin\\/applications\\/([0-9a-f-]+)\\/approve$/);\n if (req.method !== \"POST\" || !m) return null;\n const got = await gate(req, env, ctx);\n if (got instanceof Response) return got;\n const db = got;\n const id = m[1] as string;\n\n const app = await loadApp(db, id);\n if (!app) return json({ error: \"not found\" }, 404);\n const result = await approveApplication({ db, env, ctx, app, origin: url.origin, reason: \"manual\" });\n if (!result.ok) return json({ error: result.error }, result.status);\n return json({ ok: true, status: \"approved\", rolePromoted: result.rolePromoted, emailLogged: result.emailLogged });\n};\n\n/** POST /api/admin/applications/:id/refund — refund the first paid charge and\n * (per operations.refund) cancel the subscription. The status flip to \"refunded\"\n * comes from the charge.refunded webhook, so Stripe stays the source of truth. */\nexport const handleAdminRefund: Route = async (req, url, env, ctx) => {\n const m = url.pathname.match(/^\\/api\\/admin\\/applications\\/([0-9a-f-]+)\\/refund$/);\n if (req.method !== \"POST\" || !m) return null;\n const got = await gate(req, env, ctx);\n if (got instanceof Response) return got;\n const db = got;\n\n const app = await loadApp(db, m[1] as string);\n if (!app) return json({ error: \"not found\" }, 404);\n if (app.status === \"refunded\") return json({ error: \"already refunded\" }, 409);\n const allowedFrom = ctx.chapter.operations.refund.allowedFrom;\n if (allowedFrom && !allowedFrom.includes(String(app.status))) {\n return json({ error: `cannot refund from status \"${String(app.status)}\"` }, 409);\n }\n const subscriptionId = app.stripeSubscriptionId as string | undefined;\n const customerId = app.stripeCustomerId as string | undefined;\n if (!customerId) return json({ error: \"no customer on file\" }, 409);\n const sk = await getVaultSecret(db, \"stripe_secret_key\");\n if (!sk) return json({ error: \"payments not configured\" }, 503);\n\n const charges = await stripeCall(sk, \"GET\", \"/v1/charges\", { customer: customerId, limit: 100 });\n if (!charges.ok) return json({ error: \"refund failed upstream\" }, 502);\n const succeeded = ((charges.body.data as Array<Record<string, unknown>>) ?? []).filter((c) => c.status === \"succeeded\" && c.refunded !== true);\n const firstCharge = succeeded[succeeded.length - 1];\n if (!firstCharge) return json({ error: \"no paid charge to refund\" }, 409);\n\n const refund = await stripeCall(sk, \"POST\", \"/v1/refunds\", { charge: String(firstCharge.id) });\n if (!refund.ok) return json({ error: \"refund failed upstream\" }, 502);\n let subscriptionCanceled = false;\n if (ctx.chapter.operations.refund.cancelSubscription && subscriptionId) {\n const cancel = await stripeCall(sk, \"DELETE\", `/v1/subscriptions/${subscriptionId}`);\n subscriptionCanceled = cancel.ok;\n }\n return json({ ok: true, refundedCents: (refund.body.amount as number) ?? null, subscriptionCanceled });\n};\n\n/** PATCH /api/admin/applications/:id — manual correction escape hatch. Sets\n * `status` (gated by canTransition) and/or `meetingAt`. Mirrors a status move to\n * the CRM. */\nexport const handleAdminApplicationPatch: Route = async (req, url, env, ctx) => {\n const m = url.pathname.match(/^\\/api\\/admin\\/applications\\/([0-9a-f-]+)$/);\n if (req.method !== \"PATCH\" || !m) return null;\n const got = await gate(req, env, ctx);\n if (got instanceof Response) return got;\n const db = got;\n const id = m[1] as string;\n const body = await readJson(req);\n if (!body) return json({ error: \"invalid JSON body\" }, 400);\n\n const app = await loadApp(db, id);\n if (!app) return json({ error: \"not found\" }, 404);\n\n const attrs: Record<string, unknown> = {};\n if (body.status !== undefined) {\n const to = String(body.status);\n if (!ctx.chapter.pipeline.stages.includes(to)) return json({ error: `status must be one of: ${ctx.chapter.pipeline.stages.join(\", \")}` }, 400);\n if (!canTransition(String(app.status), to, ctx.chapter.pipeline)) return json({ error: `cannot move from \"${String(app.status)}\" to \"${to}\"` }, 409);\n attrs.status = to;\n }\n if (body.meetingAt !== undefined) {\n if (typeof body.meetingAt !== \"number\" || !Number.isFinite(body.meetingAt)) return json({ error: \"meetingAt must be epoch milliseconds\" }, 400);\n attrs.meetingAt = body.meetingAt;\n }\n if (Object.keys(attrs).length === 0) return json({ error: \"nothing to update\" }, 400);\n\n await db.transact([{ t: \"update\", ns: \"applications\", id, attrs }]);\n if (attrs.status !== undefined) {\n await syncApplicationToCrm(crmDeps(db, ctx), { app: { ...app, ...attrs }, stage: String(attrs.status) }).catch(() => undefined);\n }\n return json({ ok: true });\n};\n","// Admin email + comms routes: read/write the group's owner-editable email config,\n// the send audit log, an owner-triggered test send, and one person's comms\n// timeline (sent lifecycle mail + the Google calendar invitations reconstructed\n// from meeting rows). Admin-gated.\nimport { renderTemplateBody } from \"./email\";\nimport { sendTemplated, emailGroupFrom, EMAIL_TEMPLATE_NAMES } from \"./notify\";\nimport { json } from \"./worker-context\";\nimport type { ChapterEnv, WorkerContext } from \"./worker-context\";\nimport type { Route } from \"./worker-routes\";\nimport type { ChapterDb } from \"./types\";\n\nasync function gate(req: Request, env: ChapterEnv, ctx: WorkerContext): Promise<ChapterDb | Response> {\n const rawDb = ctx.makeDb(env);\n const u = await ctx.verifyUser(req, env);\n if (!u) return json({ error: \"unauthorized\" }, 401);\n if (!(await ctx.isAdmin(rawDb, u))) return json({ error: \"forbidden\" }, 403);\n return rawDb as unknown as ChapterDb;\n}\nasync function loadGroup(db: ChapterDb, id: string): Promise<Record<string, unknown> | null> {\n const { groups } = await db.query({ groups: { $: { where: { id }, limit: 1 } } });\n return groups?.[0] ?? null;\n}\nconst str = (v: unknown, d = \"\"): string => (typeof v === \"string\" ? v : d);\nconst notifyDeps = (db: ChapterDb, env: ChapterEnv) => ({\n db,\n envName: env.ODLA_ENV,\n sender: env.SEND_EMAIL,\n from: env.EMAIL_FROM,\n now: () => Date.now(),\n newId: () => crypto.randomUUID(),\n});\n\n/** GET/PUT /api/admin/group/email — read the owner-editable email config\n * (templates + addresses + read-only delivery wiring), or replace it. */\nexport const handleAdminGroupEmail: Route = async (req, url, env, ctx) => {\n if (url.pathname !== \"/api/admin/group/email\" || (req.method !== \"GET\" && req.method !== \"PUT\")) return null;\n const got = await gate(req, env, ctx);\n if (got instanceof Response) return got;\n const db = got;\n const group = await loadGroup(db, ctx.chapter.id);\n if (!group) return json({ error: \"not found\" }, 404);\n\n if (req.method === \"GET\") {\n const stored = (group.emailTemplates ?? {}) as Record<string, { subject?: string; text?: string; enabled?: boolean }>;\n const emailTemplates: Record<string, { subject: string; text: string; enabled: boolean }> = {};\n for (const key of EMAIL_TEMPLATE_NAMES) {\n const t = stored[key];\n if (t) emailTemplates[key] = { subject: str(t.subject), text: str(t.text), enabled: t.enabled !== false };\n }\n return json({\n groupId: group.id,\n name: group.name,\n replyTo: str(group.replyTo),\n notificationEmail: str(group.notificationEmail),\n debugEmail: str(group.debugEmail),\n emailTemplates,\n commitmentText: str(group.commitmentText),\n normsText: str(group.normsText),\n refundPolicyText: str(group.refundPolicyText),\n // Read-only delivery wiring — surfaced so \"why did this not send?\" is\n // answerable without logs.\n envName: env.ODLA_ENV,\n transport: env.SEND_EMAIL && env.EMAIL_FROM ? \"cloudflare\" : \"log-only\",\n fromEmail: env.EMAIL_FROM ?? null,\n });\n }\n\n let body: Record<string, unknown>;\n try {\n body = (await req.json()) as Record<string, unknown>;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n const templates = body.emailTemplates;\n if (!templates || typeof templates !== \"object\") return json({ error: \"emailTemplates object required\" }, 400);\n const clean: Record<string, { subject: string; text: string; enabled: boolean }> = {};\n for (const key of EMAIL_TEMPLATE_NAMES) {\n const t = (templates as Record<string, { subject?: unknown; text?: unknown; enabled?: unknown }>)[key];\n const subject = typeof t?.subject === \"string\" ? t.subject.trim() : \"\";\n const text = typeof t?.text === \"string\" ? t.text : \"\";\n if (!subject || !text.trim()) return json({ error: `template \"${key}\" needs a subject and a body` }, 400);\n if (/[\\r\\n]/.test(subject) || subject.length > 200) return json({ error: `template \"${key}\" subject must be a single line under 200 characters` }, 400);\n if (text.length > 10_000) return json({ error: `template \"${key}\" body is too long` }, 400);\n clean[key] = { subject, text, enabled: t?.enabled !== false };\n }\n const emailish = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n const notificationEmail = str(body.notificationEmail).trim();\n const replyTo = str(body.replyTo).trim();\n const debugEmail = str(body.debugEmail).trim();\n if (!emailish.test(notificationEmail)) return json({ error: \"notification address must be a valid email\" }, 400);\n if (!emailish.test(replyTo)) return json({ error: \"reply-to address must be a valid email\" }, 400);\n if (debugEmail && !emailish.test(debugEmail)) return json({ error: \"debug address must be a valid email\" }, 400);\n const commitmentText = str(body.commitmentText);\n const normsText = str(body.normsText);\n if (commitmentText.length > 5000 || normsText.length > 5000) return json({ error: \"commitment/norms text is too long\" }, 400);\n\n await db.transact([{ t: \"update\", ns: \"groups\", id: ctx.chapter.id, attrs: { emailTemplates: clean, commitmentText, normsText, notificationEmail, replyTo, debugEmail } }]);\n return json({ ok: true });\n};\n\n/** GET /api/admin/email/log — the send audit: every attempted send. */\nexport const handleAdminEmailLog: Route = async (req, url, env, ctx) => {\n if (req.method !== \"GET\" || url.pathname !== \"/api/admin/email/log\") return null;\n const got = await gate(req, env, ctx);\n if (got instanceof Response) return got;\n const { emailLog } = await got.query({ emailLog: { $: { order: { sentAt: \"desc\" }, limit: 50 } } });\n const sends = ((emailLog ?? []) as Array<Record<string, unknown>>).map((r) => ({\n id: r.id,\n template: r.template,\n to: r.to,\n subject: r.subject,\n transport: r.transport,\n redirected: r.redirected === true,\n error: (r.error as string) ?? null,\n sentAt: r.sentAt,\n }));\n return json({ sends });\n};\n\n/** POST /api/admin/email/test — send one template with sample data to the\n * notification address, ignoring the `enabled` flag (the admin asked). */\nexport const handleAdminEmailTest: Route = async (req, url, env, ctx) => {\n if (req.method !== \"POST\" || url.pathname !== \"/api/admin/email/test\") return null;\n const got = await gate(req, env, ctx);\n if (got instanceof Response) return got;\n const db = got;\n let body: Record<string, unknown>;\n try {\n body = (await req.json()) as Record<string, unknown>;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n const template = str(body.template);\n if (!(EMAIL_TEMPLATE_NAMES as readonly string[]).includes(template)) {\n return json({ error: `template must be one of: ${EMAIL_TEMPLATE_NAMES.join(\", \")}` }, 400);\n }\n const group = await loadGroup(db, ctx.chapter.id);\n if (!group) return json({ error: \"not found\" }, 404);\n const res = await sendTemplated(notifyDeps(db, env), {\n group: emailGroupFrom(group),\n template,\n to: str(group.notificationEmail),\n vars: { firstName: \"Sample\", lastName: \"Person\", email: \"sample@example.com\", phone: \"(555) 010-0100\", state: \"CA\", adminUrl: `${url.origin}/admin/`, membersUrl: `${url.origin}/members/` },\n dedupeKey: `test:${template}:${Date.now()}`,\n force: true,\n });\n return json({ ok: res.sent, reason: res.reason ?? null, to: str(group.notificationEmail), redirected: env.ODLA_ENV !== \"prod\" && !!group.debugEmail });\n};\n\n/** GET /api/admin/people/:applicationId/comms — one person's timeline: sent\n * lifecycle mail (adminNotification dropped — it goes to the team) plus the\n * Google calendar invitations reconstructed from their meeting rows. */\nexport const handleAdminComms: Route = async (req, url, env, ctx) => {\n const m = url.pathname.match(/^\\/api\\/admin\\/people\\/([0-9a-fA-F-]+)\\/comms$/);\n if (req.method !== \"GET\" || !m) return null;\n const got = await gate(req, env, ctx);\n if (got instanceof Response) return got;\n const db = got;\n const appId = m[1] as string;\n\n const data = await db.query({\n emailLog: {\n $: {\n where: { applicationId: appId },\n order: { sentAt: \"desc\" },\n limit: 100,\n },\n },\n meetings: { $: { where: { applicationId: appId } } },\n applications: { $: { where: { id: appId }, limit: 1 } },\n });\n const app = data.applications?.[0] ?? null;\n const group = await loadGroup(db, str(app?.groupId, ctx.chapter.id));\n const vars: Record<string, string> | null = app\n ? { firstName: str(app.firstName), lastName: str(app.lastName), email: str(app.email), phone: str(app.phone), state: str(app.state), adminUrl: `${url.origin}/admin/`, membersUrl: `${url.origin}/members/` }\n : null;\n\n const emails = ((data.emailLog ?? []) as Array<Record<string, unknown>>)\n .filter((r) => r.template !== \"adminNotification\")\n .map((r): Record<string, unknown> => {\n let mailBody: string | null = typeof r.body === \"string\" ? r.body : null;\n if (!mailBody && group && vars) mailBody = renderTemplateBody(emailGroupFrom(group), String(r.template), vars);\n const channel = r.error ? \"email (failed)\" : r.redirected ? \"email (dev-redirected)\" : r.transport === \"log-only\" ? \"email (not delivered)\" : \"email\";\n return { kind: \"email\", channel, label: String(r.template), subject: str(r.subject), to: (r.to as string) ?? null, body: mailBody, at: r.sentAt as number, error: (r.error as string) ?? null };\n });\n const calendar = ((data.meetings ?? []) as Array<Record<string, unknown>>).map((m2): Record<string, unknown> => ({\n kind: \"calendar\",\n channel: \"Google Calendar\",\n label: m2.status === \"cancelled\" ? \"Invitation (call later cancelled)\" : \"Meeting invitation\",\n subject: \"Introduction call invitation\",\n to: null,\n at: (m2.createdAt as number) ?? (m2.startAt as number),\n error: null,\n }));\n const items = [...emails, ...calendar].sort((a, b) => ((b.at as number) ?? 0) - ((a.at as number) ?? 0));\n return json({ items });\n};\n","// Leader-side network routes. The receiving route has its own module; these\n// admin-gated routes expose configured targets and fan one CRM record out to\n// selected followers with per-target vaulted credentials.\nimport { getRecord, typeSummary } from \"@odla-ai/crm\";\nimport { signFederatedRequest, verifyFederatedRequest } from \"@odla-ai/db\";\nimport { getVaultSecret } from \"./auth\";\nimport { DEFAULT_SHARE_FIELDS } from \"./network\";\nimport { json } from \"./worker-context\";\nimport type { ChapterEnv, Db, Route, Verified, WorkerContext } from \"./worker-context\";\nimport type { ChapterDb, ResolvedNetworkTarget } from \"./types\";\nimport type { NetworkRollup, NetworkRollupTarget, NetworkSnapshot } from \"./network\";\nimport { fetchNetworkTarget } from \"./worker-network-fetch\";\nimport { pushNetworkRecord } from \"./worker-network-push\";\n\nasync function gate(\n req: Request,\n env: ChapterEnv,\n ctx: WorkerContext,\n): Promise<{ response: Response } | { db: Db; user: Verified }> {\n const db = ctx.makeDb(env);\n const user = await ctx.verifyUser(req, env);\n if (!user) return { response: json({ error: \"unauthorized\" }, 401) };\n if (!(await ctx.isAdmin(db, user))) return { response: json({ error: \"forbidden\" }, 403) };\n return { db, user };\n}\n\n/** GET /api/admin/network/targets — non-secret target metadata for the UI. */\nexport const handleAdminNetworkTargets: Route = async (req, url, env, ctx) => {\n if (req.method !== \"GET\" || url.pathname !== \"/api/admin/network/targets\") return null;\n const got = await gate(req, env, ctx);\n if (\"response\" in got) return got.response;\n return json({\n targets: ctx.chapter.network.targets.map(({ id, name, url: targetUrl, fields, sharedNotes }) => ({\n id,\n name,\n url: targetUrl,\n types: Object.keys(fields ?? DEFAULT_SHARE_FIELDS),\n sharedNotes,\n })),\n });\n};\n\n/** GET /api/network/snapshot — signed, aggregate-only follower status. The\n * response contains no people, sessions, record fields, or database keys. */\nexport const handleNetworkSnapshot: Route = async (req, url, env, ctx) => {\n if (req.method !== \"GET\" || url.pathname !== \"/api/network/snapshot\") return null;\n const db = ctx.makeDb(env);\n const secret = await getVaultSecret(db as unknown as ChapterDb, \"network_share_secret\");\n if (!secret) return json({ error: \"unauthorized\" }, 401);\n const verified = await verifyFederatedRequest(req, { secret });\n if (!verified.ok) return json({ error: \"unauthorized\", reason: verified.reason }, 401);\n const types = await Promise.all(\n Object.keys(ctx.chapter.crm.config.types).map((type) =>\n typeSummary({ crm: ctx.chapter.crm, db: db as never }, type)),\n );\n const snapshot: NetworkSnapshot = {\n version: 1,\n site: { id: ctx.chapter.id, name: ctx.chapter.name, mode: ctx.chapter.mode },\n generatedAt: Date.now(),\n types,\n };\n return json(snapshot);\n};\n\nasync function snapshotOne(\n db: ChapterDb,\n env: ChapterEnv,\n ctx: WorkerContext,\n target: ResolvedNetworkTarget,\n): Promise<NetworkRollupTarget> {\n const secret = await getVaultSecret(db, target.secretName);\n if (!secret) return { id: target.id, name: target.name, url: target.url, available: false, error: \"edge secret is missing\" };\n const destination = new URL(\"/api/network/snapshot\", target.url);\n try {\n const headers = await signFederatedRequest({\n secret,\n sender: ctx.chapter.id,\n method: \"GET\",\n url: destination,\n });\n const response = await fetchNetworkTarget(env, target, destination, {\n headers,\n signal: AbortSignal.timeout(10_000),\n });\n const body = (await response.json().catch(() => null)) as NetworkSnapshot | { error?: string } | null;\n if (\n !response.ok ||\n !body ||\n !(\"version\" in body) ||\n body.version !== 1 ||\n !(\"site\" in body) ||\n body.site.id !== target.id ||\n !Array.isArray(body.types)\n ) {\n const upstream = body && \"error\" in body && typeof body.error === \"string\" ? body.error : undefined;\n return {\n id: target.id,\n name: target.name,\n url: target.url,\n available: false,\n error: upstream ?? (response.ok ? \"invalid follower snapshot\" : `follower returned ${response.status}`),\n };\n }\n return {\n id: target.id,\n name: target.name,\n url: target.url,\n available: true,\n generatedAt: body.generatedAt,\n types: body.types,\n };\n } catch (error) {\n return {\n id: target.id,\n name: target.name,\n url: target.url,\n available: false,\n error: error instanceof Error ? error.message : \"snapshot failed\",\n };\n }\n}\n\n/** GET /api/admin/network/rollup — leader-authenticated fan-out to configured\n * follower snapshots, plus cross-target aggregate totals. */\nexport const handleAdminNetworkRollup: Route = async (req, url, env, ctx) => {\n if (req.method !== \"GET\" || url.pathname !== \"/api/admin/network/rollup\") return null;\n const got = await gate(req, env, ctx);\n if (\"response\" in got) return got.response;\n const targets = await Promise.all(\n ctx.chapter.network.targets.map((target) =>\n snapshotOne(got.db as unknown as ChapterDb, env, ctx, target)),\n );\n const byType = new Map<string, { type: string; total: number; stages: Record<string, number> }>();\n for (const target of targets) {\n for (const type of target.types ?? []) {\n const aggregate = byType.get(type.type) ?? { type: type.type, total: 0, stages: {} };\n aggregate.total += type.total;\n for (const [stage, count] of Object.entries(type.stages)) {\n aggregate.stages[stage] = (aggregate.stages[stage] ?? 0) + count;\n }\n byType.set(type.type, aggregate);\n }\n }\n const rollup: NetworkRollup = {\n configured: targets.length,\n available: targets.filter((target) => target.available).length,\n totalRecords: [...byType.values()].reduce((sum, type) => sum + type.total, 0),\n types: [...byType.values()],\n targets,\n };\n return json(rollup);\n};\n\n/** POST /api/admin/network/push `{ recordId, targetIds }` — push one leader CRM\n * record to one or more configured followers. Each follower receives an\n * independently validated, allowlisted projection; partial failure is explicit. */\nexport const handleAdminNetworkPush: Route = async (req, url, env, ctx) => {\n if (req.method !== \"POST\" || url.pathname !== \"/api/admin/network/push\") return null;\n const got = await gate(req, env, ctx);\n if (\"response\" in got) return got.response;\n let body: { recordId?: unknown; targetIds?: unknown };\n try {\n body = (await req.json()) as typeof body;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n if (typeof body.recordId !== \"string\" || !Array.isArray(body.targetIds) || body.targetIds.length === 0) {\n return json({ error: \"recordId and a non-empty targetIds array are required\" }, 400);\n }\n const requested = new Set(body.targetIds.filter((id): id is string => typeof id === \"string\"));\n if (requested.size !== body.targetIds.length) return json({ error: \"targetIds must contain unique strings\" }, 400);\n const targets = ctx.chapter.network.targets.filter((target) => requested.has(target.id));\n if (targets.length !== requested.size) return json({ error: \"one or more targetIds are not configured\" }, 400);\n\n const record = await getRecord({ crm: ctx.chapter.crm, db: got.db as never }, body.recordId);\n if (!record) return json({ error: \"record not found\" }, 404);\n const results = await Promise.all(\n targets.map((target) =>\n pushNetworkRecord(got.db as unknown as ChapterDb, env, ctx, target, record)),\n );\n return json({ ok: results.every((result) => result.ok), results });\n};\n","import type { ChapterEnv } from \"./worker-context\";\nimport type { ResolvedNetworkTarget } from \"./types\";\n\ninterface NetworkFetcher {\n fetch(request: Request): Promise<Response>;\n}\n\nfunction targetFetcher(\n env: ChapterEnv,\n target: ResolvedNetworkTarget,\n): NetworkFetcher | null {\n if (!target.binding) return null;\n const candidate = (env as unknown as Record<string, unknown>)[target.binding];\n if (\n typeof candidate !== \"object\" ||\n candidate === null ||\n !(\"fetch\" in candidate) ||\n typeof candidate.fetch !== \"function\"\n ) {\n throw new Error(`service binding \"${target.binding}\" is unavailable`);\n }\n return candidate as NetworkFetcher;\n}\n\nexport function fetchNetworkTarget(\n env: ChapterEnv,\n target: ResolvedNetworkTarget,\n destination: URL,\n init: RequestInit,\n): Promise<Response> {\n const binding = targetFetcher(env, target);\n return binding\n ? binding.fetch(new Request(destination, init))\n : globalThis.fetch(destination, init);\n}\n","import { recordDeliveryAttempt } from \"@odla-ai/crm\";\nimport type { CrmRecord } from \"@odla-ai/crm\";\nimport { signFederatedRequest } from \"@odla-ai/db\";\nimport { getVaultSecret } from \"./auth\";\nimport { sharedRecordFromCrm } from \"./network\";\nimport type { WorkerContext } from \"./worker-context\";\nimport type { ChapterDb, ResolvedNetworkTarget } from \"./types\";\nimport { fetchNetworkTarget } from \"./worker-network-fetch\";\n\nexport interface NetworkPushResult {\n id: string;\n name: string;\n ok: boolean;\n status?: number;\n recordId?: string;\n error?: string;\n}\n\nexport async function pushNetworkRecord(\n db: ChapterDb,\n env: Parameters<typeof fetchNetworkTarget>[0],\n ctx: WorkerContext,\n target: ResolvedNetworkTarget,\n record: CrmRecord,\n): Promise<NetworkPushResult> {\n const secret = await getVaultSecret(db, target.secretName);\n const crmDeps = {\n crm: ctx.chapter.crm,\n db: db as never,\n now: () => Date.now(),\n newId: () => crypto.randomUUID(),\n };\n if (!secret) {\n const error = `vault secret \"${target.secretName}\" is missing`;\n await recordDeliveryAttempt(crmDeps, {\n recordId: record.id,\n targetId: target.id,\n status: \"failed\",\n payloadVersion: 2,\n error,\n });\n return { id: target.id, name: target.name, ok: false, error };\n }\n let payload;\n try {\n payload = sharedRecordFromCrm(ctx.chapter.crm, record, target, ctx.chapter.id);\n } catch (err) {\n return {\n id: target.id,\n name: target.name,\n ok: false,\n error: err instanceof Error ? err.message : \"record is not shareable\",\n };\n }\n const payloadBody = JSON.stringify(payload);\n const destination = new URL(\"/api/network/shared\", target.url);\n try {\n const signed = await signFederatedRequest({\n secret,\n sender: ctx.chapter.id,\n method: \"POST\",\n url: destination,\n body: payloadBody,\n });\n const res = await fetchNetworkTarget(env, target, destination, {\n method: \"POST\",\n headers: { ...signed, \"content-type\": \"application/json\" },\n body: payloadBody,\n signal: AbortSignal.timeout(10_000),\n });\n const responseBody = (await res.json().catch(() => ({}))) as {\n recordId?: string;\n error?: string;\n };\n if (!res.ok) {\n const error = responseBody.error ?? \"follower rejected the record\";\n await recordDeliveryAttempt(crmDeps, {\n recordId: record.id,\n targetId: target.id,\n status: \"failed\",\n payloadVersion: 2,\n error,\n });\n return {\n id: target.id,\n name: target.name,\n ok: false,\n status: res.status,\n error,\n };\n }\n await recordDeliveryAttempt(crmDeps, {\n recordId: record.id,\n targetId: target.id,\n status: \"delivered\",\n payloadVersion: 2,\n ...(responseBody.recordId ? { remoteRecordId: responseBody.recordId } : {}),\n });\n return {\n id: target.id,\n name: target.name,\n ok: true,\n status: res.status,\n recordId: responseBody.recordId,\n };\n } catch (err) {\n const error = err instanceof Error ? err.message : \"delivery failed\";\n await recordDeliveryAttempt(crmDeps, {\n recordId: record.id,\n targetId: target.id,\n status: \"failed\",\n payloadVersion: 2,\n error,\n });\n return { id: target.id, name: target.name, ok: false, error };\n }\n}\n","import { listRecords } from \"@odla-ai/crm\";\nimport { signFederatedRequest, verifyFederatedRequest } from \"@odla-ai/db\";\nimport { getVaultSecret } from \"./auth\";\nimport type {\n NetworkRecord,\n NetworkRecordPage,\n} from \"./network-contract\";\nimport type { ChapterDb, ResolvedNetworkTarget } from \"./types\";\nimport { fetchNetworkTarget } from \"./worker-network-fetch\";\nimport { json } from \"./worker-context\";\nimport type {\n ChapterEnv,\n Db,\n Route,\n Verified,\n WorkerContext,\n} from \"./worker-context\";\n\nconst IDENTIFIER = /^[a-z][a-zA-Z0-9_]*$/;\nconst MAX_PAGE = 50;\nconst MAX_OFFSET = 10_000;\nconst MAX_SEARCH = 200;\n\nasync function gate(\n req: Request,\n env: ChapterEnv,\n ctx: WorkerContext,\n): Promise<{ response: Response } | { db: Db; user: Verified }> {\n const db = ctx.makeDb(env);\n const user = await ctx.verifyUser(req, env);\n if (!user) return { response: json({ error: \"unauthorized\" }, 401) };\n if (!(await ctx.isAdmin(db, user))) return { response: json({ error: \"forbidden\" }, 403) };\n return { db, user };\n}\n\nfunction integer(\n value: string | null,\n fallback: number,\n min: number,\n max: number,\n): number | null {\n if (value == null || value === \"\") return fallback;\n if (!/^\\d+$/.test(value)) return null;\n const parsed = Number(value);\n return Number.isSafeInteger(parsed) && parsed >= min && parsed <= max ? parsed : null;\n}\n\nfunction projectRecord(\n record: Awaited<ReturnType<typeof listRecords>>[\"records\"][number],\n allowed: readonly string[],\n): NetworkRecord {\n const fields = Object.fromEntries(\n allowed.flatMap((name) =>\n Object.prototype.hasOwnProperty.call(record.fields, name)\n ? [[name, record.fields[name]]]\n : []),\n );\n return {\n id: record.id,\n type: record.type,\n name: record.name,\n ...(record.stage ? { stage: record.stage } : {}),\n fields,\n createdAt: record.createdAt,\n updatedAt: record.updatedAt,\n };\n}\n\n/** GET /api/network/records — a signed, follower-owned CRM projection.\n * Merely possessing the edge secret is insufficient: the signed sender must\n * also be declared in `network.readers`, and only that reader's fields leave. */\nexport const handleNetworkRecords: Route = async (req, url, env, ctx) => {\n if (req.method !== \"GET\" || url.pathname !== \"/api/network/records\") return null;\n const db = ctx.makeDb(env);\n const secret = await getVaultSecret(db as unknown as ChapterDb, \"network_share_secret\");\n const readers = ctx.chapter.network.readers;\n if (!secret || readers.length === 0) return json({ error: \"unauthorized\" }, 401);\n const verified = await verifyFederatedRequest(req, {\n secret,\n senders: readers.map((reader) => reader.id),\n });\n if (!verified.ok) return json({ error: \"unauthorized\", reason: verified.reason }, 401);\n const reader = readers.find((candidate) => candidate.id === verified.sender);\n const type = url.searchParams.get(\"type\") ?? \"\";\n const allowed = reader?.fields[type];\n if (!IDENTIFIER.test(type) || !allowed) return json({ error: \"record type is not shared with this reader\" }, 403);\n const limit = integer(url.searchParams.get(\"limit\"), 25, 1, MAX_PAGE);\n const offset = integer(url.searchParams.get(\"offset\"), 0, 0, MAX_OFFSET);\n const search = (url.searchParams.get(\"search\") ?? \"\").trim();\n if (limit == null || offset == null || search.length > MAX_SEARCH) {\n return json({ error: \"invalid pagination or search parameters\" }, 400);\n }\n const page = await listRecords(\n { crm: ctx.chapter.crm, db: db as never },\n {\n type,\n limit,\n offset,\n ...(search ? { search } : {}),\n sort: { field: \"updatedAt\", dir: \"desc\" },\n },\n );\n const response: NetworkRecordPage = {\n version: 1,\n site: { id: ctx.chapter.id, name: ctx.chapter.name },\n type,\n records: page.records.map((record) => projectRecord(record, allowed)),\n total: page.total,\n limit: page.limit,\n offset: page.offset,\n };\n return json(response);\n};\n\nfunction targetFor(ctx: WorkerContext, id: string): ResolvedNetworkTarget | undefined {\n return ctx.chapter.network.targets.find((target) => target.id === id);\n}\n\nasync function readTargetRecords(\n db: ChapterDb,\n env: ChapterEnv,\n ctx: WorkerContext,\n target: ResolvedNetworkTarget,\n query: URLSearchParams,\n): Promise<{ ok: true; page: NetworkRecordPage } | { ok: false; error: string }> {\n const secret = await getVaultSecret(db, target.secretName);\n if (!secret) return { ok: false, error: \"edge secret is missing\" };\n const destination = new URL(\"/api/network/records\", target.url);\n destination.search = query.toString();\n try {\n const headers = await signFederatedRequest({\n secret,\n sender: ctx.chapter.id,\n method: \"GET\",\n url: destination,\n });\n const response = await fetchNetworkTarget(env, target, destination, {\n headers,\n signal: AbortSignal.timeout(10_000),\n });\n const body = (await response.json().catch(() => null)) as NetworkRecordPage | { error?: string } | null;\n if (\n !response.ok ||\n !body ||\n !(\"version\" in body) ||\n body.version !== 1 ||\n !(\"site\" in body) ||\n body.site.id !== target.id ||\n !Array.isArray(body.records)\n ) {\n const upstream = body && \"error\" in body && typeof body.error === \"string\" ? body.error : undefined;\n return {\n ok: false,\n error: upstream ?? (response.ok ? \"invalid follower record response\" : `follower returned ${response.status}`),\n };\n }\n return { ok: true, page: body };\n } catch (error) {\n return { ok: false, error: error instanceof Error ? error.message : \"record read failed\" };\n }\n}\n\n/** GET /api/admin/network/records — local-admin proxy for one signed follower\n * record window. Browser sessions and follower credentials never cross sites. */\nexport const handleAdminNetworkRecords: Route = async (req, url, env, ctx) => {\n if (req.method !== \"GET\" || url.pathname !== \"/api/admin/network/records\") return null;\n const got = await gate(req, env, ctx);\n if (\"response\" in got) return got.response;\n const targetId = url.searchParams.get(\"targetId\") ?? \"\";\n const type = url.searchParams.get(\"type\") ?? \"\";\n const target = targetFor(ctx, targetId);\n if (!target || !IDENTIFIER.test(type)) return json({ error: \"configured targetId and record type are required\" }, 400);\n const limit = integer(url.searchParams.get(\"limit\"), 25, 1, MAX_PAGE);\n const offset = integer(url.searchParams.get(\"offset\"), 0, 0, MAX_OFFSET);\n const search = (url.searchParams.get(\"search\") ?? \"\").trim();\n if (limit == null || offset == null || search.length > MAX_SEARCH) {\n return json({ error: \"invalid pagination or search parameters\" }, 400);\n }\n const query = new URLSearchParams({ type, limit: String(limit), offset: String(offset) });\n if (search) query.set(\"search\", search);\n const result = await readTargetRecords(\n got.db as unknown as ChapterDb,\n env,\n ctx,\n target,\n query,\n );\n return result.ok ? json(result.page) : json({ error: result.error }, 502);\n};\n","import type { NetworkRecordNote } from \"./network-contract\";\nimport { json } from \"./worker-context\";\nimport type { ChapterEnv, Db, Route, Verified, WorkerContext } from \"./worker-context\";\n\nconst IDENTIFIER = /^[a-z][a-zA-Z0-9_]*$/;\nconst RECORD_ID = /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,255}$/;\nconst MAX_NOTE = 4_000;\n\nasync function gate(\n req: Request,\n env: ChapterEnv,\n ctx: WorkerContext,\n): Promise<{ response: Response } | { db: Db; user: Verified }> {\n const db = ctx.makeDb(env);\n const user = await ctx.verifyUser(req, env);\n if (!user) return { response: json({ error: \"unauthorized\" }, 401) };\n if (!(await ctx.isAdmin(db, user))) return { response: json({ error: \"forbidden\" }, 403) };\n return { db, user };\n}\n\nfunction noteIdentity(url: URL, ctx: WorkerContext) {\n const targetId = url.searchParams.get(\"targetId\") ?? \"\";\n const recordType = url.searchParams.get(\"type\") ?? \"\";\n const recordId = url.searchParams.get(\"recordId\") ?? \"\";\n const configured = ctx.chapter.network.targets.some((target) => target.id === targetId);\n if (!configured || !IDENTIFIER.test(recordType) || !RECORD_ID.test(recordId)) return null;\n return {\n targetId,\n recordType,\n recordId,\n recordKey: `${targetId}:${recordType}:${recordId}`,\n };\n}\n\nfunction asNote(row: Record<string, unknown>): NetworkRecordNote {\n return {\n id: String(row.id),\n targetId: String(row.targetId),\n recordType: String(row.recordType),\n recordId: String(row.recordId),\n body: String(row.body),\n authorId: String(row.authorId),\n ...(typeof row.authorEmail === \"string\" ? { authorEmail: row.authorEmail } : {}),\n createdAt: Number(row.createdAt),\n };\n}\n\n/** GET/POST /api/admin/network/notes — leader-private annotations keyed to a\n * stable follower record identity. No note route exists on the follower. */\nexport const handleAdminNetworkNotes: Route = async (req, url, env, ctx) => {\n if (url.pathname !== \"/api/admin/network/notes\" || (req.method !== \"GET\" && req.method !== \"POST\")) return null;\n const got = await gate(req, env, ctx);\n if (\"response\" in got) return got.response;\n const identity = noteIdentity(url, ctx);\n if (!identity) return json({ error: \"valid targetId, type, and recordId are required\" }, 400);\n if (req.method === \"GET\") {\n const result = await got.db.query({\n networkNotes: {\n $: {\n where: { recordKey: identity.recordKey },\n order: { createdAt: \"desc\" },\n limit: 100,\n },\n },\n });\n return json({ notes: (result.networkNotes ?? []).map((row) => asNote(row as Record<string, unknown>)) });\n }\n const contentLength = Number(req.headers.get(\"content-length\") ?? 0);\n if (contentLength > MAX_NOTE * 2) return json({ error: \"note is too large\" }, 413);\n let input: { body?: unknown };\n try {\n input = (await req.json()) as typeof input;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n const body = typeof input.body === \"string\" ? input.body.trim() : \"\";\n if (!body || body.length > MAX_NOTE) return json({ error: `note must be 1–${MAX_NOTE} characters` }, 400);\n const id = crypto.randomUUID();\n const note: NetworkRecordNote = {\n id,\n targetId: identity.targetId,\n recordType: identity.recordType,\n recordId: identity.recordId,\n body,\n authorId: got.user.userId,\n ...(got.user.email ? { authorEmail: got.user.email } : {}),\n createdAt: Date.now(),\n };\n await got.db.transact([{\n t: \"update\",\n ns: \"networkNotes\",\n id,\n attrs: { ...note, recordKey: identity.recordKey },\n }]);\n return json({ note }, 201);\n};\n","import {\n addActivity,\n CRM_NS,\n getRecord,\n type CrmActivity,\n} from \"@odla-ai/crm\";\nimport { signFederatedRequest, verifyFederatedRequest } from \"@odla-ai/db\";\nimport { getVaultSecret } from \"./auth\";\nimport type { NetworkSharedNote } from \"./network-contract\";\nimport type { ChapterDb, ResolvedNetworkTarget } from \"./types\";\nimport { fetchNetworkTarget } from \"./worker-network-fetch\";\nimport { json } from \"./worker-context\";\nimport type {\n ChapterEnv,\n Db,\n Route,\n Verified,\n WorkerContext,\n} from \"./worker-context\";\n\nconst IDENTIFIER = /^[a-z][a-zA-Z0-9_]*$/;\nconst RECORD_ID = /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,255}$/;\nconst MUTATION_ID = /^[A-Za-z0-9_-]{16,128}$/;\nconst MAX_NOTE = 4_000;\nconst NETWORK_META = \"chapterNetwork\";\n\nasync function gate(\n req: Request,\n env: ChapterEnv,\n ctx: WorkerContext,\n): Promise<{ response: Response } | { db: Db; user: Verified }> {\n const db = ctx.makeDb(env);\n const user = await ctx.verifyUser(req, env);\n if (!user) return { response: json({ error: \"unauthorized\" }, 401) };\n if (!(await ctx.isAdmin(db, user))) return { response: json({ error: \"forbidden\" }, 403) };\n return { db, user };\n}\n\nfunction sharedNote(activity: CrmActivity, sourceId: string): NetworkSharedNote | null {\n const meta = activity.meta?.[NETWORK_META];\n if (!meta || typeof meta !== \"object\" || Array.isArray(meta)) return null;\n const value = meta as Record<string, unknown>;\n if (value.version !== 1 || value.sourceId !== sourceId || typeof value.body !== \"string\") return null;\n return {\n id: activity.id,\n sourceId,\n recordType: String(value.recordType ?? \"\"),\n recordId: activity.recordId,\n body: value.body,\n createdAt: activity.createdAt,\n };\n}\n\nasync function listSharedNotes(db: ChapterDb, sourceId: string, recordId: string): Promise<NetworkSharedNote[]> {\n const result = await db.query({\n [CRM_NS.activity]: {\n $: {\n where: {\n and: [\n { recordId },\n { authorId: `network:${sourceId}` },\n ],\n },\n order: { createdAt: \"desc\" },\n limit: 100,\n },\n },\n });\n return ((result[CRM_NS.activity] ?? []) as unknown as CrmActivity[])\n .flatMap((activity) => {\n const note = sharedNote(activity, sourceId);\n return note ? [note] : [];\n });\n}\n\nfunction sourceLabel(sourceId: string): string {\n return sourceId.split(\"-\").map((word) =>\n word ? `${word[0]?.toUpperCase()}${word.slice(1)}` : word).join(\" \");\n}\n\n/** GET/POST /api/network/shared-notes — a signed, follower-authorized note\n * lane. Writes append to the follower CRM feed, so the follower team sees the\n * note in its normal record workflow. */\nexport const handleNetworkSharedNotes: Route = async (req, url, env, ctx) => {\n if (url.pathname !== \"/api/network/shared-notes\" || (req.method !== \"GET\" && req.method !== \"POST\")) return null;\n if (req.method === \"POST\" && Number(req.headers.get(\"content-length\") ?? 0) > MAX_NOTE * 2) {\n return json({ error: \"note is too large\" }, 413);\n }\n const db = ctx.makeDb(env);\n const secret = await getVaultSecret(db as unknown as ChapterDb, \"network_share_secret\");\n const readers = ctx.chapter.network.readers;\n if (!secret || readers.length === 0) return json({ error: \"unauthorized\" }, 401);\n const verified = await verifyFederatedRequest(req, {\n secret,\n senders: readers.map((reader) => reader.id),\n });\n if (!verified.ok) return json({ error: \"unauthorized\", reason: verified.reason }, 401);\n const reader = readers.find((candidate) => candidate.id === verified.sender);\n const recordType = url.searchParams.get(\"type\") ?? \"\";\n const recordId = url.searchParams.get(\"recordId\") ?? \"\";\n if (!IDENTIFIER.test(recordType) || !RECORD_ID.test(recordId) || !reader?.sharedNotes.includes(recordType)) {\n return json({ error: \"shared notes are not enabled for this reader and record type\" }, 403);\n }\n const record = await getRecord({ crm: ctx.chapter.crm, db: db as never }, recordId);\n if (!record || record.type !== recordType) return json({ error: \"record not found\" }, 404);\n if (req.method === \"GET\") {\n return json({\n version: 1,\n site: { id: ctx.chapter.id, name: ctx.chapter.name },\n notes: await listSharedNotes(db as unknown as ChapterDb, verified.sender, recordId),\n });\n }\n let input: { body?: unknown; mutationId?: unknown };\n try {\n input = JSON.parse(verified.body) as typeof input;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n const body = typeof input.body === \"string\" ? input.body.trim() : \"\";\n const mutationId = typeof input.mutationId === \"string\" ? input.mutationId : \"\";\n if (!body || body.length > MAX_NOTE || !MUTATION_ID.test(mutationId)) {\n return json({ error: `body must be 1–${MAX_NOTE} characters and mutationId must be valid` }, 400);\n }\n const createdAt = Date.now();\n const id = `network:${verified.sender}:${mutationId}`;\n const result = await addActivity(\n {\n crm: ctx.chapter.crm,\n db: db as never,\n now: () => createdAt,\n newId: () => id,\n },\n {\n recordId,\n kind: \"note\",\n body: `Shared by ${sourceLabel(verified.sender)}: ${body}`,\n authorId: `network:${verified.sender}`,\n meta: {\n [NETWORK_META]: {\n version: 1,\n sourceId: verified.sender,\n recordType,\n body,\n },\n },\n mutationId: id,\n },\n );\n const note: NetworkSharedNote = {\n id,\n sourceId: verified.sender,\n recordType,\n recordId,\n body,\n createdAt,\n };\n return json({ version: 1, site: { id: ctx.chapter.id, name: ctx.chapter.name }, note, duplicate: result.duplicate }, 201);\n};\n\nfunction targetFor(ctx: WorkerContext, id: string): ResolvedNetworkTarget | undefined {\n return ctx.chapter.network.targets.find((target) => target.id === id);\n}\n\n/** GET/POST /api/admin/network/shared-notes — an admin-gated leader proxy.\n * The browser never receives the edge secret or a follower credential. */\nexport const handleAdminNetworkSharedNotes: Route = async (req, url, env, ctx) => {\n if (url.pathname !== \"/api/admin/network/shared-notes\" || (req.method !== \"GET\" && req.method !== \"POST\")) return null;\n const got = await gate(req, env, ctx);\n if (\"response\" in got) return got.response;\n const targetId = url.searchParams.get(\"targetId\") ?? \"\";\n const recordType = url.searchParams.get(\"type\") ?? \"\";\n const recordId = url.searchParams.get(\"recordId\") ?? \"\";\n const target = targetFor(ctx, targetId);\n if (!target || !target.sharedNotes.includes(recordType) || !IDENTIFIER.test(recordType) || !RECORD_ID.test(recordId)) {\n return json({ error: \"configured targetId, type, and recordId are required\" }, 400);\n }\n let body = \"\";\n if (req.method === \"POST\") {\n let input: { body?: unknown };\n try {\n input = (await req.json()) as typeof input;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n const note = typeof input.body === \"string\" ? input.body.trim() : \"\";\n if (!note || note.length > MAX_NOTE) return json({ error: `note must be 1–${MAX_NOTE} characters` }, 400);\n body = JSON.stringify({ body: note, mutationId: crypto.randomUUID() });\n }\n const secret = await getVaultSecret(got.db as unknown as ChapterDb, target.secretName);\n if (!secret) return json({ error: \"edge secret is missing\" }, 502);\n const destination = new URL(\"/api/network/shared-notes\", target.url);\n destination.search = new URLSearchParams({ type: recordType, recordId }).toString();\n try {\n const headers = await signFederatedRequest({\n secret,\n sender: ctx.chapter.id,\n method: req.method,\n url: destination,\n ...(body ? { body } : {}),\n });\n const response = await fetchNetworkTarget(env, target, destination, {\n method: req.method,\n headers: { ...headers, ...(body ? { \"content-type\": \"application/json\" } : {}) },\n ...(body ? { body } : {}),\n signal: AbortSignal.timeout(10_000),\n });\n const payload = await response.json().catch(() => null) as Record<string, unknown> | null;\n const site = payload?.site as { id?: unknown } | undefined;\n if (!response.ok || !payload || site?.id !== target.id) {\n return json({\n error: typeof payload?.error === \"string\" ? payload.error : `follower returned ${response.status}`,\n }, 502);\n }\n return json(payload, req.method === \"POST\" ? 201 : 200);\n } catch (error) {\n return json({ error: error instanceof Error ? error.message : \"shared note request failed\" }, 502);\n }\n};\n","// Public intake for prospective chapter formation. The host renders the form\n// in its own brand; this route exposes only configured fields and writes one\n// normal CRM record into the configured workflow.\nimport { createRecord } from \"@odla-ai/crm\";\nimport { applicationIdForSubmission } from \"./application-id\";\nimport { chapterFlowFieldContract } from \"./flow-fields\";\nimport { json } from \"./worker-context\";\nimport type { Route } from \"./worker-context\";\n\nconst SUBMISSION = /^[A-Za-z0-9_-]{8,128}$/;\n\n/** GET /api/formation/config and POST /api/formation/applications. */\nexport const handleFormation: Route = async (req, url, env, ctx) => {\n const formation = ctx.chapter.formation;\n if (!formation.enabled) return null;\n\n if (req.method === \"GET\" && url.pathname === \"/api/formation/config\") {\n const fieldContract = chapterFlowFieldContract(ctx.chapter, \"formation\");\n return json({\n type: formation.type,\n fieldContract,\n // Backward compatibility for hosts that consumed the original array.\n fields: fieldContract.fields,\n });\n }\n if (req.method !== \"POST\" || url.pathname !== \"/api/formation/applications\") return null;\n\n const raw = await req.text();\n if (raw.length > formation.bodyCap) return json({ error: \"request body too large\" }, 413);\n let body: Record<string, unknown>;\n try {\n body = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n return json({ error: \"invalid JSON body\" }, 400);\n }\n if (!body || typeof body !== \"object\" || Array.isArray(body)) return json({ error: \"JSON body must be an object\" }, 400);\n\n const submissionId = typeof body.submissionId === \"string\" ? body.submissionId : undefined;\n if (submissionId && !SUBMISSION.test(submissionId)) {\n return json({ error: \"submissionId must be an 8–128 character base64url value\" }, 400);\n }\n const allowed = new Set([...formation.required, ...formation.optional]);\n const unknown = Object.keys(body).filter((field) => field !== \"submissionId\" && !allowed.has(field));\n if (unknown.length) return json({ error: `field \"${unknown[0]}\" is not accepted` }, 400);\n for (const field of formation.required) {\n const value = body[field];\n if (typeof value !== \"string\" || value.trim() === \"\") return json({ error: `${field} is required` }, 400);\n }\n const input: Record<string, unknown> = {};\n for (const field of allowed) {\n const value = body[field];\n if (value === undefined) continue;\n const cap = formation.maxLen[field] ?? formation.defaultMaxLen;\n if (typeof value === \"string\") {\n if (value.length > cap) return json({ error: `${field} exceeds ${cap} characters` }, 400);\n input[field] = value.trim();\n } else if (Array.isArray(value)) {\n input[field] = value.slice(0, 100);\n } else {\n input[field] = value;\n }\n }\n\n const db = ctx.makeDb(env);\n const id = submissionId\n ? await applicationIdForSubmission(`formation:${ctx.chapter.id}:${submissionId}`)\n : crypto.randomUUID();\n try {\n const created = await createRecord(\n {\n crm: ctx.chapter.crm,\n db: db as never,\n now: () => Date.now(),\n newId: () => id,\n },\n {\n type: formation.type,\n input,\n ...(submissionId ? { mutationId: `formation:${ctx.chapter.id}:${submissionId}` } : {}),\n },\n );\n return json({\n id,\n duplicate: created.duplicate,\n status: created.record.stage ?? null,\n }, created.duplicate ? 200 : 201);\n } catch (error) {\n const detail = error && typeof error === \"object\" && \"fields\" in error\n ? (error as { fields?: unknown }).fields\n : undefined;\n return json({\n error: error instanceof Error ? error.message : \"invalid formation application\",\n ...(detail ? { fields: detail } : {}),\n }, 400);\n }\n};\n","import { verifyFederatedRequest } from \"@odla-ai/db\";\nimport { getVaultSecret } from \"./auth\";\nimport {\n BUILDER_LIBRARY_ADMIN_PATH,\n BUILDER_LIBRARY_CONTROL_PATH,\n BUILDER_LIBRARY_MANIFEST_PATH,\n BUILDER_LIBRARY_PROMOTE_PATH,\n buildBuilderLibraryManifest,\n promoteBuilderLibraryResource,\n validateBuilderLibraryDocument,\n type BuilderLibraryDocument,\n type BuilderLibraryEnvelope,\n type BuilderLibraryResource,\n} from \"./builder-library\";\nimport { builderLibraryDigest } from \"./builder-library-canonical\";\nimport {\n loadActiveBuilderLibraryControls,\n loadLatestBuilderLibraryControl,\n loadLocalBuilderLibrary,\n materializeBuilderLibraryControl,\n saveLocalBuilderLibrary,\n} from \"./builder-library-store\";\nimport { json, type Route } from \"./worker-context\";\nimport type { ChapterDb } from \"./types\";\n\nconst BODY_CAP = 1_000_000;\n\nasync function verifySource(req: Request, db: ChapterDb, sources: readonly { sourceId: string; secretName: string }[]) {\n for (const source of sources) {\n const secret = await getVaultSecret(db, source.secretName);\n if (!secret) continue;\n const verified = await verifyFederatedRequest(req.clone(), { secret, senders: [source.sourceId] });\n if (verified.ok) return { source, body: verified.body };\n }\n return null;\n}\n\n/** Signed, replay-safe receiver for Chapter → BNF and BNF → Chapter library layers. */\nexport const handleBuilderLibraryControl: Route = async (req, url, env, ctx) => {\n if (req.method !== \"POST\" || url.pathname !== BUILDER_LIBRARY_CONTROL_PATH) return null;\n const settings = ctx.chapter.builderLibrary;\n if (!settings) return json({ error: \"not found\" }, 404);\n const db = ctx.makeDb(env) as unknown as ChapterDb;\n const verified = await verifySource(req, db, settings.sources);\n if (!verified) return json({ error: \"unauthorized\" }, 401);\n let input: Record<string, unknown>;\n try { input = JSON.parse(verified.body) as Record<string, unknown>; }\n catch { return json({ ok: false, reason: \"invalid_document\", errors: [\"request body must be JSON\"] }, 400); }\n const digest = typeof input.digest === \"string\" ? input.digest : \"\";\n const sourceType = ctx.chapter.mode === \"hub\" ? \"chapter\" as const : \"built_not_found\" as const;\n const checked = validateBuilderLibraryDocument(input.document, {\n sourceType,\n sourceAppId: verified.source.sourceId,\n targetAppId: ctx.chapter.id,\n });\n if (!checked.ok) return json({ ok: false, reason: \"invalid_document\", errors: checked.errors }, 400);\n const document = checked.value;\n if (ctx.chapter.mode === \"chapter\" && document.resources.some((resource) => resource.scope.kind !== \"global\")) {\n return json({ ok: false, reason: \"invalid_document\", errors: [\"Built Not Found may deliver only global resources to a Chapter\"] }, 400);\n }\n if (!document.target || document.target.environment !== env.ODLA_ENV) return json({ ok: false, reason: \"wrong_environment\" }, 409);\n if (!digest || await builderLibraryDigest(document) !== digest) return json({ ok: false, reason: \"invalid_digest\" }, 400);\n const latest = await loadLatestBuilderLibraryControl(db, document.source.appId, ctx.chapter.id, env.ODLA_ENV);\n if (latest && document.revision < latest.revision) return json({ ok: false, reason: \"stale_revision\" }, 409);\n if (latest && document.revision === latest.revision) {\n if (latest.digest !== digest) return json({ ok: false, reason: \"conflicting_revision\" }, 409);\n return json({ ok: true, target: document.target, revision: latest.revision, digest: latest.digest, status: \"replayed\", acknowledgedAt: latest.receivedAt });\n }\n const receivedAt = Date.now();\n try { await materializeBuilderLibraryControl(db, { document, digest } as BuilderLibraryEnvelope, latest, receivedAt); }\n catch { return json({ ok: false, reason: \"materialization_failed\" }, 503); }\n return json({ ok: true, target: document.target, revision: document.revision, digest, status: \"accepted\", acknowledgedAt: receivedAt });\n};\n\nfunction actorFor(user: { email?: string; userId: string }): string { return user.email ?? user.userId; }\n\nfunction withLocalAuthority(\n value: unknown,\n mode: \"chapter\" | \"hub\",\n appId: string,\n revision: number,\n now: number,\n actor: string,\n current?: BuilderLibraryDocument,\n): unknown {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return value;\n const raw = value as Record<string, unknown>;\n const currentById = new Map((current?.resources ?? []).map((item) => [item.id, item]));\n const resources = Array.isArray(raw.resources) ? raw.resources.map((input) => {\n if (!input || typeof input !== \"object\" || Array.isArray(input)) return input;\n const item = input as Record<string, unknown>;\n const existing = typeof item.id === \"string\" ? currentById.get(item.id) : undefined;\n return {\n ...item,\n revision: (existing?.revision ?? 0) + 1,\n provenance: {\n createdBy: existing?.provenance.createdBy ?? actor,\n createdAt: existing?.provenance.createdAt ?? now,\n updatedBy: actor,\n updatedAt: now,\n ...(existing?.provenance.promotedFrom ? { promotedFrom: existing.provenance.promotedFrom } : {}),\n },\n };\n }) : raw.resources;\n return {\n ...raw,\n schemaVersion: 1,\n revision,\n generatedAt: now,\n source: { type: mode === \"hub\" ? \"built_not_found\" : \"chapter\", appId },\n resources,\n };\n}\n\n/** Private admin authoring, agent manifest, and BNF-only Chapter promotion surface. */\nexport const handleAdminBuilderLibrary: Route = async (req, url, env, ctx) => {\n const paths = new Set([BUILDER_LIBRARY_ADMIN_PATH, BUILDER_LIBRARY_MANIFEST_PATH, BUILDER_LIBRARY_PROMOTE_PATH]);\n if (!paths.has(url.pathname as never)) return null;\n if (!ctx.chapter.builderLibrary) return json({ error: \"not found\" }, 404);\n const user = await ctx.verifyUser(req, env);\n if (!user) return json({ error: \"unauthorized\" }, 401);\n const db = ctx.makeDb(env) as unknown as ChapterDb;\n if (!await ctx.isAdmin(db as never, user)) return json({ error: \"forbidden\" }, 403);\n const [local, controls] = await Promise.all([\n loadLocalBuilderLibrary(db, ctx.chapter.id, env.ODLA_ENV),\n loadActiveBuilderLibraryControls(db, ctx.chapter.id, env.ODLA_ENV),\n ]);\n\n if (url.pathname === BUILDER_LIBRARY_MANIFEST_PATH) {\n if (req.method !== \"GET\") return json({ error: \"method not allowed\" }, 405);\n const chapterId = url.searchParams.get(\"chapterId\")?.trim();\n if (ctx.chapter.mode === \"hub\" && (!chapterId || !ctx.chapter.builderLibrary.sources.some((source) => source.sourceId === chapterId))) {\n return json({ error: \"chapterId must name a configured Chapter source\" }, 400);\n }\n const viewer = ctx.chapter.mode === \"hub\" ? { kind: \"chapter\" as const, chapterId: chapterId! } : { kind: \"chapter\" as const, chapterId: ctx.chapter.id };\n const documents = [\n ...(local ? [local.document] : []),\n ...controls.filter((row) => ctx.chapter.mode === \"chapter\" || row.sourceId === chapterId).map((row) => row.document),\n ];\n return json(buildBuilderLibraryManifest(documents, viewer));\n }\n\n if (url.pathname === BUILDER_LIBRARY_PROMOTE_PATH) {\n if (req.method !== \"POST\") return json({ error: \"method not allowed\" }, 405);\n if (ctx.chapter.mode !== \"hub\") return json({ error: \"only Built Not Found can promote Chapter material\" }, 403);\n let input: Record<string, unknown>;\n try { input = await req.json() as Record<string, unknown>; }\n catch { return json({ error: \"invalid JSON body\" }, 400); }\n const chapterId = typeof input.chapterId === \"string\" ? input.chapterId : \"\";\n const resourceId = typeof input.resourceId === \"string\" ? input.resourceId : \"\";\n const expectedRevision = Number(input.expectedRevision);\n const source = controls.find((row) => row.sourceId === chapterId);\n const resource = source?.document.resources.find((item) => item.id === resourceId);\n if (!source || !resource) return json({ error: \"Chapter resource not found\" }, 404);\n if (!Number.isInteger(expectedRevision) || expectedRevision !== (local?.revision ?? 0)) return json({ error: \"Builder Library changed; reload before promoting\" }, 409);\n const now = Date.now();\n let promoted: BuilderLibraryResource;\n try { promoted = promoteBuilderLibraryResource({ resource, chapterDocumentRevision: source.revision, actor: actorFor(user), promotedAt: now, ...(typeof input.globalId === \"string\" ? { globalId: input.globalId } : {}) }); }\n catch { return json({ error: \"resource cannot be promoted\" }, 400); }\n if (local?.document.resources.some((item) => item.id === promoted.id)) return json({ error: `global resource id \"${promoted.id}\" already exists` }, 409);\n const document: BuilderLibraryDocument = {\n schemaVersion: 1, revision: expectedRevision + 1, generatedAt: now,\n source: { type: \"built_not_found\", appId: ctx.chapter.id },\n resources: [...(local?.document.resources ?? []), promoted],\n };\n const checked = validateBuilderLibraryDocument(document, { sourceType: \"built_not_found\", sourceAppId: ctx.chapter.id });\n if (!checked.ok) return json({ error: \"promoted resource is invalid\", errors: checked.errors }, 400);\n try {\n const saved = await saveLocalBuilderLibrary(db, checked.value, env.ODLA_ENV, expectedRevision, now, actorFor(user));\n return json({ ok: true, revision: saved.revision, resource: promoted });\n } catch { return json({ error: \"Builder Library changed; reload before promoting\" }, 409); }\n }\n\n if (req.method === \"GET\") {\n return json({\n mode: ctx.chapter.mode,\n local: local ? { revision: local.revision, document: local.document } : null,\n sources: controls.map(({ sourceId, revision, digest, document, receivedAt }) => ({ sourceId, revision, digest, document, receivedAt })),\n localAuthoring: ctx.chapter.builderLibrary.localAuthoring,\n visibility: { builtNotFoundSeesChapterSources: ctx.chapter.mode === \"hub\", chaptersSeeSiblingSources: false },\n });\n }\n if (req.method !== \"PUT\") return json({ error: \"method not allowed\" }, 405);\n if (!ctx.chapter.builderLibrary.localAuthoring) return json({ error: \"local authoring is disabled\" }, 403);\n const raw = await req.text();\n if (raw.length > BODY_CAP) return json({ error: \"request body too large\" }, 413);\n let input: Record<string, unknown>;\n try { input = JSON.parse(raw) as Record<string, unknown>; }\n catch { return json({ error: \"invalid JSON body\" }, 400); }\n const expectedRevision = Number(input.expectedRevision);\n if (!Number.isInteger(expectedRevision) || expectedRevision < 0) return json({ error: \"expectedRevision must be a non-negative integer\" }, 400);\n const now = Date.now();\n const actor = actorFor(user);\n const authoritative = withLocalAuthority(input.document, ctx.chapter.mode, ctx.chapter.id, expectedRevision + 1, now, actor, local?.document);\n const checked = validateBuilderLibraryDocument(authoritative, { sourceType: ctx.chapter.mode === \"hub\" ? \"built_not_found\" : \"chapter\", sourceAppId: ctx.chapter.id });\n if (!checked.ok) return json({ error: \"invalid Builder Library\", errors: checked.errors }, 400);\n try {\n const saved = await saveLocalBuilderLibrary(db, checked.value, env.ODLA_ENV, expectedRevision, now, actor);\n return json({ ok: true, revision: saved.revision, document: saved.document });\n } catch (error) {\n if (error instanceof Error && error.message === \"builder_library_revision_conflict\") return json({ error: \"Builder Library changed; reload before saving\" }, 409);\n return json({ error: \"Builder Library could not be saved\" }, 503);\n }\n};\n","import {\n BUILDER_LIBRARY_SCHEMA_VERSION,\n type BuilderLibraryDocument,\n type BuilderLibraryResource,\n type BuilderLibraryScope,\n type BuilderLibraryValidationOptions,\n type BuilderLibraryValidationResult,\n} from \"./builder-library\";\n\nconst ID = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\nconst APP_ID = /^[a-z0-9][a-z0-9-]{1,62}$/;\nconst MAX_RESOURCES = 200;\nconst MAX_MARKDOWN = 65_536;\nconst MAX_TEXT = 500;\nconst MAX_TAGS = 20;\nconst KINDS = new Set([\"document\", \"note\", \"link\", \"inspiration\", \"image\", \"file\"]);\nconst STATUSES = new Set([\"draft\", \"published\", \"archived\"]);\nconst ROOT_KEYS = new Set([\"schemaVersion\", \"revision\", \"generatedAt\", \"source\", \"target\", \"resources\"]);\nconst SOURCE_KEYS = new Set([\"type\", \"appId\"]);\nconst TARGET_KEYS = new Set([\"appId\", \"environment\"]);\nconst RESOURCE_KEYS = new Set([\"id\", \"kind\", \"title\", \"summary\", \"tags\", \"scope\", \"status\", \"revision\", \"bodyMarkdown\", \"url\", \"brandAsset\", \"provenance\"]);\nconst SCOPE_KEYS = new Set([\"kind\", \"chapterId\"]);\nconst ASSET_KEYS = new Set([\"bookId\", \"assetId\", \"filename\"]);\nconst PROVENANCE_KEYS = new Set([\"createdBy\", \"createdAt\", \"updatedBy\", \"updatedAt\", \"promotedFrom\"]);\nconst PROMOTION_KEYS = new Set([\"chapterId\", \"resourceId\", \"resourceRevision\", \"documentRevision\", \"promotedBy\", \"promotedAt\"]);\n\nconst record = (value: unknown): Record<string, unknown> | null =>\n value !== null && typeof value === \"object\" && !Array.isArray(value) ? value as Record<string, unknown> : null;\n\nfunction unknownKeys(value: Record<string, unknown>, allowed: ReadonlySet<string>, path: string, errors: string[]) {\n for (const key of Object.keys(value)) if (!allowed.has(key)) errors.push(`${path}.${key} is not supported`);\n}\n\nfunction text(value: unknown, path: string, errors: string[], max = MAX_TEXT, required = true): string | undefined {\n if (value === undefined && !required) return undefined;\n if (typeof value !== \"string\" || (required && !value.trim())) {\n errors.push(`${path} must be a non-empty string`);\n return undefined;\n }\n const result = value.trim();\n if (result.length > max) errors.push(`${path} must be at most ${max} characters`);\n return result;\n}\n\nfunction integer(value: unknown, path: string, errors: string[], minimum = 1): number {\n if (!Number.isSafeInteger(value) || Number(value) < minimum) errors.push(`${path} must be an integer >= ${minimum}`);\n return Number(value);\n}\n\nfunction scopeValue(value: unknown, path: string, errors: string[]): BuilderLibraryScope | null {\n const raw = record(value);\n if (!raw) { errors.push(`${path} must be an object`); return null; }\n unknownKeys(raw, SCOPE_KEYS, path, errors);\n if (raw.kind === \"global\" || raw.kind === \"built_not_found\") {\n if (raw.chapterId !== undefined) errors.push(`${path}.chapterId is allowed only for chapter scope`);\n return { kind: raw.kind };\n }\n if (raw.kind === \"chapter\") {\n const chapterId = text(raw.chapterId, `${path}.chapterId`, errors, 63) ?? \"\";\n if (chapterId && !APP_ID.test(chapterId)) errors.push(`${path}.chapterId must be a lowercase app slug`);\n return { kind: \"chapter\", chapterId };\n }\n errors.push(`${path}.kind must be chapter, built_not_found, or global`);\n return null;\n}\n\nfunction resourceValue(value: unknown, path: string, errors: string[]): BuilderLibraryResource | null {\n const raw = record(value);\n if (!raw) { errors.push(`${path} must be an object`); return null; }\n unknownKeys(raw, RESOURCE_KEYS, path, errors);\n const id = text(raw.id, `${path}.id`, errors, 80) ?? \"\";\n if (id && !ID.test(id)) errors.push(`${path}.id must be lowercase kebab-case`);\n const kind = text(raw.kind, `${path}.kind`, errors) ?? \"\";\n if (!KINDS.has(kind)) errors.push(`${path}.kind is unsupported`);\n const title = text(raw.title, `${path}.title`, errors, 240) ?? \"\";\n const summary = text(raw.summary, `${path}.summary`, errors, 1_000, false);\n const status = text(raw.status, `${path}.status`, errors) ?? \"\";\n if (!STATUSES.has(status)) errors.push(`${path}.status must be draft, published, or archived`);\n const revision = integer(raw.revision, `${path}.revision`, errors);\n const scope = scopeValue(raw.scope, `${path}.scope`, errors) ?? { kind: \"global\" as const };\n const tags = Array.isArray(raw.tags) ? raw.tags.map((tag, index) => text(tag, `${path}.tags[${index}]`, errors, 80) ?? \"\") : [];\n if (!Array.isArray(raw.tags)) errors.push(`${path}.tags must be an array`);\n if (tags.length > MAX_TAGS) errors.push(`${path}.tags may contain at most ${MAX_TAGS} items`);\n if (new Set(tags).size !== tags.length) errors.push(`${path}.tags must be unique`);\n const bodyMarkdown = text(raw.bodyMarkdown, `${path}.bodyMarkdown`, errors, MAX_MARKDOWN, false);\n const url = text(raw.url, `${path}.url`, errors, 2_048, false);\n if (url) {\n try { if (new URL(url).protocol !== \"https:\") errors.push(`${path}.url must use https`); }\n catch { errors.push(`${path}.url must be a valid https URL`); }\n }\n const asset = raw.brandAsset === undefined ? null : record(raw.brandAsset);\n if (raw.brandAsset !== undefined && !asset) errors.push(`${path}.brandAsset must be an object`);\n if (asset) unknownKeys(asset, ASSET_KEYS, `${path}.brandAsset`, errors);\n const brandAsset = asset ? {\n bookId: text(asset.bookId, `${path}.brandAsset.bookId`, errors, 160) ?? \"\",\n assetId: text(asset.assetId, `${path}.brandAsset.assetId`, errors, 160) ?? \"\",\n ...(asset.filename === undefined ? {} : { filename: text(asset.filename, `${path}.brandAsset.filename`, errors, 240) ?? \"\" }),\n } : undefined;\n if ((kind === \"document\" || kind === \"note\") && !bodyMarkdown) errors.push(`${path}.bodyMarkdown is required for ${kind}`);\n if ((kind === \"link\" || kind === \"inspiration\") && !url) errors.push(`${path}.url is required for ${kind}`);\n if ((kind === \"image\" || kind === \"file\") && !brandAsset) errors.push(`${path}.brandAsset is required for ${kind}`);\n if (!([\"document\", \"note\"].includes(kind)) && bodyMarkdown) errors.push(`${path}.bodyMarkdown is not allowed for ${kind}`);\n if (!([\"link\", \"inspiration\"].includes(kind)) && url) errors.push(`${path}.url is not allowed for ${kind}`);\n if (!([\"image\", \"file\"].includes(kind)) && brandAsset) errors.push(`${path}.brandAsset is not allowed for ${kind}`);\n const provenanceRaw = record(raw.provenance);\n if (!provenanceRaw) errors.push(`${path}.provenance must be an object`);\n if (provenanceRaw) unknownKeys(provenanceRaw, PROVENANCE_KEYS, `${path}.provenance`, errors);\n const promotedRaw = provenanceRaw?.promotedFrom === undefined ? null : record(provenanceRaw.promotedFrom);\n if (provenanceRaw?.promotedFrom !== undefined && !promotedRaw) errors.push(`${path}.provenance.promotedFrom must be an object`);\n if (promotedRaw) unknownKeys(promotedRaw, PROMOTION_KEYS, `${path}.provenance.promotedFrom`, errors);\n const promotedFrom = promotedRaw ? {\n chapterId: text(promotedRaw.chapterId, `${path}.provenance.promotedFrom.chapterId`, errors, 63) ?? \"\",\n resourceId: text(promotedRaw.resourceId, `${path}.provenance.promotedFrom.resourceId`, errors, 80) ?? \"\",\n resourceRevision: integer(promotedRaw.resourceRevision, `${path}.provenance.promotedFrom.resourceRevision`, errors),\n documentRevision: integer(promotedRaw.documentRevision, `${path}.provenance.promotedFrom.documentRevision`, errors),\n promotedBy: text(promotedRaw.promotedBy, `${path}.provenance.promotedFrom.promotedBy`, errors, 320) ?? \"\",\n promotedAt: integer(promotedRaw.promotedAt, `${path}.provenance.promotedFrom.promotedAt`, errors, 0),\n } : undefined;\n const provenance = {\n createdBy: text(provenanceRaw?.createdBy, `${path}.provenance.createdBy`, errors, 320) ?? \"\",\n createdAt: integer(provenanceRaw?.createdAt, `${path}.provenance.createdAt`, errors, 0),\n updatedBy: text(provenanceRaw?.updatedBy, `${path}.provenance.updatedBy`, errors, 320) ?? \"\",\n updatedAt: integer(provenanceRaw?.updatedAt, `${path}.provenance.updatedAt`, errors, 0),\n ...(promotedFrom ? { promotedFrom } : {}),\n };\n return { id, kind: kind as BuilderLibraryResource[\"kind\"], title, ...(summary ? { summary } : {}), tags, scope, status: status as BuilderLibraryResource[\"status\"], revision, ...(bodyMarkdown ? { bodyMarkdown } : {}), ...(url ? { url } : {}), ...(brandAsset ? { brandAsset } : {}), provenance };\n}\n\n/** Strictly validate size, shape, authority, and the closed scope enum. */\nexport function validateBuilderLibraryDocument(\n value: unknown,\n options: BuilderLibraryValidationOptions = {},\n): BuilderLibraryValidationResult {\n const errors: string[] = [];\n const raw = record(value);\n if (!raw) return { ok: false, errors: [\"document must be an object\"] };\n unknownKeys(raw, ROOT_KEYS, \"document\", errors);\n if (raw.schemaVersion !== BUILDER_LIBRARY_SCHEMA_VERSION) errors.push(\"document.schemaVersion must be 1\");\n const revision = integer(raw.revision, \"document.revision\", errors);\n const generatedAt = integer(raw.generatedAt, \"document.generatedAt\", errors, 0);\n const sourceRaw = record(raw.source);\n if (!sourceRaw) errors.push(\"document.source must be an object\");\n if (sourceRaw) unknownKeys(sourceRaw, SOURCE_KEYS, \"document.source\", errors);\n const sourceType = sourceRaw?.type;\n if (sourceType !== \"chapter\" && sourceType !== \"built_not_found\") errors.push(\"document.source.type must be chapter or built_not_found\");\n const sourceAppId = text(sourceRaw?.appId, \"document.source.appId\", errors, 63) ?? \"\";\n if (sourceAppId && !APP_ID.test(sourceAppId)) errors.push(\"document.source.appId must be a lowercase app slug\");\n if (options.sourceType && sourceType !== options.sourceType) errors.push(`document.source.type must be ${options.sourceType}`);\n if (options.sourceAppId && sourceAppId !== options.sourceAppId) errors.push(`document.source.appId must be ${options.sourceAppId}`);\n const targetRaw = raw.target === undefined ? null : record(raw.target);\n if (raw.target !== undefined && !targetRaw) errors.push(\"document.target must be an object\");\n if (targetRaw) unknownKeys(targetRaw, TARGET_KEYS, \"document.target\", errors);\n const target = targetRaw ? {\n appId: text(targetRaw.appId, \"document.target.appId\", errors, 63) ?? \"\",\n environment: text(targetRaw.environment, \"document.target.environment\", errors, 80) ?? \"\",\n } : undefined;\n if (options.targetAppId && target?.appId !== options.targetAppId) errors.push(`document.target.appId must be ${options.targetAppId}`);\n if (!Array.isArray(raw.resources)) errors.push(\"document.resources must be an array\");\n const inputs = Array.isArray(raw.resources) ? raw.resources : [];\n if (inputs.length > MAX_RESOURCES) errors.push(`document.resources may contain at most ${MAX_RESOURCES} items`);\n const resources = inputs.map((item, index) => resourceValue(item, `document.resources[${index}]`, errors)).filter(Boolean) as BuilderLibraryResource[];\n const ids = resources.map(({ id }) => id);\n if (new Set(ids).size !== ids.length) errors.push(\"document.resources ids must be unique\");\n for (const resource of resources) {\n if (sourceType === \"chapter\" && (resource.scope.kind !== \"chapter\" || resource.scope.chapterId !== sourceAppId)) {\n errors.push(`document.resources.${resource.id}: Chapter sources may author only their own chapter scope`);\n }\n if (sourceType === \"built_not_found\" && resource.scope.kind === \"chapter\") {\n errors.push(`document.resources.${resource.id}: Built Not Found sources may author only built_not_found or global scope`);\n }\n }\n if (errors.length) return { ok: false, errors };\n return { ok: true, value: { schemaVersion: 1, revision, generatedAt, source: { type: sourceType as BuilderLibraryDocument[\"source\"][\"type\"], appId: sourceAppId }, ...(target ? { target } : {}), resources } };\n}\n","/** Versioned contract for private Builder Library source material. */\nexport const BUILDER_LIBRARY_SCHEMA_VERSION = 1 as const;\n/** Authenticated admin inventory and local-authoring endpoint. */\nexport const BUILDER_LIBRARY_ADMIN_PATH = \"/api/admin/builder-library\" as const;\n/** Authenticated, published-only agent manifest endpoint. */\nexport const BUILDER_LIBRARY_MANIFEST_PATH = \"/api/admin/builder-library/manifest\" as const;\n/** Built Not Found-only audited Chapter-to-global promotion endpoint. */\nexport const BUILDER_LIBRARY_PROMOTE_PATH = \"/api/admin/builder-library/promote\" as const;\n/** Dedicated signed federation receiver for Builder Library documents. */\nexport const BUILDER_LIBRARY_CONTROL_PATH = \"/api/builder-library-control\" as const;\n\n/** Authority kind attached to one complete Builder Library document. */\nexport type BuilderLibrarySourceType = \"chapter\" | \"built_not_found\";\n/** Stable authority identity attached to a Builder Library document. */\nexport interface BuilderLibrarySource { type: BuilderLibrarySourceType; appId: string }\n/** Exact app deployment that a signed Builder Library revision targets. */\nexport interface BuilderLibraryTarget { appId: string; environment: string }\n\n/** Exactly one visibility scope. There are deliberately no groups or audience arrays. */\nexport type BuilderLibraryScope =\n | { kind: \"chapter\"; chapterId: string }\n | { kind: \"built_not_found\" }\n | { kind: \"global\" };\n\n/** Supported private source-material representations. */\nexport type BuilderLibraryResourceKind = \"document\" | \"note\" | \"link\" | \"inspiration\" | \"image\" | \"file\";\n/** Explicit authoring lifecycle; only published resources enter agent manifests. */\nexport type BuilderLibraryResourceStatus = \"draft\" | \"published\" | \"archived\";\n\n/** Durable Brand identity only; URLs, bytes, and storage credentials never enter a manifest. */\nexport interface BuilderLibraryBrandAssetRef {\n bookId: string;\n assetId: string;\n filename?: string;\n}\n\n/** Immutable origin recorded when Built Not Found promotes Chapter material. */\nexport interface BuilderLibraryPromotionProvenance {\n chapterId: string;\n resourceId: string;\n resourceRevision: number;\n documentRevision: number;\n promotedBy: string;\n promotedAt: number;\n}\n\n/** Server-authored creation/update history for one resource. */\nexport interface BuilderLibraryResourceProvenance {\n createdBy: string;\n createdAt: number;\n updatedBy: string;\n updatedAt: number;\n promotedFrom?: BuilderLibraryPromotionProvenance;\n}\n\n/** One bounded, revisioned private source item. */\nexport interface BuilderLibraryResource {\n id: string;\n kind: BuilderLibraryResourceKind;\n title: string;\n summary?: string;\n tags: readonly string[];\n scope: BuilderLibraryScope;\n status: BuilderLibraryResourceStatus;\n revision: number;\n bodyMarkdown?: string;\n url?: string;\n brandAsset?: BuilderLibraryBrandAssetRef;\n provenance: BuilderLibraryResourceProvenance;\n}\n\n/** Complete local or federated authoring layer. */\nexport interface BuilderLibraryDocument {\n schemaVersion: typeof BUILDER_LIBRARY_SCHEMA_VERSION;\n revision: number;\n generatedAt: number;\n source: BuilderLibrarySource;\n target?: BuilderLibraryTarget;\n resources: readonly BuilderLibraryResource[];\n}\n\n/** Validation constraints that bind a document to its trusted source and target. */\nexport interface BuilderLibraryValidationOptions {\n sourceType?: BuilderLibrarySourceType;\n sourceAppId?: string;\n targetAppId?: string;\n}\n\n/** A validated document or actionable strict-contract errors. */\nexport type BuilderLibraryValidationResult =\n | { ok: true; value: BuilderLibraryDocument }\n | { ok: false; errors: readonly string[] };\n\n/** Principal whose closed-scope visibility is projected. */\nexport type BuilderLibraryViewer =\n | { kind: \"built_not_found\" }\n | { kind: \"chapter\"; chapterId: string };\n\n/** Bounded agent input. It contains references, never private asset bytes or credentials. */\nexport interface BuilderLibraryManifest {\n schemaVersion: typeof BUILDER_LIBRARY_SCHEMA_VERSION;\n generatedAt: number;\n viewer: BuilderLibraryViewer;\n revisions: readonly { source: BuilderLibrarySource; revision: number }[];\n resources: readonly BuilderLibraryResource[];\n truncated: boolean;\n}\n\n/** Canonical document and digest transmitted over the signed library edge. */\nexport interface BuilderLibraryEnvelope { digest: string; document: BuilderLibraryDocument }\n/** Durable acknowledgement for an accepted or idempotently replayed revision. */\nexport interface BuilderLibraryReceipt {\n ok: true;\n target: BuilderLibraryTarget;\n revision: number;\n digest: string;\n status: \"accepted\" | \"replayed\";\n acknowledgedAt: number;\n}\n\nexport { validateBuilderLibraryDocument } from \"./builder-library-validation\";\n\n/** Apply the closed visibility matrix. */\nexport function canViewBuilderLibraryResource(\n resource: BuilderLibraryResource,\n viewer: BuilderLibraryViewer,\n): boolean {\n if (viewer.kind === \"built_not_found\") return true;\n return resource.scope.kind === \"global\"\n || (resource.scope.kind === \"chapter\" && resource.scope.chapterId === viewer.chapterId);\n}\n\n/** Produce deterministic, published-only input for a site-building agent. */\nexport function buildBuilderLibraryManifest(\n documents: readonly BuilderLibraryDocument[],\n viewer: BuilderLibraryViewer,\n generatedAt = Date.now(),\n limit = 100,\n): BuilderLibraryManifest {\n const ordered = documents\n .flatMap((document) => document.resources.map((resource) => ({ document, resource })))\n .filter(({ resource }) => resource.status === \"published\" && canViewBuilderLibraryResource(resource, viewer))\n .sort((a, b) => a.resource.title.localeCompare(b.resource.title)\n || a.document.source.appId.localeCompare(b.document.source.appId)\n || a.resource.id.localeCompare(b.resource.id));\n return {\n schemaVersion: BUILDER_LIBRARY_SCHEMA_VERSION,\n generatedAt,\n viewer,\n revisions: documents.map(({ source, revision }) => ({ source, revision })),\n resources: ordered.slice(0, limit).map(({ resource }) => resource),\n truncated: ordered.length > limit,\n };\n}\n\n/** Build the exact signed layer for one peer; BNF-only material never crosses to a Chapter. */\nexport function projectBuilderLibraryDelivery(\n document: BuilderLibraryDocument,\n target: BuilderLibraryTarget,\n): BuilderLibraryDocument {\n return {\n ...document,\n target,\n resources: document.source.type === \"built_not_found\"\n ? document.resources.filter((resource) => resource.scope.kind === \"global\")\n : document.resources,\n };\n}\n\n/** Copy a Chapter item into global authority while preserving its exact origin. */\nexport function promoteBuilderLibraryResource(input: {\n resource: BuilderLibraryResource;\n chapterDocumentRevision: number;\n actor: string;\n promotedAt: number;\n globalId?: string;\n}): BuilderLibraryResource {\n if (input.resource.scope.kind !== \"chapter\") throw new TypeError(\"only a Chapter-scoped resource can be promoted\");\n const chapterId = input.resource.scope.chapterId;\n return {\n ...input.resource,\n id: input.globalId ?? `${chapterId}-${input.resource.id}`,\n scope: { kind: \"global\" },\n revision: 1,\n provenance: {\n createdBy: input.actor,\n createdAt: input.promotedAt,\n updatedBy: input.actor,\n updatedAt: input.promotedAt,\n promotedFrom: {\n chapterId,\n resourceId: input.resource.id,\n resourceRevision: input.resource.revision,\n documentRevision: input.chapterDocumentRevision,\n promotedBy: input.actor,\n promotedAt: input.promotedAt,\n },\n },\n };\n}\n","const encoder = new TextEncoder();\n\nfunction canonicalValue(value: unknown): string {\n if (value === null || typeof value === \"boolean\" || typeof value === \"number\" || typeof value === \"string\") return JSON.stringify(value);\n if (Array.isArray(value)) return `[${value.map(canonicalValue).join(\",\")}]`;\n if (typeof value !== \"object\") throw new TypeError(\"Builder Library contains an unsupported value\");\n const record = value as Record<string, unknown>;\n return `{${Object.keys(record).sort().flatMap((key) => record[key] === undefined ? [] : [`${JSON.stringify(key)}:${canonicalValue(record[key])}`]).join(\",\")}}`;\n}\n\n/** Serialize Builder Library JSON with recursively sorted object keys. */\nexport function canonicalBuilderLibrary(value: unknown): string { return canonicalValue(value); }\n\n/** Compute a canonical SHA-256 digest for one signed library revision. */\nexport async function builderLibraryDigest(document: unknown): Promise<string> {\n const digest = await crypto.subtle.digest(\"SHA-256\", encoder.encode(canonicalBuilderLibrary(document)));\n return `sha256:${Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\")}`;\n}\n\n/** Pair one validated document with the exact digest its target acknowledges. */\nexport async function createBuilderLibraryEnvelope(document: import(\"./builder-library\").BuilderLibraryDocument) {\n return { document, digest: await builderLibraryDigest(document) };\n}\n","import type { BuilderLibraryDocument, BuilderLibraryEnvelope } from \"./builder-library\";\nimport type { ChapterDb, DbOp } from \"./types\";\n\nexport interface StoredBuilderLibraryControl {\n id: string; sourceId: string; targetId: string; environment: string; revision: number;\n digest: string; document: BuilderLibraryDocument; active: boolean; receivedAt: number;\n}\nexport interface StoredLocalBuilderLibrary {\n id: string; appId: string; environment: string; revision: number;\n document: BuilderLibraryDocument; updatedAt: number; updatedBy?: string;\n}\n\nconst control = (row: Record<string, unknown> | undefined): StoredBuilderLibraryControl | null =>\n row?.document && typeof row.document === \"object\" ? row as unknown as StoredBuilderLibraryControl : null;\nconst local = (row: Record<string, unknown> | undefined): StoredLocalBuilderLibrary | null =>\n row?.document && typeof row.document === \"object\" ? row as unknown as StoredLocalBuilderLibrary : null;\n\nexport async function loadActiveBuilderLibraryControls(\n db: ChapterDb, targetId: string, environment: string,\n): Promise<StoredBuilderLibraryControl[]> {\n const rows = (await db.query({ builderLibraryControls: { $: { where: { targetId, environment, active: true }, limit: 500 } } })).builderLibraryControls;\n return (Array.isArray(rows) ? rows.map(control).filter(Boolean) : []) as StoredBuilderLibraryControl[];\n}\n\nexport async function loadLatestBuilderLibraryControl(\n db: ChapterDb, sourceId: string, targetId: string, environment: string,\n): Promise<StoredBuilderLibraryControl | null> {\n const rows = (await db.query({ builderLibraryControls: { $: { where: { sourceId, targetId, environment }, order: { revision: \"desc\" }, limit: 20 } } })).builderLibraryControls;\n return control(Array.isArray(rows) ? [...rows].sort((a, b) => Number(b.revision) - Number(a.revision))[0] : undefined);\n}\n\nexport async function loadLocalBuilderLibrary(db: ChapterDb, appId: string, environment: string): Promise<StoredLocalBuilderLibrary | null> {\n const id = `builder-library-local:${environment}`;\n const rows = (await db.query({ builderLibraryLocal: { $: { where: { id }, limit: 1 } } })).builderLibraryLocal;\n return local(Array.isArray(rows) ? rows[0] : undefined);\n}\n\nexport async function materializeBuilderLibraryControl(\n db: ChapterDb, envelope: BuilderLibraryEnvelope, previous: StoredBuilderLibraryControl | null, receivedAt: number,\n): Promise<void> {\n const { document, digest } = envelope;\n const target = document.target!;\n const id = `builder-library-control:${document.source.appId}:${target.environment}:${document.revision}`;\n const ops: DbOp[] = [];\n if (previous?.active) ops.push({ t: \"update\", ns: \"builderLibraryControls\", id: previous.id, attrs: { active: false } });\n ops.push({ t: \"update\", ns: \"builderLibraryControls\", id, attrs: {\n id, sourceId: document.source.appId, targetId: target.appId, environment: target.environment,\n revision: document.revision, digest, document, active: true, receivedAt,\n } });\n await db.transact(ops, { mutationId: `builder-library-control:${document.source.appId}:${target.environment}:${document.revision}:${digest}` });\n}\n\nexport async function saveLocalBuilderLibrary(\n db: ChapterDb, document: BuilderLibraryDocument, environment: string, expectedRevision: number,\n updatedAt: number, updatedBy?: string,\n): Promise<StoredLocalBuilderLibrary> {\n const id = `builder-library-local:${environment}`;\n const current = await loadLocalBuilderLibrary(db, document.source.appId, environment);\n if ((current?.revision ?? 0) !== expectedRevision) throw new Error(\"builder_library_revision_conflict\");\n const row: StoredLocalBuilderLibrary = { id, appId: document.source.appId, environment, revision: document.revision, document, updatedAt, ...(updatedBy ? { updatedBy } : {}) };\n await db.transact([{ t: \"update\", ns: \"builderLibraryLocal\", id, attrs: row as unknown as Record<string, unknown> }], {\n mutationId: `builder-library-local:${environment}:${document.revision}`,\n guards: current ? [{ ns: \"builderLibraryLocal\", id, exists: true, equals: { revision: expectedRevision } }] : [{ ns: \"builderLibraryLocal\", id, exists: false }],\n });\n return row;\n}\n","import { signFederatedRequest } from \"@odla-ai/db\";\nimport {\n SIGNUP_CONTROL_PATH,\n type SignupControlEnvelope,\n type SignupControlReceipt,\n} from \"./signup-control-contract\";\n\n/** Inputs for one signed hub-to-follower signup-control request. */\nexport interface SignupControlDeliveryOptions {\n secret: string;\n sender: string;\n targetUrl: string | URL;\n envelope: SignupControlEnvelope;\n fetch?: typeof globalThis.fetch;\n}\n\n/** Build and send one signed desired-state delivery. Durable retry belongs to the hub outbox. */\nexport async function deliverSignupControl(options: SignupControlDeliveryOptions): Promise<SignupControlReceipt> {\n const destination = new URL(SIGNUP_CONTROL_PATH, options.targetUrl);\n const body = JSON.stringify(options.envelope);\n const signed = await signFederatedRequest({\n secret: options.secret,\n sender: options.sender,\n method: \"POST\",\n url: destination,\n body,\n });\n const response = await (options.fetch ?? globalThis.fetch)(destination, {\n method: \"POST\",\n headers: { ...signed, \"content-type\": \"application/json\" },\n body,\n });\n const result = await response.json() as SignupControlReceipt | { reason?: string; error?: string };\n if (!response.ok || (!(\"ok\" in result) || result.ok !== true)) {\n const rejection = result as { reason?: string; error?: string };\n throw new Error(`signup control rejected (${response.status}): ${rejection.reason ?? rejection.error ?? \"unknown\"}`);\n }\n return result;\n}\n","import { signFederatedRequest } from \"@odla-ai/db\";\nimport {\n MEMBER_CONTENT_CONTROL_PATH,\n type MemberContentEnvelope,\n type MemberContentReceipt,\n} from \"./member-content\";\n\n/** Inputs for one signed Parent → Chapter member-content delivery. */\nexport interface MemberContentDeliveryOptions {\n secret: string;\n sender: string;\n targetUrl: string | URL;\n envelope: MemberContentEnvelope;\n fetch?: typeof globalThis.fetch;\n}\n\n/** Deliver one exact revision. Durable retry and approval remain Parent concerns. */\nexport async function deliverMemberContent(options: MemberContentDeliveryOptions): Promise<MemberContentReceipt> {\n const destination = new URL(MEMBER_CONTENT_CONTROL_PATH, options.targetUrl);\n const body = JSON.stringify(options.envelope);\n const signed = await signFederatedRequest({\n secret: options.secret,\n sender: options.sender,\n method: \"POST\",\n url: destination,\n body,\n });\n const response = await (options.fetch ?? globalThis.fetch)(destination, {\n method: \"POST\",\n headers: { ...signed, \"content-type\": \"application/json\" },\n body,\n });\n const result = await response.json() as MemberContentReceipt | { reason?: string; error?: string };\n if (!response.ok || !(\"ok\" in result) || result.ok !== true) {\n const failure = result as { reason?: string; error?: string };\n throw new Error(`member content rejected (${response.status}): ${failure.reason ?? failure.error ?? \"unknown\"}`);\n }\n return result;\n}\n","import { signFederatedRequest } from \"@odla-ai/db\";\nimport { BUILDER_LIBRARY_CONTROL_PATH, type BuilderLibraryEnvelope, type BuilderLibraryReceipt } from \"./builder-library\";\n\n/** Inputs for one signed Builder Library peer delivery. */\nexport interface BuilderLibraryDeliveryOptions {\n secret: string;\n sender: string;\n targetUrl: string | URL;\n envelope: BuilderLibraryEnvelope;\n fetch?: typeof globalThis.fetch;\n}\n\n/** Deliver one exact Builder Library revision over its dedicated signed edge. */\nexport async function deliverBuilderLibrary(options: BuilderLibraryDeliveryOptions): Promise<BuilderLibraryReceipt> {\n const destination = new URL(BUILDER_LIBRARY_CONTROL_PATH, options.targetUrl);\n const body = JSON.stringify(options.envelope);\n const signed = await signFederatedRequest({ secret: options.secret, sender: options.sender, method: \"POST\", url: destination, body });\n const response = await (options.fetch ?? globalThis.fetch)(destination, { method: \"POST\", headers: { ...signed, \"content-type\": \"application/json\" }, body });\n const result = await response.json() as BuilderLibraryReceipt | { reason?: string; error?: string };\n if (!response.ok || !(\"ok\" in result) || result.ok !== true) {\n const failure = result as { reason?: string; error?: string };\n throw new Error(`Builder Library rejected (${response.status}): ${failure.reason ?? failure.error ?? \"unknown\"}`);\n }\n return result;\n}\n","import { signFederatedRequest } from \"@odla-ai/db\";\nimport {\n ADMISSION_GRANTS_PATH,\n type AdmissionGrantEnvelope,\n type AdmissionGrantReceipt,\n} from \"./admission-grants-contract\";\n\n/** Inputs required to sign and deliver one Parent admission revision. */\nexport interface AdmissionGrantDeliveryOptions {\n secret: string;\n sender: string;\n targetUrl: string | URL;\n envelope: AdmissionGrantEnvelope;\n fetch?: typeof globalThis.fetch;\n}\n\n/** Deliver one signed Parent admission revision. Durable retry belongs upstream. */\nexport async function deliverAdmissionGrants(options: AdmissionGrantDeliveryOptions): Promise<AdmissionGrantReceipt> {\n const destination = new URL(ADMISSION_GRANTS_PATH, options.targetUrl);\n const body = JSON.stringify(options.envelope);\n const signed = await signFederatedRequest({\n secret: options.secret,\n sender: options.sender,\n method: \"POST\",\n url: destination,\n body,\n });\n const response = await (options.fetch ?? globalThis.fetch)(destination, {\n method: \"POST\",\n headers: { ...signed, \"content-type\": \"application/json\" },\n body,\n });\n const result = await response.json() as AdmissionGrantReceipt | { reason?: string; error?: string };\n if (!response.ok || !(\"ok\" in result) || result.ok !== true) {\n const failure = result as { reason?: string; error?: string };\n throw new Error(`admission grants rejected (${response.status}): ${failure.reason ?? failure.error ?? \"unknown\"}`);\n }\n return result;\n}\n","import type { SignupControlTheme } from \"./signup-control-contract\";\n\n/** Stable marker a static document can place where managed signup tokens belong. */\nexport const SIGNUP_CONTROL_THEME_MARKER = \"<!--odla:signup-control-theme-->\" as const;\n/** Stable id shared by the server renderer and browser hydration helper. */\nexport const SIGNUP_CONTROL_THEME_STYLE_ID = \"odla-signup-control-theme\" as const;\n\nconst TOKEN_NAME = /^--ui-[a-z0-9][a-z0-9-]{0,94}$/;\nconst DIGEST = /^sha256:[0-9a-f]{64}$/;\nconst UNSAFE_VALUE = /[\\u0000-\\u001f\\u007f\\\\<>{};]|\\/\\*|\\*\\/|(?:^|[^a-z])(?:url|expression)\\s*\\(|@import/i;\nconst MAX_TOKENS = 256;\nconst MAX_VALUE_LENGTH = 1_000;\nconst MAX_SERIALIZED_LENGTH = 65_536;\n\n/** The active revision shape exposed by `GET /api/join-config`. */\nexport interface SignupControlThemeRevision {\n revision: number;\n digest: string;\n theme?: SignupControlTheme;\n}\n\n/** Identity shared by initial HTML, response caching, and client hydration. */\nexport interface SignupControlThemeMetadata {\n source: \"active\" | \"bootstrap\";\n revision: number | null;\n digest: string | null;\n /** Include this value in any host-owned cache key for transformed HTML. */\n cacheKey: string;\n}\n\n/** A validated style block ready to place in an HTML head. */\nexport interface SignupControlThemeHead {\n css: string;\n head: string;\n metadata: SignupControlThemeMetadata;\n}\n\n/** Minimal DOM surface required by {@link hydrateSignupControlTheme}. */\nexport interface SignupControlThemeStyleTarget {\n textContent: string | null;\n getAttribute(name: string): string | null;\n setAttribute(name: string, value: string): void;\n removeAttribute(name: string): void;\n}\n\n/** Host-owned fallback inputs shared by server rendering and hydration. */\nexport interface SignupControlThemeOptions {\n /** Local site-owned tokens used only when no active managed revision exists. */\n bootstrapTokens?: Readonly<Record<string, string | number>>;\n}\n\nfunction validatedTokens(\n input: Readonly<Record<string, string | number>> | undefined,\n): Readonly<Record<string, string>> {\n const entries = Object.entries(input ?? {});\n if (entries.length > MAX_TOKENS) {\n throw new TypeError(`signup-control theme supports at most ${MAX_TOKENS} tokens`);\n }\n const tokens: Record<string, string> = {};\n let serializedLength = 0;\n for (const [name, raw] of entries.sort(([left], [right]) => left.localeCompare(right))) {\n if (!TOKEN_NAME.test(name)) {\n throw new TypeError(`signup-control theme token \"${name}\" must be an allowlisted --ui-* property`);\n }\n if ((typeof raw !== \"string\" && typeof raw !== \"number\") ||\n (typeof raw === \"number\" && !Number.isFinite(raw))) {\n throw new TypeError(`signup-control theme token \"${name}\" must be a finite string or number`);\n }\n const value = String(raw).trim();\n if (!value || value.length > MAX_VALUE_LENGTH || UNSAFE_VALUE.test(value)) {\n throw new TypeError(`signup-control theme token \"${name}\" has an unsafe or oversized value`);\n }\n serializedLength += name.length + value.length + 4;\n if (serializedLength > MAX_SERIALIZED_LENGTH) {\n throw new TypeError(\"signup-control theme exceeds the serialized size bound\");\n }\n tokens[name] = value;\n }\n return tokens;\n}\n\nfunction cssFor(tokens: Readonly<Record<string, string>>): string {\n const declarations = Object.entries(tokens).map(([name, value]) => ` ${name}: ${value};`);\n return declarations.length ? `:root {\\n${declarations.join(\"\\n\")}\\n}` : \"\";\n}\n\nfunction stateFor(\n revision: SignupControlThemeRevision | null,\n options: SignupControlThemeOptions,\n): { css: string; metadata: SignupControlThemeMetadata } {\n if (!revision) {\n return {\n css: cssFor(validatedTokens(options.bootstrapTokens)),\n metadata: { source: \"bootstrap\", revision: null, digest: null, cacheKey: \"signup-control:bootstrap\" },\n };\n }\n if (!Number.isSafeInteger(revision.revision) || revision.revision < 1 || !DIGEST.test(revision.digest)) {\n throw new TypeError(\"signup-control theme revision metadata is invalid\");\n }\n return {\n css: cssFor(validatedTokens(revision.theme?.tokens)),\n metadata: {\n source: \"active\",\n revision: revision.revision,\n digest: revision.digest,\n cacheKey: `signup-control:${revision.digest}`,\n },\n };\n}\n\nfunction attributes(metadata: SignupControlThemeMetadata): string {\n return [\n `id=\"${SIGNUP_CONTROL_THEME_STYLE_ID}\"`,\n `data-signup-control-source=\"${metadata.source}\"`,\n `data-signup-control-cache-key=\"${metadata.cacheKey}\"`,\n ...(metadata.revision === null ? [] : [`data-signup-control-revision=\"${metadata.revision}\"`]),\n ...(metadata.digest === null ? [] : [`data-signup-control-digest=\"${metadata.digest}\"`]),\n ].join(\" \");\n}\n\n/**\n * Render validated signup-control tokens for the initial HTML head. Passing\n * `null` emits the deterministic local bootstrap state; it never performs I/O.\n */\nexport function renderSignupControlThemeHead(\n revision: SignupControlThemeRevision | null,\n options: SignupControlThemeOptions = {},\n): SignupControlThemeHead {\n const { css, metadata } = stateFor(revision, options);\n return { css, metadata, head: `<style ${attributes(metadata)}>${css}</style>` };\n}\n\n/**\n * Replace the stable marker (preferred), an earlier Chapter style block, or the\n * closing head tag. The returned HTML always contains exactly one managed block.\n */\nexport function injectSignupControlThemeHead(\n html: string,\n rendered: SignupControlThemeHead,\n marker: string = SIGNUP_CONTROL_THEME_MARKER,\n): string {\n const existing = /<style\\b(?=[^>]*\\bid\\s*=\\s*[\"']odla-signup-control-theme[\"'])[^>]*>[\\s\\S]*?<\\/style>/gi;\n const existingBlocks = html.match(existing) ?? [];\n if (existingBlocks.length > 1) {\n throw new TypeError(\"signup-control theme style block must appear at most once\");\n }\n if (existingBlocks.length === 1) return html.replace(existing, rendered.head);\n const markerIndex = html.indexOf(marker);\n if (markerIndex >= 0) {\n if (html.indexOf(marker, markerIndex + marker.length) >= 0) {\n throw new TypeError(\"signup-control theme marker must appear exactly once\");\n }\n return `${html.slice(0, markerIndex)}${rendered.head}${html.slice(markerIndex + marker.length)}`;\n }\n const closingHead = html.search(/<\\/head\\s*>/i);\n if (closingHead < 0) throw new TypeError(\"signup-control theme requires an HTML head\");\n return `${html.slice(0, closingHead)}${rendered.head}${html.slice(closingHead)}`;\n}\n\n/**\n * Apply a newly fetched revision to the server-rendered style element. When the\n * revision and digest already match, this performs no writes and returns false,\n * so hydration cannot cause a visual token change.\n */\nexport function hydrateSignupControlTheme(\n target: SignupControlThemeStyleTarget,\n revision: SignupControlThemeRevision | null,\n options: SignupControlThemeOptions = {},\n): boolean {\n const next = stateFor(revision, options);\n const currentSource = target.getAttribute(\"data-signup-control-source\");\n const currentRevision = target.getAttribute(\"data-signup-control-revision\");\n const currentDigest = target.getAttribute(\"data-signup-control-digest\");\n if (currentSource === next.metadata.source &&\n currentRevision === (next.metadata.revision === null ? null : String(next.metadata.revision)) &&\n currentDigest === next.metadata.digest) {\n return false;\n }\n target.textContent = next.css;\n target.setAttribute(\"data-signup-control-source\", next.metadata.source);\n target.setAttribute(\"data-signup-control-cache-key\", next.metadata.cacheKey);\n if (next.metadata.revision === null) target.removeAttribute(\"data-signup-control-revision\");\n else target.setAttribute(\"data-signup-control-revision\", String(next.metadata.revision));\n if (next.metadata.digest === null) target.removeAttribute(\"data-signup-control-digest\");\n else target.setAttribute(\"data-signup-control-digest\", next.metadata.digest);\n return true;\n}\n","import { signupControlDigest } from \"./signup-control-canonical\";\nimport { loadActiveSignupControl } from \"./signup-control-store\";\nimport {\n injectSignupControlThemeHead,\n renderSignupControlThemeHead,\n type SignupControlThemeHead,\n type SignupControlThemeOptions,\n type SignupControlThemeRevision,\n} from \"./signup-control-theme\";\nimport { validateSignupControlDocument } from \"./signup-control-validate\";\nimport type { ChapterDb } from \"./types\";\n\n/** Inputs required to resolve one follower-local active signup theme. */\nexport interface ActiveSignupControlThemeOptions extends SignupControlThemeOptions {\n /** Follower-local database client. No controlling-hub request is performed. */\n db: ChapterDb;\n chapterId: string;\n environment: string;\n /** Optional host marker; defaults to `SIGNUP_CONTROL_THEME_MARKER`. */\n marker?: string;\n}\n\n/** Transformed HTML plus the exact theme and cache identity it contains. */\nexport interface ActiveSignupControlHtml {\n html: string;\n theme: SignupControlThemeHead;\n}\n\nasync function activeTheme(options: ActiveSignupControlThemeOptions): Promise<SignupControlThemeRevision | null> {\n const active = await loadActiveSignupControl(options.db, options.chapterId, options.environment);\n if (!active) return null;\n const checked = validateSignupControlDocument(active.document);\n if (!checked.ok) throw new TypeError(`active signup-control document is invalid: ${checked.errors.join(\"; \")}`);\n const document = checked.value;\n if (document.revision !== active.revision || document.target.chapterId !== options.chapterId ||\n document.target.environment !== options.environment || active.digest !== await signupControlDigest(document)) {\n throw new TypeError(\"active signup-control revision metadata or digest is invalid\");\n }\n return { revision: active.revision, digest: active.digest, theme: document.theme };\n}\n\n/**\n * Transform trusted host HTML with the follower-local last-known-good signup\n * theme. A missing active revision uses the documented bootstrap state; a read\n * failure or corrupt active row fails closed instead of fetching the hub.\n */\nexport async function renderActiveSignupControlHtml(\n html: string,\n options: ActiveSignupControlThemeOptions,\n): Promise<ActiveSignupControlHtml> {\n const theme = renderSignupControlThemeHead(await activeTheme(options), {\n bootstrapTokens: options.bootstrapTokens,\n });\n return { html: injectSignupControlThemeHead(html, theme, options.marker), theme };\n}\n\nasync function contentEtag(html: string): Promise<string> {\n const bytes = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(html));\n const hex = Array.from(new Uint8Array(bytes), (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n return `W/\"sha256-${hex}\"`;\n}\n\n/**\n * Transform an HTML response and make the cache contract safe by default.\n * `no-store` prevents a prior digest from surviving activation; hosts that own\n * a cache may instead key it with `result.theme.metadata.cacheKey` from\n * {@link renderActiveSignupControlHtml}.\n */\nexport async function withActiveSignupControlTheme(\n response: Response,\n options: ActiveSignupControlThemeOptions,\n): Promise<Response> {\n if (!response.ok || !(response.headers.get(\"content-type\") ?? \"\").toLowerCase().includes(\"text/html\")) {\n throw new TypeError(\"signup-control theme can only transform a successful HTML response\");\n }\n const rendered = await renderActiveSignupControlHtml(await response.text(), options);\n const headers = new Headers(response.headers);\n headers.delete(\"content-length\");\n headers.set(\"cache-control\", \"no-store\");\n headers.set(\"etag\", await contentEtag(rendered.html));\n headers.set(\"x-odla-signup-control-digest\", rendered.theme.metadata.digest ?? \"bootstrap\");\n if (rendered.theme.metadata.revision === null) headers.delete(\"x-odla-signup-control-revision\");\n else headers.set(\"x-odla-signup-control-revision\", String(rendered.theme.metadata.revision));\n return new Response(rendered.html, { status: response.status, statusText: response.statusText, headers });\n}\n","// chapterWorker — the Cloudflare Worker for a chapter/hub site. This entry\n// (@odla-ai/chapter/worker) is separate from the core so the CLI can load\n// odla.config.mjs without pulling in worker-runtime deps.\n//\n// The worker is the ONLY thing that talks to odla-db, using the app key\n// (ODLA_API_KEY), which bypasses the deny-all rules. Browsers never receive a\n// db credential. Access is admin-only: a request is authorized when its Clerk\n// session JWT verifies AND the user's role (a JWT claim, or a row in the\n// Studio-seeded `admins` allowlist) is an admin rung.\n//\n// The env typing + auth plumbing live in ./worker-context; the route handlers in\n// ./worker-routes. This entry only builds the context and runs the routes in\n// order — first match wins, else the static site (ASSETS).\n//\n// hub mode routes: GET /api/config, GET /api/me, /api/crm/*, POST\n// /api/network/{shared,snapshot,records}, else ASSETS. chapter mode adds the public member surface:\n// GET /api/join-config and POST /api/applications (idempotent).\nimport { createWorkerContext } from \"./worker-context\";\nimport type { ChapterEnv, ChapterWorkerOptions, Route } from \"./worker-context\";\nimport { handleConfig, handleCrm, handleHealth, handleMe, handleMember } from \"./worker-routes\";\nimport { handleNetworkShared } from \"./worker-routes-network-receive\";\nimport { handleSignupControl } from \"./worker-routes-signup-control\";\nimport {\n handleAdminMemberContent,\n handleMemberContent,\n handleMemberContentControl,\n} from \"./worker-routes-member-content\";\nimport { handleAdmissionGrants } from \"./worker-routes-admission-grants\";\nimport { handleAdminAdmissionGrants } from \"./worker-routes-admin-admission\";\nimport { handleSchedule } from \"./worker-routes-schedule\";\nimport { handlePayments } from \"./worker-routes-payments\";\nimport { handleGifts } from \"./worker-routes-gifts\";\nimport { handleAdminMeetings, handleAdminScheduling } from \"./worker-routes-admin\";\nimport { handleAdminCrmSync, handleAdminPeople, handleAdminPeopleAccess, handleAdminPeopleRole } from \"./worker-routes-admin-people\";\nimport { handleAdminClerkPrivateProfileSync } from \"./worker-routes-admin-clerk\";\nimport { handleAdminDashboard, handleAdminBilling } from \"./worker-routes-admin-dashboard\";\nimport { handleAdminMeetingReschedule, handleAdminMeetingCancel, handleAdminApprove, handleAdminRefund, handleAdminApplicationPatch } from \"./worker-routes-admin-lifecycle\";\nimport { handleAdminGroupEmail, handleAdminEmailLog, handleAdminEmailTest, handleAdminComms } from \"./worker-routes-admin-comms\";\nimport {\n handleAdminNetworkPush,\n handleAdminNetworkRollup,\n handleAdminNetworkTargets,\n handleNetworkSnapshot,\n} from \"./worker-routes-network\";\nimport {\n handleAdminNetworkRecords,\n handleNetworkRecords,\n} from \"./worker-routes-network-records\";\nimport { handleAdminNetworkNotes } from \"./worker-routes-network-notes\";\nimport {\n handleAdminNetworkSharedNotes,\n handleNetworkSharedNotes,\n} from \"./worker-routes-network-shared-notes\";\nimport { handleFormation } from \"./worker-routes-formation\";\nimport { handleAdminBuilderLibrary, handleBuilderLibraryControl } from \"./worker-routes-builder-library\";\nimport { json } from \"./worker-context\";\n\n// The route seam: a wrapping worker can build its own routes + reuse chapter's\n// auth by composing against these.\nexport { createWorkerContext } from \"./worker-context\";\nexport type { ChapterEnv, ChapterWorkerOptions, WorkerContext, Route } from \"./worker-context\";\nexport { deliverSignupControl } from \"./signup-control-delivery\";\nexport { deliverMemberContent } from \"./member-content-delivery\";\nexport { deliverBuilderLibrary } from \"./builder-library-delivery\";\nexport { deliverAdmissionGrants } from \"./admission-grants-delivery\";\nexport type { AdmissionGrantDeliveryOptions } from \"./admission-grants-delivery\";\nexport type { SignupControlDeliveryOptions } from \"./signup-control-delivery\";\nexport type { MemberContentDeliveryOptions } from \"./member-content-delivery\";\nexport type { BuilderLibraryDeliveryOptions } from \"./builder-library-delivery\";\nexport {\n renderActiveSignupControlHtml,\n withActiveSignupControlTheme,\n} from \"./signup-control-theme-worker\";\nexport type {\n ActiveSignupControlHtml,\n ActiveSignupControlThemeOptions,\n} from \"./signup-control-theme-worker\";\n\n// First-match-wins order. Host routes (options.routes) run BEFORE these.\nconst BUILTIN_ROUTES: Route[] = [\n handleHealth,\n handleConfig,\n handleMe,\n handleCrm,\n handleNetworkShared,\n handleSignupControl,\n handleMemberContentControl,\n handleBuilderLibraryControl,\n handleAdmissionGrants,\n handleNetworkSnapshot,\n handleNetworkRecords,\n handleNetworkSharedNotes,\n handleFormation,\n handleMember,\n handleMemberContent,\n handleGifts,\n handleSchedule,\n handlePayments,\n handleAdminMeetings,\n handleAdminScheduling,\n // Roster + identity\n handleAdminPeople,\n handleAdminPeopleAccess,\n handleAdminPeopleRole,\n handleAdminCrmSync,\n handleAdminAdmissionGrants,\n handleAdminClerkPrivateProfileSync,\n // Aggregation\n handleAdminDashboard,\n handleAdminBilling,\n handleAdminMemberContent,\n handleAdminBuilderLibrary,\n // Lifecycle actions\n handleAdminMeetingReschedule,\n handleAdminMeetingCancel,\n handleAdminApprove,\n handleAdminRefund,\n handleAdminApplicationPatch,\n // Email + comms\n handleAdminGroupEmail,\n handleAdminEmailLog,\n handleAdminEmailTest,\n handleAdminComms,\n // Leader → follower record delivery\n handleAdminNetworkTargets,\n handleAdminNetworkRollup,\n handleAdminNetworkPush,\n handleAdminNetworkRecords,\n handleAdminNetworkNotes,\n handleAdminNetworkSharedNotes,\n // API requests must never fall through to an SPA asset response. Hosts still\n // get first refusal through options.routes, then this terminates unknown API\n // paths with an explicit machine-readable 404.\n async (_req, url) => url.pathname.startsWith(\"/api/\")\n ? json({ error: \"not found\" }, 404)\n : null,\n];\n\n/**\n * Build the Cloudflare `ExportedHandler` for a chapter/hub site: Clerk-JWT\n * verification, the source-aware admin gate, the mounted @odla-ai/crm routes, the\n * hub→chapter network projection, and the static-asset fallback. Hub mode serves\n * /api/health, /api/config, /api/me, /api/crm/*, /api/network/*; chapter mode\n * adds the public member surface (join/apply/pay/book) and the admin surface\n * (/api/admin/*).\n *\n * A wrapping site adds its own routes via `options.routes` — each receives the\n * same {@link WorkerContext} the built-ins get (so it reuses chapter's JWT\n * verify, db client, and role resolution instead of duplicating them), and runs\n * BEFORE the built-ins so it can override or alias a path.\n *\n * Observability is a host concern, not a chapter dependency. To trace, wrap the\n * result in your worker entry — `export default withObservability(chapterWorker(\n * { chapter }))` — with `withObservability` from `@odla-ai/o11y`. Sites that\n * don't run o11y bundle `@odla-ai/chapter/worker` without installing it.\n */\nexport function chapterWorker(options: ChapterWorkerOptions) {\n const ctx = createWorkerContext(options);\n const routes: Route[] = [...(options.routes ?? []), ...BUILTIN_ROUTES];\n return {\n async fetch(req: Request, env: ChapterEnv): Promise<Response> {\n const url = new URL(req.url);\n for (const route of routes) {\n const res = await route(req, url, env, ctx);\n if (res) return res;\n }\n // Everything else is the static site.\n return env.ASSETS.fetch(req);\n },\n };\n}\n"],"mappings":"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","names":["allowed","rows","rows","record","EMAIL_RE","text","ID","allowed","record","createRecord","updateRecord","record","crmDeps","updateRecord","createRecord","text","str","rows","first","id","groups","group","canonical","record","verifyFederatedRequest","allowed","text","PRICE","ROOT_KEYS","TIER_KEYS","allowed","text","verifyFederatedRequest","verifyFederatedRequest","encoder","canonicalValue","record","ID","SLUG","ROOT_KEYS","MAX_MARKDOWN","record","unknownKeys","allowed","record","unknownKeys","ROOT_KEYS","ID","SLUG","value","MAX_MARKDOWN","rows","reject","rows","verifyFederatedRequest","local","verifyFederatedRequest","reject","verifyFederatedRequest","rows","verifyStripeSignature","clientSecret","verifyStripeSignature","rows","rows","created","secret","first","firstRow","rows","control","first","rows","control","initCalendar","initCalendar","rows","crmDeps","gate","rows","gate","rows","computeBookableSlots","initCalendar","gate","initCalendar","computeBookableSlots","gate","loadGroup","str","text","signFederatedRequest","verifyFederatedRequest","record","crmDeps","gate","verifyFederatedRequest","signFederatedRequest","record","signFederatedRequest","verifyFederatedRequest","gate","record","allowed","verifyFederatedRequest","reader","signFederatedRequest","IDENTIFIER","MAX_NOTE","gate","getRecord","signFederatedRequest","verifyFederatedRequest","IDENTIFIER","RECORD_ID","MAX_NOTE","gate","verifyFederatedRequest","reader","record","getRecord","targetFor","signFederatedRequest","createRecord","allowed","createRecord","verifyFederatedRequest","ID","MAX_MARKDOWN","MAX_TEXT","ROOT_KEYS","SOURCE_KEYS","TARGET_KEYS","record","unknownKeys","allowed","text","integer","encoder","canonicalValue","record","control","local","rows","BODY_CAP","verifyFederatedRequest","withLocalAuthority","local","input","expectedRevision","now","checked","signFederatedRequest","signFederatedRequest","signFederatedRequest","signFederatedRequest","signFederatedRequest","signFederatedRequest","signFederatedRequest","signFederatedRequest"]}