cauthy-auth 0.24.2 → 0.25.0
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.
- package/dist/client.d.mts +12 -3
- package/dist/client.d.ts +12 -3
- package/dist/client.js +13 -1
- package/dist/client.js.map +1 -1
- package/dist/client.mjs +13 -1
- package/dist/client.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +16 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +16 -4
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.mts +13 -2
- package/dist/react.d.ts +13 -2
- package/dist/react.js +23 -5
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +23 -5
- package/dist/react.mjs.map +1 -1
- package/dist/svelte.d.mts +1 -1
- package/dist/svelte.d.ts +1 -1
- package/dist/svelte.js +13 -1
- package/dist/svelte.js.map +1 -1
- package/dist/svelte.mjs +13 -1
- package/dist/svelte.mjs.map +1 -1
- package/dist/{validate-B_iC-4y8.d.mts → validate-BTRit1O1.d.mts} +1 -1
- package/dist/{validate-B_iC-4y8.d.ts → validate-BTRit1O1.d.ts} +1 -1
- package/dist/vue.d.mts +1 -1
- package/dist/vue.d.ts +1 -1
- package/dist/vue.js +13 -1
- package/dist/vue.js.map +1 -1
- package/dist/vue.mjs +13 -1
- package/dist/vue.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cookies.ts","../src/seal.ts","../src/system.ts","../src/url.ts","../src/theme.ts","../src/types.ts","../src/validate.ts","../src/webhook.ts","../src/cauthy.ts","../src/permissions.ts","../src/connect.ts","../src/verify.ts"],"sourcesContent":["// Cookies, by hand: reading the Cookie header and writing Set-Cookie.\n//\n// A session can outgrow one cookie (browsers stop near 4 KB), so a value is\n// written in numbered parts — name.0, name.1 — and read back in order.\n\nconst PART = 3500\n\nexport function readCookies(header: string | null | undefined): Map<string, string> {\n const out = new Map<string, string>()\n for (const pair of (header ?? '').split(';')) {\n const i = pair.indexOf('=')\n if (i > 0) out.set(pair.slice(0, i).trim(), pair.slice(i + 1).trim())\n }\n return out\n}\n\n/** A value written in parts, or null when the cookie is not there. */\nexport function readParts(cookies: Map<string, string>, name: string): string | null {\n let value = ''\n for (let i = 0; cookies.has(`${name}.${i}`); i++) value += cookies.get(`${name}.${i}`)\n return value === '' ? null : value\n}\n\nexport interface CookieAttributes {\n secure: boolean\n maxAge: number // seconds; 0 deletes\n path?: string\n}\n\nfunction attributes(a: CookieAttributes): string {\n // httpOnly: script never reads it. SameSite=Lax: it rides the navigation\n // that comes back from Cauthy, and no cross-site form post.\n return `Path=${a.path ?? '/'}; HttpOnly; SameSite=Lax; Max-Age=${a.maxAge}${a.secure ? '; Secure' : ''}`\n}\n\nexport function writeCookie(name: string, value: string, a: CookieAttributes): string {\n return `${name}=${value}; ${attributes(a)}`\n}\n\n/**\n * The Set-Cookie headers that store a value in parts and delete whatever\n * parts an earlier, longer value left behind.\n */\nexport function writeParts(name: string, value: string, a: CookieAttributes, had: Map<string, string>): string[] {\n const out: string[] = []\n let n = 0\n for (let i = 0; i < value.length; i += PART) out.push(writeCookie(`${name}.${n++}`, value.slice(i, i + PART), a))\n for (let i = n; had.has(`${name}.${i}`); i++) out.push(writeCookie(`${name}.${i}`, '', { ...a, maxAge: 0 }))\n return out\n}\n\nexport function clearParts(name: string, a: CookieAttributes, had: Map<string, string>): string[] {\n const out: string[] = []\n for (let i = 0; had.has(`${name}.${i}`) || i === 0; i++) out.push(writeCookie(`${name}.${i}`, '', { ...a, maxAge: 0 }))\n return out\n}\n","// The session cookie's envelope: encrypted and authenticated with a key only\n// the server has, so the browser carries the session without being able to\n// read or change it.\n\nimport { CompactEncrypt, compactDecrypt } from 'jose'\n\nconst encoder = new TextEncoder()\nconst decoder = new TextDecoder()\n\n/** The 256-bit key a secret stands for. */\nexport async function keyOf(secret: string): Promise<Uint8Array> {\n return new Uint8Array(await crypto.subtle.digest('SHA-256', encoder.encode(secret)))\n}\n\nexport async function seal(value: unknown, key: Uint8Array): Promise<string> {\n return new CompactEncrypt(encoder.encode(JSON.stringify(value)))\n .setProtectedHeader({ alg: 'dir', enc: 'A256GCM' })\n .encrypt(key)\n}\n\n/** The value sealed, or null for anything that is not a cookie this key made. */\nexport async function unseal<T>(sealed: string, key: Uint8Array): Promise<T | null> {\n try {\n const { plaintext } = await compactDecrypt(sealed, key, {\n keyManagementAlgorithms: ['dir'],\n contentEncryptionAlgorithms: ['A256GCM'],\n })\n return JSON.parse(decoder.decode(plaintext)) as T\n } catch {\n return null\n }\n}\n","// The application acting on its own: creating its organizations, adding their\n// members, inviting people. No person's token is involved — the application\n// is somebody in Cauthy, and what it may touch is its own system's\n// organizations and nothing else.\n//\n// It proves who it is with the client's secret, or with a key it holds and\n// whose public half it publishes (`publicJwks`): then nothing secret is ever\n// shared with Cauthy.\n\nimport { exportJWK, importJWK, importPKCS8, SignJWT, type JWK, type KeyLike } from 'jose'\nimport { fromWire, type CauthyTheme } from './theme'\nimport { CauthyConfigError, type JsonValue } from './types'\nimport { withoutTrailingSlashes } from './url'\n\nconst ASSERTION_TYPE = 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer'\n/** Ask for a new token this long before the one held runs out. */\nconst SKEW_MS = 30_000\n\n/** The key an application signs its assertions with. */\nexport interface SystemKey {\n /** The private key: PKCS#8 PEM, or a JWK (as an object or its JSON). RSA, for RS256. */\n privateKey: string | JWK\n /** The id the public key is published under (`kid`). */\n keyId: string\n}\n\nexport interface SystemOptions {\n /** Cauthy's address. Default: `CAUTHY_ISSUER`. */\n issuer?: string\n /** The application's client id. Default: `CAUTHY_CLIENT_ID`. */\n clientId?: string\n /** Its secret. Default: `CAUTHY_CLIENT_SECRET`. Not needed with `key`. */\n clientSecret?: string\n /**\n * The key to prove who the application is with, instead of the secret.\n * Default: `CAUTHY_SYSTEM_KEY` (the private key) and `CAUTHY_SYSTEM_KEY_ID`.\n */\n key?: SystemKey\n fetch?: typeof fetch\n}\n\n/** Cauthy refused a request of the application's own. */\nexport class CauthyApiError extends Error {\n constructor(\n readonly status: number,\n /** Cauthy's code for what went wrong: `organization_not_found`, `other_system`, `outside_system_scope`… */\n readonly code: string,\n message: string,\n ) {\n super(`cauthy-auth: ${message}`)\n this.name = 'CauthyApiError'\n }\n}\n\n/** An organization of the application's system. Every moment is UTC. */\nexport interface Organization {\n id: string\n system: string\n name: string\n kind: string\n /** The id the application knows it by. */\n externalId?: string\n status: 'active' | 'archived'\n metadata: Record<string, JsonValue>\n members: number\n createdAt: string\n updatedAt: string\n}\n\nexport interface OrganizationMember {\n userId: string\n email: string\n name: string\n /** The account's status: a disabled member is still listed. */\n status: string\n role: string\n /** True when the address had no account: one was made and invited. */\n invited?: boolean\n}\n\n/** Who to add: an account by its id, or anybody by their address (invited when new). */\nexport type NewMember = { role: string; name?: string; locale?: string } & ({ userId: string; email?: undefined } | { email: string; userId?: undefined })\n\nexport interface CauthySystem {\n /** The application's own token, asked for when needed and kept until it is about to run out. */\n token(): Promise<string>\n /** Any route the application's token may call; answers what Cauthy put under `data`. */\n request<T = unknown>(method: string, path: string, body?: unknown): Promise<T>\n organizations: {\n list(query?: { q?: string; status?: 'active' | 'archived'; limit?: number; offset?: number }): Promise<{ items: Organization[]; total: number }>\n create(input: { name: string; kind?: string; externalId?: string; metadata?: Record<string, JsonValue> }): Promise<Organization>\n get(id: string): Promise<Organization>\n update(id: string, patch: { name?: string; kind?: string; status?: 'active' | 'archived'; metadata?: Record<string, JsonValue> }): Promise<Organization>\n /** Removes the organization and every membership of it, for good. */\n remove(id: string): Promise<void>\n }\n members: {\n list(organizationId: string): Promise<OrganizationMember[]>\n add(organizationId: string, member: NewMember): Promise<OrganizationMember>\n setRole(organizationId: string, userId: string, role: string): Promise<OrganizationMember>\n remove(organizationId: string, userId: string): Promise<void>\n }\n /** Invites a person who has no account yet; answers the account made for them. */\n invite(person: { email: string; name?: string; locale?: string }): Promise<{ id: string; email: string }>\n /**\n * How the application looks on Cauthy's pages, read. It is decided in\n * Cauthy's dashboard, by a person: an application never changes it.\n */\n theme: {\n get(clientId?: string): Promise<CauthyTheme>\n }\n /** The catalog of roles of one of the application's systems, as Cauthy has it. */\n policy: {\n get(system: string): Promise<import('./permissions').PolicyRole[]>\n }\n /** The public half of `key`, to serve at the address Cauthy was given (`jwks_uri`). Empty with a secret. */\n publicJwks(): Promise<{ keys: JWK[] }>\n}\n\nfunction env(name: string): string | undefined {\n return typeof process !== 'undefined' ? process.env?.[name] : undefined\n}\n\ninterface OrgWire {\n id: string; system: string; name: string; kind: string; external_id?: string; status: 'active' | 'archived'\n metadata: Record<string, JsonValue>; members: number; created_at: string; updated_at: string\n}\n\nfunction toOrganization(o: OrgWire): Organization {\n return { id: o.id, system: o.system, name: o.name, kind: o.kind, externalId: o.external_id, status: o.status,\n metadata: o.metadata ?? {}, members: o.members, createdAt: o.created_at, updatedAt: o.updated_at }\n}\n\ninterface MemberWire { user_id: string; email: string; name: string; status: string; role: string; invited?: boolean }\n\nfunction toMember(m: MemberWire): OrganizationMember {\n return { userId: m.user_id, email: m.email, name: m.name, status: m.status, role: m.role, ...(m.invited === undefined ? {} : { invited: m.invited }) }\n}\n\nfunction asJwk(k: SystemKey): JWK | undefined {\n if (typeof k.privateKey !== 'string') return k.privateKey\n return k.privateKey.includes('BEGIN') ? undefined : (JSON.parse(k.privateKey) as JWK)\n}\n\nasync function loadKey(k: SystemKey): Promise<KeyLike | Uint8Array> {\n const jwk = asJwk(k)\n // Extractable, so its public half can be published (publicJwks).\n return jwk ? importJWK(jwk, 'RS256') : importPKCS8(k.privateKey as string, 'RS256', { extractable: true })\n}\n\nexport function createSystem(given: SystemOptions = {}): CauthySystem {\n const issuer = withoutTrailingSlashes(given.issuer ?? env('CAUTHY_ISSUER') ?? '')\n const clientId = given.clientId ?? env('CAUTHY_CLIENT_ID') ?? ''\n const clientSecret = given.clientSecret ?? env('CAUTHY_CLIENT_SECRET') ?? ''\n const envKey = env('CAUTHY_SYSTEM_KEY')\n const key = given.key ?? (envKey ? { privateKey: envKey, keyId: env('CAUTHY_SYSTEM_KEY_ID') ?? '' } : undefined)\n const doFetch: typeof fetch = (...args) => (given.fetch ?? fetch)(...args)\n const tokenEndpoint = `${issuer}/v1/oauth/token`\n\n // Checked when it is first used, not when it is made: an application that\n // only signs people in never needs any of this.\n function configured(): void {\n if (!/^https?:\\/\\//.test(issuer)) throw new CauthyConfigError('issuer (CAUTHY_ISSUER) must be Cauthy\\'s address')\n if (clientId === '') throw new CauthyConfigError('clientId (CAUTHY_CLIENT_ID) is required')\n if (key ? key.keyId === '' : clientSecret === '') {\n throw new CauthyConfigError(key ? 'the key needs its id (CAUTHY_SYSTEM_KEY_ID)'\n : 'to act on its own the application needs its secret (CAUTHY_CLIENT_SECRET) or a key (CAUTHY_SYSTEM_KEY)')\n }\n }\n\n let imported: Promise<KeyLike | Uint8Array> | undefined\n const signingKey = () => (imported ??= loadKey(key as SystemKey))\n\n async function fail(res: Response, what: string): Promise<never> {\n const body = (await res.json().catch(() => null)) as { errors?: { code?: string; message?: string }[] } | null\n const first = body?.errors?.[0]\n throw new CauthyApiError(res.status, first?.code ?? 'error', `Cauthy refused ${what} (${res.status}): ${first?.message ?? res.statusText}`)\n }\n\n let held: { value: string; until: number } | undefined\n let asking: Promise<string> | undefined\n\n async function ask(): Promise<string> {\n configured()\n const form = new URLSearchParams({ grant_type: 'client_credentials', client_id: clientId })\n if (key) {\n const assertion = await new SignJWT({})\n .setProtectedHeader({ alg: 'RS256', kid: key.keyId })\n .setIssuer(clientId).setSubject(clientId).setAudience(tokenEndpoint)\n .setJti(crypto.randomUUID()).setIssuedAt().setExpirationTime('2m')\n .sign(await signingKey())\n form.set('client_assertion_type', ASSERTION_TYPE)\n form.set('client_assertion', assertion)\n } else {\n form.set('client_secret', clientSecret)\n }\n const res = await doFetch(tokenEndpoint, { method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, body: form })\n if (!res.ok) await fail(res, 'the application\\'s own token')\n const t = (await res.json()) as { access_token: string; expires_in: number }\n held = { value: t.access_token, until: Date.now() + t.expires_in * 1000 - SKEW_MS }\n return t.access_token\n }\n\n function token(): Promise<string> {\n if (held && Date.now() < held.until) return Promise.resolve(held.value)\n // One request, however many callers arrive while it is out.\n return (asking ??= ask().finally(() => { asking = undefined }))\n }\n\n async function call(method: string, path: string, body?: unknown): Promise<unknown> {\n const send = async () => doFetch(`${issuer}${path}`, {\n method,\n headers: { authorization: `Bearer ${await token()}`, ...(body === undefined ? {} : { 'content-type': 'application/json' }) },\n body: body === undefined ? undefined : JSON.stringify(body),\n })\n let res = await send()\n if (res.status === 401 && held) {\n // The token was taken back early (the client's keys or secret changed): once more, with a new one.\n held = undefined\n res = await send()\n }\n if (!res.ok) await fail(res, `${method} ${path}`)\n return res.status === 204 ? undefined : res.json()\n }\n\n const data = async <T>(method: string, path: string, body?: unknown) => ((await call(method, path, body)) as { data: T } | undefined)?.data as T\n const id = encodeURIComponent\n\n return {\n token,\n request: data,\n organizations: {\n async list(query = {}) {\n const q = new URLSearchParams()\n for (const [k, v] of Object.entries(query)) if (v !== undefined) q.set(k, String(v))\n const out = (await call('GET', `/v1/organizations${q.size ? `?${q}` : ''}`)) as { data: OrgWire[]; total_count: number }\n return { items: out.data.map(toOrganization), total: out.total_count }\n },\n async create(input) {\n return toOrganization(await data<OrgWire>('POST', '/v1/organizations',\n { name: input.name, kind: input.kind, external_id: input.externalId, metadata: input.metadata }))\n },\n async get(orgId) {\n return toOrganization(await data<OrgWire>('GET', `/v1/organizations/${id(orgId)}`))\n },\n async update(orgId, patch) {\n return toOrganization(await data<OrgWire>('PATCH', `/v1/organizations/${id(orgId)}`, patch))\n },\n async remove(orgId) {\n await call('DELETE', `/v1/organizations/${id(orgId)}`)\n },\n },\n members: {\n async list(orgId) {\n return (await data<MemberWire[]>('GET', `/v1/organizations/${id(orgId)}/members`)).map(toMember)\n },\n async add(orgId, m) {\n return toMember(await data<MemberWire>('POST', `/v1/organizations/${id(orgId)}/members`,\n { role: m.role, user_id: m.userId, email: m.email, name: m.name, locale: m.locale, client_id: clientId }))\n },\n async setRole(orgId, userId, role) {\n return toMember(await data<MemberWire>('PUT', `/v1/organizations/${id(orgId)}/members/${id(userId)}`, { role }))\n },\n async remove(orgId, userId) {\n await call('DELETE', `/v1/organizations/${id(orgId)}/members/${id(userId)}`)\n },\n },\n async invite(person) {\n // The invitation leads back to this application once it is accepted.\n const u = await data<{ id: string; email: string }>('POST', '/v1/users', { ...person, client_id: clientId })\n return { id: u.id, email: u.email }\n },\n theme: {\n async get(of = clientId) {\n return fromWire(await data<Record<string, unknown>>('GET', `/v1/oauth/clients/${id(of)}/theme`))\n },\n },\n policy: {\n async get(system) {\n return (await data<{ roles?: import('./permissions').PolicyRole[] }>('GET', `/v1/systems/${id(system)}/policy`)).roles ?? []\n },\n },\n async publicJwks() {\n if (!key) return { keys: [] }\n const { kty, n, e } = asJwk(key) ?? (await exportJWK(await signingKey()))\n return { keys: [{ kty, n, e, kid: key.keyId, alg: 'RS256', use: 'sig' }] }\n },\n }\n}\n","/**\n * The address without its trailing slashes: `https://auth.example.com/` and\n * `https://auth.example.com` name the same issuer. A loop, not `/\\/+$/`,\n * which backtracks over a long run of slashes.\n */\nexport function withoutTrailingSlashes(s: string): string {\n let end = s.length\n while (end > 0 && s.charCodeAt(end - 1) === 47) end--\n return s.slice(0, end)\n}\n","// An application's look, for Cauthy's hosted pages.\n//\n// Cauthy's pages — sign-in, sign-up, the account page — can take the colours,\n// corners, typeface and logo of the application that sends its people there,\n// so signing in reads as a page of the application. A theme is a short list of\n// values, which Cauthy checks one by one; it is never CSS.\n//\n// An application built with Stackmyth already has those values, as its\n// `--sm-*` tokens. `themeFromStackmyth` reads them out of its stylesheets.\n\nimport { withoutTrailingSlashes } from './url'\n\n/** How an application looks on Cauthy's hosted pages. Every value is optional. */\n/** One font file the application serves: a family in one weight (or a range) and one style. */\nexport interface ThemeFont {\n family: string\n /** An https address of a `.woff2` file. It must answer with `Access-Control-Allow-Origin` for Cauthy's origin. */\n url: string\n /** `400`, or `\"100 900\"` for a variable font. Default: 400. */\n weight?: number | string\n style?: 'normal' | 'italic'\n}\n\n/** What an application says on its sign-in page, in one language. */\nexport interface ThemeTexts {\n /** Replaces \"Sign in\". */\n heading?: string\n /** Replaces \"to continue to …\". */\n subheading?: string\n /** The messages of the split layout's panel, shown one at a time (up to 5). */\n panel?: string[]\n /** Links at the foot of the split layout: privacy, terms (up to 4). */\n links?: { label: string; url: string }[]\n}\n\nexport interface CauthyTheme {\n /** The page. Colours are `#rrggbb` or `rgba(r, g, b, a)`. */\n background?: string\n /** The card, and inputs. */\n surface?: string\n /** Headings and what is typed. */\n text?: string\n /** Paragraphs, labels, small print. */\n textMuted?: string\n border?: string\n /** The fields and the secondary buttons, when they are not the card's colours. */\n inputBackground?: string\n inputBorder?: string\n /** The main button, and what is written on it. */\n primary?: string\n primaryText?: string\n /** Links, and the focus ring. */\n accent?: string\n error?: string\n errorBackground?: string\n success?: string\n successBackground?: string\n /** Corners of cards and inputs, in pixels (0–40). */\n radius?: number\n /** Corners of buttons, in pixels (0–40). */\n buttonRadius?: number\n /** A CSS font-family list: the application's typeface first, a system font after it. */\n fontFamily?: string\n /** The files of the typefaces `fontFamily` names, for people who do not have them installed. */\n fonts?: ThemeFont[]\n /** An image shown where \"Cauthy\" is, over https. */\n logoUrl?: string\n /**\n * How the sign-in pages are laid out: `card` (the default, one card in the\n * middle) or `split` (the form on one side, a panel that presents the\n * application on the other).\n */\n layout?: 'card' | 'split'\n /** The colours the split layout's backdrop blends, one to four. */\n panelColors?: string[]\n /** The colour of what is written on the panel. */\n panelText?: string\n /** An https image shown over the panel's messages. */\n panelIconUrl?: string\n /** The application's own words on the sign-in page, by language (`en`, `es`). */\n texts?: Record<string, ThemeTexts>\n /**\n * The application's Stackmyth tokens (`--sm-*`), from `tokensFromStackmyth`.\n * Cauthy's pages are drawn with Stackmyth's components, so these make its\n * buttons and fields the application's own. They are laid over the named values.\n */\n tokens?: Record<string, string>\n}\n\nexport interface StackmythThemeOptions {\n /**\n * The named theme to read, when the stylesheet keeps several under\n * `[data-theme=…]` (`\"vennet\"`). Without it only what applies to every\n * page (`:root`) is read.\n */\n theme?: string\n /** Which of the application's two modes to take. Default: `light`. */\n mode?: 'light' | 'dark'\n logoUrl?: string\n}\n\nexport interface ImportedTheme {\n theme: CauthyTheme\n /** Tokens that were there and could not be carried over, and why. */\n warnings: string[]\n}\n\nconst MAX_RADIUS = 40\n\n// ── Reading custom properties out of CSS ───────────────────────────────────\n\ninterface Declaration {\n name: string\n value: string\n /** The selectors and at-rules it sits inside, outermost first. */\n within: string[]\n}\n\n// The stylesheet without its /* comments */, read in one pass. An unclosed\n// comment runs to the end, as a browser reads it.\nfunction withoutComments(css: string): string {\n let out = ''\n let i = 0\n for (;;) {\n const open = css.indexOf('/*', i)\n if (open < 0) return out + css.slice(i)\n out += css.slice(i, open)\n const close = css.indexOf('*/', open + 2)\n if (close < 0) return out\n i = close + 2\n }\n}\n\nfunction declarations(css: string): Declaration[] {\n const text = withoutComments(css)\n const out: Declaration[] = []\n const within: string[] = []\n let chunk = ''\n let quote = ''\n let depth = 0 // parentheses, so a `;` inside url(…) does not end anything\n const flush = () => {\n const m = /^\\s*(--[\\w-]+)\\s*:\\s*([\\s\\S]+?)\\s*$/.exec(chunk)\n if (m) out.push({ name: m[1], value: m[2].replace(/\\s+/g, ' ').replace(/\\s*!important$/, ''), within: [...within] })\n chunk = ''\n }\n for (const ch of text) {\n if (quote) {\n chunk += ch\n if (ch === quote) quote = ''\n continue\n }\n if (ch === '\"' || ch === \"'\") {\n quote = ch\n chunk += ch\n } else if (ch === '(') {\n depth++\n chunk += ch\n } else if (ch === ')') {\n depth = Math.max(0, depth - 1)\n chunk += ch\n } else if (ch === '{' && depth === 0) {\n within.push(chunk.trim().replace(/\\s+/g, ' '))\n chunk = ''\n } else if (ch === '}' && depth === 0) {\n flush()\n within.pop()\n } else if (ch === ';' && depth === 0) {\n flush()\n } else {\n chunk += ch\n }\n }\n return out\n}\n\nconst DARK = /prefers-color-scheme:\\s*dark|data-(mode|theme|color-scheme)=[\"']?dark|\\.dark\\b/i\nconst LIGHT = /prefers-color-scheme:\\s*light|data-(mode|theme|color-scheme)=[\"']?light|\\.light\\b/i\nconst NAMED = /data-theme=[\"']?([\\w-]+)/i\n\n/** Whether a declaration applies to the page being themed. */\nfunction applies(d: Declaration, o: Required<Pick<StackmythThemeOptions, 'mode'>> & { theme?: string }): boolean {\n for (const scope of d.within) {\n if (o.mode === 'light' && DARK.test(scope)) return false\n if (o.mode === 'dark' && LIGHT.test(scope)) return false\n const named = NAMED.exec(scope)\n if (named && !/^(dark|light)$/i.test(named[1]) && named[1] !== o.theme) return false\n // Component-level rules (`.btn { --sm-… }`) are not the page's theme;\n // the class a mode is switched with (`.dark`, as shadcn/ui does) is.\n if (!scope.startsWith('@') && !/:root|^html\\b|^body\\b|\\[data-|^\\*$|:host|^\\.(dark|light)\\b/.test(scope)) return false\n }\n return true\n}\n\n// ── Tokens ─────────────────────────────────────────────────────────────────\n\n/** What a token's value may be written with, as Cauthy checks it. */\nconst TOKEN_CHARS = /^[A-Za-z0-9 #%.,()/'\"_+*-]+$/\nconst TOKEN_FUNCS = new Set(['var', 'calc', 'min', 'max', 'clamp', 'rgb', 'rgba', 'hsl', 'hsla', 'hwb', 'lab', 'lch', 'oklab', 'oklch', 'color',\n 'color-mix', 'light-dark', 'cubic-bezier', 'steps', 'linear', 'linear-gradient', 'radial-gradient', 'conic-gradient',\n 'repeating-linear-gradient', 'repeating-radial-gradient', 'drop-shadow', 'blur', 'translate', 'translatex', 'translatey', 'scale', 'rotate'])\n\nfunction tokenValue(value: string): string | null {\n const v = value.replace(/\\s+/g, ' ').trim()\n if (v === '' || v.length > 400 || !TOKEN_CHARS.test(v)) return null\n for (const m of v.matchAll(/([A-Za-z-]+)\\(/g)) if (!TOKEN_FUNCS.has(m[1].toLowerCase())) return null\n if (/^\\(|[ ,(]\\(/.test(v)) return null\n return v\n}\n\n/** A scope that is the page's theme itself: the root, or the theme and mode attributes — never a component inside it. */\nconst THEME_SELECTOR = /^(?::root|html|body|\\[data-(?:theme|mode|color-scheme)(?:=[\"']?[\\w-]+[\"']?)?\\])$/i\n// Checked a selector at a time (split on commas and spaces) rather than with\n// one pattern over the list, which backtracks on a long one.\nconst isThemeScope = (selectors: string) => {\n const parts = selectors.split(/[\\s,]+/).filter(Boolean)\n return parts.length > 0 && parts.every((one) => THEME_SELECTOR.test(one))\n}\n\nexport interface StackmythTokens {\n /** Every `--sm-*` token the stylesheets set for the page, ready for `theme.tokens`. */\n tokens: Record<string, string>\n /** Tokens that were there and Cauthy would not take, and why. */\n warnings: string[]\n}\n\n/**\n * Reads an application's Stackmyth tokens out of its stylesheets: every\n * `--sm-*` custom property its theme sets, in the order the sheets are given\n * (a later one wins). Its own names — a brand palette the tokens point at —\n * are written in, so what comes out stands on Stackmyth's names alone.\n *\n * Cauthy's sign-in pages are drawn with Stackmyth's components: these tokens\n * are what makes them look like the application.\n */\nexport function tokensFromStackmyth(css: string | string[], options: StackmythThemeOptions = {}): StackmythTokens {\n const mode = options.mode ?? 'light'\n const all = (Array.isArray(css) ? css : [css]).flatMap(declarations)\n const named = options.theme ?? all.map((d) => d.within.map((w) => NAMED.exec(w)?.[1]).find((n) => n && !/^(dark|light)$/i.test(n))).find(Boolean)\n const vars = new Map<string, string>()\n for (const d of all) {\n if (!applies(d, { mode, theme: named })) continue\n if (!d.within.every((w) => w.startsWith('@') || isThemeScope(w))) continue\n vars.set(d.name, d.value)\n }\n // The application's own names are written in; Stackmyth's are left as references.\n const inline = (value: string, depth = 0): string | null => {\n if (depth > 16) return null\n let failed = false\n let out = value\n for (let guard = 0; guard < 64; guard++) {\n const next = out.replace(/var\\(\\s*(--(?!sm-)[\\w-]+)\\s*(?:,\\s*([^()]*(?:\\([^()]*\\)[^()]*)*))?\\)/, (_m, name: string, fallback?: string) => {\n const known = vars.get(name)\n const got = known !== undefined ? inline(known, depth + 1) : fallback !== undefined ? inline(fallback.trim(), depth + 1) : null\n if (got === null) failed = true\n return got ?? ''\n })\n if (failed) return null\n if (next === out) break\n out = next\n }\n return out\n }\n const tokens: Record<string, string> = {}\n const warnings: string[] = []\n for (const [name, raw] of vars) {\n if (!/^--sm-[a-z0-9]+(?:-[a-z0-9]+)*$/.test(name)) continue\n const written = inline(raw)\n const value = written === null ? null : tokenValue(written)\n if (value === null) warnings.push(`${name}: \"${raw.length > 60 ? raw.slice(0, 57) + '…' : raw}\" is not a value Cauthy takes`)\n else tokens[name] = value\n }\n if (Object.keys(tokens).length === 0) warnings.push('no --sm-* token was found in these stylesheets')\n return { tokens, warnings }\n}\n\n// ── Values ─────────────────────────────────────────────────────────────────\n\nfunction resolve(value: string, vars: Map<string, string>, seen = 0): string | null {\n if (seen > 16) return null\n let unresolved = false\n // Innermost var() first: fallbacks may hold another var().\n let out = value\n for (let guard = 0; guard < 32 && /var\\(/.test(out); guard++) {\n out = out.replace(/var\\(\\s*(--[\\w-]+)\\s*(?:,\\s*([^()]*(?:\\([^()]*\\)[^()]*)*))?\\)/, (_m, name: string, fallback?: string) => {\n const known = vars.get(name)\n const next = known !== undefined ? resolve(known, vars, seen + 1) : fallback !== undefined ? resolve(fallback.trim(), vars, seen + 1) : null\n if (next === null) unresolved = true\n return next ?? ''\n })\n if (unresolved) return null\n }\n return /var\\(/.test(out) ? null : out.trim()\n}\n\nconst clamp01 = (n: number) => Math.min(1, Math.max(0, n))\nconst hex2 = (n: number) => Math.round(clamp01(n) * 255).toString(16).padStart(2, '0')\nconst gamma = (c: number) => (c <= 0.0031308 ? 12.92 * c : 1.055 * Math.pow(c, 1 / 2.4) - 0.055)\n\nfunction out(r: number, g: number, b: number, a = 1): string {\n if (a >= 1) return `#${hex2(r)}${hex2(g)}${hex2(b)}`\n return `rgba(${Math.round(clamp01(r) * 255)}, ${Math.round(clamp01(g) * 255)}, ${Math.round(clamp01(b) * 255)}, ${Math.round(clamp01(a) * 1000) / 1000})`\n}\n\nconst alpha = (s: string | undefined) => (s === undefined ? 1 : s.endsWith('%') ? parseFloat(s) / 100 : parseFloat(s))\n\nconst KEYWORDS: Record<string, string> = { white: '#ffffff', black: '#000000' }\n\n/** A colour as Cauthy takes it — `#rrggbb` or `rgba(…)` — or null when it is none it can read. */\nexport function toColor(value: string): string | null {\n const v = value.trim().toLowerCase()\n if (KEYWORDS[v]) return KEYWORDS[v]\n if (/^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/.test(v)) return v\n let m = /^rgba?\\(\\s*([\\d.]+%?)[\\s,]+([\\d.]+%?)[\\s,]+([\\d.]+%?)(?:\\s*[,/]\\s*([\\d.]+%?))?\\s*\\)$/.exec(v)\n if (m) {\n const ch = (s: string) => (s.endsWith('%') ? parseFloat(s) / 100 : parseFloat(s) / 255)\n return out(ch(m[1]), ch(m[2]), ch(m[3]), alpha(m[4]))\n }\n m = /^hsla?\\(\\s*([\\d.]+)(?:deg)?[\\s,]+([\\d.]+)%[\\s,]+([\\d.]+)%(?:\\s*[,/]\\s*([\\d.]+%?))?\\s*\\)$/.exec(v)\n if (m) {\n const h = ((parseFloat(m[1]) % 360) + 360) % 360\n const s = parseFloat(m[2]) / 100\n const l = parseFloat(m[3]) / 100\n const f = (n: number) => {\n const k = (n + h / 30) % 12\n return l - s * Math.min(l, 1 - l) * Math.max(-1, Math.min(k - 3, 9 - k, 1))\n }\n return out(f(0), f(8), f(4), alpha(m[4]))\n }\n m = /^oklch\\(\\s*([\\d.]+%?)\\s+([\\d.]+%?)\\s+([\\d.]+)(?:deg)?(?:\\s*\\/\\s*([\\d.]+%?))?\\s*\\)$/.exec(v)\n if (m) {\n const L = m[1].endsWith('%') ? parseFloat(m[1]) / 100 : parseFloat(m[1])\n const C = m[2].endsWith('%') ? (parseFloat(m[2]) / 100) * 0.4 : parseFloat(m[2])\n const H = (parseFloat(m[3]) * Math.PI) / 180\n const a = C * Math.cos(H)\n const b = C * Math.sin(H)\n const l = Math.pow(L + 0.3963377774 * a + 0.2158037573 * b, 3)\n const mm = Math.pow(L - 0.1055613458 * a - 0.0638541728 * b, 3)\n const s = Math.pow(L - 0.0894841775 * a - 1.291485548 * b, 3)\n return out(\n gamma(4.0767416621 * l - 3.3077115913 * mm + 0.2309699292 * s),\n gamma(-1.2684380046 * l + 2.6097574011 * mm - 0.3413193965 * s),\n gamma(-0.0041960863 * l - 0.7034186147 * mm + 1.707614701 * s),\n alpha(m[4]),\n )\n }\n return null\n}\n\n/** A length in pixels, within what Cauthy takes, or null. */\nfunction toRadius(value: string): number | null {\n const m = /^([\\d.]+)(px|rem|em)?$/.exec(value.trim())\n if (!m) return null\n const px = parseFloat(m[1]) * (m[2] === 'rem' || m[2] === 'em' ? 16 : 1)\n return Number.isFinite(px) ? Math.min(MAX_RADIUS, Math.max(0, Math.round(px))) : null\n}\n\n/** A font list as Cauthy takes it, or null. */\nfunction toFont(value: string): string | null {\n const v = value.trim()\n return /^[A-Za-z0-9 ,'\"_-]{1,200}$/.test(v) && (v.match(/\"/g)?.length ?? 0) % 2 === 0 && (v.match(/'/g)?.length ?? 0) % 2 === 0 ? v : null\n}\n\n// ── Stackmyth ──────────────────────────────────────────────────────────────\n\n/** Which Stackmyth token each value of a theme is read from, first found wins. */\nconst COLORS: [keyof CauthyTheme, string[]][] = [\n ['background', ['--sm-bg-surface', '--sm-surface']],\n ['surface', ['--sm-bg-surface-raised', '--sm-surface-raised']],\n ['text', ['--sm-text-primary', '--sm-surface-text']],\n ['textMuted', ['--sm-text-secondary']],\n ['border', ['--sm-border-default', '--sm-surface-border']],\n ['primary', ['--sm-primary', '--sm-bg-interactive']],\n ['primaryText', ['--sm-primary-text', '--sm-text-inverse']],\n ['accent', ['--sm-text-brand', '--sm-border-focus', '--sm-accent']],\n ['error', ['--sm-error-soft-text', '--sm-error']],\n ['errorBackground', ['--sm-error-soft']],\n ['success', ['--sm-success-soft-text', '--sm-success']],\n ['successBackground', ['--sm-success-soft']],\n]\n\n/**\n * Reads an application's Stackmyth theme out of its stylesheets.\n *\n * Give it the CSS that declares the tokens, in the order the application\n * loads it — Stackmyth's own (`@stackmyth/core/core.vars.css`, or a theme\n * file) and then the application's brand file that re-points them. Tokens\n * that point at the application's own variables are followed. The\n * application's dark mode is left out unless asked for.\n */\nexport function themeFromStackmyth(css: string | string[], options: StackmythThemeOptions = {}): ImportedTheme {\n const o = { mode: options.mode ?? 'light', theme: options.theme }\n const vars = new Map<string, string>()\n for (const sheet of Array.isArray(css) ? css : [css]) {\n for (const d of declarations(sheet)) if (applies(d, o)) vars.set(d.name, d.value)\n }\n const theme: CauthyTheme = {}\n const warnings: string[] = []\n\n const read = <T>(tokens: string[], to: (v: string) => T | null, what: string): T | undefined => {\n for (const token of tokens) {\n const raw = vars.get(token)\n if (raw === undefined) continue\n const value = resolve(raw, vars)\n const got = value === null ? null : to(value)\n if (got !== null) return got\n warnings.push(`${token}: \"${raw}\" is not ${what} Cauthy can take`)\n }\n return undefined\n }\n\n for (const [field, tokens] of COLORS) {\n const c = read(tokens, toColor, 'a colour')\n if (c !== undefined) (theme as Record<string, unknown>)[field] = c\n }\n const radius = read(['--sm-radius-container', '--sm-radius-md'], toRadius, 'a length')\n if (radius !== undefined) theme.radius = radius\n const button = read(['--sm-radius-interactive', '--sm-radius-sm'], toRadius, 'a length')\n if (button !== undefined) theme.buttonRadius = button\n const font = read(['--sm-font-family'], toFont, 'a font list')\n if (font !== undefined) theme.fontFamily = font\n if (options.logoUrl) theme.logoUrl = options.logoUrl\n\n if (vars.size === 0) warnings.push('no custom properties were found: is this the stylesheet that declares the --sm-* tokens?')\n else if (![...vars.keys()].some((k) => k.startsWith('--sm-'))) warnings.push('no --sm-* token was found in these stylesheets')\n return { theme, warnings }\n}\n\n// ── Any stylesheet ─────────────────────────────────────────────────────────\n\n/** The values of a theme a stylesheet can say. */\nexport type ThemeField =\n | 'background' | 'surface' | 'text' | 'textMuted' | 'border' | 'inputBackground' | 'inputBorder'\n | 'primary' | 'primaryText' | 'accent' | 'error' | 'errorBackground' | 'success' | 'successBackground'\n | 'radius' | 'buttonRadius' | 'fontFamily'\n\n/** How a stylesheet names its look: Stackmyth's tokens, shadcn/ui's (and Tailwind's), or the application's own. */\nexport type CssFormat = 'stackmyth' | 'shadcn' | 'custom'\n\nexport interface CssThemeOptions {\n /** Which names to read. Default: `auto`, told from the stylesheet itself. */\n format?: CssFormat | 'auto'\n /** Which of the application's two modes to take. Default: `light`. */\n mode?: 'light' | 'dark'\n /** The named theme to read, when the stylesheet keeps several under `[data-theme=…]`. */\n theme?: string\n /** For `custom`: the variable each value is read from, `{ primary: '--brand' }`. */\n map?: Partial<Record<ThemeField, string>>\n}\n\nexport interface CssImportedTheme extends ImportedTheme {\n /** The names that were read. */\n format: CssFormat\n}\n\nconst RADII: ThemeField[] = ['radius', 'buttonRadius']\n\n/** shadcn/ui's names, as Tailwind 3 (`--primary`) and Tailwind 4 (`--color-primary`) write them. */\nconst SHADCN: [ThemeField, string[]][] = [\n ['background', ['--background', '--color-background']],\n ['surface', ['--card', '--color-card', '--popover', '--color-popover']],\n ['text', ['--foreground', '--color-foreground']],\n ['textMuted', ['--muted-foreground', '--color-muted-foreground']],\n ['border', ['--border', '--color-border']],\n ['inputBorder', ['--input', '--color-input']],\n ['primary', ['--primary', '--color-primary']],\n ['primaryText', ['--primary-foreground', '--color-primary-foreground']],\n ['accent', ['--ring', '--color-ring', '--primary', '--color-primary']],\n ['error', ['--destructive', '--color-destructive']],\n ['radius', ['--radius']],\n ['buttonRadius', ['--radius']],\n ['fontFamily', ['--font-sans', '--font-family']],\n]\n\n/** A colour as shadcn/ui writes it on Tailwind 3 — `222.2 84% 4.9%`, the inside of hsl() — or any other. */\nfunction shadcnColor(value: string): string | null {\n return /^[\\d.]+(?:deg)?\\s+[\\d.]+%\\s+[\\d.]+%(?:\\s*\\/\\s*[\\d.]+%?)?$/.test(value.trim()) ? toColor(`hsl(${value.trim()})`) : toColor(value)\n}\n\n/** Every custom property a stylesheet sets for the page, the last one winning. */\nfunction pageVariables(css: string | string[], mode: 'light' | 'dark', theme?: string): Map<string, string> {\n const vars = new Map<string, string>()\n for (const sheet of Array.isArray(css) ? css : [css]) {\n for (const d of declarations(sheet)) if (applies(d, { mode, theme })) vars.set(d.name, d.value)\n }\n return vars\n}\n\n/** The custom properties a stylesheet sets for the page, by name: what a person picks from to map their own. */\nexport function cssVariables(css: string | string[], options: Pick<CssThemeOptions, 'mode' | 'theme'> = {}): string[] {\n return [...pageVariables(css, options.mode ?? 'light', options.theme).keys()].sort()\n}\n\n/**\n * Reads an application's look out of its stylesheets, whatever names it uses:\n * Stackmyth's tokens, shadcn/ui's (`--primary`, `--radius`, on Tailwind 3 or\n * 4), or the application's own variables given in `map`. What comes out is a\n * theme of named values, never CSS.\n */\nexport function themeFromCss(css: string | string[], options: CssThemeOptions = {}): CssImportedTheme {\n const mode = options.mode ?? 'light'\n const vars = pageVariables(css, mode, options.theme)\n const names = [...vars.keys()]\n let format: CssFormat\n if (options.format && options.format !== 'auto') format = options.format\n else if (options.map && Object.keys(options.map).length > 0) format = 'custom'\n else if (names.some((n) => n.startsWith('--sm-'))) format = 'stackmyth'\n else if (names.some((n) => /^--(color-)?(primary|background|foreground)$/.test(n))) format = 'shadcn'\n else format = 'custom'\n\n if (format === 'stackmyth') return { ...themeFromStackmyth(css, { mode, theme: options.theme }), format }\n\n const spec: [ThemeField, string[]][] = format === 'shadcn'\n ? SHADCN\n : Object.entries(options.map ?? {}).filter(([, v]) => v).map(([k, v]) => [k as ThemeField, [String(v).startsWith('--') ? String(v) : `--${v}`]])\n const theme: CauthyTheme = {}\n const warnings: string[] = []\n for (const [field, tokens] of spec) {\n for (const token of tokens) {\n const raw = vars.get(token)\n if (raw === undefined) continue\n const value = resolve(raw, vars)\n const got = value === null ? null\n : RADII.includes(field) ? toRadius(value)\n : field === 'fontFamily' ? toFont(value)\n : format === 'shadcn' ? shadcnColor(value) : toColor(value)\n if (got !== null) {\n (theme as Record<string, unknown>)[field] = got\n break\n }\n warnings.push(`${token}: \"${raw.length > 60 ? raw.slice(0, 57) + '…' : raw}\" is not ${RADII.includes(field) ? 'a length' : field === 'fontFamily' ? 'a font list' : 'a colour'} Cauthy can take`)\n }\n }\n if (vars.size === 0) warnings.push('no custom properties were found in these stylesheets')\n else if (format === 'custom' && spec.length === 0) warnings.push('these stylesheets use names of their own: say which variable each value is read from')\n return { theme, warnings, format }\n}\n\n// ── On the application's own screens ───────────────────────────────────────\n\n/**\n * A theme as the CSS variables of `cauthy-auth/styles.css` (`--cauthy-*`), for\n * the forms an application shows on its own pages. The page's own background,\n * the layout and the words are Cauthy's pages' matter, and left out.\n */\nexport function themeVariables(theme: CauthyTheme): Record<string, string> {\n const vars: Record<string, string> = {}\n const put = (name: string, v: string | number | undefined) => {\n if (v === undefined || v === '') return\n vars[`--cauthy-${name}`] = typeof v === 'number' ? `${v}px` : v\n }\n put('surface', theme.surface)\n put('text', theme.text)\n put('text-muted', theme.textMuted)\n put('border', theme.border)\n put('input-background', theme.inputBackground)\n put('input-border', theme.inputBorder)\n put('primary', theme.primary)\n put('primary-text', theme.primaryText)\n put('accent', theme.accent)\n put('error', theme.error)\n put('error-background', theme.errorBackground)\n put('success', theme.success)\n put('success-background', theme.successBackground)\n put('radius', theme.radius)\n put('button-radius', theme.buttonRadius)\n put('font', theme.fontFamily)\n return vars\n}\n\n// ── Sending it to Cauthy ───────────────────────────────────────────────────\n\n/** A theme as Cauthy's API names its values. */\nexport function toWire(theme: CauthyTheme): Record<string, unknown> {\n const names: Record<keyof CauthyTheme, string> = {\n background: 'background', surface: 'surface', text: 'text', textMuted: 'text_muted', border: 'border',\n primary: 'primary', primaryText: 'primary_text', accent: 'accent', error: 'error', errorBackground: 'error_background',\n success: 'success', successBackground: 'success_background', radius: 'radius', buttonRadius: 'button_radius',\n fontFamily: 'font_family', logoUrl: 'logo_url', fonts: 'fonts', layout: 'layout', panelColors: 'panel_colors',\n panelText: 'panel_text', panelIconUrl: 'panel_icon_url', texts: 'texts', inputBackground: 'input_background', inputBorder: 'input_border', tokens: 'tokens',\n }\n const wire: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(theme)) {\n if (v === undefined || v === '' || (Array.isArray(v) && v.length === 0)) continue\n wire[names[k as keyof CauthyTheme]] = v\n }\n return wire\n}\n\n/** A theme as Cauthy answers it, in this package's names. */\nexport function fromWire(wire: Record<string, unknown>): CauthyTheme {\n const names: Record<string, keyof CauthyTheme> = {\n background: 'background', surface: 'surface', text: 'text', text_muted: 'textMuted', border: 'border',\n primary: 'primary', primary_text: 'primaryText', accent: 'accent', error: 'error', error_background: 'errorBackground',\n success: 'success', success_background: 'successBackground', radius: 'radius', button_radius: 'buttonRadius',\n font_family: 'fontFamily', logo_url: 'logoUrl', fonts: 'fonts', layout: 'layout', panel_colors: 'panelColors',\n panel_text: 'panelText', panel_icon_url: 'panelIconUrl', texts: 'texts', input_background: 'inputBackground', input_border: 'inputBorder', tokens: 'tokens',\n }\n const theme: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(wire ?? {})) if (names[k] && v !== undefined && v !== null && v !== '') theme[names[k]] = v\n return theme as CauthyTheme\n}\n\nexport interface PushThemeOptions {\n /** Cauthy's address. Default: `CAUTHY_ISSUER`. */\n issuer?: string\n /** The application's client id. Default: `CAUTHY_CLIENT_ID`. */\n clientId?: string\n /** The workspace's slug. Default: `CAUTHY_TENANT`. */\n tenant?: string\n /**\n * A personal access token with `oauth_clients:manage`. Default:\n * `CAUTHY_TOKEN`. It belongs in the deploy pipeline, never in the application.\n */\n token?: string\n theme: CauthyTheme\n fetch?: typeof fetch\n}\n\n/**\n * Gives the application its look on Cauthy's pages. It replaces the theme: a\n * value left out goes back to Cauthy's own. Run it when the brand changes —\n * from a script or the deploy — not on every request.\n */\nexport async function pushTheme(o: PushThemeOptions): Promise<void> {\n const env = (n: string) => (typeof process !== 'undefined' ? process.env?.[n] : undefined)\n const issuer = withoutTrailingSlashes(o.issuer ?? env('CAUTHY_ISSUER') ?? '')\n const clientId = o.clientId ?? env('CAUTHY_CLIENT_ID') ?? ''\n const tenant = o.tenant ?? env('CAUTHY_TENANT') ?? ''\n const token = o.token ?? env('CAUTHY_TOKEN') ?? ''\n for (const [name, v] of Object.entries({ CAUTHY_ISSUER: issuer, CAUTHY_CLIENT_ID: clientId, CAUTHY_TENANT: tenant, CAUTHY_TOKEN: token })) {\n if (v === '') throw new Error(`cauthy-auth: ${name} is required to push a theme`)\n }\n const res = await (o.fetch ?? fetch)(`${issuer}/v1/oauth/clients/${encodeURIComponent(clientId)}/theme`, {\n method: 'PUT',\n headers: { authorization: `Bearer ${token}`, 'x-tenant-key': tenant, 'content-type': 'application/json' },\n body: JSON.stringify(toWire(o.theme)),\n })\n if (!res.ok) {\n const body = (await res.json().catch(() => null)) as { errors?: { message?: string }[] } | null\n throw new Error(`cauthy-auth: Cauthy refused the theme (${res.status}): ${body?.errors?.[0]?.message ?? res.statusText}`)\n }\n}\n","/** How an application is set up to sign its people in with Cauthy. */\nexport interface CauthyOptions {\n /** Cauthy's public address, e.g. `https://id.example.com`. Default: `CAUTHY_ISSUER`. */\n issuer?: string\n /** The application's OAuth client id. Default: `CAUTHY_CLIENT_ID`. */\n clientId?: string\n /** Its secret, when the client is confidential. Default: `CAUTHY_CLIENT_SECRET`. */\n clientSecret?: string\n /**\n * The key the session cookie is encrypted with: any string of 32 characters\n * or more, kept on the server. Default: `CAUTHY_SECRET`.\n */\n secret?: string\n /**\n * The system this application is, as its organizations are filed under in\n * Cauthy (`\"pondari\"`). When set, a session's organizations are that\n * system's. Default: `CAUTHY_SYSTEM`.\n */\n system?: string\n /**\n * The workspace's slug in Cauthy. Needed for the application's own sign-in\n * screens (`signIn.email`, `signUp.email`…), which sign people in through\n * the application's server instead of Cauthy's page. Default: `CAUTHY_TENANT`.\n */\n tenant?: string\n /** Where the routes are mounted. Default: `/api/auth`. */\n basePath?: string\n /**\n * The application's own public origin (`https://app.example.com`), for the\n * redirect URI. Default: the origin of each request, which is right unless\n * a proxy hides it.\n */\n baseURL?: string\n /** Where a person lands after signing in, when no `return_to` was asked. Default: `/`. */\n afterSignIn?: string\n /** Where a person lands after signing out. Default: `/`. */\n afterSignOut?: string\n /** Name of the session cookie. Default: `cauthy_session`. */\n cookieName?: string\n /**\n * A key the application proves who it is with when it acts on its own\n * (`auth.system`), instead of its secret. Default: `CAUTHY_SYSTEM_KEY` and\n * `CAUTHY_SYSTEM_KEY_ID`.\n */\n systemKey?: import('./system').SystemKey\n /**\n * The application's own pages for what arrives by mail. A link Cauthy mails\n * opens the page named here, with a `token` to give back; with none, it\n * opens Cauthy's own page.\n *\n * signIn where `<SignIn />` is: a sign-in link opens it\n * resetPassword where `<ResetPassword />` is\n * verifyEmail where `<VerifyEmail />` is\n */\n pages?: { signIn?: string; resetPassword?: string; verifyEmail?: string }\n /**\n * The address of the person a request comes from, passed on to Cauthy so\n * its limits on attempts count the person and not this server. Default: the\n * last address in `X-Forwarded-For`, which is the one the proxy in front of\n * the application wrote. With several proxies, or none, give your own.\n */\n clientIp?: (request: Request) => string | undefined\n /** `fetch` to reach Cauthy with. Default: the global one. */\n fetch?: typeof fetch\n}\n\n/** The person signed in. Every moment is UTC. */\nexport interface SessionUser {\n id: string\n email: string\n name: string\n emailVerified: boolean\n /**\n * True when the account ran out of time to confirm its address: let it read\n * and refuse its writes.\n */\n restricted: boolean\n /** When an unconfirmed address stops being enough (ISO 8601, UTC), if there is a deadline. */\n emailVerifyBy?: string\n /** The language the person reads in (\"es\", \"en-US\"), when Cauthy knows it. */\n locale?: string\n /** A guest: a visitor's session before they sign up. No email; `account.upgrade` makes it an account, keeping `id`. */\n isAnonymous?: boolean\n}\n\n/** A value JSON can carry. What crosses from server to browser is typed as this, never `unknown`. */\nexport type JsonValue = string | number | boolean | null | JsonValue[] | { [key: string]: JsonValue }\n\n/** An organization the person belongs to, with their role in it. */\nexport interface SessionOrganization {\n id: string\n system: string\n name: string\n kind: string\n externalId?: string\n role: string\n /** What the system keeps about the organization, as it filed it in Cauthy. */\n metadata: Record<string, JsonValue>\n /**\n * What the person may do here, as \"resource:action\" entries (\"*\" is any):\n * their role's permissions, what it inherits, and anything given to them\n * apart from it. Absent when the system keeps no catalog of roles in Cauthy.\n * Check with `can(organization, resource, action)`.\n */\n permissions?: string[]\n /** What the person is denied here, whatever else allows it. */\n denied?: string[]\n}\n\n/** A signed-in person, as the server sees them. */\nexport interface Session {\n user: SessionUser\n /** The Cauthy tenant the account is of. */\n tenantId: string\n /** The roles the account holds in that tenant. */\n roles: string[]\n /**\n * Cauthy's access token for this person: send it as `Authorization: Bearer`\n * to another service that verifies Cauthy's tokens. Never give it to the browser.\n */\n accessToken: string\n /** When the access token expires and the session is checked with Cauthy again (ISO 8601, UTC). */\n expiresAt: string\n}\n\n/** What the browser is told of a session: who, and their organizations — never a token. */\nexport interface PublicSession {\n user: SessionUser\n tenantId: string\n roles: string[]\n organizations: SessionOrganization[]\n expiresAt: string\n}\n\n/** Why there is no session. */\nexport type SessionStatus =\n | 'authenticated'\n | 'unauthenticated' // nobody is signed in\n | 'expired' // signed in, but the session must be renewed first (see `Cauthy.resolve`)\n\nexport class CauthyConfigError extends Error {\n constructor(message: string) {\n super(`cauthy-auth: ${message}`)\n this.name = 'CauthyConfigError'\n }\n}\n","// What a sign-in or sign-up form is checked for before anything is sent, in\n// the browser and again on the server: the same rules in both places, so the\n// form says what the server would.\n\nexport type AuthField = 'email' | 'password' | 'newPassword' | 'name' | 'code'\n\n/** A value of a form that cannot be sent as it is. */\nexport interface FieldProblem {\n field: AuthField\n /** Stable, for translating: `required`, `invalid_email`, `too_short`, `too_long`. */\n code: 'required' | 'invalid_email' | 'too_short' | 'too_long'\n message: string\n}\n\n/** The shortest password Cauthy takes for a new account. */\nexport const MIN_PASSWORD = 8\nconst MAX_PASSWORD = 256\nconst MAX_NAME = 120\n\n// One @, something on each side, a dot in the domain, no spaces: what catches\n// a typo. Whether the address exists is Cauthy's to find out.\nconst EMAIL = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n\nexport function checkEmail(value: unknown): FieldProblem | null {\n const v = typeof value === 'string' ? value.trim() : ''\n if (v === '') return { field: 'email', code: 'required', message: 'Enter your email address.' }\n if (v.length > 254 || !EMAIL.test(v)) return { field: 'email', code: 'invalid_email', message: 'That does not look like an email address.' }\n return null\n}\n\n/** A password being typed to sign in: only that there is one. */\nexport function checkPassword(value: unknown): FieldProblem | null {\n if (typeof value !== 'string' || value === '') return { field: 'password', code: 'required', message: 'Enter your password.' }\n if (value.length > MAX_PASSWORD) return { field: 'password', code: 'too_long', message: 'That password is too long.' }\n return null\n}\n\n/** A password being chosen for a new account. */\nexport function checkNewPassword(value: unknown): FieldProblem | null {\n const basic = checkPassword(value)\n if (basic) return basic\n if ((value as string).length < MIN_PASSWORD) {\n return { field: 'password', code: 'too_short', message: `Use at least ${MIN_PASSWORD} characters.` }\n }\n return null\n}\n\nexport function checkName(value: unknown): FieldProblem | null {\n if (value === undefined || value === null || value === '') return null\n if (typeof value !== 'string' || value.trim().length > MAX_NAME) return { field: 'name', code: 'too_long', message: `Use at most ${MAX_NAME} characters.` }\n return null\n}\n\nexport function checkCode(value: unknown): FieldProblem | null {\n const v = typeof value === 'string' ? value.trim() : ''\n if (v === '') return { field: 'code', code: 'required', message: 'Enter the code.' }\n if (v.length > 40) return { field: 'code', code: 'too_long', message: 'That is not a code.' }\n return null\n}\n\n/** The first problem of a form, or null when it can be sent. */\nexport function firstProblem(...checks: (FieldProblem | null)[]): FieldProblem | null {\n return checks.find((c) => c !== null) ?? null\n}\n","// Hearing from Cauthy: verifying a webhook delivery.\n//\n// Cauthy signs every delivery with its own key — the one its tokens are\n// signed with, published at /.well-known/jwks.json — so there is no secret to\n// receive, store or rotate. Verifying is one call:\n//\n// const event = await auth.webhook(request) // throws if it is not Cauthy's\n//\n// What is checked: the signature, against Cauthy's published keys; that the\n// delivery was meant for THIS endpoint (a signature anyone can verify must say\n// who it is for); that it is recent; and that the body is, byte for byte, the\n// one that was signed.\n\nimport { createRemoteJWKSet, jwtVerify, type JWTVerifyGetKey } from 'jose'\nimport type { JsonValue } from './types'\nimport { withoutTrailingSlashes } from './url'\n\n/** Something that happened in Cauthy, as a subscriber is told. Moments are UTC. */\nexport interface CauthyEvent {\n /** This delivery's id: the same event delivered again carries the same one. */\n id: string\n /** What happened: \"organization.member_added\". */\n type: string\n tenantId: string\n createdAt: string\n /** The person it happened to, when it is about one. */\n userId?: string\n /** Who did it. */\n actorId?: string\n /** What the event says: for an organization, its id, system, external_id, role… */\n data: Record<string, JsonValue>\n}\n\nexport class CauthyWebhookError extends Error {\n constructor(readonly reason: string) {\n super(`cauthy-auth: webhook refused: ${reason}`)\n this.name = 'CauthyWebhookError'\n }\n}\n\nexport interface VerifyWebhookOptions {\n /** Cauthy's address. Default: `CAUTHY_ISSUER`. */\n issuer?: string\n /**\n * This endpoint's own public address, exactly as it is registered in Cauthy.\n * Default: the request's URL, which is right unless a proxy changes it.\n */\n url?: string\n /** Cauthy's keys. Default: fetched from the issuer and cached. */\n jwks?: JWTVerifyGetKey\n /** The moment to verify at. Default: now. */\n now?: Date\n}\n\nconst keys = new Map<string, JWTVerifyGetKey>()\n\nfunction keysOf(issuer: string): JWTVerifyGetKey {\n let set = keys.get(issuer)\n if (set === undefined) {\n set = createRemoteJWKSet(new URL(`${issuer}/.well-known/jwks.json`), { cooldownDuration: 30_000 })\n keys.set(issuer, set)\n }\n return set\n}\n\nconst hex = (s: unknown) => (typeof s === 'string' && s !== '' ? s : undefined)\n\n/**\n * Verifies a delivery and answers the event it carries. Throws\n * `CauthyWebhookError` for anything that is not a delivery Cauthy made for\n * this endpoint just now: answer it 401 and nothing else.\n */\nexport async function verifyWebhook(request: Request, options: VerifyWebhookOptions = {}): Promise<CauthyEvent> {\n const env = typeof process !== 'undefined' ? process.env?.CAUTHY_ISSUER : undefined\n const issuer = withoutTrailingSlashes(options.issuer ?? env ?? '')\n if (issuer === '') throw new CauthyWebhookError('issuer (CAUTHY_ISSUER) is not set')\n const signature = request.headers.get('x-cauthy-signature-jwt')\n if (!signature) throw new CauthyWebhookError('no signature')\n\n // The bytes as they arrived: what was signed is their hash, not a re-encoding.\n const raw = new Uint8Array(await request.arrayBuffer())\n const audience = options.url ?? request.url.split('?')[0]\n\n let claims: Record<string, unknown>\n try {\n const verified = await jwtVerify(signature, options.jwks ?? keysOf(issuer), {\n algorithms: ['RS256'],\n audience,\n typ: 'cauthy-webhook+jwt',\n requiredClaims: ['exp', 'iat', 'jti', 'body_sha256'],\n currentDate: options.now,\n clockTolerance: 30,\n })\n claims = verified.payload as Record<string, unknown>\n } catch (err) {\n throw new CauthyWebhookError(err instanceof Error ? err.message : 'bad signature')\n }\n // Signed by Cauthy, for this issuer: Cauthy's own address, or the\n // workspace's custom domain (domain_iss) when that is the issuer here.\n if (claims.iss !== issuer && claims.domain_iss !== issuer) {\n throw new CauthyWebhookError('unexpected \"iss\" claim value')\n }\n\n // Not from the future either: a clock that far off is not Cauthy's.\n const now = Math.floor((options.now ?? new Date()).getTime() / 1000)\n if (typeof claims.iat !== 'number' || claims.iat > now + 30) throw new CauthyWebhookError('signed in the future')\n\n const digest = new Uint8Array(await crypto.subtle.digest('SHA-256', raw))\n let b64 = ''\n for (const b of digest) b64 += String.fromCharCode(b)\n const hash = btoa(b64).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')\n if (hash !== claims.body_sha256) throw new CauthyWebhookError('the body is not the one that was signed')\n\n let body: Record<string, any>\n try {\n body = JSON.parse(new TextDecoder().decode(raw))\n } catch {\n throw new CauthyWebhookError('the body is not JSON')\n }\n // The envelope and the signature must tell the same story.\n if (body.id !== claims.jti || body.event !== claims.evt || body.tenant_id !== claims.tid) {\n throw new CauthyWebhookError('the body and its signature disagree')\n }\n const inner = (body.data ?? {}) as Record<string, any>\n return {\n id: String(body.id),\n type: String(body.event),\n tenantId: String(body.tenant_id),\n createdAt: String(inner.created_at ?? body.created_at ?? ''),\n ...(hex(inner.user_id) ? { userId: inner.user_id } : {}),\n ...(hex(inner.actor_id) ? { actorId: inner.actor_id } : {}),\n data: (inner.data ?? {}) as Record<string, JsonValue>,\n }\n}\n","// Sign in with Cauthy, held by the application's own server.\n//\n// The application mounts one route (`handler`) and asks who is there\n// (`getSession`). Signing in, signing up, second factors, passkeys, recovering\n// a password and the account page are Cauthy's pages: this sends the browser\n// to them and keeps what comes back in an encrypted, httpOnly cookie. There is\n// no database and no screen to build.\n//\n// The session is Cauthy's short-lived access token plus the refresh token that\n// renews it. When the access token expires the session is renewed with Cauthy,\n// which is where an account disabled there, or signed out everywhere, stops\n// being signed in here — within minutes, with nothing to synchronise.\n\nimport { clearParts, readCookies, readParts, writeCookie, writeParts, type CookieAttributes } from './cookies'\nimport { keyOf, seal, unseal } from './seal'\nimport { createSystem, type CauthySystem } from './system'\nimport { checkCode, checkEmail, checkName, checkNewPassword, checkPassword, firstProblem, type FieldProblem } from './validate'\nimport { verifyWebhook, type CauthyEvent, type VerifyWebhookOptions } from './webhook'\nimport {\n CauthyConfigError,\n type CauthyOptions,\n type JsonValue,\n type PublicSession,\n type Session,\n type SessionOrganization,\n type SessionStatus,\n type SessionUser,\n} from './types'\nimport { withoutTrailingSlashes } from './url'\n\n/** What the session cookie holds. Short names: it rides every request. */\ninterface Stored {\n at: string // access token\n rt: string // refresh token\n exp: number // when the access token expires, epoch seconds\n u: SessionUser\n tid: string\n roles: string[]\n}\n\n/** What the sign-in in progress holds, between leaving for Cauthy and coming back. */\ninterface Flow {\n state: string\n verifier: string\n returnTo: string\n}\n\nconst SESSION_DAYS = 30\n// How long a sign-in may sit open at Cauthy and still be finished here. The\n// same hour Cauthy keeps its side of it.\nconst FLOW_SECONDS = 3600\n/** How long a sign-in that had to start again is remembered, so it starts again once and not forever. */\nconst AGAIN_SECONDS = 120\n/** Renew this long before the access token runs out, so a request never carries one about to. */\nconst SKEW_SECONDS = 30\nconst ORGANIZATIONS_TTL_MS = 60_000\n/** How long the workspace's look is kept before Cauthy is asked again. */\nconst LOOK_TTL_MS = 60_000\n/** A provider's id: `google`, `linkedin_oidc`, or one the workspace defined itself, `custom:<slug>`. */\nconst PROVIDER_ID = /^(custom:)?[a-z0-9_-]{1,40}$/\n\n/** The provider named in a route, as written or percent-encoded (`custom%3Aacme`). */\nfunction providerIn(segment: string): string {\n try {\n return decodeURIComponent(segment)\n } catch {\n return ''\n }\n}\n\n/** What `resolve` answers: who is there, and the cookies that must go back. */\nexport interface Resolved {\n session: Session | null\n status: SessionStatus\n /** `Set-Cookie` values to send with the response. Empty when nothing changed. */\n cookies: string[]\n}\n\nexport interface Cauthy {\n /** Serves the routes under `basePath`: login, callback, session, refresh, logout, account. */\n handler(request: Request): Promise<Response>\n /**\n * Who is signed in, or null.\n *\n * Give it the response's headers and a session that needs renewing is\n * renewed on the spot, its new cookie added to them. Without them an\n * expired session reads as null (see `status`): renewing changes the\n * cookie, and a cookie nobody sends back is a session lost.\n */\n getSession(request: Request, responseHeaders?: Headers): Promise<Session | null>\n /** Whether somebody is signed in, nobody is, or the session must be renewed first. */\n status(request: Request): Promise<SessionStatus>\n /**\n * The session, renewed when it has to be, and the cookies to send back.\n * The caller MUST send `cookies` with its response.\n */\n resolve(request: Request): Promise<Resolved>\n /**\n * For a route only a signed-in person may see: the session, or the response\n * to give instead — a redirect to sign in (or to renew) for a page, a 401\n * for anything else.\n */\n protect(request: Request): Promise<{ session: Session; response?: undefined } | { session?: undefined; response: Response }>\n /** The organizations the person belongs to (of `system`, when set), with their role in each. */\n organizations(session: Session): Promise<SessionOrganization[]>\n /**\n * Verifies a webhook delivery from Cauthy and answers the event it carries;\n * throws `CauthyWebhookError` for anything else. No secret is involved: the\n * delivery is signed with Cauthy's own key.\n */\n webhook(request: Request, options?: Pick<VerifyWebhookOptions, 'jwks' | 'now' | 'url'>): Promise<CauthyEvent>\n /**\n * The application acting on its own, with no person's token: its\n * organizations, their members, invitations. Needs the client's secret, or\n * `systemKey`.\n */\n system: CauthySystem\n /** What the browser may be told of a session. */\n toPublic(session: Session): Promise<PublicSession>\n /** Paths of this application that start a sign-in, a sign-out, or open the account page. */\n urls: { signIn(returnTo?: string): string; signOut(): string; account(returnTo?: string): string; session: string }\n options: Readonly<Required<Pick<CauthyOptions, 'issuer' | 'clientId' | 'basePath' | 'afterSignIn' | 'afterSignOut' | 'cookieName'>>>\n}\n\nfunction env(name: string): string | undefined {\n return typeof process !== 'undefined' ? process.env?.[name] : undefined\n}\n\nfunction b64url(bytes: Uint8Array): string {\n let s = ''\n for (const b of bytes) s += String.fromCharCode(b)\n return btoa(s).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')\n}\n\nfunction random(bytes = 32): string {\n return b64url(crypto.getRandomValues(new Uint8Array(bytes)))\n}\n\n/** A path of this application, and nothing else: never another site, never `//host`. */\nfunction localPath(candidate: string | null | undefined, fallback: string): string {\n if (!candidate || !candidate.startsWith('/') || candidate.startsWith('//') || candidate.includes('\\\\')) return fallback\n return candidate\n}\n\nfunction json(body: unknown, status = 200, headers?: Headers): Response {\n const h = headers ?? new Headers()\n h.set('content-type', 'application/json; charset=utf-8')\n h.set('cache-control', 'no-store')\n return new Response(JSON.stringify(body), { status, headers: h })\n}\n\nfunction redirect(location: string, cookies: string[] = []): Response {\n const h = new Headers({ location, 'cache-control': 'no-store' })\n for (const c of cookies) h.append('set-cookie', c)\n return new Response(null, { status: 302, headers: h })\n}\n\nexport function createCauthy(given: CauthyOptions = {}): Cauthy {\n const issuer = withoutTrailingSlashes(given.issuer ?? env('CAUTHY_ISSUER') ?? '')\n const clientId = given.clientId ?? env('CAUTHY_CLIENT_ID') ?? ''\n const clientSecret = given.clientSecret ?? env('CAUTHY_CLIENT_SECRET')\n const secret = given.secret ?? env('CAUTHY_SECRET') ?? ''\n const system = given.system ?? env('CAUTHY_SYSTEM') ?? ''\n const tenant = given.tenant ?? env('CAUTHY_TENANT') ?? ''\n if (!/^https?:\\/\\//.test(issuer)) throw new CauthyConfigError('issuer (CAUTHY_ISSUER) must be Cauthy\\'s address, e.g. https://id.example.com')\n if (clientId === '') throw new CauthyConfigError('clientId (CAUTHY_CLIENT_ID) is required')\n if (secret.length < 32) throw new CauthyConfigError('secret (CAUTHY_SECRET) must be at least 32 characters: it encrypts the session cookie')\n\n const basePath = '/' + (given.basePath ?? '/api/auth').replace(/^\\/+|\\/+$/g, '')\n const afterSignIn = localPath(given.afterSignIn, '/')\n const afterSignOut = localPath(given.afterSignOut, '/')\n const cookieName = given.cookieName ?? 'cauthy_session'\n const flowCookie = `${cookieName}_flow`\n const againCookie = `${cookieName}_again`\n const stepCookie = `${cookieName}_step`\n const doFetch: typeof fetch = (...args) => (given.fetch ?? fetch)(...args)\n const key = keyOf(secret)\n const pages = {\n signIn: given.pages?.signIn ? localPath(given.pages.signIn, '/') : undefined,\n resetPassword: given.pages?.resetPassword ? localPath(given.pages.resetPassword, '/') : undefined,\n verifyEmail: given.pages?.verifyEmail ? localPath(given.pages.verifyEmail, '/') : undefined,\n }\n const ownSystem = createSystem({ issuer, clientId, clientSecret, key: given.systemKey, fetch: given.fetch })\n\n const originOf = (request: Request) => withoutTrailingSlashes(given.baseURL ?? new URL(request.url).origin)\n const attrs = (request: Request, maxAge: number): CookieAttributes => ({ secure: originOf(request).startsWith('https://'), maxAge })\n\n // ── Talking to Cauthy ────────────────────────────────────────────────────\n\n async function token(form: Record<string, string>): Promise<{ ok: true; body: any } | { ok: false; ended: boolean }> {\n const body = new URLSearchParams({ client_id: clientId, ...form })\n if (clientSecret) body.set('client_secret', clientSecret)\n try {\n const res = await doFetch(`${issuer}/v1/oauth/token`, {\n method: 'POST',\n headers: { 'content-type': 'application/x-www-form-urlencoded', accept: 'application/json' },\n body,\n })\n if (res.ok) return { ok: true, body: await res.json() }\n // 4xx is Cauthy's answer: the grant is no good. Anything else is a\n // failure to ask, and says nothing about the session.\n return { ok: false, ended: res.status >= 400 && res.status < 500 }\n } catch {\n return { ok: false, ended: false }\n }\n }\n\n async function userinfo(accessToken: string): Promise<{ u: SessionUser; tid: string; roles: string[] } | null> {\n try {\n const res = await doFetch(`${issuer}/v1/oauth/userinfo`, { headers: { authorization: `Bearer ${accessToken}` } })\n if (!res.ok) return null\n const b = (await res.json()) as Record<string, any>\n return {\n tid: String(b.tid ?? ''),\n roles: Array.isArray(b.roles) ? b.roles.filter((r: unknown) => typeof r === 'string') : [],\n u: {\n id: String(b.sub ?? ''),\n email: String(b.email ?? ''),\n name: String(b.name ?? ''),\n emailVerified: b.email_verified === true,\n restricted: b.restricted === true,\n ...(typeof b.email_verify_by === 'string' ? { emailVerifyBy: b.email_verify_by } : {}),\n ...(typeof b.locale === 'string' && b.locale !== '' ? { locale: b.locale } : {}),\n ...(b.anonymous === true ? { isAnonymous: true } : {}),\n },\n }\n } catch {\n return null\n }\n }\n\n /** What Cauthy's answer to a token request becomes in the cookie. */\n async function stored(body: any): Promise<Stored | null> {\n if (typeof body?.access_token !== 'string' || typeof body?.refresh_token !== 'string') return null\n const who = await userinfo(body.access_token)\n if (who === null || who.u.id === '') return null\n const lifetime = typeof body.expires_in === 'number' && body.expires_in > 0 ? body.expires_in : 300\n return { at: body.access_token, rt: body.refresh_token, exp: Math.floor(Date.now() / 1000) + lifetime, ...who }\n }\n\n function toSession(s: Stored): Session {\n return { user: s.u, tenantId: s.tid, roles: s.roles, accessToken: s.at, expiresAt: new Date(s.exp * 1000).toISOString() }\n }\n\n // ── The cookie ───────────────────────────────────────────────────────────\n\n async function read(request: Request): Promise<{ had: Map<string, string>; value: Stored | null; present: boolean }> {\n const had = readCookies(request.headers.get('cookie'))\n const raw = readParts(had, cookieName)\n if (raw === null) return { had, value: null, present: false }\n const value = await unseal<Stored>(raw, await key)\n const sound = value !== null && typeof value.at === 'string' && typeof value.rt === 'string' && typeof value.exp === 'number'\n return { had, value: sound ? value : null, present: true }\n }\n\n async function write(request: Request, s: Stored, had: Map<string, string>): Promise<string[]> {\n return writeParts(cookieName, await seal(s, await key), attrs(request, SESSION_DAYS * 86_400), had)\n }\n\n const fresh = (s: Stored) => s.exp - Date.now() / 1000 > SKEW_SECONDS\n\n // One renewal per refresh token at a time in this process: requests that\n // arrive together share it. (Across processes Cauthy gives a few seconds'\n // grace to the same token, for the same reason.)\n const renewing = new Map<string, Promise<Stored | 'ended' | 'unreachable'>>()\n\n function renew(was: Stored): Promise<Stored | 'ended' | 'unreachable'> {\n let running = renewing.get(was.rt)\n if (running === undefined) {\n const rt = was.rt\n running = (async (): Promise<Stored | 'ended' | 'unreachable'> => {\n const res = await token({ grant_type: 'refresh_token', refresh_token: rt })\n if (!res.ok) return res.ended ? 'ended' : 'unreachable'\n const next = await stored(res.body)\n if (next !== null) return next\n // Renewed, but who it is could not be read just now. The new tokens\n // are kept all the same — the old refresh token is spent, and losing\n // its successor would lose the session — with what was known before.\n if (typeof res.body?.access_token !== 'string' || typeof res.body?.refresh_token !== 'string') return 'unreachable'\n const lifetime = typeof res.body.expires_in === 'number' && res.body.expires_in > 0 ? res.body.expires_in : 300\n return { ...was, at: res.body.access_token, rt: res.body.refresh_token, exp: Math.floor(Date.now() / 1000) + lifetime }\n })()\n renewing.set(rt, running)\n // A renewal that worked is remembered for a moment, for requests still\n // arriving with the old cookie; one that could not ask is tried again\n // by the next request.\n void running.then((result) => {\n if (result === 'unreachable') return renewing.delete(rt)\n const timer = setTimeout(() => renewing.delete(rt), 5_000)\n ;(timer as { unref?: () => void }).unref?.()\n })\n }\n return running\n }\n\n async function resolve(request: Request): Promise<Resolved> {\n const { had, value, present } = await read(request)\n if (value === null) {\n // A cookie this key did not make (a rotated secret, a tampered value) is cleared.\n return { session: null, status: 'unauthenticated', cookies: present ? clearParts(cookieName, attrs(request, 0), had) : [] }\n }\n if (fresh(value)) return { session: toSession(value), status: 'authenticated', cookies: [] }\n\n const renewed = await renew(value)\n if (renewed === 'ended') {\n return { session: null, status: 'unauthenticated', cookies: clearParts(cookieName, attrs(request, 0), had) }\n }\n // Cauthy could not be asked: the cookie stays as it is, and the next\n // request tries again. Nobody is let in on an expired token meanwhile.\n if (renewed === 'unreachable') return { session: null, status: 'expired', cookies: [] }\n return { session: toSession(renewed), status: 'authenticated', cookies: await write(request, renewed, had) }\n }\n\n async function getSession(request: Request, responseHeaders?: Headers): Promise<Session | null> {\n if (responseHeaders === undefined) {\n const { value } = await read(request)\n return value !== null && fresh(value) ? toSession(value) : null\n }\n const r = await resolve(request)\n for (const c of r.cookies) responseHeaders.append('set-cookie', c)\n return r.session\n }\n\n async function status(request: Request): Promise<SessionStatus> {\n const { value } = await read(request)\n if (value === null) return 'unauthenticated'\n return fresh(value) ? 'authenticated' : 'expired'\n }\n\n // ── Organizations ────────────────────────────────────────────────────────\n\n const orgCache = new Map<string, { at: number; value: SessionOrganization[] }>()\n\n async function organizations(session: Session): Promise<SessionOrganization[]> {\n const hit = orgCache.get(session.accessToken)\n if (hit && Date.now() - hit.at < ORGANIZATIONS_TTL_MS) return hit.value\n const url = `${issuer}/v1/oauth/organizations${system ? `?system=${encodeURIComponent(system)}` : ''}`\n const res = await doFetch(url, { headers: { authorization: `Bearer ${session.accessToken}` } })\n if (!res.ok) throw new Error(`cauthy-auth: reading organizations: ${res.status}`)\n const body = (await res.json()) as { data?: Record<string, any>[] }\n const value = (body.data ?? []).map(\n (o): SessionOrganization => ({\n id: String(o.id),\n system: String(o.system ?? ''),\n name: String(o.name ?? ''),\n kind: String(o.kind ?? ''),\n role: String(o.role ?? ''),\n metadata: (o.metadata as Record<string, JsonValue>) ?? {},\n ...(o.external_id ? { externalId: String(o.external_id) } : {}),\n ...(Array.isArray(o.permissions) ? { permissions: o.permissions.map(String), denied: Array.isArray(o.denied) ? o.denied.map(String) : [] } : {}),\n }),\n )\n if (orgCache.size > 5_000) orgCache.clear()\n orgCache.set(session.accessToken, { at: Date.now(), value })\n return value\n }\n\n // The application's own identity, as `auth.system`. A change it makes to who\n // belongs where (a new member, a new role, an organization gone) empties the\n // organizations read above: a person added a moment ago sees the\n // organization on the next page, not a minute later.\n const forgetting = <A extends unknown[], R>(fn: (...args: A) => Promise<R>) =>\n async (...args: A): Promise<R> => {\n const out = await fn(...args)\n orgCache.clear()\n return out\n }\n const systemThatRefreshes: CauthySystem = {\n ...ownSystem,\n organizations: {\n ...ownSystem.organizations,\n update: forgetting(ownSystem.organizations.update),\n remove: forgetting(ownSystem.organizations.remove),\n },\n members: {\n ...ownSystem.members,\n add: forgetting(ownSystem.members.add),\n setRole: forgetting(ownSystem.members.setRole),\n remove: forgetting(ownSystem.members.remove),\n },\n }\n\n async function toPublic(session: Session): Promise<PublicSession> {\n let orgs: SessionOrganization[] = []\n try {\n orgs = await organizations(session)\n } catch {\n // The person is signed in all the same; their organizations come back on the next read.\n }\n return { user: session.user, tenantId: session.tenantId, roles: session.roles, organizations: orgs, expiresAt: session.expiresAt }\n }\n\n // ── Routes ───────────────────────────────────────────────────────────────\n\n const urls = {\n signIn: (returnTo?: string) => `${basePath}/login${returnTo ? `?return_to=${encodeURIComponent(returnTo)}` : ''}`,\n signOut: () => `${basePath}/logout`,\n account: (returnTo?: string) => `${basePath}/account${returnTo ? `?return_to=${encodeURIComponent(returnTo)}` : ''}`,\n session: `${basePath}/session`,\n }\n\n async function login(request: Request, url: URL): Promise<Response> {\n const flow: Flow = { state: random(), verifier: random(48), returnTo: localPath(url.searchParams.get('return_to'), afterSignIn) }\n const challenge = b64url(new Uint8Array(await crypto.subtle.digest('SHA-256', new TextEncoder().encode(flow.verifier))))\n const q = new URLSearchParams({\n client_id: clientId,\n redirect_uri: `${originOf(request)}${basePath}/callback`,\n response_type: 'code',\n state: flow.state,\n code_challenge: challenge,\n code_challenge_method: 'S256',\n })\n // What the application may ask of the sign-in page: to ask again, and a language.\n const prompt = url.searchParams.get('prompt')\n if (prompt === 'login' || prompt === 'none') q.set('prompt', prompt)\n const locale = url.searchParams.get('locale') ?? url.searchParams.get('ui_locales')\n if (locale && /^[a-zA-Z-]{2,10}$/.test(locale)) q.set('ui_locales', locale)\n // An application whose own page cannot use the person's passkey sends\n // them to Cauthy's for that step alone: a page that asks for the passkey\n // and nothing else, and comes straight back.\n let passkey = ''\n if (url.searchParams.get('method') === 'passkey') {\n q.set('method', 'passkey')\n passkey = '#passkey' // what a Cauthy from before that page reads\n }\n return redirect(`${issuer}/v1/oauth/authorize?${q}${passkey}`, [\n writeCookie(flowCookie, await seal(flow, await key), attrs(request, FLOW_SECONDS)),\n ])\n }\n\n function failed(request: Request, reason: string): Response {\n const h = new Headers({ 'content-type': 'text/plain; charset=utf-8', 'cache-control': 'no-store' })\n h.append('set-cookie', writeCookie(flowCookie, '', attrs(request, 0)))\n h.append('set-cookie', writeCookie(againCookie, '', attrs(request, 0)))\n return new Response(`Sign-in could not be completed (${reason}). Go back and try again.`, { status: 400, headers: h })\n }\n\n async function callback(request: Request, url: URL): Promise<Response> {\n const had = readCookies(request.headers.get('cookie'))\n const sealed = had.get(flowCookie)\n const flow = sealed ? await unseal<Flow>(sealed, await key) : null\n // The answer must be to a question THIS browser asked: without that, a\n // stranger's link could sign a person in to the stranger's account.\n if (flow === null || url.searchParams.get('state') !== flow.state) {\n // Not this browser's question — or its question was asked so long ago\n // that it is forgotten: the page sat open, or the answer is to an older\n // tab's. Nobody is signed in by it; the sign-in starts again, once. The\n // person is still signed in at Cauthy, so they are not asked twice.\n if (had.get(againCookie) === undefined) {\n const back = flow?.returnTo ?? afterSignIn\n return redirect(`${basePath}/login?return_to=${encodeURIComponent(back)}`, [writeCookie(againCookie, '1', attrs(request, AGAIN_SECONDS))])\n }\n return failed(request, 'state_mismatch')\n }\n const error = url.searchParams.get('error')\n if (error !== null) {\n // prompt=none and nobody signed in: not an error, just \"nobody\".\n if (error === 'login_required') return redirect(flow.returnTo, [writeCookie(flowCookie, '', attrs(request, 0))])\n // The person went back from Cauthy's page: to the sign-in they came from.\n if (error === 'access_denied') {\n const back = pages.signIn ?? flow.returnTo\n return redirect(`${back}${back.includes('?') ? '&' : '?'}auth_error=cancelled`, [writeCookie(flowCookie, '', attrs(request, 0))])\n }\n return failed(request, error.slice(0, 60))\n }\n const code = url.searchParams.get('code')\n if (!code) return failed(request, 'no_code')\n const res = await token({\n grant_type: 'authorization_code',\n code,\n redirect_uri: `${originOf(request)}${basePath}/callback`,\n code_verifier: flow.verifier,\n })\n const s = res.ok ? await stored(res.body) : null\n if (s === null) return failed(request, 'exchange_failed')\n return redirect(flow.returnTo, [...(await write(request, s, had)), writeCookie(flowCookie, '', attrs(request, 0)), writeCookie(againCookie, '', attrs(request, 0))])\n }\n\n async function logout(request: Request): Promise<Response> {\n const { had, value } = await read(request)\n if (value !== null) {\n // Best effort: the session is over here whether or not Cauthy heard.\n const body = new URLSearchParams({ client_id: clientId, token: value.rt })\n if (clientSecret) body.set('client_secret', clientSecret)\n await doFetch(`${issuer}/v1/oauth/revoke`, {\n method: 'POST',\n headers: { 'content-type': 'application/x-www-form-urlencoded' },\n body,\n }).catch(() => undefined)\n orgCache.delete(value.at)\n }\n // Then through Cauthy, which ends its own session in this browser too:\n // otherwise the next \"sign in\" would walk straight back in.\n const q = new URLSearchParams({ client_id: clientId, post_logout_redirect_uri: `${originOf(request)}${afterSignOut}` })\n return redirect(`${issuer}/v1/oauth/logout?${q}`, clearParts(cookieName, attrs(request, 0), had))\n }\n\n // ── The application's own screens ────────────────────────────────────────\n //\n // The application draws its sign-in, with its own components; these routes\n // do the work behind it. The browser talks to the application's server and\n // to nobody else: the password goes from the form to here and from here to\n // Cauthy, the tokens Cauthy answers with go into the same encrypted cookie\n // as ever, and nothing the browser could keep is sent back to it.\n\n /** How long a sign-in waits for its second step, or for a provider to answer. */\n const STEP_SECONDS = 600\n /** How long a passkey ceremony waits for the person: Cauthy's own limit. */\n const PASSKEY_SECONDS = 300\n\n /** How an account takes its second step, as Cauthy says it. */\n const factorsOf = (d: any) => ({\n totp: d?.totp === true,\n phone: d?.phone ? { number: String(d.phone.number ?? ''), channel: String(d.phone.channel ?? 'sms') } : null,\n phoneChannels: Array.isArray(d?.phone_channels) ? d.phone_channels.map(String) : [],\n })\n\n /** What the browser answered a passkey ceremony with, as JSON. */\n const isCredential = (v: unknown): v is Record<string, unknown> =>\n typeof v === 'object' && v !== null && !Array.isArray(v) && typeof (v as { id?: unknown }).id === 'string' && typeof (v as { response?: unknown }).response === 'object'\n\n const passkeyOf = (d: any) => ({\n id: String(d?.id ?? ''), name: String(d?.nickname ?? ''),\n kind: ['security_key', 'synced', 'device'].includes(d?.kind) ? d.kind : 'unknown', createdAt: String(d?.created_at ?? ''), lastUsedAt: d?.last_used_at ? String(d.last_used_at) : null,\n })\n\n const UUID = /^[0-9a-f-]{36}$/i\n\n /** An organization the person belongs to, with what they may do with its people. */\n const seatOf = (d: any) => ({\n id: String(d?.id ?? ''), system: String(d?.system ?? ''), name: String(d?.name ?? ''), kind: String(d?.kind ?? ''), role: String(d?.role ?? ''),\n can: { readMembers: d?.can?.read_members === true, manageMembers: d?.can?.manage_members === true },\n })\n /** A person of an organization, as a member who may see them reads it. */\n const orgMemberOf = (d: any) => ({\n userId: String(d?.user_id ?? ''), email: String(d?.email ?? ''), name: String(d?.name ?? ''), role: String(d?.role ?? ''),\n status: String(d?.status ?? ''), invited: d?.invited === true, manager: d?.manager === true, you: d?.you === true, since: String(d?.since ?? ''),\n })\n /** A role of the organization's system that a member may give. */\n const orgRoleOf = (d: any) => ({\n role: String(d?.role ?? ''), name: String(d?.name ?? ''), description: String(d?.description ?? ''), manager: d?.manager === true,\n })\n\n /** An AI agent the person connected, as Cauthy says it. */\n const agentOf = (d: any) => ({\n id: String(d?.id ?? ''),\n name: String(d?.agent?.name ?? ''),\n redirectHost: String(d?.agent?.redirect_host ?? ''),\n resource: { name: String(d?.resource?.name ?? ''), uri: String(d?.resource?.uri ?? '') },\n scopes: Array.isArray(d?.scopes) ? d.scopes.map((s: any) => ({ name: String(s?.name ?? ''), description: String(s?.description ?? '') })) : [],\n connectedAt: String(d?.created_at ?? ''),\n lastUsedAt: String(d?.last_used_at ?? ''),\n })\n\n interface Step {\n /** `mfa`: Cauthy asked for a code. `social`: a provider is answering. `link`: a provider is answering to be linked to the signed-in account. `passkey`/`enrol`: a passkey ceremony is under way on the page. `sso`: the person's company is answering; `token` is the PKCE verifier. */\n kind: 'mfa' | 'social' | 'code' | 'link' | 'passkey' | 'enrol' | 'sso' | 'upgrade'\n token: string\n provider?: string\n returnTo: string\n }\n\n const problem = (status: number, code: string, message: string, field?: string, headers?: Headers) =>\n json({ error: { code, message, ...(field ? { field } : {}) } }, status, headers)\n\n const invalid = (p: FieldProblem) => problem(400, p.code, p.message, p.field)\n\n /** A request this application's own page made: never another site's form. */\n function ownRequest(request: Request): boolean {\n const origin = request.headers.get('origin')\n if (origin !== null) return origin === originOf(request) || origin === new URL(request.url).origin\n // No Origin: a browser sends one on every cross-site POST, so this is a\n // same-origin form of an old browser, or not a browser at all.\n return (request.headers.get('sec-fetch-site') ?? 'same-origin') === 'same-origin'\n }\n\n async function body(request: Request): Promise<Record<string, unknown> | null> {\n if (!(request.headers.get('content-type') ?? '').includes('application/json')) return null\n try {\n const b = (await request.json()) as unknown\n return typeof b === 'object' && b !== null && !Array.isArray(b) ? (b as Record<string, unknown>) : null\n } catch {\n return null\n }\n }\n\n // Every person signing in here reaches Cauthy from this server's address.\n // So the application says whose request it is passing on, and proves it is\n // a system of the workspace with its own token: Cauthy believes the address\n // from nobody else. An application that is no system passes nothing on.\n const clientIp = given.clientIp ?? ((request: Request) => request.headers.get('x-forwarded-for')?.split(',').pop()?.trim() || undefined)\n let noProofUntil = 0\n async function passedOn(request: Request): Promise<Record<string, string>> {\n const ip = clientIp(request)\n if (!ip || Date.now() < noProofUntil) return {}\n try {\n return { 'x-cauthy-client-ip': ip, 'x-cauthy-system-token': await ownSystem.token() }\n } catch {\n // Not a system, or Cauthy is not answering: ask again in a while.\n noProofUntil = Date.now() + 5 * 60_000\n return {}\n }\n }\n\n /** Asks Cauthy's own API, as this workspace's application. */\n async function ask(request: Request, method: string, path: string, payload?: unknown, page?: string, bearer?: string): Promise<{ status: number; data: any; error?: { code: string; message: string } }> {\n try {\n const res = await doFetch(`${issuer}${path}`, {\n method,\n headers: {\n 'x-tenant-key': tenant,\n accept: 'application/json',\n // A link Cauthy mails opens the application's page for it when it\n // has one; otherwise Cauthy's own. Either way in the reader's language.\n ...(page ? { 'x-cauthy-link-to': `${originOf(request)}${page}` } : { 'x-cauthy-links': 'hosted' }),\n // Whose request it is: what Cauthy mails goes in this application's\n // name, under its logo.\n ...(clientId ? { 'x-cauthy-client-id': clientId } : {}),\n ...(await passedOn(request)),\n ...(bearer ? { authorization: `Bearer ${bearer}` } : {}),\n // The answer to the workspace's Turnstile challenge, from the\n // person's browser: Cauthy checks it at the doors that ask for it.\n ...(request.headers.get('x-cauthy-captcha') ? { 'x-captcha-token': request.headers.get('x-cauthy-captcha') as string } : {}),\n ...(request.headers.get('accept-language') ? { 'accept-language': request.headers.get('accept-language') as string } : {}),\n // The language the application says its person reads, over the browser's.\n ...(request.headers.get('x-cauthy-locale') ? { 'x-cauthy-locale': request.headers.get('x-cauthy-locale') as string } : {}),\n ...(request.headers.get('user-agent') ? { 'user-agent': request.headers.get('user-agent') as string } : {}),\n ...(payload === undefined ? {} : { 'content-type': 'application/json' }),\n },\n body: payload === undefined ? undefined : JSON.stringify(payload),\n })\n const b = res.status === 204 || res.status === 202 ? null : ((await res.json().catch(() => null)) as any)\n if (res.ok) return { status: res.status, data: b?.data ?? b }\n const first = b?.errors?.[0]\n return { status: res.status, data: null, error: { code: String(first?.code ?? 'error'), message: String(first?.message ?? 'The request could not be completed.') } }\n } catch {\n return { status: 503, data: null, error: { code: 'unavailable', message: 'Sign-in is unavailable right now. Try again in a moment.' } }\n }\n }\n\n const accountOf = (d: any) => ({\n id: String(d?.id ?? ''), email: String(d?.email ?? ''), name: String(d?.name ?? ''),\n emailVerified: d?.email_verified === true, hasPassword: d?.has_password === true, mfaEnabled: d?.mfa_enabled === true,\n })\n\n /**\n * Who is signed in, for a route about their own account: their token, and\n * the cookie to send back when the session had to be renewed. Nobody signed\n * in gets the 401 to answer with.\n */\n async function signedInAs(request: Request): Promise<{ token: string; kept: Stored | null; headers: Headers } | { response: Response }> {\n const r = await resolve(request)\n const headers = new Headers()\n for (const c of r.cookies) headers.append('set-cookie', c)\n if (r.session === null) return { response: problem(401, 'unauthenticated', 'Sign in first.', undefined, headers) }\n // `kept` is the session as the request's cookie holds it, or null when it\n // was renewed just now: then the cookies above carry the new one.\n return { token: r.session.accessToken, kept: r.cookies.length === 0 ? (await read(request)).value : null, headers }\n }\n\n /** Cauthy answered with tokens: the person is signed in here. */\n async function signedIn(request: Request, tokens: any, extra: string[] = [], more: Record<string, unknown> = {}): Promise<Response> {\n const s = await stored(tokens)\n if (s === null) return problem(502, 'unavailable', 'Sign-in is unavailable right now. Try again in a moment.')\n const h = new Headers()\n for (const c of [...(await write(request, s, readCookies(request.headers.get('cookie')))), ...extra]) h.append('set-cookie', c)\n return json({ status: 'signed_in', session: await toPublic(toSession(s)), ...more }, 200, h)\n }\n\n let lookCache: { until: number; look: Record<string, unknown> } | null = null\n\n async function ownRoute(request: Request, url: URL, route: string): Promise<Response | null> {\n const post = request.method === 'POST'\n const own = ['/sign-in/email', '/sign-in/mfa', '/sign-up/email', '/forgot-password', '/reset-password', '/verify-email', '/sign-in/magic-link', '/sign-in/magic-link/verify', '/sign-in/email-code', '/me', '/me/password', '/me/mfa/setup', '/me/mfa/verify', '/me/mfa/disable', '/me/mfa/recovery-codes', '/me/mfa/factors', '/me/mfa/phone', '/me/mfa/phone/verify', '/me/mfa/phone/remove', '/sign-in/mfa/methods', '/sign-in/mfa/send', '/sign-in/mfa/push', '/sign-in/mfa/push/events', '/sign-in/mfa/push/finish', '/me/sessions', '/me/sessions/end', '/me/email', '/me/identities', '/me/identities/unlink', '/sign-out', '/methods', '/look',\n '/sign-in/passkey/begin', '/sign-in/passkey/finish', '/sign-in/google-one-tap/begin', '/sign-in/google-one-tap', '/me/passkeys', '/me/passkeys/add/begin', '/me/passkeys/add/finish', '/me/passkeys/remove', '/me/agents', '/me/agents/disconnect',\n '/sign-in/anonymous', '/me/upgrade',\n '/me/organizations', '/me/organizations/members', '/me/organizations/roles', '/me/organizations/members/add', '/me/organizations/members/role', '/me/organizations/members/remove', '/me/organizations/members/invite'].includes(route) ||\n route.startsWith('/sign-in/social/') || route.startsWith('/callback/') || route.startsWith('/me/identities/link/') || route.startsWith('/me/upgrade/social/') ||\n route === '/sign-in/sso' || route === '/sign-in/sso/discover' || route === '/sso/callback'\n if (!own) return null\n if (tenant === '') {\n return problem(500, 'not_configured', 'cauthy-auth: tenant (CAUTHY_TENANT) is required for the application\\'s own sign-in screens')\n }\n\n // How the forms look, as a person set it in Cauthy's dashboard. Kept a\n // minute: every form of every page reads it.\n if (route === '/look' && !post) {\n if (lookCache === null || lookCache.until < Date.now()) {\n const res = await ask(request, 'GET', `/v1/auth/look/${encodeURIComponent(clientId)}`)\n lookCache = { until: Date.now() + LOOK_TTL_MS, look: res.error ? {} : (res.data ?? {}) }\n }\n return json(lookCache.look)\n }\n\n // What the screen may offer: which providers, whether people may register.\n if (route === '/methods' && !post) {\n const [providers, settings, place, sso] = await Promise.all([\n ask(request, 'GET', '/v1/auth/social/providers'),\n ask(request, 'GET', '/v1/auth/settings'),\n ask(request, 'GET', `/v1/auth/webauthn/place?origin=${encodeURIComponent(originOf(request))}`),\n ask(request, 'GET', '/v1/auth/sso/connections'),\n ])\n const list = Array.isArray(providers.data) ? providers.data : []\n // Where the person uses a passkey: on this page, or on Cauthy's for that\n // step alone. A Cauthy that cannot say yet has them on its page.\n const here = place.data?.here === true\n return json({\n providers: list.map((p: any) => ({ id: String(p.provider ?? p.id ?? ''), name: String(p.label ?? p.name ?? p.provider ?? '') })).filter((p: { id: string }) => p.id !== ''),\n signUp: settings.data?.allow_signup !== false,\n // A sign-in link needs a page of the application to open.\n magicLink: settings.data?.allow_magic_link === true && pages.signIn !== undefined,\n passkey: place.error ? true : here || place.data?.on_cauthy === true,\n passkeyHere: here,\n passkeyOnCauthy: place.error ? true : place.data?.on_cauthy === true,\n // A company's sign-in, found by the person's work address.\n sso: Array.isArray(sso.data) && sso.data.some((c: any) => c?.discoverable === true),\n ...(settings.data?.captcha_enabled === true && settings.data?.captcha_site_key ? { captchaSiteKey: String(settings.data.captcha_site_key) } : {}),\n })\n }\n\n // The person's company: to its IdP and back. Cauthy ends the flow on\n // this site's page with a code, which only the browser holding the\n // sealed PKCE verifier can trade for the session.\n if (route === '/sign-in/sso' && !post) {\n const returnTo = localPath(url.searchParams.get('return_to'), afterSignIn)\n const failed = (code: string) => redirect(`${returnTo}${returnTo.includes('?') ? '&' : '?'}auth_error=${encodeURIComponent(code)}`)\n const email = (url.searchParams.get('email') ?? '').trim()\n const connection = (url.searchParams.get('connection') ?? '').trim()\n if (email === '' && connection === '') return failed('sso_not_found')\n const verifier = random(48)\n const challenge = b64url(new Uint8Array(await crypto.subtle.digest('SHA-256', new TextEncoder().encode(verifier))))\n const callback = `${basePath}/sso/callback`\n const started = await ask(request, 'POST', '/v1/auth/sso/start', {\n ...(connection ? { connection } : { email }),\n redirect_uri: `${originOf(request)}${callback}`, code_challenge: challenge,\n }, callback)\n if (started.error || typeof started.data?.redirect_url !== 'string') return failed(started.error?.code ?? 'sso_unavailable')\n const step: Step = { kind: 'sso', token: verifier, returnTo }\n return redirect(started.data.redirect_url, [writeCookie(stepCookie, await seal(step, await key), attrs(request, STEP_SECONDS))])\n }\n if (route === '/sso/callback' && !post) {\n const sealed = readCookies(request.headers.get('cookie')).get(stepCookie)\n const step = sealed ? await unseal<Step>(sealed, await key) : null\n const clear = writeCookie(stepCookie, '', attrs(request, 0))\n const back = step?.returnTo ?? afterSignIn\n const failedTo = (code: string) => redirect(`${back}${back.includes('?') ? '&' : '?'}auth_error=${encodeURIComponent(code)}`, [clear])\n if (step === null || step.kind !== 'sso') return failedTo('state_mismatch')\n const refused = url.searchParams.get('error')\n if (refused) return failedTo(refused)\n const code = url.searchParams.get('code')\n if (!code) return failedTo('sso_failed')\n const done = await ask(request, 'POST', '/v1/auth/sso/token', { code, redirect_uri: `${originOf(request)}${basePath}/sso/callback`, code_verifier: step.token })\n if (done.error) return failedTo(done.error.code)\n const s = await stored(done.data)\n if (s === null) return failedTo('unavailable')\n return redirect(back, [...(await write(request, s, readCookies(request.headers.get('cookie')))), clear])\n }\n\n // A provider: to it and back. The state is this browser's, kept sealed.\n if (route.startsWith('/sign-in/social/') && !post) {\n const provider = providerIn(route.slice('/sign-in/social/'.length))\n if (!PROVIDER_ID.test(provider)) return new Response('Not found', { status: 404 })\n const returnTo = localPath(url.searchParams.get('return_to'), afterSignIn)\n const callback = `${basePath}/callback/${provider}`\n // The callback is named as this client's page, so a provider that\n // answers through Cauthy's relay (Apple) may return the browser to it.\n const started = await ask(request, 'GET', `/v1/auth/social/${provider}?redirect_uri=${encodeURIComponent(`${originOf(request)}${callback}`)}`, undefined, callback)\n if (started.error || typeof started.data?.redirect_url !== 'string') {\n return redirect(`${returnTo}${returnTo.includes('?') ? '&' : '?'}auth_error=${encodeURIComponent(started.error?.code ?? 'provider_unavailable')}`)\n }\n const step: Step = { kind: 'social', token: String(started.data.state ?? ''), provider, returnTo }\n return redirect(started.data.redirect_url, [writeCookie(stepCookie, await seal(step, await key), attrs(request, STEP_SECONDS))])\n }\n if (route.startsWith('/callback/') && !post) {\n const provider = providerIn(route.slice('/callback/'.length))\n const sealed = readCookies(request.headers.get('cookie')).get(stepCookie)\n const step = sealed ? await unseal<Step>(sealed, await key) : null\n const clear = writeCookie(stepCookie, '', attrs(request, 0))\n const back = step?.returnTo ?? afterSignIn\n const failedTo = (code: string) => redirect(`${back}${back.includes('?') ? '&' : '?'}auth_error=${encodeURIComponent(code)}`, [clear])\n // The answer must be to the question this browser asked of this provider.\n if (step === null || (step.kind !== 'social' && step.kind !== 'link' && step.kind !== 'upgrade') || step.provider !== provider || url.searchParams.get('state') !== step.token) return failedTo('state_mismatch')\n const code = url.searchParams.get('code')\n if (!code) return failedTo(url.searchParams.get('error') === 'access_denied' ? 'cancelled' : 'provider_refused')\n const q = new URLSearchParams({ code, state: step.token, redirect_uri: `${originOf(request)}${basePath}/callback/${provider}` })\n if (step.kind === 'upgrade') {\n // The guest is now the account of that address: its session from here on.\n const mine = await signedInAs(request)\n if ('response' in mine) return failedTo('unauthenticated')\n const done = await ask(request, 'GET', `/v1/auth/anonymous/upgrade/${provider}/callback?${q}`, undefined, undefined, mine.token)\n if (done.error) return failedTo(done.error.code)\n const s = await stored(done.data)\n if (s === null) return failedTo('unavailable')\n return redirect(back, [...(await write(request, s, readCookies(request.headers.get('cookie')))), clear])\n }\n if (step.kind === 'link') {\n // Linked to the account signed in here, and back to where it was asked.\n const mine = await signedInAs(request)\n if ('response' in mine) return failedTo('unauthenticated')\n const linked = await ask(request, 'GET', `/v1/auth/identities/${provider}/link/callback?${q}`, undefined, undefined, mine.token)\n if (linked.error) return failedTo(linked.error.code)\n const h = new Headers(mine.headers)\n h.append('set-cookie', clear)\n return redirect(`${back}${back.includes('?') ? '&' : '?'}linked=${encodeURIComponent(provider)}`, [...h.getSetCookie()])\n }\n const done = await ask(request, 'GET', `/v1/auth/social/${provider}/callback?${q}`)\n if (done.error) return failedTo(done.error.code)\n const s = await stored(done.data)\n if (s === null) return failedTo('unavailable')\n return redirect(back, [...(await write(request, s, readCookies(request.headers.get('cookie')))), clear])\n }\n\n // A guest becoming the account of a provider's address: to it and back.\n if (route.startsWith('/me/upgrade/social/') && !post) {\n const provider = providerIn(route.slice('/me/upgrade/social/'.length))\n if (!PROVIDER_ID.test(provider)) return new Response('Not found', { status: 404 })\n const returnTo = localPath(url.searchParams.get('return_to'), afterSignIn)\n const failed = (code: string) => redirect(`${returnTo}${returnTo.includes('?') ? '&' : '?'}auth_error=${encodeURIComponent(code)}`)\n const mine = await signedInAs(request)\n if ('response' in mine) return failed('unauthenticated')\n const callback = `${basePath}/callback/${provider}`\n const started = await ask(request, 'GET', `/v1/auth/anonymous/upgrade/${provider}?redirect_uri=${encodeURIComponent(`${originOf(request)}${callback}`)}`, undefined, callback, mine.token)\n if (started.error || typeof started.data?.redirect_url !== 'string') return failed(started.error?.code ?? 'provider_unavailable')\n const step: Step = { kind: 'upgrade', token: String(started.data.state ?? ''), provider, returnTo }\n return redirect(started.data.redirect_url, [...mine.headers.getSetCookie(), writeCookie(stepCookie, await seal(step, await key), attrs(request, STEP_SECONDS))])\n }\n\n // A provider linked to the signed-in account: to it and back, like a sign-in.\n if (route.startsWith('/me/identities/link/') && !post) {\n const provider = providerIn(route.slice('/me/identities/link/'.length))\n if (!PROVIDER_ID.test(provider)) return new Response('Not found', { status: 404 })\n const returnTo = localPath(url.searchParams.get('return_to'), afterSignIn)\n const failed = (code: string) => redirect(`${returnTo}${returnTo.includes('?') ? '&' : '?'}auth_error=${encodeURIComponent(code)}`)\n const mine = await signedInAs(request)\n if ('response' in mine) return failed('unauthenticated')\n const callback = `${basePath}/callback/${provider}`\n const started = await ask(request, 'GET', `/v1/auth/identities/${provider}/link?redirect_uri=${encodeURIComponent(`${originOf(request)}${callback}`)}`, undefined, callback, mine.token)\n if (started.error || typeof started.data?.redirect_url !== 'string') return failed(started.error?.code ?? 'provider_unavailable')\n const step: Step = { kind: 'link', token: String(started.data.state ?? ''), provider, returnTo }\n return redirect(started.data.redirect_url, [...mine.headers.getSetCookie(), writeCookie(stepCookie, await seal(step, await key), attrs(request, STEP_SECONDS))])\n }\n\n // The person's own account: read here, changed below.\n if (route === '/me/identities' && !post) {\n const mine = await signedInAs(request)\n if ('response' in mine) return mine.response\n const res = await ask(request, 'GET', '/v1/auth/identities', undefined, undefined, mine.token)\n if (res.error) return problem(res.status, res.error.code, res.error.message, undefined, mine.headers)\n const list = Array.isArray(res.data) ? res.data : []\n return json({ identities: list.map((x: any) => ({ provider: String(x.provider ?? ''), email: String(x.email ?? ''), name: String(x.name ?? ''), linkedAt: String(x.linked_at ?? '') })) }, 200, mine.headers)\n }\n if (route === '/me/passkeys' && !post) {\n const mine = await signedInAs(request)\n if ('response' in mine) return mine.response\n const res = await ask(request, 'GET', '/v1/auth/webauthn/credentials', undefined, undefined, mine.token)\n if (res.error) return problem(res.status, res.error.code, res.error.message, undefined, mine.headers)\n const list = Array.isArray(res.data) ? res.data : []\n return json({ passkeys: list.map(passkeyOf) }, 200, mine.headers)\n }\n // The AI agents the person connected.\n if (route === '/me/agents' && !post) {\n const mine = await signedInAs(request)\n if ('response' in mine) return mine.response\n const res = await ask(request, 'GET', '/v1/auth/me/agents', undefined, undefined, mine.token)\n if (res.error) return problem(res.status, res.error.code, res.error.message, undefined, mine.headers)\n const list = Array.isArray(res.data) ? res.data : []\n return json({ agents: list.map(agentOf) }, 200, mine.headers)\n }\n // The person's organizations, and the people of one: as far as their\n // role in the system's catalog lets them see (cauthy:members read).\n if ((route === '/me/organizations' || route === '/me/organizations/members' || route === '/me/organizations/roles') && !post) {\n const mine = await signedInAs(request)\n if ('response' in mine) return mine.response\n let path = '/v1/auth/me/organizations'\n if (route !== '/me/organizations') {\n const id = url.searchParams.get('id') ?? ''\n if (!UUID.test(id)) return problem(400, 'invalid_organization', 'Say which organization.', undefined, mine.headers)\n path += `/${id}/${route.endsWith('/roles') ? 'roles' : 'members'}`\n } else if (url.searchParams.get('system')) {\n path += `?system=${encodeURIComponent(url.searchParams.get('system')!)}`\n }\n const res = await ask(request, 'GET', path, undefined, undefined, mine.token)\n if (res.error) return problem(res.status, res.error.code, res.error.message, undefined, mine.headers)\n const list = Array.isArray(res.data) ? res.data : []\n if (route === '/me/organizations') return json({ organizations: list.map(seatOf) }, 200, mine.headers)\n if (route === '/me/organizations/roles') return json({ roles: list.map(orgRoleOf) }, 200, mine.headers)\n return json({ members: list.map(orgMemberOf) }, 200, mine.headers)\n }\n // How the account takes its second step, and what the workspace offers.\n if (route === '/me/mfa/factors' && !post) {\n const mine = await signedInAs(request)\n if ('response' in mine) return mine.response\n const res = await ask(request, 'GET', '/v1/auth/mfa/factors', undefined, undefined, mine.token)\n if (res.error) return problem(res.status, res.error.code, res.error.message, undefined, mine.headers)\n return json(factorsOf(res.data), 200, mine.headers)\n }\n if ((route === '/me' || route === '/me/sessions') && !post) {\n const mine = await signedInAs(request)\n if ('response' in mine) return mine.response\n const res = await ask(request, 'GET', route === '/me' ? '/v1/auth/me' : '/v1/auth/me/sessions', undefined, undefined, mine.token)\n if (res.error) return problem(res.status, res.error.code, res.error.message, undefined, mine.headers)\n if (route === '/me/sessions') {\n const list = Array.isArray(res.data) ? res.data : []\n return json({ sessions: list.map((x: any) => ({ device: String(x.device ?? ''), ip: String(x.ip ?? ''), createdAt: String(x.created_at ?? ''), expiresAt: String(x.expires_at ?? '') })) }, 200, mine.headers)\n }\n return json({ account: accountOf(res.data) }, 200, mine.headers)\n }\n\n // The phone's answer to a push, as it comes: Cauthy's server-sent events,\n // passed through to the page that waits on them.\n if (route === '/sign-in/mfa/push/events' && !post) {\n const sealed = readCookies(request.headers.get('cookie')).get(stepCookie)\n const step = sealed ? await unseal<Step>(sealed, await key) : null\n if (step === null || step.kind !== 'mfa') return problem(400, 'step_expired', 'Sign in again: the code was asked for too long ago.')\n let upstream: Response\n try {\n upstream = await doFetch(`${issuer}/v1/auth/mfa/push/events`, {\n headers: { 'x-tenant-key': tenant, 'x-mfa-token': step.token, accept: 'text/event-stream' },\n signal: request.signal,\n })\n } catch {\n return problem(503, 'unavailable', 'Cauthy could not be reached.')\n }\n if (!upstream.ok || !upstream.body) {\n const b = (await upstream.json().catch(() => null)) as any\n return problem(upstream.status, String(b?.errors?.[0]?.code ?? 'error'), String(b?.errors?.[0]?.message ?? 'The request could not be completed.'))\n }\n return new Response(upstream.body, {\n status: 200,\n headers: { 'content-type': 'text/event-stream', 'cache-control': 'no-cache, no-store', 'x-accel-buffering': 'no' },\n })\n }\n\n if (!post) return new Response('Method not allowed', { status: 405, headers: { allow: 'POST' } })\n if (!ownRequest(request)) return problem(403, 'cross_site', 'This request did not come from this application.')\n\n if (route === '/sign-out') {\n const { had, value } = await read(request)\n if (value !== null) {\n const form = new URLSearchParams({ client_id: clientId, token: value.rt })\n if (clientSecret) form.set('client_secret', clientSecret)\n await doFetch(`${issuer}/v1/oauth/revoke`, { method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, body: form }).catch(() => undefined)\n orgCache.delete(value.at)\n }\n const h = new Headers()\n for (const c of clearParts(cookieName, attrs(request, 0), had)) h.append('set-cookie', c)\n return json({ status: 'signed_out' }, 200, h)\n }\n\n const b = await body(request)\n if (b === null) return problem(400, 'bad_request', 'Send the form as JSON.')\n\n // Which company's sign-in an address uses, if any: said of its domain,\n // never of whether the address has an account.\n if (route === '/sign-in/sso/discover') {\n const bad = checkEmail(b.email)\n if (bad) return invalid(bad)\n const res = await ask(request, 'POST', '/v1/auth/sso/discover', { email: String(b.email).trim() })\n if (res.error) return problem(res.status, res.error.code, res.error.message)\n const c = res.data?.connection\n return json(c ? { status: 'found', connection: { id: String(c.slug ?? ''), name: String(c.display_name ?? ''), enforced: c.enforced === true } } : { status: 'none' })\n }\n\n // A guest session, before the visitor signs up (the workspace's allow_anonymous).\n if (route === '/sign-in/anonymous') {\n if (!post) return new Response('Method not allowed', { status: 405, headers: { allow: 'POST' } })\n const res = await ask(request, 'POST', '/v1/auth/anonymous', {})\n if (res.error) return problem(res.status, res.error.code, res.error.message)\n return signedIn(request, res.data)\n }\n\n if (route === '/sign-in/email') {\n const bad = firstProblem(checkEmail(b.email), checkPassword(b.password))\n if (bad) return invalid(bad)\n const res = await ask(request, 'POST', '/v1/auth/login', { email: String(b.email).trim(), password: b.password })\n if (res.error) return problem(res.status, res.error.code, res.error.message)\n if (res.data?.mfa_required === true) {\n // The code is asked for next; what proves the password was right\n // stays here, sealed, and never reaches the page.\n const step: Step = { kind: 'mfa', token: String(res.data.mfa_token ?? ''), returnTo: afterSignIn }\n return json({ status: 'mfa_required' }, 200, new Headers({ 'set-cookie': writeCookie(stepCookie, await seal(step, await key), attrs(request, STEP_SECONDS)) }))\n }\n return signedIn(request, res.data)\n }\n\n if (route === '/sign-in/mfa') {\n const bad = checkCode(b.code)\n if (bad) return invalid(bad)\n const sealed = readCookies(request.headers.get('cookie')).get(stepCookie)\n const step = sealed ? await unseal<Step>(sealed, await key) : null\n if (step === null || step.kind !== 'mfa') return problem(400, 'step_expired', 'Sign in again: the code was asked for too long ago.')\n const res = await ask(request, 'POST', '/v1/auth/mfa/challenge', { mfa_token: step.token, code: String(b.code).trim() })\n if (res.error) return problem(res.status, res.error.code, res.error.message, 'code')\n return signedIn(request, res.data, [writeCookie(stepCookie, '', attrs(request, 0))])\n }\n\n // The second step by phone, while signing in: which ways the account has,\n // and a code sent to its phone. The challenge's token stays sealed here.\n // The second step approved on the phone: a push, then the sign-in once the\n // phone approved it (the answer itself streams from /sign-in/mfa/push/events).\n if (route === '/sign-in/mfa/push' || route === '/sign-in/mfa/push/finish') {\n const sealed = readCookies(request.headers.get('cookie')).get(stepCookie)\n const step = sealed ? await unseal<Step>(sealed, await key) : null\n if (step === null || step.kind !== 'mfa') return problem(400, 'step_expired', 'Sign in again: the code was asked for too long ago.')\n if (route === '/sign-in/mfa/push') {\n const res = await ask(request, 'POST', '/v1/auth/mfa/push', { mfa_token: step.token })\n if (res.error) return problem(res.status, res.error.code, res.error.message)\n return json({ status: 'sent', number: Number(res.data?.number ?? 0) })\n }\n const res = await ask(request, 'POST', '/v1/auth/mfa/challenge', { mfa_token: step.token, push: true })\n if (res.error) return problem(res.status, res.error.code, res.error.message)\n return signedIn(request, res.data, [writeCookie(stepCookie, '', attrs(request, 0))])\n }\n\n if (route === '/sign-in/mfa/methods' || route === '/sign-in/mfa/send') {\n const sealed = readCookies(request.headers.get('cookie')).get(stepCookie)\n const step = sealed ? await unseal<Step>(sealed, await key) : null\n if (step === null || step.kind !== 'mfa') return problem(400, 'step_expired', 'Sign in again: the code was asked for too long ago.')\n if (route === '/sign-in/mfa/methods') {\n const res = await ask(request, 'POST', '/v1/auth/mfa/methods', { mfa_token: step.token })\n if (res.error) return problem(res.status, res.error.code, res.error.message)\n const p = res.data?.phone\n const push = res.data?.push\n return json({ status: 'ok', totp: res.data?.totp === true, phone: p ? { number: String(p.number ?? ''), channel: String(p.channel ?? 'sms') } : null,\n push: push ? { devices: Number(push.devices ?? 0) } : null })\n }\n const res = await ask(request, 'POST', '/v1/auth/mfa/send', { mfa_token: step.token })\n if (res.error) return problem(res.status, res.error.code, res.error.message)\n return json({ status: 'sent', sentTo: String(res.data?.sent_to ?? ''), channel: String(res.data?.channel ?? 'sms') })\n }\n\n if (route === '/sign-up/email') {\n const bad = firstProblem(checkName(b.name), checkEmail(b.email), checkNewPassword(b.password))\n if (bad) return invalid(bad)\n const email = String(b.email).trim()\n const made = await ask(request, 'POST', '/v1/auth/register', { email, password: b.password, display_name: typeof b.name === 'string' ? b.name.trim() : '' }, pages.verifyEmail)\n if (made.error) return problem(made.status, made.error.code, made.error.message)\n // An account that must confirm its address first cannot sign in yet.\n if (made.data?.verification_required === true) return json({ status: 'verification_required', email })\n const res = await ask(request, 'POST', '/v1/auth/login', { email, password: b.password })\n if (res.error || res.data?.mfa_required === true) return json({ status: 'verification_required', email })\n return signedIn(request, res.data)\n }\n\n if (route === '/forgot-password') {\n const bad = checkEmail(b.email)\n if (bad) return invalid(bad)\n // The same answer whether or not the address has an account.\n await ask(request, 'POST', '/v1/auth/password/reset', { email: String(b.email).trim() }, pages.resetPassword)\n return json({ status: 'sent' })\n }\n\n if (route.startsWith('/me')) {\n const mine = await signedInAs(request)\n if ('response' in mine) return mine.response\n const as = (path: string, payload?: unknown, method = 'POST') => ask(request, method, path, payload, undefined, mine.token)\n const refused = (res: { status: number; error?: { code: string; message: string } }, field?: string) =>\n problem(res.status, res.error!.code, res.error!.message, field, mine.headers)\n // Asked again for what weakens the account; an account with no password sends none.\n const password = typeof b.password === 'string' ? b.password : ''\n\n if (route === '/me') {\n const bad = checkName(b.name)\n if (bad) return invalid(bad)\n const res = await as('/v1/auth/me', { name: typeof b.name === 'string' ? b.name.trim() : '' }, 'PATCH')\n if (res.error) return refused(res, 'name')\n // The name is part of the session: the cookie says the new one at once.\n const h = mine.headers\n if (mine.kept !== null) {\n const again = await stored({ access_token: mine.kept.at, refresh_token: mine.kept.rt, expires_in: Math.max(1, mine.kept.exp - Math.floor(Date.now() / 1000)) })\n if (again !== null) for (const c of await write(request, again, readCookies(request.headers.get('cookie')))) h.append('set-cookie', c)\n }\n return json({ status: 'saved', account: accountOf(res.data) }, 200, h)\n }\n if (route === '/me/password') {\n const bad = checkNewPassword(b.newPassword)\n if (bad) return problem(400, bad.code, bad.message, 'newPassword')\n const res = await as('/v1/auth/me/password', { current_password: password, new_password: b.newPassword })\n if (res.error) return refused(res, res.error.code === 'wrong_password' ? 'password' : res.error.code === 'weak_password' ? 'newPassword' : undefined)\n // The change ended every session of the account. Cauthy answered with\n // a new one for this browser, which just proved the password.\n const next = await stored(res.data)\n const h = new Headers()\n const had = readCookies(request.headers.get('cookie'))\n for (const c of next !== null ? await write(request, next, had) : clearParts(cookieName, attrs(request, 0), had)) h.append('set-cookie', c)\n return json({ status: 'changed', signedIn: next !== null }, 200, h)\n }\n if (route === '/me/mfa/setup') {\n const res = await as('/v1/auth/mfa/setup', { password })\n if (res.error) return refused(res, res.error.code === 'step_up_required' ? 'password' : undefined)\n return json({ status: 'started', secret: String(res.data?.secret ?? ''), otpauthUri: String(res.data?.otpauth_uri ?? '') }, 200, mine.headers)\n }\n if (route === '/me/mfa/verify') {\n const bad = checkCode(b.code)\n if (bad) return invalid(bad)\n const res = await as('/v1/auth/mfa/verify', { code: String(b.code).trim() })\n if (res.error) return refused(res, 'code')\n return json({ status: 'enabled', recoveryCodes: Array.isArray(res.data?.recovery_codes) ? res.data.recovery_codes.map(String) : [] }, 200, mine.headers)\n }\n if (route === '/me/mfa/phone') {\n const res = await as('/v1/auth/mfa/phone', { phone: typeof b.phone === 'string' ? b.phone : '', channel: typeof b.channel === 'string' ? b.channel : 'sms', password })\n if (res.error) return refused(res, res.error.code === 'step_up_required' ? 'password' : res.error.code === 'validation_error' ? 'phone' : undefined)\n return json({ status: 'sent', sentTo: String(res.data?.sent_to ?? ''), channel: String(res.data?.channel ?? '') }, 200, mine.headers)\n }\n if (route === '/me/mfa/phone/verify') {\n const bad = checkCode(b.code)\n if (bad) return invalid(bad)\n const res = await as('/v1/auth/mfa/phone/verify', { code: String(b.code).trim() })\n if (res.error) return refused(res, 'code')\n return json({ status: 'enabled', recoveryCodes: Array.isArray(res.data?.recovery_codes) ? res.data.recovery_codes.map(String) : [] }, 200, mine.headers)\n }\n if (route === '/me/mfa/phone/remove') {\n const res = await as('/v1/auth/mfa/phone/remove', { password })\n if (res.error) return refused(res, res.error.code === 'step_up_required' ? 'password' : undefined)\n return json({ status: 'removed' }, 200, mine.headers)\n }\n if (route === '/me/mfa/disable') {\n const res = await as('/v1/auth/me/mfa/disable', { password })\n if (res.error) return refused(res, res.error.code === 'step_up_required' ? 'password' : undefined)\n return json({ status: 'disabled' }, 200, mine.headers)\n }\n if (route === '/me/mfa/recovery-codes') {\n const res = await as('/v1/auth/me/mfa/recovery-codes', { password })\n if (res.error) return refused(res, res.error.code === 'step_up_required' ? 'password' : undefined)\n return json({ status: 'renewed', recoveryCodes: Array.isArray(res.data?.recovery_codes) ? res.data.recovery_codes.map(String) : [] }, 200, mine.headers)\n }\n if (route === '/me/email') {\n const bad = checkEmail(b.email)\n if (bad) return invalid(bad)\n const email = String(b.email).trim()\n const res = await as('/v1/auth/me/email', { email, password })\n if (res.error) return refused(res, res.error.code === 'step_up_required' ? 'password' : ['invalid_email', 'email_unchanged', 'email_taken'].includes(res.error.code) ? 'email' : undefined)\n // Nothing changed yet: the new address confirms it from the link it was sent.\n return json({ status: 'sent', email }, 200, mine.headers)\n }\n if (route === '/me/identities/unlink') {\n const provider = typeof b.provider === 'string' ? b.provider : ''\n if (!PROVIDER_ID.test(provider)) return problem(400, 'invalid_provider', 'Say which provider to unlink.', 'provider', mine.headers)\n const res = await as(`/v1/auth/identities/${provider}`, undefined, 'DELETE')\n if (res.error) return refused(res)\n return json({ status: 'unlinked', provider }, 200, mine.headers)\n }\n // A passkey made on this page, for the domain the workspace's passkeys\n // belong to. The ceremony's id stays here, sealed, between its two calls.\n if (route === '/me/passkeys/add/begin') {\n const kind = b.kind === 'device' || b.kind === 'security_key' ? b.kind : ''\n const res = await as('/v1/auth/webauthn/register/begin', { password, ...(kind ? { kind } : {}) })\n if (res.error) return refused(res, res.error.code === 'step_up_required' ? 'password' : undefined)\n const step: Step = { kind: 'enrol', token: String(res.data?.session_id ?? ''), returnTo: afterSignIn }\n const h = new Headers(mine.headers)\n h.append('set-cookie', writeCookie(stepCookie, await seal(step, await key), attrs(request, PASSKEY_SECONDS)))\n return json({ status: 'started', options: res.data?.options?.publicKey ?? res.data?.options ?? null }, 200, h)\n }\n if (route === '/me/passkeys/add/finish') {\n const sealed = readCookies(request.headers.get('cookie')).get(stepCookie)\n const step = sealed ? await unseal<Step>(sealed, await key) : null\n if (step === null || step.kind !== 'enrol') return problem(400, 'step_expired', 'Start adding the passkey again: it was asked for too long ago.', undefined, mine.headers)\n if (!isCredential(b.credential)) return problem(400, 'bad_request', 'Send the passkey the browser made.', undefined, mine.headers)\n const name = typeof b.name === 'string' ? b.name.trim().slice(0, 60) : ''\n const res = await as('/v1/auth/webauthn/register/finish', { session_id: step.token, nickname: name, credential: b.credential })\n const h = new Headers(mine.headers)\n h.append('set-cookie', writeCookie(stepCookie, '', attrs(request, 0)))\n if (res.error) return problem(res.status, res.error.code === 'attestation_invalid' ? 'passkey_failed' : res.error.code, res.error.code === 'attestation_invalid' ? 'The passkey could not be added. Try again.' : res.error.message, undefined, h)\n return json({ status: 'added', passkey: passkeyOf(res.data) }, 200, h)\n }\n if (route === '/me/passkeys/remove') {\n const id = typeof b.id === 'string' ? b.id : ''\n if (!/^[0-9a-f-]{36}$/i.test(id)) return problem(400, 'invalid_passkey', 'Say which passkey to remove.', undefined, mine.headers)\n const res = await as(`/v1/auth/webauthn/credentials/${id}`, undefined, 'DELETE')\n if (res.error) return refused(res)\n return json({ status: 'removed', id }, 200, mine.headers)\n }\n // A guest becoming an account of their own, with an address and a password.\n if (route === '/me/upgrade') {\n const bad = firstProblem(checkName(b.name), checkEmail(b.email), checkNewPassword(b.password))\n if (bad) return invalid(bad)\n const res = await as('/v1/auth/anonymous/upgrade', { email: String(b.email).trim(), password: b.password, display_name: typeof b.name === 'string' ? b.name.trim() : '' })\n if (res.error) return refused(res, res.error.code === 'weak_password' ? 'password' : 'email')\n return signedIn(request, res.data)\n }\n // A member administering their organization's people (cauthy:members manage).\n if (route.startsWith('/me/organizations/members/')) {\n const org = typeof b.organizationId === 'string' ? b.organizationId : ''\n if (!UUID.test(org)) return problem(400, 'invalid_organization', 'Say which organization.', undefined, mine.headers)\n const base = `/v1/auth/me/organizations/${org}/members`\n if (route === '/me/organizations/members/add') {\n const bad = checkEmail(b.email)\n if (bad) return invalid(bad)\n const role = typeof b.role === 'string' ? b.role : ''\n if (role === '') return problem(400, 'invalid_role', 'Choose a role.', 'role', mine.headers)\n const res = await as(base, { email: String(b.email).trim(), role, name: typeof b.name === 'string' ? b.name.trim() : '',\n client_id: clientId, ...(typeof b.locale === 'string' && b.locale ? { locale: b.locale } : {}) })\n if (res.error) return refused(res, res.error.code === 'unknown_role' ? 'role' : 'email')\n return json({ status: 'added', member: orgMemberOf(res.data) }, 200, mine.headers)\n }\n const user = typeof b.userId === 'string' ? b.userId : ''\n if (!UUID.test(user)) return problem(400, 'invalid_member', 'Say which member.', undefined, mine.headers)\n if (route === '/me/organizations/members/role') {\n const role = typeof b.role === 'string' ? b.role : ''\n if (role === '') return problem(400, 'invalid_role', 'Choose a role.', 'role', mine.headers)\n const res = await as(`${base}/${user}`, { role }, 'PUT')\n if (res.error) return refused(res, 'role')\n return json({ status: 'changed', userId: user, role }, 200, mine.headers)\n }\n if (route === '/me/organizations/members/remove') {\n const res = await as(`${base}/${user}`, undefined, 'DELETE')\n if (res.error) return refused(res)\n orgCache.delete(mine.token)\n return json({ status: 'removed', userId: user }, 200, mine.headers)\n }\n if (route === '/me/organizations/members/invite') {\n const res = await as(`${base}/${user}/invite`, { client_id: clientId, ...(typeof b.locale === 'string' && b.locale ? { locale: b.locale } : {}) })\n if (res.error) return refused(res)\n return json({ status: 'sent', userId: user }, 200, mine.headers)\n }\n }\n if (route === '/me/agents/disconnect') {\n const id = typeof b.id === 'string' ? b.id : ''\n if (!/^[0-9a-f-]{36}$/i.test(id)) return problem(400, 'invalid_agent', 'Say which agent to disconnect.', undefined, mine.headers)\n const res = await as(`/v1/auth/me/agents/${id}`, undefined, 'DELETE')\n if (res.error) return refused(res)\n return json({ status: 'disconnected', id }, 200, mine.headers)\n }\n if (route === '/me/sessions/end') {\n const res = await as('/v1/auth/me/sessions', undefined, 'DELETE')\n if (res.error) return refused(res)\n // Everywhere is here too.\n const h = new Headers()\n for (const c of clearParts(cookieName, attrs(request, 0), readCookies(request.headers.get('cookie')))) h.append('set-cookie', c)\n orgCache.delete(mine.token)\n return json({ status: 'signed_out' }, 200, h)\n }\n return null\n }\n\n const isToken = (v: unknown): v is string => typeof v === 'string' && v !== '' && v.length <= 512\n const badLink = () => problem(422, 'invalid_token', 'This link is not valid, or it has expired.')\n\n // What a mailed link carries back: the token it was opened with.\n if (route === '/reset-password') {\n if (!isToken(b.token)) return badLink()\n const bad = checkNewPassword(b.password)\n if (bad) return invalid(bad)\n const res = await ask(request, 'POST', '/v1/auth/password/change', { token: String(b.token), new_password: b.password })\n if (res.error) return problem(res.status, res.error.code, res.error.message, res.error.code === 'weak_password' ? 'password' : undefined)\n return json({ status: 'changed' })\n }\n if (route === '/verify-email') {\n if (!isToken(b.token)) return badLink()\n const res = await ask(request, 'POST', '/v1/auth/email/verify', { token: String(b.token) })\n if (res.error) return problem(res.status, res.error.code, res.error.message)\n return json({ status: 'verified' })\n }\n\n // A passkey, on this page: Cauthy says what to ask the browser for, the\n // browser asks the person, and the answer goes back to Cauthy through here.\n if (route === '/sign-in/passkey/begin') {\n // With the person's address, the browser is told which passkeys are\n // theirs; Cauthy answers the same for an address with none.\n const email = typeof b.email === 'string' && checkEmail(b.email) === null ? b.email.trim() : ''\n const res = await ask(request, 'POST', '/v1/auth/webauthn/login/begin', email !== '' ? { email } : {})\n if (res.error) return problem(res.status, res.error.code, res.error.message)\n const step: Step = { kind: 'passkey', token: String(res.data?.session_id ?? ''), returnTo: afterSignIn }\n return json({ status: 'started', options: res.data?.options?.publicKey ?? res.data?.options ?? null }, 200,\n new Headers({ 'set-cookie': writeCookie(stepCookie, await seal(step, await key), attrs(request, PASSKEY_SECONDS)) }))\n }\n if (route === '/sign-in/passkey/finish') {\n const sealed = readCookies(request.headers.get('cookie')).get(stepCookie)\n const step = sealed ? await unseal<Step>(sealed, await key) : null\n if (step === null || step.kind !== 'passkey') return problem(400, 'step_expired', 'Try the passkey again: it was asked for too long ago.')\n if (!isCredential(b.credential)) return problem(400, 'bad_request', 'Send the passkey the browser answered with.')\n const res = await ask(request, 'POST', '/v1/auth/webauthn/login/finish', { session_id: step.token, credential: b.credential })\n const clear = writeCookie(stepCookie, '', attrs(request, 0))\n if (res.error) {\n // Which check failed is Cauthy's to log; the page says only that it did.\n const failed = ['assertion_invalid', 'session_expired', 'clone_detected', 'not_found'].includes(res.error.code)\n return problem(res.status, failed ? 'passkey_failed' : res.error.code, failed ? 'The passkey sign-in could not be completed. Try again, or sign in another way.' : res.error.message, undefined, new Headers({ 'set-cookie': clear }))\n }\n return signedIn(request, res.data, [clear])\n }\n\n // Google One Tap: Cauthy gives the workspace's Google client and a nonce\n // for one prompt; Google's prompt gives the page an ID token, which comes\n // back here and is traded, once, for a session.\n if (route === '/sign-in/google-one-tap/begin') {\n const res = await ask(request, 'POST', '/v1/auth/google/one-tap/begin', {})\n if (res.error) return problem(res.status, res.error.code, res.error.message)\n return json({ status: 'started', clientId: String(res.data?.client_id ?? ''), nonce: String(res.data?.nonce ?? '') })\n }\n if (route === '/sign-in/google-one-tap') {\n if (typeof b.credential !== 'string' || b.credential === '') return problem(400, 'bad_request', 'Send the credential Google gave the page.')\n const res = await ask(request, 'POST', '/v1/auth/google/one-tap', { credential: b.credential })\n if (res.error) return problem(res.status, res.error.code, res.error.message)\n return signedIn(request, res.data)\n }\n\n // A sign-in link: asked for here, mailed by Cauthy, opened on the\n // application's sign-in page, which gives the token back.\n if (route === '/sign-in/magic-link') {\n const bad = checkEmail(b.email)\n if (bad) return invalid(bad)\n if (pages.signIn === undefined) return problem(500, 'not_configured', 'cauthy-auth: pages.signIn is required for sign-in links: it is the page the link opens')\n // The same answer whether or not the address has an account. With\n // create, an address with none gets one when the link or code is used\n // (if the workspace accepts new accounts): one screen for both.\n const email = String(b.email).trim()\n // Where the person goes once in travels in the link itself, as\n // `return_to` on the page it opens: it may be opened in another browser.\n const back = typeof b.returnTo === 'string' ? localPath(b.returnTo, afterSignIn) : afterSignIn\n const page = back === afterSignIn ? pages.signIn : `${pages.signIn}${pages.signIn.includes('?') ? '&' : '?'}return_to=${encodeURIComponent(back)}`\n await ask(request, 'POST', '/v1/auth/magic-link/request', { email, ...(b.create === true ? { create_account: true } : {}) }, page)\n // The mail carries a code too. Whose it is stays here, sealed, so the\n // page that asks for the code needs only the code.\n const step: Step = { kind: 'code', token: email, returnTo: back }\n return json({ status: 'sent' }, 200, new Headers({ 'set-cookie': writeCookie(stepCookie, await seal(step, await key), attrs(request, STEP_SECONDS)) }))\n }\n if (route === '/sign-in/email-code') {\n const bad = checkCode(b.code)\n if (bad) return invalid(bad)\n const sealed = readCookies(request.headers.get('cookie')).get(stepCookie)\n const step = sealed ? await unseal<Step>(sealed, await key) : null\n if (step === null || step.kind !== 'code') return problem(400, 'step_expired', 'Ask for a new link: this one was asked for too long ago.')\n const res = await ask(request, 'POST', '/v1/auth/magic-link/verify-code', { email: step.token, code: String(b.code).trim() })\n if (res.error) return problem(res.status, res.error.code, res.error.message, 'code')\n return signedIn(request, res.data, [writeCookie(stepCookie, '', attrs(request, 0))], { returnTo: step.returnTo })\n }\n if (route === '/sign-in/magic-link/verify') {\n if (!isToken(b.token)) return badLink()\n const res = await ask(request, 'POST', '/v1/auth/magic-link/verify', { token: String(b.token) })\n if (res.error) return problem(res.status, res.error.code, res.error.message)\n return signedIn(request, res.data)\n }\n return null\n }\n\n async function handler(request: Request): Promise<Response> {\n const url = new URL(request.url)\n if (url.pathname !== basePath && !url.pathname.startsWith(`${basePath}/`)) return new Response('Not found', { status: 404 })\n const route = withoutTrailingSlashes(url.pathname.slice(basePath.length)) || '/'\n const get = request.method === 'GET' || request.method === 'HEAD'\n\n const mine = await ownRoute(request, url, route)\n if (mine !== null) return mine\n\n if (route === '/login' && get) return login(request, url)\n if (route === '/callback' && get) return callback(request, url)\n if (route === '/logout' && (get || request.method === 'POST')) return logout(request)\n\n if (route === '/session' && get) {\n const r = await resolve(request)\n const h = new Headers()\n for (const c of r.cookies) h.append('set-cookie', c)\n return json({ session: r.session ? await toPublic(r.session) : null, status: r.status }, 200, h)\n }\n\n // For a page that found its session expired: renew, and go back to it.\n if (route === '/refresh' && get) {\n const r = await resolve(request)\n const back = localPath(url.searchParams.get('return_to'), afterSignIn)\n if (r.status === 'unauthenticated') return redirect(urls.signIn(back), r.cookies)\n if (r.status === 'expired') return new Response('Sign-in is unavailable right now. Try again in a moment.', { status: 503 })\n return redirect(back, r.cookies)\n }\n\n if (route === '/account' && get) {\n const q = new URLSearchParams({ client_id: clientId })\n const back = localPath(url.searchParams.get('return_to'), '')\n if (back !== '') q.set('return_to', `${originOf(request)}${back}`)\n const locale = url.searchParams.get('locale')\n if (locale && /^[a-zA-Z-]{2,10}$/.test(locale)) q.set('ui_locales', locale)\n return redirect(`${issuer}/v1/oauth/account?${q}`)\n }\n return new Response('Not found', { status: 404 })\n }\n\n async function protect(request: Request) {\n const { value } = await read(request)\n if (value !== null && fresh(value)) return { session: toSession(value) }\n const url = new URL(request.url)\n const state = value === null ? 'none' : 'expired'\n // A page is sent to sign in, or to renew and come back. Anything else —\n // a fetch, a form post — is told, and its caller decides.\n const page = request.method === 'GET' && (request.headers.get('sec-fetch-mode') ?? 'navigate') === 'navigate' &&\n (request.headers.get('accept') ?? 'text/html').includes('text/html')\n if (!page) {\n return { response: json({ error: 'unauthenticated', session: state }, 401, new Headers({ 'x-cauthy-session': state })) }\n }\n const back = url.pathname + url.search\n const to = value === null ? urls.signIn(back) : `${basePath}/refresh?return_to=${encodeURIComponent(back)}`\n return { response: redirect(to) }\n }\n\n // The endpoint's public address: the application's origin when it was\n // given (a proxy may hide it from the request), with the request's path.\n const webhook: Cauthy['webhook'] = (request, o = {}) =>\n verifyWebhook(request, { issuer, url: o.url ?? `${originOf(request)}${new URL(request.url).pathname}`, jwks: o.jwks, now: o.now })\n\n return {\n handler,\n webhook,\n system: systemThatRefreshes,\n getSession,\n status,\n resolve,\n protect,\n organizations,\n toPublic,\n urls,\n options: { issuer, clientId, basePath, afterSignIn, afterSignOut, cookieName },\n }\n}\n","// What a person may do in an organization.\n//\n// When a system keeps its catalog of roles in Cauthy, each of a person's\n// organizations arrives with what their role — and anything given or denied to\n// them apart from it — lets them do. Checking is a lookup in that list: no\n// call to Cauthy, on the server or in the browser.\n\nimport { withoutTrailingSlashes } from './url'\n\n/** The part of an organization that says what its member may do. */\nexport interface Permitted {\n /** \"resource:action\" entries the person is allowed; \"*\" is any. Absent when the system keeps no catalog in Cauthy. */\n permissions?: string[]\n /** Entries the person is denied whatever else allows them. */\n denied?: string[]\n}\n\nfunction matches(entry: string, resource: string, action: string): boolean {\n // The resource may itself hold a colon: the action is what follows the last one.\n const i = entry.lastIndexOf(':')\n if (i < 0) return false\n const r = entry.slice(0, i)\n const a = entry.slice(i + 1)\n return (r === '*' || r === resource) && (a === '*' || a === action)\n}\n\n/**\n * Whether the person may do an action on a resource in an organization:\n * allowed by some entry, and denied by none. A denial wins.\n *\n * An organization of a system that keeps no catalog in Cauthy carries no\n * permissions, and the answer is `false`: decide by its `role` instead.\n *\n * if (!can(organization, 'invoicing', 'write')) return forbidden()\n */\nexport function can(organization: Permitted | null | undefined, resource: string, action: string): boolean {\n if (!organization?.permissions) return false\n if ((organization.denied ?? []).some((d) => matches(d, resource, action))) return false\n return organization.permissions.some((p) => matches(p, resource, action))\n}\n\n// ── A system's catalog of roles ────────────────────────────────────────────\n\n/** Something a role may do: an action on a resource, in organizations of a kind (\"*\", the default, is every kind). */\nexport interface PolicyPermission {\n kind?: string\n resource: string\n action: string\n}\n\nexport interface PolicyRole {\n role: string\n name?: string\n description?: string\n /** Roles whose permissions this one has as well. */\n inherits?: string[]\n permissions?: PolicyPermission[]\n}\n\n// ── The catalog, with its types ────────────────────────────────────────────\n//\n// A catalog written down once gives the roles and the permissions their\n// names: `can(org, 'ledger:write')` then takes only a permission the catalog\n// has, the editor offers them, and a typo does not compile.\n//\n// export const policy = definePolicy([\n// { role: 'reader', permissions: [{ resource: 'ledger', action: 'read' }] },\n// { role: 'accountant', inherits: ['reader'], permissions: [{ resource: 'ledger', action: 'write' }] },\n// ])\n// export const { can, hasRole } = policy\n//\n// can(organization, 'ledger:write') // 'ledger:wirte' does not compile\n// hasRole(organization, 'accountant')\n//\n// Write it by hand, or let `cauthy-auth policy --pull` write it from the\n// catalog Cauthy has.\n\n/** A role as `definePolicy` reads it: any `PolicyRole`, kept as written. */\ntype RoleShape = {\n readonly role: string\n readonly name?: string\n readonly description?: string\n readonly inherits?: readonly string[]\n readonly permissions?: readonly { readonly kind?: string; readonly resource: string; readonly action: string }[]\n}\n\n// \"*\" in a catalog is \"any\": the name it stands for is any text.\ntype Named<S extends string> = S extends '*' ? string : S\n\ntype PermissionsIn<R> = R extends { readonly permissions: readonly (infer P)[] }\n ? P extends { readonly resource: infer Res extends string; readonly action: infer Act extends string } ? `${Named<Res>}:${Named<Act>}` : never\n : never\n\n/** The roles a catalog names: `RoleOf<typeof policy>`. */\nexport type RoleOf<P> = P extends Policy<infer R, string> ? R : never\n/** The \"resource:action\" permissions a catalog names: `PermissionOf<typeof policy>`. */\nexport type PermissionOf<P> = P extends Policy<string, infer X> ? X : never\n\nexport interface Policy<Role extends string = string, Permission extends string = string> {\n /** The catalog as Cauthy takes it: `pushPolicy({ roles: policy.roles })`. */\n roles: PolicyRole[]\n /** Every role's name. */\n roleNames: Role[]\n /** Every permission some role has, as \"resource:action\". */\n permissions: Permission[]\n /**\n * Whether the person may do this in the organization: `can(org, 'ledger:write')`.\n * It reads what Cauthy sent with the session, so a catalog edited in Cauthy\n * since this file was written is still what decides.\n */\n can(organization: Permitted | null | undefined, permission: Permission): boolean\n /** Whether the person's role in the organization is one of these. */\n hasRole(organization: { role: string } | null | undefined, ...roles: Role[]): boolean\n /**\n * What a role may do by this catalog, with what it inherits: for showing a\n * role, never for deciding about a person (their exceptions are not here).\n */\n permissionsOf(role: Role): Permission[]\n}\n\n/** Gives a catalog of roles its types. See the top of this section. */\nexport function definePolicy<const T extends readonly RoleShape[]>(roles: T): Policy<T[number]['role'], PermissionsIn<T[number]>> {\n type Role = T[number]['role']\n type Permission = PermissionsIn<T[number]>\n const entry = (p: { resource: string; action: string }) => `${p.resource}:${p.action}` as Permission\n const byName = new Map(roles.map((r) => [r.role, r]))\n const split = (permission: string): [string, string] => {\n const i = permission.lastIndexOf(':')\n return i < 0 ? [permission, ''] : [permission.slice(0, i), permission.slice(i + 1)]\n }\n return {\n roles: roles.map((r) => ({\n role: r.role,\n ...(r.name !== undefined ? { name: r.name } : {}),\n ...(r.description !== undefined ? { description: r.description } : {}),\n ...(r.inherits ? { inherits: [...r.inherits] } : {}),\n ...(r.permissions ? { permissions: r.permissions.map((p) => ({ ...p })) } : {}),\n })),\n roleNames: roles.map((r) => r.role),\n permissions: [...new Set(roles.flatMap((r) => (r.permissions ?? []).map(entry)))],\n can(organization, permission) {\n const [resource, action] = split(permission)\n return can(organization, resource, action)\n },\n hasRole(organization, ...wanted) {\n return organization != null && (wanted as string[]).includes(organization.role)\n },\n permissionsOf(role: Role) {\n const seen = new Set<string>()\n const out = new Set<Permission>()\n const walk = (name: string) => {\n if (seen.has(name)) return // a catalog that inherits in a circle still ends\n seen.add(name)\n const r = byName.get(name)\n for (const p of r?.permissions ?? []) out.add(entry(p))\n for (const parent of r?.inherits ?? []) walk(parent)\n }\n walk(role)\n return [...out]\n },\n }\n}\n\nconst IDENT = /^[A-Za-z_$][A-Za-z0-9_$]*$/\n\n/**\n * A TypeScript module that defines the catalog given, for `cauthy-auth policy\n * --pull` to write: the application's types then come from the catalog\n * Cauthy has.\n */\nexport function policySource(system: string, roles: PolicyRole[]): string {\n const text = (v: string) => JSON.stringify(v)\n const key = (k: string) => (IDENT.test(k) ? k : text(k))\n const one = (r: PolicyRole) => {\n const parts = [`role: ${text(r.role)}`]\n if (r.name) parts.push(`name: ${text(r.name)}`)\n if (r.description) parts.push(`description: ${text(r.description)}`)\n if (r.inherits?.length) parts.push(`inherits: [${r.inherits.map(text).join(', ')}]`)\n if (r.permissions?.length) {\n const list = r.permissions.map((p) => ` { ${[...(p.kind && p.kind !== '*' ? [`${key('kind')}: ${text(p.kind)}`] : []), `resource: ${text(p.resource)}`, `action: ${text(p.action)}`].join(', ')} },`)\n parts.push(`permissions: [\\n${list.join('\\n')}\\n ]`)\n }\n return ` {\\n ${parts.join(',\\n ')},\\n },`\n }\n return `// The catalog of roles of ${text(system)}, as Cauthy has it.\n// Written by \\`cauthy-auth policy --pull\\`: run it again after the catalog\n// changes, and do not edit this file by hand.\n\nimport { definePolicy, type PermissionOf, type RoleOf } from 'cauthy-auth'\n\nexport const policy = definePolicy([\n${roles.map(one).join('\\n')}\n])\n\nexport const { can, hasRole } = policy\nexport type Role = RoleOf<typeof policy>\nexport type Permission = PermissionOf<typeof policy>\n`\n}\n\n/** Reads a system's catalog of roles from Cauthy, with a personal access token. */\nexport async function pullPolicy(o: Omit<PushPolicyOptions, 'roles'> = {}): Promise<PolicyRole[]> {\n const env = (n: string) => (typeof process !== 'undefined' ? process.env?.[n] : undefined)\n const issuer = withoutTrailingSlashes(o.issuer ?? env('CAUTHY_ISSUER') ?? '')\n const system = o.system ?? env('CAUTHY_SYSTEM') ?? ''\n const tenant = o.tenant ?? env('CAUTHY_TENANT') ?? ''\n const token = o.token ?? env('CAUTHY_TOKEN') ?? ''\n for (const [name, v] of Object.entries({ CAUTHY_ISSUER: issuer, CAUTHY_SYSTEM: system, CAUTHY_TENANT: tenant, CAUTHY_TOKEN: token })) {\n if (v === '') throw new Error(`cauthy-auth: ${name} is required to read a policy`)\n }\n const res = await (o.fetch ?? fetch)(`${issuer}/v1/systems/${encodeURIComponent(system)}/policy`, {\n headers: { authorization: `Bearer ${token}`, 'x-tenant-key': tenant, accept: 'application/json' },\n })\n const body = (await res.json().catch(() => null)) as { data?: { roles?: PolicyRole[] }; errors?: { message?: string }[] } | null\n if (!res.ok) throw new Error(`cauthy-auth: Cauthy refused to give the policy (${res.status}): ${body?.errors?.[0]?.message ?? res.statusText}`)\n return body?.data?.roles ?? []\n}\n\nexport interface PushPolicyOptions {\n /** The system whose catalog this is. Default: `CAUTHY_SYSTEM`. */\n system?: string\n roles: PolicyRole[]\n /** Cauthy's address. Default: `CAUTHY_ISSUER`. */\n issuer?: string\n /** The workspace's slug. Default: `CAUTHY_TENANT`. */\n tenant?: string\n /** A personal access token with `organizations:manage`. Default: `CAUTHY_TOKEN`. */\n token?: string\n fetch?: typeof fetch\n}\n\n/**\n * Gives Cauthy a system's catalog of roles, replacing the one it has. It is\n * the way to load a first catalog from what a system already had; from then on\n * the catalog is Cauthy's, edited in its dashboard, and pushing again would\n * overwrite what was edited there.\n */\nexport async function pushPolicy(o: PushPolicyOptions): Promise<void> {\n const env = (n: string) => (typeof process !== 'undefined' ? process.env?.[n] : undefined)\n const issuer = withoutTrailingSlashes(o.issuer ?? env('CAUTHY_ISSUER') ?? '')\n const system = o.system ?? env('CAUTHY_SYSTEM') ?? ''\n const tenant = o.tenant ?? env('CAUTHY_TENANT') ?? ''\n const token = o.token ?? env('CAUTHY_TOKEN') ?? ''\n for (const [name, v] of Object.entries({ CAUTHY_ISSUER: issuer, CAUTHY_SYSTEM: system, CAUTHY_TENANT: tenant, CAUTHY_TOKEN: token })) {\n if (v === '') throw new Error(`cauthy-auth: ${name} is required to push a policy`)\n }\n const res = await (o.fetch ?? fetch)(`${issuer}/v1/systems/${encodeURIComponent(system)}/policy`, {\n method: 'PUT',\n headers: { authorization: `Bearer ${token}`, 'x-tenant-key': tenant, 'content-type': 'application/json' },\n body: JSON.stringify({ roles: o.roles }),\n })\n if (!res.ok) {\n const body = (await res.json().catch(() => null)) as { errors?: { message?: string }[] } | null\n throw new Error(`cauthy-auth: Cauthy refused the policy (${res.status}): ${body?.errors?.[0]?.message ?? res.statusText}`)\n }\n}\n","// Connecting an application to Cauthy in one call: its client, where its\n// people come back to, where it hears events, and its own identity. It is what\n// `cauthy-auth init` runs, and what Cauthy's dashboard does under \"Connect a\n// system\".\n\nimport { withoutTrailingSlashes } from './url'\n\nexport interface ConnectOptions {\n /** The system's name, as its organizations are filed under: lowercase, digits, - or _. */\n system: string\n /** The application's public address: `https://app.example.com`, or `http://localhost:3000` while developing. */\n appUrl: string\n /** Shown to people on Cauthy's pages. Default: the system's name. */\n name?: string\n /** Where the application serves the return from a sign-in. Default: `/api/auth/callback`. */\n callbackPath?: string\n /** An https address of the application that receives Cauthy's events. */\n eventsUrl?: string\n /** The events to receive. Default: all of them. */\n events?: string[]\n /** Where the application publishes its keys, to prove itself without a secret. */\n jwksUri?: string\n /** Cauthy's address. Default: `CAUTHY_ISSUER`. */\n issuer?: string\n /** The workspace's slug. Default: `CAUTHY_TENANT`. */\n tenant?: string\n /** A personal access token with `systems:connect`. Default: `CAUTHY_TOKEN`. */\n token?: string\n fetch?: typeof fetch\n}\n\nexport interface Connected {\n system: string\n clientId: string\n /** Shown this once: Cauthy keeps only its hash. */\n clientSecret: string\n redirectUris: string[]\n webhook: { id: string; url: string; events: string[] } | null\n /**\n * Everything the application sets: what Cauthy answered, plus CAUTHY_SECRET,\n * the key of the session cookie, generated here and known to nobody else.\n */\n env: Record<string, string>\n}\n\nfunction sessionSecret(): string {\n const bytes = crypto.getRandomValues(new Uint8Array(32))\n let s = ''\n for (const b of bytes) s += String.fromCharCode(b)\n return btoa(s).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')\n}\n\nexport async function connectSystem(o: ConnectOptions): Promise<Connected> {\n const env = (n: string) => (typeof process !== 'undefined' ? process.env?.[n] : undefined)\n const issuer = withoutTrailingSlashes(o.issuer ?? env('CAUTHY_ISSUER') ?? '')\n const tenant = o.tenant ?? env('CAUTHY_TENANT') ?? ''\n const token = o.token ?? env('CAUTHY_TOKEN') ?? ''\n for (const [name, v] of Object.entries({ CAUTHY_ISSUER: issuer, CAUTHY_TENANT: tenant, CAUTHY_TOKEN: token })) {\n if (v === '') throw new Error(`cauthy-auth: ${name} is required to connect a system`)\n }\n const res = await (o.fetch ?? fetch)(`${issuer}/v1/connect`, {\n method: 'POST',\n headers: { authorization: `Bearer ${token}`, 'x-tenant-key': tenant, 'content-type': 'application/json' },\n body: JSON.stringify({ system: o.system, app_url: o.appUrl, name: o.name, callback_path: o.callbackPath,\n events_url: o.eventsUrl, events: o.events, jwks_uri: o.jwksUri }),\n })\n const body = (await res.json().catch(() => null)) as {\n data?: { system: string; client_secret: string; client: { client_id: string; redirect_uris: string[] }\n webhook: Connected['webhook']; env: Record<string, string> }\n errors?: { field?: string; message?: string }[]\n } | null\n if (!res.ok || !body?.data) {\n const why = (body?.errors ?? []).map((e) => e.message).filter(Boolean).join('; ') || res.statusText\n throw new Error(`cauthy-auth: Cauthy did not connect the system (${res.status}): ${why}`)\n }\n const d = body.data\n return { system: d.system, clientId: d.client.client_id, clientSecret: d.client_secret, redirectUris: d.client.redirect_uris,\n webhook: d.webhook, env: { ...d.env, CAUTHY_SECRET: sessionSecret() } }\n}\n\n/** The variables as the lines of an env file. */\nexport function envFile(env: Record<string, string>): string {\n return Object.entries(env).map(([k, v]) => `${k}=${v}`).join('\\n') + '\\n'\n}\n","// A backend that is handed a Cauthy access token: is it real, and whose is it?\n//\n// const who = await verifyToken(request) // or the token itself\n// who.userId, who.tenantId, who.roles\n//\n// Cauthy signs its tokens with a key it publishes (/.well-known/jwks.json), so\n// checking one needs no secret and no call to Cauthy per request: the keys are\n// fetched once and cached. Throws `CauthyTokenError` for anything else: answer\n// it 401.\n\nimport { createRemoteJWKSet, jwtVerify, type JWTVerifyGetKey } from 'jose'\nimport { withoutTrailingSlashes } from './url'\n\n/** Who a verified access token belongs to. */\nexport interface TokenIdentity {\n /** The person. For a system's own token, the client it identifies as. */\n userId: string\n tenantId: string\n email?: string\n roles: string[]\n /** Set when the token is a system's own and not a person's. */\n system?: string\n /** UTC, ISO 8601. */\n expiresAt: string\n /** The token as it arrived, to pass on. */\n token: string\n}\n\nexport class CauthyTokenError extends Error {\n constructor(readonly reason: string) {\n super(`cauthy-auth: token refused: ${reason}`)\n this.name = 'CauthyTokenError'\n }\n}\n\nexport interface VerifyTokenOptions {\n /** Cauthy's address. Default: `CAUTHY_ISSUER`. */\n issuer?: string\n /** The audience the tokens must carry. Default: `CAUTHY_AUDIENCE`; unchecked when neither is set. */\n audience?: string\n /** Refuse a token of any other workspace. Default: `CAUTHY_TENANT_ID`; unchecked when neither is set. */\n tenantId?: string\n /** Cauthy's keys. Default: fetched from the issuer and cached. */\n jwks?: JWTVerifyGetKey\n /** The moment to verify at. Default: now. */\n now?: Date\n}\n\nconst keys = new Map<string, JWTVerifyGetKey>()\n\n/** Cauthy's published keys, fetched once per issuer and cached. */\nexport function keysOf(issuer: string): JWTVerifyGetKey {\n let set = keys.get(issuer)\n if (set === undefined) {\n set = createRemoteJWKSet(new URL(`${issuer}/.well-known/jwks.json`), { cooldownDuration: 30_000 })\n keys.set(issuer, set)\n }\n return set\n}\n\nfunction env(name: string): string | undefined {\n return typeof process !== 'undefined' ? process.env?.[name] : undefined\n}\n\nfunction bearer(from: string | Request | Headers): string {\n if (typeof from === 'string') return from.replace(/^Bearer\\s+/i, '').trim()\n const header = (from instanceof Headers ? from : from.headers).get('authorization') ?? ''\n return /^Bearer\\s+/i.test(header) ? header.replace(/^Bearer\\s+/i, '').trim() : ''\n}\n\n/**\n * Verifies an access token (or the `Authorization: Bearer` of a request) and\n * answers who it belongs to. Checked: the signature, against Cauthy's\n * published keys; that Cauthy issued it; that it has not expired; and the\n * audience and the workspace, when given.\n */\nexport async function verifyToken(from: string | Request | Headers, options: VerifyTokenOptions = {}): Promise<TokenIdentity> {\n const issuer = withoutTrailingSlashes(options.issuer ?? env('CAUTHY_ISSUER') ?? '')\n if (issuer === '') throw new CauthyTokenError('issuer (CAUTHY_ISSUER) is not set')\n const token = bearer(from)\n if (token === '') throw new CauthyTokenError('no token')\n\n let claims: Record<string, unknown>\n try {\n const verified = await jwtVerify(token, options.jwks ?? keysOf(issuer), {\n algorithms: ['RS256'],\n issuer,\n audience: options.audience ?? env('CAUTHY_AUDIENCE'),\n requiredClaims: ['exp', 'sub'],\n currentDate: options.now,\n })\n claims = verified.payload as Record<string, unknown>\n } catch (err) {\n throw new CauthyTokenError(err instanceof Error ? err.message : 'bad signature')\n }\n\n const tenantId = typeof claims.tid === 'string' ? claims.tid : ''\n const wanted = options.tenantId ?? env('CAUTHY_TENANT_ID')\n if (wanted && tenantId !== wanted) throw new CauthyTokenError('issued for another workspace')\n\n return {\n userId: String(claims.sub),\n tenantId,\n ...(typeof claims.email === 'string' && claims.email !== '' ? { email: claims.email } : {}),\n roles: Array.isArray(claims.roles) ? claims.roles.filter((r): r is string => typeof r === 'string') : [],\n ...(typeof claims.sys === 'string' && claims.sys !== '' ? { system: claims.sys } : {}),\n expiresAt: new Date((claims.exp as number) * 1000).toISOString(),\n token,\n }\n}\n"],"mappings":"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","names":["out","out","env","out","env","env","body","resolve","out","status","bearer","failed","callback","code","done","s","b","res","out","env","env","createRemoteJWKSet","jwtVerify","keys","keysOf","createRemoteJWKSet","env","jwtVerify"]}
|
|
1
|
+
{"version":3,"sources":["../src/cookies.ts","../src/seal.ts","../src/system.ts","../src/url.ts","../src/theme.ts","../src/types.ts","../src/validate.ts","../src/webhook.ts","../src/cauthy.ts","../src/permissions.ts","../src/connect.ts","../src/verify.ts"],"sourcesContent":["// Cookies, by hand: reading the Cookie header and writing Set-Cookie.\n//\n// A session can outgrow one cookie (browsers stop near 4 KB), so a value is\n// written in numbered parts — name.0, name.1 — and read back in order.\n\nconst PART = 3500\n\nexport function readCookies(header: string | null | undefined): Map<string, string> {\n const out = new Map<string, string>()\n for (const pair of (header ?? '').split(';')) {\n const i = pair.indexOf('=')\n if (i > 0) out.set(pair.slice(0, i).trim(), pair.slice(i + 1).trim())\n }\n return out\n}\n\n/** A value written in parts, or null when the cookie is not there. */\nexport function readParts(cookies: Map<string, string>, name: string): string | null {\n let value = ''\n for (let i = 0; cookies.has(`${name}.${i}`); i++) value += cookies.get(`${name}.${i}`)\n return value === '' ? null : value\n}\n\nexport interface CookieAttributes {\n secure: boolean\n maxAge: number // seconds; 0 deletes\n path?: string\n}\n\nfunction attributes(a: CookieAttributes): string {\n // httpOnly: script never reads it. SameSite=Lax: it rides the navigation\n // that comes back from Cauthy, and no cross-site form post.\n return `Path=${a.path ?? '/'}; HttpOnly; SameSite=Lax; Max-Age=${a.maxAge}${a.secure ? '; Secure' : ''}`\n}\n\nexport function writeCookie(name: string, value: string, a: CookieAttributes): string {\n return `${name}=${value}; ${attributes(a)}`\n}\n\n/**\n * The Set-Cookie headers that store a value in parts and delete whatever\n * parts an earlier, longer value left behind.\n */\nexport function writeParts(name: string, value: string, a: CookieAttributes, had: Map<string, string>): string[] {\n const out: string[] = []\n let n = 0\n for (let i = 0; i < value.length; i += PART) out.push(writeCookie(`${name}.${n++}`, value.slice(i, i + PART), a))\n for (let i = n; had.has(`${name}.${i}`); i++) out.push(writeCookie(`${name}.${i}`, '', { ...a, maxAge: 0 }))\n return out\n}\n\nexport function clearParts(name: string, a: CookieAttributes, had: Map<string, string>): string[] {\n const out: string[] = []\n for (let i = 0; had.has(`${name}.${i}`) || i === 0; i++) out.push(writeCookie(`${name}.${i}`, '', { ...a, maxAge: 0 }))\n return out\n}\n","// The session cookie's envelope: encrypted and authenticated with a key only\n// the server has, so the browser carries the session without being able to\n// read or change it.\n\nimport { CompactEncrypt, compactDecrypt } from 'jose'\n\nconst encoder = new TextEncoder()\nconst decoder = new TextDecoder()\n\n/** The 256-bit key a secret stands for. */\nexport async function keyOf(secret: string): Promise<Uint8Array> {\n return new Uint8Array(await crypto.subtle.digest('SHA-256', encoder.encode(secret)))\n}\n\nexport async function seal(value: unknown, key: Uint8Array): Promise<string> {\n return new CompactEncrypt(encoder.encode(JSON.stringify(value)))\n .setProtectedHeader({ alg: 'dir', enc: 'A256GCM' })\n .encrypt(key)\n}\n\n/** The value sealed, or null for anything that is not a cookie this key made. */\nexport async function unseal<T>(sealed: string, key: Uint8Array): Promise<T | null> {\n try {\n const { plaintext } = await compactDecrypt(sealed, key, {\n keyManagementAlgorithms: ['dir'],\n contentEncryptionAlgorithms: ['A256GCM'],\n })\n return JSON.parse(decoder.decode(plaintext)) as T\n } catch {\n return null\n }\n}\n","// The application acting on its own: creating its organizations, adding their\n// members, inviting people. No person's token is involved — the application\n// is somebody in Cauthy, and what it may touch is its own system's\n// organizations and nothing else.\n//\n// It proves who it is with the client's secret, or with a key it holds and\n// whose public half it publishes (`publicJwks`): then nothing secret is ever\n// shared with Cauthy.\n\nimport { exportJWK, importJWK, importPKCS8, SignJWT, type JWK, type KeyLike } from 'jose'\nimport { fromWire, type CauthyTheme } from './theme'\nimport { CauthyConfigError, type JsonValue } from './types'\nimport { withoutTrailingSlashes } from './url'\n\nconst ASSERTION_TYPE = 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer'\n/** Ask for a new token this long before the one held runs out. */\nconst SKEW_MS = 30_000\n\n/** The key an application signs its assertions with. */\nexport interface SystemKey {\n /** The private key: PKCS#8 PEM, or a JWK (as an object or its JSON). RSA, for RS256. */\n privateKey: string | JWK\n /** The id the public key is published under (`kid`). */\n keyId: string\n}\n\nexport interface SystemOptions {\n /** Cauthy's address. Default: `CAUTHY_ISSUER`. */\n issuer?: string\n /** The application's client id. Default: `CAUTHY_CLIENT_ID`. */\n clientId?: string\n /** Its secret. Default: `CAUTHY_CLIENT_SECRET`. Not needed with `key`. */\n clientSecret?: string\n /**\n * The key to prove who the application is with, instead of the secret.\n * Default: `CAUTHY_SYSTEM_KEY` (the private key) and `CAUTHY_SYSTEM_KEY_ID`.\n */\n key?: SystemKey\n fetch?: typeof fetch\n}\n\n/** Cauthy refused a request of the application's own. */\nexport class CauthyApiError extends Error {\n constructor(\n readonly status: number,\n /** Cauthy's code for what went wrong: `organization_not_found`, `other_system`, `outside_system_scope`… */\n readonly code: string,\n message: string,\n ) {\n super(`cauthy-auth: ${message}`)\n this.name = 'CauthyApiError'\n }\n}\n\n/** An organization of the application's system. Every moment is UTC. */\nexport interface Organization {\n id: string\n system: string\n name: string\n kind: string\n /** The id the application knows it by. */\n externalId?: string\n status: 'active' | 'archived'\n metadata: Record<string, JsonValue>\n members: number\n createdAt: string\n updatedAt: string\n}\n\nexport interface OrganizationMember {\n userId: string\n email: string\n name: string\n /** The account's status: a disabled member is still listed. */\n status: string\n role: string\n /** True when the address had no account: one was made and invited. */\n invited?: boolean\n}\n\n/** Who to add: an account by its id, or anybody by their address (invited when new). */\nexport type NewMember = { role: string; name?: string; locale?: string } & ({ userId: string; email?: undefined } | { email: string; userId?: undefined })\n\nexport interface CauthySystem {\n /** The application's own token, asked for when needed and kept until it is about to run out. */\n token(): Promise<string>\n /** Any route the application's token may call; answers what Cauthy put under `data`. */\n request<T = unknown>(method: string, path: string, body?: unknown): Promise<T>\n organizations: {\n list(query?: { q?: string; status?: 'active' | 'archived'; limit?: number; offset?: number }): Promise<{ items: Organization[]; total: number }>\n create(input: { name: string; kind?: string; externalId?: string; metadata?: Record<string, JsonValue> }): Promise<Organization>\n get(id: string): Promise<Organization>\n update(id: string, patch: { name?: string; kind?: string; status?: 'active' | 'archived'; metadata?: Record<string, JsonValue> }): Promise<Organization>\n /** Removes the organization and every membership of it, for good. */\n remove(id: string): Promise<void>\n }\n members: {\n list(organizationId: string): Promise<OrganizationMember[]>\n add(organizationId: string, member: NewMember): Promise<OrganizationMember>\n setRole(organizationId: string, userId: string, role: string): Promise<OrganizationMember>\n remove(organizationId: string, userId: string): Promise<void>\n }\n /** Invites a person who has no account yet; answers the account made for them. */\n invite(person: { email: string; name?: string; locale?: string }): Promise<{ id: string; email: string }>\n /**\n * How the application looks on Cauthy's pages, read. It is decided in\n * Cauthy's dashboard, by a person: an application never changes it.\n */\n theme: {\n get(clientId?: string): Promise<CauthyTheme>\n }\n /** The catalog of roles of one of the application's systems, as Cauthy has it. */\n policy: {\n get(system: string): Promise<import('./permissions').PolicyRole[]>\n }\n /** The public half of `key`, to serve at the address Cauthy was given (`jwks_uri`). Empty with a secret. */\n publicJwks(): Promise<{ keys: JWK[] }>\n}\n\nfunction env(name: string): string | undefined {\n return typeof process !== 'undefined' ? process.env?.[name] : undefined\n}\n\ninterface OrgWire {\n id: string; system: string; name: string; kind: string; external_id?: string; status: 'active' | 'archived'\n metadata: Record<string, JsonValue>; members: number; created_at: string; updated_at: string\n}\n\nfunction toOrganization(o: OrgWire): Organization {\n return { id: o.id, system: o.system, name: o.name, kind: o.kind, externalId: o.external_id, status: o.status,\n metadata: o.metadata ?? {}, members: o.members, createdAt: o.created_at, updatedAt: o.updated_at }\n}\n\ninterface MemberWire { user_id: string; email: string; name: string; status: string; role: string; invited?: boolean }\n\nfunction toMember(m: MemberWire): OrganizationMember {\n return { userId: m.user_id, email: m.email, name: m.name, status: m.status, role: m.role, ...(m.invited === undefined ? {} : { invited: m.invited }) }\n}\n\nfunction asJwk(k: SystemKey): JWK | undefined {\n if (typeof k.privateKey !== 'string') return k.privateKey\n return k.privateKey.includes('BEGIN') ? undefined : (JSON.parse(k.privateKey) as JWK)\n}\n\nasync function loadKey(k: SystemKey): Promise<KeyLike | Uint8Array> {\n const jwk = asJwk(k)\n // Extractable, so its public half can be published (publicJwks).\n return jwk ? importJWK(jwk, 'RS256') : importPKCS8(k.privateKey as string, 'RS256', { extractable: true })\n}\n\nexport function createSystem(given: SystemOptions = {}): CauthySystem {\n const issuer = withoutTrailingSlashes(given.issuer ?? env('CAUTHY_ISSUER') ?? '')\n const clientId = given.clientId ?? env('CAUTHY_CLIENT_ID') ?? ''\n const clientSecret = given.clientSecret ?? env('CAUTHY_CLIENT_SECRET') ?? ''\n const envKey = env('CAUTHY_SYSTEM_KEY')\n const key = given.key ?? (envKey ? { privateKey: envKey, keyId: env('CAUTHY_SYSTEM_KEY_ID') ?? '' } : undefined)\n const doFetch: typeof fetch = (...args) => (given.fetch ?? fetch)(...args)\n const tokenEndpoint = `${issuer}/v1/oauth/token`\n\n // Checked when it is first used, not when it is made: an application that\n // only signs people in never needs any of this.\n function configured(): void {\n if (!/^https?:\\/\\//.test(issuer)) throw new CauthyConfigError('issuer (CAUTHY_ISSUER) must be Cauthy\\'s address')\n if (clientId === '') throw new CauthyConfigError('clientId (CAUTHY_CLIENT_ID) is required')\n if (key ? key.keyId === '' : clientSecret === '') {\n throw new CauthyConfigError(key ? 'the key needs its id (CAUTHY_SYSTEM_KEY_ID)'\n : 'to act on its own the application needs its secret (CAUTHY_CLIENT_SECRET) or a key (CAUTHY_SYSTEM_KEY)')\n }\n }\n\n let imported: Promise<KeyLike | Uint8Array> | undefined\n const signingKey = () => (imported ??= loadKey(key as SystemKey))\n\n async function fail(res: Response, what: string): Promise<never> {\n const body = (await res.json().catch(() => null)) as { errors?: { code?: string; message?: string }[] } | null\n const first = body?.errors?.[0]\n throw new CauthyApiError(res.status, first?.code ?? 'error', `Cauthy refused ${what} (${res.status}): ${first?.message ?? res.statusText}`)\n }\n\n let held: { value: string; until: number } | undefined\n let asking: Promise<string> | undefined\n\n async function ask(): Promise<string> {\n configured()\n const form = new URLSearchParams({ grant_type: 'client_credentials', client_id: clientId })\n if (key) {\n const assertion = await new SignJWT({})\n .setProtectedHeader({ alg: 'RS256', kid: key.keyId })\n .setIssuer(clientId).setSubject(clientId).setAudience(tokenEndpoint)\n .setJti(crypto.randomUUID()).setIssuedAt().setExpirationTime('2m')\n .sign(await signingKey())\n form.set('client_assertion_type', ASSERTION_TYPE)\n form.set('client_assertion', assertion)\n } else {\n form.set('client_secret', clientSecret)\n }\n const res = await doFetch(tokenEndpoint, { method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, body: form })\n if (!res.ok) await fail(res, 'the application\\'s own token')\n const t = (await res.json()) as { access_token: string; expires_in: number }\n held = { value: t.access_token, until: Date.now() + t.expires_in * 1000 - SKEW_MS }\n return t.access_token\n }\n\n function token(): Promise<string> {\n if (held && Date.now() < held.until) return Promise.resolve(held.value)\n // One request, however many callers arrive while it is out.\n return (asking ??= ask().finally(() => { asking = undefined }))\n }\n\n async function call(method: string, path: string, body?: unknown): Promise<unknown> {\n const send = async () => doFetch(`${issuer}${path}`, {\n method,\n headers: { authorization: `Bearer ${await token()}`, ...(body === undefined ? {} : { 'content-type': 'application/json' }) },\n body: body === undefined ? undefined : JSON.stringify(body),\n })\n let res = await send()\n if (res.status === 401 && held) {\n // The token was taken back early (the client's keys or secret changed): once more, with a new one.\n held = undefined\n res = await send()\n }\n if (!res.ok) await fail(res, `${method} ${path}`)\n return res.status === 204 ? undefined : res.json()\n }\n\n const data = async <T>(method: string, path: string, body?: unknown) => ((await call(method, path, body)) as { data: T } | undefined)?.data as T\n const id = encodeURIComponent\n\n return {\n token,\n request: data,\n organizations: {\n async list(query = {}) {\n const q = new URLSearchParams()\n for (const [k, v] of Object.entries(query)) if (v !== undefined) q.set(k, String(v))\n const out = (await call('GET', `/v1/organizations${q.size ? `?${q}` : ''}`)) as { data: OrgWire[]; total_count: number }\n return { items: out.data.map(toOrganization), total: out.total_count }\n },\n async create(input) {\n return toOrganization(await data<OrgWire>('POST', '/v1/organizations',\n { name: input.name, kind: input.kind, external_id: input.externalId, metadata: input.metadata }))\n },\n async get(orgId) {\n return toOrganization(await data<OrgWire>('GET', `/v1/organizations/${id(orgId)}`))\n },\n async update(orgId, patch) {\n return toOrganization(await data<OrgWire>('PATCH', `/v1/organizations/${id(orgId)}`, patch))\n },\n async remove(orgId) {\n await call('DELETE', `/v1/organizations/${id(orgId)}`)\n },\n },\n members: {\n async list(orgId) {\n return (await data<MemberWire[]>('GET', `/v1/organizations/${id(orgId)}/members`)).map(toMember)\n },\n async add(orgId, m) {\n return toMember(await data<MemberWire>('POST', `/v1/organizations/${id(orgId)}/members`,\n { role: m.role, user_id: m.userId, email: m.email, name: m.name, locale: m.locale, client_id: clientId }))\n },\n async setRole(orgId, userId, role) {\n return toMember(await data<MemberWire>('PUT', `/v1/organizations/${id(orgId)}/members/${id(userId)}`, { role }))\n },\n async remove(orgId, userId) {\n await call('DELETE', `/v1/organizations/${id(orgId)}/members/${id(userId)}`)\n },\n },\n async invite(person) {\n // The invitation leads back to this application once it is accepted.\n const u = await data<{ id: string; email: string }>('POST', '/v1/users', { ...person, client_id: clientId })\n return { id: u.id, email: u.email }\n },\n theme: {\n async get(of = clientId) {\n return fromWire(await data<Record<string, unknown>>('GET', `/v1/oauth/clients/${id(of)}/theme`))\n },\n },\n policy: {\n async get(system) {\n return (await data<{ roles?: import('./permissions').PolicyRole[] }>('GET', `/v1/systems/${id(system)}/policy`)).roles ?? []\n },\n },\n async publicJwks() {\n if (!key) return { keys: [] }\n const { kty, n, e } = asJwk(key) ?? (await exportJWK(await signingKey()))\n return { keys: [{ kty, n, e, kid: key.keyId, alg: 'RS256', use: 'sig' }] }\n },\n }\n}\n","/**\n * The address without its trailing slashes: `https://auth.example.com/` and\n * `https://auth.example.com` name the same issuer. A loop, not `/\\/+$/`,\n * which backtracks over a long run of slashes.\n */\nexport function withoutTrailingSlashes(s: string): string {\n let end = s.length\n while (end > 0 && s.charCodeAt(end - 1) === 47) end--\n return s.slice(0, end)\n}\n","// An application's look, for Cauthy's hosted pages.\n//\n// Cauthy's pages — sign-in, sign-up, the account page — can take the colours,\n// corners, typeface and logo of the application that sends its people there,\n// so signing in reads as a page of the application. A theme is a short list of\n// values, which Cauthy checks one by one; it is never CSS.\n//\n// An application built with Stackmyth already has those values, as its\n// `--sm-*` tokens. `themeFromStackmyth` reads them out of its stylesheets.\n\nimport { withoutTrailingSlashes } from './url'\n\n/** How an application looks on Cauthy's hosted pages. Every value is optional. */\n/** One font file the application serves: a family in one weight (or a range) and one style. */\nexport interface ThemeFont {\n family: string\n /** An https address of a `.woff2` file. It must answer with `Access-Control-Allow-Origin` for Cauthy's origin. */\n url: string\n /** `400`, or `\"100 900\"` for a variable font. Default: 400. */\n weight?: number | string\n style?: 'normal' | 'italic'\n}\n\n/** What an application says on its sign-in page, in one language. */\nexport interface ThemeTexts {\n /** Replaces \"Sign in\". */\n heading?: string\n /** Replaces \"to continue to …\". */\n subheading?: string\n /** The messages of the split layout's panel, shown one at a time (up to 5). */\n panel?: string[]\n /** Links at the foot of the split layout: privacy, terms (up to 4). */\n links?: { label: string; url: string }[]\n}\n\nexport interface CauthyTheme {\n /** The page. Colours are `#rrggbb` or `rgba(r, g, b, a)`. */\n background?: string\n /** The card, and inputs. */\n surface?: string\n /** Headings and what is typed. */\n text?: string\n /** Paragraphs, labels, small print. */\n textMuted?: string\n border?: string\n /** The fields and the secondary buttons, when they are not the card's colours. */\n inputBackground?: string\n inputBorder?: string\n /** The main button, and what is written on it. */\n primary?: string\n primaryText?: string\n /** Links, and the focus ring. */\n accent?: string\n error?: string\n errorBackground?: string\n success?: string\n successBackground?: string\n /** Corners of cards and inputs, in pixels (0–40). */\n radius?: number\n /** Corners of buttons, in pixels (0–40). */\n buttonRadius?: number\n /** A CSS font-family list: the application's typeface first, a system font after it. */\n fontFamily?: string\n /** The files of the typefaces `fontFamily` names, for people who do not have them installed. */\n fonts?: ThemeFont[]\n /** An image shown where \"Cauthy\" is, over https. */\n logoUrl?: string\n /**\n * How the sign-in pages are laid out: `card` (the default, one card in the\n * middle) or `split` (the form on one side, a panel that presents the\n * application on the other).\n */\n layout?: 'card' | 'split'\n /** The colours the split layout's backdrop blends, one to four. */\n panelColors?: string[]\n /** The colour of what is written on the panel. */\n panelText?: string\n /** An https image shown over the panel's messages. */\n panelIconUrl?: string\n /** The application's own words on the sign-in page, by language (`en`, `es`). */\n texts?: Record<string, ThemeTexts>\n /**\n * The application's Stackmyth tokens (`--sm-*`), from `tokensFromStackmyth`.\n * Cauthy's pages are drawn with Stackmyth's components, so these make its\n * buttons and fields the application's own. They are laid over the named values.\n */\n tokens?: Record<string, string>\n}\n\nexport interface StackmythThemeOptions {\n /**\n * The named theme to read, when the stylesheet keeps several under\n * `[data-theme=…]` (`\"vennet\"`). Without it only what applies to every\n * page (`:root`) is read.\n */\n theme?: string\n /** Which of the application's two modes to take. Default: `light`. */\n mode?: 'light' | 'dark'\n logoUrl?: string\n}\n\nexport interface ImportedTheme {\n theme: CauthyTheme\n /** Tokens that were there and could not be carried over, and why. */\n warnings: string[]\n}\n\nconst MAX_RADIUS = 40\n\n// ── Reading custom properties out of CSS ───────────────────────────────────\n\ninterface Declaration {\n name: string\n value: string\n /** The selectors and at-rules it sits inside, outermost first. */\n within: string[]\n}\n\n// The stylesheet without its /* comments */, read in one pass. An unclosed\n// comment runs to the end, as a browser reads it.\nfunction withoutComments(css: string): string {\n let out = ''\n let i = 0\n for (;;) {\n const open = css.indexOf('/*', i)\n if (open < 0) return out + css.slice(i)\n out += css.slice(i, open)\n const close = css.indexOf('*/', open + 2)\n if (close < 0) return out\n i = close + 2\n }\n}\n\nfunction declarations(css: string): Declaration[] {\n const text = withoutComments(css)\n const out: Declaration[] = []\n const within: string[] = []\n let chunk = ''\n let quote = ''\n let depth = 0 // parentheses, so a `;` inside url(…) does not end anything\n const flush = () => {\n const m = /^\\s*(--[\\w-]+)\\s*:\\s*([\\s\\S]+?)\\s*$/.exec(chunk)\n if (m) out.push({ name: m[1], value: m[2].replace(/\\s+/g, ' ').replace(/\\s*!important$/, ''), within: [...within] })\n chunk = ''\n }\n for (const ch of text) {\n if (quote) {\n chunk += ch\n if (ch === quote) quote = ''\n continue\n }\n if (ch === '\"' || ch === \"'\") {\n quote = ch\n chunk += ch\n } else if (ch === '(') {\n depth++\n chunk += ch\n } else if (ch === ')') {\n depth = Math.max(0, depth - 1)\n chunk += ch\n } else if (ch === '{' && depth === 0) {\n within.push(chunk.trim().replace(/\\s+/g, ' '))\n chunk = ''\n } else if (ch === '}' && depth === 0) {\n flush()\n within.pop()\n } else if (ch === ';' && depth === 0) {\n flush()\n } else {\n chunk += ch\n }\n }\n return out\n}\n\nconst DARK = /prefers-color-scheme:\\s*dark|data-(mode|theme|color-scheme)=[\"']?dark|\\.dark\\b/i\nconst LIGHT = /prefers-color-scheme:\\s*light|data-(mode|theme|color-scheme)=[\"']?light|\\.light\\b/i\nconst NAMED = /data-theme=[\"']?([\\w-]+)/i\n\n/** Whether a declaration applies to the page being themed. */\nfunction applies(d: Declaration, o: Required<Pick<StackmythThemeOptions, 'mode'>> & { theme?: string }): boolean {\n for (const scope of d.within) {\n if (o.mode === 'light' && DARK.test(scope)) return false\n if (o.mode === 'dark' && LIGHT.test(scope)) return false\n const named = NAMED.exec(scope)\n if (named && !/^(dark|light)$/i.test(named[1]) && named[1] !== o.theme) return false\n // Component-level rules (`.btn { --sm-… }`) are not the page's theme;\n // the class a mode is switched with (`.dark`, as shadcn/ui does) is.\n if (!scope.startsWith('@') && !/:root|^html\\b|^body\\b|\\[data-|^\\*$|:host|^\\.(dark|light)\\b/.test(scope)) return false\n }\n return true\n}\n\n// ── Tokens ─────────────────────────────────────────────────────────────────\n\n/** What a token's value may be written with, as Cauthy checks it. */\nconst TOKEN_CHARS = /^[A-Za-z0-9 #%.,()/'\"_+*-]+$/\nconst TOKEN_FUNCS = new Set(['var', 'calc', 'min', 'max', 'clamp', 'rgb', 'rgba', 'hsl', 'hsla', 'hwb', 'lab', 'lch', 'oklab', 'oklch', 'color',\n 'color-mix', 'light-dark', 'cubic-bezier', 'steps', 'linear', 'linear-gradient', 'radial-gradient', 'conic-gradient',\n 'repeating-linear-gradient', 'repeating-radial-gradient', 'drop-shadow', 'blur', 'translate', 'translatex', 'translatey', 'scale', 'rotate'])\n\nfunction tokenValue(value: string): string | null {\n const v = value.replace(/\\s+/g, ' ').trim()\n if (v === '' || v.length > 400 || !TOKEN_CHARS.test(v)) return null\n for (const m of v.matchAll(/([A-Za-z-]+)\\(/g)) if (!TOKEN_FUNCS.has(m[1].toLowerCase())) return null\n if (/^\\(|[ ,(]\\(/.test(v)) return null\n return v\n}\n\n/** A scope that is the page's theme itself: the root, or the theme and mode attributes — never a component inside it. */\nconst THEME_SELECTOR = /^(?::root|html|body|\\[data-(?:theme|mode|color-scheme)(?:=[\"']?[\\w-]+[\"']?)?\\])$/i\n// Checked a selector at a time (split on commas and spaces) rather than with\n// one pattern over the list, which backtracks on a long one.\nconst isThemeScope = (selectors: string) => {\n const parts = selectors.split(/[\\s,]+/).filter(Boolean)\n return parts.length > 0 && parts.every((one) => THEME_SELECTOR.test(one))\n}\n\nexport interface StackmythTokens {\n /** Every `--sm-*` token the stylesheets set for the page, ready for `theme.tokens`. */\n tokens: Record<string, string>\n /** Tokens that were there and Cauthy would not take, and why. */\n warnings: string[]\n}\n\n/**\n * Reads an application's Stackmyth tokens out of its stylesheets: every\n * `--sm-*` custom property its theme sets, in the order the sheets are given\n * (a later one wins). Its own names — a brand palette the tokens point at —\n * are written in, so what comes out stands on Stackmyth's names alone.\n *\n * Cauthy's sign-in pages are drawn with Stackmyth's components: these tokens\n * are what makes them look like the application.\n */\nexport function tokensFromStackmyth(css: string | string[], options: StackmythThemeOptions = {}): StackmythTokens {\n const mode = options.mode ?? 'light'\n const all = (Array.isArray(css) ? css : [css]).flatMap(declarations)\n const named = options.theme ?? all.map((d) => d.within.map((w) => NAMED.exec(w)?.[1]).find((n) => n && !/^(dark|light)$/i.test(n))).find(Boolean)\n const vars = new Map<string, string>()\n for (const d of all) {\n if (!applies(d, { mode, theme: named })) continue\n if (!d.within.every((w) => w.startsWith('@') || isThemeScope(w))) continue\n vars.set(d.name, d.value)\n }\n // The application's own names are written in; Stackmyth's are left as references.\n const inline = (value: string, depth = 0): string | null => {\n if (depth > 16) return null\n let failed = false\n let out = value\n for (let guard = 0; guard < 64; guard++) {\n const next = out.replace(/var\\(\\s*(--(?!sm-)[\\w-]+)\\s*(?:,\\s*([^()]*(?:\\([^()]*\\)[^()]*)*))?\\)/, (_m, name: string, fallback?: string) => {\n const known = vars.get(name)\n const got = known !== undefined ? inline(known, depth + 1) : fallback !== undefined ? inline(fallback.trim(), depth + 1) : null\n if (got === null) failed = true\n return got ?? ''\n })\n if (failed) return null\n if (next === out) break\n out = next\n }\n return out\n }\n const tokens: Record<string, string> = {}\n const warnings: string[] = []\n for (const [name, raw] of vars) {\n if (!/^--sm-[a-z0-9]+(?:-[a-z0-9]+)*$/.test(name)) continue\n const written = inline(raw)\n const value = written === null ? null : tokenValue(written)\n if (value === null) warnings.push(`${name}: \"${raw.length > 60 ? raw.slice(0, 57) + '…' : raw}\" is not a value Cauthy takes`)\n else tokens[name] = value\n }\n if (Object.keys(tokens).length === 0) warnings.push('no --sm-* token was found in these stylesheets')\n return { tokens, warnings }\n}\n\n// ── Values ─────────────────────────────────────────────────────────────────\n\nfunction resolve(value: string, vars: Map<string, string>, seen = 0): string | null {\n if (seen > 16) return null\n let unresolved = false\n // Innermost var() first: fallbacks may hold another var().\n let out = value\n for (let guard = 0; guard < 32 && /var\\(/.test(out); guard++) {\n out = out.replace(/var\\(\\s*(--[\\w-]+)\\s*(?:,\\s*([^()]*(?:\\([^()]*\\)[^()]*)*))?\\)/, (_m, name: string, fallback?: string) => {\n const known = vars.get(name)\n const next = known !== undefined ? resolve(known, vars, seen + 1) : fallback !== undefined ? resolve(fallback.trim(), vars, seen + 1) : null\n if (next === null) unresolved = true\n return next ?? ''\n })\n if (unresolved) return null\n }\n return /var\\(/.test(out) ? null : out.trim()\n}\n\nconst clamp01 = (n: number) => Math.min(1, Math.max(0, n))\nconst hex2 = (n: number) => Math.round(clamp01(n) * 255).toString(16).padStart(2, '0')\nconst gamma = (c: number) => (c <= 0.0031308 ? 12.92 * c : 1.055 * Math.pow(c, 1 / 2.4) - 0.055)\n\nfunction out(r: number, g: number, b: number, a = 1): string {\n if (a >= 1) return `#${hex2(r)}${hex2(g)}${hex2(b)}`\n return `rgba(${Math.round(clamp01(r) * 255)}, ${Math.round(clamp01(g) * 255)}, ${Math.round(clamp01(b) * 255)}, ${Math.round(clamp01(a) * 1000) / 1000})`\n}\n\nconst alpha = (s: string | undefined) => (s === undefined ? 1 : s.endsWith('%') ? parseFloat(s) / 100 : parseFloat(s))\n\nconst KEYWORDS: Record<string, string> = { white: '#ffffff', black: '#000000' }\n\n/** A colour as Cauthy takes it — `#rrggbb` or `rgba(…)` — or null when it is none it can read. */\nexport function toColor(value: string): string | null {\n const v = value.trim().toLowerCase()\n if (KEYWORDS[v]) return KEYWORDS[v]\n if (/^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/.test(v)) return v\n let m = /^rgba?\\(\\s*([\\d.]+%?)[\\s,]+([\\d.]+%?)[\\s,]+([\\d.]+%?)(?:\\s*[,/]\\s*([\\d.]+%?))?\\s*\\)$/.exec(v)\n if (m) {\n const ch = (s: string) => (s.endsWith('%') ? parseFloat(s) / 100 : parseFloat(s) / 255)\n return out(ch(m[1]), ch(m[2]), ch(m[3]), alpha(m[4]))\n }\n m = /^hsla?\\(\\s*([\\d.]+)(?:deg)?[\\s,]+([\\d.]+)%[\\s,]+([\\d.]+)%(?:\\s*[,/]\\s*([\\d.]+%?))?\\s*\\)$/.exec(v)\n if (m) {\n const h = ((parseFloat(m[1]) % 360) + 360) % 360\n const s = parseFloat(m[2]) / 100\n const l = parseFloat(m[3]) / 100\n const f = (n: number) => {\n const k = (n + h / 30) % 12\n return l - s * Math.min(l, 1 - l) * Math.max(-1, Math.min(k - 3, 9 - k, 1))\n }\n return out(f(0), f(8), f(4), alpha(m[4]))\n }\n m = /^oklch\\(\\s*([\\d.]+%?)\\s+([\\d.]+%?)\\s+([\\d.]+)(?:deg)?(?:\\s*\\/\\s*([\\d.]+%?))?\\s*\\)$/.exec(v)\n if (m) {\n const L = m[1].endsWith('%') ? parseFloat(m[1]) / 100 : parseFloat(m[1])\n const C = m[2].endsWith('%') ? (parseFloat(m[2]) / 100) * 0.4 : parseFloat(m[2])\n const H = (parseFloat(m[3]) * Math.PI) / 180\n const a = C * Math.cos(H)\n const b = C * Math.sin(H)\n const l = Math.pow(L + 0.3963377774 * a + 0.2158037573 * b, 3)\n const mm = Math.pow(L - 0.1055613458 * a - 0.0638541728 * b, 3)\n const s = Math.pow(L - 0.0894841775 * a - 1.291485548 * b, 3)\n return out(\n gamma(4.0767416621 * l - 3.3077115913 * mm + 0.2309699292 * s),\n gamma(-1.2684380046 * l + 2.6097574011 * mm - 0.3413193965 * s),\n gamma(-0.0041960863 * l - 0.7034186147 * mm + 1.707614701 * s),\n alpha(m[4]),\n )\n }\n return null\n}\n\n/** A length in pixels, within what Cauthy takes, or null. */\nfunction toRadius(value: string): number | null {\n const m = /^([\\d.]+)(px|rem|em)?$/.exec(value.trim())\n if (!m) return null\n const px = parseFloat(m[1]) * (m[2] === 'rem' || m[2] === 'em' ? 16 : 1)\n return Number.isFinite(px) ? Math.min(MAX_RADIUS, Math.max(0, Math.round(px))) : null\n}\n\n/** A font list as Cauthy takes it, or null. */\nfunction toFont(value: string): string | null {\n const v = value.trim()\n return /^[A-Za-z0-9 ,'\"_-]{1,200}$/.test(v) && (v.match(/\"/g)?.length ?? 0) % 2 === 0 && (v.match(/'/g)?.length ?? 0) % 2 === 0 ? v : null\n}\n\n// ── Stackmyth ──────────────────────────────────────────────────────────────\n\n/** Which Stackmyth token each value of a theme is read from, first found wins. */\nconst COLORS: [keyof CauthyTheme, string[]][] = [\n ['background', ['--sm-bg-surface', '--sm-surface']],\n ['surface', ['--sm-bg-surface-raised', '--sm-surface-raised']],\n ['text', ['--sm-text-primary', '--sm-surface-text']],\n ['textMuted', ['--sm-text-secondary']],\n ['border', ['--sm-border-default', '--sm-surface-border']],\n ['primary', ['--sm-primary', '--sm-bg-interactive']],\n ['primaryText', ['--sm-primary-text', '--sm-text-inverse']],\n ['accent', ['--sm-text-brand', '--sm-border-focus', '--sm-accent']],\n ['error', ['--sm-error-soft-text', '--sm-error']],\n ['errorBackground', ['--sm-error-soft']],\n ['success', ['--sm-success-soft-text', '--sm-success']],\n ['successBackground', ['--sm-success-soft']],\n]\n\n/**\n * Reads an application's Stackmyth theme out of its stylesheets.\n *\n * Give it the CSS that declares the tokens, in the order the application\n * loads it — Stackmyth's own (`@stackmyth/core/core.vars.css`, or a theme\n * file) and then the application's brand file that re-points them. Tokens\n * that point at the application's own variables are followed. The\n * application's dark mode is left out unless asked for.\n */\nexport function themeFromStackmyth(css: string | string[], options: StackmythThemeOptions = {}): ImportedTheme {\n const o = { mode: options.mode ?? 'light', theme: options.theme }\n const vars = new Map<string, string>()\n for (const sheet of Array.isArray(css) ? css : [css]) {\n for (const d of declarations(sheet)) if (applies(d, o)) vars.set(d.name, d.value)\n }\n const theme: CauthyTheme = {}\n const warnings: string[] = []\n\n const read = <T>(tokens: string[], to: (v: string) => T | null, what: string): T | undefined => {\n for (const token of tokens) {\n const raw = vars.get(token)\n if (raw === undefined) continue\n const value = resolve(raw, vars)\n const got = value === null ? null : to(value)\n if (got !== null) return got\n warnings.push(`${token}: \"${raw}\" is not ${what} Cauthy can take`)\n }\n return undefined\n }\n\n for (const [field, tokens] of COLORS) {\n const c = read(tokens, toColor, 'a colour')\n if (c !== undefined) (theme as Record<string, unknown>)[field] = c\n }\n const radius = read(['--sm-radius-container', '--sm-radius-md'], toRadius, 'a length')\n if (radius !== undefined) theme.radius = radius\n const button = read(['--sm-radius-interactive', '--sm-radius-sm'], toRadius, 'a length')\n if (button !== undefined) theme.buttonRadius = button\n const font = read(['--sm-font-family'], toFont, 'a font list')\n if (font !== undefined) theme.fontFamily = font\n if (options.logoUrl) theme.logoUrl = options.logoUrl\n\n if (vars.size === 0) warnings.push('no custom properties were found: is this the stylesheet that declares the --sm-* tokens?')\n else if (![...vars.keys()].some((k) => k.startsWith('--sm-'))) warnings.push('no --sm-* token was found in these stylesheets')\n return { theme, warnings }\n}\n\n// ── Any stylesheet ─────────────────────────────────────────────────────────\n\n/** The values of a theme a stylesheet can say. */\nexport type ThemeField =\n | 'background' | 'surface' | 'text' | 'textMuted' | 'border' | 'inputBackground' | 'inputBorder'\n | 'primary' | 'primaryText' | 'accent' | 'error' | 'errorBackground' | 'success' | 'successBackground'\n | 'radius' | 'buttonRadius' | 'fontFamily'\n\n/** How a stylesheet names its look: Stackmyth's tokens, shadcn/ui's (and Tailwind's), or the application's own. */\nexport type CssFormat = 'stackmyth' | 'shadcn' | 'custom'\n\nexport interface CssThemeOptions {\n /** Which names to read. Default: `auto`, told from the stylesheet itself. */\n format?: CssFormat | 'auto'\n /** Which of the application's two modes to take. Default: `light`. */\n mode?: 'light' | 'dark'\n /** The named theme to read, when the stylesheet keeps several under `[data-theme=…]`. */\n theme?: string\n /** For `custom`: the variable each value is read from, `{ primary: '--brand' }`. */\n map?: Partial<Record<ThemeField, string>>\n}\n\nexport interface CssImportedTheme extends ImportedTheme {\n /** The names that were read. */\n format: CssFormat\n}\n\nconst RADII: ThemeField[] = ['radius', 'buttonRadius']\n\n/** shadcn/ui's names, as Tailwind 3 (`--primary`) and Tailwind 4 (`--color-primary`) write them. */\nconst SHADCN: [ThemeField, string[]][] = [\n ['background', ['--background', '--color-background']],\n ['surface', ['--card', '--color-card', '--popover', '--color-popover']],\n ['text', ['--foreground', '--color-foreground']],\n ['textMuted', ['--muted-foreground', '--color-muted-foreground']],\n ['border', ['--border', '--color-border']],\n ['inputBorder', ['--input', '--color-input']],\n ['primary', ['--primary', '--color-primary']],\n ['primaryText', ['--primary-foreground', '--color-primary-foreground']],\n ['accent', ['--ring', '--color-ring', '--primary', '--color-primary']],\n ['error', ['--destructive', '--color-destructive']],\n ['radius', ['--radius']],\n ['buttonRadius', ['--radius']],\n ['fontFamily', ['--font-sans', '--font-family']],\n]\n\n/** A colour as shadcn/ui writes it on Tailwind 3 — `222.2 84% 4.9%`, the inside of hsl() — or any other. */\nfunction shadcnColor(value: string): string | null {\n return /^[\\d.]+(?:deg)?\\s+[\\d.]+%\\s+[\\d.]+%(?:\\s*\\/\\s*[\\d.]+%?)?$/.test(value.trim()) ? toColor(`hsl(${value.trim()})`) : toColor(value)\n}\n\n/** Every custom property a stylesheet sets for the page, the last one winning. */\nfunction pageVariables(css: string | string[], mode: 'light' | 'dark', theme?: string): Map<string, string> {\n const vars = new Map<string, string>()\n for (const sheet of Array.isArray(css) ? css : [css]) {\n for (const d of declarations(sheet)) if (applies(d, { mode, theme })) vars.set(d.name, d.value)\n }\n return vars\n}\n\n/** The custom properties a stylesheet sets for the page, by name: what a person picks from to map their own. */\nexport function cssVariables(css: string | string[], options: Pick<CssThemeOptions, 'mode' | 'theme'> = {}): string[] {\n return [...pageVariables(css, options.mode ?? 'light', options.theme).keys()].sort()\n}\n\n/**\n * Reads an application's look out of its stylesheets, whatever names it uses:\n * Stackmyth's tokens, shadcn/ui's (`--primary`, `--radius`, on Tailwind 3 or\n * 4), or the application's own variables given in `map`. What comes out is a\n * theme of named values, never CSS.\n */\nexport function themeFromCss(css: string | string[], options: CssThemeOptions = {}): CssImportedTheme {\n const mode = options.mode ?? 'light'\n const vars = pageVariables(css, mode, options.theme)\n const names = [...vars.keys()]\n let format: CssFormat\n if (options.format && options.format !== 'auto') format = options.format\n else if (options.map && Object.keys(options.map).length > 0) format = 'custom'\n else if (names.some((n) => n.startsWith('--sm-'))) format = 'stackmyth'\n else if (names.some((n) => /^--(color-)?(primary|background|foreground)$/.test(n))) format = 'shadcn'\n else format = 'custom'\n\n if (format === 'stackmyth') return { ...themeFromStackmyth(css, { mode, theme: options.theme }), format }\n\n const spec: [ThemeField, string[]][] = format === 'shadcn'\n ? SHADCN\n : Object.entries(options.map ?? {}).filter(([, v]) => v).map(([k, v]) => [k as ThemeField, [String(v).startsWith('--') ? String(v) : `--${v}`]])\n const theme: CauthyTheme = {}\n const warnings: string[] = []\n for (const [field, tokens] of spec) {\n for (const token of tokens) {\n const raw = vars.get(token)\n if (raw === undefined) continue\n const value = resolve(raw, vars)\n const got = value === null ? null\n : RADII.includes(field) ? toRadius(value)\n : field === 'fontFamily' ? toFont(value)\n : format === 'shadcn' ? shadcnColor(value) : toColor(value)\n if (got !== null) {\n (theme as Record<string, unknown>)[field] = got\n break\n }\n warnings.push(`${token}: \"${raw.length > 60 ? raw.slice(0, 57) + '…' : raw}\" is not ${RADII.includes(field) ? 'a length' : field === 'fontFamily' ? 'a font list' : 'a colour'} Cauthy can take`)\n }\n }\n if (vars.size === 0) warnings.push('no custom properties were found in these stylesheets')\n else if (format === 'custom' && spec.length === 0) warnings.push('these stylesheets use names of their own: say which variable each value is read from')\n return { theme, warnings, format }\n}\n\n// ── On the application's own screens ───────────────────────────────────────\n\n/**\n * A theme as the CSS variables of `cauthy-auth/styles.css` (`--cauthy-*`), for\n * the forms an application shows on its own pages. The page's own background,\n * the layout and the words are Cauthy's pages' matter, and left out.\n */\nexport function themeVariables(theme: CauthyTheme): Record<string, string> {\n const vars: Record<string, string> = {}\n const put = (name: string, v: string | number | undefined) => {\n if (v === undefined || v === '') return\n vars[`--cauthy-${name}`] = typeof v === 'number' ? `${v}px` : v\n }\n put('surface', theme.surface)\n put('text', theme.text)\n put('text-muted', theme.textMuted)\n put('border', theme.border)\n put('input-background', theme.inputBackground)\n put('input-border', theme.inputBorder)\n put('primary', theme.primary)\n put('primary-text', theme.primaryText)\n put('accent', theme.accent)\n put('error', theme.error)\n put('error-background', theme.errorBackground)\n put('success', theme.success)\n put('success-background', theme.successBackground)\n put('radius', theme.radius)\n put('button-radius', theme.buttonRadius)\n put('font', theme.fontFamily)\n return vars\n}\n\n// ── Sending it to Cauthy ───────────────────────────────────────────────────\n\n/** A theme as Cauthy's API names its values. */\nexport function toWire(theme: CauthyTheme): Record<string, unknown> {\n const names: Record<keyof CauthyTheme, string> = {\n background: 'background', surface: 'surface', text: 'text', textMuted: 'text_muted', border: 'border',\n primary: 'primary', primaryText: 'primary_text', accent: 'accent', error: 'error', errorBackground: 'error_background',\n success: 'success', successBackground: 'success_background', radius: 'radius', buttonRadius: 'button_radius',\n fontFamily: 'font_family', logoUrl: 'logo_url', fonts: 'fonts', layout: 'layout', panelColors: 'panel_colors',\n panelText: 'panel_text', panelIconUrl: 'panel_icon_url', texts: 'texts', inputBackground: 'input_background', inputBorder: 'input_border', tokens: 'tokens',\n }\n const wire: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(theme)) {\n if (v === undefined || v === '' || (Array.isArray(v) && v.length === 0)) continue\n wire[names[k as keyof CauthyTheme]] = v\n }\n return wire\n}\n\n/** A theme as Cauthy answers it, in this package's names. */\nexport function fromWire(wire: Record<string, unknown>): CauthyTheme {\n const names: Record<string, keyof CauthyTheme> = {\n background: 'background', surface: 'surface', text: 'text', text_muted: 'textMuted', border: 'border',\n primary: 'primary', primary_text: 'primaryText', accent: 'accent', error: 'error', error_background: 'errorBackground',\n success: 'success', success_background: 'successBackground', radius: 'radius', button_radius: 'buttonRadius',\n font_family: 'fontFamily', logo_url: 'logoUrl', fonts: 'fonts', layout: 'layout', panel_colors: 'panelColors',\n panel_text: 'panelText', panel_icon_url: 'panelIconUrl', texts: 'texts', input_background: 'inputBackground', input_border: 'inputBorder', tokens: 'tokens',\n }\n const theme: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(wire ?? {})) if (names[k] && v !== undefined && v !== null && v !== '') theme[names[k]] = v\n return theme as CauthyTheme\n}\n\nexport interface PushThemeOptions {\n /** Cauthy's address. Default: `CAUTHY_ISSUER`. */\n issuer?: string\n /** The application's client id. Default: `CAUTHY_CLIENT_ID`. */\n clientId?: string\n /** The workspace's slug. Default: `CAUTHY_TENANT`. */\n tenant?: string\n /**\n * A personal access token with `oauth_clients:manage`. Default:\n * `CAUTHY_TOKEN`. It belongs in the deploy pipeline, never in the application.\n */\n token?: string\n theme: CauthyTheme\n fetch?: typeof fetch\n}\n\n/**\n * Gives the application its look on Cauthy's pages. It replaces the theme: a\n * value left out goes back to Cauthy's own. Run it when the brand changes —\n * from a script or the deploy — not on every request.\n */\nexport async function pushTheme(o: PushThemeOptions): Promise<void> {\n const env = (n: string) => (typeof process !== 'undefined' ? process.env?.[n] : undefined)\n const issuer = withoutTrailingSlashes(o.issuer ?? env('CAUTHY_ISSUER') ?? '')\n const clientId = o.clientId ?? env('CAUTHY_CLIENT_ID') ?? ''\n const tenant = o.tenant ?? env('CAUTHY_TENANT') ?? ''\n const token = o.token ?? env('CAUTHY_TOKEN') ?? ''\n for (const [name, v] of Object.entries({ CAUTHY_ISSUER: issuer, CAUTHY_CLIENT_ID: clientId, CAUTHY_TENANT: tenant, CAUTHY_TOKEN: token })) {\n if (v === '') throw new Error(`cauthy-auth: ${name} is required to push a theme`)\n }\n const res = await (o.fetch ?? fetch)(`${issuer}/v1/oauth/clients/${encodeURIComponent(clientId)}/theme`, {\n method: 'PUT',\n headers: { authorization: `Bearer ${token}`, 'x-tenant-key': tenant, 'content-type': 'application/json' },\n body: JSON.stringify(toWire(o.theme)),\n })\n if (!res.ok) {\n const body = (await res.json().catch(() => null)) as { errors?: { message?: string }[] } | null\n throw new Error(`cauthy-auth: Cauthy refused the theme (${res.status}): ${body?.errors?.[0]?.message ?? res.statusText}`)\n }\n}\n","/** How an application is set up to sign its people in with Cauthy. */\nexport interface CauthyOptions {\n /** Cauthy's public address, e.g. `https://id.example.com`. Default: `CAUTHY_ISSUER`. */\n issuer?: string\n /** The application's OAuth client id. Default: `CAUTHY_CLIENT_ID`. */\n clientId?: string\n /** Its secret, when the client is confidential. Default: `CAUTHY_CLIENT_SECRET`. */\n clientSecret?: string\n /**\n * The key the session cookie is encrypted with: any string of 32 characters\n * or more, kept on the server. Default: `CAUTHY_SECRET`.\n */\n secret?: string\n /**\n * The system this application is, as its organizations are filed under in\n * Cauthy (`\"pondari\"`). When set, a session's organizations are that\n * system's. Default: `CAUTHY_SYSTEM`.\n */\n system?: string\n /**\n * The workspace's slug in Cauthy. Needed for the application's own sign-in\n * screens (`signIn.email`, `signUp.email`…), which sign people in through\n * the application's server instead of Cauthy's page. Default: `CAUTHY_TENANT`.\n */\n tenant?: string\n /** Where the routes are mounted. Default: `/api/auth`. */\n basePath?: string\n /**\n * The application's own public origin (`https://app.example.com`), for the\n * redirect URI. Default: the origin of each request, which is right unless\n * a proxy hides it.\n */\n baseURL?: string\n /** Where a person lands after signing in, when no `return_to` was asked. Default: `/`. */\n afterSignIn?: string\n /** Where a person lands after signing out. Default: `/`. */\n afterSignOut?: string\n /** Name of the session cookie. Default: `cauthy_session`. */\n cookieName?: string\n /**\n * A key the application proves who it is with when it acts on its own\n * (`auth.system`), instead of its secret. Default: `CAUTHY_SYSTEM_KEY` and\n * `CAUTHY_SYSTEM_KEY_ID`.\n */\n systemKey?: import('./system').SystemKey\n /**\n * The application's own pages for what arrives by mail. A link Cauthy mails\n * opens the page named here, with a `token` to give back; with none, it\n * opens Cauthy's own page.\n *\n * signIn where `<SignIn />` is: a sign-in link opens it\n * resetPassword where `<ResetPassword />` is\n * verifyEmail where `<VerifyEmail />` is\n */\n pages?: { signIn?: string; resetPassword?: string; verifyEmail?: string }\n /**\n * The address of the person a request comes from, passed on to Cauthy so\n * its limits on attempts count the person and not this server. Default: the\n * last address in `X-Forwarded-For`, which is the one the proxy in front of\n * the application wrote. With several proxies, or none, give your own.\n */\n clientIp?: (request: Request) => string | undefined\n /** `fetch` to reach Cauthy with. Default: the global one. */\n fetch?: typeof fetch\n}\n\n/** The person signed in. Every moment is UTC. */\nexport interface SessionUser {\n id: string\n email: string\n name: string\n emailVerified: boolean\n /**\n * True when the account ran out of time to confirm its address: let it read\n * and refuse its writes.\n */\n restricted: boolean\n /** When an unconfirmed address stops being enough (ISO 8601, UTC), if there is a deadline. */\n emailVerifyBy?: string\n /** The language the person reads in (\"es\", \"en-US\"), when Cauthy knows it. */\n locale?: string\n /** A guest: a visitor's session before they sign up. No email; `account.upgrade` makes it an account, keeping `id`. */\n isAnonymous?: boolean\n}\n\n/** A value JSON can carry. What crosses from server to browser is typed as this, never `unknown`. */\nexport type JsonValue = string | number | boolean | null | JsonValue[] | { [key: string]: JsonValue }\n\n/** An organization the person belongs to, with their role in it. */\nexport interface SessionOrganization {\n id: string\n system: string\n name: string\n kind: string\n externalId?: string\n role: string\n /** What the system keeps about the organization, as it filed it in Cauthy. */\n metadata: Record<string, JsonValue>\n /**\n * What the person may do here, as \"resource:action\" entries (\"*\" is any):\n * their role's permissions, what it inherits, and anything given to them\n * apart from it. Absent when the system keeps no catalog of roles in Cauthy.\n * Check with `can(organization, resource, action)`.\n */\n permissions?: string[]\n /** What the person is denied here, whatever else allows it. */\n denied?: string[]\n}\n\n/** A signed-in person, as the server sees them. */\nexport interface Session {\n user: SessionUser\n /** The Cauthy tenant the account is of. */\n tenantId: string\n /** The roles the account holds in that tenant. */\n roles: string[]\n /**\n * Cauthy's access token for this person: send it as `Authorization: Bearer`\n * to another service that verifies Cauthy's tokens. Never give it to the browser.\n */\n accessToken: string\n /** When the access token expires and the session is checked with Cauthy again (ISO 8601, UTC). */\n expiresAt: string\n}\n\n/** What the browser is told of a session: who, and their organizations — never a token. */\nexport interface PublicSession {\n user: SessionUser\n tenantId: string\n roles: string[]\n organizations: SessionOrganization[]\n expiresAt: string\n}\n\n/** Why there is no session. */\nexport type SessionStatus =\n | 'authenticated'\n | 'unauthenticated' // nobody is signed in\n | 'expired' // signed in, but the session must be renewed first (see `Cauthy.resolve`)\n\nexport class CauthyConfigError extends Error {\n constructor(message: string) {\n super(`cauthy-auth: ${message}`)\n this.name = 'CauthyConfigError'\n }\n}\n","// What a sign-in or sign-up form is checked for before anything is sent, in\n// the browser and again on the server: the same rules in both places, so the\n// form says what the server would.\n\nexport type AuthField = 'email' | 'password' | 'newPassword' | 'name' | 'code' | 'organization'\n\n/** A value of a form that cannot be sent as it is. */\nexport interface FieldProblem {\n field: AuthField\n /** Stable, for translating: `required`, `invalid_email`, `too_short`, `too_long`. */\n code: 'required' | 'invalid_email' | 'too_short' | 'too_long'\n message: string\n}\n\n/** The shortest password Cauthy takes for a new account. */\nexport const MIN_PASSWORD = 8\nconst MAX_PASSWORD = 256\nconst MAX_NAME = 120\n\n// One @, something on each side, a dot in the domain, no spaces: what catches\n// a typo. Whether the address exists is Cauthy's to find out.\nconst EMAIL = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n\nexport function checkEmail(value: unknown): FieldProblem | null {\n const v = typeof value === 'string' ? value.trim() : ''\n if (v === '') return { field: 'email', code: 'required', message: 'Enter your email address.' }\n if (v.length > 254 || !EMAIL.test(v)) return { field: 'email', code: 'invalid_email', message: 'That does not look like an email address.' }\n return null\n}\n\n/** A password being typed to sign in: only that there is one. */\nexport function checkPassword(value: unknown): FieldProblem | null {\n if (typeof value !== 'string' || value === '') return { field: 'password', code: 'required', message: 'Enter your password.' }\n if (value.length > MAX_PASSWORD) return { field: 'password', code: 'too_long', message: 'That password is too long.' }\n return null\n}\n\n/** A password being chosen for a new account. */\nexport function checkNewPassword(value: unknown): FieldProblem | null {\n const basic = checkPassword(value)\n if (basic) return basic\n if ((value as string).length < MIN_PASSWORD) {\n return { field: 'password', code: 'too_short', message: `Use at least ${MIN_PASSWORD} characters.` }\n }\n return null\n}\n\nexport function checkName(value: unknown): FieldProblem | null {\n if (value === undefined || value === null || value === '') return null\n if (typeof value !== 'string' || value.trim().length > MAX_NAME) return { field: 'name', code: 'too_long', message: `Use at most ${MAX_NAME} characters.` }\n return null\n}\n\n/** The company's name a sign-up carries when the application's system makes an organization per sign-up. */\nexport const MAX_ORGANIZATION = 120\n\nexport function checkOrganization(value: unknown, required = false): FieldProblem | null {\n const v = typeof value === 'string' ? value.trim() : ''\n if (v === '') return required ? { field: 'organization', code: 'required', message: \"Enter your company's name.\" } : null\n if (v.length > MAX_ORGANIZATION) return { field: 'organization', code: 'too_long', message: `Use at most ${MAX_ORGANIZATION} characters.` }\n return null\n}\n\nexport function checkCode(value: unknown): FieldProblem | null {\n const v = typeof value === 'string' ? value.trim() : ''\n if (v === '') return { field: 'code', code: 'required', message: 'Enter the code.' }\n if (v.length > 40) return { field: 'code', code: 'too_long', message: 'That is not a code.' }\n return null\n}\n\n/** The first problem of a form, or null when it can be sent. */\nexport function firstProblem(...checks: (FieldProblem | null)[]): FieldProblem | null {\n return checks.find((c) => c !== null) ?? null\n}\n","// Hearing from Cauthy: verifying a webhook delivery.\n//\n// Cauthy signs every delivery with its own key — the one its tokens are\n// signed with, published at /.well-known/jwks.json — so there is no secret to\n// receive, store or rotate. Verifying is one call:\n//\n// const event = await auth.webhook(request) // throws if it is not Cauthy's\n//\n// What is checked: the signature, against Cauthy's published keys; that the\n// delivery was meant for THIS endpoint (a signature anyone can verify must say\n// who it is for); that it is recent; and that the body is, byte for byte, the\n// one that was signed.\n\nimport { createRemoteJWKSet, jwtVerify, type JWTVerifyGetKey } from 'jose'\nimport type { JsonValue } from './types'\nimport { withoutTrailingSlashes } from './url'\n\n/** Something that happened in Cauthy, as a subscriber is told. Moments are UTC. */\nexport interface CauthyEvent {\n /** This delivery's id: the same event delivered again carries the same one. */\n id: string\n /** What happened: \"organization.member_added\". */\n type: string\n tenantId: string\n createdAt: string\n /** The person it happened to, when it is about one. */\n userId?: string\n /** Who did it. */\n actorId?: string\n /** What the event says: for an organization, its id, system, external_id, role… */\n data: Record<string, JsonValue>\n}\n\nexport class CauthyWebhookError extends Error {\n constructor(readonly reason: string) {\n super(`cauthy-auth: webhook refused: ${reason}`)\n this.name = 'CauthyWebhookError'\n }\n}\n\nexport interface VerifyWebhookOptions {\n /** Cauthy's address. Default: `CAUTHY_ISSUER`. */\n issuer?: string\n /**\n * This endpoint's own public address, exactly as it is registered in Cauthy.\n * Default: the request's URL, which is right unless a proxy changes it.\n */\n url?: string\n /** Cauthy's keys. Default: fetched from the issuer and cached. */\n jwks?: JWTVerifyGetKey\n /** The moment to verify at. Default: now. */\n now?: Date\n}\n\nconst keys = new Map<string, JWTVerifyGetKey>()\n\nfunction keysOf(issuer: string): JWTVerifyGetKey {\n let set = keys.get(issuer)\n if (set === undefined) {\n set = createRemoteJWKSet(new URL(`${issuer}/.well-known/jwks.json`), { cooldownDuration: 30_000 })\n keys.set(issuer, set)\n }\n return set\n}\n\nconst hex = (s: unknown) => (typeof s === 'string' && s !== '' ? s : undefined)\n\n/**\n * Verifies a delivery and answers the event it carries. Throws\n * `CauthyWebhookError` for anything that is not a delivery Cauthy made for\n * this endpoint just now: answer it 401 and nothing else.\n */\nexport async function verifyWebhook(request: Request, options: VerifyWebhookOptions = {}): Promise<CauthyEvent> {\n const env = typeof process !== 'undefined' ? process.env?.CAUTHY_ISSUER : undefined\n const issuer = withoutTrailingSlashes(options.issuer ?? env ?? '')\n if (issuer === '') throw new CauthyWebhookError('issuer (CAUTHY_ISSUER) is not set')\n const signature = request.headers.get('x-cauthy-signature-jwt')\n if (!signature) throw new CauthyWebhookError('no signature')\n\n // The bytes as they arrived: what was signed is their hash, not a re-encoding.\n const raw = new Uint8Array(await request.arrayBuffer())\n const audience = options.url ?? request.url.split('?')[0]\n\n let claims: Record<string, unknown>\n try {\n const verified = await jwtVerify(signature, options.jwks ?? keysOf(issuer), {\n algorithms: ['RS256'],\n audience,\n typ: 'cauthy-webhook+jwt',\n requiredClaims: ['exp', 'iat', 'jti', 'body_sha256'],\n currentDate: options.now,\n clockTolerance: 30,\n })\n claims = verified.payload as Record<string, unknown>\n } catch (err) {\n throw new CauthyWebhookError(err instanceof Error ? err.message : 'bad signature')\n }\n // Signed by Cauthy, for this issuer: Cauthy's own address, or the\n // workspace's custom domain (domain_iss) when that is the issuer here.\n if (claims.iss !== issuer && claims.domain_iss !== issuer) {\n throw new CauthyWebhookError('unexpected \"iss\" claim value')\n }\n\n // Not from the future either: a clock that far off is not Cauthy's.\n const now = Math.floor((options.now ?? new Date()).getTime() / 1000)\n if (typeof claims.iat !== 'number' || claims.iat > now + 30) throw new CauthyWebhookError('signed in the future')\n\n const digest = new Uint8Array(await crypto.subtle.digest('SHA-256', raw))\n let b64 = ''\n for (const b of digest) b64 += String.fromCharCode(b)\n const hash = btoa(b64).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')\n if (hash !== claims.body_sha256) throw new CauthyWebhookError('the body is not the one that was signed')\n\n let body: Record<string, any>\n try {\n body = JSON.parse(new TextDecoder().decode(raw))\n } catch {\n throw new CauthyWebhookError('the body is not JSON')\n }\n // The envelope and the signature must tell the same story.\n if (body.id !== claims.jti || body.event !== claims.evt || body.tenant_id !== claims.tid) {\n throw new CauthyWebhookError('the body and its signature disagree')\n }\n const inner = (body.data ?? {}) as Record<string, any>\n return {\n id: String(body.id),\n type: String(body.event),\n tenantId: String(body.tenant_id),\n createdAt: String(inner.created_at ?? body.created_at ?? ''),\n ...(hex(inner.user_id) ? { userId: inner.user_id } : {}),\n ...(hex(inner.actor_id) ? { actorId: inner.actor_id } : {}),\n data: (inner.data ?? {}) as Record<string, JsonValue>,\n }\n}\n","// Sign in with Cauthy, held by the application's own server.\n//\n// The application mounts one route (`handler`) and asks who is there\n// (`getSession`). Signing in, signing up, second factors, passkeys, recovering\n// a password and the account page are Cauthy's pages: this sends the browser\n// to them and keeps what comes back in an encrypted, httpOnly cookie. There is\n// no database and no screen to build.\n//\n// The session is Cauthy's short-lived access token plus the refresh token that\n// renews it. When the access token expires the session is renewed with Cauthy,\n// which is where an account disabled there, or signed out everywhere, stops\n// being signed in here — within minutes, with nothing to synchronise.\n\nimport { clearParts, readCookies, readParts, writeCookie, writeParts, type CookieAttributes } from './cookies'\nimport { keyOf, seal, unseal } from './seal'\nimport { createSystem, type CauthySystem } from './system'\nimport { checkCode, checkEmail, checkName, checkNewPassword, checkPassword, firstProblem, type FieldProblem, checkOrganization } from './validate'\nimport { verifyWebhook, type CauthyEvent, type VerifyWebhookOptions } from './webhook'\nimport {\n CauthyConfigError,\n type CauthyOptions,\n type JsonValue,\n type PublicSession,\n type Session,\n type SessionOrganization,\n type SessionStatus,\n type SessionUser,\n} from './types'\nimport { withoutTrailingSlashes } from './url'\n\n/** What the session cookie holds. Short names: it rides every request. */\ninterface Stored {\n at: string // access token\n rt: string // refresh token\n exp: number // when the access token expires, epoch seconds\n u: SessionUser\n tid: string\n roles: string[]\n}\n\n/** What the sign-in in progress holds, between leaving for Cauthy and coming back. */\ninterface Flow {\n state: string\n verifier: string\n returnTo: string\n}\n\nconst SESSION_DAYS = 30\n// How long a sign-in may sit open at Cauthy and still be finished here. The\n// same hour Cauthy keeps its side of it.\nconst FLOW_SECONDS = 3600\n/** How long a sign-in that had to start again is remembered, so it starts again once and not forever. */\nconst AGAIN_SECONDS = 120\n/** Renew this long before the access token runs out, so a request never carries one about to. */\nconst SKEW_SECONDS = 30\nconst ORGANIZATIONS_TTL_MS = 60_000\n/** How long the workspace's look is kept before Cauthy is asked again. */\nconst LOOK_TTL_MS = 60_000\n/** A provider's id: `google`, `linkedin_oidc`, or one the workspace defined itself, `custom:<slug>`. */\nconst PROVIDER_ID = /^(custom:)?[a-z0-9_-]{1,40}$/\n\n/** The provider named in a route, as written or percent-encoded (`custom%3Aacme`). */\nfunction providerIn(segment: string): string {\n try {\n return decodeURIComponent(segment)\n } catch {\n return ''\n }\n}\n\n/** What `resolve` answers: who is there, and the cookies that must go back. */\nexport interface Resolved {\n session: Session | null\n status: SessionStatus\n /** `Set-Cookie` values to send with the response. Empty when nothing changed. */\n cookies: string[]\n}\n\nexport interface Cauthy {\n /** Serves the routes under `basePath`: login, callback, session, refresh, logout, account. */\n handler(request: Request): Promise<Response>\n /**\n * Who is signed in, or null.\n *\n * Give it the response's headers and a session that needs renewing is\n * renewed on the spot, its new cookie added to them. Without them an\n * expired session reads as null (see `status`): renewing changes the\n * cookie, and a cookie nobody sends back is a session lost.\n */\n getSession(request: Request, responseHeaders?: Headers): Promise<Session | null>\n /** Whether somebody is signed in, nobody is, or the session must be renewed first. */\n status(request: Request): Promise<SessionStatus>\n /**\n * The session, renewed when it has to be, and the cookies to send back.\n * The caller MUST send `cookies` with its response.\n */\n resolve(request: Request): Promise<Resolved>\n /**\n * For a route only a signed-in person may see: the session, or the response\n * to give instead — a redirect to sign in (or to renew) for a page, a 401\n * for anything else.\n */\n protect(request: Request): Promise<{ session: Session; response?: undefined } | { session?: undefined; response: Response }>\n /** The organizations the person belongs to (of `system`, when set), with their role in each. */\n organizations(session: Session): Promise<SessionOrganization[]>\n /**\n * Verifies a webhook delivery from Cauthy and answers the event it carries;\n * throws `CauthyWebhookError` for anything else. No secret is involved: the\n * delivery is signed with Cauthy's own key.\n */\n webhook(request: Request, options?: Pick<VerifyWebhookOptions, 'jwks' | 'now' | 'url'>): Promise<CauthyEvent>\n /**\n * The application acting on its own, with no person's token: its\n * organizations, their members, invitations. Needs the client's secret, or\n * `systemKey`.\n */\n system: CauthySystem\n /** What the browser may be told of a session. */\n toPublic(session: Session): Promise<PublicSession>\n /** Paths of this application that start a sign-in, a sign-out, or open the account page. */\n urls: { signIn(returnTo?: string): string; signOut(): string; account(returnTo?: string): string; session: string }\n options: Readonly<Required<Pick<CauthyOptions, 'issuer' | 'clientId' | 'basePath' | 'afterSignIn' | 'afterSignOut' | 'cookieName'>>>\n}\n\nfunction env(name: string): string | undefined {\n return typeof process !== 'undefined' ? process.env?.[name] : undefined\n}\n\nfunction b64url(bytes: Uint8Array): string {\n let s = ''\n for (const b of bytes) s += String.fromCharCode(b)\n return btoa(s).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')\n}\n\nfunction random(bytes = 32): string {\n return b64url(crypto.getRandomValues(new Uint8Array(bytes)))\n}\n\n/** A path of this application, and nothing else: never another site, never `//host`. */\nfunction localPath(candidate: string | null | undefined, fallback: string): string {\n if (!candidate || !candidate.startsWith('/') || candidate.startsWith('//') || candidate.includes('\\\\')) return fallback\n return candidate\n}\n\nfunction json(body: unknown, status = 200, headers?: Headers): Response {\n const h = headers ?? new Headers()\n h.set('content-type', 'application/json; charset=utf-8')\n h.set('cache-control', 'no-store')\n return new Response(JSON.stringify(body), { status, headers: h })\n}\n\nfunction redirect(location: string, cookies: string[] = []): Response {\n const h = new Headers({ location, 'cache-control': 'no-store' })\n for (const c of cookies) h.append('set-cookie', c)\n return new Response(null, { status: 302, headers: h })\n}\n\nexport function createCauthy(given: CauthyOptions = {}): Cauthy {\n const issuer = withoutTrailingSlashes(given.issuer ?? env('CAUTHY_ISSUER') ?? '')\n const clientId = given.clientId ?? env('CAUTHY_CLIENT_ID') ?? ''\n const clientSecret = given.clientSecret ?? env('CAUTHY_CLIENT_SECRET')\n const secret = given.secret ?? env('CAUTHY_SECRET') ?? ''\n const system = given.system ?? env('CAUTHY_SYSTEM') ?? ''\n const tenant = given.tenant ?? env('CAUTHY_TENANT') ?? ''\n if (!/^https?:\\/\\//.test(issuer)) throw new CauthyConfigError('issuer (CAUTHY_ISSUER) must be Cauthy\\'s address, e.g. https://id.example.com')\n if (clientId === '') throw new CauthyConfigError('clientId (CAUTHY_CLIENT_ID) is required')\n if (secret.length < 32) throw new CauthyConfigError('secret (CAUTHY_SECRET) must be at least 32 characters: it encrypts the session cookie')\n\n const basePath = '/' + (given.basePath ?? '/api/auth').replace(/^\\/+|\\/+$/g, '')\n const afterSignIn = localPath(given.afterSignIn, '/')\n const afterSignOut = localPath(given.afterSignOut, '/')\n const cookieName = given.cookieName ?? 'cauthy_session'\n const flowCookie = `${cookieName}_flow`\n const againCookie = `${cookieName}_again`\n const stepCookie = `${cookieName}_step`\n const doFetch: typeof fetch = (...args) => (given.fetch ?? fetch)(...args)\n const key = keyOf(secret)\n const pages = {\n signIn: given.pages?.signIn ? localPath(given.pages.signIn, '/') : undefined,\n resetPassword: given.pages?.resetPassword ? localPath(given.pages.resetPassword, '/') : undefined,\n verifyEmail: given.pages?.verifyEmail ? localPath(given.pages.verifyEmail, '/') : undefined,\n }\n const ownSystem = createSystem({ issuer, clientId, clientSecret, key: given.systemKey, fetch: given.fetch })\n\n const originOf = (request: Request) => withoutTrailingSlashes(given.baseURL ?? new URL(request.url).origin)\n const attrs = (request: Request, maxAge: number): CookieAttributes => ({ secure: originOf(request).startsWith('https://'), maxAge })\n\n // ── Talking to Cauthy ────────────────────────────────────────────────────\n\n async function token(form: Record<string, string>): Promise<{ ok: true; body: any } | { ok: false; ended: boolean }> {\n const body = new URLSearchParams({ client_id: clientId, ...form })\n if (clientSecret) body.set('client_secret', clientSecret)\n try {\n const res = await doFetch(`${issuer}/v1/oauth/token`, {\n method: 'POST',\n headers: { 'content-type': 'application/x-www-form-urlencoded', accept: 'application/json' },\n body,\n })\n if (res.ok) return { ok: true, body: await res.json() }\n // 4xx is Cauthy's answer: the grant is no good. Anything else is a\n // failure to ask, and says nothing about the session.\n return { ok: false, ended: res.status >= 400 && res.status < 500 }\n } catch {\n return { ok: false, ended: false }\n }\n }\n\n async function userinfo(accessToken: string): Promise<{ u: SessionUser; tid: string; roles: string[] } | null> {\n try {\n const res = await doFetch(`${issuer}/v1/oauth/userinfo`, { headers: { authorization: `Bearer ${accessToken}` } })\n if (!res.ok) return null\n const b = (await res.json()) as Record<string, any>\n return {\n tid: String(b.tid ?? ''),\n roles: Array.isArray(b.roles) ? b.roles.filter((r: unknown) => typeof r === 'string') : [],\n u: {\n id: String(b.sub ?? ''),\n email: String(b.email ?? ''),\n name: String(b.name ?? ''),\n emailVerified: b.email_verified === true,\n restricted: b.restricted === true,\n ...(typeof b.email_verify_by === 'string' ? { emailVerifyBy: b.email_verify_by } : {}),\n ...(typeof b.locale === 'string' && b.locale !== '' ? { locale: b.locale } : {}),\n ...(b.anonymous === true ? { isAnonymous: true } : {}),\n },\n }\n } catch {\n return null\n }\n }\n\n /** What Cauthy's answer to a token request becomes in the cookie. */\n async function stored(body: any): Promise<Stored | null> {\n if (typeof body?.access_token !== 'string' || typeof body?.refresh_token !== 'string') return null\n const who = await userinfo(body.access_token)\n if (who === null || who.u.id === '') return null\n const lifetime = typeof body.expires_in === 'number' && body.expires_in > 0 ? body.expires_in : 300\n return { at: body.access_token, rt: body.refresh_token, exp: Math.floor(Date.now() / 1000) + lifetime, ...who }\n }\n\n function toSession(s: Stored): Session {\n return { user: s.u, tenantId: s.tid, roles: s.roles, accessToken: s.at, expiresAt: new Date(s.exp * 1000).toISOString() }\n }\n\n // ── The cookie ───────────────────────────────────────────────────────────\n\n async function read(request: Request): Promise<{ had: Map<string, string>; value: Stored | null; present: boolean }> {\n const had = readCookies(request.headers.get('cookie'))\n const raw = readParts(had, cookieName)\n if (raw === null) return { had, value: null, present: false }\n const value = await unseal<Stored>(raw, await key)\n const sound = value !== null && typeof value.at === 'string' && typeof value.rt === 'string' && typeof value.exp === 'number'\n return { had, value: sound ? value : null, present: true }\n }\n\n async function write(request: Request, s: Stored, had: Map<string, string>): Promise<string[]> {\n return writeParts(cookieName, await seal(s, await key), attrs(request, SESSION_DAYS * 86_400), had)\n }\n\n const fresh = (s: Stored) => s.exp - Date.now() / 1000 > SKEW_SECONDS\n\n // One renewal per refresh token at a time in this process: requests that\n // arrive together share it. (Across processes Cauthy gives a few seconds'\n // grace to the same token, for the same reason.)\n const renewing = new Map<string, Promise<Stored | 'ended' | 'unreachable'>>()\n\n function renew(was: Stored): Promise<Stored | 'ended' | 'unreachable'> {\n let running = renewing.get(was.rt)\n if (running === undefined) {\n const rt = was.rt\n running = (async (): Promise<Stored | 'ended' | 'unreachable'> => {\n const res = await token({ grant_type: 'refresh_token', refresh_token: rt })\n if (!res.ok) return res.ended ? 'ended' : 'unreachable'\n const next = await stored(res.body)\n if (next !== null) return next\n // Renewed, but who it is could not be read just now. The new tokens\n // are kept all the same — the old refresh token is spent, and losing\n // its successor would lose the session — with what was known before.\n if (typeof res.body?.access_token !== 'string' || typeof res.body?.refresh_token !== 'string') return 'unreachable'\n const lifetime = typeof res.body.expires_in === 'number' && res.body.expires_in > 0 ? res.body.expires_in : 300\n return { ...was, at: res.body.access_token, rt: res.body.refresh_token, exp: Math.floor(Date.now() / 1000) + lifetime }\n })()\n renewing.set(rt, running)\n // A renewal that worked is remembered for a moment, for requests still\n // arriving with the old cookie; one that could not ask is tried again\n // by the next request.\n void running.then((result) => {\n if (result === 'unreachable') return renewing.delete(rt)\n const timer = setTimeout(() => renewing.delete(rt), 5_000)\n ;(timer as { unref?: () => void }).unref?.()\n })\n }\n return running\n }\n\n async function resolve(request: Request): Promise<Resolved> {\n const { had, value, present } = await read(request)\n if (value === null) {\n // A cookie this key did not make (a rotated secret, a tampered value) is cleared.\n return { session: null, status: 'unauthenticated', cookies: present ? clearParts(cookieName, attrs(request, 0), had) : [] }\n }\n if (fresh(value)) return { session: toSession(value), status: 'authenticated', cookies: [] }\n\n const renewed = await renew(value)\n if (renewed === 'ended') {\n return { session: null, status: 'unauthenticated', cookies: clearParts(cookieName, attrs(request, 0), had) }\n }\n // Cauthy could not be asked: the cookie stays as it is, and the next\n // request tries again. Nobody is let in on an expired token meanwhile.\n if (renewed === 'unreachable') return { session: null, status: 'expired', cookies: [] }\n return { session: toSession(renewed), status: 'authenticated', cookies: await write(request, renewed, had) }\n }\n\n async function getSession(request: Request, responseHeaders?: Headers): Promise<Session | null> {\n if (responseHeaders === undefined) {\n const { value } = await read(request)\n return value !== null && fresh(value) ? toSession(value) : null\n }\n const r = await resolve(request)\n for (const c of r.cookies) responseHeaders.append('set-cookie', c)\n return r.session\n }\n\n async function status(request: Request): Promise<SessionStatus> {\n const { value } = await read(request)\n if (value === null) return 'unauthenticated'\n return fresh(value) ? 'authenticated' : 'expired'\n }\n\n // ── Organizations ────────────────────────────────────────────────────────\n\n const orgCache = new Map<string, { at: number; value: SessionOrganization[] }>()\n\n async function organizations(session: Session): Promise<SessionOrganization[]> {\n const hit = orgCache.get(session.accessToken)\n if (hit && Date.now() - hit.at < ORGANIZATIONS_TTL_MS) return hit.value\n const url = `${issuer}/v1/oauth/organizations${system ? `?system=${encodeURIComponent(system)}` : ''}`\n const res = await doFetch(url, { headers: { authorization: `Bearer ${session.accessToken}` } })\n if (!res.ok) throw new Error(`cauthy-auth: reading organizations: ${res.status}`)\n const body = (await res.json()) as { data?: Record<string, any>[] }\n const value = (body.data ?? []).map(\n (o): SessionOrganization => ({\n id: String(o.id),\n system: String(o.system ?? ''),\n name: String(o.name ?? ''),\n kind: String(o.kind ?? ''),\n role: String(o.role ?? ''),\n metadata: (o.metadata as Record<string, JsonValue>) ?? {},\n ...(o.external_id ? { externalId: String(o.external_id) } : {}),\n ...(Array.isArray(o.permissions) ? { permissions: o.permissions.map(String), denied: Array.isArray(o.denied) ? o.denied.map(String) : [] } : {}),\n }),\n )\n if (orgCache.size > 5_000) orgCache.clear()\n orgCache.set(session.accessToken, { at: Date.now(), value })\n return value\n }\n\n // The application's own identity, as `auth.system`. A change it makes to who\n // belongs where (a new member, a new role, an organization gone) empties the\n // organizations read above: a person added a moment ago sees the\n // organization on the next page, not a minute later.\n const forgetting = <A extends unknown[], R>(fn: (...args: A) => Promise<R>) =>\n async (...args: A): Promise<R> => {\n const out = await fn(...args)\n orgCache.clear()\n return out\n }\n const systemThatRefreshes: CauthySystem = {\n ...ownSystem,\n organizations: {\n ...ownSystem.organizations,\n update: forgetting(ownSystem.organizations.update),\n remove: forgetting(ownSystem.organizations.remove),\n },\n members: {\n ...ownSystem.members,\n add: forgetting(ownSystem.members.add),\n setRole: forgetting(ownSystem.members.setRole),\n remove: forgetting(ownSystem.members.remove),\n },\n }\n\n async function toPublic(session: Session): Promise<PublicSession> {\n let orgs: SessionOrganization[] = []\n try {\n orgs = await organizations(session)\n } catch {\n // The person is signed in all the same; their organizations come back on the next read.\n }\n return { user: session.user, tenantId: session.tenantId, roles: session.roles, organizations: orgs, expiresAt: session.expiresAt }\n }\n\n // ── Routes ───────────────────────────────────────────────────────────────\n\n const urls = {\n signIn: (returnTo?: string) => `${basePath}/login${returnTo ? `?return_to=${encodeURIComponent(returnTo)}` : ''}`,\n signOut: () => `${basePath}/logout`,\n account: (returnTo?: string) => `${basePath}/account${returnTo ? `?return_to=${encodeURIComponent(returnTo)}` : ''}`,\n session: `${basePath}/session`,\n }\n\n async function login(request: Request, url: URL): Promise<Response> {\n const flow: Flow = { state: random(), verifier: random(48), returnTo: localPath(url.searchParams.get('return_to'), afterSignIn) }\n const challenge = b64url(new Uint8Array(await crypto.subtle.digest('SHA-256', new TextEncoder().encode(flow.verifier))))\n const q = new URLSearchParams({\n client_id: clientId,\n redirect_uri: `${originOf(request)}${basePath}/callback`,\n response_type: 'code',\n state: flow.state,\n code_challenge: challenge,\n code_challenge_method: 'S256',\n })\n // What the application may ask of the sign-in page: to ask again, and a language.\n const prompt = url.searchParams.get('prompt')\n if (prompt === 'login' || prompt === 'none') q.set('prompt', prompt)\n const locale = url.searchParams.get('locale') ?? url.searchParams.get('ui_locales')\n if (locale && /^[a-zA-Z-]{2,10}$/.test(locale)) q.set('ui_locales', locale)\n // An application whose own page cannot use the person's passkey sends\n // them to Cauthy's for that step alone: a page that asks for the passkey\n // and nothing else, and comes straight back.\n let passkey = ''\n if (url.searchParams.get('method') === 'passkey') {\n q.set('method', 'passkey')\n passkey = '#passkey' // what a Cauthy from before that page reads\n }\n return redirect(`${issuer}/v1/oauth/authorize?${q}${passkey}`, [\n writeCookie(flowCookie, await seal(flow, await key), attrs(request, FLOW_SECONDS)),\n ])\n }\n\n function failed(request: Request, reason: string): Response {\n const h = new Headers({ 'content-type': 'text/plain; charset=utf-8', 'cache-control': 'no-store' })\n h.append('set-cookie', writeCookie(flowCookie, '', attrs(request, 0)))\n h.append('set-cookie', writeCookie(againCookie, '', attrs(request, 0)))\n return new Response(`Sign-in could not be completed (${reason}). Go back and try again.`, { status: 400, headers: h })\n }\n\n async function callback(request: Request, url: URL): Promise<Response> {\n const had = readCookies(request.headers.get('cookie'))\n const sealed = had.get(flowCookie)\n const flow = sealed ? await unseal<Flow>(sealed, await key) : null\n // The answer must be to a question THIS browser asked: without that, a\n // stranger's link could sign a person in to the stranger's account.\n if (flow === null || url.searchParams.get('state') !== flow.state) {\n // Not this browser's question — or its question was asked so long ago\n // that it is forgotten: the page sat open, or the answer is to an older\n // tab's. Nobody is signed in by it; the sign-in starts again, once. The\n // person is still signed in at Cauthy, so they are not asked twice.\n if (had.get(againCookie) === undefined) {\n const back = flow?.returnTo ?? afterSignIn\n return redirect(`${basePath}/login?return_to=${encodeURIComponent(back)}`, [writeCookie(againCookie, '1', attrs(request, AGAIN_SECONDS))])\n }\n return failed(request, 'state_mismatch')\n }\n const error = url.searchParams.get('error')\n if (error !== null) {\n // prompt=none and nobody signed in: not an error, just \"nobody\".\n if (error === 'login_required') return redirect(flow.returnTo, [writeCookie(flowCookie, '', attrs(request, 0))])\n // The person went back from Cauthy's page: to the sign-in they came from.\n if (error === 'access_denied') {\n const back = pages.signIn ?? flow.returnTo\n return redirect(`${back}${back.includes('?') ? '&' : '?'}auth_error=cancelled`, [writeCookie(flowCookie, '', attrs(request, 0))])\n }\n return failed(request, error.slice(0, 60))\n }\n const code = url.searchParams.get('code')\n if (!code) return failed(request, 'no_code')\n const res = await token({\n grant_type: 'authorization_code',\n code,\n redirect_uri: `${originOf(request)}${basePath}/callback`,\n code_verifier: flow.verifier,\n })\n const s = res.ok ? await stored(res.body) : null\n if (s === null) return failed(request, 'exchange_failed')\n return redirect(flow.returnTo, [...(await write(request, s, had)), writeCookie(flowCookie, '', attrs(request, 0)), writeCookie(againCookie, '', attrs(request, 0))])\n }\n\n async function logout(request: Request): Promise<Response> {\n const { had, value } = await read(request)\n if (value !== null) {\n // Best effort: the session is over here whether or not Cauthy heard.\n const body = new URLSearchParams({ client_id: clientId, token: value.rt })\n if (clientSecret) body.set('client_secret', clientSecret)\n await doFetch(`${issuer}/v1/oauth/revoke`, {\n method: 'POST',\n headers: { 'content-type': 'application/x-www-form-urlencoded' },\n body,\n }).catch(() => undefined)\n orgCache.delete(value.at)\n }\n // Then through Cauthy, which ends its own session in this browser too:\n // otherwise the next \"sign in\" would walk straight back in.\n const q = new URLSearchParams({ client_id: clientId, post_logout_redirect_uri: `${originOf(request)}${afterSignOut}` })\n return redirect(`${issuer}/v1/oauth/logout?${q}`, clearParts(cookieName, attrs(request, 0), had))\n }\n\n // ── The application's own screens ────────────────────────────────────────\n //\n // The application draws its sign-in, with its own components; these routes\n // do the work behind it. The browser talks to the application's server and\n // to nobody else: the password goes from the form to here and from here to\n // Cauthy, the tokens Cauthy answers with go into the same encrypted cookie\n // as ever, and nothing the browser could keep is sent back to it.\n\n /** How long a sign-in waits for its second step, or for a provider to answer. */\n const STEP_SECONDS = 600\n /** How long a passkey ceremony waits for the person: Cauthy's own limit. */\n const PASSKEY_SECONDS = 300\n\n /** How an account takes its second step, as Cauthy says it. */\n const factorsOf = (d: any) => ({\n totp: d?.totp === true,\n phone: d?.phone ? { number: String(d.phone.number ?? ''), channel: String(d.phone.channel ?? 'sms') } : null,\n phoneChannels: Array.isArray(d?.phone_channels) ? d.phone_channels.map(String) : [],\n })\n\n /** What the browser answered a passkey ceremony with, as JSON. */\n const isCredential = (v: unknown): v is Record<string, unknown> =>\n typeof v === 'object' && v !== null && !Array.isArray(v) && typeof (v as { id?: unknown }).id === 'string' && typeof (v as { response?: unknown }).response === 'object'\n\n const passkeyOf = (d: any) => ({\n id: String(d?.id ?? ''), name: String(d?.nickname ?? ''),\n kind: ['security_key', 'synced', 'device'].includes(d?.kind) ? d.kind : 'unknown', createdAt: String(d?.created_at ?? ''), lastUsedAt: d?.last_used_at ? String(d.last_used_at) : null,\n })\n\n const UUID = /^[0-9a-f-]{36}$/i\n\n /** An organization the person belongs to, with what they may do with its people. */\n const seatOf = (d: any) => ({\n id: String(d?.id ?? ''), system: String(d?.system ?? ''), name: String(d?.name ?? ''), kind: String(d?.kind ?? ''), role: String(d?.role ?? ''),\n can: { readMembers: d?.can?.read_members === true, manageMembers: d?.can?.manage_members === true },\n })\n /** A person of an organization, as a member who may see them reads it. */\n const orgMemberOf = (d: any) => ({\n userId: String(d?.user_id ?? ''), email: String(d?.email ?? ''), name: String(d?.name ?? ''), role: String(d?.role ?? ''),\n status: String(d?.status ?? ''), invited: d?.invited === true, manager: d?.manager === true, you: d?.you === true, since: String(d?.since ?? ''),\n })\n /** A role of the organization's system that a member may give. */\n const orgRoleOf = (d: any) => ({\n role: String(d?.role ?? ''), name: String(d?.name ?? ''), description: String(d?.description ?? ''), manager: d?.manager === true,\n })\n\n /** An AI agent the person connected, as Cauthy says it. */\n const agentOf = (d: any) => ({\n id: String(d?.id ?? ''),\n name: String(d?.agent?.name ?? ''),\n redirectHost: String(d?.agent?.redirect_host ?? ''),\n resource: { name: String(d?.resource?.name ?? ''), uri: String(d?.resource?.uri ?? '') },\n scopes: Array.isArray(d?.scopes) ? d.scopes.map((s: any) => ({ name: String(s?.name ?? ''), description: String(s?.description ?? '') })) : [],\n connectedAt: String(d?.created_at ?? ''),\n lastUsedAt: String(d?.last_used_at ?? ''),\n })\n\n interface Step {\n /** `mfa`: Cauthy asked for a code. `social`: a provider is answering. `link`: a provider is answering to be linked to the signed-in account. `passkey`/`enrol`: a passkey ceremony is under way on the page. `sso`: the person's company is answering; `token` is the PKCE verifier. */\n kind: 'mfa' | 'social' | 'code' | 'link' | 'passkey' | 'enrol' | 'sso' | 'upgrade'\n token: string\n provider?: string\n returnTo: string\n }\n\n const problem = (status: number, code: string, message: string, field?: string, headers?: Headers) =>\n json({ error: { code, message, ...(field ? { field } : {}) } }, status, headers)\n\n const invalid = (p: FieldProblem) => problem(400, p.code, p.message, p.field)\n\n /** A request this application's own page made: never another site's form. */\n function ownRequest(request: Request): boolean {\n const origin = request.headers.get('origin')\n if (origin !== null) return origin === originOf(request) || origin === new URL(request.url).origin\n // No Origin: a browser sends one on every cross-site POST, so this is a\n // same-origin form of an old browser, or not a browser at all.\n return (request.headers.get('sec-fetch-site') ?? 'same-origin') === 'same-origin'\n }\n\n async function body(request: Request): Promise<Record<string, unknown> | null> {\n if (!(request.headers.get('content-type') ?? '').includes('application/json')) return null\n try {\n const b = (await request.json()) as unknown\n return typeof b === 'object' && b !== null && !Array.isArray(b) ? (b as Record<string, unknown>) : null\n } catch {\n return null\n }\n }\n\n // Every person signing in here reaches Cauthy from this server's address.\n // So the application says whose request it is passing on, and proves it is\n // a system of the workspace with its own token: Cauthy believes the address\n // from nobody else. The proof goes even when the address is unknown (no\n // proxy in front, as in development): it also tells Cauthy which\n // application signed the person in. An application that is no system\n // passes nothing on.\n const clientIp = given.clientIp ?? ((request: Request) => request.headers.get('x-forwarded-for')?.split(',').pop()?.trim() || undefined)\n let noProofUntil = 0\n async function passedOn(request: Request): Promise<Record<string, string>> {\n if (Date.now() < noProofUntil) return {}\n const ip = clientIp(request)\n try {\n const proof = { 'x-cauthy-system-token': await ownSystem.token() }\n return ip ? { ...proof, 'x-cauthy-client-ip': ip } : proof\n } catch {\n // Not a system, or Cauthy is not answering: ask again in a while.\n noProofUntil = Date.now() + 5 * 60_000\n return {}\n }\n }\n\n /** Asks Cauthy's own API, as this workspace's application. */\n async function ask(request: Request, method: string, path: string, payload?: unknown, page?: string, bearer?: string): Promise<{ status: number; data: any; error?: { code: string; message: string } }> {\n try {\n const res = await doFetch(`${issuer}${path}`, {\n method,\n headers: {\n 'x-tenant-key': tenant,\n accept: 'application/json',\n // A link Cauthy mails opens the application's page for it when it\n // has one; otherwise Cauthy's own. Either way in the reader's language.\n ...(page ? { 'x-cauthy-link-to': `${originOf(request)}${page}` } : { 'x-cauthy-links': 'hosted' }),\n // Whose request it is: what Cauthy mails goes in this application's\n // name, under its logo.\n ...(clientId ? { 'x-cauthy-client-id': clientId } : {}),\n ...(await passedOn(request)),\n ...(bearer ? { authorization: `Bearer ${bearer}` } : {}),\n // The answer to the workspace's Turnstile challenge, from the\n // person's browser: Cauthy checks it at the doors that ask for it.\n ...(request.headers.get('x-cauthy-captcha') ? { 'x-captcha-token': request.headers.get('x-cauthy-captcha') as string } : {}),\n ...(request.headers.get('accept-language') ? { 'accept-language': request.headers.get('accept-language') as string } : {}),\n // The language the application says its person reads, over the browser's.\n ...(request.headers.get('x-cauthy-locale') ? { 'x-cauthy-locale': request.headers.get('x-cauthy-locale') as string } : {}),\n ...(request.headers.get('user-agent') ? { 'user-agent': request.headers.get('user-agent') as string } : {}),\n ...(payload === undefined ? {} : { 'content-type': 'application/json' }),\n },\n body: payload === undefined ? undefined : JSON.stringify(payload),\n })\n const b = res.status === 204 || res.status === 202 ? null : ((await res.json().catch(() => null)) as any)\n if (res.ok) return { status: res.status, data: b?.data ?? b }\n const first = b?.errors?.[0]\n return { status: res.status, data: null, error: { code: String(first?.code ?? 'error'), message: String(first?.message ?? 'The request could not be completed.') } }\n } catch {\n return { status: 503, data: null, error: { code: 'unavailable', message: 'Sign-in is unavailable right now. Try again in a moment.' } }\n }\n }\n\n const accountOf = (d: any) => ({\n id: String(d?.id ?? ''), email: String(d?.email ?? ''), name: String(d?.name ?? ''),\n emailVerified: d?.email_verified === true, hasPassword: d?.has_password === true, mfaEnabled: d?.mfa_enabled === true,\n })\n\n /**\n * Who is signed in, for a route about their own account: their token, and\n * the cookie to send back when the session had to be renewed. Nobody signed\n * in gets the 401 to answer with.\n */\n async function signedInAs(request: Request): Promise<{ token: string; kept: Stored | null; headers: Headers } | { response: Response }> {\n const r = await resolve(request)\n const headers = new Headers()\n for (const c of r.cookies) headers.append('set-cookie', c)\n if (r.session === null) return { response: problem(401, 'unauthenticated', 'Sign in first.', undefined, headers) }\n // `kept` is the session as the request's cookie holds it, or null when it\n // was renewed just now: then the cookies above carry the new one.\n return { token: r.session.accessToken, kept: r.cookies.length === 0 ? (await read(request)).value : null, headers }\n }\n\n /** Cauthy answered with tokens: the person is signed in here. */\n async function signedIn(request: Request, tokens: any, extra: string[] = [], more: Record<string, unknown> = {}): Promise<Response> {\n const s = await stored(tokens)\n if (s === null) return problem(502, 'unavailable', 'Sign-in is unavailable right now. Try again in a moment.')\n const h = new Headers()\n for (const c of [...(await write(request, s, readCookies(request.headers.get('cookie')))), ...extra]) h.append('set-cookie', c)\n return json({ status: 'signed_in', session: await toPublic(toSession(s)), ...more }, 200, h)\n }\n\n let lookCache: { until: number; look: Record<string, unknown> } | null = null\n\n async function ownRoute(request: Request, url: URL, route: string): Promise<Response | null> {\n const post = request.method === 'POST'\n const own = ['/sign-in/email', '/sign-in/mfa', '/sign-up/email', '/forgot-password', '/reset-password', '/verify-email', '/sign-in/magic-link', '/sign-in/magic-link/verify', '/sign-in/email-code', '/me', '/me/password', '/me/mfa/setup', '/me/mfa/verify', '/me/mfa/disable', '/me/mfa/recovery-codes', '/me/mfa/factors', '/me/mfa/phone', '/me/mfa/phone/verify', '/me/mfa/phone/remove', '/sign-in/mfa/methods', '/sign-in/mfa/send', '/sign-in/mfa/push', '/sign-in/mfa/push/events', '/sign-in/mfa/push/finish', '/me/sessions', '/me/sessions/end', '/me/email', '/me/identities', '/me/identities/unlink', '/sign-out', '/methods', '/look',\n '/sign-in/passkey/begin', '/sign-in/passkey/finish', '/sign-in/google-one-tap/begin', '/sign-in/google-one-tap', '/me/passkeys', '/me/passkeys/add/begin', '/me/passkeys/add/finish', '/me/passkeys/remove', '/me/agents', '/me/agents/disconnect',\n '/sign-in/anonymous', '/me/upgrade',\n '/me/organizations', '/me/organizations/members', '/me/organizations/roles', '/me/organizations/members/add', '/me/organizations/members/role', '/me/organizations/members/remove', '/me/organizations/members/invite'].includes(route) ||\n route.startsWith('/sign-in/social/') || route.startsWith('/callback/') || route.startsWith('/me/identities/link/') || route.startsWith('/me/upgrade/social/') ||\n route === '/sign-in/sso' || route === '/sign-in/sso/discover' || route === '/sso/callback'\n if (!own) return null\n if (tenant === '') {\n return problem(500, 'not_configured', 'cauthy-auth: tenant (CAUTHY_TENANT) is required for the application\\'s own sign-in screens')\n }\n\n // How the forms look, as a person set it in Cauthy's dashboard. Kept a\n // minute: every form of every page reads it.\n if (route === '/look' && !post) {\n if (lookCache === null || lookCache.until < Date.now()) {\n const res = await ask(request, 'GET', `/v1/auth/look/${encodeURIComponent(clientId)}`)\n lookCache = { until: Date.now() + LOOK_TTL_MS, look: res.error ? {} : (res.data ?? {}) }\n }\n return json(lookCache.look)\n }\n\n // What the screen may offer: which providers, whether people may register.\n if (route === '/methods' && !post) {\n const [providers, settings, place, sso] = await Promise.all([\n ask(request, 'GET', '/v1/auth/social/providers'),\n ask(request, 'GET', '/v1/auth/settings'),\n ask(request, 'GET', `/v1/auth/webauthn/place?origin=${encodeURIComponent(originOf(request))}`),\n ask(request, 'GET', '/v1/auth/sso/connections'),\n ])\n const list = Array.isArray(providers.data) ? providers.data : []\n // Where the person uses a passkey: on this page, or on Cauthy's for that\n // step alone. A Cauthy that cannot say yet has them on its page.\n const here = place.data?.here === true\n return json({\n providers: list.map((p: any) => ({ id: String(p.provider ?? p.id ?? ''), name: String(p.label ?? p.name ?? p.provider ?? '') })).filter((p: { id: string }) => p.id !== ''),\n signUp: settings.data?.allow_signup !== false,\n // The application's system makes an organization per sign-up: the form asks the company's name.\n ...(settings.data?.signup?.organization?.ask === true\n ? { organization: { ask: true, required: settings.data.signup.organization.required === true } }\n : {}),\n // A sign-in link needs a page of the application to open.\n magicLink: settings.data?.allow_magic_link === true && pages.signIn !== undefined,\n passkey: place.error ? true : here || place.data?.on_cauthy === true,\n passkeyHere: here,\n passkeyOnCauthy: place.error ? true : place.data?.on_cauthy === true,\n // A company's sign-in, found by the person's work address.\n sso: Array.isArray(sso.data) && sso.data.some((c: any) => c?.discoverable === true),\n ...(settings.data?.captcha_enabled === true && settings.data?.captcha_site_key ? { captchaSiteKey: String(settings.data.captcha_site_key) } : {}),\n })\n }\n\n // The person's company: to its IdP and back. Cauthy ends the flow on\n // this site's page with a code, which only the browser holding the\n // sealed PKCE verifier can trade for the session.\n if (route === '/sign-in/sso' && !post) {\n const returnTo = localPath(url.searchParams.get('return_to'), afterSignIn)\n const failed = (code: string) => redirect(`${returnTo}${returnTo.includes('?') ? '&' : '?'}auth_error=${encodeURIComponent(code)}`)\n const email = (url.searchParams.get('email') ?? '').trim()\n const connection = (url.searchParams.get('connection') ?? '').trim()\n if (email === '' && connection === '') return failed('sso_not_found')\n const verifier = random(48)\n const challenge = b64url(new Uint8Array(await crypto.subtle.digest('SHA-256', new TextEncoder().encode(verifier))))\n const callback = `${basePath}/sso/callback`\n const started = await ask(request, 'POST', '/v1/auth/sso/start', {\n ...(connection ? { connection } : { email }),\n redirect_uri: `${originOf(request)}${callback}`, code_challenge: challenge,\n }, callback)\n if (started.error || typeof started.data?.redirect_url !== 'string') return failed(started.error?.code ?? 'sso_unavailable')\n const step: Step = { kind: 'sso', token: verifier, returnTo }\n return redirect(started.data.redirect_url, [writeCookie(stepCookie, await seal(step, await key), attrs(request, STEP_SECONDS))])\n }\n if (route === '/sso/callback' && !post) {\n const sealed = readCookies(request.headers.get('cookie')).get(stepCookie)\n const step = sealed ? await unseal<Step>(sealed, await key) : null\n const clear = writeCookie(stepCookie, '', attrs(request, 0))\n const back = step?.returnTo ?? afterSignIn\n const failedTo = (code: string) => redirect(`${back}${back.includes('?') ? '&' : '?'}auth_error=${encodeURIComponent(code)}`, [clear])\n if (step === null || step.kind !== 'sso') return failedTo('state_mismatch')\n const refused = url.searchParams.get('error')\n if (refused) return failedTo(refused)\n const code = url.searchParams.get('code')\n if (!code) return failedTo('sso_failed')\n const done = await ask(request, 'POST', '/v1/auth/sso/token', { code, redirect_uri: `${originOf(request)}${basePath}/sso/callback`, code_verifier: step.token })\n if (done.error) return failedTo(done.error.code)\n const s = await stored(done.data)\n if (s === null) return failedTo('unavailable')\n return redirect(back, [...(await write(request, s, readCookies(request.headers.get('cookie')))), clear])\n }\n\n // A provider: to it and back. The state is this browser's, kept sealed.\n if (route.startsWith('/sign-in/social/') && !post) {\n const provider = providerIn(route.slice('/sign-in/social/'.length))\n if (!PROVIDER_ID.test(provider)) return new Response('Not found', { status: 404 })\n const returnTo = localPath(url.searchParams.get('return_to'), afterSignIn)\n const callback = `${basePath}/callback/${provider}`\n // The callback is named as this client's page, so a provider that\n // answers through Cauthy's relay (Apple) may return the browser to it.\n const started = await ask(request, 'GET', `/v1/auth/social/${provider}?redirect_uri=${encodeURIComponent(`${originOf(request)}${callback}`)}`, undefined, callback)\n if (started.error || typeof started.data?.redirect_url !== 'string') {\n return redirect(`${returnTo}${returnTo.includes('?') ? '&' : '?'}auth_error=${encodeURIComponent(started.error?.code ?? 'provider_unavailable')}`)\n }\n const step: Step = { kind: 'social', token: String(started.data.state ?? ''), provider, returnTo }\n return redirect(started.data.redirect_url, [writeCookie(stepCookie, await seal(step, await key), attrs(request, STEP_SECONDS))])\n }\n if (route.startsWith('/callback/') && !post) {\n const provider = providerIn(route.slice('/callback/'.length))\n const sealed = readCookies(request.headers.get('cookie')).get(stepCookie)\n const step = sealed ? await unseal<Step>(sealed, await key) : null\n const clear = writeCookie(stepCookie, '', attrs(request, 0))\n const back = step?.returnTo ?? afterSignIn\n const failedTo = (code: string) => redirect(`${back}${back.includes('?') ? '&' : '?'}auth_error=${encodeURIComponent(code)}`, [clear])\n // The answer must be to the question this browser asked of this provider.\n if (step === null || (step.kind !== 'social' && step.kind !== 'link' && step.kind !== 'upgrade') || step.provider !== provider || url.searchParams.get('state') !== step.token) return failedTo('state_mismatch')\n const code = url.searchParams.get('code')\n if (!code) return failedTo(url.searchParams.get('error') === 'access_denied' ? 'cancelled' : 'provider_refused')\n const q = new URLSearchParams({ code, state: step.token, redirect_uri: `${originOf(request)}${basePath}/callback/${provider}` })\n if (step.kind === 'upgrade') {\n // The guest is now the account of that address: its session from here on.\n const mine = await signedInAs(request)\n if ('response' in mine) return failedTo('unauthenticated')\n const done = await ask(request, 'GET', `/v1/auth/anonymous/upgrade/${provider}/callback?${q}`, undefined, undefined, mine.token)\n if (done.error) return failedTo(done.error.code)\n const s = await stored(done.data)\n if (s === null) return failedTo('unavailable')\n return redirect(back, [...(await write(request, s, readCookies(request.headers.get('cookie')))), clear])\n }\n if (step.kind === 'link') {\n // Linked to the account signed in here, and back to where it was asked.\n const mine = await signedInAs(request)\n if ('response' in mine) return failedTo('unauthenticated')\n const linked = await ask(request, 'GET', `/v1/auth/identities/${provider}/link/callback?${q}`, undefined, undefined, mine.token)\n if (linked.error) return failedTo(linked.error.code)\n const h = new Headers(mine.headers)\n h.append('set-cookie', clear)\n return redirect(`${back}${back.includes('?') ? '&' : '?'}linked=${encodeURIComponent(provider)}`, [...h.getSetCookie()])\n }\n const done = await ask(request, 'GET', `/v1/auth/social/${provider}/callback?${q}`)\n if (done.error) return failedTo(done.error.code)\n const s = await stored(done.data)\n if (s === null) return failedTo('unavailable')\n return redirect(back, [...(await write(request, s, readCookies(request.headers.get('cookie')))), clear])\n }\n\n // A guest becoming the account of a provider's address: to it and back.\n if (route.startsWith('/me/upgrade/social/') && !post) {\n const provider = providerIn(route.slice('/me/upgrade/social/'.length))\n if (!PROVIDER_ID.test(provider)) return new Response('Not found', { status: 404 })\n const returnTo = localPath(url.searchParams.get('return_to'), afterSignIn)\n const failed = (code: string) => redirect(`${returnTo}${returnTo.includes('?') ? '&' : '?'}auth_error=${encodeURIComponent(code)}`)\n const mine = await signedInAs(request)\n if ('response' in mine) return failed('unauthenticated')\n const callback = `${basePath}/callback/${provider}`\n const started = await ask(request, 'GET', `/v1/auth/anonymous/upgrade/${provider}?redirect_uri=${encodeURIComponent(`${originOf(request)}${callback}`)}`, undefined, callback, mine.token)\n if (started.error || typeof started.data?.redirect_url !== 'string') return failed(started.error?.code ?? 'provider_unavailable')\n const step: Step = { kind: 'upgrade', token: String(started.data.state ?? ''), provider, returnTo }\n return redirect(started.data.redirect_url, [...mine.headers.getSetCookie(), writeCookie(stepCookie, await seal(step, await key), attrs(request, STEP_SECONDS))])\n }\n\n // A provider linked to the signed-in account: to it and back, like a sign-in.\n if (route.startsWith('/me/identities/link/') && !post) {\n const provider = providerIn(route.slice('/me/identities/link/'.length))\n if (!PROVIDER_ID.test(provider)) return new Response('Not found', { status: 404 })\n const returnTo = localPath(url.searchParams.get('return_to'), afterSignIn)\n const failed = (code: string) => redirect(`${returnTo}${returnTo.includes('?') ? '&' : '?'}auth_error=${encodeURIComponent(code)}`)\n const mine = await signedInAs(request)\n if ('response' in mine) return failed('unauthenticated')\n const callback = `${basePath}/callback/${provider}`\n const started = await ask(request, 'GET', `/v1/auth/identities/${provider}/link?redirect_uri=${encodeURIComponent(`${originOf(request)}${callback}`)}`, undefined, callback, mine.token)\n if (started.error || typeof started.data?.redirect_url !== 'string') return failed(started.error?.code ?? 'provider_unavailable')\n const step: Step = { kind: 'link', token: String(started.data.state ?? ''), provider, returnTo }\n return redirect(started.data.redirect_url, [...mine.headers.getSetCookie(), writeCookie(stepCookie, await seal(step, await key), attrs(request, STEP_SECONDS))])\n }\n\n // The person's own account: read here, changed below.\n if (route === '/me/identities' && !post) {\n const mine = await signedInAs(request)\n if ('response' in mine) return mine.response\n const res = await ask(request, 'GET', '/v1/auth/identities', undefined, undefined, mine.token)\n if (res.error) return problem(res.status, res.error.code, res.error.message, undefined, mine.headers)\n const list = Array.isArray(res.data) ? res.data : []\n return json({ identities: list.map((x: any) => ({ provider: String(x.provider ?? ''), email: String(x.email ?? ''), name: String(x.name ?? ''), linkedAt: String(x.linked_at ?? '') })) }, 200, mine.headers)\n }\n if (route === '/me/passkeys' && !post) {\n const mine = await signedInAs(request)\n if ('response' in mine) return mine.response\n const res = await ask(request, 'GET', '/v1/auth/webauthn/credentials', undefined, undefined, mine.token)\n if (res.error) return problem(res.status, res.error.code, res.error.message, undefined, mine.headers)\n const list = Array.isArray(res.data) ? res.data : []\n return json({ passkeys: list.map(passkeyOf) }, 200, mine.headers)\n }\n // The AI agents the person connected.\n if (route === '/me/agents' && !post) {\n const mine = await signedInAs(request)\n if ('response' in mine) return mine.response\n const res = await ask(request, 'GET', '/v1/auth/me/agents', undefined, undefined, mine.token)\n if (res.error) return problem(res.status, res.error.code, res.error.message, undefined, mine.headers)\n const list = Array.isArray(res.data) ? res.data : []\n return json({ agents: list.map(agentOf) }, 200, mine.headers)\n }\n // The person's organizations, and the people of one: as far as their\n // role in the system's catalog lets them see (cauthy:members read).\n if ((route === '/me/organizations' || route === '/me/organizations/members' || route === '/me/organizations/roles') && !post) {\n const mine = await signedInAs(request)\n if ('response' in mine) return mine.response\n let path = '/v1/auth/me/organizations'\n if (route !== '/me/organizations') {\n const id = url.searchParams.get('id') ?? ''\n if (!UUID.test(id)) return problem(400, 'invalid_organization', 'Say which organization.', undefined, mine.headers)\n path += `/${id}/${route.endsWith('/roles') ? 'roles' : 'members'}`\n } else if (url.searchParams.get('system')) {\n path += `?system=${encodeURIComponent(url.searchParams.get('system')!)}`\n }\n const res = await ask(request, 'GET', path, undefined, undefined, mine.token)\n if (res.error) return problem(res.status, res.error.code, res.error.message, undefined, mine.headers)\n const list = Array.isArray(res.data) ? res.data : []\n if (route === '/me/organizations') return json({ organizations: list.map(seatOf) }, 200, mine.headers)\n if (route === '/me/organizations/roles') return json({ roles: list.map(orgRoleOf) }, 200, mine.headers)\n return json({ members: list.map(orgMemberOf) }, 200, mine.headers)\n }\n // How the account takes its second step, and what the workspace offers.\n if (route === '/me/mfa/factors' && !post) {\n const mine = await signedInAs(request)\n if ('response' in mine) return mine.response\n const res = await ask(request, 'GET', '/v1/auth/mfa/factors', undefined, undefined, mine.token)\n if (res.error) return problem(res.status, res.error.code, res.error.message, undefined, mine.headers)\n return json(factorsOf(res.data), 200, mine.headers)\n }\n if ((route === '/me' || route === '/me/sessions') && !post) {\n const mine = await signedInAs(request)\n if ('response' in mine) return mine.response\n const res = await ask(request, 'GET', route === '/me' ? '/v1/auth/me' : '/v1/auth/me/sessions', undefined, undefined, mine.token)\n if (res.error) return problem(res.status, res.error.code, res.error.message, undefined, mine.headers)\n if (route === '/me/sessions') {\n const list = Array.isArray(res.data) ? res.data : []\n return json({ sessions: list.map((x: any) => ({ device: String(x.device ?? ''), ip: String(x.ip ?? ''), createdAt: String(x.created_at ?? ''), expiresAt: String(x.expires_at ?? '') })) }, 200, mine.headers)\n }\n return json({ account: accountOf(res.data) }, 200, mine.headers)\n }\n\n // The phone's answer to a push, as it comes: Cauthy's server-sent events,\n // passed through to the page that waits on them.\n if (route === '/sign-in/mfa/push/events' && !post) {\n const sealed = readCookies(request.headers.get('cookie')).get(stepCookie)\n const step = sealed ? await unseal<Step>(sealed, await key) : null\n if (step === null || step.kind !== 'mfa') return problem(400, 'step_expired', 'Sign in again: the code was asked for too long ago.')\n let upstream: Response\n try {\n upstream = await doFetch(`${issuer}/v1/auth/mfa/push/events`, {\n headers: { 'x-tenant-key': tenant, 'x-mfa-token': step.token, accept: 'text/event-stream' },\n signal: request.signal,\n })\n } catch {\n return problem(503, 'unavailable', 'Cauthy could not be reached.')\n }\n if (!upstream.ok || !upstream.body) {\n const b = (await upstream.json().catch(() => null)) as any\n return problem(upstream.status, String(b?.errors?.[0]?.code ?? 'error'), String(b?.errors?.[0]?.message ?? 'The request could not be completed.'))\n }\n return new Response(upstream.body, {\n status: 200,\n headers: { 'content-type': 'text/event-stream', 'cache-control': 'no-cache, no-store', 'x-accel-buffering': 'no' },\n })\n }\n\n if (!post) return new Response('Method not allowed', { status: 405, headers: { allow: 'POST' } })\n if (!ownRequest(request)) return problem(403, 'cross_site', 'This request did not come from this application.')\n\n if (route === '/sign-out') {\n const { had, value } = await read(request)\n if (value !== null) {\n const form = new URLSearchParams({ client_id: clientId, token: value.rt })\n if (clientSecret) form.set('client_secret', clientSecret)\n await doFetch(`${issuer}/v1/oauth/revoke`, { method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, body: form }).catch(() => undefined)\n orgCache.delete(value.at)\n }\n const h = new Headers()\n for (const c of clearParts(cookieName, attrs(request, 0), had)) h.append('set-cookie', c)\n return json({ status: 'signed_out' }, 200, h)\n }\n\n const b = await body(request)\n if (b === null) return problem(400, 'bad_request', 'Send the form as JSON.')\n\n // Which company's sign-in an address uses, if any: said of its domain,\n // never of whether the address has an account.\n if (route === '/sign-in/sso/discover') {\n const bad = checkEmail(b.email)\n if (bad) return invalid(bad)\n const res = await ask(request, 'POST', '/v1/auth/sso/discover', { email: String(b.email).trim() })\n if (res.error) return problem(res.status, res.error.code, res.error.message)\n const c = res.data?.connection\n return json(c ? { status: 'found', connection: { id: String(c.slug ?? ''), name: String(c.display_name ?? ''), enforced: c.enforced === true } } : { status: 'none' })\n }\n\n // A guest session, before the visitor signs up (the workspace's allow_anonymous).\n if (route === '/sign-in/anonymous') {\n if (!post) return new Response('Method not allowed', { status: 405, headers: { allow: 'POST' } })\n const res = await ask(request, 'POST', '/v1/auth/anonymous', {})\n if (res.error) return problem(res.status, res.error.code, res.error.message)\n return signedIn(request, res.data)\n }\n\n if (route === '/sign-in/email') {\n const bad = firstProblem(checkEmail(b.email), checkPassword(b.password))\n if (bad) return invalid(bad)\n const res = await ask(request, 'POST', '/v1/auth/login', { email: String(b.email).trim(), password: b.password })\n if (res.error) return problem(res.status, res.error.code, res.error.message)\n if (res.data?.mfa_required === true) {\n // The code is asked for next; what proves the password was right\n // stays here, sealed, and never reaches the page.\n const step: Step = { kind: 'mfa', token: String(res.data.mfa_token ?? ''), returnTo: afterSignIn }\n return json({ status: 'mfa_required' }, 200, new Headers({ 'set-cookie': writeCookie(stepCookie, await seal(step, await key), attrs(request, STEP_SECONDS)) }))\n }\n return signedIn(request, res.data)\n }\n\n if (route === '/sign-in/mfa') {\n const bad = checkCode(b.code)\n if (bad) return invalid(bad)\n const sealed = readCookies(request.headers.get('cookie')).get(stepCookie)\n const step = sealed ? await unseal<Step>(sealed, await key) : null\n if (step === null || step.kind !== 'mfa') return problem(400, 'step_expired', 'Sign in again: the code was asked for too long ago.')\n const res = await ask(request, 'POST', '/v1/auth/mfa/challenge', { mfa_token: step.token, code: String(b.code).trim() })\n if (res.error) return problem(res.status, res.error.code, res.error.message, 'code')\n return signedIn(request, res.data, [writeCookie(stepCookie, '', attrs(request, 0))])\n }\n\n // The second step by phone, while signing in: which ways the account has,\n // and a code sent to its phone. The challenge's token stays sealed here.\n // The second step approved on the phone: a push, then the sign-in once the\n // phone approved it (the answer itself streams from /sign-in/mfa/push/events).\n if (route === '/sign-in/mfa/push' || route === '/sign-in/mfa/push/finish') {\n const sealed = readCookies(request.headers.get('cookie')).get(stepCookie)\n const step = sealed ? await unseal<Step>(sealed, await key) : null\n if (step === null || step.kind !== 'mfa') return problem(400, 'step_expired', 'Sign in again: the code was asked for too long ago.')\n if (route === '/sign-in/mfa/push') {\n const res = await ask(request, 'POST', '/v1/auth/mfa/push', { mfa_token: step.token })\n if (res.error) return problem(res.status, res.error.code, res.error.message)\n return json({ status: 'sent', number: Number(res.data?.number ?? 0) })\n }\n const res = await ask(request, 'POST', '/v1/auth/mfa/challenge', { mfa_token: step.token, push: true })\n if (res.error) return problem(res.status, res.error.code, res.error.message)\n return signedIn(request, res.data, [writeCookie(stepCookie, '', attrs(request, 0))])\n }\n\n if (route === '/sign-in/mfa/methods' || route === '/sign-in/mfa/send') {\n const sealed = readCookies(request.headers.get('cookie')).get(stepCookie)\n const step = sealed ? await unseal<Step>(sealed, await key) : null\n if (step === null || step.kind !== 'mfa') return problem(400, 'step_expired', 'Sign in again: the code was asked for too long ago.')\n if (route === '/sign-in/mfa/methods') {\n const res = await ask(request, 'POST', '/v1/auth/mfa/methods', { mfa_token: step.token })\n if (res.error) return problem(res.status, res.error.code, res.error.message)\n const p = res.data?.phone\n const push = res.data?.push\n return json({ status: 'ok', totp: res.data?.totp === true, phone: p ? { number: String(p.number ?? ''), channel: String(p.channel ?? 'sms') } : null,\n push: push ? { devices: Number(push.devices ?? 0) } : null })\n }\n const res = await ask(request, 'POST', '/v1/auth/mfa/send', { mfa_token: step.token })\n if (res.error) return problem(res.status, res.error.code, res.error.message)\n return json({ status: 'sent', sentTo: String(res.data?.sent_to ?? ''), channel: String(res.data?.channel ?? 'sms') })\n }\n\n if (route === '/sign-up/email') {\n const bad = firstProblem(checkName(b.name), checkEmail(b.email), checkNewPassword(b.password), checkOrganization(b.organization))\n if (bad) return invalid(bad)\n const email = String(b.email).trim()\n // The company's name, when the application's system makes an organization per sign-up.\n const organization = typeof b.organization === 'string' && b.organization.trim() !== '' ? { organization: { name: b.organization.trim() } } : {}\n const made = await ask(request, 'POST', '/v1/auth/register', { email, password: b.password, display_name: typeof b.name === 'string' ? b.name.trim() : '', ...organization }, pages.verifyEmail)\n if (made.error) return problem(made.status, made.error.code, made.error.message)\n // An account that must confirm its address first cannot sign in yet.\n if (made.data?.verification_required === true) return json({ status: 'verification_required', email })\n const res = await ask(request, 'POST', '/v1/auth/login', { email, password: b.password })\n if (res.error || res.data?.mfa_required === true) return json({ status: 'verification_required', email })\n return signedIn(request, res.data)\n }\n\n if (route === '/forgot-password') {\n const bad = checkEmail(b.email)\n if (bad) return invalid(bad)\n // The same answer whether or not the address has an account.\n await ask(request, 'POST', '/v1/auth/password/reset', { email: String(b.email).trim() }, pages.resetPassword)\n return json({ status: 'sent' })\n }\n\n if (route.startsWith('/me')) {\n const mine = await signedInAs(request)\n if ('response' in mine) return mine.response\n const as = (path: string, payload?: unknown, method = 'POST') => ask(request, method, path, payload, undefined, mine.token)\n const refused = (res: { status: number; error?: { code: string; message: string } }, field?: string) =>\n problem(res.status, res.error!.code, res.error!.message, field, mine.headers)\n // Asked again for what weakens the account; an account with no password sends none.\n const password = typeof b.password === 'string' ? b.password : ''\n\n if (route === '/me') {\n const bad = checkName(b.name)\n if (bad) return invalid(bad)\n const res = await as('/v1/auth/me', { name: typeof b.name === 'string' ? b.name.trim() : '' }, 'PATCH')\n if (res.error) return refused(res, 'name')\n // The name is part of the session: the cookie says the new one at once.\n const h = mine.headers\n if (mine.kept !== null) {\n const again = await stored({ access_token: mine.kept.at, refresh_token: mine.kept.rt, expires_in: Math.max(1, mine.kept.exp - Math.floor(Date.now() / 1000)) })\n if (again !== null) for (const c of await write(request, again, readCookies(request.headers.get('cookie')))) h.append('set-cookie', c)\n }\n return json({ status: 'saved', account: accountOf(res.data) }, 200, h)\n }\n if (route === '/me/password') {\n const bad = checkNewPassword(b.newPassword)\n if (bad) return problem(400, bad.code, bad.message, 'newPassword')\n const res = await as('/v1/auth/me/password', { current_password: password, new_password: b.newPassword })\n if (res.error) return refused(res, res.error.code === 'wrong_password' ? 'password' : res.error.code === 'weak_password' ? 'newPassword' : undefined)\n // The change ended every session of the account. Cauthy answered with\n // a new one for this browser, which just proved the password.\n const next = await stored(res.data)\n const h = new Headers()\n const had = readCookies(request.headers.get('cookie'))\n for (const c of next !== null ? await write(request, next, had) : clearParts(cookieName, attrs(request, 0), had)) h.append('set-cookie', c)\n return json({ status: 'changed', signedIn: next !== null }, 200, h)\n }\n if (route === '/me/mfa/setup') {\n const res = await as('/v1/auth/mfa/setup', { password })\n if (res.error) return refused(res, res.error.code === 'step_up_required' ? 'password' : undefined)\n return json({ status: 'started', secret: String(res.data?.secret ?? ''), otpauthUri: String(res.data?.otpauth_uri ?? '') }, 200, mine.headers)\n }\n if (route === '/me/mfa/verify') {\n const bad = checkCode(b.code)\n if (bad) return invalid(bad)\n const res = await as('/v1/auth/mfa/verify', { code: String(b.code).trim() })\n if (res.error) return refused(res, 'code')\n return json({ status: 'enabled', recoveryCodes: Array.isArray(res.data?.recovery_codes) ? res.data.recovery_codes.map(String) : [] }, 200, mine.headers)\n }\n if (route === '/me/mfa/phone') {\n const res = await as('/v1/auth/mfa/phone', { phone: typeof b.phone === 'string' ? b.phone : '', channel: typeof b.channel === 'string' ? b.channel : 'sms', password })\n if (res.error) return refused(res, res.error.code === 'step_up_required' ? 'password' : res.error.code === 'validation_error' ? 'phone' : undefined)\n return json({ status: 'sent', sentTo: String(res.data?.sent_to ?? ''), channel: String(res.data?.channel ?? '') }, 200, mine.headers)\n }\n if (route === '/me/mfa/phone/verify') {\n const bad = checkCode(b.code)\n if (bad) return invalid(bad)\n const res = await as('/v1/auth/mfa/phone/verify', { code: String(b.code).trim() })\n if (res.error) return refused(res, 'code')\n return json({ status: 'enabled', recoveryCodes: Array.isArray(res.data?.recovery_codes) ? res.data.recovery_codes.map(String) : [] }, 200, mine.headers)\n }\n if (route === '/me/mfa/phone/remove') {\n const res = await as('/v1/auth/mfa/phone/remove', { password })\n if (res.error) return refused(res, res.error.code === 'step_up_required' ? 'password' : undefined)\n return json({ status: 'removed' }, 200, mine.headers)\n }\n if (route === '/me/mfa/disable') {\n const res = await as('/v1/auth/me/mfa/disable', { password })\n if (res.error) return refused(res, res.error.code === 'step_up_required' ? 'password' : undefined)\n return json({ status: 'disabled' }, 200, mine.headers)\n }\n if (route === '/me/mfa/recovery-codes') {\n const res = await as('/v1/auth/me/mfa/recovery-codes', { password })\n if (res.error) return refused(res, res.error.code === 'step_up_required' ? 'password' : undefined)\n return json({ status: 'renewed', recoveryCodes: Array.isArray(res.data?.recovery_codes) ? res.data.recovery_codes.map(String) : [] }, 200, mine.headers)\n }\n if (route === '/me/email') {\n const bad = checkEmail(b.email)\n if (bad) return invalid(bad)\n const email = String(b.email).trim()\n const res = await as('/v1/auth/me/email', { email, password })\n if (res.error) return refused(res, res.error.code === 'step_up_required' ? 'password' : ['invalid_email', 'email_unchanged', 'email_taken'].includes(res.error.code) ? 'email' : undefined)\n // Nothing changed yet: the new address confirms it from the link it was sent.\n return json({ status: 'sent', email }, 200, mine.headers)\n }\n if (route === '/me/identities/unlink') {\n const provider = typeof b.provider === 'string' ? b.provider : ''\n if (!PROVIDER_ID.test(provider)) return problem(400, 'invalid_provider', 'Say which provider to unlink.', 'provider', mine.headers)\n const res = await as(`/v1/auth/identities/${provider}`, undefined, 'DELETE')\n if (res.error) return refused(res)\n return json({ status: 'unlinked', provider }, 200, mine.headers)\n }\n // A passkey made on this page, for the domain the workspace's passkeys\n // belong to. The ceremony's id stays here, sealed, between its two calls.\n if (route === '/me/passkeys/add/begin') {\n const kind = b.kind === 'device' || b.kind === 'security_key' ? b.kind : ''\n const res = await as('/v1/auth/webauthn/register/begin', { password, ...(kind ? { kind } : {}) })\n if (res.error) return refused(res, res.error.code === 'step_up_required' ? 'password' : undefined)\n const step: Step = { kind: 'enrol', token: String(res.data?.session_id ?? ''), returnTo: afterSignIn }\n const h = new Headers(mine.headers)\n h.append('set-cookie', writeCookie(stepCookie, await seal(step, await key), attrs(request, PASSKEY_SECONDS)))\n return json({ status: 'started', options: res.data?.options?.publicKey ?? res.data?.options ?? null }, 200, h)\n }\n if (route === '/me/passkeys/add/finish') {\n const sealed = readCookies(request.headers.get('cookie')).get(stepCookie)\n const step = sealed ? await unseal<Step>(sealed, await key) : null\n if (step === null || step.kind !== 'enrol') return problem(400, 'step_expired', 'Start adding the passkey again: it was asked for too long ago.', undefined, mine.headers)\n if (!isCredential(b.credential)) return problem(400, 'bad_request', 'Send the passkey the browser made.', undefined, mine.headers)\n const name = typeof b.name === 'string' ? b.name.trim().slice(0, 60) : ''\n const res = await as('/v1/auth/webauthn/register/finish', { session_id: step.token, nickname: name, credential: b.credential })\n const h = new Headers(mine.headers)\n h.append('set-cookie', writeCookie(stepCookie, '', attrs(request, 0)))\n if (res.error) return problem(res.status, res.error.code === 'attestation_invalid' ? 'passkey_failed' : res.error.code, res.error.code === 'attestation_invalid' ? 'The passkey could not be added. Try again.' : res.error.message, undefined, h)\n return json({ status: 'added', passkey: passkeyOf(res.data) }, 200, h)\n }\n if (route === '/me/passkeys/remove') {\n const id = typeof b.id === 'string' ? b.id : ''\n if (!/^[0-9a-f-]{36}$/i.test(id)) return problem(400, 'invalid_passkey', 'Say which passkey to remove.', undefined, mine.headers)\n const res = await as(`/v1/auth/webauthn/credentials/${id}`, undefined, 'DELETE')\n if (res.error) return refused(res)\n return json({ status: 'removed', id }, 200, mine.headers)\n }\n // A guest becoming an account of their own, with an address and a password.\n if (route === '/me/upgrade') {\n const bad = firstProblem(checkName(b.name), checkEmail(b.email), checkNewPassword(b.password))\n if (bad) return invalid(bad)\n const res = await as('/v1/auth/anonymous/upgrade', { email: String(b.email).trim(), password: b.password, display_name: typeof b.name === 'string' ? b.name.trim() : '' })\n if (res.error) return refused(res, res.error.code === 'weak_password' ? 'password' : 'email')\n return signedIn(request, res.data)\n }\n // A member administering their organization's people (cauthy:members manage).\n if (route.startsWith('/me/organizations/members/')) {\n const org = typeof b.organizationId === 'string' ? b.organizationId : ''\n if (!UUID.test(org)) return problem(400, 'invalid_organization', 'Say which organization.', undefined, mine.headers)\n const base = `/v1/auth/me/organizations/${org}/members`\n if (route === '/me/organizations/members/add') {\n const bad = checkEmail(b.email)\n if (bad) return invalid(bad)\n const role = typeof b.role === 'string' ? b.role : ''\n if (role === '') return problem(400, 'invalid_role', 'Choose a role.', 'role', mine.headers)\n const res = await as(base, { email: String(b.email).trim(), role, name: typeof b.name === 'string' ? b.name.trim() : '',\n client_id: clientId, ...(typeof b.locale === 'string' && b.locale ? { locale: b.locale } : {}) })\n if (res.error) return refused(res, res.error.code === 'unknown_role' ? 'role' : 'email')\n return json({ status: 'added', member: orgMemberOf(res.data) }, 200, mine.headers)\n }\n const user = typeof b.userId === 'string' ? b.userId : ''\n if (!UUID.test(user)) return problem(400, 'invalid_member', 'Say which member.', undefined, mine.headers)\n if (route === '/me/organizations/members/role') {\n const role = typeof b.role === 'string' ? b.role : ''\n if (role === '') return problem(400, 'invalid_role', 'Choose a role.', 'role', mine.headers)\n const res = await as(`${base}/${user}`, { role }, 'PUT')\n if (res.error) return refused(res, 'role')\n return json({ status: 'changed', userId: user, role }, 200, mine.headers)\n }\n if (route === '/me/organizations/members/remove') {\n const res = await as(`${base}/${user}`, undefined, 'DELETE')\n if (res.error) return refused(res)\n orgCache.delete(mine.token)\n return json({ status: 'removed', userId: user }, 200, mine.headers)\n }\n if (route === '/me/organizations/members/invite') {\n const res = await as(`${base}/${user}/invite`, { client_id: clientId, ...(typeof b.locale === 'string' && b.locale ? { locale: b.locale } : {}) })\n if (res.error) return refused(res)\n return json({ status: 'sent', userId: user }, 200, mine.headers)\n }\n }\n if (route === '/me/agents/disconnect') {\n const id = typeof b.id === 'string' ? b.id : ''\n if (!/^[0-9a-f-]{36}$/i.test(id)) return problem(400, 'invalid_agent', 'Say which agent to disconnect.', undefined, mine.headers)\n const res = await as(`/v1/auth/me/agents/${id}`, undefined, 'DELETE')\n if (res.error) return refused(res)\n return json({ status: 'disconnected', id }, 200, mine.headers)\n }\n if (route === '/me/sessions/end') {\n const res = await as('/v1/auth/me/sessions', undefined, 'DELETE')\n if (res.error) return refused(res)\n // Everywhere is here too.\n const h = new Headers()\n for (const c of clearParts(cookieName, attrs(request, 0), readCookies(request.headers.get('cookie')))) h.append('set-cookie', c)\n orgCache.delete(mine.token)\n return json({ status: 'signed_out' }, 200, h)\n }\n return null\n }\n\n const isToken = (v: unknown): v is string => typeof v === 'string' && v !== '' && v.length <= 512\n const badLink = () => problem(422, 'invalid_token', 'This link is not valid, or it has expired.')\n\n // What a mailed link carries back: the token it was opened with.\n if (route === '/reset-password') {\n if (!isToken(b.token)) return badLink()\n const bad = checkNewPassword(b.password)\n if (bad) return invalid(bad)\n const res = await ask(request, 'POST', '/v1/auth/password/change', { token: String(b.token), new_password: b.password })\n if (res.error) return problem(res.status, res.error.code, res.error.message, res.error.code === 'weak_password' ? 'password' : undefined)\n return json({ status: 'changed' })\n }\n if (route === '/verify-email') {\n if (!isToken(b.token)) return badLink()\n const res = await ask(request, 'POST', '/v1/auth/email/verify', { token: String(b.token) })\n if (res.error) return problem(res.status, res.error.code, res.error.message)\n // The link proved the address: Cauthy signs the person in from it, unless\n // their account asks a second step — then they sign in the usual way.\n if (res.data?.access_token) return signedIn(request, res.data)\n return json({ status: 'verified' })\n }\n\n // A passkey, on this page: Cauthy says what to ask the browser for, the\n // browser asks the person, and the answer goes back to Cauthy through here.\n if (route === '/sign-in/passkey/begin') {\n // With the person's address, the browser is told which passkeys are\n // theirs; Cauthy answers the same for an address with none.\n const email = typeof b.email === 'string' && checkEmail(b.email) === null ? b.email.trim() : ''\n const res = await ask(request, 'POST', '/v1/auth/webauthn/login/begin', email !== '' ? { email } : {})\n if (res.error) return problem(res.status, res.error.code, res.error.message)\n const step: Step = { kind: 'passkey', token: String(res.data?.session_id ?? ''), returnTo: afterSignIn }\n return json({ status: 'started', options: res.data?.options?.publicKey ?? res.data?.options ?? null }, 200,\n new Headers({ 'set-cookie': writeCookie(stepCookie, await seal(step, await key), attrs(request, PASSKEY_SECONDS)) }))\n }\n if (route === '/sign-in/passkey/finish') {\n const sealed = readCookies(request.headers.get('cookie')).get(stepCookie)\n const step = sealed ? await unseal<Step>(sealed, await key) : null\n if (step === null || step.kind !== 'passkey') return problem(400, 'step_expired', 'Try the passkey again: it was asked for too long ago.')\n if (!isCredential(b.credential)) return problem(400, 'bad_request', 'Send the passkey the browser answered with.')\n const res = await ask(request, 'POST', '/v1/auth/webauthn/login/finish', { session_id: step.token, credential: b.credential })\n const clear = writeCookie(stepCookie, '', attrs(request, 0))\n if (res.error) {\n // Which check failed is Cauthy's to log; the page says only that it did.\n const failed = ['assertion_invalid', 'session_expired', 'clone_detected', 'not_found'].includes(res.error.code)\n return problem(res.status, failed ? 'passkey_failed' : res.error.code, failed ? 'The passkey sign-in could not be completed. Try again, or sign in another way.' : res.error.message, undefined, new Headers({ 'set-cookie': clear }))\n }\n return signedIn(request, res.data, [clear])\n }\n\n // Google One Tap: Cauthy gives the workspace's Google client and a nonce\n // for one prompt; Google's prompt gives the page an ID token, which comes\n // back here and is traded, once, for a session.\n if (route === '/sign-in/google-one-tap/begin') {\n const res = await ask(request, 'POST', '/v1/auth/google/one-tap/begin', {})\n if (res.error) return problem(res.status, res.error.code, res.error.message)\n return json({ status: 'started', clientId: String(res.data?.client_id ?? ''), nonce: String(res.data?.nonce ?? '') })\n }\n if (route === '/sign-in/google-one-tap') {\n if (typeof b.credential !== 'string' || b.credential === '') return problem(400, 'bad_request', 'Send the credential Google gave the page.')\n const res = await ask(request, 'POST', '/v1/auth/google/one-tap', { credential: b.credential })\n if (res.error) return problem(res.status, res.error.code, res.error.message)\n return signedIn(request, res.data)\n }\n\n // A sign-in link: asked for here, mailed by Cauthy, opened on the\n // application's sign-in page, which gives the token back.\n if (route === '/sign-in/magic-link') {\n const bad = checkEmail(b.email)\n if (bad) return invalid(bad)\n if (pages.signIn === undefined) return problem(500, 'not_configured', 'cauthy-auth: pages.signIn is required for sign-in links: it is the page the link opens')\n // The same answer whether or not the address has an account. With\n // create, an address with none gets one when the link or code is used\n // (if the workspace accepts new accounts): one screen for both.\n const email = String(b.email).trim()\n // Where the person goes once in travels in the link itself, as\n // `return_to` on the page it opens: it may be opened in another browser.\n const back = typeof b.returnTo === 'string' ? localPath(b.returnTo, afterSignIn) : afterSignIn\n const page = back === afterSignIn ? pages.signIn : `${pages.signIn}${pages.signIn.includes('?') ? '&' : '?'}return_to=${encodeURIComponent(back)}`\n await ask(request, 'POST', '/v1/auth/magic-link/request', { email, ...(b.create === true ? { create_account: true } : {}) }, page)\n // The mail carries a code too. Whose it is stays here, sealed, so the\n // page that asks for the code needs only the code.\n const step: Step = { kind: 'code', token: email, returnTo: back }\n return json({ status: 'sent' }, 200, new Headers({ 'set-cookie': writeCookie(stepCookie, await seal(step, await key), attrs(request, STEP_SECONDS)) }))\n }\n if (route === '/sign-in/email-code') {\n const bad = checkCode(b.code)\n if (bad) return invalid(bad)\n const sealed = readCookies(request.headers.get('cookie')).get(stepCookie)\n const step = sealed ? await unseal<Step>(sealed, await key) : null\n if (step === null || step.kind !== 'code') return problem(400, 'step_expired', 'Ask for a new link: this one was asked for too long ago.')\n const res = await ask(request, 'POST', '/v1/auth/magic-link/verify-code', { email: step.token, code: String(b.code).trim() })\n if (res.error) return problem(res.status, res.error.code, res.error.message, 'code')\n return signedIn(request, res.data, [writeCookie(stepCookie, '', attrs(request, 0))], { returnTo: step.returnTo })\n }\n if (route === '/sign-in/magic-link/verify') {\n if (!isToken(b.token)) return badLink()\n const res = await ask(request, 'POST', '/v1/auth/magic-link/verify', { token: String(b.token) })\n if (res.error) return problem(res.status, res.error.code, res.error.message)\n return signedIn(request, res.data)\n }\n return null\n }\n\n async function handler(request: Request): Promise<Response> {\n const url = new URL(request.url)\n if (url.pathname !== basePath && !url.pathname.startsWith(`${basePath}/`)) return new Response('Not found', { status: 404 })\n const route = withoutTrailingSlashes(url.pathname.slice(basePath.length)) || '/'\n const get = request.method === 'GET' || request.method === 'HEAD'\n\n const mine = await ownRoute(request, url, route)\n if (mine !== null) return mine\n\n if (route === '/login' && get) return login(request, url)\n if (route === '/callback' && get) return callback(request, url)\n if (route === '/logout' && (get || request.method === 'POST')) return logout(request)\n\n if (route === '/session' && get) {\n const r = await resolve(request)\n const h = new Headers()\n for (const c of r.cookies) h.append('set-cookie', c)\n return json({ session: r.session ? await toPublic(r.session) : null, status: r.status }, 200, h)\n }\n\n // For a page that found its session expired: renew, and go back to it.\n if (route === '/refresh' && get) {\n const r = await resolve(request)\n const back = localPath(url.searchParams.get('return_to'), afterSignIn)\n if (r.status === 'unauthenticated') return redirect(urls.signIn(back), r.cookies)\n if (r.status === 'expired') return new Response('Sign-in is unavailable right now. Try again in a moment.', { status: 503 })\n return redirect(back, r.cookies)\n }\n\n if (route === '/account' && get) {\n const q = new URLSearchParams({ client_id: clientId })\n const back = localPath(url.searchParams.get('return_to'), '')\n if (back !== '') q.set('return_to', `${originOf(request)}${back}`)\n const locale = url.searchParams.get('locale')\n if (locale && /^[a-zA-Z-]{2,10}$/.test(locale)) q.set('ui_locales', locale)\n return redirect(`${issuer}/v1/oauth/account?${q}`)\n }\n return new Response('Not found', { status: 404 })\n }\n\n async function protect(request: Request) {\n const { value } = await read(request)\n if (value !== null && fresh(value)) return { session: toSession(value) }\n const url = new URL(request.url)\n const state = value === null ? 'none' : 'expired'\n // A page is sent to sign in, or to renew and come back. Anything else —\n // a fetch, a form post — is told, and its caller decides.\n const page = request.method === 'GET' && (request.headers.get('sec-fetch-mode') ?? 'navigate') === 'navigate' &&\n (request.headers.get('accept') ?? 'text/html').includes('text/html')\n if (!page) {\n return { response: json({ error: 'unauthenticated', session: state }, 401, new Headers({ 'x-cauthy-session': state })) }\n }\n const back = url.pathname + url.search\n const to = value === null ? urls.signIn(back) : `${basePath}/refresh?return_to=${encodeURIComponent(back)}`\n return { response: redirect(to) }\n }\n\n // The endpoint's public address: the application's origin when it was\n // given (a proxy may hide it from the request), with the request's path.\n const webhook: Cauthy['webhook'] = (request, o = {}) =>\n verifyWebhook(request, { issuer, url: o.url ?? `${originOf(request)}${new URL(request.url).pathname}`, jwks: o.jwks, now: o.now })\n\n return {\n handler,\n webhook,\n system: systemThatRefreshes,\n getSession,\n status,\n resolve,\n protect,\n organizations,\n toPublic,\n urls,\n options: { issuer, clientId, basePath, afterSignIn, afterSignOut, cookieName },\n }\n}\n","// What a person may do in an organization.\n//\n// When a system keeps its catalog of roles in Cauthy, each of a person's\n// organizations arrives with what their role — and anything given or denied to\n// them apart from it — lets them do. Checking is a lookup in that list: no\n// call to Cauthy, on the server or in the browser.\n\nimport { withoutTrailingSlashes } from './url'\n\n/** The part of an organization that says what its member may do. */\nexport interface Permitted {\n /** \"resource:action\" entries the person is allowed; \"*\" is any. Absent when the system keeps no catalog in Cauthy. */\n permissions?: string[]\n /** Entries the person is denied whatever else allows them. */\n denied?: string[]\n}\n\nfunction matches(entry: string, resource: string, action: string): boolean {\n // The resource may itself hold a colon: the action is what follows the last one.\n const i = entry.lastIndexOf(':')\n if (i < 0) return false\n const r = entry.slice(0, i)\n const a = entry.slice(i + 1)\n return (r === '*' || r === resource) && (a === '*' || a === action)\n}\n\n/**\n * Whether the person may do an action on a resource in an organization:\n * allowed by some entry, and denied by none. A denial wins.\n *\n * An organization of a system that keeps no catalog in Cauthy carries no\n * permissions, and the answer is `false`: decide by its `role` instead.\n *\n * if (!can(organization, 'invoicing', 'write')) return forbidden()\n */\nexport function can(organization: Permitted | null | undefined, resource: string, action: string): boolean {\n if (!organization?.permissions) return false\n if ((organization.denied ?? []).some((d) => matches(d, resource, action))) return false\n return organization.permissions.some((p) => matches(p, resource, action))\n}\n\n// ── A system's catalog of roles ────────────────────────────────────────────\n\n/** Something a role may do: an action on a resource, in organizations of a kind (\"*\", the default, is every kind). */\nexport interface PolicyPermission {\n kind?: string\n resource: string\n action: string\n}\n\nexport interface PolicyRole {\n role: string\n name?: string\n description?: string\n /** Roles whose permissions this one has as well. */\n inherits?: string[]\n permissions?: PolicyPermission[]\n}\n\n// ── The catalog, with its types ────────────────────────────────────────────\n//\n// A catalog written down once gives the roles and the permissions their\n// names: `can(org, 'ledger:write')` then takes only a permission the catalog\n// has, the editor offers them, and a typo does not compile.\n//\n// export const policy = definePolicy([\n// { role: 'reader', permissions: [{ resource: 'ledger', action: 'read' }] },\n// { role: 'accountant', inherits: ['reader'], permissions: [{ resource: 'ledger', action: 'write' }] },\n// ])\n// export const { can, hasRole } = policy\n//\n// can(organization, 'ledger:write') // 'ledger:wirte' does not compile\n// hasRole(organization, 'accountant')\n//\n// Write it by hand, or let `cauthy-auth policy --pull` write it from the\n// catalog Cauthy has.\n\n/** A role as `definePolicy` reads it: any `PolicyRole`, kept as written. */\ntype RoleShape = {\n readonly role: string\n readonly name?: string\n readonly description?: string\n readonly inherits?: readonly string[]\n readonly permissions?: readonly { readonly kind?: string; readonly resource: string; readonly action: string }[]\n}\n\n// \"*\" in a catalog is \"any\": the name it stands for is any text.\ntype Named<S extends string> = S extends '*' ? string : S\n\ntype PermissionsIn<R> = R extends { readonly permissions: readonly (infer P)[] }\n ? P extends { readonly resource: infer Res extends string; readonly action: infer Act extends string } ? `${Named<Res>}:${Named<Act>}` : never\n : never\n\n/** The roles a catalog names: `RoleOf<typeof policy>`. */\nexport type RoleOf<P> = P extends Policy<infer R, string> ? R : never\n/** The \"resource:action\" permissions a catalog names: `PermissionOf<typeof policy>`. */\nexport type PermissionOf<P> = P extends Policy<string, infer X> ? X : never\n\nexport interface Policy<Role extends string = string, Permission extends string = string> {\n /** The catalog as Cauthy takes it: `pushPolicy({ roles: policy.roles })`. */\n roles: PolicyRole[]\n /** Every role's name. */\n roleNames: Role[]\n /** Every permission some role has, as \"resource:action\". */\n permissions: Permission[]\n /**\n * Whether the person may do this in the organization: `can(org, 'ledger:write')`.\n * It reads what Cauthy sent with the session, so a catalog edited in Cauthy\n * since this file was written is still what decides.\n */\n can(organization: Permitted | null | undefined, permission: Permission): boolean\n /** Whether the person's role in the organization is one of these. */\n hasRole(organization: { role: string } | null | undefined, ...roles: Role[]): boolean\n /**\n * What a role may do by this catalog, with what it inherits: for showing a\n * role, never for deciding about a person (their exceptions are not here).\n */\n permissionsOf(role: Role): Permission[]\n}\n\n/** Gives a catalog of roles its types. See the top of this section. */\nexport function definePolicy<const T extends readonly RoleShape[]>(roles: T): Policy<T[number]['role'], PermissionsIn<T[number]>> {\n type Role = T[number]['role']\n type Permission = PermissionsIn<T[number]>\n const entry = (p: { resource: string; action: string }) => `${p.resource}:${p.action}` as Permission\n const byName = new Map(roles.map((r) => [r.role, r]))\n const split = (permission: string): [string, string] => {\n const i = permission.lastIndexOf(':')\n return i < 0 ? [permission, ''] : [permission.slice(0, i), permission.slice(i + 1)]\n }\n return {\n roles: roles.map((r) => ({\n role: r.role,\n ...(r.name !== undefined ? { name: r.name } : {}),\n ...(r.description !== undefined ? { description: r.description } : {}),\n ...(r.inherits ? { inherits: [...r.inherits] } : {}),\n ...(r.permissions ? { permissions: r.permissions.map((p) => ({ ...p })) } : {}),\n })),\n roleNames: roles.map((r) => r.role),\n permissions: [...new Set(roles.flatMap((r) => (r.permissions ?? []).map(entry)))],\n can(organization, permission) {\n const [resource, action] = split(permission)\n return can(organization, resource, action)\n },\n hasRole(organization, ...wanted) {\n return organization != null && (wanted as string[]).includes(organization.role)\n },\n permissionsOf(role: Role) {\n const seen = new Set<string>()\n const out = new Set<Permission>()\n const walk = (name: string) => {\n if (seen.has(name)) return // a catalog that inherits in a circle still ends\n seen.add(name)\n const r = byName.get(name)\n for (const p of r?.permissions ?? []) out.add(entry(p))\n for (const parent of r?.inherits ?? []) walk(parent)\n }\n walk(role)\n return [...out]\n },\n }\n}\n\nconst IDENT = /^[A-Za-z_$][A-Za-z0-9_$]*$/\n\n/**\n * A TypeScript module that defines the catalog given, for `cauthy-auth policy\n * --pull` to write: the application's types then come from the catalog\n * Cauthy has.\n */\nexport function policySource(system: string, roles: PolicyRole[]): string {\n const text = (v: string) => JSON.stringify(v)\n const key = (k: string) => (IDENT.test(k) ? k : text(k))\n const one = (r: PolicyRole) => {\n const parts = [`role: ${text(r.role)}`]\n if (r.name) parts.push(`name: ${text(r.name)}`)\n if (r.description) parts.push(`description: ${text(r.description)}`)\n if (r.inherits?.length) parts.push(`inherits: [${r.inherits.map(text).join(', ')}]`)\n if (r.permissions?.length) {\n const list = r.permissions.map((p) => ` { ${[...(p.kind && p.kind !== '*' ? [`${key('kind')}: ${text(p.kind)}`] : []), `resource: ${text(p.resource)}`, `action: ${text(p.action)}`].join(', ')} },`)\n parts.push(`permissions: [\\n${list.join('\\n')}\\n ]`)\n }\n return ` {\\n ${parts.join(',\\n ')},\\n },`\n }\n return `// The catalog of roles of ${text(system)}, as Cauthy has it.\n// Written by \\`cauthy-auth policy --pull\\`: run it again after the catalog\n// changes, and do not edit this file by hand.\n\nimport { definePolicy, type PermissionOf, type RoleOf } from 'cauthy-auth'\n\nexport const policy = definePolicy([\n${roles.map(one).join('\\n')}\n])\n\nexport const { can, hasRole } = policy\nexport type Role = RoleOf<typeof policy>\nexport type Permission = PermissionOf<typeof policy>\n`\n}\n\n/** Reads a system's catalog of roles from Cauthy, with a personal access token. */\nexport async function pullPolicy(o: Omit<PushPolicyOptions, 'roles'> = {}): Promise<PolicyRole[]> {\n const env = (n: string) => (typeof process !== 'undefined' ? process.env?.[n] : undefined)\n const issuer = withoutTrailingSlashes(o.issuer ?? env('CAUTHY_ISSUER') ?? '')\n const system = o.system ?? env('CAUTHY_SYSTEM') ?? ''\n const tenant = o.tenant ?? env('CAUTHY_TENANT') ?? ''\n const token = o.token ?? env('CAUTHY_TOKEN') ?? ''\n for (const [name, v] of Object.entries({ CAUTHY_ISSUER: issuer, CAUTHY_SYSTEM: system, CAUTHY_TENANT: tenant, CAUTHY_TOKEN: token })) {\n if (v === '') throw new Error(`cauthy-auth: ${name} is required to read a policy`)\n }\n const res = await (o.fetch ?? fetch)(`${issuer}/v1/systems/${encodeURIComponent(system)}/policy`, {\n headers: { authorization: `Bearer ${token}`, 'x-tenant-key': tenant, accept: 'application/json' },\n })\n const body = (await res.json().catch(() => null)) as { data?: { roles?: PolicyRole[] }; errors?: { message?: string }[] } | null\n if (!res.ok) throw new Error(`cauthy-auth: Cauthy refused to give the policy (${res.status}): ${body?.errors?.[0]?.message ?? res.statusText}`)\n return body?.data?.roles ?? []\n}\n\nexport interface PushPolicyOptions {\n /** The system whose catalog this is. Default: `CAUTHY_SYSTEM`. */\n system?: string\n roles: PolicyRole[]\n /** Cauthy's address. Default: `CAUTHY_ISSUER`. */\n issuer?: string\n /** The workspace's slug. Default: `CAUTHY_TENANT`. */\n tenant?: string\n /** A personal access token with `organizations:manage`. Default: `CAUTHY_TOKEN`. */\n token?: string\n fetch?: typeof fetch\n}\n\n/**\n * Gives Cauthy a system's catalog of roles, replacing the one it has. It is\n * the way to load a first catalog from what a system already had; from then on\n * the catalog is Cauthy's, edited in its dashboard, and pushing again would\n * overwrite what was edited there.\n */\nexport async function pushPolicy(o: PushPolicyOptions): Promise<void> {\n const env = (n: string) => (typeof process !== 'undefined' ? process.env?.[n] : undefined)\n const issuer = withoutTrailingSlashes(o.issuer ?? env('CAUTHY_ISSUER') ?? '')\n const system = o.system ?? env('CAUTHY_SYSTEM') ?? ''\n const tenant = o.tenant ?? env('CAUTHY_TENANT') ?? ''\n const token = o.token ?? env('CAUTHY_TOKEN') ?? ''\n for (const [name, v] of Object.entries({ CAUTHY_ISSUER: issuer, CAUTHY_SYSTEM: system, CAUTHY_TENANT: tenant, CAUTHY_TOKEN: token })) {\n if (v === '') throw new Error(`cauthy-auth: ${name} is required to push a policy`)\n }\n const res = await (o.fetch ?? fetch)(`${issuer}/v1/systems/${encodeURIComponent(system)}/policy`, {\n method: 'PUT',\n headers: { authorization: `Bearer ${token}`, 'x-tenant-key': tenant, 'content-type': 'application/json' },\n body: JSON.stringify({ roles: o.roles }),\n })\n if (!res.ok) {\n const body = (await res.json().catch(() => null)) as { errors?: { message?: string }[] } | null\n throw new Error(`cauthy-auth: Cauthy refused the policy (${res.status}): ${body?.errors?.[0]?.message ?? res.statusText}`)\n }\n}\n","// Connecting an application to Cauthy in one call: its client, where its\n// people come back to, where it hears events, and its own identity. It is what\n// `cauthy-auth init` runs, and what Cauthy's dashboard does under \"Connect a\n// system\".\n\nimport { withoutTrailingSlashes } from './url'\n\nexport interface ConnectOptions {\n /** The system's name, as its organizations are filed under: lowercase, digits, - or _. */\n system: string\n /** The application's public address: `https://app.example.com`, or `http://localhost:3000` while developing. */\n appUrl: string\n /** Shown to people on Cauthy's pages. Default: the system's name. */\n name?: string\n /** Where the application serves the return from a sign-in. Default: `/api/auth/callback`. */\n callbackPath?: string\n /** An https address of the application that receives Cauthy's events. */\n eventsUrl?: string\n /** The events to receive. Default: all of them. */\n events?: string[]\n /** Where the application publishes its keys, to prove itself without a secret. */\n jwksUri?: string\n /** Cauthy's address. Default: `CAUTHY_ISSUER`. */\n issuer?: string\n /** The workspace's slug. Default: `CAUTHY_TENANT`. */\n tenant?: string\n /** A personal access token with `systems:connect`. Default: `CAUTHY_TOKEN`. */\n token?: string\n fetch?: typeof fetch\n}\n\nexport interface Connected {\n system: string\n clientId: string\n /** Shown this once: Cauthy keeps only its hash. */\n clientSecret: string\n redirectUris: string[]\n webhook: { id: string; url: string; events: string[] } | null\n /**\n * Everything the application sets: what Cauthy answered, plus CAUTHY_SECRET,\n * the key of the session cookie, generated here and known to nobody else.\n */\n env: Record<string, string>\n}\n\nfunction sessionSecret(): string {\n const bytes = crypto.getRandomValues(new Uint8Array(32))\n let s = ''\n for (const b of bytes) s += String.fromCharCode(b)\n return btoa(s).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')\n}\n\nexport async function connectSystem(o: ConnectOptions): Promise<Connected> {\n const env = (n: string) => (typeof process !== 'undefined' ? process.env?.[n] : undefined)\n const issuer = withoutTrailingSlashes(o.issuer ?? env('CAUTHY_ISSUER') ?? '')\n const tenant = o.tenant ?? env('CAUTHY_TENANT') ?? ''\n const token = o.token ?? env('CAUTHY_TOKEN') ?? ''\n for (const [name, v] of Object.entries({ CAUTHY_ISSUER: issuer, CAUTHY_TENANT: tenant, CAUTHY_TOKEN: token })) {\n if (v === '') throw new Error(`cauthy-auth: ${name} is required to connect a system`)\n }\n const res = await (o.fetch ?? fetch)(`${issuer}/v1/connect`, {\n method: 'POST',\n headers: { authorization: `Bearer ${token}`, 'x-tenant-key': tenant, 'content-type': 'application/json' },\n body: JSON.stringify({ system: o.system, app_url: o.appUrl, name: o.name, callback_path: o.callbackPath,\n events_url: o.eventsUrl, events: o.events, jwks_uri: o.jwksUri }),\n })\n const body = (await res.json().catch(() => null)) as {\n data?: { system: string; client_secret: string; client: { client_id: string; redirect_uris: string[] }\n webhook: Connected['webhook']; env: Record<string, string> }\n errors?: { field?: string; message?: string }[]\n } | null\n if (!res.ok || !body?.data) {\n const why = (body?.errors ?? []).map((e) => e.message).filter(Boolean).join('; ') || res.statusText\n throw new Error(`cauthy-auth: Cauthy did not connect the system (${res.status}): ${why}`)\n }\n const d = body.data\n return { system: d.system, clientId: d.client.client_id, clientSecret: d.client_secret, redirectUris: d.client.redirect_uris,\n webhook: d.webhook, env: { ...d.env, CAUTHY_SECRET: sessionSecret() } }\n}\n\n/** The variables as the lines of an env file. */\nexport function envFile(env: Record<string, string>): string {\n return Object.entries(env).map(([k, v]) => `${k}=${v}`).join('\\n') + '\\n'\n}\n","// A backend that is handed a Cauthy access token: is it real, and whose is it?\n//\n// const who = await verifyToken(request) // or the token itself\n// who.userId, who.tenantId, who.roles\n//\n// Cauthy signs its tokens with a key it publishes (/.well-known/jwks.json), so\n// checking one needs no secret and no call to Cauthy per request: the keys are\n// fetched once and cached. Throws `CauthyTokenError` for anything else: answer\n// it 401.\n\nimport { createRemoteJWKSet, jwtVerify, type JWTVerifyGetKey } from 'jose'\nimport { withoutTrailingSlashes } from './url'\n\n/** Who a verified access token belongs to. */\nexport interface TokenIdentity {\n /** The person. For a system's own token, the client it identifies as. */\n userId: string\n tenantId: string\n email?: string\n roles: string[]\n /** Set when the token is a system's own and not a person's. */\n system?: string\n /** UTC, ISO 8601. */\n expiresAt: string\n /** The token as it arrived, to pass on. */\n token: string\n}\n\nexport class CauthyTokenError extends Error {\n constructor(readonly reason: string) {\n super(`cauthy-auth: token refused: ${reason}`)\n this.name = 'CauthyTokenError'\n }\n}\n\nexport interface VerifyTokenOptions {\n /** Cauthy's address. Default: `CAUTHY_ISSUER`. */\n issuer?: string\n /** The audience the tokens must carry. Default: `CAUTHY_AUDIENCE`; unchecked when neither is set. */\n audience?: string\n /** Refuse a token of any other workspace. Default: `CAUTHY_TENANT_ID`; unchecked when neither is set. */\n tenantId?: string\n /** Cauthy's keys. Default: fetched from the issuer and cached. */\n jwks?: JWTVerifyGetKey\n /** The moment to verify at. Default: now. */\n now?: Date\n}\n\nconst keys = new Map<string, JWTVerifyGetKey>()\n\n/** Cauthy's published keys, fetched once per issuer and cached. */\nexport function keysOf(issuer: string): JWTVerifyGetKey {\n let set = keys.get(issuer)\n if (set === undefined) {\n set = createRemoteJWKSet(new URL(`${issuer}/.well-known/jwks.json`), { cooldownDuration: 30_000 })\n keys.set(issuer, set)\n }\n return set\n}\n\nfunction env(name: string): string | undefined {\n return typeof process !== 'undefined' ? process.env?.[name] : undefined\n}\n\nfunction bearer(from: string | Request | Headers): string {\n if (typeof from === 'string') return from.replace(/^Bearer\\s+/i, '').trim()\n const header = (from instanceof Headers ? from : from.headers).get('authorization') ?? ''\n return /^Bearer\\s+/i.test(header) ? header.replace(/^Bearer\\s+/i, '').trim() : ''\n}\n\n/**\n * Verifies an access token (or the `Authorization: Bearer` of a request) and\n * answers who it belongs to. Checked: the signature, against Cauthy's\n * published keys; that Cauthy issued it; that it has not expired; and the\n * audience and the workspace, when given.\n */\nexport async function verifyToken(from: string | Request | Headers, options: VerifyTokenOptions = {}): Promise<TokenIdentity> {\n const issuer = withoutTrailingSlashes(options.issuer ?? env('CAUTHY_ISSUER') ?? '')\n if (issuer === '') throw new CauthyTokenError('issuer (CAUTHY_ISSUER) is not set')\n const token = bearer(from)\n if (token === '') throw new CauthyTokenError('no token')\n\n let claims: Record<string, unknown>\n try {\n const verified = await jwtVerify(token, options.jwks ?? keysOf(issuer), {\n algorithms: ['RS256'],\n issuer,\n audience: options.audience ?? env('CAUTHY_AUDIENCE'),\n requiredClaims: ['exp', 'sub'],\n currentDate: options.now,\n })\n claims = verified.payload as Record<string, unknown>\n } catch (err) {\n throw new CauthyTokenError(err instanceof Error ? err.message : 'bad signature')\n }\n\n const tenantId = typeof claims.tid === 'string' ? claims.tid : ''\n const wanted = options.tenantId ?? env('CAUTHY_TENANT_ID')\n if (wanted && tenantId !== wanted) throw new CauthyTokenError('issued for another workspace')\n\n return {\n userId: String(claims.sub),\n tenantId,\n ...(typeof claims.email === 'string' && claims.email !== '' ? { email: claims.email } : {}),\n roles: Array.isArray(claims.roles) ? claims.roles.filter((r): r is string => typeof r === 'string') : [],\n ...(typeof claims.sys === 'string' && claims.sys !== '' ? { system: claims.sys } : {}),\n expiresAt: new Date((claims.exp as number) * 1000).toISOString(),\n token,\n }\n}\n"],"mappings":";AAKA,IAAM,OAAO;AAEN,SAAS,YAAY,QAAwD;AAClF,QAAMA,OAAM,oBAAI,IAAoB;AACpC,aAAW,SAAS,UAAU,IAAI,MAAM,GAAG,GAAG;AAC5C,UAAM,IAAI,KAAK,QAAQ,GAAG;AAC1B,QAAI,IAAI,EAAG,CAAAA,KAAI,IAAI,KAAK,MAAM,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,MAAM,IAAI,CAAC,EAAE,KAAK,CAAC;AAAA,EACtE;AACA,SAAOA;AACT;AAGO,SAAS,UAAU,SAA8B,MAA6B;AACnF,MAAI,QAAQ;AACZ,WAAS,IAAI,GAAG,QAAQ,IAAI,GAAG,IAAI,IAAI,CAAC,EAAE,GAAG,IAAK,UAAS,QAAQ,IAAI,GAAG,IAAI,IAAI,CAAC,EAAE;AACrF,SAAO,UAAU,KAAK,OAAO;AAC/B;AAQA,SAAS,WAAW,GAA6B;AAG/C,SAAO,QAAQ,EAAE,QAAQ,GAAG,qCAAqC,EAAE,MAAM,GAAG,EAAE,SAAS,aAAa,EAAE;AACxG;AAEO,SAAS,YAAY,MAAc,OAAe,GAA6B;AACpF,SAAO,GAAG,IAAI,IAAI,KAAK,KAAK,WAAW,CAAC,CAAC;AAC3C;AAMO,SAAS,WAAW,MAAc,OAAe,GAAqB,KAAoC;AAC/G,QAAMA,OAAgB,CAAC;AACvB,MAAI,IAAI;AACR,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,KAAM,CAAAA,KAAI,KAAK,YAAY,GAAG,IAAI,IAAI,GAAG,IAAI,MAAM,MAAM,GAAG,IAAI,IAAI,GAAG,CAAC,CAAC;AAChH,WAAS,IAAI,GAAG,IAAI,IAAI,GAAG,IAAI,IAAI,CAAC,EAAE,GAAG,IAAK,CAAAA,KAAI,KAAK,YAAY,GAAG,IAAI,IAAI,CAAC,IAAI,IAAI,EAAE,GAAG,GAAG,QAAQ,EAAE,CAAC,CAAC;AAC3G,SAAOA;AACT;AAEO,SAAS,WAAW,MAAc,GAAqB,KAAoC;AAChG,QAAMA,OAAgB,CAAC;AACvB,WAAS,IAAI,GAAG,IAAI,IAAI,GAAG,IAAI,IAAI,CAAC,EAAE,KAAK,MAAM,GAAG,IAAK,CAAAA,KAAI,KAAK,YAAY,GAAG,IAAI,IAAI,CAAC,IAAI,IAAI,EAAE,GAAG,GAAG,QAAQ,EAAE,CAAC,CAAC;AACtH,SAAOA;AACT;;;ACnDA,SAAS,gBAAgB,sBAAsB;AAE/C,IAAM,UAAU,IAAI,YAAY;AAChC,IAAM,UAAU,IAAI,YAAY;AAGhC,eAAsB,MAAM,QAAqC;AAC/D,SAAO,IAAI,WAAW,MAAM,OAAO,OAAO,OAAO,WAAW,QAAQ,OAAO,MAAM,CAAC,CAAC;AACrF;AAEA,eAAsB,KAAK,OAAgB,KAAkC;AAC3E,SAAO,IAAI,eAAe,QAAQ,OAAO,KAAK,UAAU,KAAK,CAAC,CAAC,EAC5D,mBAAmB,EAAE,KAAK,OAAO,KAAK,UAAU,CAAC,EACjD,QAAQ,GAAG;AAChB;AAGA,eAAsB,OAAU,QAAgB,KAAoC;AAClF,MAAI;AACF,UAAM,EAAE,UAAU,IAAI,MAAM,eAAe,QAAQ,KAAK;AAAA,MACtD,yBAAyB,CAAC,KAAK;AAAA,MAC/B,6BAA6B,CAAC,SAAS;AAAA,IACzC,CAAC;AACD,WAAO,KAAK,MAAM,QAAQ,OAAO,SAAS,CAAC;AAAA,EAC7C,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;ACtBA,SAAS,WAAW,WAAW,aAAa,eAAuC;;;ACJ5E,SAAS,uBAAuB,GAAmB;AACxD,MAAI,MAAM,EAAE;AACZ,SAAO,MAAM,KAAK,EAAE,WAAW,MAAM,CAAC,MAAM,GAAI;AAChD,SAAO,EAAE,MAAM,GAAG,GAAG;AACvB;;;ACkGA,IAAM,aAAa;AAanB,SAAS,gBAAgB,KAAqB;AAC5C,MAAIC,OAAM;AACV,MAAI,IAAI;AACR,aAAS;AACP,UAAM,OAAO,IAAI,QAAQ,MAAM,CAAC;AAChC,QAAI,OAAO,EAAG,QAAOA,OAAM,IAAI,MAAM,CAAC;AACtC,IAAAA,QAAO,IAAI,MAAM,GAAG,IAAI;AACxB,UAAM,QAAQ,IAAI,QAAQ,MAAM,OAAO,CAAC;AACxC,QAAI,QAAQ,EAAG,QAAOA;AACtB,QAAI,QAAQ;AAAA,EACd;AACF;AAEA,SAAS,aAAa,KAA4B;AAChD,QAAM,OAAO,gBAAgB,GAAG;AAChC,QAAMA,OAAqB,CAAC;AAC5B,QAAM,SAAmB,CAAC;AAC1B,MAAI,QAAQ;AACZ,MAAI,QAAQ;AACZ,MAAI,QAAQ;AACZ,QAAM,QAAQ,MAAM;AAClB,UAAM,IAAI,sCAAsC,KAAK,KAAK;AAC1D,QAAI,EAAG,CAAAA,KAAI,KAAK,EAAE,MAAM,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,QAAQ,QAAQ,GAAG,EAAE,QAAQ,kBAAkB,EAAE,GAAG,QAAQ,CAAC,GAAG,MAAM,EAAE,CAAC;AACnH,YAAQ;AAAA,EACV;AACA,aAAW,MAAM,MAAM;AACrB,QAAI,OAAO;AACT,eAAS;AACT,UAAI,OAAO,MAAO,SAAQ;AAC1B;AAAA,IACF;AACA,QAAI,OAAO,OAAO,OAAO,KAAK;AAC5B,cAAQ;AACR,eAAS;AAAA,IACX,WAAW,OAAO,KAAK;AACrB;AACA,eAAS;AAAA,IACX,WAAW,OAAO,KAAK;AACrB,cAAQ,KAAK,IAAI,GAAG,QAAQ,CAAC;AAC7B,eAAS;AAAA,IACX,WAAW,OAAO,OAAO,UAAU,GAAG;AACpC,aAAO,KAAK,MAAM,KAAK,EAAE,QAAQ,QAAQ,GAAG,CAAC;AAC7C,cAAQ;AAAA,IACV,WAAW,OAAO,OAAO,UAAU,GAAG;AACpC,YAAM;AACN,aAAO,IAAI;AAAA,IACb,WAAW,OAAO,OAAO,UAAU,GAAG;AACpC,YAAM;AAAA,IACR,OAAO;AACL,eAAS;AAAA,IACX;AAAA,EACF;AACA,SAAOA;AACT;AAEA,IAAM,OAAO;AACb,IAAM,QAAQ;AACd,IAAM,QAAQ;AAGd,SAAS,QAAQ,GAAgB,GAAgF;AAC/G,aAAW,SAAS,EAAE,QAAQ;AAC5B,QAAI,EAAE,SAAS,WAAW,KAAK,KAAK,KAAK,EAAG,QAAO;AACnD,QAAI,EAAE,SAAS,UAAU,MAAM,KAAK,KAAK,EAAG,QAAO;AACnD,UAAM,QAAQ,MAAM,KAAK,KAAK;AAC9B,QAAI,SAAS,CAAC,kBAAkB,KAAK,MAAM,CAAC,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,MAAO,QAAO;AAG/E,QAAI,CAAC,MAAM,WAAW,GAAG,KAAK,CAAC,6DAA6D,KAAK,KAAK,EAAG,QAAO;AAAA,EAClH;AACA,SAAO;AACT;AAKA,IAAM,cAAc;AACpB,IAAM,cAAc,oBAAI,IAAI;AAAA,EAAC;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAO;AAAA,EAAS;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAS;AAAA,EAAS;AAAA,EACtI;AAAA,EAAa;AAAA,EAAc;AAAA,EAAgB;AAAA,EAAS;AAAA,EAAU;AAAA,EAAmB;AAAA,EAAmB;AAAA,EACpG;AAAA,EAA6B;AAAA,EAA6B;AAAA,EAAe;AAAA,EAAQ;AAAA,EAAa;AAAA,EAAc;AAAA,EAAc;AAAA,EAAS;AAAQ,CAAC;AAE9I,SAAS,WAAW,OAA8B;AAChD,QAAM,IAAI,MAAM,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAC1C,MAAI,MAAM,MAAM,EAAE,SAAS,OAAO,CAAC,YAAY,KAAK,CAAC,EAAG,QAAO;AAC/D,aAAW,KAAK,EAAE,SAAS,iBAAiB,EAAG,KAAI,CAAC,YAAY,IAAI,EAAE,CAAC,EAAE,YAAY,CAAC,EAAG,QAAO;AAChG,MAAI,cAAc,KAAK,CAAC,EAAG,QAAO;AAClC,SAAO;AACT;AAGA,IAAM,iBAAiB;AAGvB,IAAM,eAAe,CAAC,cAAsB;AAC1C,QAAM,QAAQ,UAAU,MAAM,QAAQ,EAAE,OAAO,OAAO;AACtD,SAAO,MAAM,SAAS,KAAK,MAAM,MAAM,CAAC,QAAQ,eAAe,KAAK,GAAG,CAAC;AAC1E;AAkBO,SAAS,oBAAoB,KAAwB,UAAiC,CAAC,GAAoB;AAChH,QAAM,OAAO,QAAQ,QAAQ;AAC7B,QAAM,OAAO,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,GAAG,GAAG,QAAQ,YAAY;AACnE,QAAM,QAAQ,QAAQ,SAAS,IAAI,IAAI,CAAC,MAAM,EAAE,OAAO,IAAI,CAAC,MAAM,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,KAAK,CAAC,kBAAkB,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO;AAChJ,QAAM,OAAO,oBAAI,IAAoB;AACrC,aAAW,KAAK,KAAK;AACnB,QAAI,CAAC,QAAQ,GAAG,EAAE,MAAM,OAAO,MAAM,CAAC,EAAG;AACzC,QAAI,CAAC,EAAE,OAAO,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK,aAAa,CAAC,CAAC,EAAG;AAClE,SAAK,IAAI,EAAE,MAAM,EAAE,KAAK;AAAA,EAC1B;AAEA,QAAM,SAAS,CAAC,OAAe,QAAQ,MAAqB;AAC1D,QAAI,QAAQ,GAAI,QAAO;AACvB,QAAI,SAAS;AACb,QAAIA,OAAM;AACV,aAAS,QAAQ,GAAG,QAAQ,IAAI,SAAS;AACvC,YAAM,OAAOA,KAAI,QAAQ,wEAAwE,CAAC,IAAI,MAAc,aAAsB;AACxI,cAAM,QAAQ,KAAK,IAAI,IAAI;AAC3B,cAAM,MAAM,UAAU,SAAY,OAAO,OAAO,QAAQ,CAAC,IAAI,aAAa,SAAY,OAAO,SAAS,KAAK,GAAG,QAAQ,CAAC,IAAI;AAC3H,YAAI,QAAQ,KAAM,UAAS;AAC3B,eAAO,OAAO;AAAA,MAChB,CAAC;AACD,UAAI,OAAQ,QAAO;AACnB,UAAI,SAASA,KAAK;AAClB,MAAAA,OAAM;AAAA,IACR;AACA,WAAOA;AAAA,EACT;AACA,QAAM,SAAiC,CAAC;AACxC,QAAM,WAAqB,CAAC;AAC5B,aAAW,CAAC,MAAM,GAAG,KAAK,MAAM;AAC9B,QAAI,CAAC,kCAAkC,KAAK,IAAI,EAAG;AACnD,UAAM,UAAU,OAAO,GAAG;AAC1B,UAAM,QAAQ,YAAY,OAAO,OAAO,WAAW,OAAO;AAC1D,QAAI,UAAU,KAAM,UAAS,KAAK,GAAG,IAAI,MAAM,IAAI,SAAS,KAAK,IAAI,MAAM,GAAG,EAAE,IAAI,WAAM,GAAG,+BAA+B;AAAA,QACvH,QAAO,IAAI,IAAI;AAAA,EACtB;AACA,MAAI,OAAO,KAAK,MAAM,EAAE,WAAW,EAAG,UAAS,KAAK,gDAAgD;AACpG,SAAO,EAAE,QAAQ,SAAS;AAC5B;AAIA,SAAS,QAAQ,OAAe,MAA2B,OAAO,GAAkB;AAClF,MAAI,OAAO,GAAI,QAAO;AACtB,MAAI,aAAa;AAEjB,MAAIA,OAAM;AACV,WAAS,QAAQ,GAAG,QAAQ,MAAM,QAAQ,KAAKA,IAAG,GAAG,SAAS;AAC5D,IAAAA,OAAMA,KAAI,QAAQ,iEAAiE,CAAC,IAAI,MAAc,aAAsB;AAC1H,YAAM,QAAQ,KAAK,IAAI,IAAI;AAC3B,YAAM,OAAO,UAAU,SAAY,QAAQ,OAAO,MAAM,OAAO,CAAC,IAAI,aAAa,SAAY,QAAQ,SAAS,KAAK,GAAG,MAAM,OAAO,CAAC,IAAI;AACxI,UAAI,SAAS,KAAM,cAAa;AAChC,aAAO,QAAQ;AAAA,IACjB,CAAC;AACD,QAAI,WAAY,QAAO;AAAA,EACzB;AACA,SAAO,QAAQ,KAAKA,IAAG,IAAI,OAAOA,KAAI,KAAK;AAC7C;AAEA,IAAM,UAAU,CAAC,MAAc,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC;AACzD,IAAM,OAAO,CAAC,MAAc,KAAK,MAAM,QAAQ,CAAC,IAAI,GAAG,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AACrF,IAAM,QAAQ,CAAC,MAAe,KAAK,WAAY,QAAQ,IAAI,QAAQ,KAAK,IAAI,GAAG,IAAI,GAAG,IAAI;AAE1F,SAAS,IAAI,GAAW,GAAW,GAAW,IAAI,GAAW;AAC3D,MAAI,KAAK,EAAG,QAAO,IAAI,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;AAClD,SAAO,QAAQ,KAAK,MAAM,QAAQ,CAAC,IAAI,GAAG,CAAC,KAAK,KAAK,MAAM,QAAQ,CAAC,IAAI,GAAG,CAAC,KAAK,KAAK,MAAM,QAAQ,CAAC,IAAI,GAAG,CAAC,KAAK,KAAK,MAAM,QAAQ,CAAC,IAAI,GAAI,IAAI,GAAI;AACxJ;AAEA,IAAM,QAAQ,CAAC,MAA2B,MAAM,SAAY,IAAI,EAAE,SAAS,GAAG,IAAI,WAAW,CAAC,IAAI,MAAM,WAAW,CAAC;AAEpH,IAAM,WAAmC,EAAE,OAAO,WAAW,OAAO,UAAU;AAGvE,SAAS,QAAQ,OAA8B;AACpD,QAAM,IAAI,MAAM,KAAK,EAAE,YAAY;AACnC,MAAI,SAAS,CAAC,EAAG,QAAO,SAAS,CAAC;AAClC,MAAI,6CAA6C,KAAK,CAAC,EAAG,QAAO;AACjE,MAAI,IAAI,uFAAuF,KAAK,CAAC;AACrG,MAAI,GAAG;AACL,UAAM,KAAK,CAAC,MAAe,EAAE,SAAS,GAAG,IAAI,WAAW,CAAC,IAAI,MAAM,WAAW,CAAC,IAAI;AACnF,WAAO,IAAI,GAAG,EAAE,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC;AAAA,EACtD;AACA,MAAI,2FAA2F,KAAK,CAAC;AACrG,MAAI,GAAG;AACL,UAAM,KAAM,WAAW,EAAE,CAAC,CAAC,IAAI,MAAO,OAAO;AAC7C,UAAM,IAAI,WAAW,EAAE,CAAC,CAAC,IAAI;AAC7B,UAAM,IAAI,WAAW,EAAE,CAAC,CAAC,IAAI;AAC7B,UAAM,IAAI,CAAC,MAAc;AACvB,YAAM,KAAK,IAAI,IAAI,MAAM;AACzB,aAAO,IAAI,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC;AAAA,IAC5E;AACA,WAAO,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC;AAAA,EAC1C;AACA,MAAI,qFAAqF,KAAK,CAAC;AAC/F,MAAI,GAAG;AACL,UAAM,IAAI,EAAE,CAAC,EAAE,SAAS,GAAG,IAAI,WAAW,EAAE,CAAC,CAAC,IAAI,MAAM,WAAW,EAAE,CAAC,CAAC;AACvE,UAAM,IAAI,EAAE,CAAC,EAAE,SAAS,GAAG,IAAK,WAAW,EAAE,CAAC,CAAC,IAAI,MAAO,MAAM,WAAW,EAAE,CAAC,CAAC;AAC/E,UAAM,IAAK,WAAW,EAAE,CAAC,CAAC,IAAI,KAAK,KAAM;AACzC,UAAM,IAAI,IAAI,KAAK,IAAI,CAAC;AACxB,UAAM,IAAI,IAAI,KAAK,IAAI,CAAC;AACxB,UAAM,IAAI,KAAK,IAAI,IAAI,eAAe,IAAI,eAAe,GAAG,CAAC;AAC7D,UAAM,KAAK,KAAK,IAAI,IAAI,eAAe,IAAI,eAAe,GAAG,CAAC;AAC9D,UAAM,IAAI,KAAK,IAAI,IAAI,eAAe,IAAI,cAAc,GAAG,CAAC;AAC5D,WAAO;AAAA,MACL,MAAM,eAAe,IAAI,eAAe,KAAK,eAAe,CAAC;AAAA,MAC7D,MAAM,gBAAgB,IAAI,eAAe,KAAK,eAAe,CAAC;AAAA,MAC9D,MAAM,gBAAgB,IAAI,eAAe,KAAK,cAAc,CAAC;AAAA,MAC7D,MAAM,EAAE,CAAC,CAAC;AAAA,IACZ;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,SAAS,OAA8B;AAC9C,QAAM,IAAI,yBAAyB,KAAK,MAAM,KAAK,CAAC;AACpD,MAAI,CAAC,EAAG,QAAO;AACf,QAAM,KAAK,WAAW,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,SAAS,EAAE,CAAC,MAAM,OAAO,KAAK;AACtE,SAAO,OAAO,SAAS,EAAE,IAAI,KAAK,IAAI,YAAY,KAAK,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC,CAAC,IAAI;AACnF;AAGA,SAAS,OAAO,OAA8B;AAC5C,QAAM,IAAI,MAAM,KAAK;AACrB,SAAO,6BAA6B,KAAK,CAAC,MAAM,EAAE,MAAM,IAAI,GAAG,UAAU,KAAK,MAAM,MAAM,EAAE,MAAM,IAAI,GAAG,UAAU,KAAK,MAAM,IAAI,IAAI;AACxI;AAKA,IAAM,SAA0C;AAAA,EAC9C,CAAC,cAAc,CAAC,mBAAmB,cAAc,CAAC;AAAA,EAClD,CAAC,WAAW,CAAC,0BAA0B,qBAAqB,CAAC;AAAA,EAC7D,CAAC,QAAQ,CAAC,qBAAqB,mBAAmB,CAAC;AAAA,EACnD,CAAC,aAAa,CAAC,qBAAqB,CAAC;AAAA,EACrC,CAAC,UAAU,CAAC,uBAAuB,qBAAqB,CAAC;AAAA,EACzD,CAAC,WAAW,CAAC,gBAAgB,qBAAqB,CAAC;AAAA,EACnD,CAAC,eAAe,CAAC,qBAAqB,mBAAmB,CAAC;AAAA,EAC1D,CAAC,UAAU,CAAC,mBAAmB,qBAAqB,aAAa,CAAC;AAAA,EAClE,CAAC,SAAS,CAAC,wBAAwB,YAAY,CAAC;AAAA,EAChD,CAAC,mBAAmB,CAAC,iBAAiB,CAAC;AAAA,EACvC,CAAC,WAAW,CAAC,0BAA0B,cAAc,CAAC;AAAA,EACtD,CAAC,qBAAqB,CAAC,mBAAmB,CAAC;AAC7C;AAWO,SAAS,mBAAmB,KAAwB,UAAiC,CAAC,GAAkB;AAC7G,QAAM,IAAI,EAAE,MAAM,QAAQ,QAAQ,SAAS,OAAO,QAAQ,MAAM;AAChE,QAAM,OAAO,oBAAI,IAAoB;AACrC,aAAW,SAAS,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,GAAG,GAAG;AACpD,eAAW,KAAK,aAAa,KAAK,EAAG,KAAI,QAAQ,GAAG,CAAC,EAAG,MAAK,IAAI,EAAE,MAAM,EAAE,KAAK;AAAA,EAClF;AACA,QAAM,QAAqB,CAAC;AAC5B,QAAM,WAAqB,CAAC;AAE5B,QAAM,OAAO,CAAI,QAAkB,IAA6B,SAAgC;AAC9F,eAAW,SAAS,QAAQ;AAC1B,YAAM,MAAM,KAAK,IAAI,KAAK;AAC1B,UAAI,QAAQ,OAAW;AACvB,YAAM,QAAQ,QAAQ,KAAK,IAAI;AAC/B,YAAM,MAAM,UAAU,OAAO,OAAO,GAAG,KAAK;AAC5C,UAAI,QAAQ,KAAM,QAAO;AACzB,eAAS,KAAK,GAAG,KAAK,MAAM,GAAG,YAAY,IAAI,kBAAkB;AAAA,IACnE;AACA,WAAO;AAAA,EACT;AAEA,aAAW,CAAC,OAAO,MAAM,KAAK,QAAQ;AACpC,UAAM,IAAI,KAAK,QAAQ,SAAS,UAAU;AAC1C,QAAI,MAAM,OAAW,CAAC,MAAkC,KAAK,IAAI;AAAA,EACnE;AACA,QAAM,SAAS,KAAK,CAAC,yBAAyB,gBAAgB,GAAG,UAAU,UAAU;AACrF,MAAI,WAAW,OAAW,OAAM,SAAS;AACzC,QAAM,SAAS,KAAK,CAAC,2BAA2B,gBAAgB,GAAG,UAAU,UAAU;AACvF,MAAI,WAAW,OAAW,OAAM,eAAe;AAC/C,QAAM,OAAO,KAAK,CAAC,kBAAkB,GAAG,QAAQ,aAAa;AAC7D,MAAI,SAAS,OAAW,OAAM,aAAa;AAC3C,MAAI,QAAQ,QAAS,OAAM,UAAU,QAAQ;AAE7C,MAAI,KAAK,SAAS,EAAG,UAAS,KAAK,0FAA0F;AAAA,WACpH,CAAC,CAAC,GAAG,KAAK,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,EAAE,WAAW,OAAO,CAAC,EAAG,UAAS,KAAK,gDAAgD;AAC7H,SAAO,EAAE,OAAO,SAAS;AAC3B;AAmJO,SAAS,OAAO,OAA6C;AAClE,QAAM,QAA2C;AAAA,IAC/C,YAAY;AAAA,IAAc,SAAS;AAAA,IAAW,MAAM;AAAA,IAAQ,WAAW;AAAA,IAAc,QAAQ;AAAA,IAC7F,SAAS;AAAA,IAAW,aAAa;AAAA,IAAgB,QAAQ;AAAA,IAAU,OAAO;AAAA,IAAS,iBAAiB;AAAA,IACpG,SAAS;AAAA,IAAW,mBAAmB;AAAA,IAAsB,QAAQ;AAAA,IAAU,cAAc;AAAA,IAC7F,YAAY;AAAA,IAAe,SAAS;AAAA,IAAY,OAAO;AAAA,IAAS,QAAQ;AAAA,IAAU,aAAa;AAAA,IAC/F,WAAW;AAAA,IAAc,cAAc;AAAA,IAAkB,OAAO;AAAA,IAAS,iBAAiB;AAAA,IAAoB,aAAa;AAAA,IAAgB,QAAQ;AAAA,EACrJ;AACA,QAAM,OAAgC,CAAC;AACvC,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,KAAK,GAAG;AAC1C,QAAI,MAAM,UAAa,MAAM,MAAO,MAAM,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAI;AACzE,SAAK,MAAM,CAAsB,CAAC,IAAI;AAAA,EACxC;AACA,SAAO;AACT;AAGO,SAAS,SAAS,MAA4C;AACnE,QAAM,QAA2C;AAAA,IAC/C,YAAY;AAAA,IAAc,SAAS;AAAA,IAAW,MAAM;AAAA,IAAQ,YAAY;AAAA,IAAa,QAAQ;AAAA,IAC7F,SAAS;AAAA,IAAW,cAAc;AAAA,IAAe,QAAQ;AAAA,IAAU,OAAO;AAAA,IAAS,kBAAkB;AAAA,IACrG,SAAS;AAAA,IAAW,oBAAoB;AAAA,IAAqB,QAAQ;AAAA,IAAU,eAAe;AAAA,IAC9F,aAAa;AAAA,IAAc,UAAU;AAAA,IAAW,OAAO;AAAA,IAAS,QAAQ;AAAA,IAAU,cAAc;AAAA,IAChG,YAAY;AAAA,IAAa,gBAAgB;AAAA,IAAgB,OAAO;AAAA,IAAS,kBAAkB;AAAA,IAAmB,cAAc;AAAA,IAAe,QAAQ;AAAA,EACrJ;AACA,QAAM,QAAiC,CAAC;AACxC,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,QAAQ,CAAC,CAAC,EAAG,KAAI,MAAM,CAAC,KAAK,MAAM,UAAa,MAAM,QAAQ,MAAM,GAAI,OAAM,MAAM,CAAC,CAAC,IAAI;AAC9H,SAAO;AACT;AAuBA,eAAsB,UAAU,GAAoC;AAClE,QAAMC,OAAM,CAAC,MAAe,OAAO,YAAY,cAAc,QAAQ,MAAM,CAAC,IAAI;AAChF,QAAM,SAAS,uBAAuB,EAAE,UAAUA,KAAI,eAAe,KAAK,EAAE;AAC5E,QAAM,WAAW,EAAE,YAAYA,KAAI,kBAAkB,KAAK;AAC1D,QAAM,SAAS,EAAE,UAAUA,KAAI,eAAe,KAAK;AACnD,QAAM,QAAQ,EAAE,SAASA,KAAI,cAAc,KAAK;AAChD,aAAW,CAAC,MAAM,CAAC,KAAK,OAAO,QAAQ,EAAE,eAAe,QAAQ,kBAAkB,UAAU,eAAe,QAAQ,cAAc,MAAM,CAAC,GAAG;AACzI,QAAI,MAAM,GAAI,OAAM,IAAI,MAAM,gBAAgB,IAAI,8BAA8B;AAAA,EAClF;AACA,QAAM,MAAM,OAAO,EAAE,SAAS,OAAO,GAAG,MAAM,qBAAqB,mBAAmB,QAAQ,CAAC,UAAU;AAAA,IACvG,QAAQ;AAAA,IACR,SAAS,EAAE,eAAe,UAAU,KAAK,IAAI,gBAAgB,QAAQ,gBAAgB,mBAAmB;AAAA,IACxG,MAAM,KAAK,UAAU,OAAO,EAAE,KAAK,CAAC;AAAA,EACtC,CAAC;AACD,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,OAAQ,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI;AAC/C,UAAM,IAAI,MAAM,0CAA0C,IAAI,MAAM,MAAM,MAAM,SAAS,CAAC,GAAG,WAAW,IAAI,UAAU,EAAE;AAAA,EAC1H;AACF;;;ACrfO,IAAM,oBAAN,cAAgC,MAAM;AAAA,EAC3C,YAAY,SAAiB;AAC3B,UAAM,gBAAgB,OAAO,EAAE;AAC/B,SAAK,OAAO;AAAA,EACd;AACF;;;AHnIA,IAAM,iBAAiB;AAEvB,IAAM,UAAU;AA0BT,IAAM,iBAAN,cAA6B,MAAM;AAAA,EACxC,YACW,QAEA,MACT,SACA;AACA,UAAM,gBAAgB,OAAO,EAAE;AALtB;AAEA;AAIT,SAAK,OAAO;AAAA,EACd;AAAA,EAPW;AAAA,EAEA;AAMb;AAmEA,SAAS,IAAI,MAAkC;AAC7C,SAAO,OAAO,YAAY,cAAc,QAAQ,MAAM,IAAI,IAAI;AAChE;AAOA,SAAS,eAAe,GAA0B;AAChD,SAAO;AAAA,IAAE,IAAI,EAAE;AAAA,IAAI,QAAQ,EAAE;AAAA,IAAQ,MAAM,EAAE;AAAA,IAAM,MAAM,EAAE;AAAA,IAAM,YAAY,EAAE;AAAA,IAAa,QAAQ,EAAE;AAAA,IACpG,UAAU,EAAE,YAAY,CAAC;AAAA,IAAG,SAAS,EAAE;AAAA,IAAS,WAAW,EAAE;AAAA,IAAY,WAAW,EAAE;AAAA,EAAW;AACrG;AAIA,SAAS,SAAS,GAAmC;AACnD,SAAO,EAAE,QAAQ,EAAE,SAAS,OAAO,EAAE,OAAO,MAAM,EAAE,MAAM,QAAQ,EAAE,QAAQ,MAAM,EAAE,MAAM,GAAI,EAAE,YAAY,SAAY,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAG;AACvJ;AAEA,SAAS,MAAM,GAA+B;AAC5C,MAAI,OAAO,EAAE,eAAe,SAAU,QAAO,EAAE;AAC/C,SAAO,EAAE,WAAW,SAAS,OAAO,IAAI,SAAa,KAAK,MAAM,EAAE,UAAU;AAC9E;AAEA,eAAe,QAAQ,GAA6C;AAClE,QAAM,MAAM,MAAM,CAAC;AAEnB,SAAO,MAAM,UAAU,KAAK,OAAO,IAAI,YAAY,EAAE,YAAsB,SAAS,EAAE,aAAa,KAAK,CAAC;AAC3G;AAEO,SAAS,aAAa,QAAuB,CAAC,GAAiB;AACpE,QAAM,SAAS,uBAAuB,MAAM,UAAU,IAAI,eAAe,KAAK,EAAE;AAChF,QAAM,WAAW,MAAM,YAAY,IAAI,kBAAkB,KAAK;AAC9D,QAAM,eAAe,MAAM,gBAAgB,IAAI,sBAAsB,KAAK;AAC1E,QAAM,SAAS,IAAI,mBAAmB;AACtC,QAAM,MAAM,MAAM,QAAQ,SAAS,EAAE,YAAY,QAAQ,OAAO,IAAI,sBAAsB,KAAK,GAAG,IAAI;AACtG,QAAM,UAAwB,IAAI,UAAU,MAAM,SAAS,OAAO,GAAG,IAAI;AACzE,QAAM,gBAAgB,GAAG,MAAM;AAI/B,WAAS,aAAmB;AAC1B,QAAI,CAAC,eAAe,KAAK,MAAM,EAAG,OAAM,IAAI,kBAAkB,iDAAkD;AAChH,QAAI,aAAa,GAAI,OAAM,IAAI,kBAAkB,yCAAyC;AAC1F,QAAI,MAAM,IAAI,UAAU,KAAK,iBAAiB,IAAI;AAChD,YAAM,IAAI,kBAAkB,MAAM,gDAC9B,wGAAwG;AAAA,IAC9G;AAAA,EACF;AAEA,MAAI;AACJ,QAAM,aAAa,MAAO,aAAa,QAAQ,GAAgB;AAE/D,iBAAe,KAAK,KAAe,MAA8B;AAC/D,UAAM,OAAQ,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI;AAC/C,UAAM,QAAQ,MAAM,SAAS,CAAC;AAC9B,UAAM,IAAI,eAAe,IAAI,QAAQ,OAAO,QAAQ,SAAS,kBAAkB,IAAI,KAAK,IAAI,MAAM,MAAM,OAAO,WAAW,IAAI,UAAU,EAAE;AAAA,EAC5I;AAEA,MAAI;AACJ,MAAI;AAEJ,iBAAe,MAAuB;AACpC,eAAW;AACX,UAAM,OAAO,IAAI,gBAAgB,EAAE,YAAY,sBAAsB,WAAW,SAAS,CAAC;AAC1F,QAAI,KAAK;AACP,YAAM,YAAY,MAAM,IAAI,QAAQ,CAAC,CAAC,EACnC,mBAAmB,EAAE,KAAK,SAAS,KAAK,IAAI,MAAM,CAAC,EACnD,UAAU,QAAQ,EAAE,WAAW,QAAQ,EAAE,YAAY,aAAa,EAClE,OAAO,OAAO,WAAW,CAAC,EAAE,YAAY,EAAE,kBAAkB,IAAI,EAChE,KAAK,MAAM,WAAW,CAAC;AAC1B,WAAK,IAAI,yBAAyB,cAAc;AAChD,WAAK,IAAI,oBAAoB,SAAS;AAAA,IACxC,OAAO;AACL,WAAK,IAAI,iBAAiB,YAAY;AAAA,IACxC;AACA,UAAM,MAAM,MAAM,QAAQ,eAAe,EAAE,QAAQ,QAAQ,SAAS,EAAE,gBAAgB,oCAAoC,GAAG,MAAM,KAAK,CAAC;AACzI,QAAI,CAAC,IAAI,GAAI,OAAM,KAAK,KAAK,6BAA8B;AAC3D,UAAM,IAAK,MAAM,IAAI,KAAK;AAC1B,WAAO,EAAE,OAAO,EAAE,cAAc,OAAO,KAAK,IAAI,IAAI,EAAE,aAAa,MAAO,QAAQ;AAClF,WAAO,EAAE;AAAA,EACX;AAEA,WAAS,QAAyB;AAChC,QAAI,QAAQ,KAAK,IAAI,IAAI,KAAK,MAAO,QAAO,QAAQ,QAAQ,KAAK,KAAK;AAEtE,WAAQ,WAAW,IAAI,EAAE,QAAQ,MAAM;AAAE,eAAS;AAAA,IAAU,CAAC;AAAA,EAC/D;AAEA,iBAAe,KAAK,QAAgB,MAAc,MAAkC;AAClF,UAAM,OAAO,YAAY,QAAQ,GAAG,MAAM,GAAG,IAAI,IAAI;AAAA,MACnD;AAAA,MACA,SAAS,EAAE,eAAe,UAAU,MAAM,MAAM,CAAC,IAAI,GAAI,SAAS,SAAY,CAAC,IAAI,EAAE,gBAAgB,mBAAmB,EAAG;AAAA,MAC3H,MAAM,SAAS,SAAY,SAAY,KAAK,UAAU,IAAI;AAAA,IAC5D,CAAC;AACD,QAAI,MAAM,MAAM,KAAK;AACrB,QAAI,IAAI,WAAW,OAAO,MAAM;AAE9B,aAAO;AACP,YAAM,MAAM,KAAK;AAAA,IACnB;AACA,QAAI,CAAC,IAAI,GAAI,OAAM,KAAK,KAAK,GAAG,MAAM,IAAI,IAAI,EAAE;AAChD,WAAO,IAAI,WAAW,MAAM,SAAY,IAAI,KAAK;AAAA,EACnD;AAEA,QAAM,OAAO,OAAU,QAAgB,MAAc,UAAqB,MAAM,KAAK,QAAQ,MAAM,IAAI,IAAgC;AACvI,QAAM,KAAK;AAEX,SAAO;AAAA,IACL;AAAA,IACA,SAAS;AAAA,IACT,eAAe;AAAA,MACb,MAAM,KAAK,QAAQ,CAAC,GAAG;AACrB,cAAM,IAAI,IAAI,gBAAgB;AAC9B,mBAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,KAAK,EAAG,KAAI,MAAM,OAAW,GAAE,IAAI,GAAG,OAAO,CAAC,CAAC;AACnF,cAAMC,OAAO,MAAM,KAAK,OAAO,oBAAoB,EAAE,OAAO,IAAI,CAAC,KAAK,EAAE,EAAE;AAC1E,eAAO,EAAE,OAAOA,KAAI,KAAK,IAAI,cAAc,GAAG,OAAOA,KAAI,YAAY;AAAA,MACvE;AAAA,MACA,MAAM,OAAO,OAAO;AAClB,eAAO,eAAe,MAAM;AAAA,UAAc;AAAA,UAAQ;AAAA,UAChD,EAAE,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,aAAa,MAAM,YAAY,UAAU,MAAM,SAAS;AAAA,QAAC,CAAC;AAAA,MACpG;AAAA,MACA,MAAM,IAAI,OAAO;AACf,eAAO,eAAe,MAAM,KAAc,OAAO,qBAAqB,GAAG,KAAK,CAAC,EAAE,CAAC;AAAA,MACpF;AAAA,MACA,MAAM,OAAO,OAAO,OAAO;AACzB,eAAO,eAAe,MAAM,KAAc,SAAS,qBAAqB,GAAG,KAAK,CAAC,IAAI,KAAK,CAAC;AAAA,MAC7F;AAAA,MACA,MAAM,OAAO,OAAO;AAClB,cAAM,KAAK,UAAU,qBAAqB,GAAG,KAAK,CAAC,EAAE;AAAA,MACvD;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,MAAM,KAAK,OAAO;AAChB,gBAAQ,MAAM,KAAmB,OAAO,qBAAqB,GAAG,KAAK,CAAC,UAAU,GAAG,IAAI,QAAQ;AAAA,MACjG;AAAA,MACA,MAAM,IAAI,OAAO,GAAG;AAClB,eAAO,SAAS,MAAM;AAAA,UAAiB;AAAA,UAAQ,qBAAqB,GAAG,KAAK,CAAC;AAAA,UAC3E,EAAE,MAAM,EAAE,MAAM,SAAS,EAAE,QAAQ,OAAO,EAAE,OAAO,MAAM,EAAE,MAAM,QAAQ,EAAE,QAAQ,WAAW,SAAS;AAAA,QAAC,CAAC;AAAA,MAC7G;AAAA,MACA,MAAM,QAAQ,OAAO,QAAQ,MAAM;AACjC,eAAO,SAAS,MAAM,KAAiB,OAAO,qBAAqB,GAAG,KAAK,CAAC,YAAY,GAAG,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAAA,MACjH;AAAA,MACA,MAAM,OAAO,OAAO,QAAQ;AAC1B,cAAM,KAAK,UAAU,qBAAqB,GAAG,KAAK,CAAC,YAAY,GAAG,MAAM,CAAC,EAAE;AAAA,MAC7E;AAAA,IACF;AAAA,IACA,MAAM,OAAO,QAAQ;AAEnB,YAAM,IAAI,MAAM,KAAoC,QAAQ,aAAa,EAAE,GAAG,QAAQ,WAAW,SAAS,CAAC;AAC3G,aAAO,EAAE,IAAI,EAAE,IAAI,OAAO,EAAE,MAAM;AAAA,IACpC;AAAA,IACA,OAAO;AAAA,MACL,MAAM,IAAI,KAAK,UAAU;AACvB,eAAO,SAAS,MAAM,KAA8B,OAAO,qBAAqB,GAAG,EAAE,CAAC,QAAQ,CAAC;AAAA,MACjG;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,MACN,MAAM,IAAI,QAAQ;AAChB,gBAAQ,MAAM,KAAuD,OAAO,eAAe,GAAG,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC;AAAA,MAC7H;AAAA,IACF;AAAA,IACA,MAAM,aAAa;AACjB,UAAI,CAAC,IAAK,QAAO,EAAE,MAAM,CAAC,EAAE;AAC5B,YAAM,EAAE,KAAK,GAAG,EAAE,IAAI,MAAM,GAAG,KAAM,MAAM,UAAU,MAAM,WAAW,CAAC;AACvE,aAAO,EAAE,MAAM,CAAC,EAAE,KAAK,GAAG,GAAG,KAAK,IAAI,OAAO,KAAK,SAAS,KAAK,MAAM,CAAC,EAAE;AAAA,IAC3E;AAAA,EACF;AACF;;;AIjRO,IAAM,eAAe;AAC5B,IAAM,eAAe;AACrB,IAAM,WAAW;AAIjB,IAAM,QAAQ;AAEP,SAAS,WAAW,OAAqC;AAC9D,QAAM,IAAI,OAAO,UAAU,WAAW,MAAM,KAAK,IAAI;AACrD,MAAI,MAAM,GAAI,QAAO,EAAE,OAAO,SAAS,MAAM,YAAY,SAAS,4BAA4B;AAC9F,MAAI,EAAE,SAAS,OAAO,CAAC,MAAM,KAAK,CAAC,EAAG,QAAO,EAAE,OAAO,SAAS,MAAM,iBAAiB,SAAS,4CAA4C;AAC3I,SAAO;AACT;AAGO,SAAS,cAAc,OAAqC;AACjE,MAAI,OAAO,UAAU,YAAY,UAAU,GAAI,QAAO,EAAE,OAAO,YAAY,MAAM,YAAY,SAAS,uBAAuB;AAC7H,MAAI,MAAM,SAAS,aAAc,QAAO,EAAE,OAAO,YAAY,MAAM,YAAY,SAAS,6BAA6B;AACrH,SAAO;AACT;AAGO,SAAS,iBAAiB,OAAqC;AACpE,QAAM,QAAQ,cAAc,KAAK;AACjC,MAAI,MAAO,QAAO;AAClB,MAAK,MAAiB,SAAS,cAAc;AAC3C,WAAO,EAAE,OAAO,YAAY,MAAM,aAAa,SAAS,gBAAgB,YAAY,eAAe;AAAA,EACrG;AACA,SAAO;AACT;AAEO,SAAS,UAAU,OAAqC;AAC7D,MAAI,UAAU,UAAa,UAAU,QAAQ,UAAU,GAAI,QAAO;AAClE,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,SAAS,SAAU,QAAO,EAAE,OAAO,QAAQ,MAAM,YAAY,SAAS,eAAe,QAAQ,eAAe;AAC1J,SAAO;AACT;AAGO,IAAM,mBAAmB;AAEzB,SAAS,kBAAkB,OAAgB,WAAW,OAA4B;AACvF,QAAM,IAAI,OAAO,UAAU,WAAW,MAAM,KAAK,IAAI;AACrD,MAAI,MAAM,GAAI,QAAO,WAAW,EAAE,OAAO,gBAAgB,MAAM,YAAY,SAAS,6BAA6B,IAAI;AACrH,MAAI,EAAE,SAAS,iBAAkB,QAAO,EAAE,OAAO,gBAAgB,MAAM,YAAY,SAAS,eAAe,gBAAgB,eAAe;AAC1I,SAAO;AACT;AAEO,SAAS,UAAU,OAAqC;AAC7D,QAAM,IAAI,OAAO,UAAU,WAAW,MAAM,KAAK,IAAI;AACrD,MAAI,MAAM,GAAI,QAAO,EAAE,OAAO,QAAQ,MAAM,YAAY,SAAS,kBAAkB;AACnF,MAAI,EAAE,SAAS,GAAI,QAAO,EAAE,OAAO,QAAQ,MAAM,YAAY,SAAS,sBAAsB;AAC5F,SAAO;AACT;AAGO,SAAS,gBAAgB,QAAsD;AACpF,SAAO,OAAO,KAAK,CAAC,MAAM,MAAM,IAAI,KAAK;AAC3C;;;AC5DA,SAAS,oBAAoB,iBAAuC;AAoB7D,IAAM,qBAAN,cAAiC,MAAM;AAAA,EAC5C,YAAqB,QAAgB;AACnC,UAAM,iCAAiC,MAAM,EAAE;AAD5B;AAEnB,SAAK,OAAO;AAAA,EACd;AAAA,EAHqB;AAIvB;AAgBA,IAAM,OAAO,oBAAI,IAA6B;AAE9C,SAAS,OAAO,QAAiC;AAC/C,MAAI,MAAM,KAAK,IAAI,MAAM;AACzB,MAAI,QAAQ,QAAW;AACrB,UAAM,mBAAmB,IAAI,IAAI,GAAG,MAAM,wBAAwB,GAAG,EAAE,kBAAkB,IAAO,CAAC;AACjG,SAAK,IAAI,QAAQ,GAAG;AAAA,EACtB;AACA,SAAO;AACT;AAEA,IAAM,MAAM,CAAC,MAAgB,OAAO,MAAM,YAAY,MAAM,KAAK,IAAI;AAOrE,eAAsB,cAAc,SAAkB,UAAgC,CAAC,GAAyB;AAC9G,QAAMC,OAAM,OAAO,YAAY,cAAc,QAAQ,KAAK,gBAAgB;AAC1E,QAAM,SAAS,uBAAuB,QAAQ,UAAUA,QAAO,EAAE;AACjE,MAAI,WAAW,GAAI,OAAM,IAAI,mBAAmB,mCAAmC;AACnF,QAAM,YAAY,QAAQ,QAAQ,IAAI,wBAAwB;AAC9D,MAAI,CAAC,UAAW,OAAM,IAAI,mBAAmB,cAAc;AAG3D,QAAM,MAAM,IAAI,WAAW,MAAM,QAAQ,YAAY,CAAC;AACtD,QAAM,WAAW,QAAQ,OAAO,QAAQ,IAAI,MAAM,GAAG,EAAE,CAAC;AAExD,MAAI;AACJ,MAAI;AACF,UAAM,WAAW,MAAM,UAAU,WAAW,QAAQ,QAAQ,OAAO,MAAM,GAAG;AAAA,MAC1E,YAAY,CAAC,OAAO;AAAA,MACpB;AAAA,MACA,KAAK;AAAA,MACL,gBAAgB,CAAC,OAAO,OAAO,OAAO,aAAa;AAAA,MACnD,aAAa,QAAQ;AAAA,MACrB,gBAAgB;AAAA,IAClB,CAAC;AACD,aAAS,SAAS;AAAA,EACpB,SAAS,KAAK;AACZ,UAAM,IAAI,mBAAmB,eAAe,QAAQ,IAAI,UAAU,eAAe;AAAA,EACnF;AAGA,MAAI,OAAO,QAAQ,UAAU,OAAO,eAAe,QAAQ;AACzD,UAAM,IAAI,mBAAmB,8BAA8B;AAAA,EAC7D;AAGA,QAAM,MAAM,KAAK,OAAO,QAAQ,OAAO,oBAAI,KAAK,GAAG,QAAQ,IAAI,GAAI;AACnE,MAAI,OAAO,OAAO,QAAQ,YAAY,OAAO,MAAM,MAAM,GAAI,OAAM,IAAI,mBAAmB,sBAAsB;AAEhH,QAAM,SAAS,IAAI,WAAW,MAAM,OAAO,OAAO,OAAO,WAAW,GAAG,CAAC;AACxE,MAAI,MAAM;AACV,aAAW,KAAK,OAAQ,QAAO,OAAO,aAAa,CAAC;AACpD,QAAM,OAAO,KAAK,GAAG,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,EAAE;AAChF,MAAI,SAAS,OAAO,YAAa,OAAM,IAAI,mBAAmB,yCAAyC;AAEvG,MAAI;AACJ,MAAI;AACF,WAAO,KAAK,MAAM,IAAI,YAAY,EAAE,OAAO,GAAG,CAAC;AAAA,EACjD,QAAQ;AACN,UAAM,IAAI,mBAAmB,sBAAsB;AAAA,EACrD;AAEA,MAAI,KAAK,OAAO,OAAO,OAAO,KAAK,UAAU,OAAO,OAAO,KAAK,cAAc,OAAO,KAAK;AACxF,UAAM,IAAI,mBAAmB,qCAAqC;AAAA,EACpE;AACA,QAAM,QAAS,KAAK,QAAQ,CAAC;AAC7B,SAAO;AAAA,IACL,IAAI,OAAO,KAAK,EAAE;AAAA,IAClB,MAAM,OAAO,KAAK,KAAK;AAAA,IACvB,UAAU,OAAO,KAAK,SAAS;AAAA,IAC/B,WAAW,OAAO,MAAM,cAAc,KAAK,cAAc,EAAE;AAAA,IAC3D,GAAI,IAAI,MAAM,OAAO,IAAI,EAAE,QAAQ,MAAM,QAAQ,IAAI,CAAC;AAAA,IACtD,GAAI,IAAI,MAAM,QAAQ,IAAI,EAAE,SAAS,MAAM,SAAS,IAAI,CAAC;AAAA,IACzD,MAAO,MAAM,QAAQ,CAAC;AAAA,EACxB;AACF;;;ACtFA,IAAM,eAAe;AAGrB,IAAM,eAAe;AAErB,IAAM,gBAAgB;AAEtB,IAAM,eAAe;AACrB,IAAM,uBAAuB;AAE7B,IAAM,cAAc;AAEpB,IAAM,cAAc;AAGpB,SAAS,WAAW,SAAyB;AAC3C,MAAI;AACF,WAAO,mBAAmB,OAAO;AAAA,EACnC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAwDA,SAASC,KAAI,MAAkC;AAC7C,SAAO,OAAO,YAAY,cAAc,QAAQ,MAAM,IAAI,IAAI;AAChE;AAEA,SAAS,OAAO,OAA2B;AACzC,MAAI,IAAI;AACR,aAAW,KAAK,MAAO,MAAK,OAAO,aAAa,CAAC;AACjD,SAAO,KAAK,CAAC,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,EAAE;AAC1E;AAEA,SAAS,OAAO,QAAQ,IAAY;AAClC,SAAO,OAAO,OAAO,gBAAgB,IAAI,WAAW,KAAK,CAAC,CAAC;AAC7D;AAGA,SAAS,UAAU,WAAsC,UAA0B;AACjF,MAAI,CAAC,aAAa,CAAC,UAAU,WAAW,GAAG,KAAK,UAAU,WAAW,IAAI,KAAK,UAAU,SAAS,IAAI,EAAG,QAAO;AAC/G,SAAO;AACT;AAEA,SAAS,KAAK,MAAe,SAAS,KAAK,SAA6B;AACtE,QAAM,IAAI,WAAW,IAAI,QAAQ;AACjC,IAAE,IAAI,gBAAgB,iCAAiC;AACvD,IAAE,IAAI,iBAAiB,UAAU;AACjC,SAAO,IAAI,SAAS,KAAK,UAAU,IAAI,GAAG,EAAE,QAAQ,SAAS,EAAE,CAAC;AAClE;AAEA,SAAS,SAAS,UAAkB,UAAoB,CAAC,GAAa;AACpE,QAAM,IAAI,IAAI,QAAQ,EAAE,UAAU,iBAAiB,WAAW,CAAC;AAC/D,aAAW,KAAK,QAAS,GAAE,OAAO,cAAc,CAAC;AACjD,SAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,KAAK,SAAS,EAAE,CAAC;AACvD;AAEO,SAAS,aAAa,QAAuB,CAAC,GAAW;AAC9D,QAAM,SAAS,uBAAuB,MAAM,UAAUA,KAAI,eAAe,KAAK,EAAE;AAChF,QAAM,WAAW,MAAM,YAAYA,KAAI,kBAAkB,KAAK;AAC9D,QAAM,eAAe,MAAM,gBAAgBA,KAAI,sBAAsB;AACrE,QAAM,SAAS,MAAM,UAAUA,KAAI,eAAe,KAAK;AACvD,QAAM,SAAS,MAAM,UAAUA,KAAI,eAAe,KAAK;AACvD,QAAM,SAAS,MAAM,UAAUA,KAAI,eAAe,KAAK;AACvD,MAAI,CAAC,eAAe,KAAK,MAAM,EAAG,OAAM,IAAI,kBAAkB,8EAA+E;AAC7I,MAAI,aAAa,GAAI,OAAM,IAAI,kBAAkB,yCAAyC;AAC1F,MAAI,OAAO,SAAS,GAAI,OAAM,IAAI,kBAAkB,uFAAuF;AAE3I,QAAM,WAAW,OAAO,MAAM,YAAY,aAAa,QAAQ,cAAc,EAAE;AAC/E,QAAM,cAAc,UAAU,MAAM,aAAa,GAAG;AACpD,QAAM,eAAe,UAAU,MAAM,cAAc,GAAG;AACtD,QAAM,aAAa,MAAM,cAAc;AACvC,QAAM,aAAa,GAAG,UAAU;AAChC,QAAM,cAAc,GAAG,UAAU;AACjC,QAAM,aAAa,GAAG,UAAU;AAChC,QAAM,UAAwB,IAAI,UAAU,MAAM,SAAS,OAAO,GAAG,IAAI;AACzE,QAAM,MAAM,MAAM,MAAM;AACxB,QAAM,QAAQ;AAAA,IACZ,QAAQ,MAAM,OAAO,SAAS,UAAU,MAAM,MAAM,QAAQ,GAAG,IAAI;AAAA,IACnE,eAAe,MAAM,OAAO,gBAAgB,UAAU,MAAM,MAAM,eAAe,GAAG,IAAI;AAAA,IACxF,aAAa,MAAM,OAAO,cAAc,UAAU,MAAM,MAAM,aAAa,GAAG,IAAI;AAAA,EACpF;AACA,QAAM,YAAY,aAAa,EAAE,QAAQ,UAAU,cAAc,KAAK,MAAM,WAAW,OAAO,MAAM,MAAM,CAAC;AAE3G,QAAM,WAAW,CAAC,YAAqB,uBAAuB,MAAM,WAAW,IAAI,IAAI,QAAQ,GAAG,EAAE,MAAM;AAC1G,QAAM,QAAQ,CAAC,SAAkB,YAAsC,EAAE,QAAQ,SAAS,OAAO,EAAE,WAAW,UAAU,GAAG,OAAO;AAIlI,iBAAe,MAAM,MAAgG;AACnH,UAAMC,QAAO,IAAI,gBAAgB,EAAE,WAAW,UAAU,GAAG,KAAK,CAAC;AACjE,QAAI,aAAc,CAAAA,MAAK,IAAI,iBAAiB,YAAY;AACxD,QAAI;AACF,YAAM,MAAM,MAAM,QAAQ,GAAG,MAAM,mBAAmB;AAAA,QACpD,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,qCAAqC,QAAQ,mBAAmB;AAAA,QAC3F,MAAAA;AAAA,MACF,CAAC;AACD,UAAI,IAAI,GAAI,QAAO,EAAE,IAAI,MAAM,MAAM,MAAM,IAAI,KAAK,EAAE;AAGtD,aAAO,EAAE,IAAI,OAAO,OAAO,IAAI,UAAU,OAAO,IAAI,SAAS,IAAI;AAAA,IACnE,QAAQ;AACN,aAAO,EAAE,IAAI,OAAO,OAAO,MAAM;AAAA,IACnC;AAAA,EACF;AAEA,iBAAe,SAAS,aAAuF;AAC7G,QAAI;AACF,YAAM,MAAM,MAAM,QAAQ,GAAG,MAAM,sBAAsB,EAAE,SAAS,EAAE,eAAe,UAAU,WAAW,GAAG,EAAE,CAAC;AAChH,UAAI,CAAC,IAAI,GAAI,QAAO;AACpB,YAAM,IAAK,MAAM,IAAI,KAAK;AAC1B,aAAO;AAAA,QACL,KAAK,OAAO,EAAE,OAAO,EAAE;AAAA,QACvB,OAAO,MAAM,QAAQ,EAAE,KAAK,IAAI,EAAE,MAAM,OAAO,CAAC,MAAe,OAAO,MAAM,QAAQ,IAAI,CAAC;AAAA,QACzF,GAAG;AAAA,UACD,IAAI,OAAO,EAAE,OAAO,EAAE;AAAA,UACtB,OAAO,OAAO,EAAE,SAAS,EAAE;AAAA,UAC3B,MAAM,OAAO,EAAE,QAAQ,EAAE;AAAA,UACzB,eAAe,EAAE,mBAAmB;AAAA,UACpC,YAAY,EAAE,eAAe;AAAA,UAC7B,GAAI,OAAO,EAAE,oBAAoB,WAAW,EAAE,eAAe,EAAE,gBAAgB,IAAI,CAAC;AAAA,UACpF,GAAI,OAAO,EAAE,WAAW,YAAY,EAAE,WAAW,KAAK,EAAE,QAAQ,EAAE,OAAO,IAAI,CAAC;AAAA,UAC9E,GAAI,EAAE,cAAc,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;AAAA,QACtD;AAAA,MACF;AAAA,IACF,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAGA,iBAAe,OAAOA,OAAmC;AACvD,QAAI,OAAOA,OAAM,iBAAiB,YAAY,OAAOA,OAAM,kBAAkB,SAAU,QAAO;AAC9F,UAAM,MAAM,MAAM,SAASA,MAAK,YAAY;AAC5C,QAAI,QAAQ,QAAQ,IAAI,EAAE,OAAO,GAAI,QAAO;AAC5C,UAAM,WAAW,OAAOA,MAAK,eAAe,YAAYA,MAAK,aAAa,IAAIA,MAAK,aAAa;AAChG,WAAO,EAAE,IAAIA,MAAK,cAAc,IAAIA,MAAK,eAAe,KAAK,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI,IAAI,UAAU,GAAG,IAAI;AAAA,EAChH;AAEA,WAAS,UAAU,GAAoB;AACrC,WAAO,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE,KAAK,OAAO,EAAE,OAAO,aAAa,EAAE,IAAI,WAAW,IAAI,KAAK,EAAE,MAAM,GAAI,EAAE,YAAY,EAAE;AAAA,EAC1H;AAIA,iBAAe,KAAK,SAAiG;AACnH,UAAM,MAAM,YAAY,QAAQ,QAAQ,IAAI,QAAQ,CAAC;AACrD,UAAM,MAAM,UAAU,KAAK,UAAU;AACrC,QAAI,QAAQ,KAAM,QAAO,EAAE,KAAK,OAAO,MAAM,SAAS,MAAM;AAC5D,UAAM,QAAQ,MAAM,OAAe,KAAK,MAAM,GAAG;AACjD,UAAM,QAAQ,UAAU,QAAQ,OAAO,MAAM,OAAO,YAAY,OAAO,MAAM,OAAO,YAAY,OAAO,MAAM,QAAQ;AACrH,WAAO,EAAE,KAAK,OAAO,QAAQ,QAAQ,MAAM,SAAS,KAAK;AAAA,EAC3D;AAEA,iBAAe,MAAM,SAAkB,GAAW,KAA6C;AAC7F,WAAO,WAAW,YAAY,MAAM,KAAK,GAAG,MAAM,GAAG,GAAG,MAAM,SAAS,eAAe,KAAM,GAAG,GAAG;AAAA,EACpG;AAEA,QAAM,QAAQ,CAAC,MAAc,EAAE,MAAM,KAAK,IAAI,IAAI,MAAO;AAKzD,QAAM,WAAW,oBAAI,IAAuD;AAE5E,WAAS,MAAM,KAAwD;AACrE,QAAI,UAAU,SAAS,IAAI,IAAI,EAAE;AACjC,QAAI,YAAY,QAAW;AACzB,YAAM,KAAK,IAAI;AACf,iBAAW,YAAuD;AAChE,cAAM,MAAM,MAAM,MAAM,EAAE,YAAY,iBAAiB,eAAe,GAAG,CAAC;AAC1E,YAAI,CAAC,IAAI,GAAI,QAAO,IAAI,QAAQ,UAAU;AAC1C,cAAM,OAAO,MAAM,OAAO,IAAI,IAAI;AAClC,YAAI,SAAS,KAAM,QAAO;AAI1B,YAAI,OAAO,IAAI,MAAM,iBAAiB,YAAY,OAAO,IAAI,MAAM,kBAAkB,SAAU,QAAO;AACtG,cAAM,WAAW,OAAO,IAAI,KAAK,eAAe,YAAY,IAAI,KAAK,aAAa,IAAI,IAAI,KAAK,aAAa;AAC5G,eAAO,EAAE,GAAG,KAAK,IAAI,IAAI,KAAK,cAAc,IAAI,IAAI,KAAK,eAAe,KAAK,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI,IAAI,SAAS;AAAA,MACxH,GAAG;AACH,eAAS,IAAI,IAAI,OAAO;AAIxB,WAAK,QAAQ,KAAK,CAAC,WAAW;AAC5B,YAAI,WAAW,cAAe,QAAO,SAAS,OAAO,EAAE;AACvD,cAAM,QAAQ,WAAW,MAAM,SAAS,OAAO,EAAE,GAAG,GAAK;AACxD,QAAC,MAAiC,QAAQ;AAAA,MAC7C,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAEA,iBAAeC,SAAQ,SAAqC;AAC1D,UAAM,EAAE,KAAK,OAAO,QAAQ,IAAI,MAAM,KAAK,OAAO;AAClD,QAAI,UAAU,MAAM;AAElB,aAAO,EAAE,SAAS,MAAM,QAAQ,mBAAmB,SAAS,UAAU,WAAW,YAAY,MAAM,SAAS,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE;AAAA,IAC5H;AACA,QAAI,MAAM,KAAK,EAAG,QAAO,EAAE,SAAS,UAAU,KAAK,GAAG,QAAQ,iBAAiB,SAAS,CAAC,EAAE;AAE3F,UAAM,UAAU,MAAM,MAAM,KAAK;AACjC,QAAI,YAAY,SAAS;AACvB,aAAO,EAAE,SAAS,MAAM,QAAQ,mBAAmB,SAAS,WAAW,YAAY,MAAM,SAAS,CAAC,GAAG,GAAG,EAAE;AAAA,IAC7G;AAGA,QAAI,YAAY,cAAe,QAAO,EAAE,SAAS,MAAM,QAAQ,WAAW,SAAS,CAAC,EAAE;AACtF,WAAO,EAAE,SAAS,UAAU,OAAO,GAAG,QAAQ,iBAAiB,SAAS,MAAM,MAAM,SAAS,SAAS,GAAG,EAAE;AAAA,EAC7G;AAEA,iBAAe,WAAW,SAAkB,iBAAoD;AAC9F,QAAI,oBAAoB,QAAW;AACjC,YAAM,EAAE,MAAM,IAAI,MAAM,KAAK,OAAO;AACpC,aAAO,UAAU,QAAQ,MAAM,KAAK,IAAI,UAAU,KAAK,IAAI;AAAA,IAC7D;AACA,UAAM,IAAI,MAAMA,SAAQ,OAAO;AAC/B,eAAW,KAAK,EAAE,QAAS,iBAAgB,OAAO,cAAc,CAAC;AACjE,WAAO,EAAE;AAAA,EACX;AAEA,iBAAe,OAAO,SAA0C;AAC9D,UAAM,EAAE,MAAM,IAAI,MAAM,KAAK,OAAO;AACpC,QAAI,UAAU,KAAM,QAAO;AAC3B,WAAO,MAAM,KAAK,IAAI,kBAAkB;AAAA,EAC1C;AAIA,QAAM,WAAW,oBAAI,IAA0D;AAE/E,iBAAe,cAAc,SAAkD;AAC7E,UAAM,MAAM,SAAS,IAAI,QAAQ,WAAW;AAC5C,QAAI,OAAO,KAAK,IAAI,IAAI,IAAI,KAAK,qBAAsB,QAAO,IAAI;AAClE,UAAM,MAAM,GAAG,MAAM,0BAA0B,SAAS,WAAW,mBAAmB,MAAM,CAAC,KAAK,EAAE;AACpG,UAAM,MAAM,MAAM,QAAQ,KAAK,EAAE,SAAS,EAAE,eAAe,UAAU,QAAQ,WAAW,GAAG,EAAE,CAAC;AAC9F,QAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM,uCAAuC,IAAI,MAAM,EAAE;AAChF,UAAMD,QAAQ,MAAM,IAAI,KAAK;AAC7B,UAAM,SAASA,MAAK,QAAQ,CAAC,GAAG;AAAA,MAC9B,CAAC,OAA4B;AAAA,QAC3B,IAAI,OAAO,EAAE,EAAE;AAAA,QACf,QAAQ,OAAO,EAAE,UAAU,EAAE;AAAA,QAC7B,MAAM,OAAO,EAAE,QAAQ,EAAE;AAAA,QACzB,MAAM,OAAO,EAAE,QAAQ,EAAE;AAAA,QACzB,MAAM,OAAO,EAAE,QAAQ,EAAE;AAAA,QACzB,UAAW,EAAE,YAA0C,CAAC;AAAA,QACxD,GAAI,EAAE,cAAc,EAAE,YAAY,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC;AAAA,QAC7D,GAAI,MAAM,QAAQ,EAAE,WAAW,IAAI,EAAE,aAAa,EAAE,YAAY,IAAI,MAAM,GAAG,QAAQ,MAAM,QAAQ,EAAE,MAAM,IAAI,EAAE,OAAO,IAAI,MAAM,IAAI,CAAC,EAAE,IAAI,CAAC;AAAA,MAChJ;AAAA,IACF;AACA,QAAI,SAAS,OAAO,IAAO,UAAS,MAAM;AAC1C,aAAS,IAAI,QAAQ,aAAa,EAAE,IAAI,KAAK,IAAI,GAAG,MAAM,CAAC;AAC3D,WAAO;AAAA,EACT;AAMA,QAAM,aAAa,CAAyB,OAC1C,UAAU,SAAwB;AAChC,UAAME,OAAM,MAAM,GAAG,GAAG,IAAI;AAC5B,aAAS,MAAM;AACf,WAAOA;AAAA,EACT;AACF,QAAM,sBAAoC;AAAA,IACxC,GAAG;AAAA,IACH,eAAe;AAAA,MACb,GAAG,UAAU;AAAA,MACb,QAAQ,WAAW,UAAU,cAAc,MAAM;AAAA,MACjD,QAAQ,WAAW,UAAU,cAAc,MAAM;AAAA,IACnD;AAAA,IACA,SAAS;AAAA,MACP,GAAG,UAAU;AAAA,MACb,KAAK,WAAW,UAAU,QAAQ,GAAG;AAAA,MACrC,SAAS,WAAW,UAAU,QAAQ,OAAO;AAAA,MAC7C,QAAQ,WAAW,UAAU,QAAQ,MAAM;AAAA,IAC7C;AAAA,EACF;AAEA,iBAAe,SAAS,SAA0C;AAChE,QAAI,OAA8B,CAAC;AACnC,QAAI;AACF,aAAO,MAAM,cAAc,OAAO;AAAA,IACpC,QAAQ;AAAA,IAER;AACA,WAAO,EAAE,MAAM,QAAQ,MAAM,UAAU,QAAQ,UAAU,OAAO,QAAQ,OAAO,eAAe,MAAM,WAAW,QAAQ,UAAU;AAAA,EACnI;AAIA,QAAM,OAAO;AAAA,IACX,QAAQ,CAAC,aAAsB,GAAG,QAAQ,SAAS,WAAW,cAAc,mBAAmB,QAAQ,CAAC,KAAK,EAAE;AAAA,IAC/G,SAAS,MAAM,GAAG,QAAQ;AAAA,IAC1B,SAAS,CAAC,aAAsB,GAAG,QAAQ,WAAW,WAAW,cAAc,mBAAmB,QAAQ,CAAC,KAAK,EAAE;AAAA,IAClH,SAAS,GAAG,QAAQ;AAAA,EACtB;AAEA,iBAAe,MAAM,SAAkB,KAA6B;AAClE,UAAM,OAAa,EAAE,OAAO,OAAO,GAAG,UAAU,OAAO,EAAE,GAAG,UAAU,UAAU,IAAI,aAAa,IAAI,WAAW,GAAG,WAAW,EAAE;AAChI,UAAM,YAAY,OAAO,IAAI,WAAW,MAAM,OAAO,OAAO,OAAO,WAAW,IAAI,YAAY,EAAE,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC;AACvH,UAAM,IAAI,IAAI,gBAAgB;AAAA,MAC5B,WAAW;AAAA,MACX,cAAc,GAAG,SAAS,OAAO,CAAC,GAAG,QAAQ;AAAA,MAC7C,eAAe;AAAA,MACf,OAAO,KAAK;AAAA,MACZ,gBAAgB;AAAA,MAChB,uBAAuB;AAAA,IACzB,CAAC;AAED,UAAM,SAAS,IAAI,aAAa,IAAI,QAAQ;AAC5C,QAAI,WAAW,WAAW,WAAW,OAAQ,GAAE,IAAI,UAAU,MAAM;AACnE,UAAM,SAAS,IAAI,aAAa,IAAI,QAAQ,KAAK,IAAI,aAAa,IAAI,YAAY;AAClF,QAAI,UAAU,oBAAoB,KAAK,MAAM,EAAG,GAAE,IAAI,cAAc,MAAM;AAI1E,QAAI,UAAU;AACd,QAAI,IAAI,aAAa,IAAI,QAAQ,MAAM,WAAW;AAChD,QAAE,IAAI,UAAU,SAAS;AACzB,gBAAU;AAAA,IACZ;AACA,WAAO,SAAS,GAAG,MAAM,uBAAuB,CAAC,GAAG,OAAO,IAAI;AAAA,MAC7D,YAAY,YAAY,MAAM,KAAK,MAAM,MAAM,GAAG,GAAG,MAAM,SAAS,YAAY,CAAC;AAAA,IACnF,CAAC;AAAA,EACH;AAEA,WAAS,OAAO,SAAkB,QAA0B;AAC1D,UAAM,IAAI,IAAI,QAAQ,EAAE,gBAAgB,6BAA6B,iBAAiB,WAAW,CAAC;AAClG,MAAE,OAAO,cAAc,YAAY,YAAY,IAAI,MAAM,SAAS,CAAC,CAAC,CAAC;AACrE,MAAE,OAAO,cAAc,YAAY,aAAa,IAAI,MAAM,SAAS,CAAC,CAAC,CAAC;AACtE,WAAO,IAAI,SAAS,mCAAmC,MAAM,6BAA6B,EAAE,QAAQ,KAAK,SAAS,EAAE,CAAC;AAAA,EACvH;AAEA,iBAAe,SAAS,SAAkB,KAA6B;AACrE,UAAM,MAAM,YAAY,QAAQ,QAAQ,IAAI,QAAQ,CAAC;AACrD,UAAM,SAAS,IAAI,IAAI,UAAU;AACjC,UAAM,OAAO,SAAS,MAAM,OAAa,QAAQ,MAAM,GAAG,IAAI;AAG9D,QAAI,SAAS,QAAQ,IAAI,aAAa,IAAI,OAAO,MAAM,KAAK,OAAO;AAKjE,UAAI,IAAI,IAAI,WAAW,MAAM,QAAW;AACtC,cAAM,OAAO,MAAM,YAAY;AAC/B,eAAO,SAAS,GAAG,QAAQ,oBAAoB,mBAAmB,IAAI,CAAC,IAAI,CAAC,YAAY,aAAa,KAAK,MAAM,SAAS,aAAa,CAAC,CAAC,CAAC;AAAA,MAC3I;AACA,aAAO,OAAO,SAAS,gBAAgB;AAAA,IACzC;AACA,UAAM,QAAQ,IAAI,aAAa,IAAI,OAAO;AAC1C,QAAI,UAAU,MAAM;AAElB,UAAI,UAAU,iBAAkB,QAAO,SAAS,KAAK,UAAU,CAAC,YAAY,YAAY,IAAI,MAAM,SAAS,CAAC,CAAC,CAAC,CAAC;AAE/G,UAAI,UAAU,iBAAiB;AAC7B,cAAM,OAAO,MAAM,UAAU,KAAK;AAClC,eAAO,SAAS,GAAG,IAAI,GAAG,KAAK,SAAS,GAAG,IAAI,MAAM,GAAG,wBAAwB,CAAC,YAAY,YAAY,IAAI,MAAM,SAAS,CAAC,CAAC,CAAC,CAAC;AAAA,MAClI;AACA,aAAO,OAAO,SAAS,MAAM,MAAM,GAAG,EAAE,CAAC;AAAA,IAC3C;AACA,UAAM,OAAO,IAAI,aAAa,IAAI,MAAM;AACxC,QAAI,CAAC,KAAM,QAAO,OAAO,SAAS,SAAS;AAC3C,UAAM,MAAM,MAAM,MAAM;AAAA,MACtB,YAAY;AAAA,MACZ;AAAA,MACA,cAAc,GAAG,SAAS,OAAO,CAAC,GAAG,QAAQ;AAAA,MAC7C,eAAe,KAAK;AAAA,IACtB,CAAC;AACD,UAAM,IAAI,IAAI,KAAK,MAAM,OAAO,IAAI,IAAI,IAAI;AAC5C,QAAI,MAAM,KAAM,QAAO,OAAO,SAAS,iBAAiB;AACxD,WAAO,SAAS,KAAK,UAAU,CAAC,GAAI,MAAM,MAAM,SAAS,GAAG,GAAG,GAAI,YAAY,YAAY,IAAI,MAAM,SAAS,CAAC,CAAC,GAAG,YAAY,aAAa,IAAI,MAAM,SAAS,CAAC,CAAC,CAAC,CAAC;AAAA,EACrK;AAEA,iBAAe,OAAO,SAAqC;AACzD,UAAM,EAAE,KAAK,MAAM,IAAI,MAAM,KAAK,OAAO;AACzC,QAAI,UAAU,MAAM;AAElB,YAAMF,QAAO,IAAI,gBAAgB,EAAE,WAAW,UAAU,OAAO,MAAM,GAAG,CAAC;AACzE,UAAI,aAAc,CAAAA,MAAK,IAAI,iBAAiB,YAAY;AACxD,YAAM,QAAQ,GAAG,MAAM,oBAAoB;AAAA,QACzC,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,oCAAoC;AAAA,QAC/D,MAAAA;AAAA,MACF,CAAC,EAAE,MAAM,MAAM,MAAS;AACxB,eAAS,OAAO,MAAM,EAAE;AAAA,IAC1B;AAGA,UAAM,IAAI,IAAI,gBAAgB,EAAE,WAAW,UAAU,0BAA0B,GAAG,SAAS,OAAO,CAAC,GAAG,YAAY,GAAG,CAAC;AACtH,WAAO,SAAS,GAAG,MAAM,oBAAoB,CAAC,IAAI,WAAW,YAAY,MAAM,SAAS,CAAC,GAAG,GAAG,CAAC;AAAA,EAClG;AAWA,QAAM,eAAe;AAErB,QAAM,kBAAkB;AAGxB,QAAM,YAAY,CAAC,OAAY;AAAA,IAC7B,MAAM,GAAG,SAAS;AAAA,IAClB,OAAO,GAAG,QAAQ,EAAE,QAAQ,OAAO,EAAE,MAAM,UAAU,EAAE,GAAG,SAAS,OAAO,EAAE,MAAM,WAAW,KAAK,EAAE,IAAI;AAAA,IACxG,eAAe,MAAM,QAAQ,GAAG,cAAc,IAAI,EAAE,eAAe,IAAI,MAAM,IAAI,CAAC;AAAA,EACpF;AAGA,QAAM,eAAe,CAAC,MACpB,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,MAAM,QAAQ,CAAC,KAAK,OAAQ,EAAuB,OAAO,YAAY,OAAQ,EAA6B,aAAa;AAElK,QAAM,YAAY,CAAC,OAAY;AAAA,IAC7B,IAAI,OAAO,GAAG,MAAM,EAAE;AAAA,IAAG,MAAM,OAAO,GAAG,YAAY,EAAE;AAAA,IACvD,MAAM,CAAC,gBAAgB,UAAU,QAAQ,EAAE,SAAS,GAAG,IAAI,IAAI,EAAE,OAAO;AAAA,IAAW,WAAW,OAAO,GAAG,cAAc,EAAE;AAAA,IAAG,YAAY,GAAG,eAAe,OAAO,EAAE,YAAY,IAAI;AAAA,EACpL;AAEA,QAAM,OAAO;AAGb,QAAM,SAAS,CAAC,OAAY;AAAA,IAC1B,IAAI,OAAO,GAAG,MAAM,EAAE;AAAA,IAAG,QAAQ,OAAO,GAAG,UAAU,EAAE;AAAA,IAAG,MAAM,OAAO,GAAG,QAAQ,EAAE;AAAA,IAAG,MAAM,OAAO,GAAG,QAAQ,EAAE;AAAA,IAAG,MAAM,OAAO,GAAG,QAAQ,EAAE;AAAA,IAC9I,KAAK,EAAE,aAAa,GAAG,KAAK,iBAAiB,MAAM,eAAe,GAAG,KAAK,mBAAmB,KAAK;AAAA,EACpG;AAEA,QAAM,cAAc,CAAC,OAAY;AAAA,IAC/B,QAAQ,OAAO,GAAG,WAAW,EAAE;AAAA,IAAG,OAAO,OAAO,GAAG,SAAS,EAAE;AAAA,IAAG,MAAM,OAAO,GAAG,QAAQ,EAAE;AAAA,IAAG,MAAM,OAAO,GAAG,QAAQ,EAAE;AAAA,IACxH,QAAQ,OAAO,GAAG,UAAU,EAAE;AAAA,IAAG,SAAS,GAAG,YAAY;AAAA,IAAM,SAAS,GAAG,YAAY;AAAA,IAAM,KAAK,GAAG,QAAQ;AAAA,IAAM,OAAO,OAAO,GAAG,SAAS,EAAE;AAAA,EACjJ;AAEA,QAAM,YAAY,CAAC,OAAY;AAAA,IAC7B,MAAM,OAAO,GAAG,QAAQ,EAAE;AAAA,IAAG,MAAM,OAAO,GAAG,QAAQ,EAAE;AAAA,IAAG,aAAa,OAAO,GAAG,eAAe,EAAE;AAAA,IAAG,SAAS,GAAG,YAAY;AAAA,EAC/H;AAGA,QAAM,UAAU,CAAC,OAAY;AAAA,IAC3B,IAAI,OAAO,GAAG,MAAM,EAAE;AAAA,IACtB,MAAM,OAAO,GAAG,OAAO,QAAQ,EAAE;AAAA,IACjC,cAAc,OAAO,GAAG,OAAO,iBAAiB,EAAE;AAAA,IAClD,UAAU,EAAE,MAAM,OAAO,GAAG,UAAU,QAAQ,EAAE,GAAG,KAAK,OAAO,GAAG,UAAU,OAAO,EAAE,EAAE;AAAA,IACvF,QAAQ,MAAM,QAAQ,GAAG,MAAM,IAAI,EAAE,OAAO,IAAI,CAAC,OAAY,EAAE,MAAM,OAAO,GAAG,QAAQ,EAAE,GAAG,aAAa,OAAO,GAAG,eAAe,EAAE,EAAE,EAAE,IAAI,CAAC;AAAA,IAC7I,aAAa,OAAO,GAAG,cAAc,EAAE;AAAA,IACvC,YAAY,OAAO,GAAG,gBAAgB,EAAE;AAAA,EAC1C;AAUA,QAAM,UAAU,CAACG,SAAgB,MAAc,SAAiB,OAAgB,YAC9E,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC,EAAG,EAAE,GAAGA,SAAQ,OAAO;AAEjF,QAAM,UAAU,CAAC,MAAoB,QAAQ,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK;AAG5E,WAAS,WAAW,SAA2B;AAC7C,UAAM,SAAS,QAAQ,QAAQ,IAAI,QAAQ;AAC3C,QAAI,WAAW,KAAM,QAAO,WAAW,SAAS,OAAO,KAAK,WAAW,IAAI,IAAI,QAAQ,GAAG,EAAE;AAG5F,YAAQ,QAAQ,QAAQ,IAAI,gBAAgB,KAAK,mBAAmB;AAAA,EACtE;AAEA,iBAAe,KAAK,SAA2D;AAC7E,QAAI,EAAE,QAAQ,QAAQ,IAAI,cAAc,KAAK,IAAI,SAAS,kBAAkB,EAAG,QAAO;AACtF,QAAI;AACF,YAAM,IAAK,MAAM,QAAQ,KAAK;AAC9B,aAAO,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,MAAM,QAAQ,CAAC,IAAK,IAAgC;AAAA,IACrG,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AASA,QAAM,WAAW,MAAM,aAAa,CAAC,YAAqB,QAAQ,QAAQ,IAAI,iBAAiB,GAAG,MAAM,GAAG,EAAE,IAAI,GAAG,KAAK,KAAK;AAC9H,MAAI,eAAe;AACnB,iBAAe,SAAS,SAAmD;AACzE,QAAI,KAAK,IAAI,IAAI,aAAc,QAAO,CAAC;AACvC,UAAM,KAAK,SAAS,OAAO;AAC3B,QAAI;AACF,YAAM,QAAQ,EAAE,yBAAyB,MAAM,UAAU,MAAM,EAAE;AACjE,aAAO,KAAK,EAAE,GAAG,OAAO,sBAAsB,GAAG,IAAI;AAAA,IACvD,QAAQ;AAEN,qBAAe,KAAK,IAAI,IAAI,IAAI;AAChC,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAGA,iBAAe,IAAI,SAAkB,QAAgB,MAAc,SAAmB,MAAeC,SAAoG;AACvM,QAAI;AACF,YAAM,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,IAAI,IAAI;AAAA,QAC5C;AAAA,QACA,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,QAAQ;AAAA;AAAA;AAAA,UAGR,GAAI,OAAO,EAAE,oBAAoB,GAAG,SAAS,OAAO,CAAC,GAAG,IAAI,GAAG,IAAI,EAAE,kBAAkB,SAAS;AAAA;AAAA;AAAA,UAGhG,GAAI,WAAW,EAAE,sBAAsB,SAAS,IAAI,CAAC;AAAA,UACrD,GAAI,MAAM,SAAS,OAAO;AAAA,UAC1B,GAAIA,UAAS,EAAE,eAAe,UAAUA,OAAM,GAAG,IAAI,CAAC;AAAA;AAAA;AAAA,UAGtD,GAAI,QAAQ,QAAQ,IAAI,kBAAkB,IAAI,EAAE,mBAAmB,QAAQ,QAAQ,IAAI,kBAAkB,EAAY,IAAI,CAAC;AAAA,UAC1H,GAAI,QAAQ,QAAQ,IAAI,iBAAiB,IAAI,EAAE,mBAAmB,QAAQ,QAAQ,IAAI,iBAAiB,EAAY,IAAI,CAAC;AAAA;AAAA,UAExH,GAAI,QAAQ,QAAQ,IAAI,iBAAiB,IAAI,EAAE,mBAAmB,QAAQ,QAAQ,IAAI,iBAAiB,EAAY,IAAI,CAAC;AAAA,UACxH,GAAI,QAAQ,QAAQ,IAAI,YAAY,IAAI,EAAE,cAAc,QAAQ,QAAQ,IAAI,YAAY,EAAY,IAAI,CAAC;AAAA,UACzG,GAAI,YAAY,SAAY,CAAC,IAAI,EAAE,gBAAgB,mBAAmB;AAAA,QACxE;AAAA,QACA,MAAM,YAAY,SAAY,SAAY,KAAK,UAAU,OAAO;AAAA,MAClE,CAAC;AACD,YAAM,IAAI,IAAI,WAAW,OAAO,IAAI,WAAW,MAAM,OAAS,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI;AAC/F,UAAI,IAAI,GAAI,QAAO,EAAE,QAAQ,IAAI,QAAQ,MAAM,GAAG,QAAQ,EAAE;AAC5D,YAAM,QAAQ,GAAG,SAAS,CAAC;AAC3B,aAAO,EAAE,QAAQ,IAAI,QAAQ,MAAM,MAAM,OAAO,EAAE,MAAM,OAAO,OAAO,QAAQ,OAAO,GAAG,SAAS,OAAO,OAAO,WAAW,qCAAqC,EAAE,EAAE;AAAA,IACrK,QAAQ;AACN,aAAO,EAAE,QAAQ,KAAK,MAAM,MAAM,OAAO,EAAE,MAAM,eAAe,SAAS,2DAA2D,EAAE;AAAA,IACxI;AAAA,EACF;AAEA,QAAM,YAAY,CAAC,OAAY;AAAA,IAC7B,IAAI,OAAO,GAAG,MAAM,EAAE;AAAA,IAAG,OAAO,OAAO,GAAG,SAAS,EAAE;AAAA,IAAG,MAAM,OAAO,GAAG,QAAQ,EAAE;AAAA,IAClF,eAAe,GAAG,mBAAmB;AAAA,IAAM,aAAa,GAAG,iBAAiB;AAAA,IAAM,YAAY,GAAG,gBAAgB;AAAA,EACnH;AAOA,iBAAe,WAAW,SAA8G;AACtI,UAAM,IAAI,MAAMH,SAAQ,OAAO;AAC/B,UAAM,UAAU,IAAI,QAAQ;AAC5B,eAAW,KAAK,EAAE,QAAS,SAAQ,OAAO,cAAc,CAAC;AACzD,QAAI,EAAE,YAAY,KAAM,QAAO,EAAE,UAAU,QAAQ,KAAK,mBAAmB,kBAAkB,QAAW,OAAO,EAAE;AAGjH,WAAO,EAAE,OAAO,EAAE,QAAQ,aAAa,MAAM,EAAE,QAAQ,WAAW,KAAK,MAAM,KAAK,OAAO,GAAG,QAAQ,MAAM,QAAQ;AAAA,EACpH;AAGA,iBAAe,SAAS,SAAkB,QAAa,QAAkB,CAAC,GAAG,OAAgC,CAAC,GAAsB;AAClI,UAAM,IAAI,MAAM,OAAO,MAAM;AAC7B,QAAI,MAAM,KAAM,QAAO,QAAQ,KAAK,eAAe,0DAA0D;AAC7G,UAAM,IAAI,IAAI,QAAQ;AACtB,eAAW,KAAK,CAAC,GAAI,MAAM,MAAM,SAAS,GAAG,YAAY,QAAQ,QAAQ,IAAI,QAAQ,CAAC,CAAC,GAAI,GAAG,KAAK,EAAG,GAAE,OAAO,cAAc,CAAC;AAC9H,WAAO,KAAK,EAAE,QAAQ,aAAa,SAAS,MAAM,SAAS,UAAU,CAAC,CAAC,GAAG,GAAG,KAAK,GAAG,KAAK,CAAC;AAAA,EAC7F;AAEA,MAAI,YAAqE;AAEzE,iBAAe,SAAS,SAAkB,KAAU,OAAyC;AAC3F,UAAM,OAAO,QAAQ,WAAW;AAChC,UAAM,MAAM;AAAA,MAAC;AAAA,MAAkB;AAAA,MAAgB;AAAA,MAAkB;AAAA,MAAoB;AAAA,MAAmB;AAAA,MAAiB;AAAA,MAAuB;AAAA,MAA8B;AAAA,MAAuB;AAAA,MAAO;AAAA,MAAgB;AAAA,MAAiB;AAAA,MAAkB;AAAA,MAAmB;AAAA,MAA0B;AAAA,MAAmB;AAAA,MAAiB;AAAA,MAAwB;AAAA,MAAwB;AAAA,MAAwB;AAAA,MAAqB;AAAA,MAAqB;AAAA,MAA4B;AAAA,MAA4B;AAAA,MAAgB;AAAA,MAAoB;AAAA,MAAa;AAAA,MAAkB;AAAA,MAAyB;AAAA,MAAa;AAAA,MAAY;AAAA,MAC7mB;AAAA,MAA0B;AAAA,MAA2B;AAAA,MAAiC;AAAA,MAA2B;AAAA,MAAgB;AAAA,MAA0B;AAAA,MAA2B;AAAA,MAAuB;AAAA,MAAc;AAAA,MAC3N;AAAA,MAAsB;AAAA,MACtB;AAAA,MAAqB;AAAA,MAA6B;AAAA,MAA2B;AAAA,MAAiC;AAAA,MAAkC;AAAA,MAAoC;AAAA,IAAkC,EAAE,SAAS,KAAK,KACtO,MAAM,WAAW,kBAAkB,KAAK,MAAM,WAAW,YAAY,KAAK,MAAM,WAAW,sBAAsB,KAAK,MAAM,WAAW,qBAAqB,KAC5J,UAAU,kBAAkB,UAAU,2BAA2B,UAAU;AAC7E,QAAI,CAAC,IAAK,QAAO;AACjB,QAAI,WAAW,IAAI;AACjB,aAAO,QAAQ,KAAK,kBAAkB,2FAA4F;AAAA,IACpI;AAIA,QAAI,UAAU,WAAW,CAAC,MAAM;AAC9B,UAAI,cAAc,QAAQ,UAAU,QAAQ,KAAK,IAAI,GAAG;AACtD,cAAM,MAAM,MAAM,IAAI,SAAS,OAAO,iBAAiB,mBAAmB,QAAQ,CAAC,EAAE;AACrF,oBAAY,EAAE,OAAO,KAAK,IAAI,IAAI,aAAa,MAAM,IAAI,QAAQ,CAAC,IAAK,IAAI,QAAQ,CAAC,EAAG;AAAA,MACzF;AACA,aAAO,KAAK,UAAU,IAAI;AAAA,IAC5B;AAGA,QAAI,UAAU,cAAc,CAAC,MAAM;AACjC,YAAM,CAAC,WAAW,UAAU,OAAO,GAAG,IAAI,MAAM,QAAQ,IAAI;AAAA,QAC1D,IAAI,SAAS,OAAO,2BAA2B;AAAA,QAC/C,IAAI,SAAS,OAAO,mBAAmB;AAAA,QACvC,IAAI,SAAS,OAAO,kCAAkC,mBAAmB,SAAS,OAAO,CAAC,CAAC,EAAE;AAAA,QAC7F,IAAI,SAAS,OAAO,0BAA0B;AAAA,MAChD,CAAC;AACD,YAAM,OAAO,MAAM,QAAQ,UAAU,IAAI,IAAI,UAAU,OAAO,CAAC;AAG/D,YAAM,OAAO,MAAM,MAAM,SAAS;AAClC,aAAO,KAAK;AAAA,QACV,WAAW,KAAK,IAAI,CAAC,OAAY,EAAE,IAAI,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,MAAM,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,MAAsB,EAAE,OAAO,EAAE;AAAA,QAC1K,QAAQ,SAAS,MAAM,iBAAiB;AAAA;AAAA,QAExC,GAAI,SAAS,MAAM,QAAQ,cAAc,QAAQ,OAC7C,EAAE,cAAc,EAAE,KAAK,MAAM,UAAU,SAAS,KAAK,OAAO,aAAa,aAAa,KAAK,EAAE,IAC7F,CAAC;AAAA;AAAA,QAEL,WAAW,SAAS,MAAM,qBAAqB,QAAQ,MAAM,WAAW;AAAA,QACxE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM,MAAM,cAAc;AAAA,QAChE,aAAa;AAAA,QACb,iBAAiB,MAAM,QAAQ,OAAO,MAAM,MAAM,cAAc;AAAA;AAAA,QAEhE,KAAK,MAAM,QAAQ,IAAI,IAAI,KAAK,IAAI,KAAK,KAAK,CAAC,MAAW,GAAG,iBAAiB,IAAI;AAAA,QAClF,GAAI,SAAS,MAAM,oBAAoB,QAAQ,SAAS,MAAM,mBAAmB,EAAE,gBAAgB,OAAO,SAAS,KAAK,gBAAgB,EAAE,IAAI,CAAC;AAAA,MACjJ,CAAC;AAAA,IACH;AAKA,QAAI,UAAU,kBAAkB,CAAC,MAAM;AACrC,YAAM,WAAW,UAAU,IAAI,aAAa,IAAI,WAAW,GAAG,WAAW;AACzE,YAAMI,UAAS,CAAC,SAAiB,SAAS,GAAG,QAAQ,GAAG,SAAS,SAAS,GAAG,IAAI,MAAM,GAAG,cAAc,mBAAmB,IAAI,CAAC,EAAE;AAClI,YAAM,SAAS,IAAI,aAAa,IAAI,OAAO,KAAK,IAAI,KAAK;AACzD,YAAM,cAAc,IAAI,aAAa,IAAI,YAAY,KAAK,IAAI,KAAK;AACnE,UAAI,UAAU,MAAM,eAAe,GAAI,QAAOA,QAAO,eAAe;AACpE,YAAM,WAAW,OAAO,EAAE;AAC1B,YAAM,YAAY,OAAO,IAAI,WAAW,MAAM,OAAO,OAAO,OAAO,WAAW,IAAI,YAAY,EAAE,OAAO,QAAQ,CAAC,CAAC,CAAC;AAClH,YAAMC,YAAW,GAAG,QAAQ;AAC5B,YAAM,UAAU,MAAM,IAAI,SAAS,QAAQ,sBAAsB;AAAA,QAC/D,GAAI,aAAa,EAAE,WAAW,IAAI,EAAE,MAAM;AAAA,QAC1C,cAAc,GAAG,SAAS,OAAO,CAAC,GAAGA,SAAQ;AAAA,QAAI,gBAAgB;AAAA,MACnE,GAAGA,SAAQ;AACX,UAAI,QAAQ,SAAS,OAAO,QAAQ,MAAM,iBAAiB,SAAU,QAAOD,QAAO,QAAQ,OAAO,QAAQ,iBAAiB;AAC3H,YAAM,OAAa,EAAE,MAAM,OAAO,OAAO,UAAU,SAAS;AAC5D,aAAO,SAAS,QAAQ,KAAK,cAAc,CAAC,YAAY,YAAY,MAAM,KAAK,MAAM,MAAM,GAAG,GAAG,MAAM,SAAS,YAAY,CAAC,CAAC,CAAC;AAAA,IACjI;AACA,QAAI,UAAU,mBAAmB,CAAC,MAAM;AACtC,YAAM,SAAS,YAAY,QAAQ,QAAQ,IAAI,QAAQ,CAAC,EAAE,IAAI,UAAU;AACxE,YAAM,OAAO,SAAS,MAAM,OAAa,QAAQ,MAAM,GAAG,IAAI;AAC9D,YAAM,QAAQ,YAAY,YAAY,IAAI,MAAM,SAAS,CAAC,CAAC;AAC3D,YAAM,OAAO,MAAM,YAAY;AAC/B,YAAM,WAAW,CAACE,UAAiB,SAAS,GAAG,IAAI,GAAG,KAAK,SAAS,GAAG,IAAI,MAAM,GAAG,cAAc,mBAAmBA,KAAI,CAAC,IAAI,CAAC,KAAK,CAAC;AACrI,UAAI,SAAS,QAAQ,KAAK,SAAS,MAAO,QAAO,SAAS,gBAAgB;AAC1E,YAAM,UAAU,IAAI,aAAa,IAAI,OAAO;AAC5C,UAAI,QAAS,QAAO,SAAS,OAAO;AACpC,YAAM,OAAO,IAAI,aAAa,IAAI,MAAM;AACxC,UAAI,CAAC,KAAM,QAAO,SAAS,YAAY;AACvC,YAAM,OAAO,MAAM,IAAI,SAAS,QAAQ,sBAAsB,EAAE,MAAM,cAAc,GAAG,SAAS,OAAO,CAAC,GAAG,QAAQ,iBAAiB,eAAe,KAAK,MAAM,CAAC;AAC/J,UAAI,KAAK,MAAO,QAAO,SAAS,KAAK,MAAM,IAAI;AAC/C,YAAM,IAAI,MAAM,OAAO,KAAK,IAAI;AAChC,UAAI,MAAM,KAAM,QAAO,SAAS,aAAa;AAC7C,aAAO,SAAS,MAAM,CAAC,GAAI,MAAM,MAAM,SAAS,GAAG,YAAY,QAAQ,QAAQ,IAAI,QAAQ,CAAC,CAAC,GAAI,KAAK,CAAC;AAAA,IACzG;AAGA,QAAI,MAAM,WAAW,kBAAkB,KAAK,CAAC,MAAM;AACjD,YAAM,WAAW,WAAW,MAAM,MAAM,mBAAmB,MAAM,CAAC;AAClE,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,QAAO,IAAI,SAAS,aAAa,EAAE,QAAQ,IAAI,CAAC;AACjF,YAAM,WAAW,UAAU,IAAI,aAAa,IAAI,WAAW,GAAG,WAAW;AACzE,YAAMD,YAAW,GAAG,QAAQ,aAAa,QAAQ;AAGjD,YAAM,UAAU,MAAM,IAAI,SAAS,OAAO,mBAAmB,QAAQ,iBAAiB,mBAAmB,GAAG,SAAS,OAAO,CAAC,GAAGA,SAAQ,EAAE,CAAC,IAAI,QAAWA,SAAQ;AAClK,UAAI,QAAQ,SAAS,OAAO,QAAQ,MAAM,iBAAiB,UAAU;AACnE,eAAO,SAAS,GAAG,QAAQ,GAAG,SAAS,SAAS,GAAG,IAAI,MAAM,GAAG,cAAc,mBAAmB,QAAQ,OAAO,QAAQ,sBAAsB,CAAC,EAAE;AAAA,MACnJ;AACA,YAAM,OAAa,EAAE,MAAM,UAAU,OAAO,OAAO,QAAQ,KAAK,SAAS,EAAE,GAAG,UAAU,SAAS;AACjG,aAAO,SAAS,QAAQ,KAAK,cAAc,CAAC,YAAY,YAAY,MAAM,KAAK,MAAM,MAAM,GAAG,GAAG,MAAM,SAAS,YAAY,CAAC,CAAC,CAAC;AAAA,IACjI;AACA,QAAI,MAAM,WAAW,YAAY,KAAK,CAAC,MAAM;AAC3C,YAAM,WAAW,WAAW,MAAM,MAAM,aAAa,MAAM,CAAC;AAC5D,YAAM,SAAS,YAAY,QAAQ,QAAQ,IAAI,QAAQ,CAAC,EAAE,IAAI,UAAU;AACxE,YAAM,OAAO,SAAS,MAAM,OAAa,QAAQ,MAAM,GAAG,IAAI;AAC9D,YAAM,QAAQ,YAAY,YAAY,IAAI,MAAM,SAAS,CAAC,CAAC;AAC3D,YAAM,OAAO,MAAM,YAAY;AAC/B,YAAM,WAAW,CAACC,UAAiB,SAAS,GAAG,IAAI,GAAG,KAAK,SAAS,GAAG,IAAI,MAAM,GAAG,cAAc,mBAAmBA,KAAI,CAAC,IAAI,CAAC,KAAK,CAAC;AAErI,UAAI,SAAS,QAAS,KAAK,SAAS,YAAY,KAAK,SAAS,UAAU,KAAK,SAAS,aAAc,KAAK,aAAa,YAAY,IAAI,aAAa,IAAI,OAAO,MAAM,KAAK,MAAO,QAAO,SAAS,gBAAgB;AAChN,YAAM,OAAO,IAAI,aAAa,IAAI,MAAM;AACxC,UAAI,CAAC,KAAM,QAAO,SAAS,IAAI,aAAa,IAAI,OAAO,MAAM,kBAAkB,cAAc,kBAAkB;AAC/G,YAAM,IAAI,IAAI,gBAAgB,EAAE,MAAM,OAAO,KAAK,OAAO,cAAc,GAAG,SAAS,OAAO,CAAC,GAAG,QAAQ,aAAa,QAAQ,GAAG,CAAC;AAC/H,UAAI,KAAK,SAAS,WAAW;AAE3B,cAAM,OAAO,MAAM,WAAW,OAAO;AACrC,YAAI,cAAc,KAAM,QAAO,SAAS,iBAAiB;AACzD,cAAMC,QAAO,MAAM,IAAI,SAAS,OAAO,8BAA8B,QAAQ,aAAa,CAAC,IAAI,QAAW,QAAW,KAAK,KAAK;AAC/H,YAAIA,MAAK,MAAO,QAAO,SAASA,MAAK,MAAM,IAAI;AAC/C,cAAMC,KAAI,MAAM,OAAOD,MAAK,IAAI;AAChC,YAAIC,OAAM,KAAM,QAAO,SAAS,aAAa;AAC7C,eAAO,SAAS,MAAM,CAAC,GAAI,MAAM,MAAM,SAASA,IAAG,YAAY,QAAQ,QAAQ,IAAI,QAAQ,CAAC,CAAC,GAAI,KAAK,CAAC;AAAA,MACzG;AACA,UAAI,KAAK,SAAS,QAAQ;AAExB,cAAM,OAAO,MAAM,WAAW,OAAO;AACrC,YAAI,cAAc,KAAM,QAAO,SAAS,iBAAiB;AACzD,cAAM,SAAS,MAAM,IAAI,SAAS,OAAO,uBAAuB,QAAQ,kBAAkB,CAAC,IAAI,QAAW,QAAW,KAAK,KAAK;AAC/H,YAAI,OAAO,MAAO,QAAO,SAAS,OAAO,MAAM,IAAI;AACnD,cAAM,IAAI,IAAI,QAAQ,KAAK,OAAO;AAClC,UAAE,OAAO,cAAc,KAAK;AAC5B,eAAO,SAAS,GAAG,IAAI,GAAG,KAAK,SAAS,GAAG,IAAI,MAAM,GAAG,UAAU,mBAAmB,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;AAAA,MACzH;AACA,YAAM,OAAO,MAAM,IAAI,SAAS,OAAO,mBAAmB,QAAQ,aAAa,CAAC,EAAE;AAClF,UAAI,KAAK,MAAO,QAAO,SAAS,KAAK,MAAM,IAAI;AAC/C,YAAM,IAAI,MAAM,OAAO,KAAK,IAAI;AAChC,UAAI,MAAM,KAAM,QAAO,SAAS,aAAa;AAC7C,aAAO,SAAS,MAAM,CAAC,GAAI,MAAM,MAAM,SAAS,GAAG,YAAY,QAAQ,QAAQ,IAAI,QAAQ,CAAC,CAAC,GAAI,KAAK,CAAC;AAAA,IACzG;AAGA,QAAI,MAAM,WAAW,qBAAqB,KAAK,CAAC,MAAM;AACpD,YAAM,WAAW,WAAW,MAAM,MAAM,sBAAsB,MAAM,CAAC;AACrE,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,QAAO,IAAI,SAAS,aAAa,EAAE,QAAQ,IAAI,CAAC;AACjF,YAAM,WAAW,UAAU,IAAI,aAAa,IAAI,WAAW,GAAG,WAAW;AACzE,YAAMJ,UAAS,CAAC,SAAiB,SAAS,GAAG,QAAQ,GAAG,SAAS,SAAS,GAAG,IAAI,MAAM,GAAG,cAAc,mBAAmB,IAAI,CAAC,EAAE;AAClI,YAAM,OAAO,MAAM,WAAW,OAAO;AACrC,UAAI,cAAc,KAAM,QAAOA,QAAO,iBAAiB;AACvD,YAAMC,YAAW,GAAG,QAAQ,aAAa,QAAQ;AACjD,YAAM,UAAU,MAAM,IAAI,SAAS,OAAO,8BAA8B,QAAQ,iBAAiB,mBAAmB,GAAG,SAAS,OAAO,CAAC,GAAGA,SAAQ,EAAE,CAAC,IAAI,QAAWA,WAAU,KAAK,KAAK;AACzL,UAAI,QAAQ,SAAS,OAAO,QAAQ,MAAM,iBAAiB,SAAU,QAAOD,QAAO,QAAQ,OAAO,QAAQ,sBAAsB;AAChI,YAAM,OAAa,EAAE,MAAM,WAAW,OAAO,OAAO,QAAQ,KAAK,SAAS,EAAE,GAAG,UAAU,SAAS;AAClG,aAAO,SAAS,QAAQ,KAAK,cAAc,CAAC,GAAG,KAAK,QAAQ,aAAa,GAAG,YAAY,YAAY,MAAM,KAAK,MAAM,MAAM,GAAG,GAAG,MAAM,SAAS,YAAY,CAAC,CAAC,CAAC;AAAA,IACjK;AAGA,QAAI,MAAM,WAAW,sBAAsB,KAAK,CAAC,MAAM;AACrD,YAAM,WAAW,WAAW,MAAM,MAAM,uBAAuB,MAAM,CAAC;AACtE,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,QAAO,IAAI,SAAS,aAAa,EAAE,QAAQ,IAAI,CAAC;AACjF,YAAM,WAAW,UAAU,IAAI,aAAa,IAAI,WAAW,GAAG,WAAW;AACzE,YAAMA,UAAS,CAAC,SAAiB,SAAS,GAAG,QAAQ,GAAG,SAAS,SAAS,GAAG,IAAI,MAAM,GAAG,cAAc,mBAAmB,IAAI,CAAC,EAAE;AAClI,YAAM,OAAO,MAAM,WAAW,OAAO;AACrC,UAAI,cAAc,KAAM,QAAOA,QAAO,iBAAiB;AACvD,YAAMC,YAAW,GAAG,QAAQ,aAAa,QAAQ;AACjD,YAAM,UAAU,MAAM,IAAI,SAAS,OAAO,uBAAuB,QAAQ,sBAAsB,mBAAmB,GAAG,SAAS,OAAO,CAAC,GAAGA,SAAQ,EAAE,CAAC,IAAI,QAAWA,WAAU,KAAK,KAAK;AACvL,UAAI,QAAQ,SAAS,OAAO,QAAQ,MAAM,iBAAiB,SAAU,QAAOD,QAAO,QAAQ,OAAO,QAAQ,sBAAsB;AAChI,YAAM,OAAa,EAAE,MAAM,QAAQ,OAAO,OAAO,QAAQ,KAAK,SAAS,EAAE,GAAG,UAAU,SAAS;AAC/F,aAAO,SAAS,QAAQ,KAAK,cAAc,CAAC,GAAG,KAAK,QAAQ,aAAa,GAAG,YAAY,YAAY,MAAM,KAAK,MAAM,MAAM,GAAG,GAAG,MAAM,SAAS,YAAY,CAAC,CAAC,CAAC;AAAA,IACjK;AAGA,QAAI,UAAU,oBAAoB,CAAC,MAAM;AACvC,YAAM,OAAO,MAAM,WAAW,OAAO;AACrC,UAAI,cAAc,KAAM,QAAO,KAAK;AACpC,YAAM,MAAM,MAAM,IAAI,SAAS,OAAO,uBAAuB,QAAW,QAAW,KAAK,KAAK;AAC7F,UAAI,IAAI,MAAO,QAAO,QAAQ,IAAI,QAAQ,IAAI,MAAM,MAAM,IAAI,MAAM,SAAS,QAAW,KAAK,OAAO;AACpG,YAAM,OAAO,MAAM,QAAQ,IAAI,IAAI,IAAI,IAAI,OAAO,CAAC;AACnD,aAAO,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC,OAAY,EAAE,UAAU,OAAO,EAAE,YAAY,EAAE,GAAG,OAAO,OAAO,EAAE,SAAS,EAAE,GAAG,MAAM,OAAO,EAAE,QAAQ,EAAE,GAAG,UAAU,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,EAAE,GAAG,KAAK,KAAK,OAAO;AAAA,IAC9M;AACA,QAAI,UAAU,kBAAkB,CAAC,MAAM;AACrC,YAAM,OAAO,MAAM,WAAW,OAAO;AACrC,UAAI,cAAc,KAAM,QAAO,KAAK;AACpC,YAAM,MAAM,MAAM,IAAI,SAAS,OAAO,iCAAiC,QAAW,QAAW,KAAK,KAAK;AACvG,UAAI,IAAI,MAAO,QAAO,QAAQ,IAAI,QAAQ,IAAI,MAAM,MAAM,IAAI,MAAM,SAAS,QAAW,KAAK,OAAO;AACpG,YAAM,OAAO,MAAM,QAAQ,IAAI,IAAI,IAAI,IAAI,OAAO,CAAC;AACnD,aAAO,KAAK,EAAE,UAAU,KAAK,IAAI,SAAS,EAAE,GAAG,KAAK,KAAK,OAAO;AAAA,IAClE;AAEA,QAAI,UAAU,gBAAgB,CAAC,MAAM;AACnC,YAAM,OAAO,MAAM,WAAW,OAAO;AACrC,UAAI,cAAc,KAAM,QAAO,KAAK;AACpC,YAAM,MAAM,MAAM,IAAI,SAAS,OAAO,sBAAsB,QAAW,QAAW,KAAK,KAAK;AAC5F,UAAI,IAAI,MAAO,QAAO,QAAQ,IAAI,QAAQ,IAAI,MAAM,MAAM,IAAI,MAAM,SAAS,QAAW,KAAK,OAAO;AACpG,YAAM,OAAO,MAAM,QAAQ,IAAI,IAAI,IAAI,IAAI,OAAO,CAAC;AACnD,aAAO,KAAK,EAAE,QAAQ,KAAK,IAAI,OAAO,EAAE,GAAG,KAAK,KAAK,OAAO;AAAA,IAC9D;AAGA,SAAK,UAAU,uBAAuB,UAAU,+BAA+B,UAAU,8BAA8B,CAAC,MAAM;AAC5H,YAAM,OAAO,MAAM,WAAW,OAAO;AACrC,UAAI,cAAc,KAAM,QAAO,KAAK;AACpC,UAAI,OAAO;AACX,UAAI,UAAU,qBAAqB;AACjC,cAAM,KAAK,IAAI,aAAa,IAAI,IAAI,KAAK;AACzC,YAAI,CAAC,KAAK,KAAK,EAAE,EAAG,QAAO,QAAQ,KAAK,wBAAwB,2BAA2B,QAAW,KAAK,OAAO;AAClH,gBAAQ,IAAI,EAAE,IAAI,MAAM,SAAS,QAAQ,IAAI,UAAU,SAAS;AAAA,MAClE,WAAW,IAAI,aAAa,IAAI,QAAQ,GAAG;AACzC,gBAAQ,WAAW,mBAAmB,IAAI,aAAa,IAAI,QAAQ,CAAE,CAAC;AAAA,MACxE;AACA,YAAM,MAAM,MAAM,IAAI,SAAS,OAAO,MAAM,QAAW,QAAW,KAAK,KAAK;AAC5E,UAAI,IAAI,MAAO,QAAO,QAAQ,IAAI,QAAQ,IAAI,MAAM,MAAM,IAAI,MAAM,SAAS,QAAW,KAAK,OAAO;AACpG,YAAM,OAAO,MAAM,QAAQ,IAAI,IAAI,IAAI,IAAI,OAAO,CAAC;AACnD,UAAI,UAAU,oBAAqB,QAAO,KAAK,EAAE,eAAe,KAAK,IAAI,MAAM,EAAE,GAAG,KAAK,KAAK,OAAO;AACrG,UAAI,UAAU,0BAA2B,QAAO,KAAK,EAAE,OAAO,KAAK,IAAI,SAAS,EAAE,GAAG,KAAK,KAAK,OAAO;AACtG,aAAO,KAAK,EAAE,SAAS,KAAK,IAAI,WAAW,EAAE,GAAG,KAAK,KAAK,OAAO;AAAA,IACnE;AAEA,QAAI,UAAU,qBAAqB,CAAC,MAAM;AACxC,YAAM,OAAO,MAAM,WAAW,OAAO;AACrC,UAAI,cAAc,KAAM,QAAO,KAAK;AACpC,YAAM,MAAM,MAAM,IAAI,SAAS,OAAO,wBAAwB,QAAW,QAAW,KAAK,KAAK;AAC9F,UAAI,IAAI,MAAO,QAAO,QAAQ,IAAI,QAAQ,IAAI,MAAM,MAAM,IAAI,MAAM,SAAS,QAAW,KAAK,OAAO;AACpG,aAAO,KAAK,UAAU,IAAI,IAAI,GAAG,KAAK,KAAK,OAAO;AAAA,IACpD;AACA,SAAK,UAAU,SAAS,UAAU,mBAAmB,CAAC,MAAM;AAC1D,YAAM,OAAO,MAAM,WAAW,OAAO;AACrC,UAAI,cAAc,KAAM,QAAO,KAAK;AACpC,YAAM,MAAM,MAAM,IAAI,SAAS,OAAO,UAAU,QAAQ,gBAAgB,wBAAwB,QAAW,QAAW,KAAK,KAAK;AAChI,UAAI,IAAI,MAAO,QAAO,QAAQ,IAAI,QAAQ,IAAI,MAAM,MAAM,IAAI,MAAM,SAAS,QAAW,KAAK,OAAO;AACpG,UAAI,UAAU,gBAAgB;AAC5B,cAAM,OAAO,MAAM,QAAQ,IAAI,IAAI,IAAI,IAAI,OAAO,CAAC;AACnD,eAAO,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC,OAAY,EAAE,QAAQ,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,OAAO,EAAE,MAAM,EAAE,GAAG,WAAW,OAAO,EAAE,cAAc,EAAE,GAAG,WAAW,OAAO,EAAE,cAAc,EAAE,EAAE,EAAE,EAAE,GAAG,KAAK,KAAK,OAAO;AAAA,MAC/M;AACA,aAAO,KAAK,EAAE,SAAS,UAAU,IAAI,IAAI,EAAE,GAAG,KAAK,KAAK,OAAO;AAAA,IACjE;AAIA,QAAI,UAAU,8BAA8B,CAAC,MAAM;AACjD,YAAM,SAAS,YAAY,QAAQ,QAAQ,IAAI,QAAQ,CAAC,EAAE,IAAI,UAAU;AACxE,YAAM,OAAO,SAAS,MAAM,OAAa,QAAQ,MAAM,GAAG,IAAI;AAC9D,UAAI,SAAS,QAAQ,KAAK,SAAS,MAAO,QAAO,QAAQ,KAAK,gBAAgB,qDAAqD;AACnI,UAAI;AACJ,UAAI;AACF,mBAAW,MAAM,QAAQ,GAAG,MAAM,4BAA4B;AAAA,UAC5D,SAAS,EAAE,gBAAgB,QAAQ,eAAe,KAAK,OAAO,QAAQ,oBAAoB;AAAA,UAC1F,QAAQ,QAAQ;AAAA,QAClB,CAAC;AAAA,MACH,QAAQ;AACN,eAAO,QAAQ,KAAK,eAAe,8BAA8B;AAAA,MACnE;AACA,UAAI,CAAC,SAAS,MAAM,CAAC,SAAS,MAAM;AAClC,cAAMK,KAAK,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,IAAI;AACjD,eAAO,QAAQ,SAAS,QAAQ,OAAOA,IAAG,SAAS,CAAC,GAAG,QAAQ,OAAO,GAAG,OAAOA,IAAG,SAAS,CAAC,GAAG,WAAW,qCAAqC,CAAC;AAAA,MACnJ;AACA,aAAO,IAAI,SAAS,SAAS,MAAM;AAAA,QACjC,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,qBAAqB,iBAAiB,sBAAsB,qBAAqB,KAAK;AAAA,MACnH,CAAC;AAAA,IACH;AAEA,QAAI,CAAC,KAAM,QAAO,IAAI,SAAS,sBAAsB,EAAE,QAAQ,KAAK,SAAS,EAAE,OAAO,OAAO,EAAE,CAAC;AAChG,QAAI,CAAC,WAAW,OAAO,EAAG,QAAO,QAAQ,KAAK,cAAc,kDAAkD;AAE9G,QAAI,UAAU,aAAa;AACzB,YAAM,EAAE,KAAK,MAAM,IAAI,MAAM,KAAK,OAAO;AACzC,UAAI,UAAU,MAAM;AAClB,cAAM,OAAO,IAAI,gBAAgB,EAAE,WAAW,UAAU,OAAO,MAAM,GAAG,CAAC;AACzE,YAAI,aAAc,MAAK,IAAI,iBAAiB,YAAY;AACxD,cAAM,QAAQ,GAAG,MAAM,oBAAoB,EAAE,QAAQ,QAAQ,SAAS,EAAE,gBAAgB,oCAAoC,GAAG,MAAM,KAAK,CAAC,EAAE,MAAM,MAAM,MAAS;AAClK,iBAAS,OAAO,MAAM,EAAE;AAAA,MAC1B;AACA,YAAM,IAAI,IAAI,QAAQ;AACtB,iBAAW,KAAK,WAAW,YAAY,MAAM,SAAS,CAAC,GAAG,GAAG,EAAG,GAAE,OAAO,cAAc,CAAC;AACxF,aAAO,KAAK,EAAE,QAAQ,aAAa,GAAG,KAAK,CAAC;AAAA,IAC9C;AAEA,UAAM,IAAI,MAAM,KAAK,OAAO;AAC5B,QAAI,MAAM,KAAM,QAAO,QAAQ,KAAK,eAAe,wBAAwB;AAI3E,QAAI,UAAU,yBAAyB;AACrC,YAAM,MAAM,WAAW,EAAE,KAAK;AAC9B,UAAI,IAAK,QAAO,QAAQ,GAAG;AAC3B,YAAM,MAAM,MAAM,IAAI,SAAS,QAAQ,yBAAyB,EAAE,OAAO,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AACjG,UAAI,IAAI,MAAO,QAAO,QAAQ,IAAI,QAAQ,IAAI,MAAM,MAAM,IAAI,MAAM,OAAO;AAC3E,YAAM,IAAI,IAAI,MAAM;AACpB,aAAO,KAAK,IAAI,EAAE,QAAQ,SAAS,YAAY,EAAE,IAAI,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,OAAO,EAAE,gBAAgB,EAAE,GAAG,UAAU,EAAE,aAAa,KAAK,EAAE,IAAI,EAAE,QAAQ,OAAO,CAAC;AAAA,IACvK;AAGA,QAAI,UAAU,sBAAsB;AAClC,UAAI,CAAC,KAAM,QAAO,IAAI,SAAS,sBAAsB,EAAE,QAAQ,KAAK,SAAS,EAAE,OAAO,OAAO,EAAE,CAAC;AAChG,YAAM,MAAM,MAAM,IAAI,SAAS,QAAQ,sBAAsB,CAAC,CAAC;AAC/D,UAAI,IAAI,MAAO,QAAO,QAAQ,IAAI,QAAQ,IAAI,MAAM,MAAM,IAAI,MAAM,OAAO;AAC3E,aAAO,SAAS,SAAS,IAAI,IAAI;AAAA,IACnC;AAEA,QAAI,UAAU,kBAAkB;AAC9B,YAAM,MAAM,aAAa,WAAW,EAAE,KAAK,GAAG,cAAc,EAAE,QAAQ,CAAC;AACvE,UAAI,IAAK,QAAO,QAAQ,GAAG;AAC3B,YAAM,MAAM,MAAM,IAAI,SAAS,QAAQ,kBAAkB,EAAE,OAAO,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,UAAU,EAAE,SAAS,CAAC;AAChH,UAAI,IAAI,MAAO,QAAO,QAAQ,IAAI,QAAQ,IAAI,MAAM,MAAM,IAAI,MAAM,OAAO;AAC3E,UAAI,IAAI,MAAM,iBAAiB,MAAM;AAGnC,cAAM,OAAa,EAAE,MAAM,OAAO,OAAO,OAAO,IAAI,KAAK,aAAa,EAAE,GAAG,UAAU,YAAY;AACjG,eAAO,KAAK,EAAE,QAAQ,eAAe,GAAG,KAAK,IAAI,QAAQ,EAAE,cAAc,YAAY,YAAY,MAAM,KAAK,MAAM,MAAM,GAAG,GAAG,MAAM,SAAS,YAAY,CAAC,EAAE,CAAC,CAAC;AAAA,MAChK;AACA,aAAO,SAAS,SAAS,IAAI,IAAI;AAAA,IACnC;AAEA,QAAI,UAAU,gBAAgB;AAC5B,YAAM,MAAM,UAAU,EAAE,IAAI;AAC5B,UAAI,IAAK,QAAO,QAAQ,GAAG;AAC3B,YAAM,SAAS,YAAY,QAAQ,QAAQ,IAAI,QAAQ,CAAC,EAAE,IAAI,UAAU;AACxE,YAAM,OAAO,SAAS,MAAM,OAAa,QAAQ,MAAM,GAAG,IAAI;AAC9D,UAAI,SAAS,QAAQ,KAAK,SAAS,MAAO,QAAO,QAAQ,KAAK,gBAAgB,qDAAqD;AACnI,YAAM,MAAM,MAAM,IAAI,SAAS,QAAQ,0BAA0B,EAAE,WAAW,KAAK,OAAO,MAAM,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACvH,UAAI,IAAI,MAAO,QAAO,QAAQ,IAAI,QAAQ,IAAI,MAAM,MAAM,IAAI,MAAM,SAAS,MAAM;AACnF,aAAO,SAAS,SAAS,IAAI,MAAM,CAAC,YAAY,YAAY,IAAI,MAAM,SAAS,CAAC,CAAC,CAAC,CAAC;AAAA,IACrF;AAMA,QAAI,UAAU,uBAAuB,UAAU,4BAA4B;AACzE,YAAM,SAAS,YAAY,QAAQ,QAAQ,IAAI,QAAQ,CAAC,EAAE,IAAI,UAAU;AACxE,YAAM,OAAO,SAAS,MAAM,OAAa,QAAQ,MAAM,GAAG,IAAI;AAC9D,UAAI,SAAS,QAAQ,KAAK,SAAS,MAAO,QAAO,QAAQ,KAAK,gBAAgB,qDAAqD;AACnI,UAAI,UAAU,qBAAqB;AACjC,cAAMC,OAAM,MAAM,IAAI,SAAS,QAAQ,qBAAqB,EAAE,WAAW,KAAK,MAAM,CAAC;AACrF,YAAIA,KAAI,MAAO,QAAO,QAAQA,KAAI,QAAQA,KAAI,MAAM,MAAMA,KAAI,MAAM,OAAO;AAC3E,eAAO,KAAK,EAAE,QAAQ,QAAQ,QAAQ,OAAOA,KAAI,MAAM,UAAU,CAAC,EAAE,CAAC;AAAA,MACvE;AACA,YAAM,MAAM,MAAM,IAAI,SAAS,QAAQ,0BAA0B,EAAE,WAAW,KAAK,OAAO,MAAM,KAAK,CAAC;AACtG,UAAI,IAAI,MAAO,QAAO,QAAQ,IAAI,QAAQ,IAAI,MAAM,MAAM,IAAI,MAAM,OAAO;AAC3E,aAAO,SAAS,SAAS,IAAI,MAAM,CAAC,YAAY,YAAY,IAAI,MAAM,SAAS,CAAC,CAAC,CAAC,CAAC;AAAA,IACrF;AAEA,QAAI,UAAU,0BAA0B,UAAU,qBAAqB;AACrE,YAAM,SAAS,YAAY,QAAQ,QAAQ,IAAI,QAAQ,CAAC,EAAE,IAAI,UAAU;AACxE,YAAM,OAAO,SAAS,MAAM,OAAa,QAAQ,MAAM,GAAG,IAAI;AAC9D,UAAI,SAAS,QAAQ,KAAK,SAAS,MAAO,QAAO,QAAQ,KAAK,gBAAgB,qDAAqD;AACnI,UAAI,UAAU,wBAAwB;AACpC,cAAMA,OAAM,MAAM,IAAI,SAAS,QAAQ,wBAAwB,EAAE,WAAW,KAAK,MAAM,CAAC;AACxF,YAAIA,KAAI,MAAO,QAAO,QAAQA,KAAI,QAAQA,KAAI,MAAM,MAAMA,KAAI,MAAM,OAAO;AAC3E,cAAM,IAAIA,KAAI,MAAM;AACpB,cAAM,OAAOA,KAAI,MAAM;AACvB,eAAO,KAAK;AAAA,UAAE,QAAQ;AAAA,UAAM,MAAMA,KAAI,MAAM,SAAS;AAAA,UAAM,OAAO,IAAI,EAAE,QAAQ,OAAO,EAAE,UAAU,EAAE,GAAG,SAAS,OAAO,EAAE,WAAW,KAAK,EAAE,IAAI;AAAA,UAC9I,MAAM,OAAO,EAAE,SAAS,OAAO,KAAK,WAAW,CAAC,EAAE,IAAI;AAAA,QAAK,CAAC;AAAA,MAChE;AACA,YAAM,MAAM,MAAM,IAAI,SAAS,QAAQ,qBAAqB,EAAE,WAAW,KAAK,MAAM,CAAC;AACrF,UAAI,IAAI,MAAO,QAAO,QAAQ,IAAI,QAAQ,IAAI,MAAM,MAAM,IAAI,MAAM,OAAO;AAC3E,aAAO,KAAK,EAAE,QAAQ,QAAQ,QAAQ,OAAO,IAAI,MAAM,WAAW,EAAE,GAAG,SAAS,OAAO,IAAI,MAAM,WAAW,KAAK,EAAE,CAAC;AAAA,IACtH;AAEA,QAAI,UAAU,kBAAkB;AAC9B,YAAM,MAAM,aAAa,UAAU,EAAE,IAAI,GAAG,WAAW,EAAE,KAAK,GAAG,iBAAiB,EAAE,QAAQ,GAAG,kBAAkB,EAAE,YAAY,CAAC;AAChI,UAAI,IAAK,QAAO,QAAQ,GAAG;AAC3B,YAAM,QAAQ,OAAO,EAAE,KAAK,EAAE,KAAK;AAEnC,YAAM,eAAe,OAAO,EAAE,iBAAiB,YAAY,EAAE,aAAa,KAAK,MAAM,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,KAAK,EAAE,EAAE,IAAI,CAAC;AAC/I,YAAM,OAAO,MAAM,IAAI,SAAS,QAAQ,qBAAqB,EAAE,OAAO,UAAU,EAAE,UAAU,cAAc,OAAO,EAAE,SAAS,WAAW,EAAE,KAAK,KAAK,IAAI,IAAI,GAAG,aAAa,GAAG,MAAM,WAAW;AAC/L,UAAI,KAAK,MAAO,QAAO,QAAQ,KAAK,QAAQ,KAAK,MAAM,MAAM,KAAK,MAAM,OAAO;AAE/E,UAAI,KAAK,MAAM,0BAA0B,KAAM,QAAO,KAAK,EAAE,QAAQ,yBAAyB,MAAM,CAAC;AACrG,YAAM,MAAM,MAAM,IAAI,SAAS,QAAQ,kBAAkB,EAAE,OAAO,UAAU,EAAE,SAAS,CAAC;AACxF,UAAI,IAAI,SAAS,IAAI,MAAM,iBAAiB,KAAM,QAAO,KAAK,EAAE,QAAQ,yBAAyB,MAAM,CAAC;AACxG,aAAO,SAAS,SAAS,IAAI,IAAI;AAAA,IACnC;AAEA,QAAI,UAAU,oBAAoB;AAChC,YAAM,MAAM,WAAW,EAAE,KAAK;AAC9B,UAAI,IAAK,QAAO,QAAQ,GAAG;AAE3B,YAAM,IAAI,SAAS,QAAQ,2BAA2B,EAAE,OAAO,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,MAAM,aAAa;AAC5G,aAAO,KAAK,EAAE,QAAQ,OAAO,CAAC;AAAA,IAChC;AAEA,QAAI,MAAM,WAAW,KAAK,GAAG;AAC3B,YAAM,OAAO,MAAM,WAAW,OAAO;AACrC,UAAI,cAAc,KAAM,QAAO,KAAK;AACpC,YAAM,KAAK,CAAC,MAAc,SAAmB,SAAS,WAAW,IAAI,SAAS,QAAQ,MAAM,SAAS,QAAW,KAAK,KAAK;AAC1H,YAAM,UAAU,CAAC,KAAoE,UACnF,QAAQ,IAAI,QAAQ,IAAI,MAAO,MAAM,IAAI,MAAO,SAAS,OAAO,KAAK,OAAO;AAE9E,YAAM,WAAW,OAAO,EAAE,aAAa,WAAW,EAAE,WAAW;AAE/D,UAAI,UAAU,OAAO;AACnB,cAAM,MAAM,UAAU,EAAE,IAAI;AAC5B,YAAI,IAAK,QAAO,QAAQ,GAAG;AAC3B,cAAM,MAAM,MAAM,GAAG,eAAe,EAAE,MAAM,OAAO,EAAE,SAAS,WAAW,EAAE,KAAK,KAAK,IAAI,GAAG,GAAG,OAAO;AACtG,YAAI,IAAI,MAAO,QAAO,QAAQ,KAAK,MAAM;AAEzC,cAAM,IAAI,KAAK;AACf,YAAI,KAAK,SAAS,MAAM;AACtB,gBAAM,QAAQ,MAAM,OAAO,EAAE,cAAc,KAAK,KAAK,IAAI,eAAe,KAAK,KAAK,IAAI,YAAY,KAAK,IAAI,GAAG,KAAK,KAAK,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI,CAAC,EAAE,CAAC;AAC9J,cAAI,UAAU,KAAM,YAAW,KAAK,MAAM,MAAM,SAAS,OAAO,YAAY,QAAQ,QAAQ,IAAI,QAAQ,CAAC,CAAC,EAAG,GAAE,OAAO,cAAc,CAAC;AAAA,QACvI;AACA,eAAO,KAAK,EAAE,QAAQ,SAAS,SAAS,UAAU,IAAI,IAAI,EAAE,GAAG,KAAK,CAAC;AAAA,MACvE;AACA,UAAI,UAAU,gBAAgB;AAC5B,cAAM,MAAM,iBAAiB,EAAE,WAAW;AAC1C,YAAI,IAAK,QAAO,QAAQ,KAAK,IAAI,MAAM,IAAI,SAAS,aAAa;AACjE,cAAM,MAAM,MAAM,GAAG,wBAAwB,EAAE,kBAAkB,UAAU,cAAc,EAAE,YAAY,CAAC;AACxG,YAAI,IAAI,MAAO,QAAO,QAAQ,KAAK,IAAI,MAAM,SAAS,mBAAmB,aAAa,IAAI,MAAM,SAAS,kBAAkB,gBAAgB,MAAS;AAGpJ,cAAM,OAAO,MAAM,OAAO,IAAI,IAAI;AAClC,cAAM,IAAI,IAAI,QAAQ;AACtB,cAAM,MAAM,YAAY,QAAQ,QAAQ,IAAI,QAAQ,CAAC;AACrD,mBAAW,KAAK,SAAS,OAAO,MAAM,MAAM,SAAS,MAAM,GAAG,IAAI,WAAW,YAAY,MAAM,SAAS,CAAC,GAAG,GAAG,EAAG,GAAE,OAAO,cAAc,CAAC;AAC1I,eAAO,KAAK,EAAE,QAAQ,WAAW,UAAU,SAAS,KAAK,GAAG,KAAK,CAAC;AAAA,MACpE;AACA,UAAI,UAAU,iBAAiB;AAC7B,cAAM,MAAM,MAAM,GAAG,sBAAsB,EAAE,SAAS,CAAC;AACvD,YAAI,IAAI,MAAO,QAAO,QAAQ,KAAK,IAAI,MAAM,SAAS,qBAAqB,aAAa,MAAS;AACjG,eAAO,KAAK,EAAE,QAAQ,WAAW,QAAQ,OAAO,IAAI,MAAM,UAAU,EAAE,GAAG,YAAY,OAAO,IAAI,MAAM,eAAe,EAAE,EAAE,GAAG,KAAK,KAAK,OAAO;AAAA,MAC/I;AACA,UAAI,UAAU,kBAAkB;AAC9B,cAAM,MAAM,UAAU,EAAE,IAAI;AAC5B,YAAI,IAAK,QAAO,QAAQ,GAAG;AAC3B,cAAM,MAAM,MAAM,GAAG,uBAAuB,EAAE,MAAM,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAC3E,YAAI,IAAI,MAAO,QAAO,QAAQ,KAAK,MAAM;AACzC,eAAO,KAAK,EAAE,QAAQ,WAAW,eAAe,MAAM,QAAQ,IAAI,MAAM,cAAc,IAAI,IAAI,KAAK,eAAe,IAAI,MAAM,IAAI,CAAC,EAAE,GAAG,KAAK,KAAK,OAAO;AAAA,MACzJ;AACA,UAAI,UAAU,iBAAiB;AAC7B,cAAM,MAAM,MAAM,GAAG,sBAAsB,EAAE,OAAO,OAAO,EAAE,UAAU,WAAW,EAAE,QAAQ,IAAI,SAAS,OAAO,EAAE,YAAY,WAAW,EAAE,UAAU,OAAO,SAAS,CAAC;AACtK,YAAI,IAAI,MAAO,QAAO,QAAQ,KAAK,IAAI,MAAM,SAAS,qBAAqB,aAAa,IAAI,MAAM,SAAS,qBAAqB,UAAU,MAAS;AACnJ,eAAO,KAAK,EAAE,QAAQ,QAAQ,QAAQ,OAAO,IAAI,MAAM,WAAW,EAAE,GAAG,SAAS,OAAO,IAAI,MAAM,WAAW,EAAE,EAAE,GAAG,KAAK,KAAK,OAAO;AAAA,MACtI;AACA,UAAI,UAAU,wBAAwB;AACpC,cAAM,MAAM,UAAU,EAAE,IAAI;AAC5B,YAAI,IAAK,QAAO,QAAQ,GAAG;AAC3B,cAAM,MAAM,MAAM,GAAG,6BAA6B,EAAE,MAAM,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACjF,YAAI,IAAI,MAAO,QAAO,QAAQ,KAAK,MAAM;AACzC,eAAO,KAAK,EAAE,QAAQ,WAAW,eAAe,MAAM,QAAQ,IAAI,MAAM,cAAc,IAAI,IAAI,KAAK,eAAe,IAAI,MAAM,IAAI,CAAC,EAAE,GAAG,KAAK,KAAK,OAAO;AAAA,MACzJ;AACA,UAAI,UAAU,wBAAwB;AACpC,cAAM,MAAM,MAAM,GAAG,6BAA6B,EAAE,SAAS,CAAC;AAC9D,YAAI,IAAI,MAAO,QAAO,QAAQ,KAAK,IAAI,MAAM,SAAS,qBAAqB,aAAa,MAAS;AACjG,eAAO,KAAK,EAAE,QAAQ,UAAU,GAAG,KAAK,KAAK,OAAO;AAAA,MACtD;AACA,UAAI,UAAU,mBAAmB;AAC/B,cAAM,MAAM,MAAM,GAAG,2BAA2B,EAAE,SAAS,CAAC;AAC5D,YAAI,IAAI,MAAO,QAAO,QAAQ,KAAK,IAAI,MAAM,SAAS,qBAAqB,aAAa,MAAS;AACjG,eAAO,KAAK,EAAE,QAAQ,WAAW,GAAG,KAAK,KAAK,OAAO;AAAA,MACvD;AACA,UAAI,UAAU,0BAA0B;AACtC,cAAM,MAAM,MAAM,GAAG,kCAAkC,EAAE,SAAS,CAAC;AACnE,YAAI,IAAI,MAAO,QAAO,QAAQ,KAAK,IAAI,MAAM,SAAS,qBAAqB,aAAa,MAAS;AACjG,eAAO,KAAK,EAAE,QAAQ,WAAW,eAAe,MAAM,QAAQ,IAAI,MAAM,cAAc,IAAI,IAAI,KAAK,eAAe,IAAI,MAAM,IAAI,CAAC,EAAE,GAAG,KAAK,KAAK,OAAO;AAAA,MACzJ;AACA,UAAI,UAAU,aAAa;AACzB,cAAM,MAAM,WAAW,EAAE,KAAK;AAC9B,YAAI,IAAK,QAAO,QAAQ,GAAG;AAC3B,cAAM,QAAQ,OAAO,EAAE,KAAK,EAAE,KAAK;AACnC,cAAM,MAAM,MAAM,GAAG,qBAAqB,EAAE,OAAO,SAAS,CAAC;AAC7D,YAAI,IAAI,MAAO,QAAO,QAAQ,KAAK,IAAI,MAAM,SAAS,qBAAqB,aAAa,CAAC,iBAAiB,mBAAmB,aAAa,EAAE,SAAS,IAAI,MAAM,IAAI,IAAI,UAAU,MAAS;AAE1L,eAAO,KAAK,EAAE,QAAQ,QAAQ,MAAM,GAAG,KAAK,KAAK,OAAO;AAAA,MAC1D;AACA,UAAI,UAAU,yBAAyB;AACrC,cAAM,WAAW,OAAO,EAAE,aAAa,WAAW,EAAE,WAAW;AAC/D,YAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,QAAO,QAAQ,KAAK,oBAAoB,iCAAiC,YAAY,KAAK,OAAO;AAClI,cAAM,MAAM,MAAM,GAAG,uBAAuB,QAAQ,IAAI,QAAW,QAAQ;AAC3E,YAAI,IAAI,MAAO,QAAO,QAAQ,GAAG;AACjC,eAAO,KAAK,EAAE,QAAQ,YAAY,SAAS,GAAG,KAAK,KAAK,OAAO;AAAA,MACjE;AAGA,UAAI,UAAU,0BAA0B;AACtC,cAAM,OAAO,EAAE,SAAS,YAAY,EAAE,SAAS,iBAAiB,EAAE,OAAO;AACzE,cAAM,MAAM,MAAM,GAAG,oCAAoC,EAAE,UAAU,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC,EAAG,CAAC;AAChG,YAAI,IAAI,MAAO,QAAO,QAAQ,KAAK,IAAI,MAAM,SAAS,qBAAqB,aAAa,MAAS;AACjG,cAAM,OAAa,EAAE,MAAM,SAAS,OAAO,OAAO,IAAI,MAAM,cAAc,EAAE,GAAG,UAAU,YAAY;AACrG,cAAM,IAAI,IAAI,QAAQ,KAAK,OAAO;AAClC,UAAE,OAAO,cAAc,YAAY,YAAY,MAAM,KAAK,MAAM,MAAM,GAAG,GAAG,MAAM,SAAS,eAAe,CAAC,CAAC;AAC5G,eAAO,KAAK,EAAE,QAAQ,WAAW,SAAS,IAAI,MAAM,SAAS,aAAa,IAAI,MAAM,WAAW,KAAK,GAAG,KAAK,CAAC;AAAA,MAC/G;AACA,UAAI,UAAU,2BAA2B;AACvC,cAAM,SAAS,YAAY,QAAQ,QAAQ,IAAI,QAAQ,CAAC,EAAE,IAAI,UAAU;AACxE,cAAM,OAAO,SAAS,MAAM,OAAa,QAAQ,MAAM,GAAG,IAAI;AAC9D,YAAI,SAAS,QAAQ,KAAK,SAAS,QAAS,QAAO,QAAQ,KAAK,gBAAgB,kEAAkE,QAAW,KAAK,OAAO;AACzK,YAAI,CAAC,aAAa,EAAE,UAAU,EAAG,QAAO,QAAQ,KAAK,eAAe,sCAAsC,QAAW,KAAK,OAAO;AACjI,cAAM,OAAO,OAAO,EAAE,SAAS,WAAW,EAAE,KAAK,KAAK,EAAE,MAAM,GAAG,EAAE,IAAI;AACvE,cAAM,MAAM,MAAM,GAAG,qCAAqC,EAAE,YAAY,KAAK,OAAO,UAAU,MAAM,YAAY,EAAE,WAAW,CAAC;AAC9H,cAAM,IAAI,IAAI,QAAQ,KAAK,OAAO;AAClC,UAAE,OAAO,cAAc,YAAY,YAAY,IAAI,MAAM,SAAS,CAAC,CAAC,CAAC;AACrE,YAAI,IAAI,MAAO,QAAO,QAAQ,IAAI,QAAQ,IAAI,MAAM,SAAS,wBAAwB,mBAAmB,IAAI,MAAM,MAAM,IAAI,MAAM,SAAS,wBAAwB,+CAA+C,IAAI,MAAM,SAAS,QAAW,CAAC;AACjP,eAAO,KAAK,EAAE,QAAQ,SAAS,SAAS,UAAU,IAAI,IAAI,EAAE,GAAG,KAAK,CAAC;AAAA,MACvE;AACA,UAAI,UAAU,uBAAuB;AACnC,cAAM,KAAK,OAAO,EAAE,OAAO,WAAW,EAAE,KAAK;AAC7C,YAAI,CAAC,mBAAmB,KAAK,EAAE,EAAG,QAAO,QAAQ,KAAK,mBAAmB,gCAAgC,QAAW,KAAK,OAAO;AAChI,cAAM,MAAM,MAAM,GAAG,iCAAiC,EAAE,IAAI,QAAW,QAAQ;AAC/E,YAAI,IAAI,MAAO,QAAO,QAAQ,GAAG;AACjC,eAAO,KAAK,EAAE,QAAQ,WAAW,GAAG,GAAG,KAAK,KAAK,OAAO;AAAA,MAC1D;AAEA,UAAI,UAAU,eAAe;AAC3B,cAAM,MAAM,aAAa,UAAU,EAAE,IAAI,GAAG,WAAW,EAAE,KAAK,GAAG,iBAAiB,EAAE,QAAQ,CAAC;AAC7F,YAAI,IAAK,QAAO,QAAQ,GAAG;AAC3B,cAAM,MAAM,MAAM,GAAG,8BAA8B,EAAE,OAAO,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,UAAU,EAAE,UAAU,cAAc,OAAO,EAAE,SAAS,WAAW,EAAE,KAAK,KAAK,IAAI,GAAG,CAAC;AACzK,YAAI,IAAI,MAAO,QAAO,QAAQ,KAAK,IAAI,MAAM,SAAS,kBAAkB,aAAa,OAAO;AAC5F,eAAO,SAAS,SAAS,IAAI,IAAI;AAAA,MACnC;AAEA,UAAI,MAAM,WAAW,4BAA4B,GAAG;AAClD,cAAM,MAAM,OAAO,EAAE,mBAAmB,WAAW,EAAE,iBAAiB;AACtE,YAAI,CAAC,KAAK,KAAK,GAAG,EAAG,QAAO,QAAQ,KAAK,wBAAwB,2BAA2B,QAAW,KAAK,OAAO;AACnH,cAAM,OAAO,6BAA6B,GAAG;AAC7C,YAAI,UAAU,iCAAiC;AAC7C,gBAAM,MAAM,WAAW,EAAE,KAAK;AAC9B,cAAI,IAAK,QAAO,QAAQ,GAAG;AAC3B,gBAAM,OAAO,OAAO,EAAE,SAAS,WAAW,EAAE,OAAO;AACnD,cAAI,SAAS,GAAI,QAAO,QAAQ,KAAK,gBAAgB,kBAAkB,QAAQ,KAAK,OAAO;AAC3F,gBAAM,MAAM,MAAM,GAAG,MAAM;AAAA,YAAE,OAAO,OAAO,EAAE,KAAK,EAAE,KAAK;AAAA,YAAG;AAAA,YAAM,MAAM,OAAO,EAAE,SAAS,WAAW,EAAE,KAAK,KAAK,IAAI;AAAA,YACnH,WAAW;AAAA,YAAU,GAAI,OAAO,EAAE,WAAW,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,IAAI,CAAC;AAAA,UAAG,CAAC;AAClG,cAAI,IAAI,MAAO,QAAO,QAAQ,KAAK,IAAI,MAAM,SAAS,iBAAiB,SAAS,OAAO;AACvF,iBAAO,KAAK,EAAE,QAAQ,SAAS,QAAQ,YAAY,IAAI,IAAI,EAAE,GAAG,KAAK,KAAK,OAAO;AAAA,QACnF;AACA,cAAM,OAAO,OAAO,EAAE,WAAW,WAAW,EAAE,SAAS;AACvD,YAAI,CAAC,KAAK,KAAK,IAAI,EAAG,QAAO,QAAQ,KAAK,kBAAkB,qBAAqB,QAAW,KAAK,OAAO;AACxG,YAAI,UAAU,kCAAkC;AAC9C,gBAAM,OAAO,OAAO,EAAE,SAAS,WAAW,EAAE,OAAO;AACnD,cAAI,SAAS,GAAI,QAAO,QAAQ,KAAK,gBAAgB,kBAAkB,QAAQ,KAAK,OAAO;AAC3F,gBAAM,MAAM,MAAM,GAAG,GAAG,IAAI,IAAI,IAAI,IAAI,EAAE,KAAK,GAAG,KAAK;AACvD,cAAI,IAAI,MAAO,QAAO,QAAQ,KAAK,MAAM;AACzC,iBAAO,KAAK,EAAE,QAAQ,WAAW,QAAQ,MAAM,KAAK,GAAG,KAAK,KAAK,OAAO;AAAA,QAC1E;AACA,YAAI,UAAU,oCAAoC;AAChD,gBAAM,MAAM,MAAM,GAAG,GAAG,IAAI,IAAI,IAAI,IAAI,QAAW,QAAQ;AAC3D,cAAI,IAAI,MAAO,QAAO,QAAQ,GAAG;AACjC,mBAAS,OAAO,KAAK,KAAK;AAC1B,iBAAO,KAAK,EAAE,QAAQ,WAAW,QAAQ,KAAK,GAAG,KAAK,KAAK,OAAO;AAAA,QACpE;AACA,YAAI,UAAU,oCAAoC;AAChD,gBAAM,MAAM,MAAM,GAAG,GAAG,IAAI,IAAI,IAAI,WAAW,EAAE,WAAW,UAAU,GAAI,OAAO,EAAE,WAAW,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,IAAI,CAAC,EAAG,CAAC;AACjJ,cAAI,IAAI,MAAO,QAAO,QAAQ,GAAG;AACjC,iBAAO,KAAK,EAAE,QAAQ,QAAQ,QAAQ,KAAK,GAAG,KAAK,KAAK,OAAO;AAAA,QACjE;AAAA,MACF;AACA,UAAI,UAAU,yBAAyB;AACrC,cAAM,KAAK,OAAO,EAAE,OAAO,WAAW,EAAE,KAAK;AAC7C,YAAI,CAAC,mBAAmB,KAAK,EAAE,EAAG,QAAO,QAAQ,KAAK,iBAAiB,kCAAkC,QAAW,KAAK,OAAO;AAChI,cAAM,MAAM,MAAM,GAAG,sBAAsB,EAAE,IAAI,QAAW,QAAQ;AACpE,YAAI,IAAI,MAAO,QAAO,QAAQ,GAAG;AACjC,eAAO,KAAK,EAAE,QAAQ,gBAAgB,GAAG,GAAG,KAAK,KAAK,OAAO;AAAA,MAC/D;AACA,UAAI,UAAU,oBAAoB;AAChC,cAAM,MAAM,MAAM,GAAG,wBAAwB,QAAW,QAAQ;AAChE,YAAI,IAAI,MAAO,QAAO,QAAQ,GAAG;AAEjC,cAAM,IAAI,IAAI,QAAQ;AACtB,mBAAW,KAAK,WAAW,YAAY,MAAM,SAAS,CAAC,GAAG,YAAY,QAAQ,QAAQ,IAAI,QAAQ,CAAC,CAAC,EAAG,GAAE,OAAO,cAAc,CAAC;AAC/H,iBAAS,OAAO,KAAK,KAAK;AAC1B,eAAO,KAAK,EAAE,QAAQ,aAAa,GAAG,KAAK,CAAC;AAAA,MAC9C;AACA,aAAO;AAAA,IACT;AAEA,UAAM,UAAU,CAAC,MAA4B,OAAO,MAAM,YAAY,MAAM,MAAM,EAAE,UAAU;AAC9F,UAAM,UAAU,MAAM,QAAQ,KAAK,iBAAiB,4CAA4C;AAGhG,QAAI,UAAU,mBAAmB;AAC/B,UAAI,CAAC,QAAQ,EAAE,KAAK,EAAG,QAAO,QAAQ;AACtC,YAAM,MAAM,iBAAiB,EAAE,QAAQ;AACvC,UAAI,IAAK,QAAO,QAAQ,GAAG;AAC3B,YAAM,MAAM,MAAM,IAAI,SAAS,QAAQ,4BAA4B,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,cAAc,EAAE,SAAS,CAAC;AACvH,UAAI,IAAI,MAAO,QAAO,QAAQ,IAAI,QAAQ,IAAI,MAAM,MAAM,IAAI,MAAM,SAAS,IAAI,MAAM,SAAS,kBAAkB,aAAa,MAAS;AACxI,aAAO,KAAK,EAAE,QAAQ,UAAU,CAAC;AAAA,IACnC;AACA,QAAI,UAAU,iBAAiB;AAC7B,UAAI,CAAC,QAAQ,EAAE,KAAK,EAAG,QAAO,QAAQ;AACtC,YAAM,MAAM,MAAM,IAAI,SAAS,QAAQ,yBAAyB,EAAE,OAAO,OAAO,EAAE,KAAK,EAAE,CAAC;AAC1F,UAAI,IAAI,MAAO,QAAO,QAAQ,IAAI,QAAQ,IAAI,MAAM,MAAM,IAAI,MAAM,OAAO;AAG3E,UAAI,IAAI,MAAM,aAAc,QAAO,SAAS,SAAS,IAAI,IAAI;AAC7D,aAAO,KAAK,EAAE,QAAQ,WAAW,CAAC;AAAA,IACpC;AAIA,QAAI,UAAU,0BAA0B;AAGtC,YAAM,QAAQ,OAAO,EAAE,UAAU,YAAY,WAAW,EAAE,KAAK,MAAM,OAAO,EAAE,MAAM,KAAK,IAAI;AAC7F,YAAM,MAAM,MAAM,IAAI,SAAS,QAAQ,iCAAiC,UAAU,KAAK,EAAE,MAAM,IAAI,CAAC,CAAC;AACrG,UAAI,IAAI,MAAO,QAAO,QAAQ,IAAI,QAAQ,IAAI,MAAM,MAAM,IAAI,MAAM,OAAO;AAC3E,YAAM,OAAa,EAAE,MAAM,WAAW,OAAO,OAAO,IAAI,MAAM,cAAc,EAAE,GAAG,UAAU,YAAY;AACvG,aAAO;AAAA,QAAK,EAAE,QAAQ,WAAW,SAAS,IAAI,MAAM,SAAS,aAAa,IAAI,MAAM,WAAW,KAAK;AAAA,QAAG;AAAA,QACrG,IAAI,QAAQ,EAAE,cAAc,YAAY,YAAY,MAAM,KAAK,MAAM,MAAM,GAAG,GAAG,MAAM,SAAS,eAAe,CAAC,EAAE,CAAC;AAAA,MAAC;AAAA,IACxH;AACA,QAAI,UAAU,2BAA2B;AACvC,YAAM,SAAS,YAAY,QAAQ,QAAQ,IAAI,QAAQ,CAAC,EAAE,IAAI,UAAU;AACxE,YAAM,OAAO,SAAS,MAAM,OAAa,QAAQ,MAAM,GAAG,IAAI;AAC9D,UAAI,SAAS,QAAQ,KAAK,SAAS,UAAW,QAAO,QAAQ,KAAK,gBAAgB,uDAAuD;AACzI,UAAI,CAAC,aAAa,EAAE,UAAU,EAAG,QAAO,QAAQ,KAAK,eAAe,6CAA6C;AACjH,YAAM,MAAM,MAAM,IAAI,SAAS,QAAQ,kCAAkC,EAAE,YAAY,KAAK,OAAO,YAAY,EAAE,WAAW,CAAC;AAC7H,YAAM,QAAQ,YAAY,YAAY,IAAI,MAAM,SAAS,CAAC,CAAC;AAC3D,UAAI,IAAI,OAAO;AAEb,cAAMN,UAAS,CAAC,qBAAqB,mBAAmB,kBAAkB,WAAW,EAAE,SAAS,IAAI,MAAM,IAAI;AAC9G,eAAO,QAAQ,IAAI,QAAQA,UAAS,mBAAmB,IAAI,MAAM,MAAMA,UAAS,mFAAmF,IAAI,MAAM,SAAS,QAAW,IAAI,QAAQ,EAAE,cAAc,MAAM,CAAC,CAAC;AAAA,MACvO;AACA,aAAO,SAAS,SAAS,IAAI,MAAM,CAAC,KAAK,CAAC;AAAA,IAC5C;AAKA,QAAI,UAAU,iCAAiC;AAC7C,YAAM,MAAM,MAAM,IAAI,SAAS,QAAQ,iCAAiC,CAAC,CAAC;AAC1E,UAAI,IAAI,MAAO,QAAO,QAAQ,IAAI,QAAQ,IAAI,MAAM,MAAM,IAAI,MAAM,OAAO;AAC3E,aAAO,KAAK,EAAE,QAAQ,WAAW,UAAU,OAAO,IAAI,MAAM,aAAa,EAAE,GAAG,OAAO,OAAO,IAAI,MAAM,SAAS,EAAE,EAAE,CAAC;AAAA,IACtH;AACA,QAAI,UAAU,2BAA2B;AACvC,UAAI,OAAO,EAAE,eAAe,YAAY,EAAE,eAAe,GAAI,QAAO,QAAQ,KAAK,eAAe,2CAA2C;AAC3I,YAAM,MAAM,MAAM,IAAI,SAAS,QAAQ,2BAA2B,EAAE,YAAY,EAAE,WAAW,CAAC;AAC9F,UAAI,IAAI,MAAO,QAAO,QAAQ,IAAI,QAAQ,IAAI,MAAM,MAAM,IAAI,MAAM,OAAO;AAC3E,aAAO,SAAS,SAAS,IAAI,IAAI;AAAA,IACnC;AAIA,QAAI,UAAU,uBAAuB;AACnC,YAAM,MAAM,WAAW,EAAE,KAAK;AAC9B,UAAI,IAAK,QAAO,QAAQ,GAAG;AAC3B,UAAI,MAAM,WAAW,OAAW,QAAO,QAAQ,KAAK,kBAAkB,wFAAwF;AAI9J,YAAM,QAAQ,OAAO,EAAE,KAAK,EAAE,KAAK;AAGnC,YAAM,OAAO,OAAO,EAAE,aAAa,WAAW,UAAU,EAAE,UAAU,WAAW,IAAI;AACnF,YAAM,OAAO,SAAS,cAAc,MAAM,SAAS,GAAG,MAAM,MAAM,GAAG,MAAM,OAAO,SAAS,GAAG,IAAI,MAAM,GAAG,aAAa,mBAAmB,IAAI,CAAC;AAChJ,YAAM,IAAI,SAAS,QAAQ,+BAA+B,EAAE,OAAO,GAAI,EAAE,WAAW,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC,EAAG,GAAG,IAAI;AAGjI,YAAM,OAAa,EAAE,MAAM,QAAQ,OAAO,OAAO,UAAU,KAAK;AAChE,aAAO,KAAK,EAAE,QAAQ,OAAO,GAAG,KAAK,IAAI,QAAQ,EAAE,cAAc,YAAY,YAAY,MAAM,KAAK,MAAM,MAAM,GAAG,GAAG,MAAM,SAAS,YAAY,CAAC,EAAE,CAAC,CAAC;AAAA,IACxJ;AACA,QAAI,UAAU,uBAAuB;AACnC,YAAM,MAAM,UAAU,EAAE,IAAI;AAC5B,UAAI,IAAK,QAAO,QAAQ,GAAG;AAC3B,YAAM,SAAS,YAAY,QAAQ,QAAQ,IAAI,QAAQ,CAAC,EAAE,IAAI,UAAU;AACxE,YAAM,OAAO,SAAS,MAAM,OAAa,QAAQ,MAAM,GAAG,IAAI;AAC9D,UAAI,SAAS,QAAQ,KAAK,SAAS,OAAQ,QAAO,QAAQ,KAAK,gBAAgB,0DAA0D;AACzI,YAAM,MAAM,MAAM,IAAI,SAAS,QAAQ,mCAAmC,EAAE,OAAO,KAAK,OAAO,MAAM,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAC5H,UAAI,IAAI,MAAO,QAAO,QAAQ,IAAI,QAAQ,IAAI,MAAM,MAAM,IAAI,MAAM,SAAS,MAAM;AACnF,aAAO,SAAS,SAAS,IAAI,MAAM,CAAC,YAAY,YAAY,IAAI,MAAM,SAAS,CAAC,CAAC,CAAC,GAAG,EAAE,UAAU,KAAK,SAAS,CAAC;AAAA,IAClH;AACA,QAAI,UAAU,8BAA8B;AAC1C,UAAI,CAAC,QAAQ,EAAE,KAAK,EAAG,QAAO,QAAQ;AACtC,YAAM,MAAM,MAAM,IAAI,SAAS,QAAQ,8BAA8B,EAAE,OAAO,OAAO,EAAE,KAAK,EAAE,CAAC;AAC/F,UAAI,IAAI,MAAO,QAAO,QAAQ,IAAI,QAAQ,IAAI,MAAM,MAAM,IAAI,MAAM,OAAO;AAC3E,aAAO,SAAS,SAAS,IAAI,IAAI;AAAA,IACnC;AACA,WAAO;AAAA,EACT;AAEA,iBAAe,QAAQ,SAAqC;AAC1D,UAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;AAC/B,QAAI,IAAI,aAAa,YAAY,CAAC,IAAI,SAAS,WAAW,GAAG,QAAQ,GAAG,EAAG,QAAO,IAAI,SAAS,aAAa,EAAE,QAAQ,IAAI,CAAC;AAC3H,UAAM,QAAQ,uBAAuB,IAAI,SAAS,MAAM,SAAS,MAAM,CAAC,KAAK;AAC7E,UAAM,MAAM,QAAQ,WAAW,SAAS,QAAQ,WAAW;AAE3D,UAAM,OAAO,MAAM,SAAS,SAAS,KAAK,KAAK;AAC/C,QAAI,SAAS,KAAM,QAAO;AAE1B,QAAI,UAAU,YAAY,IAAK,QAAO,MAAM,SAAS,GAAG;AACxD,QAAI,UAAU,eAAe,IAAK,QAAO,SAAS,SAAS,GAAG;AAC9D,QAAI,UAAU,cAAc,OAAO,QAAQ,WAAW,QAAS,QAAO,OAAO,OAAO;AAEpF,QAAI,UAAU,cAAc,KAAK;AAC/B,YAAM,IAAI,MAAMJ,SAAQ,OAAO;AAC/B,YAAM,IAAI,IAAI,QAAQ;AACtB,iBAAW,KAAK,EAAE,QAAS,GAAE,OAAO,cAAc,CAAC;AACnD,aAAO,KAAK,EAAE,SAAS,EAAE,UAAU,MAAM,SAAS,EAAE,OAAO,IAAI,MAAM,QAAQ,EAAE,OAAO,GAAG,KAAK,CAAC;AAAA,IACjG;AAGA,QAAI,UAAU,cAAc,KAAK;AAC/B,YAAM,IAAI,MAAMA,SAAQ,OAAO;AAC/B,YAAM,OAAO,UAAU,IAAI,aAAa,IAAI,WAAW,GAAG,WAAW;AACrE,UAAI,EAAE,WAAW,kBAAmB,QAAO,SAAS,KAAK,OAAO,IAAI,GAAG,EAAE,OAAO;AAChF,UAAI,EAAE,WAAW,UAAW,QAAO,IAAI,SAAS,4DAA4D,EAAE,QAAQ,IAAI,CAAC;AAC3H,aAAO,SAAS,MAAM,EAAE,OAAO;AAAA,IACjC;AAEA,QAAI,UAAU,cAAc,KAAK;AAC/B,YAAM,IAAI,IAAI,gBAAgB,EAAE,WAAW,SAAS,CAAC;AACrD,YAAM,OAAO,UAAU,IAAI,aAAa,IAAI,WAAW,GAAG,EAAE;AAC5D,UAAI,SAAS,GAAI,GAAE,IAAI,aAAa,GAAG,SAAS,OAAO,CAAC,GAAG,IAAI,EAAE;AACjE,YAAM,SAAS,IAAI,aAAa,IAAI,QAAQ;AAC5C,UAAI,UAAU,oBAAoB,KAAK,MAAM,EAAG,GAAE,IAAI,cAAc,MAAM;AAC1E,aAAO,SAAS,GAAG,MAAM,qBAAqB,CAAC,EAAE;AAAA,IACnD;AACA,WAAO,IAAI,SAAS,aAAa,EAAE,QAAQ,IAAI,CAAC;AAAA,EAClD;AAEA,iBAAe,QAAQ,SAAkB;AACvC,UAAM,EAAE,MAAM,IAAI,MAAM,KAAK,OAAO;AACpC,QAAI,UAAU,QAAQ,MAAM,KAAK,EAAG,QAAO,EAAE,SAAS,UAAU,KAAK,EAAE;AACvE,UAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;AAC/B,UAAM,QAAQ,UAAU,OAAO,SAAS;AAGxC,UAAM,OAAO,QAAQ,WAAW,UAAU,QAAQ,QAAQ,IAAI,gBAAgB,KAAK,gBAAgB,eAChG,QAAQ,QAAQ,IAAI,QAAQ,KAAK,aAAa,SAAS,WAAW;AACrE,QAAI,CAAC,MAAM;AACT,aAAO,EAAE,UAAU,KAAK,EAAE,OAAO,mBAAmB,SAAS,MAAM,GAAG,KAAK,IAAI,QAAQ,EAAE,oBAAoB,MAAM,CAAC,CAAC,EAAE;AAAA,IACzH;AACA,UAAM,OAAO,IAAI,WAAW,IAAI;AAChC,UAAM,KAAK,UAAU,OAAO,KAAK,OAAO,IAAI,IAAI,GAAG,QAAQ,sBAAsB,mBAAmB,IAAI,CAAC;AACzG,WAAO,EAAE,UAAU,SAAS,EAAE,EAAE;AAAA,EAClC;AAIA,QAAM,UAA6B,CAAC,SAAS,IAAI,CAAC,MAChD,cAAc,SAAS,EAAE,QAAQ,KAAK,EAAE,OAAO,GAAG,SAAS,OAAO,CAAC,GAAG,IAAI,IAAI,QAAQ,GAAG,EAAE,QAAQ,IAAI,MAAM,EAAE,MAAM,KAAK,EAAE,IAAI,CAAC;AAEnI,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA,SAAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,EAAE,QAAQ,UAAU,UAAU,aAAa,cAAc,WAAW;AAAA,EAC/E;AACF;;;AC93CA,SAAS,QAAQ,OAAe,UAAkB,QAAyB;AAEzE,QAAM,IAAI,MAAM,YAAY,GAAG;AAC/B,MAAI,IAAI,EAAG,QAAO;AAClB,QAAM,IAAI,MAAM,MAAM,GAAG,CAAC;AAC1B,QAAM,IAAI,MAAM,MAAM,IAAI,CAAC;AAC3B,UAAQ,MAAM,OAAO,MAAM,cAAc,MAAM,OAAO,MAAM;AAC9D;AAWO,SAAS,IAAI,cAA4C,UAAkB,QAAyB;AACzG,MAAI,CAAC,cAAc,YAAa,QAAO;AACvC,OAAK,aAAa,UAAU,CAAC,GAAG,KAAK,CAAC,MAAM,QAAQ,GAAG,UAAU,MAAM,CAAC,EAAG,QAAO;AAClF,SAAO,aAAa,YAAY,KAAK,CAAC,MAAM,QAAQ,GAAG,UAAU,MAAM,CAAC;AAC1E;AAkFO,SAAS,aAAmD,OAA+D;AAGhI,QAAM,QAAQ,CAAC,MAA4C,GAAG,EAAE,QAAQ,IAAI,EAAE,MAAM;AACpF,QAAM,SAAS,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AACpD,QAAM,QAAQ,CAAC,eAAyC;AACtD,UAAM,IAAI,WAAW,YAAY,GAAG;AACpC,WAAO,IAAI,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,WAAW,MAAM,GAAG,CAAC,GAAG,WAAW,MAAM,IAAI,CAAC,CAAC;AAAA,EACpF;AACA,SAAO;AAAA,IACL,OAAO,MAAM,IAAI,CAAC,OAAO;AAAA,MACvB,MAAM,EAAE;AAAA,MACR,GAAI,EAAE,SAAS,SAAY,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;AAAA,MAC/C,GAAI,EAAE,gBAAgB,SAAY,EAAE,aAAa,EAAE,YAAY,IAAI,CAAC;AAAA,MACpE,GAAI,EAAE,WAAW,EAAE,UAAU,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC;AAAA,MAClD,GAAI,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC;AAAA,IAC/E,EAAE;AAAA,IACF,WAAW,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,IAClC,aAAa,CAAC,GAAG,IAAI,IAAI,MAAM,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC;AAAA,IAChF,IAAI,cAAc,YAAY;AAC5B,YAAM,CAAC,UAAU,MAAM,IAAI,MAAM,UAAU;AAC3C,aAAO,IAAI,cAAc,UAAU,MAAM;AAAA,IAC3C;AAAA,IACA,QAAQ,iBAAiB,QAAQ;AAC/B,aAAO,gBAAgB,QAAS,OAAoB,SAAS,aAAa,IAAI;AAAA,IAChF;AAAA,IACA,cAAc,MAAY;AACxB,YAAM,OAAO,oBAAI,IAAY;AAC7B,YAAMW,OAAM,oBAAI,IAAgB;AAChC,YAAM,OAAO,CAAC,SAAiB;AAC7B,YAAI,KAAK,IAAI,IAAI,EAAG;AACpB,aAAK,IAAI,IAAI;AACb,cAAM,IAAI,OAAO,IAAI,IAAI;AACzB,mBAAW,KAAK,GAAG,eAAe,CAAC,EAAG,CAAAA,KAAI,IAAI,MAAM,CAAC,CAAC;AACtD,mBAAW,UAAU,GAAG,YAAY,CAAC,EAAG,MAAK,MAAM;AAAA,MACrD;AACA,WAAK,IAAI;AACT,aAAO,CAAC,GAAGA,IAAG;AAAA,IAChB;AAAA,EACF;AACF;AAEA,IAAM,QAAQ;AAOP,SAAS,aAAa,QAAgB,OAA6B;AACxE,QAAM,OAAO,CAAC,MAAc,KAAK,UAAU,CAAC;AAC5C,QAAM,MAAM,CAAC,MAAe,MAAM,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC;AACtD,QAAM,MAAM,CAAC,MAAkB;AAC7B,UAAM,QAAQ,CAAC,SAAS,KAAK,EAAE,IAAI,CAAC,EAAE;AACtC,QAAI,EAAE,KAAM,OAAM,KAAK,SAAS,KAAK,EAAE,IAAI,CAAC,EAAE;AAC9C,QAAI,EAAE,YAAa,OAAM,KAAK,gBAAgB,KAAK,EAAE,WAAW,CAAC,EAAE;AACnE,QAAI,EAAE,UAAU,OAAQ,OAAM,KAAK,cAAc,EAAE,SAAS,IAAI,IAAI,EAAE,KAAK,IAAI,CAAC,GAAG;AACnF,QAAI,EAAE,aAAa,QAAQ;AACzB,YAAM,OAAO,EAAE,YAAY,IAAI,CAAC,MAAM,WAAW,CAAC,GAAI,EAAE,QAAQ,EAAE,SAAS,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,KAAK,KAAK,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,GAAI,aAAa,KAAK,EAAE,QAAQ,CAAC,IAAI,WAAW,KAAK,EAAE,MAAM,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC,KAAK;AACzM,YAAM,KAAK;AAAA,EAAmB,KAAK,KAAK,IAAI,CAAC;AAAA,MAAS;AAAA,IACxD;AACA,WAAO;AAAA,MAAY,MAAM,KAAK,SAAS,CAAC;AAAA;AAAA,EAC1C;AACA,SAAO,8BAA8B,KAAK,MAAM,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjD,MAAM,IAAI,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAO3B;AAGA,eAAsB,WAAW,IAAsC,CAAC,GAA0B;AAChG,QAAMC,OAAM,CAAC,MAAe,OAAO,YAAY,cAAc,QAAQ,MAAM,CAAC,IAAI;AAChF,QAAM,SAAS,uBAAuB,EAAE,UAAUA,KAAI,eAAe,KAAK,EAAE;AAC5E,QAAM,SAAS,EAAE,UAAUA,KAAI,eAAe,KAAK;AACnD,QAAM,SAAS,EAAE,UAAUA,KAAI,eAAe,KAAK;AACnD,QAAM,QAAQ,EAAE,SAASA,KAAI,cAAc,KAAK;AAChD,aAAW,CAAC,MAAM,CAAC,KAAK,OAAO,QAAQ,EAAE,eAAe,QAAQ,eAAe,QAAQ,eAAe,QAAQ,cAAc,MAAM,CAAC,GAAG;AACpI,QAAI,MAAM,GAAI,OAAM,IAAI,MAAM,gBAAgB,IAAI,+BAA+B;AAAA,EACnF;AACA,QAAM,MAAM,OAAO,EAAE,SAAS,OAAO,GAAG,MAAM,eAAe,mBAAmB,MAAM,CAAC,WAAW;AAAA,IAChG,SAAS,EAAE,eAAe,UAAU,KAAK,IAAI,gBAAgB,QAAQ,QAAQ,mBAAmB;AAAA,EAClG,CAAC;AACD,QAAM,OAAQ,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI;AAC/C,MAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM,mDAAmD,IAAI,MAAM,MAAM,MAAM,SAAS,CAAC,GAAG,WAAW,IAAI,UAAU,EAAE;AAC9I,SAAO,MAAM,MAAM,SAAS,CAAC;AAC/B;AAqBA,eAAsB,WAAW,GAAqC;AACpE,QAAMA,OAAM,CAAC,MAAe,OAAO,YAAY,cAAc,QAAQ,MAAM,CAAC,IAAI;AAChF,QAAM,SAAS,uBAAuB,EAAE,UAAUA,KAAI,eAAe,KAAK,EAAE;AAC5E,QAAM,SAAS,EAAE,UAAUA,KAAI,eAAe,KAAK;AACnD,QAAM,SAAS,EAAE,UAAUA,KAAI,eAAe,KAAK;AACnD,QAAM,QAAQ,EAAE,SAASA,KAAI,cAAc,KAAK;AAChD,aAAW,CAAC,MAAM,CAAC,KAAK,OAAO,QAAQ,EAAE,eAAe,QAAQ,eAAe,QAAQ,eAAe,QAAQ,cAAc,MAAM,CAAC,GAAG;AACpI,QAAI,MAAM,GAAI,OAAM,IAAI,MAAM,gBAAgB,IAAI,+BAA+B;AAAA,EACnF;AACA,QAAM,MAAM,OAAO,EAAE,SAAS,OAAO,GAAG,MAAM,eAAe,mBAAmB,MAAM,CAAC,WAAW;AAAA,IAChG,QAAQ;AAAA,IACR,SAAS,EAAE,eAAe,UAAU,KAAK,IAAI,gBAAgB,QAAQ,gBAAgB,mBAAmB;AAAA,IACxG,MAAM,KAAK,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC;AAAA,EACzC,CAAC;AACD,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,OAAQ,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI;AAC/C,UAAM,IAAI,MAAM,2CAA2C,IAAI,MAAM,MAAM,MAAM,SAAS,CAAC,GAAG,WAAW,IAAI,UAAU,EAAE;AAAA,EAC3H;AACF;;;AClNA,SAAS,gBAAwB;AAC/B,QAAM,QAAQ,OAAO,gBAAgB,IAAI,WAAW,EAAE,CAAC;AACvD,MAAI,IAAI;AACR,aAAW,KAAK,MAAO,MAAK,OAAO,aAAa,CAAC;AACjD,SAAO,KAAK,CAAC,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,EAAE;AAC1E;AAEA,eAAsB,cAAc,GAAuC;AACzE,QAAMC,OAAM,CAAC,MAAe,OAAO,YAAY,cAAc,QAAQ,MAAM,CAAC,IAAI;AAChF,QAAM,SAAS,uBAAuB,EAAE,UAAUA,KAAI,eAAe,KAAK,EAAE;AAC5E,QAAM,SAAS,EAAE,UAAUA,KAAI,eAAe,KAAK;AACnD,QAAM,QAAQ,EAAE,SAASA,KAAI,cAAc,KAAK;AAChD,aAAW,CAAC,MAAM,CAAC,KAAK,OAAO,QAAQ,EAAE,eAAe,QAAQ,eAAe,QAAQ,cAAc,MAAM,CAAC,GAAG;AAC7G,QAAI,MAAM,GAAI,OAAM,IAAI,MAAM,gBAAgB,IAAI,kCAAkC;AAAA,EACtF;AACA,QAAM,MAAM,OAAO,EAAE,SAAS,OAAO,GAAG,MAAM,eAAe;AAAA,IAC3D,QAAQ;AAAA,IACR,SAAS,EAAE,eAAe,UAAU,KAAK,IAAI,gBAAgB,QAAQ,gBAAgB,mBAAmB;AAAA,IACxG,MAAM,KAAK,UAAU;AAAA,MAAE,QAAQ,EAAE;AAAA,MAAQ,SAAS,EAAE;AAAA,MAAQ,MAAM,EAAE;AAAA,MAAM,eAAe,EAAE;AAAA,MACzF,YAAY,EAAE;AAAA,MAAW,QAAQ,EAAE;AAAA,MAAQ,UAAU,EAAE;AAAA,IAAQ,CAAC;AAAA,EACpE,CAAC;AACD,QAAM,OAAQ,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI;AAK/C,MAAI,CAAC,IAAI,MAAM,CAAC,MAAM,MAAM;AAC1B,UAAM,OAAO,MAAM,UAAU,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI,KAAK,IAAI;AACzF,UAAM,IAAI,MAAM,mDAAmD,IAAI,MAAM,MAAM,GAAG,EAAE;AAAA,EAC1F;AACA,QAAM,IAAI,KAAK;AACf,SAAO;AAAA,IAAE,QAAQ,EAAE;AAAA,IAAQ,UAAU,EAAE,OAAO;AAAA,IAAW,cAAc,EAAE;AAAA,IAAe,cAAc,EAAE,OAAO;AAAA,IAC7G,SAAS,EAAE;AAAA,IAAS,KAAK,EAAE,GAAG,EAAE,KAAK,eAAe,cAAc,EAAE;AAAA,EAAE;AAC1E;;;ACpEA,SAAS,sBAAAC,qBAAoB,aAAAC,kBAAuC;AAkB7D,IAAM,mBAAN,cAA+B,MAAM;AAAA,EAC1C,YAAqB,QAAgB;AACnC,UAAM,+BAA+B,MAAM,EAAE;AAD1B;AAEnB,SAAK,OAAO;AAAA,EACd;AAAA,EAHqB;AAIvB;AAeA,IAAMC,QAAO,oBAAI,IAA6B;AAGvC,SAASC,QAAO,QAAiC;AACtD,MAAI,MAAMD,MAAK,IAAI,MAAM;AACzB,MAAI,QAAQ,QAAW;AACrB,UAAME,oBAAmB,IAAI,IAAI,GAAG,MAAM,wBAAwB,GAAG,EAAE,kBAAkB,IAAO,CAAC;AACjG,IAAAF,MAAK,IAAI,QAAQ,GAAG;AAAA,EACtB;AACA,SAAO;AACT;AAEA,SAASG,KAAI,MAAkC;AAC7C,SAAO,OAAO,YAAY,cAAc,QAAQ,MAAM,IAAI,IAAI;AAChE;AAEA,SAAS,OAAO,MAA0C;AACxD,MAAI,OAAO,SAAS,SAAU,QAAO,KAAK,QAAQ,eAAe,EAAE,EAAE,KAAK;AAC1E,QAAM,UAAU,gBAAgB,UAAU,OAAO,KAAK,SAAS,IAAI,eAAe,KAAK;AACvF,SAAO,cAAc,KAAK,MAAM,IAAI,OAAO,QAAQ,eAAe,EAAE,EAAE,KAAK,IAAI;AACjF;AAQA,eAAsB,YAAY,MAAkC,UAA8B,CAAC,GAA2B;AAC5H,QAAM,SAAS,uBAAuB,QAAQ,UAAUA,KAAI,eAAe,KAAK,EAAE;AAClF,MAAI,WAAW,GAAI,OAAM,IAAI,iBAAiB,mCAAmC;AACjF,QAAM,QAAQ,OAAO,IAAI;AACzB,MAAI,UAAU,GAAI,OAAM,IAAI,iBAAiB,UAAU;AAEvD,MAAI;AACJ,MAAI;AACF,UAAM,WAAW,MAAMC,WAAU,OAAO,QAAQ,QAAQH,QAAO,MAAM,GAAG;AAAA,MACtE,YAAY,CAAC,OAAO;AAAA,MACpB;AAAA,MACA,UAAU,QAAQ,YAAYE,KAAI,iBAAiB;AAAA,MACnD,gBAAgB,CAAC,OAAO,KAAK;AAAA,MAC7B,aAAa,QAAQ;AAAA,IACvB,CAAC;AACD,aAAS,SAAS;AAAA,EACpB,SAAS,KAAK;AACZ,UAAM,IAAI,iBAAiB,eAAe,QAAQ,IAAI,UAAU,eAAe;AAAA,EACjF;AAEA,QAAM,WAAW,OAAO,OAAO,QAAQ,WAAW,OAAO,MAAM;AAC/D,QAAM,SAAS,QAAQ,YAAYA,KAAI,kBAAkB;AACzD,MAAI,UAAU,aAAa,OAAQ,OAAM,IAAI,iBAAiB,8BAA8B;AAE5F,SAAO;AAAA,IACL,QAAQ,OAAO,OAAO,GAAG;AAAA,IACzB;AAAA,IACA,GAAI,OAAO,OAAO,UAAU,YAAY,OAAO,UAAU,KAAK,EAAE,OAAO,OAAO,MAAM,IAAI,CAAC;AAAA,IACzF,OAAO,MAAM,QAAQ,OAAO,KAAK,IAAI,OAAO,MAAM,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ,IAAI,CAAC;AAAA,IACvG,GAAI,OAAO,OAAO,QAAQ,YAAY,OAAO,QAAQ,KAAK,EAAE,QAAQ,OAAO,IAAI,IAAI,CAAC;AAAA,IACpF,WAAW,IAAI,KAAM,OAAO,MAAiB,GAAI,EAAE,YAAY;AAAA,IAC/D;AAAA,EACF;AACF;","names":["out","out","env","out","env","env","body","resolve","out","status","bearer","failed","callback","code","done","s","b","res","out","env","env","createRemoteJWKSet","jwtVerify","keys","keysOf","createRemoteJWKSet","env","jwtVerify"]}
|