@ractive-ch/tab-mcp 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js.map CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/address.ts", "../src/config.ts", "../src/jwt.ts", "../src/identity.ts", "../src/ip.ts", "../src/log.ts", "../src/protocol.ts", "../src/exchange.ts", "../src/notopen.ts", "../src/oauth/server.ts", "../src/ratelimit.ts", "../src/tokens.ts", "../src/oauth/cimd.ts", "../src/oauth/html.ts", "../src/oauth/oidc.ts", "../src/oauth/pairing.ts", "../src/session.ts", "../src/store/memory.ts", "../src/store/sqlite.ts", "../src/relay.ts"],
3
+ "sources": ["../src/address.ts", "../src/config.ts", "../src/jwt.ts", "../src/identity.ts", "../src/ip.ts", "../src/log.ts", "../src/protocol.ts", "../src/exchange.ts", "../src/icons.ts", "../src/notopen.ts", "../src/oauth/server.ts", "../src/ratelimit.ts", "../src/tokens.ts", "../src/oauth/cimd.ts", "../src/oauth/html.ts", "../src/oauth/oidc.ts", "../src/oauth/pairing.ts", "../src/session.ts", "../src/store/memory.ts", "../src/store/sqlite.ts", "../src/relay.ts"],
4
4
  "sourcesContent": [
5
5
  "/**\n * Stable addresses (DEC-027): the page keeps a random secret, the address id is\n * `base32(sha256(secret))`. The relay stores nothing to recognise an address.\n */\n\nconst BASE32_ALPHABET = \"abcdefghijklmnopqrstuvwxyz234567\";\n\n/** RFC 4648 base32, lower case, without padding. */\nexport function base32(bytes: Uint8Array): string {\n\tlet out = \"\";\n\tlet buffer = 0;\n\tlet bits = 0;\n\tfor (const byte of bytes) {\n\t\tbuffer = (buffer << 8) | byte;\n\t\tbits += 8;\n\t\twhile (bits >= 5) {\n\t\t\tbits -= 5;\n\t\t\tout += BASE32_ALPHABET[(buffer >>> bits) & 31];\n\t\t}\n\t\tbuffer &= (1 << bits) - 1;\n\t}\n\tif (bits > 0) out += BASE32_ALPHABET[(buffer << (5 - bits)) & 31];\n\treturn out;\n}\n\n/** 32 random bytes as base64url without padding: 43 characters. */\nconst SECRET_PATTERN = /^[A-Za-z0-9_-]{43}$/;\n\n/** An address id: base32 of a SHA-256 digest, 52 characters. */\nconst ADDRESS_ID_PATTERN = /^[a-z2-7]{52}$/;\n\nexport function isWellFormedSecret(secret: string): boolean {\n\treturn SECRET_PATTERN.test(secret);\n}\n\nexport function isAddressId(id: string): boolean {\n\treturn ADDRESS_ID_PATTERN.test(id);\n}\n\n/** The address id for a page secret: base32(sha256(UTF-8 secret)). */\nexport function addressIdFromSecret(secret: string): string {\n\tconst digest = new Bun.CryptoHasher(\"sha256\").update(secret).digest();\n\treturn base32(\n\t\tnew Uint8Array(digest.buffer, digest.byteOffset, digest.length),\n\t);\n}\n\n/** A new page secret (what the browser library does; used by tests and tools). */\nexport function newSecret(): string {\n\treturn crypto\n\t\t.getRandomValues(new Uint8Array(32))\n\t\t.toBase64({ alphabet: \"base64url\", omitPadding: true });\n}\n\n/** Shortened address id for logs: enough to correlate, too short to use. */\nexport function shortAddress(id: string): string {\n\treturn id.slice(0, 8);\n}\n",
6
6
  "/**\n * Relay configuration: defaults (DEC-034), validation, and reading `TAB_MCP_*`\n * environment variables. The table lives in `kb/design/architecture.md`.\n */\n\nexport type TrustProxy = \"none\" | \"x-real-ip\" | \"x-forwarded-for\";\nexport type LogLevel = \"error\" | \"warn\" | \"info\" | \"debug\";\nexport type StoreKind = \"sqlite\" | \"memory\";\n\n/**\n * How a browser at `/authorize` proves it belongs to the tab's user (DEC-042):\n * the 6-digit code shown in the tab (DEC-028), or identity binding at an\n * OpenID Connect provider (DEC-075).\n */\nexport type PairingKind = \"code\" | \"oidc\";\n\n/** Claims the relay may compare as the subject (DEC-079); never mutable ones. */\nexport type SubjectClaim = \"sub\" | \"oid\";\n\n/** The OpenID Connect provider and the tab assertion signer (DEC-079). */\nexport interface OidcConfig {\n\t/** The provider's issuer (discovery at `/.well-known/openid-configuration`). */\n\tissuer: string;\n\t/** The relay's client at the provider. */\n\tclientId: string;\n\t/** Its secret; absent for a public client (PKCE only). */\n\tclientSecret?: string;\n\t/** The ID token claim compared with the tab's subject; default `sub`. */\n\tsubjectClaim?: SubjectClaim;\n\t/** Expected `iss` of the tab assertions (the web app's backend). */\n\tassertionIssuer: string;\n\t/** JWKS of the web app's backend that signs tab assertions. */\n\tassertionJwksUrl: string;\n}\n\n/** The limits a site may set for its own tab sessions (DEC-045). */\nexport interface SiteLimits {\n\tmaxMessageBytes: number;\n\tmaxConcurrentRequests: number;\n\trequestTimeoutMs: number;\n\tkeepAliveMs: number;\n\tidleTimeoutMs: number;\n\tsessionLifetimeMs: number;\n\theartbeatMs: number;\n}\n\n/** One site (page origin) the relay serves, as configured (DEC-045). */\nexport interface SiteConfig {\n\t/** The page origin, e.g. `https://ractive.ch`. */\n\torigin: string;\n\t/** The app name `/authorize` shows; wins over the name the page sends. */\n\tname?: string;\n\t/** Pairing method; default `identity` of the instance (`code`). */\n\tpairing?: PairingKind;\n\t/** Overrides of the instance-wide limits for this site's sessions. */\n\tlimits?: Partial<SiteLimits>;\n}\n\n/** A site with everything filled in. */\nexport interface Site {\n\t/** The origin, or `*` for the open relay's default site. */\n\torigin: string;\n\tname?: string;\n\tpairing: PairingKind;\n\tlimits: SiteLimits;\n}\n\n/**\n * The smallest `maxMessageBytes` the relay accepts: MCP requests need room,\n * and the browser library refuses a session that cannot frame a response\n * chunk (below 896 bytes).\n */\nexport const MIN_MESSAGE_BYTES = 16_384;\n\n/** Longest grace period for a page to (re)connect (DEC-074). */\nexport const MAX_PAGE_WAIT_MS = 60_000;\n\n/** Longest app name (configured or sent by the page). */\nexport const MAX_APP_NAME = 64;\n\nexport interface RelayConfig {\n\t/** External origin, e.g. `https://relay.ractive.ch`. Optional only in development. */\n\tpublicUrl?: string;\n\tport: number;\n\thost: string;\n\t/**\n\t * Page origins allowed to open tab sessions with the instance-wide limits;\n\t * `\"*\"` admits any (open relay). Shorthand for `sites` without overrides.\n\t */\n\tallowedOrigins: string[] | \"*\";\n\t/** Sites with their own name, pairing method or limits (DEC-045). */\n\tsites: SiteConfig[];\n\t/**\n\t * The pairing of sites without their own (`allowedOrigins` included):\n\t * `code` (default, DEC-028) or `oidc` (identity binding, DEC-079).\n\t */\n\tidentity: PairingKind;\n\t/** The provider and assertion signer; required when a site uses `oidc`. */\n\toidc?: OidcConfig;\n\t/** Hosts whose Client ID Metadata Documents are accepted; empty = any. */\n\tclientIdHosts: string[];\n\ttrustProxy: TrustProxy;\n\t/** CORS without credentials on the MCP endpoint (DEC-036). */\n\tcors: boolean;\n\tstore: StoreKind;\n\tsqlitePath: string;\n\tmaxSessions: number;\n\tmaxSessionsPerIp: number;\n\tmaxConcurrentRequests: number;\n\trequestTimeoutMs: number;\n\tkeepAliveMs: number;\n\tidleTimeoutMs: number;\n\tsessionLifetimeMs: number;\n\theartbeatMs: number;\n\thelloTimeoutMs: number;\n\t/** Deadline for receiving an MCP request body (Bun's idle timer does not cover it). */\n\tbodyTimeoutMs: number;\n\t/**\n\t * How long an MCP request waits for its page to (re)connect before the relay\n\t * answers \"the page is not open\" (DEC-074); 0 answers at once.\n\t */\n\tpageWaitMs: number;\n\t/** Limit for MCP request bodies and for messages from the tab. */\n\tmaxMessageBytes: number;\n\taccessTokenTtlMs: number;\n\trefreshTokenTtlMs: number;\n\t/**\n\t * Absolute end of a grant after pairing: refreshes slide by\n\t * `refreshTokenTtlMs` but never beyond this (DEC-062).\n\t */\n\tgrantLifetimeMs: number;\n\t/** How often expired tokens are deleted from the store. */\n\tsweepIntervalMs: number;\n\t/** Per-socket WebSocket send buffer; beyond it sends are dropped (DEC-021). */\n\tbackpressureLimitBytes: number;\n\t/** Bun's HTTP idle timeout in seconds; MCP requests switch it off per request. */\n\thttpIdleTimeoutS: number;\n\tlogLevel: LogLevel;\n\t/** Allows `http:` public URLs and a derived public URL. */\n\tdevelopment: boolean;\n}\n\nexport const DEFAULT_CONFIG: Readonly<RelayConfig> = {\n\tport: 8080,\n\thost: \"0.0.0.0\",\n\tallowedOrigins: [],\n\tsites: [],\n\tidentity: \"code\",\n\tclientIdHosts: [],\n\ttrustProxy: \"none\",\n\tcors: true,\n\tstore: \"sqlite\",\n\tsqlitePath: \"tab-mcp.db\",\n\tmaxSessions: 500,\n\tmaxSessionsPerIp: 5,\n\tmaxConcurrentRequests: 8,\n\trequestTimeoutMs: 300_000,\n\tkeepAliveMs: 20_000,\n\tidleTimeoutMs: 3_600_000,\n\tsessionLifetimeMs: 43_200_000,\n\theartbeatMs: 25_000,\n\thelloTimeoutMs: 10_000,\n\tbodyTimeoutMs: 10_000,\n\tpageWaitMs: 10_000,\n\tmaxMessageBytes: 1_048_576,\n\taccessTokenTtlMs: 3_600_000,\n\trefreshTokenTtlMs: 2_592_000_000,\n\tgrantLifetimeMs: 7_776_000_000,\n\tsweepIntervalMs: 600_000,\n\tbackpressureLimitBytes: 4 * 1_048_576,\n\thttpIdleTimeoutS: 30,\n\tlogLevel: \"info\",\n\tdevelopment: false,\n};\n\nexport class ConfigError extends Error {\n\toverride name = \"ConfigError\";\n}\n\n/** Normalise an origin (`scheme://host[:port]`), or throw. */\nexport function normalizeOrigin(value: string): string {\n\tlet url: URL;\n\ttry {\n\t\turl = new URL(value);\n\t} catch {\n\t\tthrow new ConfigError(`not an origin: ${value}`);\n\t}\n\tif (url.protocol !== \"https:\" && url.protocol !== \"http:\") {\n\t\tthrow new ConfigError(`origin must be http or https: ${value}`);\n\t}\n\tif (\n\t\t(url.pathname !== \"/\" && url.pathname !== \"\") ||\n\t\turl.search !== \"\" ||\n\t\turl.hash !== \"\" ||\n\t\turl.username !== \"\" ||\n\t\turl.password !== \"\"\n\t) {\n\t\tthrow new ConfigError(\n\t\t\t`an origin has no path, query or credentials (browsers send only the origin): ${value}`,\n\t\t);\n\t}\n\treturn url.origin;\n}\n\n/** Fill in defaults and validate. Throws `ConfigError` on bad values. */\nexport function resolveConfig(input: Partial<RelayConfig> = {}): RelayConfig {\n\tconst config: RelayConfig = { ...DEFAULT_CONFIG, ...input };\n\n\tif (config.publicUrl !== undefined) {\n\t\tconst origin = normalizeOrigin(config.publicUrl);\n\t\tif (!origin.startsWith(\"https:\") && !config.development) {\n\t\t\tthrow new ConfigError(\n\t\t\t\t\"TAB_MCP_PUBLIC_URL must be https outside development\",\n\t\t\t);\n\t\t}\n\t\tconfig.publicUrl = origin;\n\t} else if (!config.development) {\n\t\tthrow new ConfigError(\"TAB_MCP_PUBLIC_URL is required\");\n\t}\n\n\tif (config.allowedOrigins !== \"*\") {\n\t\tconfig.allowedOrigins = config.allowedOrigins.map(normalizeOrigin);\n\t}\n\tconfig.sites = config.sites.map((site) => validateSite(site));\n\tconst seen = new Set(\n\t\tconfig.allowedOrigins === \"*\" ? [] : config.allowedOrigins,\n\t);\n\tfor (const site of config.sites) {\n\t\tif (seen.has(site.origin)) {\n\t\t\tthrow new ConfigError(`origin configured twice: ${site.origin}`);\n\t\t}\n\t\tseen.add(site.origin);\n\t}\n\tvalidateIdentity(config);\n\tconfig.clientIdHosts = config.clientIdHosts.map((h) => {\n\t\tconst host = h.trim().toLowerCase();\n\t\tif (!/^[a-z0-9.-]+(:\\d+)?$/.test(host)) {\n\t\t\tthrow new ConfigError(`not a host name: ${h}`);\n\t\t}\n\t\treturn host;\n\t});\n\n\tconst positive: (keyof RelayConfig)[] = [\n\t\t\"maxSessions\",\n\t\t\"maxSessionsPerIp\",\n\t\t\"maxConcurrentRequests\",\n\t\t\"requestTimeoutMs\",\n\t\t\"keepAliveMs\",\n\t\t\"idleTimeoutMs\",\n\t\t\"sessionLifetimeMs\",\n\t\t\"heartbeatMs\",\n\t\t\"helloTimeoutMs\",\n\t\t\"bodyTimeoutMs\",\n\t\t\"maxMessageBytes\",\n\t\t\"accessTokenTtlMs\",\n\t\t\"refreshTokenTtlMs\",\n\t\t\"grantLifetimeMs\",\n\t\t\"sweepIntervalMs\",\n\t\t\"backpressureLimitBytes\",\n\t\t\"httpIdleTimeoutS\",\n\t];\n\tfor (const key of positive) {\n\t\tconst v = config[key];\n\t\tif (typeof v !== \"number\" || !Number.isFinite(v) || v <= 0) {\n\t\t\tthrow new ConfigError(`${key} must be a positive number`);\n\t\t}\n\t}\n\tif (\n\t\ttypeof config.pageWaitMs !== \"number\" ||\n\t\t!Number.isFinite(config.pageWaitMs) ||\n\t\tconfig.pageWaitMs < 0 ||\n\t\tconfig.pageWaitMs > MAX_PAGE_WAIT_MS\n\t) {\n\t\tthrow new ConfigError(\n\t\t\t`pageWaitMs must be 0-${MAX_PAGE_WAIT_MS} (0-${MAX_PAGE_WAIT_MS / 1000} seconds)`,\n\t\t);\n\t}\n\tif (config.maxMessageBytes < MIN_MESSAGE_BYTES) {\n\t\tthrow new ConfigError(\n\t\t\t`maxMessageBytes must be at least ${MIN_MESSAGE_BYTES} (16 KiB)`,\n\t\t);\n\t}\n\tif (config.httpIdleTimeoutS > 255) {\n\t\tthrow new ConfigError(\"httpIdleTimeoutS must be at most 255\");\n\t}\n\tif (\n\t\t!Number.isInteger(config.port) ||\n\t\tconfig.port < 0 ||\n\t\tconfig.port > 65535\n\t) {\n\t\tthrow new ConfigError(\"port must be 0-65535\");\n\t}\n\treturn config;\n}\n\nconst SITE_KEYS = new Set([\"origin\", \"name\", \"pairing\", \"limits\"]);\nconst LIMIT_KEYS: readonly (keyof SiteLimits)[] = [\n\t\"maxMessageBytes\",\n\t\"maxConcurrentRequests\",\n\t\"requestTimeoutMs\",\n\t\"keepAliveMs\",\n\t\"idleTimeoutMs\",\n\t\"sessionLifetimeMs\",\n\t\"heartbeatMs\",\n];\n\n/** An app name: 1-64 characters, no control characters. */\nexport function isAppName(value: unknown): value is string {\n\treturn (\n\t\ttypeof value === \"string\" &&\n\t\tvalue.trim().length > 0 &&\n\t\tvalue.length <= MAX_APP_NAME &&\n\t\t![...value].some((ch) => {\n\t\t\tconst c = ch.codePointAt(0) ?? 0;\n\t\t\treturn c < 0x20 || (c >= 0x7f && c <= 0x9f);\n\t\t})\n\t);\n}\n\nfunction validateSite(input: unknown): SiteConfig {\n\tif (typeof input !== \"object\" || input === null || Array.isArray(input)) {\n\t\tthrow new ConfigError(\"a site must be an object with an origin\");\n\t}\n\tconst site = input as Record<string, unknown>;\n\tfor (const key of Object.keys(site)) {\n\t\tif (!SITE_KEYS.has(key)) throw new ConfigError(`unknown site key: ${key}`);\n\t}\n\tif (typeof site[\"origin\"] !== \"string\") {\n\t\tthrow new ConfigError(\"a site needs an origin\");\n\t}\n\tconst out: SiteConfig = { origin: normalizeOrigin(site[\"origin\"]) };\n\tif (site[\"name\"] !== undefined) {\n\t\tif (!isAppName(site[\"name\"])) {\n\t\t\tthrow new ConfigError(\n\t\t\t\t`site name must be 1-${MAX_APP_NAME} characters: ${out.origin}`,\n\t\t\t);\n\t\t}\n\t\tout.name = site[\"name\"];\n\t}\n\tconst pairing = site[\"pairing\"];\n\tif (pairing !== undefined) {\n\t\tif (pairing !== \"code\" && pairing !== \"oidc\") {\n\t\t\tthrow new ConfigError(`pairing must be \"code\" or \"oidc\": ${out.origin}`);\n\t\t}\n\t\tout.pairing = pairing;\n\t}\n\tconst limits = site[\"limits\"];\n\tif (limits !== undefined) {\n\t\tif (typeof limits !== \"object\" || limits === null) {\n\t\t\tthrow new ConfigError(`site limits must be an object: ${out.origin}`);\n\t\t}\n\t\tconst given = limits as Record<string, unknown>;\n\t\tconst parsed: Partial<SiteLimits> = {};\n\t\tfor (const [key, value] of Object.entries(given)) {\n\t\t\tif (!(LIMIT_KEYS as readonly string[]).includes(key)) {\n\t\t\t\tthrow new ConfigError(`unknown site limit: ${key}`);\n\t\t\t}\n\t\t\tif (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) {\n\t\t\t\tthrow new ConfigError(`site limit ${key} must be a positive number`);\n\t\t\t}\n\t\t\tparsed[key as keyof SiteLimits] = value;\n\t\t}\n\t\tif (\n\t\t\tparsed.maxMessageBytes !== undefined &&\n\t\t\tparsed.maxMessageBytes < MIN_MESSAGE_BYTES\n\t\t) {\n\t\t\tthrow new ConfigError(\n\t\t\t\t`site limit maxMessageBytes must be at least ${MIN_MESSAGE_BYTES}`,\n\t\t\t);\n\t\t}\n\t\tout.limits = parsed;\n\t}\n\treturn out;\n}\n\n/** An https URL (http only in development) without query or fragment. */\nfunction checkUrl(value: unknown, name: string, development: boolean): string {\n\tif (typeof value !== \"string\" || value === \"\") {\n\t\tthrow new ConfigError(`${name} is required for identity binding`);\n\t}\n\tlet url: URL;\n\ttry {\n\t\turl = new URL(value);\n\t} catch {\n\t\tthrow new ConfigError(`${name} is not a URL: ${value}`);\n\t}\n\tif (url.protocol !== \"https:\" && !(development && url.protocol === \"http:\")) {\n\t\tthrow new ConfigError(`${name} must be https: ${value}`);\n\t}\n\tif (\n\t\turl.search !== \"\" ||\n\t\turl.hash !== \"\" ||\n\t\turl.username !== \"\" ||\n\t\turl.password !== \"\"\n\t) {\n\t\tthrow new ConfigError(\n\t\t\t`${name} has no query, fragment or credentials: ${value}`,\n\t\t);\n\t}\n\treturn value;\n}\n\n/** Whether any site pairs by identity, and the OIDC settings it needs (DEC-079). */\nfunction validateIdentity(config: RelayConfig): void {\n\tif (config.identity !== \"code\" && config.identity !== \"oidc\") {\n\t\tthrow new ConfigError('identity must be \"code\" or \"oidc\"');\n\t}\n\tconst used =\n\t\tconfig.sites.some((s) => (s.pairing ?? config.identity) === \"oidc\") ||\n\t\t(config.identity === \"oidc\" &&\n\t\t\tconfig.allowedOrigins !== \"*\" &&\n\t\t\tconfig.allowedOrigins.length > 0);\n\tif (config.identity === \"oidc\" && config.allowedOrigins === \"*\") {\n\t\tthrow new ConfigError(\n\t\t\t\"TAB_MCP_IDENTITY=oidc cannot be used with TAB_MCP_ALLOWED_ORIGINS=* (one provider cannot vouch for any website's users)\",\n\t\t);\n\t}\n\tconst oidc = config.oidc;\n\tif (oidc === undefined) {\n\t\tif (used) {\n\t\t\tthrow new ConfigError(\n\t\t\t\t\"identity binding (oidc) needs TAB_MCP_OIDC_ISSUER, TAB_MCP_OIDC_CLIENT_ID, TAB_MCP_TAB_ASSERTION_ISSUER and TAB_MCP_TAB_ASSERTION_JWKS_URL\",\n\t\t\t);\n\t\t}\n\t\treturn;\n\t}\n\tconst dev = config.development;\n\tcheckUrl(oidc.issuer, \"TAB_MCP_OIDC_ISSUER\", dev);\n\tcheckUrl(oidc.assertionJwksUrl, \"TAB_MCP_TAB_ASSERTION_JWKS_URL\", dev);\n\tif (typeof oidc.clientId !== \"string\" || oidc.clientId === \"\") {\n\t\tthrow new ConfigError(\n\t\t\t\"TAB_MCP_OIDC_CLIENT_ID is required for identity binding\",\n\t\t);\n\t}\n\tif (\n\t\toidc.clientSecret !== undefined &&\n\t\ttypeof oidc.clientSecret !== \"string\"\n\t) {\n\t\tthrow new ConfigError(\"TAB_MCP_OIDC_CLIENT_SECRET must be a string\");\n\t}\n\tif (typeof oidc.assertionIssuer !== \"string\" || oidc.assertionIssuer === \"\") {\n\t\tthrow new ConfigError(\n\t\t\t\"TAB_MCP_TAB_ASSERTION_ISSUER is required for identity binding\",\n\t\t);\n\t}\n\tconst claim = oidc.subjectClaim ?? \"sub\";\n\tif (claim !== \"sub\" && claim !== \"oid\") {\n\t\tthrow new ConfigError(\n\t\t\t'TAB_MCP_OIDC_SUBJECT_CLAIM must be \"sub\" or \"oid\" (a stable identifier, never email or a user name)',\n\t\t);\n\t}\n\tconfig.oidc = { ...oidc, subjectClaim: claim };\n}\n\n/** The instance-wide limits, the defaults of every site. */\nexport function defaultLimits(config: RelayConfig): SiteLimits {\n\treturn {\n\t\tmaxMessageBytes: config.maxMessageBytes,\n\t\tmaxConcurrentRequests: config.maxConcurrentRequests,\n\t\trequestTimeoutMs: config.requestTimeoutMs,\n\t\tkeepAliveMs: config.keepAliveMs,\n\t\tidleTimeoutMs: config.idleTimeoutMs,\n\t\tsessionLifetimeMs: config.sessionLifetimeMs,\n\t\theartbeatMs: config.heartbeatMs,\n\t};\n}\n\n/**\n * The site for a page origin, or `undefined` if the relay does not serve it.\n * Configured sites win; `allowedOrigins` origins and, on an open relay, any\n * other origin get the instance-wide defaults.\n */\nexport function siteFor(\n\tconfig: RelayConfig,\n\torigin: string | null,\n): Site | undefined {\n\tconst defaults = defaultLimits(config);\n\tconst configured =\n\t\torigin === null ? undefined : config.sites.find((s) => s.origin === origin);\n\tif (configured !== undefined) {\n\t\tconst site: Site = {\n\t\t\torigin: configured.origin,\n\t\t\tpairing: configured.pairing ?? config.identity,\n\t\t\tlimits: { ...defaults, ...configured.limits },\n\t\t};\n\t\tif (configured.name !== undefined) site.name = configured.name;\n\t\treturn site;\n\t}\n\tif (\n\t\tconfig.allowedOrigins === \"*\" ||\n\t\t(origin !== null && config.allowedOrigins.includes(origin))\n\t) {\n\t\treturn {\n\t\t\torigin: config.allowedOrigins === \"*\" ? \"*\" : (origin ?? \"\"),\n\t\t\tpairing: config.allowedOrigins === \"*\" ? \"code\" : config.identity,\n\t\t\tlimits: defaults,\n\t\t};\n\t}\n\treturn undefined;\n}\n\n/** The largest message limit of any site (Bun's server-wide limits). */\nexport function largestMessageBytes(config: RelayConfig): number {\n\treturn Math.max(\n\t\tconfig.maxMessageBytes,\n\t\t...config.sites.map((s) => s.limits?.maxMessageBytes ?? 0),\n\t);\n}\n\ntype Env = Record<string, string | undefined>;\n\nfunction seconds(env: Env, name: string): number | undefined {\n\tconst raw = env[name];\n\tif (raw === undefined || raw === \"\") return undefined;\n\tconst n = Number(raw);\n\tif (!Number.isFinite(n) || n <= 0) {\n\t\tthrow new ConfigError(`${name} must be a positive number of seconds`);\n\t}\n\treturn Math.round(n * 1000);\n}\n\n/** Like `seconds`, but 0 is allowed (it switches the feature off). */\nfunction secondsOrZero(env: Env, name: string): number | undefined {\n\tconst raw = env[name];\n\tif (raw === undefined || raw === \"\") return undefined;\n\tconst n = Number(raw);\n\tif (!Number.isFinite(n) || n < 0) {\n\t\tthrow new ConfigError(`${name} must be 0 or a positive number of seconds`);\n\t}\n\treturn Math.round(n * 1000);\n}\n\nfunction integer(env: Env, name: string): number | undefined {\n\tconst raw = env[name];\n\tif (raw === undefined || raw === \"\") return undefined;\n\tconst n = Number(raw);\n\tif (!Number.isInteger(n) || n < 0) {\n\t\tthrow new ConfigError(`${name} must be a whole number`);\n\t}\n\treturn n;\n}\n\nfunction oneOf<T extends string>(\n\tenv: Env,\n\tname: string,\n\tvalues: readonly T[],\n): T | undefined {\n\tconst raw = env[name];\n\tif (raw === undefined || raw === \"\") return undefined;\n\tif (!(values as readonly string[]).includes(raw)) {\n\t\tthrow new ConfigError(`${name} must be one of ${values.join(\", \")}`);\n\t}\n\treturn raw as T;\n}\n\n/** Read `TAB_MCP_*` variables (and `NODE_ENV`) into a partial config. */\nexport function configFromEnv(env: Env): Partial<RelayConfig> {\n\tconst out: Partial<RelayConfig> = {};\n\tconst set = <K extends keyof RelayConfig>(\n\t\tkey: K,\n\t\tvalue: RelayConfig[K] | undefined,\n\t) => {\n\t\tif (value !== undefined) out[key] = value;\n\t};\n\n\tset(\"development\", env[\"NODE_ENV\"] === \"development\" ? true : undefined);\n\tconst publicUrl = env[\"TAB_MCP_PUBLIC_URL\"];\n\tif (publicUrl !== undefined && publicUrl !== \"\") out.publicUrl = publicUrl;\n\tset(\"port\", integer(env, \"TAB_MCP_PORT\"));\n\tconst host = env[\"TAB_MCP_HOST\"];\n\tif (host !== undefined && host !== \"\") out.host = host;\n\n\tconst origins = env[\"TAB_MCP_ALLOWED_ORIGINS\"];\n\tif (origins !== undefined) {\n\t\tconst trimmed = origins.trim();\n\t\tout.allowedOrigins =\n\t\t\ttrimmed === \"*\"\n\t\t\t\t? \"*\"\n\t\t\t\t: trimmed\n\t\t\t\t\t\t.split(\",\")\n\t\t\t\t\t\t.map((s) => s.trim())\n\t\t\t\t\t\t.filter((s) => s !== \"\");\n\t}\n\n\tconst sites = env[\"TAB_MCP_SITES\"];\n\tif (sites !== undefined && sites.trim() !== \"\") {\n\t\tlet parsed: unknown;\n\t\ttry {\n\t\t\tparsed = JSON.parse(sites);\n\t\t} catch {\n\t\t\tthrow new ConfigError(\"TAB_MCP_SITES must be a JSON array of sites\");\n\t\t}\n\t\tif (!Array.isArray(parsed)) {\n\t\t\tthrow new ConfigError(\"TAB_MCP_SITES must be a JSON array of sites\");\n\t\t}\n\t\tout.sites = parsed as SiteConfig[];\n\t}\n\tconst hosts = env[\"TAB_MCP_CLIENT_ID_HOSTS\"];\n\tif (hosts !== undefined && hosts.trim() !== \"\") {\n\t\tout.clientIdHosts = hosts\n\t\t\t.split(\",\")\n\t\t\t.map((h) => h.trim())\n\t\t\t.filter((h) => h !== \"\");\n\t}\n\n\tset(\"identity\", oneOf(env, \"TAB_MCP_IDENTITY\", [\"code\", \"oidc\"] as const));\n\tconst oidcVars = {\n\t\tissuer: env[\"TAB_MCP_OIDC_ISSUER\"],\n\t\tclientId: env[\"TAB_MCP_OIDC_CLIENT_ID\"],\n\t\tclientSecret: env[\"TAB_MCP_OIDC_CLIENT_SECRET\"],\n\t\tsubjectClaim: env[\"TAB_MCP_OIDC_SUBJECT_CLAIM\"],\n\t\tassertionIssuer: env[\"TAB_MCP_TAB_ASSERTION_ISSUER\"],\n\t\tassertionJwksUrl: env[\"TAB_MCP_TAB_ASSERTION_JWKS_URL\"],\n\t};\n\tif (Object.values(oidcVars).some((v) => v !== undefined && v !== \"\")) {\n\t\tconst oidc: OidcConfig = {\n\t\t\tissuer: oidcVars.issuer ?? \"\",\n\t\t\tclientId: oidcVars.clientId ?? \"\",\n\t\t\tassertionIssuer: oidcVars.assertionIssuer ?? \"\",\n\t\t\tassertionJwksUrl: oidcVars.assertionJwksUrl ?? \"\",\n\t\t};\n\t\tif (oidcVars.clientSecret !== undefined && oidcVars.clientSecret !== \"\") {\n\t\t\toidc.clientSecret = oidcVars.clientSecret;\n\t\t}\n\t\tif (oidcVars.subjectClaim !== undefined && oidcVars.subjectClaim !== \"\") {\n\t\t\toidc.subjectClaim = oidcVars.subjectClaim as SubjectClaim;\n\t\t}\n\t\tout.oidc = oidc;\n\t}\n\tset(\n\t\t\"trustProxy\",\n\t\toneOf(env, \"TAB_MCP_TRUST_PROXY\", [\n\t\t\t\"none\",\n\t\t\t\"x-real-ip\",\n\t\t\t\"x-forwarded-for\",\n\t\t] as const),\n\t);\n\tconst cors = oneOf(env, \"TAB_MCP_CORS\", [\"on\", \"off\"] as const);\n\tif (cors !== undefined) out.cors = cors === \"on\";\n\tset(\"store\", oneOf(env, \"TAB_MCP_STORE\", [\"sqlite\", \"memory\"] as const));\n\tconst sqlitePath = env[\"TAB_MCP_SQLITE_PATH\"];\n\tif (sqlitePath !== undefined && sqlitePath !== \"\")\n\t\tout.sqlitePath = sqlitePath;\n\n\tset(\"maxSessions\", integer(env, \"TAB_MCP_MAX_SESSIONS\"));\n\tset(\"maxSessionsPerIp\", integer(env, \"TAB_MCP_MAX_SESSIONS_PER_IP\"));\n\tset(\"maxConcurrentRequests\", integer(env, \"TAB_MCP_MAX_CONCURRENT_REQUESTS\"));\n\tset(\"requestTimeoutMs\", seconds(env, \"TAB_MCP_REQUEST_TIMEOUT_S\"));\n\tset(\"keepAliveMs\", seconds(env, \"TAB_MCP_KEEPALIVE_S\"));\n\tset(\"idleTimeoutMs\", seconds(env, \"TAB_MCP_IDLE_TIMEOUT_S\"));\n\tset(\"sessionLifetimeMs\", seconds(env, \"TAB_MCP_SESSION_LIFETIME_S\"));\n\tset(\"heartbeatMs\", seconds(env, \"TAB_MCP_HEARTBEAT_S\"));\n\tset(\"bodyTimeoutMs\", seconds(env, \"TAB_MCP_BODY_TIMEOUT_S\"));\n\tset(\"pageWaitMs\", secondsOrZero(env, \"TAB_MCP_PAGE_WAIT_S\"));\n\tset(\"maxMessageBytes\", integer(env, \"TAB_MCP_MAX_MESSAGE_BYTES\"));\n\tset(\"accessTokenTtlMs\", seconds(env, \"TAB_MCP_ACCESS_TOKEN_TTL_S\"));\n\tset(\"refreshTokenTtlMs\", seconds(env, \"TAB_MCP_REFRESH_TOKEN_TTL_S\"));\n\tset(\"grantLifetimeMs\", seconds(env, \"TAB_MCP_GRANT_LIFETIME_S\"));\n\tset(\n\t\t\"logLevel\",\n\t\toneOf(env, \"TAB_MCP_LOG_LEVEL\", [\n\t\t\t\"error\",\n\t\t\t\"warn\",\n\t\t\t\"info\",\n\t\t\t\"debug\",\n\t\t] as const),\n\t);\n\treturn out;\n}\n",
@@ -10,20 +10,21 @@
10
10
  "import type { LogLevel } from \"./config.ts\";\nimport { parseIpv4, parseIpv6 } from \"./ip.ts\";\n\n/**\n * Structured JSON-line logging (threat model A9). Callers pass only metadata:\n * never request or response bodies, tool names, arguments, results, tokens,\n * pairing codes or page secrets. There is deliberately no helper that accepts\n * a body.\n */\n\nexport type LogFields = Record<string, string | number | boolean | null>;\n\nexport interface Logger {\n\terror(event: string, fields?: LogFields): void;\n\twarn(event: string, fields?: LogFields): void;\n\tinfo(event: string, fields?: LogFields): void;\n\tdebug(event: string, fields?: LogFields): void;\n}\n\nconst ORDER: Record<LogLevel, number> = {\n\terror: 0,\n\twarn: 1,\n\tinfo: 2,\n\tdebug: 3,\n};\n\n/** A logger that writes one JSON object per line to `sink` (stdout by default). */\nexport function createLogger(\n\tlevel: LogLevel,\n\tsink: (line: string) => void = (line) => {\n\t\tprocess.stdout.write(`${line}\\n`);\n\t},\n): Logger {\n\tconst max = ORDER[level];\n\tconst write = (lvl: LogLevel, event: string, fields?: LogFields) => {\n\t\tif (ORDER[lvl] > max) return;\n\t\tsink(\n\t\t\tJSON.stringify({\n\t\t\t\ttime: new Date().toISOString(),\n\t\t\t\tlevel: lvl,\n\t\t\t\tevent,\n\t\t\t\t...fields,\n\t\t\t}),\n\t\t);\n\t};\n\treturn {\n\t\terror: (e, f) => write(\"error\", e, f),\n\t\twarn: (e, f) => write(\"warn\", e, f),\n\t\tinfo: (e, f) => write(\"info\", e, f),\n\t\tdebug: (e, f) => write(\"debug\", e, f),\n\t};\n}\n\n/**\n * Truncate an IP for logs: IPv4 to /24, IPv6 to /48. IPv4-mapped IPv6\n * (`::ffff:a.b.c.d`) is treated as IPv4. `?` if it does not parse.\n */\nexport function truncateIp(ip: string): string {\n\tconst v4 = parseIpv4(ip);\n\tif (v4 !== undefined) return `${v4.slice(0, 3).join(\".\")}.0/24`;\n\tconst v6 = parseIpv6(ip);\n\tif (v6 === undefined) return \"?\";\n\tconst mapped = v6.slice(0, 5).every((g) => g === 0) && v6[5] === 0xffff;\n\tif (mapped) {\n\t\tconst hi = v6[6] ?? 0;\n\t\treturn `${hi >> 8}.${hi & 0xff}.${(v6[7] ?? 0) >> 8}.0/24`;\n\t}\n\treturn `${v6\n\t\t.slice(0, 3)\n\t\t.map((g) => g.toString(16))\n\t\t.join(\":\")}::/48`;\n}\n\n/**\n * An error for a log line: its name only. Messages can carry request data,\n * and a custom store's can hold token hashes or a connection string.\n */\nexport function errorName(error: unknown): string {\n\treturn error instanceof Error ? error.name : typeof error;\n}\n\n/**\n * Defence in depth (DEC-047). The relay catches errors per message and per\n * request; anything that still escapes is logged, never silently fatal:\n * - an unhandled promise rejection is logged and the relay keeps running, so one\n * bad request or tab cannot end every other session;\n * - an uncaught exception is logged and the process exits with 1, because the\n * relay's state may be inconsistent; the supervisor (Docker, systemd) restarts\n * it and AI apps keep their tokens (they live in the store).\n * Only the error's name is logged: messages can carry request data.\n * Returns a function that removes the handlers.\n */\nexport function installCrashLogging(\n\tlogger: Logger,\n\texit: (code: number) => void = (code) => process.exit(code),\n): () => void {\n\tconst onRejection = (error: unknown) => {\n\t\tlogger.error(\"process.unhandled_rejection\", { error: errorName(error) });\n\t};\n\tconst onException = (error: unknown) => {\n\t\tlogger.error(\"process.uncaught_exception\", { error: errorName(error) });\n\t\texit(1);\n\t};\n\tprocess.on(\"unhandledRejection\", onRejection);\n\tprocess.on(\"uncaughtException\", onException);\n\treturn () => {\n\t\tprocess.off(\"unhandledRejection\", onRejection);\n\t\tprocess.off(\"uncaughtException\", onException);\n\t};\n}\n",
11
11
  "/**\n * The tab↔relay protocol, version 1 (`tab-mcp.v1`).\n *\n * One WebSocket per tab session; text frames with one JSON object each. The\n * normative description is `kb/design/protocol.md` (later `docs/protocol.md`).\n */\n\nimport { isAppName, MAX_APP_NAME, type PairingKind } from \"./config.ts\";\nimport { MAX_JWT_BYTES } from \"./jwt.ts\";\n\nexport const SUBPROTOCOL = \"tab-mcp.v1\";\n\n/** The only MCP revision the relay serves (DEC-033). */\nexport const MCP_PROTOCOL_VERSION = \"2026-07-28\";\n\n/** `_meta` key that carries the protocol version in every 2026-07-28 request. */\nexport const PROTOCOL_VERSION_META_KEY =\n\t\"io.modelcontextprotocol/protocolVersion\";\n\nexport const CloseCode = {\n\tnormal: 1000,\n\tpolicyViolation: 1008,\n\ttooLarge: 1009,\n\tsessionExpired: 4001,\n\tidleTimeout: 4002,\n\theartbeatLost: 4003,\n\tshuttingDown: 4004,\n\treplaced: 4005,\n\t/** Reserved in the protocol (`rate_limited`); the relay does not send it yet. */\n\trateLimited: 4008,\n\t/** The address id in the `/tab` URL is not the secret's (DEC-098). */\n\taddressMismatch: 4009,\n} as const;\n\nexport type ByeReason = \"replaced\" | \"expired\" | \"idle\" | \"shutdown\" | \"user\";\n\nexport interface Limits {\n\tmaxMessageBytes: number;\n\tmaxBodyBytes: number;\n\trequestTimeoutMs: number;\n\tidleTimeoutMs: number;\n\theartbeatMs: number;\n\tkeepAliveMs: number;\n\tmaxConcurrentRequests: number;\n}\n\n/** Who is calling, as the tab sees it (passed to the MCP handler as `authInfo`). */\nexport interface GrantRef {\n\tgrantId: string;\n\tclientId: string;\n\tscopes: string[];\n}\n\n/** A connected AI app as listed to the tab. */\nexport interface GrantInfo {\n\tgrantId: string;\n\tclient: { id: string; name: string; host: string };\n\tcreatedAt: string;\n}\n\n// Relay → tab\n\nexport interface SessionMessage {\n\ttype: \"session\";\n\tsessionId: string;\n\taddress: string;\n\torigin: string;\n\t/** The name `/authorize` shows: the site's configured name, else the page's. */\n\tappName?: string;\n\t/** How AI apps pair with this page: `code` or `oidc` (DEC-079). */\n\tpairing: PairingKind;\n\texpiresAt: string;\n\tlimits: Limits;\n\tgrants: GrantInfo[];\n}\nexport interface PingMessage {\n\ttype: \"ping\";\n\tt: number;\n}\nexport interface ByeMessage {\n\ttype: \"bye\";\n\treason: string;\n}\nexport interface HttpRequestMessage {\n\ttype: \"http.request\";\n\tid: string;\n\tmethod: string;\n\tpath: string;\n\theaders: Record<string, string>;\n\tbody: string;\n\tgrant: GrantRef;\n}\nexport interface HttpCancelMessage {\n\ttype: \"http.cancel\";\n\tid: string;\n\treason: \"client_closed\" | \"timeout\" | \"error\";\n}\nexport interface PairingCodeMessage {\n\ttype: \"pairing.code\";\n\tcode: string;\n\texpiresAt: string;\n}\nexport interface GrantAddedMessage {\n\ttype: \"grant.added\";\n\tgrant: GrantInfo;\n}\nexport interface GrantRemovedMessage {\n\ttype: \"grant.removed\";\n\tgrantId: string;\n\treason: \"revoked\" | \"reuse_detected\" | \"expired\";\n}\n/** The page's identity assertion was accepted (DEC-076). */\nexport interface IdentityBoundMessage {\n\ttype: \"identity.bound\";\n\t/** The `round` of the `identity` this answers, echoed when it had one. */\n\tround?: number;\n}\nexport interface ErrorMessage {\n\ttype: \"error\";\n\tcode: ErrorCode;\n\tmessage: string;\n\tid?: string;\n\t/** On `identity_refused`: the `round` of the `identity` it answers, if it had one. */\n\tround?: number;\n}\nexport type RelayMessage =\n\t| SessionMessage\n\t| PingMessage\n\t| ByeMessage\n\t| HttpRequestMessage\n\t| HttpCancelMessage\n\t| PairingCodeMessage\n\t| GrantAddedMessage\n\t| GrantRemovedMessage\n\t| IdentityBoundMessage\n\t| ErrorMessage;\n\nexport type ErrorCode =\n\t| \"bad_message\"\n\t| \"unknown_type\"\n\t| \"unknown_id\"\n\t| \"too_large\"\n\t| \"rate_limited\"\n\t| \"identity_refused\"\n\t| \"address_mismatch\";\n\n// Tab → relay\n\nexport interface HelloMessage {\n\ttype: \"hello\";\n\tlibrary: { name: string; version: string };\n\tpage: { title: string };\n\t/** Self-declared app name (DEC-045), unverified. */\n\tapp?: { name: string };\n\tsecret: string;\n\t/**\n\t * Revoke every grant of the address as the session claims it, before the\n\t * `session` answer (which then lists none): a page taking its address back\n\t * from whoever took it over (DEC-095).\n\t */\n\trevokeAll?: boolean;\n}\nexport interface PongMessage {\n\ttype: \"pong\";\n\tt: number;\n}\nexport interface HttpResponseMessage {\n\ttype: \"http.response\";\n\tid: string;\n\tstatus: number;\n\theaders: Record<string, string>;\n\tbody: string;\n}\nexport interface HttpResponseStartMessage {\n\ttype: \"http.response.start\";\n\tid: string;\n\tstatus: number;\n\theaders: Record<string, string>;\n}\nexport interface HttpResponseChunkMessage {\n\ttype: \"http.response.chunk\";\n\tid: string;\n\tdata: string;\n}\nexport interface HttpResponseEndMessage {\n\ttype: \"http.response.end\";\n\tid: string;\n}\nexport interface TabErrorMessage {\n\ttype: \"error\";\n\tcode: string;\n\tmessage: string;\n\tid?: string;\n}\nexport interface PairingStartMessage {\n\ttype: \"pairing.start\";\n}\nexport interface PairingStopMessage {\n\ttype: \"pairing.stop\";\n}\nexport interface GrantRevokeMessage {\n\ttype: \"grant.revoke\";\n\tgrantId: string;\n}\nexport interface GrantsRevokeAllMessage {\n\ttype: \"grants.revokeAll\";\n}\n/** The web app's signed statement of who the page's user is (DEC-076). */\nexport interface IdentityMessage {\n\ttype: \"identity\";\n\tassertion: string;\n\t/** The page's number for this assertion, echoed in the answer (a lost answer cannot be mistaken for a later one). */\n\tround?: number;\n}\n/** The page's user signed out: end every AI connection (DEC-078). */\nexport interface IdentityLogoutMessage {\n\ttype: \"identity.logout\";\n}\nexport type TabMessage =\n\t| HelloMessage\n\t| PairingStartMessage\n\t| PairingStopMessage\n\t| GrantRevokeMessage\n\t| GrantsRevokeAllMessage\n\t| IdentityMessage\n\t| IdentityLogoutMessage\n\t| PongMessage\n\t| ByeMessage\n\t| HttpResponseMessage\n\t| HttpResponseStartMessage\n\t| HttpResponseChunkMessage\n\t| HttpResponseEndMessage\n\t| TabErrorMessage;\n\n/** Result of parsing one frame from the tab. */\nexport type ParseResult =\n\t| { ok: true; message: TabMessage }\n\t/** A well-formed message of a type this relay does not know. */\n\t| { ok: true; unknown: true; type: string; id?: string }\n\t| { ok: false; error: string; id?: string };\n\nconst MAX_TITLE = 300;\nconst MAX_NAME = 200;\nconst MAX_ID = 128;\nconst MAX_HEADER_COUNT = 32;\nconst MAX_HEADER_VALUE = 8192;\n\n/**\n * RFC 9110 §5.5 field value: visible ASCII, obs-text (0x80-0xFF), space and\n * tab; no other control characters (CR, LF, NUL, DEL, …) and nothing beyond\n * 0xFF, which `Headers` would reject.\n */\nconst FIELD_VALUE = /^[\\t\\x20-\\x7E\\x80-\\xFF]*$/;\n\ntype Json = Record<string, unknown>;\n\nfunction isObject(v: unknown): v is Json {\n\treturn typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\nfunction isString(v: unknown, max: number): v is string {\n\treturn typeof v === \"string\" && v.length <= max;\n}\n\nfunction isId(v: unknown): v is string {\n\treturn typeof v === \"string\" && v.length > 0 && v.length <= MAX_ID;\n}\n\nfunction isStatus(v: unknown): v is number {\n\treturn typeof v === \"number\" && Number.isInteger(v) && v >= 200 && v <= 599;\n}\n\nfunction isHeaders(v: unknown): v is Record<string, string> {\n\tif (!isObject(v)) return false;\n\tconst entries = Object.entries(v);\n\tif (entries.length > MAX_HEADER_COUNT) return false;\n\treturn entries.every(\n\t\t([k, val]) =>\n\t\t\t/^[a-z0-9-]{1,64}$/.test(k) &&\n\t\t\tisString(val, MAX_HEADER_VALUE) &&\n\t\t\tFIELD_VALUE.test(val),\n\t);\n}\n\nfunction idOf(v: Json): string | undefined {\n\treturn isId(v[\"id\"]) ? v[\"id\"] : undefined;\n}\n\n/**\n * Parse and validate one text frame from the tab. Hand-written on purpose: the\n * relay has no schema library (DEC-014).\n */\nexport function parseTabMessage(text: string): ParseResult {\n\tlet v: unknown;\n\ttry {\n\t\tv = JSON.parse(text);\n\t} catch {\n\t\treturn { ok: false, error: \"not JSON\" };\n\t}\n\tif (!isObject(v)) return { ok: false, error: \"not a JSON object\" };\n\tconst type = v[\"type\"];\n\tif (typeof type !== \"string\" || type.length === 0 || type.length > 64) {\n\t\treturn { ok: false, error: \"missing type\" };\n\t}\n\tconst id = idOf(v);\n\tconst bad = (error: string): ParseResult =>\n\t\tid === undefined ? { ok: false, error } : { ok: false, error, id };\n\n\tswitch (type) {\n\t\tcase \"hello\": {\n\t\t\tconst library = v[\"library\"];\n\t\t\tconst page = v[\"page\"];\n\t\t\tif (\n\t\t\t\t!isObject(library) ||\n\t\t\t\t!isString(library[\"name\"], MAX_NAME) ||\n\t\t\t\t!isString(library[\"version\"], MAX_NAME)\n\t\t\t) {\n\t\t\t\treturn bad(\"hello.library must be {name, version}\");\n\t\t\t}\n\t\t\tif (!isObject(page) || !isString(page[\"title\"], MAX_TITLE)) {\n\t\t\t\treturn bad(\"hello.page must be {title}\");\n\t\t\t}\n\t\t\tif (typeof v[\"secret\"] !== \"string\") return bad(\"hello.secret missing\");\n\t\t\tconst app = v[\"app\"];\n\t\t\tif (app !== undefined && (!isObject(app) || !isAppName(app[\"name\"]))) {\n\t\t\t\treturn bad(`hello.app.name must be 1-${MAX_APP_NAME} characters`);\n\t\t\t}\n\t\t\tconst revokeAll = v[\"revokeAll\"];\n\t\t\tif (revokeAll !== undefined && typeof revokeAll !== \"boolean\") {\n\t\t\t\treturn bad(\"hello.revokeAll must be a boolean\");\n\t\t\t}\n\t\t\tconst hello: HelloMessage = {\n\t\t\t\ttype,\n\t\t\t\tlibrary: { name: library[\"name\"], version: library[\"version\"] },\n\t\t\t\tpage: { title: page[\"title\"] },\n\t\t\t\tsecret: v[\"secret\"],\n\t\t\t};\n\t\t\tif (isObject(app) && isAppName(app[\"name\"])) {\n\t\t\t\thello.app = { name: app[\"name\"] };\n\t\t\t}\n\t\t\tif (revokeAll === true) hello.revokeAll = true;\n\t\t\treturn { ok: true, message: hello };\n\t\t}\n\t\tcase \"pong\": {\n\t\t\tconst t = v[\"t\"];\n\t\t\tif (typeof t !== \"number\") return bad(\"pong.t must be a number\");\n\t\t\treturn { ok: true, message: { type, t } };\n\t\t}\n\t\tcase \"bye\": {\n\t\t\tconst reason = v[\"reason\"];\n\t\t\treturn {\n\t\t\t\tok: true,\n\t\t\t\tmessage: {\n\t\t\t\t\ttype,\n\t\t\t\t\treason: isString(reason, MAX_NAME) ? reason : \"\",\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tcase \"http.response\": {\n\t\t\tif (id === undefined) return bad(\"http.response.id missing\");\n\t\t\tconst { status, headers, body } = v;\n\t\t\tif (!isStatus(status)) return bad(\"http.response.status invalid\");\n\t\t\tif (!isHeaders(headers)) return bad(\"http.response.headers invalid\");\n\t\t\tif (typeof body !== \"string\") return bad(\"http.response.body invalid\");\n\t\t\treturn { ok: true, message: { type, id, status, headers, body } };\n\t\t}\n\t\tcase \"http.response.start\": {\n\t\t\tif (id === undefined) return bad(\"http.response.start.id missing\");\n\t\t\tconst { status, headers } = v;\n\t\t\tif (!isStatus(status)) return bad(\"http.response.start.status invalid\");\n\t\t\tif (!isHeaders(headers))\n\t\t\t\treturn bad(\"http.response.start.headers invalid\");\n\t\t\treturn { ok: true, message: { type, id, status, headers } };\n\t\t}\n\t\tcase \"http.response.chunk\": {\n\t\t\tif (id === undefined) return bad(\"http.response.chunk.id missing\");\n\t\t\tconst data = v[\"data\"];\n\t\t\tif (typeof data !== \"string\")\n\t\t\t\treturn bad(\"http.response.chunk.data invalid\");\n\t\t\treturn { ok: true, message: { type, id, data } };\n\t\t}\n\t\tcase \"http.response.end\": {\n\t\t\tif (id === undefined) return bad(\"http.response.end.id missing\");\n\t\t\treturn { ok: true, message: { type, id } };\n\t\t}\n\t\tcase \"pairing.start\":\n\t\tcase \"pairing.stop\":\n\t\tcase \"grants.revokeAll\":\n\t\tcase \"identity.logout\":\n\t\t\treturn { ok: true, message: { type } };\n\t\tcase \"identity\": {\n\t\t\tconst assertion = v[\"assertion\"];\n\t\t\tif (\n\t\t\t\ttypeof assertion !== \"string\" ||\n\t\t\t\tassertion === \"\" ||\n\t\t\t\tassertion.length > MAX_JWT_BYTES\n\t\t\t) {\n\t\t\t\treturn bad(\n\t\t\t\t\t`identity.assertion must be a JWT of at most ${MAX_JWT_BYTES} bytes`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst round = v[\"round\"];\n\t\t\tif (\n\t\t\t\tround !== undefined &&\n\t\t\t\t!(Number.isSafeInteger(round) && (round as number) >= 0)\n\t\t\t) {\n\t\t\t\treturn bad(\"identity.round must be a non-negative integer\");\n\t\t\t}\n\t\t\treturn round === undefined\n\t\t\t\t? { ok: true, message: { type, assertion } }\n\t\t\t\t: { ok: true, message: { type, assertion, round: round as number } };\n\t\t}\n\t\tcase \"grant.revoke\": {\n\t\t\tconst grantId = v[\"grantId\"];\n\t\t\tif (!isId(grantId)) return bad(\"grant.revoke.grantId missing\");\n\t\t\treturn { ok: true, message: { type, grantId } };\n\t\t}\n\t\tcase \"error\": {\n\t\t\tconst code = v[\"code\"];\n\t\t\tconst message = v[\"message\"];\n\t\t\tif (!isString(code, MAX_NAME)) return bad(\"error.code invalid\");\n\t\t\tconst m: TabErrorMessage = {\n\t\t\t\ttype,\n\t\t\t\tcode,\n\t\t\t\tmessage: isString(message, 1000) ? message : \"\",\n\t\t\t};\n\t\t\tif (id !== undefined) m.id = id;\n\t\t\treturn { ok: true, message: m };\n\t\t}\n\t\tdefault:\n\t\t\treturn id === undefined\n\t\t\t\t? { ok: true, unknown: true, type }\n\t\t\t\t: { ok: true, unknown: true, type, id };\n\t}\n}\n",
12
12
  "import type {\n\tHttpResponseMessage,\n\tHttpResponseStartMessage,\n} from \"./protocol.ts\";\n\n/**\n * One tunnelled MCP request: the AI app's HTTP response, built from the tab's\n * `http.response*` messages, with the request timer, SSE keep-alives (DEC-020)\n * and the relay-started event stream (DEC-039).\n */\n\nexport type RpcId = string | number | null;\n\n/** JSON-RPC error codes the relay itself uses (outside the reserved range). */\nexport const RelayErrorCode = {\n\tpageNotOpen: -31001,\n\ttimeout: -31002,\n\ttabGone: -31003,\n\toverloaded: -31004,\n\tsendFailed: -31005,\n\ttooLarge: -31006,\n\tbadResponse: -31007,\n\tstoreUnavailable: -31008,\n\tsignedOut: -31009,\n\trestarting: -31010,\n} as const;\n\nexport type CancelReason = \"client_closed\" | \"timeout\" | \"error\";\n\n/**\n * What to do when the page goes away mid-request (DEC-074): send the request\n * to the page again once it is back (only while nothing was sent to the AI\n * app), answer with this JSON-RPC message at HTTP 200, or fail with this\n * error (no body and no error: 503, `-31003`).\n */\nexport type PageGoneReply =\n\t| { retry: true }\n\t| { retry: false; body?: string }\n\t| {\n\t\t\tretry: false;\n\t\t\terror: {\n\t\t\t\tstatus: number;\n\t\t\t\tcode: number;\n\t\t\t\tmessage: string;\n\t\t\t\theaders: Record<string, string>;\n\t\t\t};\n\t };\n\nexport interface ExchangeOptions {\n\tid: string;\n\t/** JSON-RPC id of the request; `undefined` for a notification. */\n\trpcId: RpcId | undefined;\n\t/** `subscriptions/listen`: exempt from the request timer. */\n\tisListen: boolean;\n\trequestTimeoutMs: number;\n\tkeepAliveMs: number;\n\t/**\n\t * Limit for the response body the tab sends (not for listen streams), and\n\t * the bound for bytes queued towards an AI app that does not read.\n\t */\n\tmaxBodyBytes: number;\n\t/** Extra headers for every response (CORS). */\n\textraHeaders: Record<string, string>;\n\t/** Tell the tab to stop working on this request. */\n\tcancel: (reason: CancelReason) => void;\n\t/** Called once when the exchange is over. */\n\tonDone: (exchange: Exchange) => void;\n\t/**\n\t * Decides the answer when the page goes away mid-request; `waiting` is true\n\t * while nothing was sent to the AI app. Without it: 503, `-31003`.\n\t */\n\tpageGone?: (waiting: boolean) => PageGoneReply;\n}\n\nconst encoder = new TextEncoder();\n\n/** Statuses that must not carry a body (Fetch \"null body status\", 101/103 excluded by the parser). */\nconst NULL_BODY_STATUSES = new Set([204, 205, 304]);\n\n/** Response headers the relay passes on from the tab. */\nconst PASSED_RESPONSE_HEADERS = new Set([\"content-type\", \"cache-control\"]);\n\nfunction isEventStream(headers: Record<string, string>): boolean {\n\treturn (headers[\"content-type\"] ?? \"\")\n\t\t.toLowerCase()\n\t\t.startsWith(\"text/event-stream\");\n}\n\nfunction endsAtBoundary(text: string): boolean {\n\treturn (\n\t\ttext.endsWith(\"\\n\\n\") || text.endsWith(\"\\r\\n\\r\\n\") || text.endsWith(\"\\r\\r\")\n\t);\n}\n\n/** One SSE `message` event carrying `data` (split into `data:` lines). */\nexport function sseEvent(data: string): string {\n\tconst lines = data.split(/\\r\\n|\\r|\\n/);\n\treturn `event: message\\n${lines.map((l) => `data: ${l}`).join(\"\\n\")}\\n\\n`;\n}\n\nexport function rpcErrorBody(\n\trpcId: RpcId | undefined,\n\tcode: number,\n\tmessage: string,\n\tdata?: unknown,\n): string {\n\tconst error: Record<string, unknown> = { code, message };\n\tif (data !== undefined) error[\"data\"] = data;\n\treturn JSON.stringify({ jsonrpc: \"2.0\", id: rpcId ?? null, error });\n}\n\n/**\n * Where an exchange is. While `waiting` nothing was sent to the AI app.\n * `tab_stream`: the tab's `http.response.start` was passed on. The relay may\n * start the event stream itself (`relay_stream`, DEC-039); the tab's response\n * then becomes events: a tab event stream passes through (`relay_passed`), any\n * other streamed body is buffered and sent as one event (`relay_wrapped`).\n */\ntype State =\n\t| \"waiting\"\n\t| \"tab_stream\"\n\t| \"relay_stream\"\n\t| \"relay_passed\"\n\t| \"relay_wrapped\"\n\t| \"done\";\n\n/** States in which the tab sent `http.response.start`. */\nconst TAB_STARTED: ReadonlySet<State> = new Set([\n\t\"tab_stream\",\n\t\"relay_passed\",\n\t\"relay_wrapped\",\n]);\n\nexport class Exchange {\n\treadonly id: string;\n\treadonly isListen: boolean;\n\treadonly response: Promise<Response>;\n\t/** HTTP status sent to the AI app (for logs); 0 while waiting. */\n\tstatus = 0;\n\t/** How the exchange ended (for logs). */\n\toutcome = \"pending\";\n\t/** Why the tab's response was refused, for the tab's `error` message. */\n\tbadResponseReason: string | undefined;\n\n\treadonly #options: ExchangeOptions;\n\t#resolve!: (response: Response) => void;\n\t#state: State = \"waiting\";\n\t/** The buffered body in `relay_wrapped`. */\n\t#wrapped = \"\";\n\t#controller: ReadableStreamDefaultController<Uint8Array> | undefined;\n\t/** The last write to the AI app ended an SSE event (or nothing was sent). */\n\t#atBoundary = true;\n\t/** Response body bytes received from the tab so far. */\n\t#bodyBytes = 0;\n\t#startTimer: Timer | undefined;\n\t#requestTimer: Timer | undefined;\n\t#keepAliveTimer: Timer | undefined;\n\n\tconstructor(options: ExchangeOptions) {\n\t\tthis.#options = options;\n\t\tthis.id = options.id;\n\t\tthis.isListen = options.isListen;\n\t\tthis.response = new Promise((resolve) => {\n\t\t\tthis.#resolve = resolve;\n\t\t});\n\t\tif (options.rpcId !== undefined) {\n\t\t\tthis.#startTimer = setTimeout(\n\t\t\t\t() => this.#startRelayStream(),\n\t\t\t\toptions.keepAliveMs,\n\t\t\t);\n\t\t}\n\t\tif (!options.isListen) {\n\t\t\tthis.#requestTimer = setTimeout(\n\t\t\t\t() => this.#timeout(),\n\t\t\t\toptions.requestTimeoutMs,\n\t\t\t);\n\t\t}\n\t}\n\n\tget done(): boolean {\n\t\treturn this.#state === \"done\";\n\t}\n\n\t/** A complete response from the tab. */\n\tonResponse(msg: HttpResponseMessage): void {\n\t\tif (TAB_STARTED.has(this.#state)) {\n\t\t\tthis.#badResponse(\"http.response after http.response.start\");\n\t\t\treturn;\n\t\t}\n\t\tif (this.#state === \"waiting\") {\n\t\t\tif (!this.#account(msg.body)) return;\n\t\t\tif (NULL_BODY_STATUSES.has(msg.status) && msg.body !== \"\") {\n\t\t\t\tthis.#badResponse(`status ${msg.status} must not have a body`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlet response: Response;\n\t\t\ttry {\n\t\t\t\tresponse = new Response(msg.body === \"\" ? null : msg.body, {\n\t\t\t\t\tstatus: msg.status,\n\t\t\t\t\theaders: this.#headers(msg.headers),\n\t\t\t\t});\n\t\t\t} catch {\n\t\t\t\tthis.#badResponse(\"the response could not be built\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.#respond(response, msg.status);\n\t\t\tthis.#finish(\"ok\");\n\t\t} else if (this.#state === \"relay_stream\") {\n\t\t\tif (!this.#account(msg.body)) return;\n\t\t\tif (msg.body !== \"\") this.#write(sseEvent(msg.body));\n\t\t\tthis.#finish(\"ok\");\n\t\t}\n\t}\n\n\tonStart(msg: HttpResponseStartMessage): void {\n\t\tif (this.#state === \"done\") return;\n\t\tif (TAB_STARTED.has(this.#state)) {\n\t\t\tthis.#badResponse(\"http.response.start sent twice\");\n\t\t\treturn;\n\t\t}\n\t\t// A listen stream has no total limit, so it must be an event stream: any\n\t\t// other body would be buffered or passed on without bound.\n\t\tconst eventStream = isEventStream(msg.headers);\n\t\tif (this.isListen && !eventStream) {\n\t\t\tthis.#badResponse(\"a listen response must be an event stream\");\n\t\t\treturn;\n\t\t}\n\t\tif (this.#state === \"waiting\") {\n\t\t\tif (NULL_BODY_STATUSES.has(msg.status)) {\n\t\t\t\tthis.#badResponse(`status ${msg.status} cannot be streamed`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlet headers: Headers;\n\t\t\ttry {\n\t\t\t\theaders = this.#headers(msg.headers);\n\t\t\t} catch {\n\t\t\t\tthis.#badResponse(\"the response headers are invalid\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.#openStream(msg.status, headers, \"tab_stream\");\n\t\t} else {\n\t\t\tthis.#state = eventStream ? \"relay_passed\" : \"relay_wrapped\";\n\t\t}\n\t}\n\n\tonChunk(data: string): void {\n\t\tif (!this.#streaming) return;\n\t\tif (this.#state === \"relay_stream\") {\n\t\t\tthis.#badResponse(\"http.response.chunk before http.response.start\");\n\t\t\treturn;\n\t\t}\n\t\tif (!this.#account(data)) return;\n\t\tif (this.#state === \"relay_wrapped\") this.#wrapped += data;\n\t\telse this.#write(data);\n\t}\n\n\tonEnd(): void {\n\t\tif (!this.#streaming) return;\n\t\tif (this.#state === \"relay_wrapped\" && this.#wrapped !== \"\")\n\t\t\tthis.#write(sseEvent(this.#wrapped));\n\t\tthis.#finish(\"ok\");\n\t}\n\n\t/** The AI app went away: tell the tab, send nothing more. */\n\tclientClosed(): void {\n\t\tif (this.#state === \"done\") return;\n\t\tif (this.#state === \"waiting\")\n\t\t\tthis.#respond(new Response(null, { status: 503 }), 0);\n\t\tthis.#options.cancel(\"client_closed\");\n\t\tthis.#finish(\"client_closed\", false);\n\t}\n\n\t/**\n\t * The page's session ended. With a retry the exchange ends without an\n\t * answer (its `response` never settles; the relay sends the request again),\n\t * else the AI app gets the `pageGone` answer at HTTP 200 (DEC-074).\n\t */\n\ttabGone(): void {\n\t\tif (this.#state === \"done\") return;\n\t\tconst waiting = this.#state === \"waiting\";\n\t\tconst reply = this.#options.pageGone?.(waiting);\n\t\tif (reply?.retry === true && waiting) {\n\t\t\tclearTimeout(this.#startTimer);\n\t\t\tthis.#finish(\"page_gone_retry\");\n\t\t\treturn;\n\t\t}\n\t\tif (reply !== undefined && \"error\" in reply) {\n\t\t\tconst e = reply.error;\n\t\t\tthis.fail(e.status, e.code, e.message, false, e.headers);\n\t\t\treturn;\n\t\t}\n\t\tconst body = reply?.retry === false ? reply.body : undefined;\n\t\tif (body === undefined) {\n\t\t\tthis.fail(\n\t\t\t\t503,\n\t\t\t\tRelayErrorCode.tabGone,\n\t\t\t\t\"The page closed its connection to the relay.\",\n\t\t\t\tfalse,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tif (waiting) {\n\t\t\tthis.#respond(\n\t\t\t\tnew Response(body, {\n\t\t\t\t\tstatus: 200,\n\t\t\t\t\theaders: this.#headers({ \"content-type\": \"application/json\" }),\n\t\t\t\t}),\n\t\t\t\t200,\n\t\t\t);\n\t\t} else if (this.#atBoundary) {\n\t\t\tthis.#write(sseEvent(body));\n\t\t}\n\t\tthis.#finish(\"page_gone\");\n\t}\n\n\t/**\n\t * End the exchange with an error the AI app can read: an HTTP error while\n\t * nothing was sent, else a JSON-RPC error event if the stream is at an\n\t * event boundary.\n\t */\n\tfail(\n\t\tstatus: number,\n\t\tcode: number,\n\t\tmessage: string,\n\t\tcancelTab: boolean,\n\t\theaders: Record<string, string> = {},\n\t): void {\n\t\tif (this.#state === \"done\") return;\n\t\tif (this.#state === \"waiting\") {\n\t\t\tthis.#respond(\n\t\t\t\tthis.#errorResponse(status, code, message, headers),\n\t\t\t\tstatus,\n\t\t\t);\n\t\t} else if (this.#atBoundary && this.#options.rpcId !== undefined) {\n\t\t\tthis.#write(sseEvent(rpcErrorBody(this.#options.rpcId, code, message)));\n\t\t}\n\t\tif (cancelTab) this.#options.cancel(\"error\");\n\t\tthis.#finish(`error_${code}`);\n\t}\n\n\t/**\n\t * The tab sent a response the relay cannot pass on: 502 to the AI app (or an\n\t * error event), cancel the tab's work. `reason` goes to the tab, not the app.\n\t */\n\t#badResponse(reason: string): void {\n\t\tthis.badResponseReason = reason;\n\t\tthis.fail(\n\t\t\t502,\n\t\t\tRelayErrorCode.badResponse,\n\t\t\t\"The page sent an invalid response.\",\n\t\t\ttrue,\n\t\t);\n\t}\n\n\t/**\n\t * Count response bytes from the tab; past `maxBodyBytes` fail with 502 /\n\t * -31006 and cancel the tab. False when failed. Only a listen request's\n\t * event stream is exempt; a buffered body is always bounded.\n\t */\n\t#account(data: string): boolean {\n\t\tthis.#bodyBytes += Buffer.byteLength(data);\n\t\tconst unbounded =\n\t\t\tthis.isListen &&\n\t\t\t(this.#state === \"tab_stream\" || this.#state === \"relay_passed\");\n\t\tif (unbounded || this.#bodyBytes <= this.#options.maxBodyBytes) {\n\t\t\treturn true;\n\t\t}\n\t\tthis.fail(\n\t\t\t502,\n\t\t\tRelayErrorCode.tooLarge,\n\t\t\t\"The page sent a response that is too large.\",\n\t\t\ttrue,\n\t\t);\n\t\treturn false;\n\t}\n\n\t#timeout(): void {\n\t\tif (this.#state === \"done\") return;\n\t\tthis.fail(\n\t\t\t504,\n\t\t\tRelayErrorCode.timeout,\n\t\t\t\"The page did not answer in time.\",\n\t\t\tfalse,\n\t\t);\n\t\tthis.#options.cancel(\"timeout\");\n\t}\n\n\t#startRelayStream(): void {\n\t\tif (this.#state !== \"waiting\") return;\n\t\tthis.#openStream(\n\t\t\t200,\n\t\t\tthis.#headers({ \"content-type\": \"text/event-stream\" }),\n\t\t\t\"relay_stream\",\n\t\t);\n\t}\n\n\t#openStream(\n\t\tstatus: number,\n\t\theaders: Headers,\n\t\tstate: \"tab_stream\" | \"relay_stream\",\n\t): void {\n\t\t// Bounded queue: if the AI app stops reading, desiredSize goes negative\n\t\t// once maxBodyBytes are queued, and the exchange ends (see #write).\n\t\tconst stream = new ReadableStream<Uint8Array>(\n\t\t\t{\n\t\t\t\tstart: (controller) => {\n\t\t\t\t\tthis.#controller = controller;\n\t\t\t\t},\n\t\t\t\tcancel: () => this.clientClosed(),\n\t\t\t},\n\t\t\tnew ByteLengthQueuingStrategy({\n\t\t\t\thighWaterMark: this.#options.maxBodyBytes,\n\t\t\t}),\n\t\t);\n\t\tif (isEventStream(Object.fromEntries(headers))) {\n\t\t\theaders.set(\"x-accel-buffering\", \"no\");\n\t\t\tif (!headers.has(\"cache-control\"))\n\t\t\t\theaders.set(\"cache-control\", \"no-cache\");\n\t\t}\n\t\tlet response: Response;\n\t\ttry {\n\t\t\tresponse = new Response(stream, { status, headers });\n\t\t} catch {\n\t\t\tthis.#badResponse(\"the response could not be built\");\n\t\t\treturn;\n\t\t}\n\t\tthis.#state = state;\n\t\tthis.#respond(response, status);\n\t\tthis.#scheduleKeepAlive();\n\t}\n\n\t#write(text: string): void {\n\t\tif (!this.#streaming || this.#controller === undefined || text === \"\")\n\t\t\treturn;\n\t\ttry {\n\t\t\tthis.#controller.enqueue(encoder.encode(text));\n\t\t} catch {\n\t\t\tthis.clientClosed();\n\t\t\treturn;\n\t\t}\n\t\tthis.#atBoundary = endsAtBoundary(text);\n\t\tconst room = this.#controller.desiredSize;\n\t\tif (room !== null && room < 0) {\n\t\t\t// The AI app is not reading: stop the tab, drop the stream. No error\n\t\t\t// event, since nothing more would reach the reader anyway.\n\t\t\tthis.#options.cancel(\"error\");\n\t\t\tthis.#finish(\"backpressure\");\n\t\t\treturn;\n\t\t}\n\t\tthis.#scheduleKeepAlive();\n\t}\n\n\t/** The AI app's response is a stream that is still open. */\n\tget #streaming(): boolean {\n\t\treturn this.#state !== \"waiting\" && this.#state !== \"done\";\n\t}\n\n\t/** A keep-alive comment `keepAliveMs` after the last write, at a boundary. */\n\t#scheduleKeepAlive(): void {\n\t\tclearTimeout(this.#keepAliveTimer);\n\t\tif (!this.#streaming) return;\n\t\tif (this.#state === \"relay_wrapped\") {\n\t\t\tthis.#keepAliveTimer = setTimeout(() => {\n\t\t\t\t// While buffering a wrapped body nothing has been forwarded since\n\t\t\t\t// the last boundary, so a comment is safe.\n\t\t\t\tthis.#write(\": keep-alive\\n\\n\");\n\t\t\t}, this.#options.keepAliveMs);\n\t\t\treturn;\n\t\t}\n\t\tthis.#keepAliveTimer = setTimeout(() => {\n\t\t\tif (this.#atBoundary) this.#write(\": keep-alive\\n\\n\");\n\t\t\telse this.#scheduleKeepAlive();\n\t\t}, this.#options.keepAliveMs);\n\t}\n\n\t#headers(fromTab: Record<string, string>): Headers {\n\t\tconst headers = new Headers(this.#options.extraHeaders);\n\t\tfor (const [k, v] of Object.entries(fromTab)) {\n\t\t\tif (PASSED_RESPONSE_HEADERS.has(k)) headers.set(k, v);\n\t\t}\n\t\treturn headers;\n\t}\n\n\t#errorResponse(\n\t\tstatus: number,\n\t\tcode: number,\n\t\tmessage: string,\n\t\textra: Record<string, string>,\n\t): Response {\n\t\tconst headers = this.#headers({ \"content-type\": \"application/json\" });\n\t\tfor (const [k, v] of Object.entries(extra)) headers.set(k, v);\n\t\treturn new Response(rpcErrorBody(this.#options.rpcId, code, message), {\n\t\t\tstatus,\n\t\t\theaders,\n\t\t});\n\t}\n\n\t#respond(response: Response, status: number): void {\n\t\tclearTimeout(this.#startTimer);\n\t\tthis.status = status;\n\t\tthis.#resolve(response);\n\t}\n\n\t#finish(outcome: string, closeStream = true): void {\n\t\tif (this.#state === \"done\") return;\n\t\tconst wasStreaming = this.#streaming;\n\t\tthis.#state = \"done\";\n\t\tthis.outcome = outcome;\n\t\tclearTimeout(this.#startTimer);\n\t\tclearTimeout(this.#requestTimer);\n\t\tclearTimeout(this.#keepAliveTimer);\n\t\tif (wasStreaming && closeStream) {\n\t\t\ttry {\n\t\t\t\tthis.#controller?.close();\n\t\t\t} catch {\n\t\t\t\t// already closed by the client\n\t\t\t}\n\t\t}\n\t\tthis.#options.onDone(this);\n\t}\n}\n",
13
+ "// Generated by scripts/favicon.ts from scripts/favicon.svg; do not edit.\n\n/** The relay's icon: a browser tab with two linked dots. */\nexport const FAVICON_SVG: string =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\"><title>tab-mcp relay</title><rect width=\"64\" height=\"64\" rx=\"14\" fill=\"#1d4ed8\"/><path d=\"M32 22l3.4-7A3.5 3.5 0 0 1 38.6 13h9.8a3.5 3.5 0 0 1 3.2 2l3.4 7z\" fill=\"#fff\" fill-opacity=\".45\"/><path d=\"M9 49V26a5 5 0 0 1 5-5h.5l3.7-7.4A3.5 3.5 0 0 1 21.3 12h9.4a3.5 3.5 0 0 1 3.1 1.6L37.5 21H50a5 5 0 0 1 5 5v23a5 5 0 0 1-5 5H14a5 5 0 0 1-5-5z\" fill=\"#fff\"/><rect x=\"22\" y=\"35.5\" width=\"20\" height=\"5\" fill=\"#1d4ed8\"/><circle cx=\"21\" cy=\"38\" r=\"6\" fill=\"#1d4ed8\"/><circle cx=\"43\" cy=\"38\" r=\"6\" fill=\"#1d4ed8\"/></svg>';\n\n/** favicon.ico: 16, 32 and 48 px. */\nexport const FAVICON_ICO: Uint8Array<ArrayBuffer> = new Uint8Array(\n\tBuffer.from(\n\t\t\"AAABAAMAEBAAAAEAIABoBAAANgAAACAgAAABACAAqBAAAJ4EAAAwMAAAAQAgAKglAABGFQAAKAAAABAAAAAgAAAAAQAgAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAANhOHQfYTh1x2E4d5dhOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3n2E4dd9hOHQnYTh1u2E4d89hNG//XTBr/2Ewa/9hMGv/YTBr/2Ewa/9hMGv/YTBr/2Ewa/9hMGv/XTBr/2E0b/9hOHfXYTh132E4d39hNHP/ea0L/66WM/+2slP/tq5T/7auU/+2rlP/tq5T/7auU/+2rlP/trJT/66aN/99uRv/YTRz/2E4d59hOHf7YTx//8b2r///////////////////////////////////////////////////////yw7P/2VEg/9hOHf/YTh3/2VIi//TMvf///////fbz//vs5////v7/////////////////++3o//318v//////9dHE/9lUJP/YTh3/2E4d/9lSIv/0zL7//PLu/+SGZf/dZjz/7a6X//fZzv/32c7/7rGc/95nPf/kg2D/++/r//XSxf/ZUyT/2E4d/9hOHf/ZUiL/9M7A//bWy//ZUiL/10oX/9lUJf/cYjf/3GI3/9pVJv/XShj/2FAf//XRxP/108f/2VMk/9hOHf/YTh3/2VIi//TMvv/88/D/5Ytr/95qQf/us57/+N7U//je1P/vt6P/32xD/+WHZv/88e3/9dLF/9lTJP/YTh3/2E4d/9lSIv/0y73///////349v/88Ov///////////////////////zw7P/99/X///////XRxP/ZVCT/2E4d/9hOHf/YUCD/8sa2///////////////////////////////////////////////////////zy7z/2VIi/9hOHf/YTh3/2E0c/+J9WP/21cn////+///////////////////////77Ob/+eLa//nj2//44dn/6Jh7/9hNHP/YTh3/2E4d/9hOHf/XTBr/3WY8//nm3//////////////////88/D/7a+Y/+qghv/qoYf/6p2D/95oPv/YTRz/2E4d/9hOHf3YTh3/2E4d/9hNHP/pm3//+unj//rq5P/66eP/7KiQ/+N/W//khmX/5Idl/+F4U//ZUiL/2E4d/9hOHf/YTh3d2E4d/9hOHf/YTh3/2VIi/9xhNv/dZDn/3GI2/9lSIv/YTh3/2FAf/9hQH//YTh3/2E4d/9hOHf/YTh3l2E4daNhOHfHYTh3/2E4d/9hOHf/YTRv/2E0b/9hNG//YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3z2E4dcdhOHQXYTh1o2E4d3dhOHf3YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf7YTh3f2E4dbthOHQcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAACAAAABAAAAAAQAgAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAANhOHQDYTh0A2E4dANhOHTrYTh2l2E4d6thOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d7thOHazYTh1C2E4dAdhOHQDYTh0A2E4dANhOHQTYTh1p2E4d5NhOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHenYTh112E4dB9hOHQDYTh0A2E4dZthOHfbYTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHfrYTh112E4dAdhOHTTYTh3g2E4d/9hOHf/YTh3/2E4d/9hNHP/YTBv/2Ewb/9hMG//YTBv/2Ewb/9hMG//YTBv/2Ewb/9hMG//YTBv/2Ewb/9hMG//YTBv/2Ewb/9hMG//YTBv/2Ewb/9hMG//YTRv/2E4d/9hOHf/YTh3/2E4d/9hOHenYTh1C2E4dmNhOHf/YTh3/2E4d/9hNHP/YTx7/3F8z/95pQP/eaUD/3mlA/95pQP/eaUD/3mlA/95pQP/eaUD/3mlA/95pQP/eaUD/3mlA/95pQP/eaUD/3mlA/95pQP/eaUD/3mlA/9xhNf/YTx//2E0c/9hOHf/YTh3/2E4d/9hOHazYTh3e2E4d/9hOHf/YTh3/2VMj/+qghv/55N3/++/q//vv6v/77+r/++/q//vv6v/77+r/++/q//vv6v/77+r/++/q//vv6v/77+r/++/q//vv6v/77+r/++/q//vv6v/77+v/+ubf/+yokP/aVSb/2E0c/9hOHf/YTh3/2E4d7thOHfnYTh3/2E4d/9dMGv/jf1z//fj2/////////////////////////////////////////////////////////////////////////////////////////////////////////////vz7/+WKav/XSxr/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/10sZ/+qghv//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////7a2W/9hMG//YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/XSxr/66SL///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////usZv/2Ewb/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9dLGv/rpIv///////////////////////zz8P/55d7//PLu/////////////////////////////////////////////PPw//nl3v/88u7//////////////////////+6xm//YTBv/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/10sa/+uki//////////////////zx7j/4XVO/9xeMv/gcUn/8cCu//////////////////////////////////PHuP/gdE7/3F4y/+BxSf/xv67///79////////////7rGb/9hMG//YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/XSxr/66SL////////////+N7U/9xhNf/XSxn/2E0c/9dLGf/bWy7/7rCa//LDs//ywrH/8sKx//LDsv/vtaD/3GE1/9dLGf/YTRz/10sZ/9tbLv/21cn////////////usZv/2Ewb/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9dLGv/rpIv////////////usZz/2Ewb/9hOHf/YTh3/2E4d/9hNHP/YTh3/2E8e/9hPHv/YTx7/2E8e/9hOHf/YTRz/2E4d/9hOHf/YTh3/10sZ/+uljP///////////+6xm//YTBv/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/10sa/+uki////////////+6znv/YTBv/2E4d/9hOHf/YTh3/2E0c/9lQIP/ZUiP/2VIi/9lSIv/ZUiP/2VEh/9hNHP/YTh3/2E4d/9hOHf/XSxn/7KeO////////////7rGb/9hMG//YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/XSxr/66SL////////////+eLa/91mPP/XShj/2Ewb/9dLGf/cYDT/8Luo//TPwf/0zcD/9M3A//TOwf/xwK//3WU7/9dKGP/YTBv/10sZ/9xgM//32s/////////////usZv/2Ewb/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9dLGv/rpIv/////////////////9dDD/+N/W//dZjv/4npW//PJuv/////////////////////////////////10MP/439b/91mO//ie1b/88m6/////////////////+6xm//YTBv/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/10sa/+uki////////////////////////fj2//vt5//99/T////////////////////////////////////////////9+Pb/++3n//339P//////////////////////7rGb/9hMG//YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/XSxr/66SL///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////usZv/2Ewb/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9dLGv/rpIv//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+6wm//YTBv/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/10sZ/+eSdP//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////6p6D/9dLGv/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTRv/3GE2//XTxv////////////////////////////////////////////////////////////////////////////////////////////////////////////nj2//fbkb/2Ewb/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTRz/3GE2/+eSc//21sv///////////////////////////////////////////////////////vs5//0zb//9M2///TNv//0zb//9M2///TNv//yxbX/66aN/91kOf/YTRz/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTRv/10kX/+N/W//99/T////////////////////////////////////////////+/fz/8b6s/+mbf//pnIH/6ZyB/+mcgf/pnIH/6ZyB/+mdgv/liWn/2VMj/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YThz/2VMk//LGtv////////////////////////////////////////////nl3v/ro4n/6Z2C/+qeg//qnoP/6p6D/+qeg//qnoP/6Z2B/95rQv/YTRz/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/XTBr/439b//339f/////////////////////////////////++vn/6p+F/+iWef/qn4T/6p+E/+qfhP/qn4T/6p+E/+qfhP/liGf/2VMk/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d+NhOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/ZUiP/7KiP//nm3//66uT/+urk//rq5P/66uT/+ufg/+6wmv/aVij/3WQ5/+B0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Hf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3y2E4dUNhOHQDYTh0L2E4dr9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4dxdhOHRfYTh1M2E4d8thOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hNHP/XSxn/2Ewb/9hNHP/YTRz/2E0c/9hNHP/YTRz/2E0c/9hNHP/YTRz/2E0c/9hNHP/YTRz/2E0c/9hNHP/YTRz/2E0c/9hNHP/YTRz/2E0c/9hNHP/YTRz/2E0c/9hNHP/YTRz/2E0c/9hNHP/YTRz/2E0b/9dLGf/YTRv/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d+thOHWfYTh2f2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E0b/9xhNv/nlHb/7rCa/++1oP/vtaD/77Wg/++1oP/vtaD/77Wg/++1oP/vtaD/77Wg/++1oP/vtaD/77Wg/++1oP/vtaD/77Wg/++1oP/vtaD/77Wg/++1oP/vtaD/77Wg/++1oP/vtaD/77Wg/++1oP/vtaD/7rGc/+iYfP/eZz3/2E0c/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHbzYTh3Y2E4d/9hOHf/YTh3/2E4d/9hOHf/YTBv/4HFJ//fZz//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////54tr/4nxY/9hMG//YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHfDYTh3z2E4d/9hOHf/YTh3/2E4d/9hNHP/aVif/88q7////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////99nO/9tdMP/YTRz/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3+2E4d/9hOHf/YTh3/2E4d/9hMG//fbkX//PLu/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////vn4/+J8WP/XSxr/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9dLGv/ifVn//vn4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////7+/+aObv/XSxn/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9dLGv/jflr//vr4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////7+/+aPcP/XSxn/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9dLGv/jflr//vr4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////7+/+aPcP/XSxn/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9dLGv/jflr//vr4//////////////////////////////////zy7v/44dn/+ebf//759//////////////////////////////////////////////////////////////////++/r/+ujh//jg2P/87+v///////////////////////////////////7+/+aPcP/XSxn/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9dLGv/jflr//vr4///////////////////////99fP/7a+Y/99wSP/bXC//3GA0/+OBX//0z8H///////////////////////////////////////////////////////bYzf/liWj/3GI3/9tcLv/fbEP/66WM//zw7P////////////////////////7+/+aPcP/XSxn/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9dLGv/jflr//vr4//////////////////759//ol3v/2E4d/9dMGv/YTRz/2E0b/9dLGf/bXTD/88i4////////////////////////////////////////////9tXK/91lOv/XSxn/2E0b/9hNHP/YTBr/2E0b/+WJaP/88/D///////////////////7+/+aPcP/XSxn/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9dLGv/jflr//vr4//////////////////PHuP/ZUyP/2E0c/9hOHf/YTh3/2E4d/9hOHf/YTBr/3mk//+ynjv/sqpL/7KmS/+ypkv/sqZL/7KmS/+ypkv/sqZH/4HJL/9dMGv/YTh3/2E4d/9hOHf/YTh3/2E4d/9hPHv/vtqL///////////////////7+/+aPcP/XSxn/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9dLGv/jflr//vr4/////////////////+eUd//XSxn/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E0c/9dMGv/XTBr/10wa/9dMGv/XTBr/10wa/9dMGv/XTBr/2E0b/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9dLGf/kg2D//vv6//////////////7+/+aPcP/XSxn/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9dLGv/jflr//vr4/////////////vz8/+SFY//XSxn/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9dMGv/hdU7//fb0//////////////7+/+aPcP/XSxn/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9dLGv/jflr//vr4/////////////////+iZfP/XSxn/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E0c/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E0c/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9dLGf/lh2b//vz7//////////////7+/+aPcP/XSxn/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9dLGv/jflr//vr4//////////////////TOwf/aVyj/2E0c/9hOHf/YTh3/2E4d/9hOHf/XSxr/4HJK//C5pv/wvKr/8Lyp//C8qf/wvKn/8Lyp//C8qv/wvKn/4nxY/9dLGv/YTh3/2E4d/9hOHf/YTh3/2E0c/9lRIf/xvq3///////////////////7+/+aPcP/XSxn/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9dLGv/jflr//vr4//////////////////78+//rpYz/2VIj/9dLGf/YTBv/2Ewa/9dLGf/dZTv/9dPG////////////////////////////////////////////+N/W/99vR//XSxn/2Ewa/9hMG//XSxr/2E8f/+iWef/9+Pb///////////////////7+/+aPcP/XSxn/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9dLGv/jflr//vr4///////////////////////++vn/8b+u/+N/W//eZz3/32xE/+eSdP/33NL///////////////////////////////////////////////////////nk3P/pmn7/329H/91mPP/ielX/77ai//329P////////////////////////7+/+aPcP/XSxn/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9dLGv/jflr//vr4//////////////////////////////////759//77ej//PHt///9/f////////////////////////////////////////////////////////////////////7//PLu//vs5//99/X///////////////////////////////////7+/+aPcP/XSxn/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9dLGv/jflr//vr4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////7+/+aPcP/XSxn/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9dLGv/jflr//vr4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////7+/+aPcP/XSxn/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9dLGv/jflr//vr4///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+/+aPcP/XSxn/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9dLGv/heVT//fj2//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////39/+WKaf/XSxn/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hNG//dZTr/+urk/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////PPw/+BySv/YTBr/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTx//7KuU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8Luo/9lTJP/YThz/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTRz/21os/+yrlP/66uT//vn3//////////////////////////////////////////////////////////////////////////////////////////////38//78+//+/Pv//vz7//78+//+/Pv//vz7//78+//+/Pv//vv6//318v/21cn/5oxs/9pYKv/YTRz/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E0c/9hPH//dZDn/44Jf//nk3f/////////////////////////////////////////////////////////////////////////////////99fP/8cGv/++3pP/vuKT/77ik/++4pP/vuKT/77ik/++4pP/vuKT/77ai/+2slf/qoIb/5Ytr/9lUJf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTBv/10oZ/+qfhf/////////////////////////////////////////////////////////////////////////////////21Mj/6Z2C/+mcgf/pnIH/6ZyB/+mcgf/pnIH/6ZyB/+mcgf/pnIH/6ZyB/+mdgv/pnIH/32xD/9hNHP/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E0b/9xiN//54tr///////////////////////////////////////////////////////////////////////318v/tr5n/6Z2B/+qeg//qnoP/6p6D/+qeg//qnoP/6p6D/+qeg//qnoP/6p6D/+qfhP/mjG3/2VQl/9hOHP/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hMG//qoIX///////////////////////////////////////////////////////////////////////bUyP/qnoP/6p6D/+qeg//qnoP/6p6D/+qeg//qnoP/6p6D/+qeg//qnoP/6p6D/+mdgv/fbkb/2E0c/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hNG//cYjf/+eLa////////////////////////////////////////////////////////////++zn/+iVeP/pnYL/6p6D/+qeg//qnoP/6p6D/+qeg//qnoP/6p6D/+qeg//qnoP/6p+F/+aNbv/aVSb/2E4c/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3+2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTBv/6Z2C////////////////////////////////////////////////////////////7a2X/9pWJ//kgmD/6Zl9/+mbgP/pm4D/6ZuA/+mbgP/pm4D/6ZuA/+mbgP/pm3//5pBx/91kOf/YTRz/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3x2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTRz/2lcp/+yokP/44dj/+urk//rq5P/66uT/+urk//rq5P/66uT/+urk//nj2//us57/210w/9hMG//ZUiL/3F8y/91jOP/dZDn/3WQ5/91kOf/dZDn/3WQ5/91kOf/cYjb/2lYo/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3T2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E0c/9hPHv/bXC//3WM4/91jOP/dYzj/3WM4/91jOP/dYzj/3WM4/9teMf/YUB//2E0c/9hOHf/YTh3/2E0c/9hNG//YTRv/2E0b/9hNG//YTRv/2E0b/9hNG//YTRz/2E0c/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHevYTh2W2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTRz/2E0b/9hNG//YTRv/2E0b/9hNG//YTRv/2E0b/9hNHP/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHbPYTh1D2E4d7thOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d99hOHVzYTh0H2E4do9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4dudhOHRDYTh0A2E4dL9hOHd7YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3q2E4dQdhOHQDYTh0A2E4dANhOHVPYTh3r2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHfTYTh1o2E4dANhOHQDYTh0A2E4dANhOHQDYTh1T2E4d3thOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d59hOHWXYTh0D2E4dANhOHQAAAAAA2E4dANhOHQDYTh0A2E4dL9hOHaPYTh3u2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHfLYTh2v2E4dO9hOHQDYTh0A2E4dAAAAAAAAAAAAAAAAANhOHQDYTh0A2E4dANhOHQfYTh1D2E4dlthOHdPYTh3x2E4d/thOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/9hOHf/YTh3/2E4d/thOHfPYTh3Y2E4dn9hOHUzYTh0L2E4dANhOHQDYTh0AAAAAAAAAAADYAAAAABsAALAAAAAABQAAQAAAAAACAADAAAAAAAEAAIAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAQAAwAAAAAADAABgAAAAAAIAALAAAAAADQAA2AAAAAAbAAA=\",\n\t\t\"base64\",\n\t),\n);\n\n/** apple-touch-icon.png: 180 px. */\nexport const APPLE_TOUCH_ICON: Uint8Array<ArrayBuffer> = new Uint8Array(\n\tBuffer.from(\n\t\t\"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\",\n\t\t\"base64\",\n\t),\n);\n",
13
14
  "import { RelayErrorCode, type RpcId } from \"./exchange.ts\";\nimport { MCP_PROTOCOL_VERSION } from \"./protocol.ts\";\n\n/**\n * The relay's answers when the page is not open (DEC-074): HTTP 200 with a\n * JSON-RPC message the AI app's model can act on, instead of an HTTP error\n * status that makes MCP clients re-probe the server's protocol era.\n */\n\n/**\n * Why the page is not there: never came, went away mid-request, or is open\n * but nobody is signed in to it (identity binding, DEC-077). While the relay\n * stops, `restarting` (the request never reached the page) or\n * `restarting_gone` (it was in flight).\n */\nexport type NotOpenPhase =\n\t| \"not_open\"\n\t| \"gone\"\n\t| \"signed_out\"\n\t| \"restarting\"\n\t| \"restarting_gone\";\n\n/** What the relay says about itself in a stand-in `server/discover` result. */\nexport interface RelayInfo {\n\tname: string;\n\tversion: string;\n}\n\n/**\n * Methods the relay sends to the page again after it went away mid-request:\n * read-only and not the era probe (`server/discover` must answer quickly).\n */\nconst RETRYABLE = new Set([\"tools/list\"]);\n\nexport function isRetryable(method: unknown): boolean {\n\treturn typeof method === \"string\" && RETRYABLE.has(method);\n}\n\nfunction pageName(appName: string | undefined): string {\n\treturn appName ?? \"the web page\";\n}\n\n/** The text for \"the page is not open\" (tool results and JSON-RPC errors). */\nexport function notOpenText(appName: string | undefined): string {\n\treturn `The page is not open, or not in front. Ask the user to open ${pageName(appName)} and keep it in front (on a phone, in split screen), then try again.`;\n}\n\n/** The text for a page that is open but not signed in (DEC-077). */\nexport function signedOutText(appName: string | undefined): string {\n\treturn `The page is open, but nobody is signed in to it. Ask the user to sign in to ${pageName(appName)}, then try again.`;\n}\n\n/** The text while the relay stops: the AI app should try again, not send the user. */\nexport function restartingText(): string {\n\treturn \"The relay is restarting. Try again in a few seconds.\";\n}\n\nfunction phaseText(phase: NotOpenPhase, appName: string | undefined): string {\n\tif (phase === \"restarting\" || phase === \"restarting_gone\") {\n\t\treturn restartingText();\n\t}\n\treturn phase === \"signed_out\" ? signedOutText(appName) : notOpenText(appName);\n}\n\n/** The text for a tool call whose page went away while it ran. */\nexport function goneDuringCallText(appName: string | undefined): string {\n\treturn `The page closed while the tool was running, so it may or may not have finished. Ask the user to open ${pageName(appName)} and keep it in front (on a phone, in split screen), then check the result before trying again.`;\n}\n\n/** The text for a tool call that was running when the relay stopped. */\nexport function restartedDuringCallText(): string {\n\treturn \"The relay restarted while the tool was running, so it may or may not have finished. Check the result before trying again in a few seconds.\";\n}\n\n/**\n * The JSON-RPC message the relay answers with (at HTTP 200) when the page is\n * not open, or `undefined` for a notification (that keeps an HTTP error\n * status: the spec requires one for a notification the server cannot accept).\n */\nexport function notOpenAnswer(\n\tbody: Record<string, unknown>,\n\trpcId: RpcId | undefined,\n\tappName: string | undefined,\n\tphase: NotOpenPhase,\n\trelay: RelayInfo,\n): string | undefined {\n\tif (rpcId === undefined) return undefined;\n\tconst id = rpcId;\n\tconst method = body[\"method\"];\n\tif (method === \"tools/call\") {\n\t\tconst text =\n\t\t\tphase === \"gone\"\n\t\t\t\t? goneDuringCallText(appName)\n\t\t\t\t: phase === \"restarting_gone\"\n\t\t\t\t\t? restartedDuringCallText()\n\t\t\t\t\t: phaseText(phase, appName);\n\t\treturn JSON.stringify({\n\t\t\tjsonrpc: \"2.0\",\n\t\t\tid,\n\t\t\tresult: {\n\t\t\t\tresultType: \"complete\",\n\t\t\t\tcontent: [{ type: \"text\", text }],\n\t\t\t\tisError: true,\n\t\t\t},\n\t\t});\n\t}\n\tif (method === \"server/discover\") {\n\t\t// A stand-in for the page's own result: the era probe must succeed (a\n\t\t// non-modern error makes dual-era clients fall back to `initialize`), and\n\t\t// `ttlMs: 0` makes clients ask the page again as soon as they need it.\n\t\treturn JSON.stringify({\n\t\t\tjsonrpc: \"2.0\",\n\t\t\tid,\n\t\t\tresult: {\n\t\t\t\tresultType: \"complete\",\n\t\t\t\tsupportedVersions: [MCP_PROTOCOL_VERSION],\n\t\t\t\tcapabilities: { tools: { listChanged: true } },\n\t\t\t\tinstructions: phaseText(phase, appName),\n\t\t\t\tttlMs: 0,\n\t\t\t\tcacheScope: \"private\",\n\t\t\t\t_meta: {\n\t\t\t\t\t\"io.modelcontextprotocol/serverInfo\": {\n\t\t\t\t\t\tname: relay.name,\n\t\t\t\t\t\tversion: relay.version,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\t}\n\treturn JSON.stringify({\n\t\tjsonrpc: \"2.0\",\n\t\tid,\n\t\terror: {\n\t\t\tcode:\n\t\t\t\tphase === \"gone\"\n\t\t\t\t\t? RelayErrorCode.tabGone\n\t\t\t\t\t: phase === \"restarting\" || phase === \"restarting_gone\"\n\t\t\t\t\t\t? RelayErrorCode.restarting\n\t\t\t\t\t\t: RelayErrorCode.pageNotOpen,\n\t\t\tmessage: phaseText(phase, appName),\n\t\t},\n\t});\n}\n",
14
15
  "/**\n * The relay's OAuth 2.1 authorization server (DEC-006, DEC-015, DEC-031),\n * written without an OAuth library:\n *\n * - RFC 9728 protected-resource metadata per address, RFC 8414 server metadata;\n * - clients only through Client ID Metadata Documents (`cimd.ts`);\n * - `/authorize` with PKCE S256 only, exact redirect URIs (loopback port\n * relaxed), `resource` bound to one address (RFC 8707), `iss` in every\n * response (RFC 9207), and the pairing step of the address's site (DEC-042);\n * - `/token` for the authorization code and rotating refresh tokens (DEC-029);\n * - `/revoke` (RFC 7009).\n */\n\nimport { timingSafeEqual } from \"node:crypto\";\nimport { isAddressId, shortAddress } from \"../address.ts\";\nimport type { PairingKind, RelayConfig, Site } from \"../config.ts\";\nimport type { Logger } from \"../log.ts\";\nimport type { GrantInfo } from \"../protocol.ts\";\nimport { RateLimiter } from \"../ratelimit.ts\";\nimport type { TokenRecord, TokenStore } from \"../store/types.ts\";\nimport { hashToken, issueTokenPair, newId } from \"../tokens.ts\";\nimport {\n\ttype CimdTestMode,\n\ttype ClientMetadata,\n\tClientMetadataError,\n\tClientMetadataFetcher,\n\tredirectUriMatches,\n} from \"./cimd.ts\";\nimport { AUTHORIZE_CSS, escapeHtml, pageHeaders, renderPage } from \"./html.ts\";\nimport { OidcPairing } from \"./oidc.ts\";\nimport {\n\tPAIRING_METHODS,\n\ttype PairingMethod,\n\ttype PairingResult,\n\ttype PairingTarget,\n} from \"./pairing.ts\";\n\n/** The only scope: calling the page's tools. */\nexport const SCOPE = \"tools\";\n\n/** How long a user has to finish the `/authorize` page. */\nconst PENDING_TTL_MS = 10 * 60_000;\n/** Authorization codes are single-use and short-lived (RFC 6749 §4.1.2). */\nconst AUTH_CODE_TTL_MS = 60_000;\nconst MAX_PENDING = 10_000;\n/** Open authorization requests per IP (prefix) and per address (DEC-061). */\nconst MAX_PENDING_PER_IP = 10;\nconst MAX_PENDING_PER_ADDRESS = 20;\n/** One network's share of an address's open requests (DEC-088). */\nconst MAX_PENDING_PER_ADDRESS_IP = 5;\n/** How long a used refresh token is kept to detect its reuse (DEC-091). */\nconst REFRESH_REUSE_WINDOW_MS = 24 * 60 * 60_000;\nconst MAX_CODES = 10_000;\nconst MAX_FORM_BYTES = 8192;\nconst MAX_STATE_LENGTH = 1024;\n\n/** A tab session as the authorization server sees it. */\nexport interface AuthorizeSession extends PairingTarget {\n\treadonly origin: string;\n\treadonly appName: string | undefined;\n\treadonly site: Site;\n}\n\nexport interface AuthorizationHost {\n\treadonly config: RelayConfig;\n\treadonly logger: Logger;\n\treadonly store: TokenStore;\n\tpublicUrl(): string;\n\t/** The connected (ready) tab session of an address. */\n\tsession(addressId: string): AuthorizeSession | undefined;\n\t/** Tell the address's tab, if connected. */\n\tgrantAdded(addressId: string, grant: GrantInfo): void;\n\tgrantRemoved(addressId: string, grantId: string, reason: string): void;\n}\n\n/** Test-only settings; never reachable from configuration. */\nexport interface AuthorizationTestMode {\n\tcimd?: CimdTestMode;\n\tauthCodeTtlMs?: number;\n\t/** Replace the pairing methods (a stub method proves the server needs no codes). */\n\tpairingMethods?: Partial<Record<PairingKind, PairingMethod>>;\n\t/** A smaller cap on open OIDC sign-ins. */\n\toidcMaxFlows?: number;\n}\n\ninterface AuthorizationRequest {\n\tclient: ClientMetadata;\n\tredirectUri: string;\n\tstate: string | undefined;\n\tcodeChallenge: string;\n\taddressId: string;\n\tresource: string;\n\tscopes: string[];\n}\n\ninterface Pending extends AuthorizationRequest {\n\tid: string;\n\texpiresAt: number;\n\t/** The IP (prefix) key that opened it, for the per-IP cap. */\n\tip: string;\n}\n\ninterface IssuedCode extends AuthorizationRequest {\n\texpiresAt: number;\n\tused: boolean;\n\tgrantId?: string;\n\t/** The binding key the grant is made for (identity binding, DEC-077). */\n\tsubject?: string;\n}\n\nclass OAuthError extends Error {\n\treadonly status: number;\n\treadonly code: string;\n\tconstructor(status: number, code: string, description: string) {\n\t\tsuper(description);\n\t\tthis.status = status;\n\t\tthis.code = code;\n\t}\n}\n\nfunction constantTimeEqual(a: string, b: string): boolean {\n\tconst x = Buffer.from(a);\n\tconst y = Buffer.from(b);\n\treturn x.length === y.length && timingSafeEqual(x, y);\n}\n\n/** BASE64URL(SHA256(verifier)) (RFC 7636 §4.6). */\nexport function s256(verifier: string): string {\n\treturn new Bun.CryptoHasher(\"sha256\")\n\t\t.update(verifier)\n\t\t.digest()\n\t\t.toBase64({ alphabet: \"base64url\", omitPadding: true });\n}\n\n/** RFC 7636 §4.1: 43-128 unreserved characters. */\nconst VERIFIER = /^[A-Za-z0-9\\-._~]{43,128}$/;\n\n/** Parameters, refusing duplicates (RFC 6749 §3.1, §3.2). */\nfunction single(\n\tparams: URLSearchParams,\n\tnames: readonly string[],\n): Record<string, string | undefined> | { duplicate: string } {\n\tconst out: Record<string, string | undefined> = {};\n\tfor (const name of names) {\n\t\tconst values = params.getAll(name);\n\t\tif (values.length > 1) return { duplicate: name };\n\t\tconst value = values[0];\n\t\tout[name] = value === undefined || value === \"\" ? undefined : value;\n\t}\n\treturn out;\n}\n\nfunction random(bytes: number): string {\n\treturn crypto\n\t\t.getRandomValues(new Uint8Array(bytes))\n\t\t.toBase64({ alphabet: \"base64url\", omitPadding: true });\n}\n\n/** The origin a redirect URI sends the browser to, for CSP `form-action`. */\nfunction formTarget(redirectUri: string): string {\n\ttry {\n\t\tconst u = new URL(redirectUri);\n\t\treturn u.protocol === \"http:\" || u.protocol === \"https:\"\n\t\t\t? u.origin\n\t\t\t: u.protocol;\n\t} catch {\n\t\treturn \"'none'\";\n\t}\n}\n\nfunction hostOf(url: string): string {\n\ttry {\n\t\tconst u = new URL(url);\n\t\treturn u.host || u.protocol;\n\t} catch {\n\t\treturn url;\n\t}\n}\n\n/** The OAuth endpoints and pages, mounted by the relay. */\nexport class AuthorizationServer {\n\treadonly #host: AuthorizationHost;\n\treadonly #cimd: ClientMetadataFetcher;\n\t/** Insertion order is expiry order (one lifetime for all), so sweeps stop early. */\n\treadonly #pending = new Map<string, Pending>();\n\treadonly #pendingPerIp = new Map<string, number>();\n\treadonly #pendingPerAddress = new Map<string, number>();\n\treadonly #codes = new Map<string, IssuedCode>();\n\treadonly #authCodeTtlMs: number;\n\treadonly #methods: Partial<Record<PairingKind, PairingMethod>>;\n\treadonly #csrfSecret = random(32);\n\t/** `/authorize` page loads per IP. */\n\treadonly #viewsPerIp = new RateLimiter({\n\t\tcapacity: 30,\n\t\trefillPerSecond: 0.5,\n\t});\n\t/** Form posts per IP (every action; locks out only that network). */\n\treadonly #attemptsPerIp = new RateLimiter({\n\t\tcapacity: 20,\n\t\trefillPerSecond: 0.1,\n\t});\n\t/**\n\t * Code guesses (well-formed, against an active code) per address and IP:\n\t * one network cannot use up an address's allowance alone (DEC-061).\n\t */\n\treadonly #guessesPerAddressIp = new RateLimiter({\n\t\tcapacity: 10,\n\t\trefillPerSecond: 1 / 60,\n\t});\n\t/** Code guesses per address from everywhere: the brute-force cap (A1). */\n\treadonly #guessesPerAddress = new RateLimiter({\n\t\tcapacity: 30,\n\t\trefillPerSecond: 1 / 30,\n\t});\n\treadonly #tokenPerIp = new RateLimiter({ capacity: 30, refillPerSecond: 1 });\n\t/** Refreshes per grant: each leaves a row for the reuse window (DEC-091). */\n\treadonly #refreshesPerGrant = new RateLimiter({\n\t\tcapacity: 20,\n\t\trefillPerSecond: 1 / 60,\n\t});\n\n\tconstructor(host: AuthorizationHost, testMode?: AuthorizationTestMode) {\n\t\tthis.#host = host;\n\t\tthis.#authCodeTtlMs = testMode?.authCodeTtlMs ?? AUTH_CODE_TTL_MS;\n\t\tconst oidc = host.config.oidc;\n\t\tthis.#methods = {\n\t\t\t...PAIRING_METHODS,\n\t\t\t...(oidc === undefined\n\t\t\t\t? {}\n\t\t\t\t: {\n\t\t\t\t\t\toidc: new OidcPairing({\n\t\t\t\t\t\t\tconfig: oidc,\n\t\t\t\t\t\t\tpublicUrl: () => host.publicUrl(),\n\t\t\t\t\t\t\tlogger: host.logger,\n\t\t\t\t\t\t\tdevelopment: host.config.development,\n\t\t\t\t\t\t\t...(testMode?.oidcMaxFlows === undefined\n\t\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t\t: { maxFlows: testMode.oidcMaxFlows }),\n\t\t\t\t\t\t}),\n\t\t\t\t\t}),\n\t\t\t...testMode?.pairingMethods,\n\t\t};\n\t\tthis.#cimd = new ClientMetadataFetcher({\n\t\t\tallowedHosts: host.config.clientIdHosts,\n\t\t\tlogger: host.logger,\n\t\t\t...(testMode?.cimd === undefined ? {} : { testMode: testMode.cimd }),\n\t\t});\n\t}\n\n\tget #issuer(): string {\n\t\treturn this.#host.publicUrl();\n\t}\n\n\t#cors(): Record<string, string> {\n\t\treturn this.#host.config.cors ? { \"access-control-allow-origin\": \"*\" } : {};\n\t}\n\n\t#json(\n\t\tstatus: number,\n\t\tvalue: unknown,\n\t\theaders: Record<string, string> = {},\n\t): Response {\n\t\treturn new Response(JSON.stringify(value), {\n\t\t\tstatus,\n\t\t\theaders: {\n\t\t\t\t\"content-type\": \"application/json\",\n\t\t\t\t...this.#cors(),\n\t\t\t\t...headers,\n\t\t\t},\n\t\t});\n\t}\n\n\t/** CORS preflight for the metadata, token and revoke endpoints. */\n\tpreflight(methods: string): Response {\n\t\tif (!this.#host.config.cors) {\n\t\t\treturn new Response(null, { status: 405, headers: { allow: methods } });\n\t\t}\n\t\treturn new Response(null, {\n\t\t\tstatus: 204,\n\t\t\theaders: {\n\t\t\t\t...this.#cors(),\n\t\t\t\t\"access-control-allow-methods\": `${methods}, OPTIONS`,\n\t\t\t\t\"access-control-allow-headers\":\n\t\t\t\t\t\"authorization, content-type, mcp-protocol-version\",\n\t\t\t\t\"access-control-max-age\": \"600\",\n\t\t\t},\n\t\t});\n\t}\n\n\t// RFC 9728 and RFC 8414\n\n\t/** `/.well-known/oauth-protected-resource/a/{id}/mcp`. */\n\tprotectedResource(addressId: string): Response {\n\t\tif (!isAddressId(addressId))\n\t\t\treturn new Response(\"Not found\", { status: 404 });\n\t\treturn this.#json(\n\t\t\t200,\n\t\t\t{\n\t\t\t\tresource: `${this.#issuer}/a/${addressId}/mcp`,\n\t\t\t\tauthorization_servers: [this.#issuer],\n\t\t\t\tscopes_supported: [SCOPE],\n\t\t\t\tbearer_methods_supported: [\"header\"],\n\t\t\t\tresource_name: \"Tools of a web page (tab-mcp)\",\n\t\t\t},\n\t\t\t{ \"cache-control\": \"public, max-age=3600\" },\n\t\t);\n\t}\n\n\t/** `/.well-known/oauth-authorization-server`. */\n\tmetadata(): Response {\n\t\tconst issuer = this.#issuer;\n\t\treturn this.#json(\n\t\t\t200,\n\t\t\t{\n\t\t\t\tissuer,\n\t\t\t\tauthorization_endpoint: `${issuer}/authorize`,\n\t\t\t\ttoken_endpoint: `${issuer}/token`,\n\t\t\t\trevocation_endpoint: `${issuer}/revoke`,\n\t\t\t\tresponse_types_supported: [\"code\"],\n\t\t\t\tresponse_modes_supported: [\"query\"],\n\t\t\t\tgrant_types_supported: [\"authorization_code\", \"refresh_token\"],\n\t\t\t\tcode_challenge_methods_supported: [\"S256\"],\n\t\t\t\ttoken_endpoint_auth_methods_supported: [\"none\"],\n\t\t\t\trevocation_endpoint_auth_methods_supported: [\"none\"],\n\t\t\t\tscopes_supported: [SCOPE],\n\t\t\t\tclient_id_metadata_document_supported: true,\n\t\t\t\tauthorization_response_iss_parameter_supported: true,\n\t\t\t\tservice_documentation: \"https://github.com/ractive/tab-mcp\",\n\t\t\t},\n\t\t\t{ \"cache-control\": \"public, max-age=3600\" },\n\t\t);\n\t}\n\n\tstylesheet(): Response {\n\t\treturn new Response(AUTHORIZE_CSS, {\n\t\t\theaders: {\n\t\t\t\t\"content-type\": \"text/css; charset=utf-8\",\n\t\t\t\t\"cache-control\": \"public, max-age=3600\",\n\t\t\t\t\"x-content-type-options\": \"nosniff\",\n\t\t\t},\n\t\t});\n\t}\n\n\t// /authorize\n\n\t#page(\n\t\tstatus: number,\n\t\ttitle: string,\n\t\tbody: string,\n\t\tformTargets: readonly string[] = [],\n\t\textraHeaders: Record<string, string> = {},\n\t): Response {\n\t\tconst headers = pageHeaders(formTargets);\n\t\tfor (const [k, v] of Object.entries(extraHeaders)) headers.append(k, v);\n\t\treturn new Response(renderPage(title, body), { status, headers });\n\t}\n\n\t/** An error shown on the page: the redirect URI is not trusted (yet). */\n\t#errorPage(status: number, message: string): Response {\n\t\treturn this.#page(\n\t\t\tstatus,\n\t\t\t\"This connection cannot be made\",\n\t\t\t`<h1>This connection cannot be made</h1>\n<p role=\"alert\">${escapeHtml(message)}</p>\n<p>Go back to your AI app and try again. If it keeps happening, the AI app may not work with this relay.</p>`,\n\t\t);\n\t}\n\n\t/** The client's redirect URI with `error` (RFC 6749 §4.1.2.1) and `iss`. */\n\t#errorUrl(\n\t\tredirectUri: string,\n\t\tstate: string | undefined,\n\t\terror: string,\n\t\tdescription: string,\n\t): string {\n\t\tconst url = new URL(redirectUri);\n\t\tconst params: Record<string, string> = {\n\t\t\terror,\n\t\t\terror_description: description,\n\t\t\t...(state === undefined ? {} : { state }),\n\t\t\tiss: this.#issuer,\n\t\t};\n\t\tfor (const [k, v] of Object.entries(params)) url.searchParams.append(k, v);\n\t\treturn url.href;\n\t}\n\n\t/**\n\t * An invalid request from a client: not redirected automatically, so the\n\t * relay is no open redirector for self-published clients (RFC 9700\n\t * §4.11.2). The page names the destination and links to it (DEC-064).\n\t */\n\t#invalidRequestPage(\n\t\tredirectUri: string,\n\t\tstate: string | undefined,\n\t\terror: string,\n\t\tdescription: string,\n\t): Response {\n\t\tconst url = this.#errorUrl(redirectUri, state, error, description);\n\t\tconst host = hostOf(redirectUri);\n\t\treturn this.#page(\n\t\t\t400,\n\t\t\t\"This connection cannot be made\",\n\t\t\t`<h1>This connection cannot be made</h1>\n<p role=\"alert\">The AI app sent a request this relay cannot accept: ${escapeHtml(description)} (${escapeHtml(error)}).</p>\n<p>You can go back to the AI app at ${escapeHtml(host)} to tell it, or close this page.</p>\n<div class=\"actions\"><a class=\"button\" href=\"${escapeHtml(url)}\">Go back to ${escapeHtml(host)}</a></div>`,\n\t\t);\n\t}\n\n\t/** The user's own Cancel: back to the client at once (`access_denied`). */\n\t#redirectError(\n\t\tredirectUri: string,\n\t\tstate: string | undefined,\n\t\terror: string,\n\t\tdescription: string,\n\t): Response {\n\t\treturn new Response(null, {\n\t\t\tstatus: 303,\n\t\t\theaders: {\n\t\t\t\tlocation: this.#errorUrl(redirectUri, state, error, description),\n\t\t\t\t\"cache-control\": \"no-store\",\n\t\t\t\t\"referrer-policy\": \"no-referrer\",\n\t\t\t},\n\t\t});\n\t}\n\n\t#redirect(redirectUri: string, params: Record<string, string>): Response {\n\t\tconst url = new URL(redirectUri);\n\t\tfor (const [k, v] of Object.entries(params)) url.searchParams.append(k, v);\n\t\treturn new Response(null, {\n\t\t\tstatus: 303,\n\t\t\theaders: {\n\t\t\t\tlocation: url.href,\n\t\t\t\t\"cache-control\": \"no-store\",\n\t\t\t\t\"referrer-policy\": \"no-referrer\",\n\t\t\t},\n\t\t});\n\t}\n\n\t/** GET `/authorize`: check the request, then show the pairing page. */\n\tasync authorize(req: Request, ip: string): Promise<Response> {\n\t\tif (!this.#viewsPerIp.take(ip)) {\n\t\t\treturn this.#errorPage(\n\t\t\t\t429,\n\t\t\t\t\"Too many requests from your network. Wait a minute and try again.\",\n\t\t\t);\n\t\t}\n\t\tconst query = new URL(req.url).searchParams;\n\t\tconst p = single(query, [\n\t\t\t\"response_type\",\n\t\t\t\"client_id\",\n\t\t\t\"redirect_uri\",\n\t\t\t\"code_challenge\",\n\t\t\t\"code_challenge_method\",\n\t\t\t\"state\",\n\t\t\t\"resource\",\n\t\t\t\"scope\",\n\t\t]);\n\t\tif (\"duplicate\" in p) {\n\t\t\tif (p.duplicate === \"client_id\" || p.duplicate === \"redirect_uri\") {\n\t\t\t\treturn this.#errorPage(400, `The request names ${p.duplicate} twice.`);\n\t\t\t}\n\t\t}\n\t\tconst clientId = \"duplicate\" in p ? query.get(\"client_id\") : p[\"client_id\"];\n\t\tconst redirectUri =\n\t\t\t\"duplicate\" in p ? query.get(\"redirect_uri\") : p[\"redirect_uri\"];\n\t\tif (clientId === undefined || clientId === null) {\n\t\t\treturn this.#errorPage(400, \"The request has no client_id.\");\n\t\t}\n\t\tlet client: ClientMetadata;\n\t\ttry {\n\t\t\tclient = await this.#cimd.get(clientId);\n\t\t} catch (error) {\n\t\t\tif (error instanceof ClientMetadataError) {\n\t\t\t\tthis.#host.logger.info(\"oauth.client_refused\", {\n\t\t\t\t\treason: error.reason,\n\t\t\t\t\t// Not the text itself: it is anyone's choice.\n\t\t\t\t\thost: URL.canParse(clientId)\n\t\t\t\t\t\t? hostOf(clientId).slice(0, 100)\n\t\t\t\t\t\t: \"(not a URL)\",\n\t\t\t\t});\n\t\t\t\treturn this.#errorPage(400, error.message);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t\tif (redirectUri === undefined || redirectUri === null) {\n\t\t\treturn this.#errorPage(400, \"The request has no redirect_uri.\");\n\t\t}\n\t\tif (!client.redirectUris.some((r) => redirectUriMatches(redirectUri, r))) {\n\t\t\tthis.#host.logger.info(\"oauth.client_refused\", {\n\t\t\t\treason: \"redirect_uri\",\n\t\t\t\thost: client.host,\n\t\t\t});\n\t\t\treturn this.#errorPage(\n\t\t\t\t400,\n\t\t\t\t`${client.name} asked to return to an address it has not registered (${hostOf(redirectUri)}).`,\n\t\t\t);\n\t\t}\n\t\t// From here on errors go back to the (now trusted) redirect URI.\n\t\tconst state = \"duplicate\" in p ? undefined : p[\"state\"];\n\t\tconst fail = (error: string, description: string) =>\n\t\t\tthis.#invalidRequestPage(redirectUri, state, error, description);\n\t\tif (\"duplicate\" in p) {\n\t\t\treturn fail(\"invalid_request\", `${p.duplicate} was sent more than once`);\n\t\t}\n\t\tif (state !== undefined && state.length > MAX_STATE_LENGTH) {\n\t\t\treturn fail(\"invalid_request\", \"state is too long\");\n\t\t}\n\t\tif (p[\"response_type\"] !== \"code\") {\n\t\t\treturn fail(\n\t\t\t\t\"unsupported_response_type\",\n\t\t\t\t\"only response_type=code is supported\",\n\t\t\t);\n\t\t}\n\t\tconst challenge = p[\"code_challenge\"];\n\t\tif (challenge === undefined) {\n\t\t\treturn fail(\"invalid_request\", \"code_challenge is required (PKCE)\");\n\t\t}\n\t\tif (p[\"code_challenge_method\"] !== \"S256\") {\n\t\t\treturn fail(\"invalid_request\", \"code_challenge_method must be S256\");\n\t\t}\n\t\tif (!/^[A-Za-z0-9\\-._~]{43,128}$/.test(challenge)) {\n\t\t\treturn fail(\"invalid_request\", \"code_challenge is malformed\");\n\t\t}\n\t\tconst resource = p[\"resource\"];\n\t\tconst addressId = this.#addressOf(resource);\n\t\tif (resource === undefined || addressId === undefined) {\n\t\t\treturn fail(\n\t\t\t\t\"invalid_target\",\n\t\t\t\t\"resource must be the MCP address of a page on this relay\",\n\t\t\t);\n\t\t}\n\t\tconst scopes = this.#grantedScopes(p[\"scope\"]);\n\t\tif (scopes === undefined) {\n\t\t\treturn fail(\"invalid_scope\", `the only scope is \"${SCOPE}\"`);\n\t\t}\n\n\t\t// No connected tab, or its dialog is closed: nothing to pair with, so\n\t\t// nothing is kept (DEC-061, DEC-088). Pairing needs the dialog open\n\t\t// anyway, so a stranger who knows the address cannot fill its slots.\n\t\tconst session = this.#host.session(addressId);\n\t\tif (session === undefined || !session.pairingOpen) {\n\t\t\treturn this.#offlinePage(\n\t\t\t\tclient,\n\t\t\t\t`/authorize${new URL(req.url).search}`,\n\t\t\t\tthis.#errorUrl(\n\t\t\t\t\tredirectUri,\n\t\t\t\t\tstate,\n\t\t\t\t\t\"access_denied\",\n\t\t\t\t\t\"the user cancelled the connection\",\n\t\t\t\t),\n\t\t\t\tsession !== undefined,\n\t\t\t);\n\t\t}\n\t\tconst method = this.#methods[session.site.pairing];\n\t\tif (method?.prepare !== undefined) {\n\t\t\ttry {\n\t\t\t\tawait method.prepare();\n\t\t\t} catch (error) {\n\t\t\t\tthis.#host.logger.warn(\"oidc.discovery_failed\", {\n\t\t\t\t\tmessage:\n\t\t\t\t\t\terror instanceof Error ? error.message.slice(0, 200) : \"unknown\",\n\t\t\t\t});\n\t\t\t\treturn this.#errorPage(\n\t\t\t\t\t503,\n\t\t\t\t\t\"The sign-in provider of this page cannot be reached right now. Wait a minute and try again.\",\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tthis.#sweepPending();\n\t\tif (\n\t\t\tthis.#pending.size >= MAX_PENDING ||\n\t\t\t(this.#pendingPerIp.get(ip) ?? 0) >= MAX_PENDING_PER_IP\n\t\t) {\n\t\t\treturn this.#errorPage(\n\t\t\t\t429,\n\t\t\t\t\"Too many connection requests are open right now. Wait a few minutes and try again.\",\n\t\t\t);\n\t\t}\n\t\tthis.#makeRoom(addressId, ip);\n\t\tconst pending: Pending = {\n\t\t\tid: random(24),\n\t\t\texpiresAt: Date.now() + PENDING_TTL_MS,\n\t\t\tip,\n\t\t\tclient,\n\t\t\tredirectUri,\n\t\t\tstate,\n\t\t\tcodeChallenge: challenge,\n\t\t\taddressId,\n\t\t\tresource,\n\t\t\tscopes,\n\t\t};\n\t\tthis.#addPending(pending);\n\t\tconst browser = this.#browserId(req);\n\t\treturn this.#pairingPage(\n\t\t\tpending,\n\t\t\tbrowser.id,\n\t\t\tundefined,\n\t\t\t200,\n\t\t\tbrowser.cookie,\n\t\t);\n\t}\n\n\t#addPending(p: Pending): void {\n\t\tthis.#pending.set(p.id, p);\n\t\tthis.#pendingPerIp.set(p.ip, (this.#pendingPerIp.get(p.ip) ?? 0) + 1);\n\t\tthis.#pendingPerAddress.set(\n\t\t\tp.addressId,\n\t\t\t(this.#pendingPerAddress.get(p.addressId) ?? 0) + 1,\n\t\t);\n\t}\n\n\t/**\n\t * An address at its caps evicts instead of refusing (DEC-088): a network\n\t * past its share loses its own oldest request; a full address loses the\n\t * oldest request of the network holding the most, so a flood from a few\n\t * networks does not push out the owner's one request.\n\t */\n\t#makeRoom(addressId: string, ip: string): void {\n\t\tconst count = this.#pendingPerAddress.get(addressId) ?? 0;\n\t\tif (count < MAX_PENDING_PER_ADDRESS_IP) return;\n\t\tconst byIp = new Map<string, Pending[]>();\n\t\tfor (const p of this.#pending.values()) {\n\t\t\tif (p.addressId !== addressId) continue;\n\t\t\tconst list = byIp.get(p.ip);\n\t\t\tif (list === undefined) byIp.set(p.ip, [p]);\n\t\t\telse list.push(p);\n\t\t}\n\t\tconst own = byIp.get(ip) ?? [];\n\t\tif (own.length >= MAX_PENDING_PER_ADDRESS_IP) {\n\t\t\tif (own[0] !== undefined) this.#dropPending(own[0]);\n\t\t\treturn;\n\t\t}\n\t\tif (count < MAX_PENDING_PER_ADDRESS) return;\n\t\t// Networks come in order of their first request: `>=` breaks a tie\n\t\t// toward the one that came last, so an equal flood never evicts the\n\t\t// owner who was there first (review of PR 32).\n\t\tlet most: Pending[] = [];\n\t\tfor (const list of byIp.values()) {\n\t\t\tif (list.length >= most.length) most = list;\n\t\t}\n\t\tif (most[0] !== undefined) this.#dropPending(most[0]);\n\t}\n\n\t#dropPending(p: Pending): void {\n\t\tif (!this.#pending.delete(p.id)) return;\n\t\tconst dec = (map: Map<string, number>, key: string) => {\n\t\t\tconst n = (map.get(key) ?? 1) - 1;\n\t\t\tif (n <= 0) map.delete(key);\n\t\t\telse map.set(key, n);\n\t\t};\n\t\tdec(this.#pendingPerIp, p.ip);\n\t\tdec(this.#pendingPerAddress, p.addressId);\n\t\tfor (const method of Object.values(this.#methods)) method?.forget?.(p.id);\n\t}\n\n\t/**\n\t * The tab is not connected, or (`connected`) its dialog is closed: try\n\t * again by loading the page again.\n\t */\n\t#offlinePage(\n\t\tclient: ClientMetadata,\n\t\tretryUrl: string,\n\t\tcancelUrl: string,\n\t\tconnected = false,\n\t): Response {\n\t\tconst who = `<strong>${escapeHtml(client.name)}</strong> (${escapeHtml(client.host)})`;\n\t\tconst title = connected\n\t\t\t? \"Open “Connect your AI app” first\"\n\t\t\t: \"Open the page first\";\n\t\tconst intro = connected\n\t\t\t? `<p>${who} wants to use the tools of a web page, but that page is not connecting right now.</p>\n<p>In the page, click “Connect your AI app”, then try again here.</p>`\n\t\t\t: `<p>${who} wants to use the tools of a web page, but that page is not open right now.</p>\n<p>Open the page, click “Connect your AI app”, then try again here.</p>`;\n\t\tconst body = `<h1>${title}</h1>\n${intro}\n<div class=\"actions\">\n<a class=\"button primary\" href=\"${escapeHtml(retryUrl)}\">Try again</a>\n<a class=\"button\" href=\"${escapeHtml(cancelUrl)}\">Cancel</a>\n</div>`;\n\t\treturn this.#page(200, title, body);\n\t}\n\n\t/** POST `/authorize`: the pairing form (connect, cancel, try again). */\n\tasync authorizeSubmit(req: Request, ip: string): Promise<Response> {\n\t\t// Only our own form may post here (defence in depth beside the token).\n\t\tconst origin = req.headers.get(\"origin\");\n\t\tconst site = req.headers.get(\"sec-fetch-site\");\n\t\tif (\n\t\t\t(origin !== null && origin !== this.#issuer) ||\n\t\t\t(site !== null && site !== \"same-origin\")\n\t\t) {\n\t\t\treturn this.#errorPage(403, \"This form can only be sent from this page.\");\n\t\t}\n\t\tif (!this.#attemptsPerIp.take(ip)) {\n\t\t\treturn this.#errorPage(\n\t\t\t\t429,\n\t\t\t\t\"Too many attempts from your network. Wait a few minutes, then start again from your AI app.\",\n\t\t\t);\n\t\t}\n\t\tconst type = (req.headers.get(\"content-type\") ?? \"\").split(\";\")[0]?.trim();\n\t\tif (type !== \"application/x-www-form-urlencoded\") {\n\t\t\treturn this.#errorPage(400, \"The form was not sent correctly.\");\n\t\t}\n\t\tconst text = await this.#readForm(req);\n\t\tif (text === undefined) {\n\t\t\treturn this.#errorPage(413, \"The form was too large.\");\n\t\t}\n\t\tconst form = new URLSearchParams(text);\n\t\tconst pending = this.#pending.get(form.get(\"request_id\") ?? \"\");\n\t\tif (pending === undefined || pending.expiresAt <= Date.now()) {\n\t\t\treturn this.#errorPage(\n\t\t\t\t400,\n\t\t\t\t\"This connection request has expired or was already used.\",\n\t\t\t);\n\t\t}\n\t\tconst browser = this.#browserId(req);\n\t\tconst csrf = form.get(\"csrf\") ?? \"\";\n\t\tif (\n\t\t\tbrowser.cookie !== undefined ||\n\t\t\t!Bun.CSRF.verify(csrf, {\n\t\t\t\tsecret: this.#csrfSecret,\n\t\t\t\tsessionId: `${pending.id}.${browser.id}`,\n\t\t\t\tmaxAge: PENDING_TTL_MS,\n\t\t\t})\n\t\t) {\n\t\t\t// A new cookie means the browser did not send ours: not the same visit.\n\t\t\treturn this.#errorPage(\n\t\t\t\t403,\n\t\t\t\t\"The form could not be checked. Your browser may block cookies for this site.\",\n\t\t\t);\n\t\t}\n\n\t\tconst action = form.get(\"action\");\n\t\tif (action === \"cancel\") {\n\t\t\tthis.#dropPending(pending);\n\t\t\tthis.#host.logger.info(\"oauth.cancelled\", {\n\t\t\t\taddress: shortAddress(pending.addressId),\n\t\t\t\tclient: pending.client.host,\n\t\t\t});\n\t\t\treturn this.#redirectError(\n\t\t\t\tpending.redirectUri,\n\t\t\t\tpending.state,\n\t\t\t\t\"access_denied\",\n\t\t\t\t\"the user cancelled the connection\",\n\t\t\t);\n\t\t}\n\t\tif (action !== \"connect\") {\n\t\t\treturn this.#pairingPage(pending, browser.id);\n\t\t}\n\n\t\tconst session = this.#host.session(pending.addressId);\n\t\tif (session === undefined) {\n\t\t\treturn this.#pairingPage(\n\t\t\t\tpending,\n\t\t\t\tbrowser.id,\n\t\t\t\t\"The page is still not open.\",\n\t\t\t);\n\t\t}\n\t\tconst method = this.#methods[session.site.pairing];\n\t\tif (method === undefined) {\n\t\t\treturn this.#errorPage(\n\t\t\t\t500,\n\t\t\t\t\"This page's pairing method is not available.\",\n\t\t\t);\n\t\t}\n\t\t// Only a real guess is charged: the method calls this right before it\n\t\t// compares a well-formed answer (DEC-061).\n\t\tconst admit = () =>\n\t\t\tthis.#guessesPerAddressIp.take(`${pending.addressId}|${ip}`) &&\n\t\t\tthis.#guessesPerAddress.take(pending.addressId);\n\t\tconst result = await method.check(session, form, admit, {\n\t\t\trequestId: pending.id,\n\t\t\tbrowserId: browser.id,\n\t\t\taddressId: pending.addressId,\n\t\t});\n\t\tif (result.ok === \"redirect\") {\n\t\t\tthis.#host.logger.info(\"oauth.pairing_redirect\", {\n\t\t\t\taddress: shortAddress(pending.addressId),\n\t\t\t\tclient: pending.client.host,\n\t\t\t\tmethod: method.kind,\n\t\t\t});\n\t\t\treturn new Response(null, {\n\t\t\t\tstatus: 303,\n\t\t\t\theaders: {\n\t\t\t\t\tlocation: result.location,\n\t\t\t\t\t\"cache-control\": \"no-store\",\n\t\t\t\t\t\"referrer-policy\": \"no-referrer\",\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t\tif (!result.ok) {\n\t\t\tthis.#host.logger.info(\"oauth.pairing_failed\", {\n\t\t\t\taddress: shortAddress(pending.addressId),\n\t\t\t\tclient: pending.client.host,\n\t\t\t\treason: result.reason,\n\t\t\t});\n\t\t\treturn this.#pairingPage(\n\t\t\t\tpending,\n\t\t\t\tbrowser.id,\n\t\t\t\tresult.message,\n\t\t\t\tresult.reason === \"rate_limited\" || result.reason === \"busy\"\n\t\t\t\t\t? 429\n\t\t\t\t\t: 400,\n\t\t\t);\n\t\t}\n\n\t\treturn this.#paired(pending, method.kind, result);\n\t}\n\n\t/** Pairing succeeded: issue the authorization code and send the browser back. */\n\t#paired(\n\t\tpending: Pending,\n\t\tkind: PairingKind,\n\t\tresult: Extract<PairingResult, { ok: true }>,\n\t): Response {\n\t\tthis.#dropPending(pending);\n\t\t// The address id first, so a load balancer that reads the `/token` body\n\t\t// can route the exchange to this instance, which holds the code (DEC-098).\n\t\tconst code = `${pending.addressId}.${random(32)}`;\n\t\tif (this.#codes.size >= MAX_CODES) this.#sweepCodes(true);\n\t\tconst { id: _id, expiresAt: _expires, ip: _ip, ...request } = pending;\n\t\tthis.#codes.set(hashToken(code), {\n\t\t\t...request,\n\t\t\texpiresAt: Date.now() + this.#authCodeTtlMs,\n\t\t\tused: false,\n\t\t\t...(result.subject === undefined ? {} : { subject: result.subject }),\n\t\t});\n\t\tthis.#host.logger.info(\"oauth.paired\", {\n\t\t\taddress: shortAddress(pending.addressId),\n\t\t\tclient: pending.client.host,\n\t\t\tmethod: kind,\n\t\t});\n\t\treturn this.#redirect(pending.redirectUri, {\n\t\t\tcode,\n\t\t\t...(pending.state === undefined ? {} : { state: pending.state }),\n\t\t\tiss: this.#issuer,\n\t\t});\n\t}\n\n\t/** GET `/authorize/callback`: the provider sends the browser back (DEC-079). */\n\tasync authorizeCallback(req: Request, ip: string): Promise<Response> {\n\t\tif (!this.#viewsPerIp.take(ip)) {\n\t\t\treturn this.#errorPage(\n\t\t\t\t429,\n\t\t\t\t\"Too many requests from your network. Wait a minute and try again.\",\n\t\t\t);\n\t\t}\n\t\tconst method = this.#methods.oidc;\n\t\tif (method?.callback === undefined) {\n\t\t\treturn new Response(\"Not found\", { status: 404 });\n\t\t}\n\t\tconst browser = this.#browserId(req);\n\t\tif (browser.cookie !== undefined) {\n\t\t\t// No visit cookie: not the browser that started the sign-in.\n\t\t\treturn this.#errorPage(\n\t\t\t\t403,\n\t\t\t\t\"The sign-in could not be checked. Your browser may block cookies for this site; start again from your AI app.\",\n\t\t\t);\n\t\t}\n\t\tthis.#sweepPending();\n\t\tconst params = new URL(req.url).searchParams;\n\t\tconst { requestId, result } = await method.callback(\n\t\t\tparams,\n\t\t\tbrowser.id,\n\t\t\t(id) => {\n\t\t\t\tconst p = this.#pending.get(id);\n\t\t\t\treturn p === undefined ? undefined : this.#host.session(p.addressId);\n\t\t\t},\n\t\t);\n\t\tconst pending =\n\t\t\trequestId === undefined ? undefined : this.#pending.get(requestId);\n\t\tif (pending === undefined || pending.expiresAt <= Date.now()) {\n\t\t\tconst message =\n\t\t\t\tresult.ok === false\n\t\t\t\t\t? result.message\n\t\t\t\t\t: \"This connection request has expired or was already used.\";\n\t\t\treturn this.#errorPage(400, message);\n\t\t}\n\t\tif (result.ok === true) return this.#paired(pending, method.kind, result);\n\t\tconst message =\n\t\t\tresult.ok === false ? result.message : \"Something went wrong.\";\n\t\tconst reason = result.ok === false ? result.reason : \"unexpected\";\n\t\tthis.#host.logger.info(\"oauth.pairing_failed\", {\n\t\t\taddress: shortAddress(pending.addressId),\n\t\t\tclient: pending.client.host,\n\t\t\treason,\n\t\t});\n\t\treturn this.#pairingPage(\n\t\t\tpending,\n\t\t\tbrowser.id,\n\t\t\tmessage,\n\t\t\treason === \"mismatch\" ? 403 : 400,\n\t\t);\n\t}\n\n\t#addressOf(resource: string | undefined): string | undefined {\n\t\tif (resource === undefined) return undefined;\n\t\tconst prefix = `${this.#issuer}/a/`;\n\t\tif (!resource.startsWith(prefix) || !resource.endsWith(\"/mcp\")) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst id = resource.slice(prefix.length, -\"/mcp\".length);\n\t\treturn isAddressId(id) ? id : undefined;\n\t}\n\n\t/** Requested scopes reduced to what exists; `undefined` = none of them. */\n\t#grantedScopes(scope: string | undefined): string[] | undefined {\n\t\tif (scope === undefined) return [SCOPE];\n\t\tconst requested = scope.split(\" \").filter((s) => s !== \"\");\n\t\tif (requested.length === 0) return [SCOPE];\n\t\treturn requested.includes(SCOPE) ? [SCOPE] : undefined;\n\t}\n\n\t/** The browser's visit id from our cookie, or a new one with its cookie. */\n\t#browserId(req: Request): { id: string; cookie?: string } {\n\t\tconst name = this.#cookieName();\n\t\tconst header = req.headers.get(\"cookie\") ?? \"\";\n\t\tfor (const part of header.split(\";\")) {\n\t\t\tconst [k, v] = part.trim().split(\"=\");\n\t\t\tif (k === name && v !== undefined && /^[A-Za-z0-9_-]{22}$/.test(v)) {\n\t\t\t\treturn { id: v };\n\t\t\t}\n\t\t}\n\t\tconst id = random(16);\n\t\tconst secure = this.#issuer.startsWith(\"https:\") ? \"; Secure\" : \"\";\n\t\treturn {\n\t\t\tid,\n\t\t\tcookie: `${name}=${id}; Path=/; HttpOnly; SameSite=Lax; Max-Age=${PENDING_TTL_MS / 1000}${secure}`,\n\t\t};\n\t}\n\n\t#cookieName(): string {\n\t\treturn this.#issuer.startsWith(\"https:\")\n\t\t\t? \"__Host-tab-mcp-authorize\"\n\t\t\t: \"tab-mcp-authorize\";\n\t}\n\n\tasync #readForm(req: Request): Promise<string | undefined> {\n\t\tconst length = Number(req.headers.get(\"content-length\") ?? \"0\");\n\t\tif (length > MAX_FORM_BYTES) return undefined;\n\t\tconst bytes = await req.arrayBuffer().catch(() => new ArrayBuffer(0));\n\t\tif (bytes.byteLength > MAX_FORM_BYTES) return undefined;\n\t\treturn new TextDecoder().decode(bytes);\n\t}\n\n\t#pairingPage(\n\t\tpending: Pending,\n\t\tbrowserId: string,\n\t\terror?: string,\n\t\tstatus = 200,\n\t\tcookie?: string,\n\t): Response {\n\t\tconst csrf = Bun.CSRF.generate(this.#csrfSecret, {\n\t\t\tsessionId: `${pending.id}.${browserId}`,\n\t\t\texpiresIn: PENDING_TTL_MS,\n\t\t});\n\t\tconst client = pending.client;\n\t\tconst clientLabel = `<strong>${escapeHtml(client.name)}</strong> (${escapeHtml(client.host)})`;\n\t\tconst hidden = `<input type=\"hidden\" name=\"request_id\" value=\"${escapeHtml(pending.id)}\">\n<input type=\"hidden\" name=\"csrf\" value=\"${escapeHtml(csrf)}\">`;\n\t\tconst errorHtml =\n\t\t\terror === undefined\n\t\t\t\t? \"\"\n\t\t\t\t: `<p class=\"error\" role=\"alert\" id=\"error\">${escapeHtml(error)}</p>`;\n\t\tconst extra = cookie === undefined ? {} : { \"set-cookie\": cookie };\n\t\tconst targets: string[] = [formTarget(pending.redirectUri)];\n\t\tconst cancel = `<button type=\"submit\" class=\"secondary\" name=\"action\" value=\"cancel\" formnovalidate>Cancel</button>`;\n\n\t\tconst session = this.#host.session(pending.addressId);\n\t\tif (session === undefined) {\n\t\t\t// The tab went away after the page was opened: keep the request,\n\t\t\t// so Try again (a post) can continue once the tab is back.\n\t\t\tconst body = `<h1>Open the page first</h1>\n${errorHtml}\n<p>${clientLabel} wants to use the tools of a web page, but that page is not open right now.</p>\n<p>Open the page, click “Connect your AI app”, then try again here.</p>\n<form method=\"post\" action=\"/authorize?a=${pending.addressId}\">\n${hidden}\n<div class=\"actions\">\n<button type=\"submit\" class=\"primary\" name=\"action\" value=\"retry\">Try again</button>\n${cancel}\n</div>\n</form>`;\n\t\t\treturn this.#page(status, \"Open the page first\", body, targets, extra);\n\t\t}\n\n\t\tconst method = this.#methods[session.site.pairing];\n\t\tif (method === undefined) {\n\t\t\treturn this.#errorPage(\n\t\t\t\t500,\n\t\t\t\t\"This page's pairing method is not available.\",\n\t\t\t);\n\t\t}\n\t\ttargets.push(...(method.formTargets?.() ?? []));\n\t\t// A browser always sends an Origin; only a non-browser tab on an open\n\t\t// relay has none.\n\t\tconst page =\n\t\t\tsession.origin === \"\"\n\t\t\t\t? \"a page that did not say where it runs\"\n\t\t\t\t: `<span class=\"origin\">${escapeHtml(session.origin)}</span>`;\n\t\tconst target =\n\t\t\tsession.appName === undefined\n\t\t\t\t? `tools from ${page}`\n\t\t\t\t: `<strong>${escapeHtml(session.appName)}</strong> on ${page}`;\n\t\t// The verified host is part of the heading and title, so a\n\t\t// self-declared name never stands alone (DEC-065).\n\t\tconst heading = `Connect ${client.name} from ${client.host}`;\n\t\tconst body = `<h1>${escapeHtml(heading)}</h1>\n<p>You're connecting ${clientLabel} to ${target}.</p>\n<p>${escapeHtml(client.name)} can then use this page's tools while the page is open. You can disconnect it in the page at any time.</p>\n${errorHtml}\n<form method=\"post\" action=\"/authorize?a=${pending.addressId}\">\n${hidden}\n${method.render(session)}\n<div class=\"actions\">\n<button type=\"submit\" class=\"primary\" name=\"action\" value=\"connect\">Connect</button>\n${cancel}\n</div>\n</form>\n<p class=\"help\">After you connect, your browser goes back to ${escapeHtml(hostOf(pending.redirectUri))}. Only connect AI apps you started yourself.</p>`;\n\t\treturn this.#page(status, heading, body, targets, extra);\n\t}\n\n\t// /token\n\n\t/** POST `/token`. */\n\tasync token(req: Request, ip: string): Promise<Response> {\n\t\tconst noStore = { \"cache-control\": \"no-store\", pragma: \"no-cache\" };\n\t\ttry {\n\t\t\tif (!this.#tokenPerIp.take(ip)) {\n\t\t\t\tthrow new OAuthError(\n\t\t\t\t\t429,\n\t\t\t\t\t\"temporarily_unavailable\",\n\t\t\t\t\t\"too many requests; try again shortly\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst params = await this.#formParams(req);\n\t\t\tconst p = single(params, [\n\t\t\t\t\"grant_type\",\n\t\t\t\t\"client_id\",\n\t\t\t\t\"code\",\n\t\t\t\t\"redirect_uri\",\n\t\t\t\t\"code_verifier\",\n\t\t\t\t\"refresh_token\",\n\t\t\t\t\"resource\",\n\t\t\t\t\"scope\",\n\t\t\t]);\n\t\t\tif (\"duplicate\" in p) {\n\t\t\t\tthrow new OAuthError(\n\t\t\t\t\t400,\n\t\t\t\t\t\"invalid_request\",\n\t\t\t\t\t`${p.duplicate} was sent more than once`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst clientId = p[\"client_id\"];\n\t\t\tif (clientId === undefined) {\n\t\t\t\tthrow new OAuthError(400, \"invalid_request\", \"client_id is required\");\n\t\t\t}\n\t\t\tlet body: Record<string, unknown>;\n\t\t\tif (p[\"grant_type\"] === \"authorization_code\") {\n\t\t\t\tbody = await this.#codeGrant(p, clientId);\n\t\t\t} else if (p[\"grant_type\"] === \"refresh_token\") {\n\t\t\t\tbody = await this.#refreshGrant(p, clientId);\n\t\t\t} else if (p[\"grant_type\"] === undefined) {\n\t\t\t\tthrow new OAuthError(400, \"invalid_request\", \"grant_type is required\");\n\t\t\t} else {\n\t\t\t\tthrow new OAuthError(\n\t\t\t\t\t400,\n\t\t\t\t\t\"unsupported_grant_type\",\n\t\t\t\t\t\"only authorization_code and refresh_token are supported\",\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn this.#json(200, body, noStore);\n\t\t} catch (error) {\n\t\t\treturn this.#oauthErrorResponse(error, noStore);\n\t\t}\n\t}\n\n\t#oauthErrorResponse(\n\t\terror: unknown,\n\t\theaders: Record<string, string>,\n\t): Response {\n\t\tif (error instanceof OAuthError) {\n\t\t\tconst extra: Record<string, string> = { ...headers };\n\t\t\tif (error.status === 401)\n\t\t\t\textra[\"www-authenticate\"] = 'Basic realm=\"tab-mcp\"';\n\t\t\tif (error.status === 429 || error.status === 503)\n\t\t\t\textra[\"retry-after\"] = \"10\";\n\t\t\treturn this.#json(\n\t\t\t\terror.status,\n\t\t\t\t{ error: error.code, error_description: error.message },\n\t\t\t\textra,\n\t\t\t);\n\t\t}\n\t\tthis.#host.logger.error(\"oauth.error\", {\n\t\t\tmessage: error instanceof Error ? error.name : \"unknown\",\n\t\t});\n\t\treturn this.#json(\n\t\t\t503,\n\t\t\t{\n\t\t\t\terror: \"temporarily_unavailable\",\n\t\t\t\terror_description: \"the relay cannot issue tokens right now\",\n\t\t\t},\n\t\t\t{ ...headers, \"retry-after\": \"10\" },\n\t\t);\n\t}\n\n\t/** Form parameters of a token or revocation request (client auth `none` only). */\n\tasync #formParams(req: Request): Promise<URLSearchParams> {\n\t\tconst type = (req.headers.get(\"content-type\") ?? \"\").split(\";\")[0]?.trim();\n\t\tif (type !== \"application/x-www-form-urlencoded\") {\n\t\t\tthrow new OAuthError(\n\t\t\t\t400,\n\t\t\t\t\"invalid_request\",\n\t\t\t\t\"the body must be application/x-www-form-urlencoded\",\n\t\t\t);\n\t\t}\n\t\tif (req.headers.get(\"authorization\") !== null) {\n\t\t\t// RFC 6749 §5.2: a client that tried to authenticate gets 401.\n\t\t\tthrow new OAuthError(\n\t\t\t\t401,\n\t\t\t\t\"invalid_client\",\n\t\t\t\t\"client authentication is not supported (token_endpoint_auth_method none)\",\n\t\t\t);\n\t\t}\n\t\tconst text = await this.#readForm(req);\n\t\tif (text === undefined) {\n\t\t\tthrow new OAuthError(413, \"invalid_request\", \"the request is too large\");\n\t\t}\n\t\tconst params = new URLSearchParams(text);\n\t\tif (params.has(\"client_secret\") || params.has(\"client_assertion\")) {\n\t\t\tthrow new OAuthError(\n\t\t\t\t400,\n\t\t\t\t\"invalid_client\",\n\t\t\t\t\"client authentication is not supported (token_endpoint_auth_method none)\",\n\t\t\t);\n\t\t}\n\t\treturn params;\n\t}\n\n\tasync #codeGrant(\n\t\tp: Record<string, string | undefined>,\n\t\tclientId: string,\n\t): Promise<Record<string, unknown>> {\n\t\tconst code = p[\"code\"];\n\t\tconst redirectUri = p[\"redirect_uri\"];\n\t\tconst verifier = p[\"code_verifier\"];\n\t\tif (\n\t\t\tcode === undefined ||\n\t\t\tredirectUri === undefined ||\n\t\t\tverifier === undefined\n\t\t) {\n\t\t\tthrow new OAuthError(\n\t\t\t\t400,\n\t\t\t\t\"invalid_request\",\n\t\t\t\t\"code, redirect_uri and code_verifier are required\",\n\t\t\t);\n\t\t}\n\t\tconst key = hashToken(code);\n\t\tconst issued = this.#codes.get(key);\n\t\tconst invalid = (why: string) => new OAuthError(400, \"invalid_grant\", why);\n\t\tif (issued === undefined) throw invalid(\"the code is not valid\");\n\t\tif (issued.used) {\n\t\t\t// RFC 6749 §4.1.2: a code used twice revokes what it produced.\n\t\t\tif (issued.grantId !== undefined) {\n\t\t\t\tawait this.#revokeGrant(\n\t\t\t\t\tissued.addressId,\n\t\t\t\t\tissued.grantId,\n\t\t\t\t\t\"reuse_detected\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow invalid(\"the code was already used\");\n\t\t}\n\t\tissued.used = true; // a failed check below burns the code too\n\t\tif (issued.expiresAt <= Date.now()) throw invalid(\"the code has expired\");\n\t\tif (!constantTimeEqual(clientId, issued.client.clientId)) {\n\t\t\tthrow invalid(\"the code was issued to another client\");\n\t\t}\n\t\tif (redirectUri !== issued.redirectUri) {\n\t\t\tthrow invalid(\"redirect_uri does not match the authorization request\");\n\t\t}\n\t\tif (p[\"resource\"] !== undefined && p[\"resource\"] !== issued.resource) {\n\t\t\tthrow new OAuthError(\n\t\t\t\t400,\n\t\t\t\t\"invalid_target\",\n\t\t\t\t\"resource does not match the authorization request\",\n\t\t\t);\n\t\t}\n\t\tif (\n\t\t\t!VERIFIER.test(verifier) ||\n\t\t\t!constantTimeEqual(s256(verifier), issued.codeChallenge)\n\t\t) {\n\t\t\tthrow invalid(\"code_verifier does not match the code_challenge\");\n\t\t}\n\t\t// Identity binding: the person paired must still be the page's user, so\n\t\t// a code issued before a sign-out or a change of user buys nothing.\n\t\tif (\n\t\t\tissued.subject !== undefined &&\n\t\t\tthis.#host.session(issued.addressId)?.identity !== issued.subject\n\t\t) {\n\t\t\tthrow invalid(\"the page's user signed out or changed\");\n\t\t}\n\n\t\tconst now = Date.now();\n\t\tconst grantId = newId(\"g\");\n\t\tissued.grantId = grantId;\n\t\tconst config = this.#host.config;\n\t\tconst tokens = await issueTokenPair(\n\t\t\tthis.#host.store,\n\t\t\t{\n\t\t\t\tgrantId,\n\t\t\t\taddressId: issued.addressId,\n\t\t\t\tclientId: issued.client.clientId,\n\t\t\t\tclientName: issued.client.name,\n\t\t\t\tscopes: issued.scopes,\n\t\t\t\tgrantCreatedAt: now,\n\t\t\t\t...(issued.subject === undefined ? {} : { subject: issued.subject }),\n\t\t\t},\n\t\t\t{\n\t\t\t\taccessTtlMs: config.accessTokenTtlMs,\n\t\t\t\trefreshTtlMs: config.refreshTokenTtlMs,\n\t\t\t\tgrantEndsAt: now + config.grantLifetimeMs,\n\t\t\t\tnow,\n\t\t\t},\n\t\t);\n\t\tif (tokens === undefined) {\n\t\t\t// Revoked while the tokens were issued (code reuse, New address).\n\t\t\tthrow invalid(\"the connection was revoked\");\n\t\t}\n\t\tthis.#host.logger.info(\"oauth.grant_created\", {\n\t\t\taddress: shortAddress(issued.addressId),\n\t\t\tclient: issued.client.host,\n\t\t});\n\t\tthis.#host.grantAdded(issued.addressId, {\n\t\t\tgrantId,\n\t\t\tclient: {\n\t\t\t\tid: issued.client.clientId,\n\t\t\t\tname: issued.client.name,\n\t\t\t\thost: issued.client.host,\n\t\t\t},\n\t\t\tcreatedAt: new Date(now).toISOString(),\n\t\t});\n\t\treturn this.#tokenBody(tokens, issued.scopes);\n\t}\n\n\t#tokenBody(\n\t\ttokens: { accessToken: string; refreshToken: string; expiresIn: number },\n\t\tscopes: string[],\n\t): Record<string, unknown> {\n\t\treturn {\n\t\t\taccess_token: tokens.accessToken,\n\t\t\ttoken_type: \"Bearer\",\n\t\t\texpires_in: tokens.expiresIn,\n\t\t\trefresh_token: tokens.refreshToken,\n\t\t\tscope: scopes.join(\" \"),\n\t\t};\n\t}\n\n\tasync #refreshGrant(\n\t\tp: Record<string, string | undefined>,\n\t\tclientId: string,\n\t): Promise<Record<string, unknown>> {\n\t\tconst token = p[\"refresh_token\"];\n\t\tif (token === undefined) {\n\t\t\tthrow new OAuthError(400, \"invalid_request\", \"refresh_token is required\");\n\t\t}\n\t\tconst invalid = (why: string) => new OAuthError(400, \"invalid_grant\", why);\n\t\tconst hash = hashToken(token);\n\t\tconst record = await this.#host.store.get(hash);\n\t\tif (record === undefined || record.kind !== \"refresh\") {\n\t\t\tthrow invalid(\"the refresh token is not valid\");\n\t\t}\n\t\tif (!constantTimeEqual(clientId, record.clientId)) {\n\t\t\tthrow invalid(\"the refresh token was issued to another client\");\n\t\t}\n\t\tconst now = Date.now();\n\t\tif (record.expiresAt <= now) throw invalid(\"the refresh token has expired\");\n\t\tif (record.usedAt !== undefined) {\n\t\t\tawait this.#reuseDetected(record);\n\t\t\tthrow invalid(\n\t\t\t\t\"the refresh token was already used; the connection was revoked\",\n\t\t\t);\n\t\t}\n\t\tif (\n\t\t\tp[\"resource\"] !== undefined &&\n\t\t\tp[\"resource\"] !== `${this.#issuer}/a/${record.addressId}/mcp`\n\t\t) {\n\t\t\tthrow new OAuthError(\n\t\t\t\t400,\n\t\t\t\t\"invalid_target\",\n\t\t\t\t\"resource is not the address this token belongs to\",\n\t\t\t);\n\t\t}\n\t\tconst scope = p[\"scope\"];\n\t\tif (scope !== undefined) {\n\t\t\tconst wanted = scope.split(\" \").filter((s) => s !== \"\");\n\t\t\tif (!wanted.every((s) => record.scopes.includes(s))) {\n\t\t\t\tthrow new OAuthError(400, \"invalid_scope\", \"scope exceeds the grant\");\n\t\t\t}\n\t\t}\n\t\tif (!this.#refreshesPerGrant.take(record.grantId, now)) {\n\t\t\tthrow new OAuthError(\n\t\t\t\t429,\n\t\t\t\t\"temporarily_unavailable\",\n\t\t\t\t\"too many refreshes for this connection; try again in a minute\",\n\t\t\t);\n\t\t}\n\t\t// Atomic: of two refreshes with the same token only one gets here.\n\t\t// The used token is kept for the reuse window only (DEC-091).\n\t\tif (\n\t\t\t!(await this.#host.store.markUsed(\n\t\t\t\thash,\n\t\t\t\tnow,\n\t\t\t\tnow + REFRESH_REUSE_WINDOW_MS,\n\t\t\t))\n\t\t) {\n\t\t\tawait this.#reuseDetected(record);\n\t\t\tthrow invalid(\n\t\t\t\t\"the refresh token was already used; the connection was revoked\",\n\t\t\t);\n\t\t}\n\t\tconst tokens = await issueTokenPair(\n\t\t\tthis.#host.store,\n\t\t\t{\n\t\t\t\tgrantId: record.grantId,\n\t\t\t\taddressId: record.addressId,\n\t\t\t\tclientId: record.clientId,\n\t\t\t\tclientName: record.clientName,\n\t\t\t\tscopes: record.scopes,\n\t\t\t\tgrantCreatedAt: record.grantCreatedAt,\n\t\t\t\t...(record.subject === undefined ? {} : { subject: record.subject }),\n\t\t\t},\n\t\t\t{\n\t\t\t\taccessTtlMs: this.#host.config.accessTokenTtlMs,\n\t\t\t\trefreshTtlMs: this.#host.config.refreshTokenTtlMs,\n\t\t\t\t// Refreshes slide, but never beyond the grant's absolute end (DEC-062).\n\t\t\t\tgrantEndsAt: record.grantCreatedAt + this.#host.config.grantLifetimeMs,\n\t\t\t\tnow,\n\t\t\t},\n\t\t);\n\t\tif (tokens === undefined) {\n\t\t\t// The grant was revoked while this refresh ran (DEC-063).\n\t\t\tthrow invalid(\"the connection was revoked\");\n\t\t}\n\t\tthis.#host.logger.debug(\"oauth.refreshed\", {\n\t\t\taddress: shortAddress(record.addressId),\n\t\t\tclient: hostOf(record.clientId),\n\t\t});\n\t\treturn this.#tokenBody(tokens, record.scopes);\n\t}\n\n\tasync #reuseDetected(record: TokenRecord): Promise<void> {\n\t\tthis.#host.logger.warn(\"oauth.refresh_reuse\", {\n\t\t\taddress: shortAddress(record.addressId),\n\t\t\tclient: hostOf(record.clientId),\n\t\t});\n\t\tawait this.#revokeGrant(record.addressId, record.grantId, \"reuse_detected\");\n\t}\n\n\tasync #revokeGrant(\n\t\taddressId: string,\n\t\tgrantId: string,\n\t\treason: string,\n\t): Promise<void> {\n\t\tconst now = Date.now();\n\t\tconst n = await this.#host.store.revoke(\n\t\t\t{ grantId },\n\t\t\t{ now, keepUntil: now + this.#host.config.grantLifetimeMs },\n\t\t);\n\t\tif (n > 0) this.#host.grantRemoved(addressId, grantId, reason);\n\t}\n\n\t// /revoke\n\n\t/** POST `/revoke` (RFC 7009). */\n\tasync revoke(req: Request, ip: string): Promise<Response> {\n\t\tconst noStore = { \"cache-control\": \"no-store\" };\n\t\ttry {\n\t\t\tif (!this.#tokenPerIp.take(ip)) {\n\t\t\t\tthrow new OAuthError(\n\t\t\t\t\t429,\n\t\t\t\t\t\"temporarily_unavailable\",\n\t\t\t\t\t\"too many requests; try again shortly\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst params = await this.#formParams(req);\n\t\t\tconst p = single(params, [\"token\", \"client_id\", \"token_type_hint\"]);\n\t\t\tif (\"duplicate\" in p) {\n\t\t\t\tthrow new OAuthError(\n\t\t\t\t\t400,\n\t\t\t\t\t\"invalid_request\",\n\t\t\t\t\t`${p.duplicate} was sent more than once`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst token = p[\"token\"];\n\t\t\tconst clientId = p[\"client_id\"];\n\t\t\tif (token === undefined || clientId === undefined) {\n\t\t\t\tthrow new OAuthError(\n\t\t\t\t\t400,\n\t\t\t\t\t\"invalid_request\",\n\t\t\t\t\t\"token and client_id are required\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst record = await this.#host.store.get(hashToken(token));\n\t\t\t// RFC 7009 §2.2: an unknown token is not an error.\n\t\t\tif (record === undefined)\n\t\t\t\treturn new Response(null, {\n\t\t\t\t\tstatus: 200,\n\t\t\t\t\theaders: { ...this.#cors(), ...noStore },\n\t\t\t\t});\n\t\t\tif (!constantTimeEqual(clientId, record.clientId)) {\n\t\t\t\tthrow new OAuthError(\n\t\t\t\t\t400,\n\t\t\t\t\t\"invalid_client\",\n\t\t\t\t\t\"the token was issued to another client\",\n\t\t\t\t);\n\t\t\t}\n\t\t\t// The grant is the connection: revoking either token ends it.\n\t\t\tawait this.#revokeGrant(record.addressId, record.grantId, \"revoked\");\n\t\t\tthis.#host.logger.info(\"oauth.revoked\", {\n\t\t\t\taddress: shortAddress(record.addressId),\n\t\t\t\tclient: hostOf(record.clientId),\n\t\t\t\tby: \"client\",\n\t\t\t});\n\t\t\treturn new Response(null, {\n\t\t\t\tstatus: 200,\n\t\t\t\theaders: { ...this.#cors(), ...noStore },\n\t\t\t});\n\t\t} catch (error) {\n\t\t\treturn this.#oauthErrorResponse(error, noStore);\n\t\t}\n\t}\n\n\t// Housekeeping\n\n\t/** Drop expired requests; insertion order is expiry order, so stop at the first live one. */\n\t#sweepPending(): void {\n\t\tconst now = Date.now();\n\t\tfor (const p of this.#pending.values()) {\n\t\t\tif (p.expiresAt > now) break;\n\t\t\tthis.#dropPending(p);\n\t\t}\n\t}\n\n\t#sweepCodes(force = false): void {\n\t\tconst now = Date.now();\n\t\t// Keep used codes until they expire, to detect reuse.\n\t\tfor (const [key, c] of this.#codes) {\n\t\t\tif (c.expiresAt <= now) this.#codes.delete(key);\n\t\t}\n\t\tif (force && this.#codes.size >= MAX_CODES) {\n\t\t\tconst drop = this.#codes.size - MAX_CODES + 1;\n\t\t\tfor (const key of [...this.#codes.keys()].slice(0, drop)) {\n\t\t\t\tthis.#codes.delete(key);\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Drop expired state; the relay calls it periodically. */\n\tsweep(): void {\n\t\tthis.#sweepPending();\n\t\tthis.#sweepCodes();\n\t\tconst now = Date.now();\n\t\tthis.#viewsPerIp.sweep(now);\n\t\tthis.#attemptsPerIp.sweep(now);\n\t\tthis.#guessesPerAddressIp.sweep(now);\n\t\tthis.#guessesPerAddress.sweep(now);\n\t\tthis.#tokenPerIp.sweep(now);\n\t\tthis.#refreshesPerGrant.sweep(now);\n\t}\n}\n",
15
16
  "/**\n * In-memory token buckets keyed by IP, address or host (threat model A8).\n * Bounded: when full, the least recently created bucket is dropped, which at\n * worst gives that key a fresh, full bucket.\n */\n\ninterface Bucket {\n\ttokens: number;\n\tupdatedAt: number;\n}\n\nexport interface RateLimitOptions {\n\t/** Burst size: how many requests a fresh key may make at once. */\n\tcapacity: number;\n\t/** Tokens added per second. */\n\trefillPerSecond: number;\n\t/** Most keys kept in memory. */\n\tmaxKeys?: number;\n}\n\nexport class RateLimiter {\n\treadonly #buckets = new Map<string, Bucket>();\n\treadonly #capacity: number;\n\treadonly #refill: number;\n\treadonly #maxKeys: number;\n\n\tconstructor(options: RateLimitOptions) {\n\t\tthis.#capacity = options.capacity;\n\t\tthis.#refill = options.refillPerSecond;\n\t\tthis.#maxKeys = options.maxKeys ?? 10_000;\n\t}\n\n\t/** Take one token for `key`; false when the bucket is empty. */\n\ttake(key: string, now: number = Date.now()): boolean {\n\t\tlet bucket = this.#buckets.get(key);\n\t\tif (bucket === undefined) {\n\t\t\tif (this.#buckets.size >= this.#maxKeys) {\n\t\t\t\tconst oldest = this.#buckets.keys().next().value;\n\t\t\t\tif (oldest !== undefined) this.#buckets.delete(oldest);\n\t\t\t}\n\t\t\tbucket = { tokens: this.#capacity, updatedAt: now };\n\t\t\tthis.#buckets.set(key, bucket);\n\t\t} else {\n\t\t\tconst elapsed = Math.max(0, now - bucket.updatedAt) / 1000;\n\t\t\tbucket.tokens = Math.min(\n\t\t\t\tthis.#capacity,\n\t\t\t\tbucket.tokens + elapsed * this.#refill,\n\t\t\t);\n\t\t\tbucket.updatedAt = now;\n\t\t}\n\t\tif (bucket.tokens < 1) return false;\n\t\tbucket.tokens -= 1;\n\t\treturn true;\n\t}\n\n\t/** Whether `take` would succeed for `key` now; takes nothing. */\n\tavailable(key: string, now: number = Date.now()): boolean {\n\t\tconst bucket = this.#buckets.get(key);\n\t\tif (bucket === undefined) return this.#capacity >= 1;\n\t\tconst elapsed = Math.max(0, now - bucket.updatedAt) / 1000;\n\t\treturn (\n\t\t\tMath.min(this.#capacity, bucket.tokens + elapsed * this.#refill) >= 1\n\t\t);\n\t}\n\n\t/** Drop buckets that are full again (nothing to remember). */\n\tsweep(now: number = Date.now()): void {\n\t\tfor (const [key, b] of this.#buckets) {\n\t\t\tconst elapsed = Math.max(0, now - b.updatedAt) / 1000;\n\t\t\tif (b.tokens + elapsed * this.#refill >= this.#capacity) {\n\t\t\t\tthis.#buckets.delete(key);\n\t\t\t}\n\t\t}\n\t}\n}\n",
16
17
  "import type { TokenKind, TokenRecord, TokenStore } from \"./store/types.ts\";\n\n/** Prefixes make leaked tokens recognisable to secret scanners. */\nconst PREFIX: Record<TokenKind, string> = {\n\taccess: \"tmcp_at_\",\n\trefresh: \"tmcp_rt_\",\n};\n\nfunction random(bytes: number): string {\n\treturn crypto\n\t\t.getRandomValues(new Uint8Array(bytes))\n\t\t.toBase64({ alphabet: \"base64url\", omitPadding: true });\n}\n\n/** A new opaque token with 256 bits of randomness. */\nexport function newToken(kind: TokenKind): string {\n\treturn PREFIX[kind] + random(32);\n}\n\n/** A random identifier with a readable prefix, e.g. `g_…`, `s_…`. */\nexport function newId(prefix: string): string {\n\treturn `${prefix}_${random(12)}`;\n}\n\n/** SHA-256 of a token, base64url without padding: the store key. */\nexport function hashToken(token: string): string {\n\treturn new Bun.CryptoHasher(\"sha256\")\n\t\t.update(token)\n\t\t.digest()\n\t\t.toBase64({ alphabet: \"base64url\", omitPadding: true });\n}\n\n/** The parts of a grant needed to issue tokens for it. */\nexport interface GrantInput {\n\tgrantId?: string;\n\taddressId: string;\n\tclientId: string;\n\tclientName: string;\n\tscopes?: string[];\n\tgrantCreatedAt?: number;\n\t/** The hashed identity of an identity-bound grant (DEC-077). */\n\tsubject?: string;\n}\n\n/**\n * Issue an access token for a grant and store its hash, without OAuth. An\n * internal helper for tests that need a token but not the flow; the token\n * endpoint issues through `issueTokenPair`.\n */\nexport async function issueAccessToken(\n\tstore: TokenStore,\n\tgrant: GrantInput,\n\toptions: { ttlMs: number; now?: number },\n): Promise<{ token: string; record: TokenRecord }> {\n\tconst now = options.now ?? Date.now();\n\tconst token = newToken(\"access\");\n\tconst record: TokenRecord = {\n\t\thash: hashToken(token),\n\t\tkind: \"access\",\n\t\tgrantId: grant.grantId ?? newId(\"g\"),\n\t\taddressId: grant.addressId,\n\t\tclientId: grant.clientId,\n\t\tclientName: grant.clientName,\n\t\tscopes: grant.scopes ?? [\"tools\"],\n\t\tgrantCreatedAt: grant.grantCreatedAt ?? now,\n\t\tissuedAt: now,\n\t\texpiresAt: now + options.ttlMs,\n\t};\n\tif (grant.subject !== undefined) record.subject = grant.subject;\n\tawait store.put(record);\n\treturn { token, record };\n}\n\n/**\n * A new access token and refresh token for a grant (DEC-029). Neither lives\n * beyond `grantEndsAt` (DEC-062). Returns `undefined` if the store refuses\n * them because the grant was revoked meanwhile (its tombstone, DEC-063).\n */\nexport async function issueTokenPair(\n\tstore: TokenStore,\n\tgrant: Required<Omit<GrantInput, \"scopes\" | \"subject\">> & {\n\t\tscopes: string[];\n\t\tsubject?: string;\n\t},\n\toptions: {\n\t\taccessTtlMs: number;\n\t\trefreshTtlMs: number;\n\t\tgrantEndsAt: number;\n\t\tnow?: number;\n\t},\n): Promise<\n\t{ accessToken: string; refreshToken: string; expiresIn: number } | undefined\n> {\n\tconst now = options.now ?? Date.now();\n\tconst accessToken = newToken(\"access\");\n\tconst refreshToken = newToken(\"refresh\");\n\tconst base = {\n\t\tgrantId: grant.grantId,\n\t\taddressId: grant.addressId,\n\t\tclientId: grant.clientId,\n\t\tclientName: grant.clientName,\n\t\tscopes: grant.scopes,\n\t\tgrantCreatedAt: grant.grantCreatedAt,\n\t\tissuedAt: now,\n\t\t...(grant.subject === undefined ? {} : { subject: grant.subject }),\n\t};\n\tconst accessExpires = Math.min(\n\t\tnow + options.accessTtlMs,\n\t\toptions.grantEndsAt,\n\t);\n\t// The refresh token first: a grant whose access token exists always has\n\t// a way to be listed and revoked. If a revocation lands between the two\n\t// puts, it deletes the first and its tombstone refuses the second.\n\tconst refreshStored = await store.put({\n\t\t...base,\n\t\thash: hashToken(refreshToken),\n\t\tkind: \"refresh\",\n\t\texpiresAt: Math.min(now + options.refreshTtlMs, options.grantEndsAt),\n\t});\n\tif (!refreshStored) return undefined;\n\tconst accessStored = await store.put({\n\t\t...base,\n\t\thash: hashToken(accessToken),\n\t\tkind: \"access\",\n\t\texpiresAt: accessExpires,\n\t});\n\tif (!accessStored) return undefined;\n\treturn {\n\t\taccessToken,\n\t\trefreshToken,\n\t\texpiresIn: Math.max(0, Math.floor((accessExpires - now) / 1000)),\n\t};\n}\n",
17
- "/**\n * Client ID Metadata Documents (CIMD, draft-ietf-oauth-client-id-metadata-document;\n * MCP 2026-07-28 client registration): the `client_id` is an HTTPS URL, and\n * the relay fetches it to learn the client's name and redirect URIs.\n *\n * The URL is chosen by an unauthenticated party, so the fetch is guarded\n * against SSRF (threat model A3): https only, default port, no credentials,\n * the host resolved first and every address checked to be public, no\n * redirects, 5 s, 64 KiB, `application/json`, results cached and fetches per\n * domain and in total rate-limited.\n */\n\nimport { isLoopbackHost, isPublicIp, parseIpv4, parseIpv6 } from \"../ip.ts\";\nimport type { Logger } from \"../log.ts\";\nimport { RateLimiter } from \"../ratelimit.ts\";\n\n/** What the relay needs to know about a client. */\nexport interface ClientMetadata {\n\t/** The client id: the document's URL. */\n\tclientId: string;\n\t/** Self-declared, cleaned and shortened for display. */\n\tname: string;\n\t/** Host of the client id URL: the verified part. */\n\thost: string;\n\tredirectUris: string[];\n}\n\n/** Why a client id was refused; `message` is plain English for the page. */\nexport class ClientMetadataError extends Error {\n\toverride name = \"ClientMetadataError\";\n\treadonly reason: string;\n\tconstructor(reason: string, message: string) {\n\t\tsuper(message);\n\t\tthis.reason = reason;\n\t}\n}\n\n/**\n * Test-only relaxations (never from configuration): loopback hosts, any port,\n * `http:`, and an extra CA for a self-signed test server.\n */\nexport interface CimdTestMode {\n\tca?: string;\n}\n\nexport interface ClientMetadataFetcherOptions {\n\t/** Accepted client id hosts; empty = any. */\n\tallowedHosts?: readonly string[];\n\tlogger?: Logger;\n\ttimeoutMs?: number;\n\tmaxBytes?: number;\n\t/** Resolve a host name to its addresses (tests replace it). */\n\tlookup?: (hostname: string) => Promise<string[]>;\n\tfetch?: typeof fetch;\n\ttestMode?: CimdTestMode;\n\tnow?: () => number;\n}\n\nconst MAX_CLIENT_ID_LENGTH = 2048;\nconst MAX_NAME_LENGTH = 64;\nconst MAX_REDIRECT_URIS = 20;\nconst MIN_CACHE_MS = 5 * 60_000;\nconst DEFAULT_CACHE_MS = 60 * 60_000;\nconst MAX_CACHE_MS = 24 * 60 * 60_000;\nconst MAX_CACHE_ENTRIES = 1000;\n\nasync function defaultLookup(hostname: string): Promise<string[]> {\n\tconst records = await Bun.dns.lookup(hostname, {});\n\treturn records.map((r) => r.address);\n}\n\n/**\n * Invisible characters that are not format characters (`Cf`): Hangul and\n * other fillers, the braille blank, combining grapheme joiner, variation\n * selectors.\n */\nconst INVISIBLE =\n\t/[\\u034F\\u115F\\u1160\\u17B4\\u17B5\\u2800\\u3164\\uFFA0]|\\p{Variation_Selector}/gu;\n\n/**\n * Clean a self-declared name for display: control and line/paragraph\n * separators become spaces; format characters (`Cf`: zero-width, bidi,\n * word joiner, BOM, soft hyphen, …) and other invisible characters are\n * removed; whitespace collapses; at most 64 characters (DEC-065).\n */\nexport function displayName(raw: string): string {\n\tlet cleaned = raw\n\t\t.normalize(\"NFC\")\n\t\t.replace(/[\\p{Cc}\\p{Zl}\\p{Zp}]/gu, \" \")\n\t\t.replace(/\\p{Cf}/gu, \"\")\n\t\t.replace(INVISIBLE, \"\");\n\tcleaned = cleaned.replace(/\\s+/g, \" \").trim();\n\tconst chars = [...cleaned];\n\treturn chars.length > MAX_NAME_LENGTH\n\t\t? `${chars.slice(0, MAX_NAME_LENGTH - 1).join(\"\")}…`\n\t\t: cleaned;\n}\n\n/** Seconds of `max-age` in a Cache-Control header, or a marker. */\nfunction cacheMs(header: string | null): number {\n\tif (header === null) return DEFAULT_CACHE_MS;\n\tconst directives = header\n\t\t.toLowerCase()\n\t\t.split(\",\")\n\t\t.map((d) => d.trim());\n\tif (directives.includes(\"no-store\") || directives.includes(\"no-cache\")) {\n\t\treturn MIN_CACHE_MS;\n\t}\n\tconst maxAge = directives\n\t\t.map((d) => /^max-age=(\\d+)$/.exec(d)?.[1])\n\t\t.find((v) => v !== undefined);\n\tif (maxAge === undefined) return DEFAULT_CACHE_MS;\n\treturn Math.min(MAX_CACHE_MS, Math.max(MIN_CACHE_MS, Number(maxAge) * 1000));\n}\n\nfunction isIpLiteral(hostname: string): boolean {\n\tconst h = hostname.replace(/^\\[|\\]$/g, \"\");\n\treturn parseIpv4(h) !== undefined || parseIpv6(h) !== undefined;\n}\n\n/**\n * The key fetches are limited under (DEC-089): the last two labels of a host\n * name, so `*.evil.example` is one key however many subdomains it has; an IP\n * literal as is. Without the Public Suffix List, clients under a multi-label\n * suffix (`co.uk`, `pages.dev`) share one key, so many hosts there can slow\n * the others' uncached fetches; one host alone cannot (its own limit is lower).\n */\nexport function limitKey(hostname: string): string {\n\tconst h = hostname.replace(/^\\[|\\]$/g, \"\").replace(/\\.$/, \"\");\n\tif (isIpLiteral(h)) return h;\n\treturn h.split(\".\").slice(-2).join(\".\");\n}\n\n/** Fetches, validates and caches Client ID Metadata Documents. */\nexport class ClientMetadataFetcher {\n\treadonly #cache = new Map<string, { meta: ClientMetadata; until: number }>();\n\treadonly #perHost = new RateLimiter({ capacity: 5, refillPerSecond: 0.2 });\n\t/** Three hosts' worth: one host alone cannot use up its domain (DEC-089). */\n\treadonly #perDomain = new RateLimiter({ capacity: 15, refillPerSecond: 0.6 });\n\t/** All fetches together: many attacker-owned hosts cannot add up (DEC-061). */\n\treadonly #global = new RateLimiter({ capacity: 30, refillPerSecond: 1 });\n\treadonly #allowedHosts: readonly string[];\n\treadonly #logger: Logger | undefined;\n\treadonly #timeoutMs: number;\n\treadonly #maxBytes: number;\n\treadonly #lookup: (hostname: string) => Promise<string[]>;\n\treadonly #fetch: typeof fetch;\n\treadonly #testMode: CimdTestMode | undefined;\n\treadonly #now: () => number;\n\n\tconstructor(options: ClientMetadataFetcherOptions = {}) {\n\t\tthis.#allowedHosts = options.allowedHosts ?? [];\n\t\tthis.#logger = options.logger;\n\t\tthis.#timeoutMs = options.timeoutMs ?? 5000;\n\t\tthis.#maxBytes = options.maxBytes ?? 65_536;\n\t\tthis.#lookup = options.lookup ?? defaultLookup;\n\t\tthis.#fetch = options.fetch ?? fetch;\n\t\tthis.#testMode = options.testMode;\n\t\tthis.#now = options.now ?? Date.now;\n\t}\n\n\t/** The client's metadata, from the cache or freshly fetched. Throws `ClientMetadataError`. */\n\tasync get(clientId: string): Promise<ClientMetadata> {\n\t\tconst url = this.#checkUrl(clientId);\n\t\tconst now = this.#now();\n\t\tconst cached = this.#cache.get(clientId);\n\t\tif (cached !== undefined && cached.until > now) {\n\t\t\t// Least recently used first: a hit moves the entry to the end.\n\t\t\tthis.#cache.delete(clientId);\n\t\t\tthis.#cache.set(clientId, cached);\n\t\t\treturn cached.meta;\n\t\t}\n\t\t// Per host and per domain, and only charged once the global limit\n\t\t// admits the fetch: refusals cost the others nothing (DEC-089).\n\t\tconst key = limitKey(url.hostname);\n\t\tif (\n\t\t\t!this.#perHost.available(url.host, now) ||\n\t\t\t!this.#perDomain.available(key, now)\n\t\t) {\n\t\t\tthrow new ClientMetadataError(\n\t\t\t\t\"rate_limited\",\n\t\t\t\t\"Too many requests for this AI app's details. Try again in a minute.\",\n\t\t\t);\n\t\t}\n\t\tif (!this.#global.take(\"all\", now)) {\n\t\t\tthrow new ClientMetadataError(\n\t\t\t\t\"rate_limited\",\n\t\t\t\t\"The relay is busy. Try again in a minute.\",\n\t\t\t);\n\t\t}\n\t\tthis.#perHost.take(url.host, now);\n\t\tthis.#perDomain.take(key, now);\n\t\tconst address = await this.#vettedAddress(url);\n\t\tconst { meta, ttlMs } = await this.#fetchDocument(url, clientId, address);\n\t\tthis.#cache.delete(clientId);\n\t\tif (this.#cache.size >= MAX_CACHE_ENTRIES) {\n\t\t\tconst oldest = this.#cache.keys().next().value;\n\t\t\tif (oldest !== undefined) this.#cache.delete(oldest);\n\t\t}\n\t\tthis.#cache.set(clientId, { meta, until: now + ttlMs });\n\t\treturn meta;\n\t}\n\n\t/** The URL rules of the CIMD draft plus our SSRF rules, before any network use. */\n\t#checkUrl(clientId: string): URL {\n\t\tconst refuse = (message: string) =>\n\t\t\tnew ClientMetadataError(\"invalid_client_id\", message);\n\t\tif (clientId.length === 0 || clientId.length > MAX_CLIENT_ID_LENGTH) {\n\t\t\tthrow refuse(\"The AI app's client_id is missing or too long.\");\n\t\t}\n\t\tlet url: URL;\n\t\ttry {\n\t\t\turl = new URL(clientId);\n\t\t} catch {\n\t\t\tthrow refuse(\"The AI app's client_id is not a URL.\");\n\t\t}\n\t\tconst test = this.#testMode !== undefined;\n\t\tconst scheme =\n\t\t\turl.protocol === \"https:\" || (test && url.protocol === \"http:\");\n\t\tif (!scheme) {\n\t\t\tthrow refuse(\"The AI app's client_id must be an https:// URL.\");\n\t\t}\n\t\t// Canonical form only: this rejects dot segments, fragments' oddities,\n\t\t// an explicit default port, upper-case hosts and other aliases.\n\t\tif (url.href !== clientId) {\n\t\t\tthrow refuse(\"The AI app's client_id is not a canonical URL.\");\n\t\t}\n\t\tif (url.username !== \"\" || url.password !== \"\" || url.hash !== \"\") {\n\t\t\tthrow refuse(\n\t\t\t\t\"The AI app's client_id must not contain credentials or a fragment.\",\n\t\t\t);\n\t\t}\n\t\tif (url.pathname === \"/\" || url.pathname === \"\") {\n\t\t\tthrow refuse(\"The AI app's client_id must have a path.\");\n\t\t}\n\t\tif (url.port !== \"\" && !test) {\n\t\t\tthrow refuse(\"The AI app's client_id must use the default port.\");\n\t\t}\n\t\tif (\n\t\t\tthis.#allowedHosts.length > 0 &&\n\t\t\t!this.#allowedHosts.includes(url.host)\n\t\t) {\n\t\t\tthrow new ClientMetadataError(\n\t\t\t\t\"host_not_allowed\",\n\t\t\t\t`This relay does not accept AI apps from ${url.host}.`,\n\t\t\t);\n\t\t}\n\t\tif (isIpLiteral(url.hostname) && !this.#addressAllowed(url.hostname)) {\n\t\t\tthrow this.#notLoaded(\"private_address\", url);\n\t\t}\n\t\treturn url;\n\t}\n\n\t#addressAllowed(address: string): boolean {\n\t\tif (isPublicIp(address)) return true;\n\t\treturn this.#testMode !== undefined && isLoopbackHost(address);\n\t}\n\n\t/**\n\t * One fixed message for every failure from resolving to parsing, so the\n\t * page tells nothing about what answered (threat model A3, DEC-066). The\n\t * reason goes to the log.\n\t */\n\t#notLoaded(reason: string, url: URL, detail = reason): ClientMetadataError {\n\t\tthis.#logger?.info(\"oauth.cimd_failed\", { host: url.host, reason: detail });\n\t\treturn new ClientMetadataError(\n\t\t\treason,\n\t\t\t`The AI app's details could not be loaded from ${url.host}.`,\n\t\t);\n\t}\n\n\t/**\n\t * Resolve the host, refuse it if any address is not public, and return the\n\t * address to connect to (IPv4 first). The fetch is pinned to it, so a DNS\n\t * answer that changes between check and connect is never used.\n\t */\n\tasync #vettedAddress(url: URL): Promise<string> {\n\t\tconst hostname = url.hostname.replace(/^\\[|\\]$/g, \"\");\n\t\tif (isIpLiteral(hostname)) return hostname; // checked in #checkUrl\n\t\tlet addresses: string[];\n\t\ttry {\n\t\t\taddresses = await this.#lookup(hostname);\n\t\t} catch {\n\t\t\tthrow this.#notLoaded(\"unresolvable\", url);\n\t\t}\n\t\tif (\n\t\t\taddresses.length === 0 ||\n\t\t\t!addresses.every((a) => this.#addressAllowed(a))\n\t\t) {\n\t\t\tthrow this.#notLoaded(\"private_address\", url);\n\t\t}\n\t\treturn (\n\t\t\taddresses.find((a) => parseIpv4(a) !== undefined) ?? addresses[0] ?? \"\"\n\t\t);\n\t}\n\n\tasync #fetchDocument(\n\t\turl: URL,\n\t\tclientId: string,\n\t\taddress: string,\n\t): Promise<{ meta: ClientMetadata; ttlMs: number }> {\n\t\tconst fail = (detail: string) =>\n\t\t\tthis.#notLoaded(\"fetch_failed\", url, detail);\n\t\t// Connect to the vetted address; Host and the TLS server name stay the\n\t\t// original host, so the certificate is checked against it.\n\t\tconst pinned = new URL(clientId);\n\t\tpinned.hostname = address.includes(\":\") ? `[${address}]` : address;\n\t\tconst hostname = url.hostname.replace(/^\\[|\\]$/g, \"\");\n\t\tconst tls =\n\t\t\turl.protocol === \"https:\"\n\t\t\t\t? {\n\t\t\t\t\t\ttls: {\n\t\t\t\t\t\t\t...(isIpLiteral(hostname) ? {} : { serverName: hostname }),\n\t\t\t\t\t\t\t...(this.#testMode?.ca === undefined\n\t\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t\t: { ca: this.#testMode.ca }),\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t: {};\n\t\tlet response: Response;\n\t\ttry {\n\t\t\tresponse = await this.#fetch(pinned.href, {\n\t\t\t\tmethod: \"GET\",\n\t\t\t\tredirect: \"manual\",\n\t\t\t\theaders: { accept: \"application/json\", host: url.host },\n\t\t\t\tsignal: AbortSignal.timeout(this.#timeoutMs),\n\t\t\t\t...tls,\n\t\t\t} as RequestInit);\n\t\t} catch (error) {\n\t\t\tthrow fail(\n\t\t\t\t`fetch_failed:${error instanceof Error ? error.name : \"unknown\"}`,\n\t\t\t);\n\t\t}\n\t\ttry {\n\t\t\tif (response.status !== 200) throw fail(`status_${response.status}`);\n\t\t\tconst type = (response.headers.get(\"content-type\") ?? \"\")\n\t\t\t\t.split(\";\")[0]\n\t\t\t\t?.trim()\n\t\t\t\t.toLowerCase();\n\t\t\tif (type !== \"application/json\") throw fail(\"not_json\");\n\t\t\tconst text = await this.#readLimited(response, url);\n\t\t\tlet doc: unknown;\n\t\t\ttry {\n\t\t\t\tdoc = JSON.parse(text);\n\t\t\t} catch {\n\t\t\t\tthrow fail(\"bad_json\");\n\t\t\t}\n\t\t\tconst meta = validateDocument(doc, clientId, url);\n\t\t\treturn { meta, ttlMs: cacheMs(response.headers.get(\"cache-control\")) };\n\t\t} finally {\n\t\t\tif (!response.bodyUsed) response.body?.cancel().catch(() => {});\n\t\t}\n\t}\n\n\tasync #readLimited(response: Response, url: URL): Promise<string> {\n\t\tconst tooLarge = () => this.#notLoaded(\"too_large\", url);\n\t\tconst length = Number(response.headers.get(\"content-length\") ?? \"0\");\n\t\tif (length > this.#maxBytes) throw tooLarge();\n\t\tconst reader = response.body?.getReader();\n\t\tif (reader === undefined) return \"\";\n\t\tconst chunks: Uint8Array[] = [];\n\t\tlet total = 0;\n\t\tfor (;;) {\n\t\t\tconst { done, value } = await reader.read();\n\t\t\tif (done) break;\n\t\t\ttotal += value.byteLength;\n\t\t\tif (total > this.#maxBytes) {\n\t\t\t\tawait reader.cancel().catch(() => {});\n\t\t\t\tthrow tooLarge();\n\t\t\t}\n\t\t\tchunks.push(value);\n\t\t}\n\t\ttry {\n\t\t\treturn new TextDecoder(\"utf-8\", { fatal: true }).decode(\n\t\t\t\tBuffer.concat(chunks),\n\t\t\t);\n\t\t} catch {\n\t\t\tthrow this.#notLoaded(\"fetch_failed\", url, \"bad_utf8\");\n\t\t}\n\t}\n}\n\n/** Labels separated by dots, ending in a label of 2-63 letters: `claude.ai`, `x.co.uk`. */\nconst DOMAIN_SHAPED =\n\t/(?:[\\p{L}\\p{N}](?:[\\p{L}\\p{N}-]*[\\p{L}\\p{N}])?\\.)+\\p{L}{2,63}(?![\\p{L}\\p{N}])/gu;\n\n/**\n * A name as the address checks read it: compatibility forms folded (NFKC),\n * combining marks removed, so \"claude.a̲i\" reads \"claude.ai\", the\n * ideographic full stops browsers read as dots made dots, lower case.\n */\nfunction comparable(name: string): string {\n\treturn name\n\t\t.normalize(\"NFKC\")\n\t\t.replace(/\\p{M}/gu, \"\")\n\t\t.replace(/[。.。]/g, \".\")\n\t\t.toLowerCase();\n}\n\n/** A host name in its ASCII (punycode) form, as `URL` gives it. */\nfunction asciiHost(token: string): string {\n\ttry {\n\t\treturn new URL(`https://${token}/`).hostname;\n\t} catch {\n\t\treturn token;\n\t}\n}\n\n/**\n * Whether a name contains a domain-shaped token that is not the verified\n * host, a subdomain of it or a parent of it (DEC-092). Internationalised\n * names are compared in their ASCII form, as the host is.\n */\nexport function foreignDomain(name: string, hostname: string): boolean {\n\tconst host = hostname.toLowerCase();\n\tfor (const [match] of comparable(name).matchAll(DOMAIN_SHAPED)) {\n\t\tconst token = asciiHost(match);\n\t\tconst own =\n\t\t\ttoken === host ||\n\t\t\thost.endsWith(`.${token}`) ||\n\t\t\ttoken.endsWith(`.${host}`);\n\t\tif (!own) return true;\n\t}\n\treturn false;\n}\n\n/** Check a fetched document against the CIMD rules and what the relay supports. */\nexport function validateDocument(\n\tdoc: unknown,\n\tclientId: string,\n\turl: URL,\n): ClientMetadata {\n\tconst invalid = (message: string) =>\n\t\tnew ClientMetadataError(\"invalid_metadata\", message);\n\tif (typeof doc !== \"object\" || doc === null || Array.isArray(doc)) {\n\t\tthrow invalid(\"The AI app's details are not a JSON object.\");\n\t}\n\tconst d = doc as Record<string, unknown>;\n\tif (d[\"client_id\"] !== clientId) {\n\t\tthrow invalid(\"The AI app's details name a different client_id.\");\n\t}\n\tif (\n\t\td[\"client_secret\"] !== undefined ||\n\t\td[\"client_secret_expires_at\"] !== undefined\n\t) {\n\t\tthrow invalid(\"The AI app's details must not contain a client secret.\");\n\t}\n\tconst name = d[\"client_name\"];\n\tif (typeof name !== \"string\" || displayName(name) === \"\") {\n\t\tthrow invalid(\"The AI app's details have no client_name.\");\n\t}\n\t// \"Claude (claude.ai)\" from evil.example would read like a verified host.\n\tif (\n\t\t/\\(\\s*[^()\\s]*[a-z0-9-]\\.[a-z]{2,}[^()]*\\)/i.test(\n\t\t\tcomparable(displayName(name)),\n\t\t)\n\t) {\n\t\tthrow invalid(\n\t\t\t\"The AI app's name contains a web address in parentheses, which this relay does not show.\",\n\t\t);\n\t}\n\t// \"Claude · claude.ai\" from evil.example reads the same way (DEC-092).\n\tif (foreignDomain(displayName(name), url.hostname)) {\n\t\tthrow invalid(\n\t\t\t\"The AI app's name contains a web address other than its own, which this relay does not show.\",\n\t\t);\n\t}\n\tconst uris = d[\"redirect_uris\"];\n\tif (\n\t\t!Array.isArray(uris) ||\n\t\turis.length === 0 ||\n\t\turis.length > MAX_REDIRECT_URIS ||\n\t\t!uris.every((u) => typeof u === \"string\" && isRedirectUri(u))\n\t) {\n\t\tthrow invalid(\"The AI app's details have no valid redirect_uris.\");\n\t}\n\tconst method = d[\"token_endpoint_auth_method\"];\n\tif (method !== undefined && method !== \"none\") {\n\t\tthrow invalid(\n\t\t\t'The AI app must use token_endpoint_auth_method \"none\" with this relay.',\n\t\t);\n\t}\n\tconst grants = d[\"grant_types\"];\n\tif (\n\t\tgrants !== undefined &&\n\t\t(!Array.isArray(grants) || !grants.includes(\"authorization_code\"))\n\t) {\n\t\tthrow invalid(\n\t\t\t\"The AI app's details do not allow the authorization code grant.\",\n\t\t);\n\t}\n\tconst responses = d[\"response_types\"];\n\tif (\n\t\tresponses !== undefined &&\n\t\t(!Array.isArray(responses) || !responses.includes(\"code\"))\n\t) {\n\t\tthrow invalid('The AI app\\'s details do not allow response type \"code\".');\n\t}\n\treturn {\n\t\tclientId,\n\t\tname: displayName(name),\n\t\thost: url.host,\n\t\tredirectUris: uris as string[],\n\t};\n}\n\n/** A private-use URI scheme in reverse-domain form (RFC 8252 §7.1), e.g. `com.example.app:`. */\nconst PRIVATE_USE_SCHEME = /^[a-z][a-z0-9+-]*(\\.[a-z0-9+-]+)+:$/;\n\n/**\n * A redirect URI the relay accepts (DEC-067): absolute, no fragment or\n * credentials, and `https:`; `http:` only for loopback hosts (RFC 8252 §7.3);\n * or a reverse-domain private-use scheme for native apps (RFC 8252 §7.1).\n * Everything else (`file:`, `blob:`, `data:`, `javascript:`, plain `http:`,\n * one-word custom schemes) is refused.\n */\nexport function isRedirectUri(value: string): boolean {\n\tif (value.length > 2048 || value.includes(\"#\")) return false;\n\tlet u: URL;\n\ttry {\n\t\tu = new URL(value);\n\t} catch {\n\t\treturn false;\n\t}\n\tif (u.username !== \"\" || u.password !== \"\") return false;\n\tif (u.protocol === \"https:\") return u.hostname !== \"\";\n\tif (u.protocol === \"http:\") return LOOPBACK_REDIRECT_HOSTS.has(u.hostname);\n\treturn PRIVATE_USE_SCHEME.test(u.protocol);\n}\n\nconst LOOPBACK_REDIRECT_HOSTS = new Set([\"localhost\", \"127.0.0.1\", \"[::1]\"]);\n\n/**\n * Whether a requested redirect URI matches a registered one: exact string\n * equality, except that for an `http:` loopback redirect the port is ignored\n * (RFC 8252 §7.3; OAuth 2.1 §8.4.2). Host, path and query must still match.\n */\nexport function redirectUriMatches(\n\trequested: string,\n\tregistered: string,\n): boolean {\n\tif (requested === registered) return true;\n\tlet a: URL;\n\tlet b: URL;\n\ttry {\n\t\ta = new URL(requested);\n\t\tb = new URL(registered);\n\t} catch {\n\t\treturn false;\n\t}\n\tif (a.protocol !== \"http:\" || b.protocol !== \"http:\") return false;\n\tif (!LOOPBACK_REDIRECT_HOSTS.has(b.hostname) || a.hostname !== b.hostname) {\n\t\treturn false;\n\t}\n\t// The requested URI must be in canonical form, so the parser cannot\n\t// have changed what the comparison sees (dot segments, case, …).\n\tif (\n\t\ta.href !== requested ||\n\t\ta.username !== \"\" ||\n\t\ta.password !== \"\" ||\n\t\ta.hash !== \"\"\n\t) {\n\t\treturn false;\n\t}\n\ta.port = \"\";\n\tb.port = \"\";\n\treturn a.href === b.href;\n}\n",
18
- "/**\n * Server-rendered HTML for `/authorize` (threat model A7): every value is\n * escaped, the page has no scripts, and its headers forbid framing, inline\n * code and foreign form targets.\n */\n\nconst ESCAPES: Record<string, string> = {\n\t\"&\": \"&amp;\",\n\t\"<\": \"&lt;\",\n\t\">\": \"&gt;\",\n\t'\"': \"&quot;\",\n\t\"'\": \"&#39;\",\n};\n\n/** Escape text for HTML element content and quoted attribute values. */\nexport function escapeHtml(text: string): string {\n\treturn text.replace(/[&<>\"']/g, (c) => ESCAPES[c] ?? c);\n}\n\n/** The stylesheet at `/authorize.css` (`style-src 'self'`). */\nexport const AUTHORIZE_CSS = `:root { color-scheme: light dark; --accent: #1d4ed8; --error: #b91c1c; }\n@media (prefers-color-scheme: dark) { :root { --accent: #93b4ff; --error: #fca5a5; } }\n* { box-sizing: border-box; }\nbody { margin: 0; font: 1rem/1.5 system-ui, -apple-system, \"Segoe UI\", sans-serif; background: Canvas; color: CanvasText; }\nmain { max-width: 34rem; margin: 3rem auto; padding: 0 1rem; }\nh1 { font-size: 1.5rem; line-height: 1.25; margin: 0 0 1rem; }\np { margin: 0 0 1rem; }\ncode, .origin { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; overflow-wrap: anywhere; }\n.help { color: GrayText; font-size: 0.9rem; }\n.error { color: var(--error); font-weight: 600; }\nlabel { display: block; font-weight: 600; margin-bottom: 0.25rem; }\ninput[type=\"text\"] { font: 1.5rem/1.2 ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: 0.2em; width: 10ch; padding: 0.4rem 0.5rem; border: 2px solid GrayText; border-radius: 0.4rem; background: Field; color: FieldText; }\ninput[type=\"text\"]:focus-visible, button:focus-visible, a:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }\n.actions { display: flex; gap: 0.75rem; flex-wrap: wrap; margin: 1.5rem 0 1.25rem; }\nbutton, .button { font: inherit; padding: 0.5rem 1.25rem; border-radius: 0.4rem; border: 2px solid var(--accent); cursor: pointer; text-decoration: none; display: inline-block; }\nbutton.primary, .button.primary { background: var(--accent); color: Canvas; }\nbutton.secondary, .button:not(.primary) { background: transparent; color: var(--accent); }\nfooter { margin-top: 2.5rem; font-size: 0.85rem; color: GrayText; }\n`;\n\n/** Security headers of every `/authorize` response. */\nexport function pageHeaders(formTargets: readonly string[] = []): Headers {\n\t// Chrome applies form-action to the redirect after a POST, so the client's\n\t// redirect origin must be allowed explicitly.\n\tconst formAction = [\"'self'\", ...formTargets].join(\" \");\n\treturn new Headers({\n\t\t\"content-type\": \"text/html; charset=utf-8\",\n\t\t\"content-security-policy\": `default-src 'none'; style-src 'self'; img-src 'self'; base-uri 'none'; frame-ancestors 'none'; form-action ${formAction}`,\n\t\t\"x-frame-options\": \"DENY\",\n\t\t\"x-content-type-options\": \"nosniff\",\n\t\t// Not no-referrer: browsers then send `Origin: null` on the form post,\n\t\t// which the origin check must refuse. same-origin still sends nothing\n\t\t// to the client's redirect.\n\t\t\"referrer-policy\": \"same-origin\",\n\t\t\"cache-control\": \"no-store\",\n\t});\n}\n\n/** A complete page; `body` must already be escaped. */\nexport function renderPage(title: string, body: string): string {\n\treturn `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<meta name=\"robots\" content=\"noindex\">\n<title>${escapeHtml(title)}</title>\n<link rel=\"stylesheet\" href=\"/authorize.css\">\n</head>\n<body>\n<main>\n${body}\n<footer>tab-mcp relay. It passes requests between AI apps and web pages and does not store their contents.</footer>\n</main>\n</body>\n</html>`;\n}\n",
18
+ "/**\n * Client ID Metadata Documents (CIMD, draft-ietf-oauth-client-id-metadata-document;\n * MCP 2026-07-28 client registration): the `client_id` is an HTTPS URL, and\n * the relay fetches it to learn the client's name and redirect URIs.\n *\n * The URL is chosen by an unauthenticated party, so the fetch is guarded\n * against SSRF (threat model A3): https only, default port, no credentials,\n * the host resolved first and every address checked to be public, no\n * redirects, 5 s, 64 KiB, `application/json`, results cached and fetches per\n * domain and in total rate-limited.\n */\n\nimport { isLoopbackHost, isPublicIp, parseIpv4, parseIpv6 } from \"../ip.ts\";\nimport type { Logger } from \"../log.ts\";\nimport { RateLimiter } from \"../ratelimit.ts\";\n\n/** What the relay needs to know about a client. */\nexport interface ClientMetadata {\n\t/** The client id: the document's URL. */\n\tclientId: string;\n\t/** Self-declared, cleaned and shortened for display. */\n\tname: string;\n\t/** Host of the client id URL: the verified part. */\n\thost: string;\n\tredirectUris: string[];\n}\n\n/** Why a client id was refused; `message` is plain English for the page. */\nexport class ClientMetadataError extends Error {\n\toverride name = \"ClientMetadataError\";\n\treadonly reason: string;\n\tconstructor(reason: string, message: string) {\n\t\tsuper(message);\n\t\tthis.reason = reason;\n\t}\n}\n\n/**\n * Test-only relaxations (never from configuration): loopback hosts, any port,\n * `http:`, and an extra CA for a self-signed test server.\n */\nexport interface CimdTestMode {\n\tca?: string;\n}\n\nexport interface ClientMetadataFetcherOptions {\n\t/** Accepted client id hosts; empty = any. */\n\tallowedHosts?: readonly string[];\n\tlogger?: Logger;\n\ttimeoutMs?: number;\n\tmaxBytes?: number;\n\t/** Resolve a host name to its addresses (tests replace it). */\n\tlookup?: (hostname: string) => Promise<string[]>;\n\tfetch?: typeof fetch;\n\ttestMode?: CimdTestMode;\n\tnow?: () => number;\n}\n\nconst MAX_CLIENT_ID_LENGTH = 2048;\nconst MAX_NAME_LENGTH = 64;\nconst MAX_REDIRECT_URIS = 20;\nconst MIN_CACHE_MS = 5 * 60_000;\nconst DEFAULT_CACHE_MS = 60 * 60_000;\nconst MAX_CACHE_MS = 24 * 60 * 60_000;\nconst MAX_CACHE_ENTRIES = 1000;\n\nasync function defaultLookup(hostname: string): Promise<string[]> {\n\tconst records = await Bun.dns.lookup(hostname, {});\n\treturn records.map((r) => r.address);\n}\n\n/**\n * Invisible characters that are not format characters (`Cf`): Hangul and\n * other fillers, the braille blank, combining grapheme joiner, variation\n * selectors.\n */\nconst INVISIBLE =\n\t/[\\u034F\\u115F\\u1160\\u17B4\\u17B5\\u2800\\u3164\\uFFA0]|\\p{Variation_Selector}/gu;\n\n/**\n * Clean a self-declared name for display: control and line/paragraph\n * separators become spaces; format characters (`Cf`: zero-width, bidi,\n * word joiner, BOM, soft hyphen, …) and other invisible characters are\n * removed; whitespace collapses; at most 64 characters (DEC-065).\n */\nexport function displayName(raw: string): string {\n\tlet cleaned = raw\n\t\t.normalize(\"NFC\")\n\t\t.replace(/[\\p{Cc}\\p{Zl}\\p{Zp}]/gu, \" \")\n\t\t.replace(/\\p{Cf}/gu, \"\")\n\t\t.replace(INVISIBLE, \"\");\n\tcleaned = cleaned.replace(/\\s+/g, \" \").trim();\n\tconst chars = [...cleaned];\n\treturn chars.length > MAX_NAME_LENGTH\n\t\t? `${chars.slice(0, MAX_NAME_LENGTH - 1).join(\"\")}…`\n\t\t: cleaned;\n}\n\n/** Seconds of `max-age` in a Cache-Control header, or a marker. */\nfunction cacheMs(header: string | null): number {\n\tif (header === null) return DEFAULT_CACHE_MS;\n\tconst directives = header\n\t\t.toLowerCase()\n\t\t.split(\",\")\n\t\t.map((d) => d.trim());\n\tif (directives.includes(\"no-store\") || directives.includes(\"no-cache\")) {\n\t\treturn MIN_CACHE_MS;\n\t}\n\tconst maxAge = directives\n\t\t.map((d) => /^max-age=(\\d+)$/.exec(d)?.[1])\n\t\t.find((v) => v !== undefined);\n\tif (maxAge === undefined) return DEFAULT_CACHE_MS;\n\treturn Math.min(MAX_CACHE_MS, Math.max(MIN_CACHE_MS, Number(maxAge) * 1000));\n}\n\nfunction isIpLiteral(hostname: string): boolean {\n\tconst h = hostname.replace(/^\\[|\\]$/g, \"\");\n\treturn parseIpv4(h) !== undefined || parseIpv6(h) !== undefined;\n}\n\n/**\n * The key fetches are limited under (DEC-089): the last two labels of a host\n * name, so `*.evil.example` is one key however many subdomains it has; an IP\n * literal as is. Without the Public Suffix List, clients under a multi-label\n * suffix (`co.uk`, `pages.dev`) share one key, so many hosts there can slow\n * the others' uncached fetches; one host alone cannot (its own limit is lower).\n */\nexport function limitKey(hostname: string): string {\n\tconst h = hostname.replace(/^\\[|\\]$/g, \"\").replace(/\\.$/, \"\");\n\tif (isIpLiteral(h)) return h;\n\treturn h.split(\".\").slice(-2).join(\".\");\n}\n\n/** Fetches, validates and caches Client ID Metadata Documents. */\nexport class ClientMetadataFetcher {\n\treadonly #cache = new Map<string, { meta: ClientMetadata; until: number }>();\n\treadonly #perHost = new RateLimiter({ capacity: 5, refillPerSecond: 0.2 });\n\t/** Three hosts' worth: one host alone cannot use up its domain (DEC-089). */\n\treadonly #perDomain = new RateLimiter({ capacity: 15, refillPerSecond: 0.6 });\n\t/** All fetches together: many attacker-owned hosts cannot add up (DEC-061). */\n\treadonly #global = new RateLimiter({ capacity: 30, refillPerSecond: 1 });\n\treadonly #allowedHosts: readonly string[];\n\treadonly #logger: Logger | undefined;\n\treadonly #timeoutMs: number;\n\treadonly #maxBytes: number;\n\treadonly #lookup: (hostname: string) => Promise<string[]>;\n\treadonly #fetch: typeof fetch;\n\treadonly #testMode: CimdTestMode | undefined;\n\treadonly #now: () => number;\n\n\tconstructor(options: ClientMetadataFetcherOptions = {}) {\n\t\tthis.#allowedHosts = options.allowedHosts ?? [];\n\t\tthis.#logger = options.logger;\n\t\tthis.#timeoutMs = options.timeoutMs ?? 5000;\n\t\tthis.#maxBytes = options.maxBytes ?? 65_536;\n\t\tthis.#lookup = options.lookup ?? defaultLookup;\n\t\tthis.#fetch = options.fetch ?? fetch;\n\t\tthis.#testMode = options.testMode;\n\t\tthis.#now = options.now ?? Date.now;\n\t}\n\n\t/** The client's metadata, from the cache or freshly fetched. Throws `ClientMetadataError`. */\n\tasync get(clientId: string): Promise<ClientMetadata> {\n\t\tconst url = this.#checkUrl(clientId);\n\t\tconst now = this.#now();\n\t\tconst cached = this.#cache.get(clientId);\n\t\tif (cached !== undefined && cached.until > now) {\n\t\t\t// Least recently used first: a hit moves the entry to the end.\n\t\t\tthis.#cache.delete(clientId);\n\t\t\tthis.#cache.set(clientId, cached);\n\t\t\treturn cached.meta;\n\t\t}\n\t\t// Per host and per domain, and only charged once the global limit\n\t\t// admits the fetch: refusals cost the others nothing (DEC-089).\n\t\tconst key = limitKey(url.hostname);\n\t\tif (\n\t\t\t!this.#perHost.available(url.host, now) ||\n\t\t\t!this.#perDomain.available(key, now)\n\t\t) {\n\t\t\tthrow new ClientMetadataError(\n\t\t\t\t\"rate_limited\",\n\t\t\t\t\"Too many requests for this AI app's details. Try again in a minute.\",\n\t\t\t);\n\t\t}\n\t\tif (!this.#global.take(\"all\", now)) {\n\t\t\tthrow new ClientMetadataError(\n\t\t\t\t\"rate_limited\",\n\t\t\t\t\"The relay is busy. Try again in a minute.\",\n\t\t\t);\n\t\t}\n\t\tthis.#perHost.take(url.host, now);\n\t\tthis.#perDomain.take(key, now);\n\t\tconst address = await this.#vettedAddress(url);\n\t\tconst { meta, ttlMs } = await this.#fetchDocument(url, clientId, address);\n\t\tthis.#cache.delete(clientId);\n\t\tif (this.#cache.size >= MAX_CACHE_ENTRIES) {\n\t\t\tconst oldest = this.#cache.keys().next().value;\n\t\t\tif (oldest !== undefined) this.#cache.delete(oldest);\n\t\t}\n\t\tthis.#cache.set(clientId, { meta, until: now + ttlMs });\n\t\treturn meta;\n\t}\n\n\t/** The URL rules of the CIMD draft plus our SSRF rules, before any network use. */\n\t#checkUrl(clientId: string): URL {\n\t\tconst refuse = (message: string) =>\n\t\t\tnew ClientMetadataError(\"invalid_client_id\", message);\n\t\tif (clientId.length === 0 || clientId.length > MAX_CLIENT_ID_LENGTH) {\n\t\t\tthrow refuse(\"The AI app's client_id is missing or too long.\");\n\t\t}\n\t\tlet url: URL;\n\t\ttry {\n\t\t\turl = new URL(clientId);\n\t\t} catch {\n\t\t\tthrow refuse(\"The AI app's client_id is not a URL.\");\n\t\t}\n\t\tconst test = this.#testMode !== undefined;\n\t\tconst scheme =\n\t\t\turl.protocol === \"https:\" || (test && url.protocol === \"http:\");\n\t\tif (!scheme) {\n\t\t\tthrow refuse(\"The AI app's client_id must be an https:// URL.\");\n\t\t}\n\t\t// Canonical form only: this rejects dot segments, fragments' oddities,\n\t\t// an explicit default port, upper-case hosts and other aliases.\n\t\tif (url.href !== clientId) {\n\t\t\tthrow refuse(\"The AI app's client_id is not a canonical URL.\");\n\t\t}\n\t\tif (url.username !== \"\" || url.password !== \"\" || url.hash !== \"\") {\n\t\t\tthrow refuse(\n\t\t\t\t\"The AI app's client_id must not contain credentials or a fragment.\",\n\t\t\t);\n\t\t}\n\t\tif (url.pathname === \"/\" || url.pathname === \"\") {\n\t\t\tthrow refuse(\"The AI app's client_id must have a path.\");\n\t\t}\n\t\tif (url.port !== \"\" && !test) {\n\t\t\tthrow refuse(\"The AI app's client_id must use the default port.\");\n\t\t}\n\t\tif (\n\t\t\tthis.#allowedHosts.length > 0 &&\n\t\t\t!this.#allowedHosts.includes(url.host)\n\t\t) {\n\t\t\tthrow new ClientMetadataError(\n\t\t\t\t\"host_not_allowed\",\n\t\t\t\t`This relay does not accept AI apps from ${url.host}.`,\n\t\t\t);\n\t\t}\n\t\tif (isIpLiteral(url.hostname) && !this.#addressAllowed(url.hostname)) {\n\t\t\tthrow this.#notLoaded(\"private_address\", url);\n\t\t}\n\t\treturn url;\n\t}\n\n\t#addressAllowed(address: string): boolean {\n\t\tif (isPublicIp(address)) return true;\n\t\treturn this.#testMode !== undefined && isLoopbackHost(address);\n\t}\n\n\t/**\n\t * One fixed message for every failure from resolving to parsing, so the\n\t * page tells nothing about what answered (threat model A3, DEC-066). The\n\t * reason goes to the log.\n\t */\n\t#notLoaded(reason: string, url: URL, detail = reason): ClientMetadataError {\n\t\tthis.#logger?.info(\"oauth.cimd_failed\", { host: url.host, reason: detail });\n\t\treturn new ClientMetadataError(\n\t\t\treason,\n\t\t\t`The AI app's details could not be loaded from ${url.host}.`,\n\t\t);\n\t}\n\n\t/**\n\t * Resolve the host, refuse it if any address is not public, and return the\n\t * address to connect to (IPv4 first). The fetch is pinned to it, so a DNS\n\t * answer that changes between check and connect is never used.\n\t */\n\tasync #vettedAddress(url: URL): Promise<string> {\n\t\tconst hostname = url.hostname.replace(/^\\[|\\]$/g, \"\");\n\t\tif (isIpLiteral(hostname)) return hostname; // checked in #checkUrl\n\t\tlet addresses: string[];\n\t\ttry {\n\t\t\taddresses = await this.#lookup(hostname);\n\t\t} catch {\n\t\t\tthrow this.#notLoaded(\"unresolvable\", url);\n\t\t}\n\t\tif (\n\t\t\taddresses.length === 0 ||\n\t\t\t!addresses.every((a) => this.#addressAllowed(a))\n\t\t) {\n\t\t\tthrow this.#notLoaded(\"private_address\", url);\n\t\t}\n\t\treturn (\n\t\t\taddresses.find((a) => parseIpv4(a) !== undefined) ?? addresses[0] ?? \"\"\n\t\t);\n\t}\n\n\tasync #fetchDocument(\n\t\turl: URL,\n\t\tclientId: string,\n\t\taddress: string,\n\t): Promise<{ meta: ClientMetadata; ttlMs: number }> {\n\t\tconst fail = (detail: string) =>\n\t\t\tthis.#notLoaded(\"fetch_failed\", url, detail);\n\t\t// Connect to the vetted address; Host and the TLS server name stay the\n\t\t// original host, so the certificate is checked against it.\n\t\tconst pinned = new URL(clientId);\n\t\tpinned.hostname = address.includes(\":\") ? `[${address}]` : address;\n\t\tconst hostname = url.hostname.replace(/^\\[|\\]$/g, \"\");\n\t\tconst tls =\n\t\t\turl.protocol === \"https:\"\n\t\t\t\t? {\n\t\t\t\t\t\ttls: {\n\t\t\t\t\t\t\t...(isIpLiteral(hostname) ? {} : { serverName: hostname }),\n\t\t\t\t\t\t\t...(this.#testMode?.ca === undefined\n\t\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t\t: { ca: this.#testMode.ca }),\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t: {};\n\t\tlet response: Response;\n\t\ttry {\n\t\t\tresponse = await this.#fetch(pinned.href, {\n\t\t\t\tmethod: \"GET\",\n\t\t\t\tredirect: \"manual\",\n\t\t\t\theaders: { accept: \"application/json\", host: url.host },\n\t\t\t\tsignal: AbortSignal.timeout(this.#timeoutMs),\n\t\t\t\t...tls,\n\t\t\t} as RequestInit);\n\t\t} catch (error) {\n\t\t\tthrow fail(\n\t\t\t\t`fetch_failed:${error instanceof Error ? error.name : \"unknown\"}`,\n\t\t\t);\n\t\t}\n\t\ttry {\n\t\t\tif (response.status !== 200) throw fail(`status_${response.status}`);\n\t\t\tconst type = (response.headers.get(\"content-type\") ?? \"\")\n\t\t\t\t.split(\";\")[0]\n\t\t\t\t?.trim()\n\t\t\t\t.toLowerCase();\n\t\t\tif (type !== \"application/json\") throw fail(\"not_json\");\n\t\t\tconst text = await this.#readLimited(response, url);\n\t\t\tlet doc: unknown;\n\t\t\ttry {\n\t\t\t\tdoc = JSON.parse(text);\n\t\t\t} catch {\n\t\t\t\tthrow fail(\"bad_json\");\n\t\t\t}\n\t\t\tconst meta = validateDocument(doc, clientId, url);\n\t\t\treturn { meta, ttlMs: cacheMs(response.headers.get(\"cache-control\")) };\n\t\t} finally {\n\t\t\tif (!response.bodyUsed) response.body?.cancel().catch(() => {});\n\t\t}\n\t}\n\n\tasync #readLimited(response: Response, url: URL): Promise<string> {\n\t\tconst tooLarge = () => this.#notLoaded(\"too_large\", url);\n\t\tconst length = Number(response.headers.get(\"content-length\") ?? \"0\");\n\t\tif (length > this.#maxBytes) throw tooLarge();\n\t\tconst reader = response.body?.getReader();\n\t\tif (reader === undefined) return \"\";\n\t\tconst chunks: Uint8Array[] = [];\n\t\tlet total = 0;\n\t\tfor (;;) {\n\t\t\tconst { done, value } = await reader.read();\n\t\t\tif (done) break;\n\t\t\ttotal += value.byteLength;\n\t\t\tif (total > this.#maxBytes) {\n\t\t\t\tawait reader.cancel().catch(() => {});\n\t\t\t\tthrow tooLarge();\n\t\t\t}\n\t\t\tchunks.push(value);\n\t\t}\n\t\ttry {\n\t\t\treturn new TextDecoder(\"utf-8\", { fatal: true }).decode(\n\t\t\t\tBuffer.concat(chunks),\n\t\t\t);\n\t\t} catch {\n\t\t\tthrow this.#notLoaded(\"fetch_failed\", url, \"bad_utf8\");\n\t\t}\n\t}\n}\n\n/** Labels separated by dots, ending in a label of 2-63 letters: `claude.ai`, `x.co.uk`. */\nconst DOMAIN_SHAPED =\n\t/(?:[\\p{L}\\p{N}](?:[\\p{L}\\p{N}-]*[\\p{L}\\p{N}])?\\.)+\\p{L}{2,63}(?![\\p{L}\\p{N}])/gu;\n\n/**\n * A name as the address checks read it: compatibility forms folded (NFKC),\n * combining marks removed, so \"claude.a̲i\" reads \"claude.ai\", the\n * ideographic full stops browsers read as dots made dots, lower case.\n */\nfunction comparable(name: string): string {\n\treturn name\n\t\t.normalize(\"NFKC\")\n\t\t.replace(/\\p{M}/gu, \"\")\n\t\t.replace(/[。.。]/g, \".\")\n\t\t.toLowerCase();\n}\n\n/** A host name in its ASCII (punycode) form, as `URL` gives it. */\nfunction asciiHost(token: string): string {\n\ttry {\n\t\treturn new URL(`https://${token}/`).hostname;\n\t} catch {\n\t\treturn token;\n\t}\n}\n\n/**\n * Whether a name contains a domain-shaped token that is not the verified\n * host, a subdomain of it or a parent of it (DEC-092). Internationalised\n * names are compared in their ASCII form, as the host is.\n */\nexport function foreignDomain(name: string, hostname: string): boolean {\n\tconst host = hostname.toLowerCase();\n\tfor (const [match] of comparable(name).matchAll(DOMAIN_SHAPED)) {\n\t\tconst token = asciiHost(match);\n\t\tconst own =\n\t\t\ttoken === host ||\n\t\t\thost.endsWith(`.${token}`) ||\n\t\t\ttoken.endsWith(`.${host}`);\n\t\tif (!own) return true;\n\t}\n\treturn false;\n}\n\n/** Check a fetched document against the CIMD rules and what the relay supports. */\nexport function validateDocument(\n\tdoc: unknown,\n\tclientId: string,\n\turl: URL,\n): ClientMetadata {\n\tconst invalid = (message: string) =>\n\t\tnew ClientMetadataError(\"invalid_metadata\", message);\n\tif (typeof doc !== \"object\" || doc === null || Array.isArray(doc)) {\n\t\tthrow invalid(\"The AI app's details are not a JSON object.\");\n\t}\n\tconst d = doc as Record<string, unknown>;\n\tif (d[\"client_id\"] !== clientId) {\n\t\tthrow invalid(\"The AI app's details name a different client_id.\");\n\t}\n\tif (\n\t\td[\"client_secret\"] !== undefined ||\n\t\td[\"client_secret_expires_at\"] !== undefined\n\t) {\n\t\tthrow invalid(\"The AI app's details must not contain a client secret.\");\n\t}\n\tconst name = d[\"client_name\"];\n\tif (typeof name !== \"string\" || displayName(name) === \"\") {\n\t\tthrow invalid(\"The AI app's details have no client_name.\");\n\t}\n\t// \"Claude (claude.ai)\" from evil.example would read like a verified host.\n\tif (\n\t\t/\\(\\s*[^()\\s]*[a-z0-9-]\\.[a-z]{2,}[^()]*\\)/i.test(\n\t\t\tcomparable(displayName(name)),\n\t\t)\n\t) {\n\t\tthrow invalid(\n\t\t\t\"The AI app's name contains a web address in parentheses, which this relay does not show.\",\n\t\t);\n\t}\n\t// \"Claude · claude.ai\" from evil.example reads the same way (DEC-092).\n\tif (foreignDomain(displayName(name), url.hostname)) {\n\t\tthrow invalid(\n\t\t\t\"The AI app's name contains a web address other than its own, which this relay does not show.\",\n\t\t);\n\t}\n\tconst uris = d[\"redirect_uris\"];\n\tif (\n\t\t!Array.isArray(uris) ||\n\t\turis.length === 0 ||\n\t\turis.length > MAX_REDIRECT_URIS ||\n\t\t!uris.every((u) => typeof u === \"string\" && isRedirectUri(u))\n\t) {\n\t\tthrow invalid(\"The AI app's details have no valid redirect_uris.\");\n\t}\n\t// The method the app will use; an app that prefers another but lists\n\t// \"none\" among the methods it supports (ChatGPT: private_key_jwt, with\n\t// [\"none\", \"private_key_jwt\"]) uses \"none\" here, the only one this\n\t// relay's metadata offers (DEC-104).\n\tconst method = d[\"token_endpoint_auth_method\"];\n\tconst supported = d[\"token_endpoint_auth_methods_supported\"];\n\tif (\n\t\tmethod !== undefined &&\n\t\tmethod !== \"none\" &&\n\t\t!(Array.isArray(supported) && supported.includes(\"none\"))\n\t) {\n\t\tthrow invalid(\n\t\t\t'The AI app must use token_endpoint_auth_method \"none\" with this relay, or list \"none\" in token_endpoint_auth_methods_supported.',\n\t\t);\n\t}\n\tconst grants = d[\"grant_types\"];\n\tif (\n\t\tgrants !== undefined &&\n\t\t(!Array.isArray(grants) || !grants.includes(\"authorization_code\"))\n\t) {\n\t\tthrow invalid(\n\t\t\t\"The AI app's details do not allow the authorization code grant.\",\n\t\t);\n\t}\n\tconst responses = d[\"response_types\"];\n\tif (\n\t\tresponses !== undefined &&\n\t\t(!Array.isArray(responses) || !responses.includes(\"code\"))\n\t) {\n\t\tthrow invalid('The AI app\\'s details do not allow response type \"code\".');\n\t}\n\treturn {\n\t\tclientId,\n\t\tname: displayName(name),\n\t\thost: url.host,\n\t\tredirectUris: uris as string[],\n\t};\n}\n\n/** A private-use URI scheme in reverse-domain form (RFC 8252 §7.1), e.g. `com.example.app:`. */\nconst PRIVATE_USE_SCHEME = /^[a-z][a-z0-9+-]*(\\.[a-z0-9+-]+)+:$/;\n\n/**\n * A redirect URI the relay accepts (DEC-067): absolute, no fragment or\n * credentials, and `https:`; `http:` only for loopback hosts (RFC 8252 §7.3);\n * or a reverse-domain private-use scheme for native apps (RFC 8252 §7.1).\n * Everything else (`file:`, `blob:`, `data:`, `javascript:`, plain `http:`,\n * one-word custom schemes) is refused.\n */\nexport function isRedirectUri(value: string): boolean {\n\tif (value.length > 2048 || value.includes(\"#\")) return false;\n\tlet u: URL;\n\ttry {\n\t\tu = new URL(value);\n\t} catch {\n\t\treturn false;\n\t}\n\tif (u.username !== \"\" || u.password !== \"\") return false;\n\tif (u.protocol === \"https:\") return u.hostname !== \"\";\n\tif (u.protocol === \"http:\") return LOOPBACK_REDIRECT_HOSTS.has(u.hostname);\n\treturn PRIVATE_USE_SCHEME.test(u.protocol);\n}\n\nconst LOOPBACK_REDIRECT_HOSTS = new Set([\"localhost\", \"127.0.0.1\", \"[::1]\"]);\n\n/**\n * Whether a requested redirect URI matches a registered one: exact string\n * equality, except that for an `http:` loopback redirect the port is ignored\n * (RFC 8252 §7.3; OAuth 2.1 §8.4.2). Host, path and query must still match.\n */\nexport function redirectUriMatches(\n\trequested: string,\n\tregistered: string,\n): boolean {\n\tif (requested === registered) return true;\n\tlet a: URL;\n\tlet b: URL;\n\ttry {\n\t\ta = new URL(requested);\n\t\tb = new URL(registered);\n\t} catch {\n\t\treturn false;\n\t}\n\tif (a.protocol !== \"http:\" || b.protocol !== \"http:\") return false;\n\tif (!LOOPBACK_REDIRECT_HOSTS.has(b.hostname) || a.hostname !== b.hostname) {\n\t\treturn false;\n\t}\n\t// The requested URI must be in canonical form, so the parser cannot\n\t// have changed what the comparison sees (dot segments, case, …).\n\tif (\n\t\ta.href !== requested ||\n\t\ta.username !== \"\" ||\n\t\ta.password !== \"\" ||\n\t\ta.hash !== \"\"\n\t) {\n\t\treturn false;\n\t}\n\ta.port = \"\";\n\tb.port = \"\";\n\treturn a.href === b.href;\n}\n",
19
+ "/**\n * Server-rendered HTML for `/authorize` (threat model A7): every value is\n * escaped, the page has no scripts, and its headers forbid framing, inline\n * code and foreign form targets.\n */\n\nconst ESCAPES: Record<string, string> = {\n\t\"&\": \"&amp;\",\n\t\"<\": \"&lt;\",\n\t\">\": \"&gt;\",\n\t'\"': \"&quot;\",\n\t\"'\": \"&#39;\",\n};\n\n/** Escape text for HTML element content and quoted attribute values. */\nexport function escapeHtml(text: string): string {\n\treturn text.replace(/[&<>\"']/g, (c) => ESCAPES[c] ?? c);\n}\n\n/** The stylesheet at `/authorize.css` (`style-src 'self'`). */\nexport const AUTHORIZE_CSS = `:root { color-scheme: light dark; --accent: #1d4ed8; --error: #b91c1c; }\n@media (prefers-color-scheme: dark) { :root { --accent: #93b4ff; --error: #fca5a5; } }\n* { box-sizing: border-box; }\nbody { margin: 0; font: 1rem/1.5 system-ui, -apple-system, \"Segoe UI\", sans-serif; background: Canvas; color: CanvasText; }\nmain { max-width: 34rem; margin: 3rem auto; padding: 0 1rem; }\nh1 { font-size: 1.5rem; line-height: 1.25; margin: 0 0 1rem; }\np { margin: 0 0 1rem; }\ncode, .origin { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; overflow-wrap: anywhere; }\n.help { color: GrayText; font-size: 0.9rem; }\n.error { color: var(--error); font-weight: 600; }\nlabel { display: block; font-weight: 600; margin-bottom: 0.25rem; }\ninput[type=\"text\"] { font: 1.5rem/1.2 ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: 0.2em; width: 10ch; padding: 0.4rem 0.5rem; border: 2px solid GrayText; border-radius: 0.4rem; background: Field; color: FieldText; }\ninput[type=\"text\"]:focus-visible, button:focus-visible, a:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }\n.actions { display: flex; gap: 0.75rem; flex-wrap: wrap; margin: 1.5rem 0 1.25rem; }\nbutton, .button { font: inherit; padding: 0.5rem 1.25rem; border-radius: 0.4rem; border: 2px solid var(--accent); cursor: pointer; text-decoration: none; display: inline-block; }\nbutton.primary, .button.primary { background: var(--accent); color: Canvas; }\nbutton.secondary, .button:not(.primary) { background: transparent; color: var(--accent); }\nfooter { margin-top: 2.5rem; font-size: 0.85rem; color: GrayText; }\n`;\n\n/** Security headers of every `/authorize` response. */\nexport function pageHeaders(formTargets: readonly string[] = []): Headers {\n\t// Chrome applies form-action to the redirect after a POST, so the client's\n\t// redirect origin must be allowed explicitly.\n\tconst formAction = [\"'self'\", ...formTargets].join(\" \");\n\treturn new Headers({\n\t\t\"content-type\": \"text/html; charset=utf-8\",\n\t\t\"content-security-policy\": `default-src 'none'; style-src 'self'; img-src 'self'; base-uri 'none'; frame-ancestors 'none'; form-action ${formAction}`,\n\t\t\"x-frame-options\": \"DENY\",\n\t\t\"x-content-type-options\": \"nosniff\",\n\t\t// Not no-referrer: browsers then send `Origin: null` on the form post,\n\t\t// which the origin check must refuse. same-origin still sends nothing\n\t\t// to the client's redirect.\n\t\t\"referrer-policy\": \"same-origin\",\n\t\t\"cache-control\": \"no-store\",\n\t});\n}\n\n/** A complete page; `body` must already be escaped. */\nexport function renderPage(title: string, body: string): string {\n\treturn `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<meta name=\"robots\" content=\"noindex\">\n<title>${escapeHtml(title)}</title>\n<link rel=\"stylesheet\" href=\"/authorize.css\">\n<link rel=\"icon\" href=\"/favicon.ico\" sizes=\"32x32\">\n<link rel=\"icon\" href=\"/favicon.svg\" type=\"image/svg+xml\">\n<link rel=\"apple-touch-icon\" href=\"/apple-touch-icon.png\">\n</head>\n<body>\n<main>\n${body}\n<footer>tab-mcp relay. It passes requests between AI apps and web pages and does not store their contents.</footer>\n</main>\n</body>\n</html>`;\n}\n",
19
20
  "/**\n * The OIDC pairing method (DEC-075, DEC-079): at `/authorize` the user signs in\n * at the configured OpenID Connect provider, and the relay pairs the AI app if\n * that person is the page's user. The relay is an ordinary OIDC client there\n * (authorization code flow, PKCE S256, `state`, `nonce`).\n */\n\nimport type { OidcConfig } from \"../config.ts\";\nimport { CLOCK_LEEWAY_MS, identityKey, MISMATCH_TEXT } from \"../identity.ts\";\nimport {\n\taudiences,\n\tfetchJson,\n\tHttpJsonError,\n\tJwksCache,\n\tJwtError,\n\tnumericDate,\n\tverifyJwt,\n} from \"../jwt.ts\";\nimport type { Logger } from \"../log.ts\";\nimport { escapeHtml } from \"./html.ts\";\nimport type {\n\tPairingContext,\n\tPairingMethod,\n\tPairingResult,\n\tPairingTarget,\n} from \"./pairing.ts\";\n\n/** How long a sign-in at the provider may take (the pending request lives 10 minutes). */\nconst FLOW_TTL_MS = 10 * 60_000;\nconst MAX_FLOWS = 10_000;\nconst METADATA_TTL_MS = 60 * 60_000;\nconst MAX_TOKEN_RESPONSE_BYTES = 65_536;\n\n/** The provider's metadata the relay uses (OIDC Discovery §3). */\nexport interface ProviderMetadata {\n\tissuer: string;\n\tauthorizationEndpoint: string;\n\ttokenEndpoint: string;\n\tjwksUri: string;\n\t/** `client_secret_basic` (default) or `client_secret_post`. */\n\ttokenAuth: \"client_secret_basic\" | \"client_secret_post\";\n}\n\ninterface Flow {\n\trequestId: string;\n\tbrowserId: string;\n\tnonce: string;\n\tverifier: string;\n\texpiresAt: number;\n}\n\nexport class OidcError extends Error {\n\toverride name = \"OidcError\";\n\treadonly reason: string;\n\tconstructor(reason: string, message: string) {\n\t\tsuper(message);\n\t\tthis.reason = reason;\n\t}\n}\n\nfunction random(bytes: number): string {\n\treturn crypto\n\t\t.getRandomValues(new Uint8Array(bytes))\n\t\t.toBase64({ alphabet: \"base64url\", omitPadding: true });\n}\n\nfunction s256(verifier: string): string {\n\treturn new Bun.CryptoHasher(\"sha256\")\n\t\t.update(verifier)\n\t\t.digest()\n\t\t.toBase64({ alphabet: \"base64url\", omitPadding: true });\n}\n\nfunction str(v: unknown): string | undefined {\n\treturn typeof v === \"string\" && v !== \"\" ? v : undefined;\n}\n\nfunction originOf(url: string): string | undefined {\n\ttry {\n\t\treturn new URL(url).origin;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/** Discovery for the configured issuer, cached an hour (OIDC Discovery §4). */\nexport class ProviderDiscovery {\n\treadonly #issuer: string;\n\treadonly #development: boolean;\n\t#metadata: ProviderMetadata | undefined;\n\t#fetchedAt = 0;\n\t#inflight: Promise<ProviderMetadata> | undefined;\n\n\tconstructor(issuer: string, development: boolean) {\n\t\tthis.#issuer = issuer;\n\t\tthis.#development = development;\n\t}\n\n\t/** The cached metadata, if loaded. */\n\tget cached(): ProviderMetadata | undefined {\n\t\treturn this.#metadata;\n\t}\n\n\tasync get(): Promise<ProviderMetadata> {\n\t\tif (\n\t\t\tthis.#metadata !== undefined &&\n\t\t\tDate.now() - this.#fetchedAt < METADATA_TTL_MS\n\t\t) {\n\t\t\treturn this.#metadata;\n\t\t}\n\t\tthis.#inflight ??= this.#load().finally(() => {\n\t\t\tthis.#inflight = undefined;\n\t\t});\n\t\treturn this.#inflight;\n\t}\n\n\tasync #load(): Promise<ProviderMetadata> {\n\t\tconst url = `${this.#issuer.replace(/\\/+$/, \"\")}/.well-known/openid-configuration`;\n\t\tconst doc = (await fetchJson(url)) as Record<string, unknown> | null;\n\t\tif (typeof doc !== \"object\" || doc === null) {\n\t\t\tthrow new OidcError(\n\t\t\t\t\"discovery\",\n\t\t\t\t\"the provider's metadata is not an object\",\n\t\t\t);\n\t\t}\n\t\t// OIDC Discovery §4.3: the issuer must be exactly the configured one.\n\t\tif (doc[\"issuer\"] !== this.#issuer) {\n\t\t\tthrow new OidcError(\n\t\t\t\t\"discovery_issuer\",\n\t\t\t\t\"the provider's metadata names another issuer\",\n\t\t\t);\n\t\t}\n\t\tconst endpoint = (name: string): string => {\n\t\t\tconst v = str(doc[name]);\n\t\t\tconst ok =\n\t\t\t\tv !== undefined &&\n\t\t\t\t(v.startsWith(\"https://\") ||\n\t\t\t\t\t(this.#development && v.startsWith(\"http://\")));\n\t\t\tif (!ok) {\n\t\t\t\tthrow new OidcError(\n\t\t\t\t\t\"discovery\",\n\t\t\t\t\t`the provider's metadata lacks ${name}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn v;\n\t\t};\n\t\tconst methods = doc[\"token_endpoint_auth_methods_supported\"];\n\t\tconst tokenAuth =\n\t\t\tArray.isArray(methods) &&\n\t\t\t!methods.includes(\"client_secret_basic\") &&\n\t\t\tmethods.includes(\"client_secret_post\")\n\t\t\t\t? \"client_secret_post\"\n\t\t\t\t: \"client_secret_basic\";\n\t\tconst metadata: ProviderMetadata = {\n\t\t\tissuer: this.#issuer,\n\t\t\tauthorizationEndpoint: endpoint(\"authorization_endpoint\"),\n\t\t\ttokenEndpoint: endpoint(\"token_endpoint\"),\n\t\t\tjwksUri: endpoint(\"jwks_uri\"),\n\t\t\ttokenAuth,\n\t\t};\n\t\tthis.#metadata = metadata;\n\t\tthis.#fetchedAt = Date.now();\n\t\treturn metadata;\n\t}\n}\n\nexport interface OidcPairingOptions {\n\tconfig: OidcConfig;\n\t/** The relay's public URL (the callback is `<url>/authorize/callback`). */\n\tpublicUrl: () => string;\n\tlogger: Logger;\n\tdevelopment: boolean;\n\t/** At most this many open sign-ins (tests lower it). */\n\tmaxFlows?: number;\n}\n\n/** The identity-binding pairing method. */\nexport class OidcPairing implements PairingMethod {\n\treadonly kind = \"oidc\" as const;\n\treadonly #config: OidcConfig;\n\treadonly #maxFlows: number;\n\treadonly #publicUrl: () => string;\n\treadonly #logger: Logger;\n\treadonly #discovery: ProviderDiscovery;\n\treadonly #jwks: JwksCache;\n\t/** state → flow; insertion order is expiry order. */\n\treadonly #flows = new Map<string, Flow>();\n\t/**\n\t * Pending request → its one flow's state (DEC-090): a new Connect\n\t * replaces the earlier sign-in, so flows are bounded by the pending\n\t * requests, which are capped per network and per address.\n\t */\n\treadonly #flowOf = new Map<string, string>();\n\t/** Requests that met a mismatch: the next sign-in asks for the account again. */\n\treadonly #mismatched = new Set<string>();\n\n\tconstructor(options: OidcPairingOptions) {\n\t\tthis.#config = options.config;\n\t\tthis.#maxFlows = options.maxFlows ?? MAX_FLOWS;\n\t\tthis.#publicUrl = options.publicUrl;\n\t\tthis.#logger = options.logger;\n\t\tthis.#discovery = new ProviderDiscovery(\n\t\t\toptions.config.issuer,\n\t\t\toptions.development,\n\t\t);\n\t\tthis.#jwks = new JwksCache(\n\t\t\tasync () => (await this.#discovery.get()).jwksUri,\n\t\t);\n\t}\n\n\tget #providerHost(): string {\n\t\ttry {\n\t\t\treturn new URL(this.#config.issuer).host;\n\t\t} catch {\n\t\t\treturn this.#config.issuer;\n\t\t}\n\t}\n\n\tget callbackUrl(): string {\n\t\treturn `${this.#publicUrl()}/authorize/callback`;\n\t}\n\n\t/** Load the provider's metadata before the page is shown. */\n\tasync prepare(): Promise<void> {\n\t\tawait this.#discovery.get();\n\t}\n\n\t/** The provider's origins, for the page's CSP `form-action` (the redirect after the post). */\n\tformTargets(): string[] {\n\t\tconst out = new Set<string>();\n\t\tconst issuer = originOf(this.#config.issuer);\n\t\tif (issuer !== undefined) out.add(issuer);\n\t\tconst auth = this.#discovery.cached?.authorizationEndpoint;\n\t\tconst origin = auth === undefined ? undefined : originOf(auth);\n\t\tif (origin !== undefined) out.add(origin);\n\t\treturn [...out];\n\t}\n\n\trender(target: PairingTarget): string {\n\t\tconst host = escapeHtml(this.#providerHost);\n\t\tif (target.identity === undefined) {\n\t\t\treturn `<p class=\"help\">Nobody is signed in to the page. Sign in there first, then click Connect.</p>`;\n\t\t}\n\t\treturn `<p>When you click Connect, sign in at <strong>${host}</strong> with the account you use in the page. No code is needed.</p>`;\n\t}\n\n\tasync check(\n\t\ttarget: PairingTarget,\n\t\t_form: URLSearchParams,\n\t\tadmit: () => boolean,\n\t\tcontext?: PairingContext,\n\t): Promise<PairingResult> {\n\t\tif (!target.pairingOpen) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\tmessage:\n\t\t\t\t\t\"The page is not connecting right now. In the page, open “Connect your AI app”, then click Connect here again.\",\n\t\t\t\treason: \"inactive\",\n\t\t\t};\n\t\t}\n\t\tif (target.identity === undefined) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\tmessage:\n\t\t\t\t\t\"Nobody is signed in to the page. Sign in there first, then click Connect here again.\",\n\t\t\t\treason: \"signed_out\",\n\t\t\t};\n\t\t}\n\t\tif (context === undefined) {\n\t\t\treturn { ok: false, message: \"Something went wrong.\", reason: \"context\" };\n\t\t}\n\t\tlet metadata: ProviderMetadata;\n\t\ttry {\n\t\t\tmetadata = await this.#discovery.get();\n\t\t} catch (error) {\n\t\t\treturn this.#unavailable(error);\n\t\t}\n\t\tthis.#sweep();\n\t\tthis.#dropFlow(context.requestId);\n\t\tif (this.#flows.size >= this.#maxFlows) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\tmessage:\n\t\t\t\t\t\"Too many sign-ins are open right now. Wait a few minutes and try again.\",\n\t\t\t\treason: \"busy\",\n\t\t\t};\n\t\t}\n\t\t// A sign-in could pair: charged like a code guess (DEC-061, DEC-090),\n\t\t// and only once one can start.\n\t\tif (!admit()) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\tmessage:\n\t\t\t\t\t\"Too many attempts for this page. Wait a few minutes and try again.\",\n\t\t\t\treason: \"rate_limited\",\n\t\t\t};\n\t\t}\n\t\t// The provider sends the state back to /authorize/callback, whose URL is\n\t\t// fixed: the address id in front lets a load balancer route the callback\n\t\t// to this instance, which holds the flow (DEC-098).\n\t\tconst state = `${context.addressId}.${random(24)}`;\n\t\tconst nonce = random(24);\n\t\tconst verifier = random(32);\n\t\tthis.#flowOf.set(context.requestId, state);\n\t\tthis.#flows.set(state, {\n\t\t\trequestId: context.requestId,\n\t\t\tbrowserId: context.browserId,\n\t\t\tnonce,\n\t\t\tverifier,\n\t\t\texpiresAt: Date.now() + FLOW_TTL_MS,\n\t\t});\n\t\tconst url = new URL(metadata.authorizationEndpoint);\n\t\tconst params: Record<string, string> = {\n\t\t\tresponse_type: \"code\",\n\t\t\tclient_id: this.#config.clientId,\n\t\t\tredirect_uri: this.callbackUrl,\n\t\t\tscope: \"openid\",\n\t\t\tstate,\n\t\t\tnonce,\n\t\t\tcode_challenge: s256(verifier),\n\t\t\tcode_challenge_method: \"S256\",\n\t\t};\n\t\tif (this.#mismatched.has(context.requestId)) params[\"prompt\"] = \"login\";\n\t\tfor (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);\n\t\treturn { ok: \"redirect\", location: url.href };\n\t}\n\n\t/**\n\t * The provider sent the browser back. Returns the pending request the\n\t * sign-in belongs to (if the state is known) and the result.\n\t */\n\tasync callback(\n\t\tparams: URLSearchParams,\n\t\tbrowserId: string,\n\t\ttargetFor: (requestId: string) => PairingTarget | undefined,\n\t): Promise<{ requestId?: string; result: PairingResult }> {\n\t\tthis.#sweep();\n\t\tconst state = params.get(\"state\") ?? \"\";\n\t\tconst flow = this.#flows.get(state);\n\t\tif (flow === undefined || flow.expiresAt <= Date.now()) {\n\t\t\treturn {\n\t\t\t\tresult: {\n\t\t\t\t\tok: false,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\t\"This sign-in has expired or was already used. Start again from your AI app.\",\n\t\t\t\t\treason: \"unknown_state\",\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tthis.#flows.delete(state); // single use\n\t\tconst requestId = flow.requestId;\n\t\tthis.#flowOf.delete(requestId);\n\t\tconst fail = (reason: string, message: string) => ({\n\t\t\trequestId,\n\t\t\tresult: { ok: false as const, message, reason },\n\t\t});\n\t\tif (flow.browserId !== browserId) {\n\t\t\treturn fail(\n\t\t\t\t\"browser\",\n\t\t\t\t\"This sign-in was started in another browser. Start again from your AI app.\",\n\t\t\t);\n\t\t}\n\t\t// RFC 9207: a provider that names itself must be the configured one.\n\t\tconst iss = params.get(\"iss\");\n\t\tif (iss !== null && iss !== this.#config.issuer) {\n\t\t\treturn fail(\"iss\", \"The sign-in came back from an unexpected provider.\");\n\t\t}\n\t\tconst error = params.get(\"error\");\n\t\tif (error !== null) {\n\t\t\tthis.#logger.info(\"oidc.provider_error\", { error: error.slice(0, 64) });\n\t\t\treturn fail(\n\t\t\t\t`provider_${error.slice(0, 32)}`,\n\t\t\t\t`The sign-in at ${this.#providerHost} did not finish. Click Connect to try again.`,\n\t\t\t);\n\t\t}\n\t\tconst code = params.get(\"code\");\n\t\tif (code === null || code === \"\") {\n\t\t\treturn fail(\n\t\t\t\t\"no_code\",\n\t\t\t\t\"The provider sent no sign-in result. Click Connect to try again.\",\n\t\t\t);\n\t\t}\n\t\tlet subject: string;\n\t\ttry {\n\t\t\tsubject = await this.#signIn(code, flow);\n\t\t} catch (e) {\n\t\t\tconst reason =\n\t\t\t\te instanceof OidcError || e instanceof JwtError ? e.reason : \"exchange\";\n\t\t\tthis.#logger.warn(\"oidc.sign_in_failed\", {\n\t\t\t\treason,\n\t\t\t\tmessage: e instanceof Error ? e.message.slice(0, 200) : \"unknown\",\n\t\t\t});\n\t\t\treturn fail(\n\t\t\t\treason,\n\t\t\t\t`The sign-in at ${this.#providerHost} could not be checked. Click Connect to try again.`,\n\t\t\t);\n\t\t}\n\t\t// Compared now, so a page that signed out meanwhile pairs nobody.\n\t\tconst target = targetFor(requestId);\n\t\tif (target === undefined) {\n\t\t\treturn fail(\n\t\t\t\t\"page_closed\",\n\t\t\t\t\"The page is not open any more. Open it and try again.\",\n\t\t\t);\n\t\t}\n\t\tif (target.identity === undefined) {\n\t\t\treturn fail(\n\t\t\t\t\"signed_out\",\n\t\t\t\t\"Nobody is signed in to the page any more. Sign in there first, then click Connect here again.\",\n\t\t\t);\n\t\t}\n\t\tconst key = identityKey(this.#config.issuer, subject);\n\t\tif (key !== target.identity) {\n\t\t\tthis.#mismatched.add(requestId);\n\t\t\tif (this.#mismatched.size > MAX_FLOWS) {\n\t\t\t\tconst oldest = this.#mismatched.values().next().value;\n\t\t\t\tif (oldest !== undefined) this.#mismatched.delete(oldest);\n\t\t\t}\n\t\t\treturn fail(\n\t\t\t\t\"mismatch\",\n\t\t\t\t`${MISMATCH_TEXT} Click Connect to sign in with the page's account, or Cancel.`,\n\t\t\t);\n\t\t}\n\t\tthis.#mismatched.delete(requestId);\n\t\treturn { requestId, result: { ok: true, subject: key } };\n\t}\n\n\t/** Exchange the code and validate the ID token (OIDC Core §3.1.3.7); returns the subject. */\n\tasync #signIn(code: string, flow: Flow): Promise<string> {\n\t\tconst metadata = await this.#discovery.get();\n\t\tconst body = new URLSearchParams({\n\t\t\tgrant_type: \"authorization_code\",\n\t\t\tcode,\n\t\t\tredirect_uri: this.callbackUrl,\n\t\t\tcode_verifier: flow.verifier,\n\t\t});\n\t\tconst headers: Record<string, string> = {\n\t\t\t\"content-type\": \"application/x-www-form-urlencoded\",\n\t\t};\n\t\tconst secret = this.#config.clientSecret;\n\t\tif (secret !== undefined && metadata.tokenAuth === \"client_secret_basic\") {\n\t\t\t// RFC 6749 §2.3.1: both parts form-encoded before Base64.\n\t\t\tconst enc = (v: string) => encodeURIComponent(v).replace(/%20/g, \"+\");\n\t\t\theaders[\"authorization\"] =\n\t\t\t\t`Basic ${btoa(`${enc(this.#config.clientId)}:${enc(secret)}`)}`;\n\t\t} else {\n\t\t\tbody.set(\"client_id\", this.#config.clientId);\n\t\t\tif (secret !== undefined) body.set(\"client_secret\", secret);\n\t\t}\n\t\tlet response: unknown;\n\t\ttry {\n\t\t\tresponse = await fetchJson(\n\t\t\t\tmetadata.tokenEndpoint,\n\t\t\t\t{ method: \"POST\", headers, body },\n\t\t\t\tMAX_TOKEN_RESPONSE_BYTES,\n\t\t\t);\n\t\t} catch (e) {\n\t\t\tif (e instanceof HttpJsonError) {\n\t\t\t\tthrow new OidcError(`token_${e.error || e.status}`, e.message);\n\t\t\t}\n\t\t\tthrow e;\n\t\t}\n\t\tconst idToken = str(\n\t\t\t(response as Record<string, unknown> | null)?.[\"id_token\"],\n\t\t);\n\t\tif (idToken === undefined) {\n\t\t\tthrow new OidcError(\"no_id_token\", \"the token response has no id_token\");\n\t\t}\n\t\tconst { payload } = await verifyJwt(idToken, this.#jwks);\n\t\tconst now = Date.now();\n\t\tif (payload[\"iss\"] !== metadata.issuer) {\n\t\t\tthrow new OidcError(\"id_token_iss\", \"the ID token's issuer is wrong\");\n\t\t}\n\t\tconst aud = audiences(payload);\n\t\tif (!aud.includes(this.#config.clientId)) {\n\t\t\tthrow new OidcError(\"id_token_aud\", \"the ID token is not for this relay\");\n\t\t}\n\t\tconst azp = payload[\"azp\"];\n\t\tif (\n\t\t\t(aud.length > 1 || azp !== undefined) &&\n\t\t\tazp !== this.#config.clientId\n\t\t) {\n\t\t\tthrow new OidcError(\n\t\t\t\t\"id_token_azp\",\n\t\t\t\t\"the ID token's azp is not this relay\",\n\t\t\t);\n\t\t}\n\t\tconst exp = numericDate(payload, \"exp\");\n\t\tif (exp === undefined || exp <= now - CLOCK_LEEWAY_MS) {\n\t\t\tthrow new OidcError(\"id_token_exp\", \"the ID token has expired\");\n\t\t}\n\t\tconst iat = numericDate(payload, \"iat\");\n\t\tif (iat === undefined || iat > now + CLOCK_LEEWAY_MS) {\n\t\t\tthrow new OidcError(\n\t\t\t\t\"id_token_iat\",\n\t\t\t\t\"the ID token's iat is missing or in the future\",\n\t\t\t);\n\t\t}\n\t\tif (payload[\"nonce\"] !== flow.nonce) {\n\t\t\tthrow new OidcError(\n\t\t\t\t\"id_token_nonce\",\n\t\t\t\t\"the ID token's nonce does not match\",\n\t\t\t);\n\t\t}\n\t\tconst claim = this.#config.subjectClaim ?? \"sub\";\n\t\tconst subject = payload[claim];\n\t\tif (typeof subject !== \"string\" || subject === \"\" || subject.length > 255) {\n\t\t\tthrow new OidcError(\"id_token_subject\", `the ID token has no ${claim}`);\n\t\t}\n\t\treturn subject;\n\t}\n\n\t#unavailable(error: unknown): PairingResult {\n\t\tthis.#logger.warn(\"oidc.discovery_failed\", {\n\t\t\treason: error instanceof OidcError ? error.reason : \"fetch\",\n\t\t\tmessage: error instanceof Error ? error.message.slice(0, 200) : \"unknown\",\n\t\t});\n\t\treturn {\n\t\t\tok: false,\n\t\t\tmessage: `The sign-in provider ${this.#providerHost} cannot be reached right now. Try again in a minute.`,\n\t\t\treason: \"provider_unavailable\",\n\t\t};\n\t}\n\n\t/** The pending request ended: drop its sign-in and its mismatch mark. */\n\tforget(requestId: string): void {\n\t\tthis.#dropFlow(requestId);\n\t\tthis.#mismatched.delete(requestId);\n\t}\n\n\t#dropFlow(requestId: string): void {\n\t\tconst state = this.#flowOf.get(requestId);\n\t\tif (state !== undefined) this.#flows.delete(state);\n\t\tthis.#flowOf.delete(requestId);\n\t}\n\n\t#sweep(): void {\n\t\tconst now = Date.now();\n\t\tfor (const [state, flow] of this.#flows) {\n\t\t\tif (flow.expiresAt > now) break;\n\t\t\tthis.#flows.delete(state);\n\t\t\tif (this.#flowOf.get(flow.requestId) === state) {\n\t\t\t\tthis.#flowOf.delete(flow.requestId);\n\t\t\t}\n\t\t}\n\t}\n}\n",
20
21
  "/**\n * Pairing (DEC-028, DEC-042): the step at `/authorize` that proves the browser\n * belongs to the tab's user. The authorization server only knows the\n * `PairingMethod` interface; which method a session uses comes from its site\n * (DEC-045): the 6-digit code shown in the tab, or identity binding at an\n * OpenID Connect provider (`oidc.ts`, DEC-079).\n */\n\nimport { timingSafeEqual } from \"node:crypto\";\nimport type { PairingKind } from \"../config.ts\";\n\n/** What a pairing method sees of a tab session. */\nexport interface PairingTarget {\n\t/** The code state of the session (used by the code method). */\n\treadonly codes: PairingCodes;\n\t/** The binding key of the page's user, if signed in (DEC-077). */\n\treadonly identity: string | undefined;\n\t/** Whether the page's \"Connect your AI app\" dialog is open. */\n\treadonly pairingOpen: boolean;\n}\n\n/** The pending request a check belongs to (for methods that leave the page). */\nexport interface PairingContext {\n\trequestId: string;\n\tbrowserId: string;\n\t/** The address being paired: the routing key of the return trip (DEC-098). */\n\taddressId: string;\n}\n\nexport type PairingResult =\n\t/** Paired; `subject` is recorded on the grant (identity binding, DEC-077). */\n\t| { ok: true; subject?: string }\n\t/** Continue elsewhere (the provider's sign-in); the answer comes to `callback`. */\n\t| { ok: \"redirect\"; location: string }\n\t| {\n\t\t\tok: false;\n\t\t\t/** Plain English for the page (plain text; the page escapes it). */\n\t\t\tmessage: string;\n\t\t\t/** A short reason for the log. */\n\t\t\treason: string;\n\t };\n\n/**\n * A way to pair a browser at `/authorize` with an address. The authorization\n * server renders `render()` inside its form (CSRF token, buttons and the\n * request id are its own) and passes the submitted form to `check()`.\n */\nexport interface PairingMethod {\n\treadonly kind: PairingKind;\n\t/** HTML of the method's step (escaped by the method). */\n\trender(target: PairingTarget): string;\n\t/**\n\t * Check the submitted form fields. Call `admit()` right before judging an\n\t * answer that could be right (a real guess); if it returns false, refuse\n\t * with reason `rate_limited` without judging. Malformed input and a state\n\t * that cannot succeed are answered without calling it (DEC-061).\n\t */\n\tcheck(\n\t\ttarget: PairingTarget,\n\t\tform: URLSearchParams,\n\t\tadmit: () => boolean,\n\t\tcontext?: PairingContext,\n\t): PairingResult | Promise<PairingResult>;\n\t/** Work before the page is shown (e.g. provider discovery); throws if unavailable. */\n\tprepare?(): Promise<void>;\n\t/** Extra origins the page's form may lead to (CSP `form-action`). */\n\tformTargets?(): readonly string[];\n\t/** The pending request ended (paired, cancelled, expired, evicted): drop its state. */\n\tforget?(requestId: string): void;\n\t/** The answer of a method that redirected (`/authorize/callback`). */\n\tcallback?(\n\t\tparams: URLSearchParams,\n\t\tbrowserId: string,\n\t\ttargetFor: (requestId: string) => PairingTarget | undefined,\n\t): Promise<{ requestId?: string; result: PairingResult }>;\n}\n\n/** Code lifetime and attempts (DEC-028). */\nexport const PAIRING_CODE_TTL_MS = 120_000;\nexport const PAIRING_MAX_ATTEMPTS = 5;\n\nexport type CodeCheck =\n\t| \"ok\"\n\t| \"limited\"\n\t| \"wrong\"\n\t| \"expired\"\n\t| \"locked\"\n\t| \"inactive\"\n\t| \"malformed\";\n\n/** Six uniformly distributed digits. */\nexport function newPairingCode(): string {\n\t// 4 294 000 000 is the largest multiple of 10^6 below 2^32: rejecting the\n\t// values above it keeps every code equally likely.\n\tconst buffer = new Uint32Array(1);\n\tfor (;;) {\n\t\tcrypto.getRandomValues(buffer);\n\t\tconst n = buffer[0] ?? 0;\n\t\tif (n < 4_294_000_000) return String(n % 1_000_000).padStart(6, \"0\");\n\t}\n}\n\nfunction sameCode(a: string, b: string): boolean {\n\tconst x = Buffer.from(a);\n\tconst y = Buffer.from(b);\n\treturn x.length === y.length && timingSafeEqual(x, y);\n}\n\n/**\n * The pairing codes of one tab session: on while the tab's dialog is open\n * (`pairing.start` … `pairing.stop`); a fresh code after expiry, after use and\n * after too many wrong attempts. Codes are never logged.\n */\nexport class PairingCodes {\n\treadonly #send: (code: string, expiresAt: number) => void;\n\treadonly #ttlMs: number;\n\treadonly #maxAttempts: number;\n\t#current: { code: string; expiresAt: number; attempts: number } | undefined;\n\t#previous: string | undefined;\n\t#timer: Timer | undefined;\n\n\tconstructor(\n\t\tsend: (code: string, expiresAt: number) => void,\n\t\toptions: { ttlMs?: number; maxAttempts?: number } = {},\n\t) {\n\t\tthis.#send = send;\n\t\tthis.#ttlMs = options.ttlMs ?? PAIRING_CODE_TTL_MS;\n\t\tthis.#maxAttempts = options.maxAttempts ?? PAIRING_MAX_ATTEMPTS;\n\t}\n\n\t/** Whether the tab is showing codes. */\n\tget active(): boolean {\n\t\treturn this.#current !== undefined;\n\t}\n\n\t/** Attempts left for the current code. */\n\tget attemptsLeft(): number {\n\t\treturn this.#current === undefined\n\t\t\t? 0\n\t\t\t: this.#maxAttempts - this.#current.attempts;\n\t}\n\n\tstart(): void {\n\t\tif (this.#current !== undefined) {\n\t\t\t// Already on (e.g. a second dialog): show the same code again.\n\t\t\tthis.#send(this.#current.code, this.#current.expiresAt);\n\t\t\treturn;\n\t\t}\n\t\tthis.#issue();\n\t}\n\n\tstop(): void {\n\t\tclearTimeout(this.#timer);\n\t\tthis.#timer = undefined;\n\t\tthis.#current = undefined;\n\t\tthis.#previous = undefined;\n\t}\n\n\t/**\n\t * Check a typed code; a correct one is used up and replaced. `admit` is\n\t * asked only for a well-formed code while a code is active.\n\t */\n\tcheck(\n\t\tinput: string,\n\t\tnow: number = Date.now(),\n\t\tadmit: () => boolean = () => true,\n\t): CodeCheck {\n\t\tconst current = this.#current;\n\t\tif (current === undefined) return \"inactive\";\n\t\tconst typed = input.replace(/[\\s-]/g, \"\");\n\t\tif (!/^\\d{6}$/.test(typed)) return \"malformed\";\n\t\tif (!admit()) return \"limited\";\n\t\tif (now >= current.expiresAt) {\n\t\t\tthis.#previous = current.code;\n\t\t\tthis.#issue();\n\t\t\treturn \"expired\";\n\t\t}\n\t\tif (sameCode(typed, current.code)) {\n\t\t\tthis.#previous = undefined;\n\t\t\tthis.#issue();\n\t\t\treturn \"ok\";\n\t\t}\n\t\tcurrent.attempts++;\n\t\tconst expired =\n\t\t\tthis.#previous !== undefined && sameCode(typed, this.#previous);\n\t\tif (current.attempts >= this.#maxAttempts) {\n\t\t\tthis.#previous = undefined;\n\t\t\tthis.#issue();\n\t\t\treturn \"locked\";\n\t\t}\n\t\treturn expired ? \"expired\" : \"wrong\";\n\t}\n\n\t#issue(): void {\n\t\tclearTimeout(this.#timer);\n\t\tconst expiresAt = Date.now() + this.#ttlMs;\n\t\tthis.#current = { code: newPairingCode(), expiresAt, attempts: 0 };\n\t\tthis.#timer = setTimeout(() => {\n\t\t\tif (this.#current === undefined) return;\n\t\t\tthis.#previous = this.#current.code;\n\t\t\tthis.#issue();\n\t\t}, this.#ttlMs);\n\t\tthis.#send(this.#current.code, expiresAt);\n\t}\n}\n\nconst MESSAGES: Record<Exclude<CodeCheck, \"ok\">, string> = {\n\twrong:\n\t\t\"That code is not right. Check the code shown in the page and try again.\",\n\texpired:\n\t\t\"That code has expired. The page now shows a new code: enter that one.\",\n\tlocked:\n\t\t\"Too many wrong codes. The page now shows a new code: enter that one.\",\n\tinactive:\n\t\t\"The page is not showing a code right now. In the page, open “Connect your AI app” to see one, then enter it here.\",\n\tmalformed: \"Enter the 6 digits shown in the page.\",\n\tlimited:\n\t\t\"Too many attempts for this page. Wait a few minutes and try again. If it keeps happening, someone else may be guessing: use “New address” in the page.\",\n};\n\n/** The 6-digit code typed at `/authorize` (DEC-028). */\nexport const codePairing: PairingMethod = {\n\tkind: \"code\",\n\trender(): string {\n\t\treturn `<p><label for=\"code\">Code shown in the page</label>\n<input id=\"code\" name=\"code\" type=\"text\" inputmode=\"numeric\" autocomplete=\"one-time-code\" pattern=\"[0-9 ]{6,7}\" maxlength=\"7\" required autofocus aria-describedby=\"code-help\"></p>\n<p id=\"code-help\" class=\"help\">In the page, “Connect your AI app” shows a 6-digit code. It changes every 2 minutes.</p>`;\n\t},\n\tcheck(target, form, admit): PairingResult {\n\t\tconst result = target.codes.check(\n\t\t\tform.get(\"code\") ?? \"\",\n\t\t\tDate.now(),\n\t\t\tadmit,\n\t\t);\n\t\tif (result === \"ok\") return { ok: true };\n\t\tlet message = MESSAGES[result];\n\t\tif (result === \"wrong\") {\n\t\t\tconst left = target.codes.attemptsLeft;\n\t\t\tmessage += ` ${left === 1 ? \"1 try is\" : `${left} tries are`} left for this code.`;\n\t\t}\n\t\treturn {\n\t\t\tok: false,\n\t\t\tmessage,\n\t\t\treason: result === \"limited\" ? \"rate_limited\" : result,\n\t\t};\n\t},\n};\n\n/** The methods without settings; `oidc` is added by the server when configured. */\nexport const PAIRING_METHODS: Partial<Record<PairingKind, PairingMethod>> = {\n\tcode: codePairing,\n};\n",
21
22
  "import {\n\taddressIdFromSecret,\n\tisWellFormedSecret,\n\tshortAddress,\n} from \"./address.ts\";\nimport type { RelayConfig, Site, SiteLimits } from \"./config.ts\";\nimport {\n\tExchange,\n\ttype PageGoneReply,\n\tRelayErrorCode,\n\ttype RpcId,\n} from \"./exchange.ts\";\nimport { errorName, type Logger } from \"./log.ts\";\nimport { PairingCodes } from \"./oauth/pairing.ts\";\nimport {\n\ttype ByeReason,\n\tCloseCode,\n\ttype ErrorCode,\n\ttype GrantInfo,\n\ttype GrantRef,\n\ttype Limits,\n\tparseTabMessage,\n\ttype RelayMessage,\n\ttype TabMessage,\n} from \"./protocol.ts\";\nimport type { TokenStore } from \"./store/types.ts\";\nimport { newId } from \"./tokens.ts\";\n\n/** The part of Bun's `ServerWebSocket` a session uses (a fake in unit tests). */\nexport interface SocketLike {\n\t/** Bytes sent, -1 when queued under backpressure, 0 when dropped. */\n\tsend(data: string): number;\n\tclose(code?: number, reason?: string): void;\n}\n\n/** What a session needs from its relay. */\nexport interface SessionHost {\n\treadonly config: RelayConfig;\n\treadonly logger: Logger;\n\treadonly store: TokenStore;\n\t/** The external origin, e.g. `https://relay.ractive.ch`. */\n\tpublicUrl(): string;\n\t/** Register a session for its address; returns the session it replaced. */\n\tclaimAddress(session: TabSession): TabSession | undefined;\n\t/** Called once when a session is over. */\n\treleased(session: TabSession): void;\n\t/** Called once when a session is ready for MCP requests (DEC-074). */\n\tready(session: TabSession): void;\n\t/** The tab pressed Disconnect for one app; false if the grant is not this address's. */\n\trevokeGrant(session: TabSession, grantId: string): Promise<boolean>;\n\t/** The tab revokes every grant of its address (\"New address\"). */\n\trevokeAll(session: TabSession): Promise<void>;\n\t/** The page proves who its user is (DEC-076); answers the tab itself. */\n\tbindIdentity(\n\t\tsession: TabSession,\n\t\tassertion: string,\n\t\tround?: number,\n\t): Promise<void>;\n\t/** The page's user signed out (DEC-078). */\n\tsignOut(session: TabSession): Promise<void>;\n\t/** Pairing code lifetime (tests shorten it). */\n\treadonly pairingCodeTtlMs?: number;\n}\n\n/** One MCP request for the tab: always `POST /mcp` (protocol: tunnelled MCP requests). */\nexport interface ForwardInput {\n\theaders: Record<string, string>;\n\tbody: string;\n\trpcId: RpcId | undefined;\n\tisListen: boolean;\n\tgrant: GrantRef;\n\textraHeaders: Record<string, string>;\n\t/** Called once with the finished exchange (for the request log line). */\n\tonDone: (exchange: Exchange) => void;\n\t/** The answer when the page goes away mid-request (DEC-074). */\n\tpageGone?: (waiting: boolean) => PageGoneReply;\n}\n\n/** The limits announced to the tab (protocol: `session.limits`). */\nexport function limitsOf(limits: SiteLimits | RelayConfig): Limits {\n\treturn {\n\t\tmaxMessageBytes: limits.maxMessageBytes,\n\t\tmaxBodyBytes: limits.maxMessageBytes,\n\t\trequestTimeoutMs: limits.requestTimeoutMs,\n\t\tidleTimeoutMs: limits.idleTimeoutMs,\n\t\theartbeatMs: limits.heartbeatMs,\n\t\tkeepAliveMs: limits.keepAliveMs,\n\t\tmaxConcurrentRequests: limits.maxConcurrentRequests,\n\t};\n}\n\nfunction clientHost(clientId: string): string {\n\ttry {\n\t\treturn new URL(clientId).host;\n\t} catch {\n\t\treturn \"\";\n\t}\n}\n\n/**\n * The request id of a frame too large to parse, from a cheap match at its\n * start (the tab library sends `type` and `id` first); `undefined` if absent.\n */\nfunction frameId(data: string): string | undefined {\n\treturn /\"id\"\\s*:\\s*\"([^\"\\\\]{1,64})\"/.exec(data.slice(0, 256))?.[1];\n}\n\n/** One tab's WebSocket session, from open to close. */\nexport class TabSession {\n\treadonly sessionId: string = newId(\"s\");\n\treadonly ip: string;\n\treadonly origin: string;\n\t/** The site this session's origin belongs to (DEC-045). */\n\treadonly site: Site;\n\treadonly openedAt: number = Date.now();\n\t/**\n\t * The address id the `/tab` URL named (`?a=`, DEC-098), checked against\n\t * the secret in `hello`; `undefined` for libraries that do not send it.\n\t */\n\treadonly expectedAddress: string | undefined;\n\t/** Set once `hello` was accepted. */\n\taddressId: string | undefined;\n\t/** The app name `/authorize` shows: the site's name, else the page's claim. */\n\tappName: string | undefined;\n\t/** Pairing codes while the tab's dialog is open (DEC-028). */\n\treadonly codes: PairingCodes;\n\t/**\n\t * The binding key of the page's user, once an assertion was accepted\n\t * (DEC-077); `undefined` while nobody is signed in.\n\t */\n\tidentity: string | undefined;\n\t/**\n\t * The last assertion could not be checked (keys or store unavailable): while\n\t * nobody is bound, AI apps are told to try again rather than to sign in.\n\t */\n\tidentityUnchecked = false;\n\treadonly pending: Map<string, Exchange> = new Map();\n\t/** The grant of each pending listen stream (a cap per grant). */\n\treadonly #listenGrants = new Map<string, string>();\n\n\treadonly #ws: SocketLike;\n\treadonly #host: SessionHost;\n\t#state: \"new\" | \"hello\" | \"ready\" | \"ended\" = \"new\";\n\t/** The \"Connect your AI app\" dialog is open (OIDC pairing, DEC-079). */\n\t#dialogOpen = false;\n\t#identityChain: Promise<void> = Promise.resolve();\n\t#lastRequestAt = Date.now();\n\t#missedPongs = 0;\n\t#nextRequest = 0;\n\t#helloTimer: Timer | undefined;\n\t#heartbeatTimer: Timer | undefined;\n\t#lifetimeTimer: Timer | undefined;\n\n\tconstructor(\n\t\tws: SocketLike,\n\t\tip: string,\n\t\torigin: string,\n\t\tsite: Site,\n\t\thost: SessionHost,\n\t\texpectedAddress?: string,\n\t) {\n\t\tthis.#ws = ws;\n\t\tthis.ip = ip;\n\t\tthis.origin = origin;\n\t\tthis.site = site;\n\t\tthis.#host = host;\n\t\tthis.expectedAddress = expectedAddress;\n\t\tthis.codes = new PairingCodes(\n\t\t\t(code, expiresAt) => {\n\t\t\t\tthis.send({\n\t\t\t\t\ttype: \"pairing.code\",\n\t\t\t\t\tcode,\n\t\t\t\t\texpiresAt: new Date(expiresAt).toISOString(),\n\t\t\t\t});\n\t\t\t},\n\t\t\thost.pairingCodeTtlMs === undefined\n\t\t\t\t? {}\n\t\t\t\t: { ttlMs: host.pairingCodeTtlMs },\n\t\t);\n\t\tthis.#helloTimer = setTimeout(() => {\n\t\t\tif (this.#state === \"new\") {\n\t\t\t\tthis.#protocolError(\"bad_message\", \"no hello in time\");\n\t\t\t}\n\t\t}, host.config.helloTimeoutMs);\n\t}\n\n\tget ready(): boolean {\n\t\treturn this.#state === \"ready\";\n\t}\n\n\t/** Whether the page's \"Connect your AI app\" dialog is open. */\n\tget pairingOpen(): boolean {\n\t\treturn this.site.pairing === \"code\" ? this.codes.active : this.#dialogOpen;\n\t}\n\n\t/** The limits of this session (its site's). */\n\tget limits(): SiteLimits {\n\t\treturn this.site.limits;\n\t}\n\n\t/** Send one message; false if Bun dropped it under backpressure (DEC-021). */\n\tsend(message: RelayMessage): boolean {\n\t\tif (this.#state === \"ended\") return false;\n\t\tlet sent: number;\n\t\ttry {\n\t\t\tsent = this.#ws.send(JSON.stringify(message));\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t\tif (sent === 0) {\n\t\t\tthis.#host.logger.warn(\"tab.send_dropped\", {\n\t\t\t\tsession: this.sessionId,\n\t\t\t\ttype: message.type,\n\t\t\t});\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/** A frame arrived from the tab. */\n\thandleFrame(data: string | Uint8Array): void {\n\t\tif (this.#state === \"ended\") return;\n\t\tif (typeof data !== \"string\") {\n\t\t\tthis.#protocolError(\"bad_message\", \"binary frames are not allowed\");\n\t\t\treturn;\n\t\t}\n\t\t// Refused by length before parsing: a page of a site with a small limit\n\t\t// must not make the relay parse frames up to the largest site's.\n\t\tif (Buffer.byteLength(data) > this.limits.maxMessageBytes) {\n\t\t\tconst id = frameId(data);\n\t\t\tthis.#sendError(\"too_large\", \"message exceeds maxMessageBytes\", id);\n\t\t\tconst exchange = id === undefined ? undefined : this.pending.get(id);\n\t\t\texchange?.fail(\n\t\t\t\t502,\n\t\t\t\tRelayErrorCode.tooLarge,\n\t\t\t\t\"The page sent a response that is too large.\",\n\t\t\t\ttrue,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tconst parsed = parseTabMessage(data);\n\t\tif (!parsed.ok) {\n\t\t\tif (this.#state === \"new\") {\n\t\t\t\tthis.#protocolError(\"bad_message\", parsed.error);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.#sendError(\"bad_message\", parsed.error, parsed.id);\n\t\t\t// A malformed response must not leave its request hanging.\n\t\t\tconst exchange =\n\t\t\t\tparsed.id === undefined ? undefined : this.pending.get(parsed.id);\n\t\t\texchange?.fail(\n\t\t\t\t502,\n\t\t\t\tRelayErrorCode.badResponse,\n\t\t\t\t\"The page sent an invalid response.\",\n\t\t\t\ttrue,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tif (\"unknown\" in parsed) {\n\t\t\tif (this.#state === \"new\") {\n\t\t\t\tthis.#protocolError(\"bad_message\", \"hello expected\");\n\t\t\t} else if (parsed.id !== undefined) {\n\t\t\t\tthis.#sendError(\n\t\t\t\t\t\"unknown_type\",\n\t\t\t\t\t`unknown type ${parsed.type}`,\n\t\t\t\t\tparsed.id,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\t// One bad frame must never become an unhandled rejection (it would end\n\t\t// the process): log it, tell the tab, keep the session.\n\t\tthis.#handle(parsed.message).catch((error: unknown) => {\n\t\t\tthis.#host.logger.error(\"tab.handler_error\", {\n\t\t\t\tsession: this.sessionId,\n\t\t\t\ttype: parsed.message.type,\n\t\t\t\tmessage: error instanceof Error ? error.name : \"unknown\",\n\t\t\t});\n\t\t\tthis.#sendError(\"bad_message\", \"the relay could not handle this message\");\n\t\t});\n\t}\n\n\tasync #handle(msg: TabMessage): Promise<void> {\n\t\tif (this.#state === \"new\") {\n\t\t\tif (msg.type !== \"hello\") {\n\t\t\t\tthis.#protocolError(\"bad_message\", \"hello expected\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait this.#hello(\n\t\t\t\tmsg.secret,\n\t\t\t\tmsg.library,\n\t\t\t\tmsg.app?.name,\n\t\t\t\tmsg.revokeAll === true,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tif (this.#state === \"hello\") return; // still answering hello\n\t\tswitch (msg.type) {\n\t\t\tcase \"hello\":\n\t\t\t\tthis.#sendError(\"bad_message\", \"hello was already sent\");\n\t\t\t\treturn;\n\t\t\tcase \"pong\":\n\t\t\t\tthis.#missedPongs = 0;\n\t\t\t\treturn;\n\t\t\tcase \"bye\":\n\t\t\t\tthis.end(CloseCode.normal, \"bye\");\n\t\t\t\treturn;\n\t\t\tcase \"pairing.start\":\n\t\t\t\tif (this.site.pairing === \"code\") this.codes.start();\n\t\t\t\telse this.#dialogOpen = true;\n\t\t\t\treturn;\n\t\t\tcase \"pairing.stop\":\n\t\t\t\tthis.codes.stop();\n\t\t\t\tthis.#dialogOpen = false;\n\t\t\t\treturn;\n\t\t\tcase \"identity\":\n\t\t\t\tawait this.#serialIdentity(() =>\n\t\t\t\t\tthis.#host.bindIdentity(this, msg.assertion, msg.round),\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\tcase \"identity.logout\":\n\t\t\t\tawait this.#serialIdentity(() => this.#host.signOut(this));\n\t\t\t\treturn;\n\t\t\tcase \"grant.revoke\":\n\t\t\t\tif (!(await this.#host.revokeGrant(this, msg.grantId))) {\n\t\t\t\t\tthis.#sendError(\"unknown_id\", \"unknown grant\");\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\tcase \"grants.revokeAll\":\n\t\t\t\tawait this.#host.revokeAll(this);\n\t\t\t\treturn;\n\t\t\tcase \"error\":\n\t\t\t\tthis.#host.logger.debug(\"tab.error\", {\n\t\t\t\t\tsession: this.sessionId,\n\t\t\t\t\tcode: msg.code,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\tcase \"http.response\":\n\t\t\tcase \"http.response.start\":\n\t\t\tcase \"http.response.chunk\":\n\t\t\tcase \"http.response.end\": {\n\t\t\t\tconst exchange = this.pending.get(msg.id);\n\t\t\t\tif (exchange === undefined) return; // finished or cancelled: drop\n\t\t\t\tif (msg.type === \"http.response\") exchange.onResponse(msg);\n\t\t\t\telse if (msg.type === \"http.response.start\") exchange.onStart(msg);\n\t\t\t\telse if (msg.type === \"http.response.chunk\") exchange.onChunk(msg.data);\n\t\t\t\telse exchange.onEnd();\n\t\t\t\tif (exchange.badResponseReason !== undefined) {\n\t\t\t\t\tthis.#sendError(\"bad_message\", exchange.badResponseReason, msg.id);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\tasync #hello(\n\t\tsecret: string,\n\t\tlibrary: { name: string; version: string },\n\t\tappName: string | undefined,\n\t\trevokeAll = false,\n\t): Promise<void> {\n\t\tif (!isWellFormedSecret(secret)) {\n\t\t\tthis.#protocolError(\n\t\t\t\t\"bad_message\",\n\t\t\t\t\"secret must be 43 base64url characters\",\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tconst addressId = addressIdFromSecret(secret);\n\t\tif (\n\t\t\tthis.expectedAddress !== undefined &&\n\t\t\tthis.expectedAddress !== addressId\n\t\t) {\n\t\t\t// A load balancer routed this socket by the URL's id (DEC-098): a\n\t\t\t// session for another address must not open on this instance.\n\t\t\t// Nothing was claimed, so the address's real session stays.\n\t\t\tthis.#host.logger.warn(\"tab.refused\", { reason: \"address_mismatch\" });\n\t\t\tthis.#sendError(\n\t\t\t\t\"address_mismatch\",\n\t\t\t\t\"the address id in the URL is not the one of the secret\",\n\t\t\t);\n\t\t\tthis.end(CloseCode.addressMismatch, \"address mismatch\");\n\t\t\treturn;\n\t\t}\n\t\tclearTimeout(this.#helloTimer);\n\t\tthis.#state = \"hello\";\n\t\tthis.addressId = addressId;\n\t\tthis.appName = this.site.name ?? appName;\n\t\tconst replaced = this.#host.claimAddress(this);\n\t\tif (replaced !== undefined) {\n\t\t\treplaced.end(\n\t\t\t\tCloseCode.replaced,\n\t\t\t\t\"replaced by a newer session\",\n\t\t\t\t\"replaced\",\n\t\t\t);\n\t\t}\n\t\tif (revokeAll) {\n\t\t\t// The page takes its address back (DEC-095): every grant goes in the\n\t\t\t// same step as the claim, whatever claims the address next, and the\n\t\t\t// `session` below lists none, which confirms it to the page.\n\t\t\ttry {\n\t\t\t\tawait this.#host.revokeAll(this);\n\t\t\t} catch (error) {\n\t\t\t\tthis.#host.logger.error(\"store.error\", {\n\t\t\t\t\top: \"revokeAll\",\n\t\t\t\t\terror: errorName(error),\n\t\t\t\t});\n\t\t\t\tthis.end(CloseCode.policyViolation, \"could not revoke the grants\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tlet grants: GrantInfo[] = [];\n\t\ttry {\n\t\t\tconst list = await this.#host.store.listGrants(\n\t\t\t\tthis.addressId,\n\t\t\t\tDate.now(),\n\t\t\t);\n\t\t\tgrants = list.map((g) => ({\n\t\t\t\tgrantId: g.grantId,\n\t\t\t\tclient: {\n\t\t\t\t\tid: g.clientId,\n\t\t\t\t\tname: g.clientName,\n\t\t\t\t\thost: clientHost(g.clientId),\n\t\t\t\t},\n\t\t\t\tcreatedAt: new Date(g.createdAt).toISOString(),\n\t\t\t}));\n\t\t} catch (error) {\n\t\t\tthis.#host.logger.error(\"store.error\", {\n\t\t\t\top: \"listGrants\",\n\t\t\t\terror: errorName(error),\n\t\t\t});\n\t\t}\n\t\tif (this.#state !== \"hello\") return; // closed meanwhile\n\n\t\tconst limits = this.limits;\n\t\tconst expiresAt = this.openedAt + limits.sessionLifetimeMs;\n\t\tthis.#state = \"ready\";\n\t\tconst sent = this.send({\n\t\t\ttype: \"session\",\n\t\t\tsessionId: this.sessionId,\n\t\t\taddress: `${this.#host.publicUrl()}/a/${this.addressId}/mcp`,\n\t\t\torigin: this.origin,\n\t\t\t...(this.appName === undefined ? {} : { appName: this.appName }),\n\t\t\tpairing: this.site.pairing,\n\t\t\texpiresAt: new Date(expiresAt).toISOString(),\n\t\t\tlimits: limitsOf(limits),\n\t\t\tgrants,\n\t\t});\n\t\tif (!sent) {\n\t\t\tthis.end(CloseCode.policyViolation, \"send failed\");\n\t\t\treturn;\n\t\t}\n\t\tthis.#heartbeatTimer = setInterval(() => this.#tick(), limits.heartbeatMs);\n\t\tthis.#lifetimeTimer = setTimeout(\n\t\t\t() =>\n\t\t\t\tthis.end(\n\t\t\t\t\tCloseCode.sessionExpired,\n\t\t\t\t\t\"session lifetime reached\",\n\t\t\t\t\t\"expired\",\n\t\t\t\t),\n\t\t\tMath.max(0, expiresAt - Date.now()),\n\t\t);\n\t\tthis.#host.logger.info(\"tab.session\", {\n\t\t\tsession: this.sessionId,\n\t\t\taddress: shortAddress(this.addressId),\n\t\t\torigin: this.origin,\n\t\t\tlibrary: `${library.name}@${library.version}`,\n\t\t\treplaced: replaced !== undefined,\n\t\t});\n\t\tthis.#host.ready(this);\n\t}\n\n\t/**\n\t * Identity messages run one after another, in the order they came: frames\n\t * are handled concurrently, and a slow assertion check must not finish\n\t * after a later sign-out (review of PR #13).\n\t */\n\t#serialIdentity(run: () => Promise<void>): Promise<void> {\n\t\tconst next = this.#identityChain.then(run);\n\t\tthis.#identityChain = next.catch(() => {});\n\t\treturn next;\n\t}\n\n\t#tick(): void {\n\t\tif (this.#state !== \"ready\") return;\n\t\tif (this.#missedPongs >= 2) {\n\t\t\tthis.end(CloseCode.heartbeatLost, \"heartbeat lost\");\n\t\t\treturn;\n\t\t}\n\t\t// Idle = no MCP request and nothing in flight, listen streams included:\n\t\t// a listen stream may stay open for the session's lifetime (protocol.md),\n\t\t// which still caps it.\n\t\tif (\n\t\t\tthis.pending.size === 0 &&\n\t\t\tDate.now() - this.#lastRequestAt >= this.limits.idleTimeoutMs\n\t\t) {\n\t\t\tthis.end(CloseCode.idleTimeout, \"idle\", \"idle\");\n\t\t\treturn;\n\t\t}\n\t\tthis.#missedPongs++;\n\t\tthis.send({ type: \"ping\", t: Date.now() });\n\t}\n\n\t/** The listen streams one grant has open on this session. */\n\tlistenStreams(grantId: string): number {\n\t\tlet n = 0;\n\t\tfor (const g of this.#listenGrants.values()) if (g === grantId) n++;\n\t\treturn n;\n\t}\n\n\t/** Tunnel one MCP request to the tab. Resolves with the AI app's response. */\n\tforward(input: ForwardInput): Exchange {\n\t\tthis.#lastRequestAt = Date.now();\n\t\tconst id = `r${++this.#nextRequest}`;\n\t\tconst limits = this.limits;\n\t\tconst exchange = new Exchange({\n\t\t\tid,\n\t\t\trpcId: input.rpcId,\n\t\t\tisListen: input.isListen,\n\t\t\trequestTimeoutMs: limits.requestTimeoutMs,\n\t\t\tkeepAliveMs: limits.keepAliveMs,\n\t\t\tmaxBodyBytes: limitsOf(limits).maxBodyBytes,\n\t\t\textraHeaders: input.extraHeaders,\n\t\t\tcancel: (reason) => {\n\t\t\t\tif (!this.send({ type: \"http.cancel\", id, reason })) {\n\t\t\t\t\tthis.#host.logger.debug(\"tab.cancel_not_sent\", {\n\t\t\t\t\t\tsession: this.sessionId,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t},\n\t\t\tonDone: (e) => {\n\t\t\t\tthis.pending.delete(id);\n\t\t\t\tthis.#listenGrants.delete(id);\n\t\t\t\tthis.#lastRequestAt = Date.now();\n\t\t\t\tinput.onDone(e);\n\t\t\t},\n\t\t\t...(input.pageGone === undefined ? {} : { pageGone: input.pageGone }),\n\t\t});\n\t\tthis.pending.set(id, exchange);\n\t\tif (input.isListen) this.#listenGrants.set(id, input.grant.grantId);\n\t\tconst sent = this.send({\n\t\t\ttype: \"http.request\",\n\t\t\tid,\n\t\t\tmethod: \"POST\",\n\t\t\tpath: \"/mcp\",\n\t\t\theaders: input.headers,\n\t\t\tbody: input.body,\n\t\t\tgrant: input.grant,\n\t\t});\n\t\tif (!sent) {\n\t\t\texchange.fail(\n\t\t\t\t503,\n\t\t\t\tRelayErrorCode.sendFailed,\n\t\t\t\t\"The connection to the page is overloaded. Try again.\",\n\t\t\t\tfalse,\n\t\t\t);\n\t\t}\n\t\treturn exchange;\n\t}\n\n\t/** End the session: optional `bye`, then close the socket. Idempotent. */\n\tend(code: number, reason: string, bye?: ByeReason): void {\n\t\tif (this.#state === \"ended\") return;\n\t\tif (bye !== undefined) this.send({ type: \"bye\", reason: bye });\n\t\tthis.#cleanup(code, reason);\n\t\ttry {\n\t\t\tthis.#ws.close(code, reason);\n\t\t} catch {\n\t\t\t// already closed\n\t\t}\n\t}\n\n\t/** The socket closed (from Bun's `close` handler). */\n\tclosed(code: number): void {\n\t\tthis.#cleanup(code, \"closed\");\n\t}\n\n\t#cleanup(code: number, reason: string): void {\n\t\tif (this.#state === \"ended\") return;\n\t\tconst wasReady = this.#state === \"ready\" || this.#state === \"hello\";\n\t\tthis.#state = \"ended\";\n\t\tthis.codes.stop();\n\t\tthis.#dialogOpen = false;\n\t\tclearTimeout(this.#helloTimer);\n\t\tclearInterval(this.#heartbeatTimer);\n\t\tclearTimeout(this.#lifetimeTimer);\n\t\t// Released first, so a request the relay sends again waits for the next\n\t\t// session instead of finding this one.\n\t\tthis.#host.released(this);\n\t\tfor (const exchange of [...this.pending.values()]) exchange.tabGone();\n\t\tif (wasReady) {\n\t\t\tthis.#host.logger.info(\"tab.closed\", {\n\t\t\t\tsession: this.sessionId,\n\t\t\t\tcode,\n\t\t\t\treason,\n\t\t\t\tdurationMs: Date.now() - this.openedAt,\n\t\t\t});\n\t\t}\n\t}\n\n\t#sendError(code: ErrorCode, message: string, id?: string): void {\n\t\tthis.send(\n\t\t\tid === undefined\n\t\t\t\t? { type: \"error\", code, message }\n\t\t\t\t: { type: \"error\", code, message, id },\n\t\t);\n\t}\n\n\t#protocolError(code: ErrorCode, message: string): void {\n\t\tthis.#sendError(code, message);\n\t\tthis.end(CloseCode.policyViolation, message);\n\t}\n}\n",
22
23
  "import type {\n\tGrantSummary,\n\tRevokeOptions,\n\tRevokeSelector,\n\tTokenRecord,\n\tTokenStore,\n} from \"./types.ts\";\n\nfunction copy(record: TokenRecord): TokenRecord {\n\treturn { ...record, scopes: [...record.scopes] };\n}\n\nfunction matches(record: TokenRecord, selector: RevokeSelector): boolean {\n\treturn \"grantId\" in selector\n\t\t? record.grantId === selector.grantId\n\t\t: record.addressId === selector.addressId;\n}\n\n/** Usable at `now`: unexpired, and for refresh tokens not yet used. */\nexport function isLive(record: TokenRecord, now: number): boolean {\n\treturn (\n\t\trecord.expiresAt > now &&\n\t\t(record.kind === \"access\" || record.usedAt === undefined)\n\t);\n}\n\n/** Group live records into grant summaries, oldest grant first. */\nexport function summarizeGrants(\n\trecords: Iterable<TokenRecord>,\n\tnow: number,\n): GrantSummary[] {\n\tconst grants = new Map<string, GrantSummary>();\n\tfor (const r of records) {\n\t\tif (!isLive(r, now) || grants.has(r.grantId)) continue;\n\t\tconst summary: GrantSummary = {\n\t\t\tgrantId: r.grantId,\n\t\t\tclientId: r.clientId,\n\t\t\tclientName: r.clientName,\n\t\t\tscopes: [...r.scopes],\n\t\t\tcreatedAt: r.grantCreatedAt,\n\t\t};\n\t\tif (r.subject !== undefined) summary.subject = r.subject;\n\t\tgrants.set(r.grantId, summary);\n\t}\n\treturn [...grants.values()].sort(\n\t\t(a, b) => a.createdAt - b.createdAt || a.grantId.localeCompare(b.grantId),\n\t);\n}\n\n/** Tokens in process memory; everything is lost on restart. */\nexport class MemoryTokenStore implements TokenStore {\n\treadonly #records = new Map<string, TokenRecord>();\n\t/** Revoked grants: grant id → keep until. */\n\treadonly #revokedGrants = new Map<string, number>();\n\t/** Revoked addresses: address id → { at, keep until }. */\n\treadonly #revokedAddresses = new Map<string, { at: number; until: number }>();\n\n\tasync put(record: TokenRecord): Promise<boolean> {\n\t\tif (this.#revokedGrants.has(record.grantId)) return false;\n\t\tconst address = this.#revokedAddresses.get(record.addressId);\n\t\tif (address !== undefined && record.grantCreatedAt <= address.at) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.#records.set(record.hash, copy(record));\n\t\treturn true;\n\t}\n\n\tasync get(hash: string): Promise<TokenRecord | undefined> {\n\t\tconst r = this.#records.get(hash);\n\t\treturn r === undefined ? undefined : copy(r);\n\t}\n\n\tasync markUsed(\n\t\thash: string,\n\t\tnow: number,\n\t\tkeepUntil: number,\n\t): Promise<boolean> {\n\t\tconst r = this.#records.get(hash);\n\t\tif (r === undefined || r.usedAt !== undefined) return false;\n\t\tr.usedAt = now;\n\t\tr.expiresAt = Math.min(r.expiresAt, keepUntil);\n\t\treturn true;\n\t}\n\n\tasync revoke(\n\t\tselector: RevokeSelector,\n\t\toptions: RevokeOptions,\n\t): Promise<number> {\n\t\tif (\"grantId\" in selector) {\n\t\t\tthis.#revokedGrants.set(selector.grantId, options.keepUntil);\n\t\t} else {\n\t\t\tconst old = this.#revokedAddresses.get(selector.addressId);\n\t\t\tthis.#revokedAddresses.set(selector.addressId, {\n\t\t\t\tat: Math.max(old?.at ?? 0, options.now),\n\t\t\t\tuntil: Math.max(old?.until ?? 0, options.keepUntil),\n\t\t\t});\n\t\t}\n\t\tlet n = 0;\n\t\tfor (const [hash, r] of this.#records) {\n\t\t\tif (matches(r, selector)) {\n\t\t\t\tthis.#records.delete(hash);\n\t\t\t\tn++;\n\t\t\t}\n\t\t}\n\t\treturn n;\n\t}\n\n\tasync listGrants(addressId: string, now: number): Promise<GrantSummary[]> {\n\t\tconst own = [...this.#records.values()].filter(\n\t\t\t(r) => r.addressId === addressId,\n\t\t);\n\t\treturn summarizeGrants(own, now);\n\t}\n\n\tasync deleteExpired(now: number): Promise<number> {\n\t\tfor (const [id, until] of this.#revokedGrants) {\n\t\t\tif (until <= now) this.#revokedGrants.delete(id);\n\t\t}\n\t\tfor (const [id, t] of this.#revokedAddresses) {\n\t\t\tif (t.until <= now) this.#revokedAddresses.delete(id);\n\t\t}\n\t\tlet n = 0;\n\t\tfor (const [hash, r] of this.#records) {\n\t\t\tif (r.expiresAt <= now) {\n\t\t\t\tthis.#records.delete(hash);\n\t\t\t\tn++;\n\t\t\t}\n\t\t}\n\t\treturn n;\n\t}\n\n\tasync close(): Promise<void> {\n\t\tthis.#records.clear();\n\t\tthis.#revokedGrants.clear();\n\t\tthis.#revokedAddresses.clear();\n\t}\n}\n",
23
24
  "import { Database } from \"bun:sqlite\";\nimport { summarizeGrants } from \"./memory.ts\";\nimport type {\n\tGrantSummary,\n\tRevokeOptions,\n\tRevokeSelector,\n\tTokenKind,\n\tTokenRecord,\n\tTokenStore,\n} from \"./types.ts\";\n\nconst SCHEMA_VERSION = 4;\n/** The reuse window of used refresh tokens (DEC-091), for the version 4 step. */\nconst REUSE_WINDOW_MS = 86_400_000;\n\ninterface Row {\n\thash: string;\n\tkind: string;\n\tgrant_id: string;\n\taddress_id: string;\n\tclient_id: string;\n\tclient_name: string;\n\tscopes: string;\n\tgrant_created_at: number;\n\tissued_at: number;\n\texpires_at: number;\n\tused_at: number | null;\n\tsubject: string | null;\n}\n\nfunction toRecord(row: Row): TokenRecord {\n\tconst record: TokenRecord = {\n\t\thash: row.hash,\n\t\tkind: row.kind as TokenKind,\n\t\tgrantId: row.grant_id,\n\t\taddressId: row.address_id,\n\t\tclientId: row.client_id,\n\t\tclientName: row.client_name,\n\t\tscopes: JSON.parse(row.scopes) as string[],\n\t\tgrantCreatedAt: row.grant_created_at,\n\t\tissuedAt: row.issued_at,\n\t\texpiresAt: row.expires_at,\n\t};\n\tif (row.used_at !== null) record.usedAt = row.used_at;\n\tif (row.subject !== null) record.subject = row.subject;\n\treturn record;\n}\n\n/**\n * Tokens in a SQLite file via `bun:sqlite` (the default store, DEC-030). Uses\n * WAL mode so another process (or a test) can read and write the same file.\n */\nexport class SqliteTokenStore implements TokenStore {\n\treadonly #db: Database;\n\n\t/** `path` is a file path, or `:memory:`. */\n\tconstructor(path: string) {\n\t\tthis.#db = new Database(path, { create: true, strict: true });\n\t\tthis.#db.run(\"PRAGMA busy_timeout = 5000\");\n\t\tif (path !== \":memory:\") this.#db.run(\"PRAGMA journal_mode = WAL\");\n\t\tthis.#migrate();\n\t}\n\n\t#migrate(): void {\n\t\tconst row = this.#db.query(\"PRAGMA user_version\").get() as {\n\t\t\tuser_version: number;\n\t\t};\n\t\tif (row.user_version >= SCHEMA_VERSION) return;\n\t\tthis.#db.transaction(() => {\n\t\t\t// Version 2: tombstones of revoked grants and addresses.\n\t\t\tthis.#db.run(`CREATE TABLE IF NOT EXISTS revocations (\n\t\t\t\tkind TEXT NOT NULL CHECK (kind IN ('grant', 'address')),\n\t\t\t\tid TEXT NOT NULL,\n\t\t\t\tat INTEGER NOT NULL,\n\t\t\t\tkeep_until INTEGER NOT NULL,\n\t\t\t\tPRIMARY KEY (kind, id)\n\t\t\t) STRICT`);\n\t\t\tthis.#db.run(`CREATE TABLE IF NOT EXISTS tokens (\n\t\t\t\thash TEXT PRIMARY KEY,\n\t\t\t\tkind TEXT NOT NULL CHECK (kind IN ('access', 'refresh')),\n\t\t\t\tgrant_id TEXT NOT NULL,\n\t\t\t\taddress_id TEXT NOT NULL,\n\t\t\t\tclient_id TEXT NOT NULL,\n\t\t\t\tclient_name TEXT NOT NULL,\n\t\t\t\tscopes TEXT NOT NULL,\n\t\t\t\tgrant_created_at INTEGER NOT NULL,\n\t\t\t\tissued_at INTEGER NOT NULL,\n\t\t\t\texpires_at INTEGER NOT NULL,\n\t\t\t\tused_at INTEGER,\n\t\t\t\tsubject TEXT\n\t\t\t) STRICT`);\n\t\t\t// Version 3: the subject of identity-bound grants (DEC-077).\n\t\t\tconst columns = this.#db.query(\"PRAGMA table_info(tokens)\").all() as {\n\t\t\t\tname: string;\n\t\t\t}[];\n\t\t\tif (!columns.some((c) => c.name === \"subject\")) {\n\t\t\t\tthis.#db.run(\"ALTER TABLE tokens ADD COLUMN subject TEXT\");\n\t\t\t}\n\t\t\tthis.#db.run(\n\t\t\t\t\"CREATE INDEX IF NOT EXISTS tokens_grant ON tokens (grant_id)\",\n\t\t\t);\n\t\t\tthis.#db.run(\n\t\t\t\t\"CREATE INDEX IF NOT EXISTS tokens_address ON tokens (address_id)\",\n\t\t\t);\n\t\t\tthis.#db.run(\n\t\t\t\t\"CREATE INDEX IF NOT EXISTS tokens_expires ON tokens (expires_at)\",\n\t\t\t);\n\t\t\t// Version 4: refresh tokens used before the upgrade get the reuse\n\t\t\t// window that markUsed now gives (DEC-091), so they go too.\n\t\t\tthis.#db\n\t\t\t\t.query(\n\t\t\t\t\t`UPDATE tokens SET expires_at = min(expires_at, used_at + $window)\n\t\t\t\t\tWHERE kind = 'refresh' AND used_at IS NOT NULL`,\n\t\t\t\t)\n\t\t\t\t.run({ window: REUSE_WINDOW_MS });\n\t\t\tthis.#db.run(`PRAGMA user_version = ${SCHEMA_VERSION}`);\n\t\t})();\n\t}\n\n\tasync put(r: TokenRecord): Promise<boolean> {\n\t\treturn this.#db.transaction(() => {\n\t\t\tconst revoked = this.#db\n\t\t\t\t.query(\n\t\t\t\t\t`SELECT 1 FROM revocations WHERE (kind = 'grant' AND id = $grant_id)\n\t\t\t\t\tOR (kind = 'address' AND id = $address_id AND at >= $created)`,\n\t\t\t\t)\n\t\t\t\t.get({\n\t\t\t\t\tgrant_id: r.grantId,\n\t\t\t\t\taddress_id: r.addressId,\n\t\t\t\t\tcreated: r.grantCreatedAt,\n\t\t\t\t});\n\t\t\tif (revoked !== null) return false;\n\t\t\tthis.#insert(r);\n\t\t\treturn true;\n\t\t})();\n\t}\n\n\t#insert(r: TokenRecord): void {\n\t\tthis.#db\n\t\t\t.query(\n\t\t\t\t`INSERT OR REPLACE INTO tokens (hash, kind, grant_id, address_id, client_id,\n\t\t\t\tclient_name, scopes, grant_created_at, issued_at, expires_at, used_at, subject)\n\t\t\t\tVALUES ($hash, $kind, $grant_id, $address_id, $client_id, $client_name,\n\t\t\t\t$scopes, $grant_created_at, $issued_at, $expires_at, $used_at, $subject)`,\n\t\t\t)\n\t\t\t.run({\n\t\t\t\thash: r.hash,\n\t\t\t\tkind: r.kind,\n\t\t\t\tgrant_id: r.grantId,\n\t\t\t\taddress_id: r.addressId,\n\t\t\t\tclient_id: r.clientId,\n\t\t\t\tclient_name: r.clientName,\n\t\t\t\tscopes: JSON.stringify(r.scopes),\n\t\t\t\tgrant_created_at: r.grantCreatedAt,\n\t\t\t\tissued_at: r.issuedAt,\n\t\t\t\texpires_at: r.expiresAt,\n\t\t\t\tused_at: r.usedAt ?? null,\n\t\t\t\tsubject: r.subject ?? null,\n\t\t\t});\n\t}\n\n\tasync get(hash: string): Promise<TokenRecord | undefined> {\n\t\tconst row = this.#db\n\t\t\t.query(\"SELECT * FROM tokens WHERE hash = $hash\")\n\t\t\t.get({ hash }) as Row | null;\n\t\treturn row === null ? undefined : toRecord(row);\n\t}\n\n\tasync markUsed(\n\t\thash: string,\n\t\tnow: number,\n\t\tkeepUntil: number,\n\t): Promise<boolean> {\n\t\tconst result = this.#db\n\t\t\t.query(\n\t\t\t\t`UPDATE tokens SET used_at = $now, expires_at = min(expires_at, $keep_until)\n\t\t\t\tWHERE hash = $hash AND used_at IS NULL`,\n\t\t\t)\n\t\t\t.run({ hash, now, keep_until: keepUntil });\n\t\treturn result.changes === 1;\n\t}\n\n\tasync revoke(\n\t\tselector: RevokeSelector,\n\t\toptions: RevokeOptions,\n\t): Promise<number> {\n\t\treturn this.#db.transaction(() => {\n\t\t\tthis.#db\n\t\t\t\t.query(\n\t\t\t\t\t`INSERT INTO revocations (kind, id, at, keep_until) VALUES ($kind, $id, $at, $until)\n\t\t\t\t\tON CONFLICT (kind, id) DO UPDATE SET at = max(at, excluded.at),\n\t\t\t\t\tkeep_until = max(keep_until, excluded.keep_until)`,\n\t\t\t\t)\n\t\t\t\t.run({\n\t\t\t\t\tkind: \"grantId\" in selector ? \"grant\" : \"address\",\n\t\t\t\t\tid: \"grantId\" in selector ? selector.grantId : selector.addressId,\n\t\t\t\t\tat: options.now,\n\t\t\t\t\tuntil: options.keepUntil,\n\t\t\t\t});\n\t\t\treturn this.#delete(selector);\n\t\t})();\n\t}\n\n\t#delete(selector: RevokeSelector): number {\n\t\tconst result =\n\t\t\t\"grantId\" in selector\n\t\t\t\t? this.#db\n\t\t\t\t\t\t.query(\"DELETE FROM tokens WHERE grant_id = $id\")\n\t\t\t\t\t\t.run({ id: selector.grantId })\n\t\t\t\t: this.#db\n\t\t\t\t\t\t.query(\"DELETE FROM tokens WHERE address_id = $id\")\n\t\t\t\t\t\t.run({ id: selector.addressId });\n\t\treturn result.changes;\n\t}\n\n\tasync listGrants(addressId: string, now: number): Promise<GrantSummary[]> {\n\t\tconst rows = this.#db\n\t\t\t.query(\n\t\t\t\t`SELECT * FROM tokens WHERE address_id = $addressId AND expires_at > $now\n\t\t\t\tAND (kind = 'access' OR used_at IS NULL)`,\n\t\t\t)\n\t\t\t.all({ addressId, now }) as Row[];\n\t\treturn summarizeGrants(rows.map(toRecord), now);\n\t}\n\n\tasync deleteExpired(now: number): Promise<number> {\n\t\tthis.#db\n\t\t\t.query(\"DELETE FROM revocations WHERE keep_until <= $now\")\n\t\t\t.run({ now });\n\t\treturn this.#db\n\t\t\t.query(\"DELETE FROM tokens WHERE expires_at <= $now\")\n\t\t\t.run({ now }).changes;\n\t}\n\n\tasync close(): Promise<void> {\n\t\tthis.#db.close();\n\t}\n}\n",
24
- "import type { Server, ServerWebSocket } from \"bun\";\nimport { version } from \"../package.json\" with { type: \"json\" };\nimport { addressIdFromSecret, isAddressId, shortAddress } from \"./address.ts\";\nimport {\n\tlargestMessageBytes,\n\tMIN_MESSAGE_BYTES,\n\ttype RelayConfig,\n\tresolveConfig,\n\ttype Site,\n\ttype StoreKind,\n\tsiteFor,\n} from \"./config.ts\";\nimport {\n\ttype Exchange,\n\tRelayErrorCode,\n\ttype RpcId,\n\trpcErrorBody,\n} from \"./exchange.ts\";\nimport { MISMATCH_TEXT, TabAssertionVerifier } from \"./identity.ts\";\nimport { ipPrefixKey } from \"./ip.ts\";\nimport { JwtError, type KeySource } from \"./jwt.ts\";\nimport { createLogger, errorName, type Logger, truncateIp } from \"./log.ts\";\nimport {\n\tisRetryable,\n\ttype NotOpenPhase,\n\tnotOpenAnswer,\n\ttype RelayInfo,\n} from \"./notopen.ts\";\nimport {\n\tAuthorizationServer,\n\ttype AuthorizationTestMode,\n} from \"./oauth/server.ts\";\nimport {\n\tCloseCode,\n\ttype GrantInfo,\n\tMCP_PROTOCOL_VERSION,\n\tPROTOCOL_VERSION_META_KEY,\n\ttype RelayMessage,\n\tSUBPROTOCOL,\n} from \"./protocol.ts\";\nimport { TabSession } from \"./session.ts\";\nimport { MemoryTokenStore } from \"./store/memory.ts\";\nimport { SqliteTokenStore } from \"./store/sqlite.ts\";\nimport type { TokenRecord, TokenStore } from \"./store/types.ts\";\nimport { hashToken } from \"./tokens.ts\";\n\nexport const VERSION: string = version;\n\nconst RELAY_INFO: RelayInfo = { name: \"tab-mcp\", version };\n\n/** Settles the race between an exchange and its page going away. */\nconst RETRY = Symbol(\"retry\");\n\n/** The one mismatched header Claude sends today (claude-code #93290, DEC-033). */\nconst CLAUDE_MISMATCHED_HEADER = \"2025-11-25\";\n\n/**\n * Listen streams one grant may hold on a page at once: they have no request\n * timer, so without a cap one AI app could take every concurrency slot.\n */\nconst MAX_LISTEN_STREAMS_PER_GRANT = 2;\n\n/**\n * Bun closes a WebSocket whose frame is over `maxPayloadLength` (1009). Frames\n * up to this many times the largest site limit get a `too_large` error instead\n * and the session stays; they are refused by length, before parsing.\n */\nconst FRAME_HEADROOM = 4;\n\n/**\n * Refusals of a tab assertion that say nothing about the user: the relay could\n * not check (signing keys or store unavailable, an unexpected error).\n */\nconst TRANSIENT_REFUSALS = new Set([\n\t\"jwks_unavailable\",\n\t\"store_unavailable\",\n\t\"relay_busy\",\n\t\"error\",\n]);\n\n/** The text for requests that cannot be checked against the page's user. */\nconst UNCHECKED_TEXT =\n\t\"The relay cannot check the page's user right now. Try again shortly.\";\n\n/** `Retry-After` (seconds) for answers that ask an AI app to try again soon. */\nconst RETRY_AFTER_S = \"5\";\n\n/** Request headers forwarded to the tab (protocol: tunnelled MCP requests). */\nconst FORWARDED_HEADERS = new Set([\n\t\"content-type\",\n\t\"accept\",\n\t\"mcp-method\",\n\t\"mcp-name\",\n\t\"traceparent\",\n\t\"tracestate\",\n]);\n\nexport interface CreateRelayOptions\n\textends Omit<Partial<RelayConfig>, \"store\"> {\n\t/**\n\t * The token store: a `TokenStore` instance (e.g. Prisma, Redis), or the name\n\t * of a built-in one (`\"sqlite\"`, the default, at `sqlitePath`; `\"memory\"`).\n\t */\n\tstore?: StoreKind | TokenStore;\n\t/** Logger; defaults to JSON lines on stdout at `logLevel`. */\n\tlogger?: Logger;\n}\n\nexport interface Relay {\n\t/** The external origin (issuer and address base). */\n\treadonly url: string;\n\t/** The port the server listens on. */\n\treadonly port: number;\n\treadonly config: RelayConfig;\n\t/** The MCP address a page with this secret gets. */\n\taddressFor(secret: string): string;\n\t/** Number of connected tab sessions. */\n\treadonly sessionCount: number;\n\t/** Close all sessions (bye `shutdown`, close 4004) and stop the server. */\n\tstop(): Promise<void>;\n}\n\n/** What `/healthz` says about the token store (DEC-099). */\ntype StoreHealth = \"ok\" | \"store_unavailable\" | \"store_timeout\";\n/** How long the health probe waits for the store. */\nconst HEALTH_STORE_TIMEOUT_MS = 1000;\n/** How long a probe's answer is reused. */\nconst HEALTH_REUSE_MS = 1000;\n/** While an earlier read hangs, how long before a new one is tried. */\nconst HEALTH_HUNG_RETRY_MS = 30_000;\n/** A store key no token ever has (a token's hash is of `tmcp_…`). */\nconst HEALTH_PROBE_HASH = hashToken(\"tab-mcp /healthz probe\");\n\n/**\n * The `a` parameter of a `/tab` query, read from the raw text: `undefined`\n * when absent, `false` when malformed or repeated. Only the literal id\n * counts, never a percent-encoded one, so the relay agrees with a load\n * balancer that matches the URL as sent (review of PR 38).\n */\nfunction rawAddressParam(search: string): string | undefined | false {\n\tlet found: string | undefined;\n\tfor (const pair of search.replace(/^\\?/, \"\").split(\"&\")) {\n\t\tif (pair === \"\") continue;\n\t\tconst eq = pair.indexOf(\"=\");\n\t\tconst rawName = eq < 0 ? pair : pair.slice(0, eq);\n\t\tlet name: string;\n\t\ttry {\n\t\t\tname = decodeURIComponent(rawName.replaceAll(\"+\", \" \"));\n\t\t} catch {\n\t\t\tcontinue; // not ours: other parameters are ignored\n\t\t}\n\t\tif (name !== \"a\") continue;\n\t\tconst value = eq < 0 ? \"\" : pair.slice(eq + 1);\n\t\tif (rawName !== \"a\" || found !== undefined || !isAddressId(value)) {\n\t\t\treturn false;\n\t\t}\n\t\tfound = value;\n\t}\n\treturn found;\n}\n\ninterface WsData {\n\tip: string;\n\torigin: string;\n\tsite: Site;\n\t/** The address id the URL named (`/tab?a=`, DEC-098). */\n\taddress?: string;\n\tsession?: TabSession;\n}\n\n/**\n * Test-only relaxations, never reachable from configuration or the package's\n * public API (`createTestRelay` is not exported from the package): CIMD\n * fetches from loopback test servers, shorter code lifetimes.\n */\nexport interface RelayTestHooks extends AuthorizationTestMode {\n\tpairingCodeTtlMs?: number;\n\t/** Keys for tab assertions instead of fetching the JWKS URL. */\n\tassertionKeys?: KeySource;\n\t/** A smaller relay-wide replay cache for tab assertions. */\n\tmaxSeenAssertions?: number;\n\t/** How long `/healthz` waits before a new read while one hangs. */\n\thealthRetryMs?: number;\n}\n\ninterface Body {\n\tvalue: Record<string, unknown>;\n\ttext: string;\n}\n\nfunction json(\n\tstatus: number,\n\tvalue: unknown,\n\theaders?: Record<string, string>,\n): Response {\n\tconst h = new Headers(headers);\n\th.set(\"content-type\", \"application/json\");\n\treturn new Response(JSON.stringify(value), { status, headers: h });\n}\n\nfunction rpcError(\n\tstatus: number,\n\trpcId: RpcId | undefined,\n\tcode: number,\n\tmessage: string,\n\theaders: Record<string, string>,\n\tdata?: unknown,\n): Response {\n\treturn new Response(rpcErrorBody(rpcId, code, message, data), {\n\t\tstatus,\n\t\theaders: { ...headers, \"content-type\": \"application/json\" },\n\t});\n}\n\nfunction rpcIdOf(body: Record<string, unknown>): RpcId | undefined {\n\tif (!(\"id\" in body)) return undefined;\n\tconst id = body[\"id\"];\n\treturn typeof id === \"string\" || typeof id === \"number\" ? id : null;\n}\n\n/** A loggable MCP method name (attacker-controlled input, so constrained). */\nfunction methodForLog(body: Record<string, unknown>): string {\n\tconst m = body[\"method\"];\n\treturn typeof m === \"string\" && /^[A-Za-z0-9_/.-]{1,64}$/.test(m) ? m : \"?\";\n}\n\nfunction metaVersion(body: Record<string, unknown>): unknown {\n\tconst params = body[\"params\"];\n\tif (typeof params !== \"object\" || params === null) return undefined;\n\tconst meta = (params as Record<string, unknown>)[\"_meta\"];\n\tif (typeof meta !== \"object\" || meta === null) return undefined;\n\treturn (meta as Record<string, unknown>)[PROTOCOL_VERSION_META_KEY];\n}\n\nconst INDEX_HTML = `<!doctype html>\n<html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>tab-mcp relay</title></head>\n<body><h1>tab-mcp relay</h1>\n<p>This server relays AI apps' MCP requests to tools offered by web pages open in a browser tab.\nIt does not log request contents. Source and documentation:\n<a href=\"https://github.com/ractive/tab-mcp\">github.com/ractive/tab-mcp</a>.</p>\n</body></html>`;\n\n/** Start a relay. Returns once the server listens. */\nexport function createRelay(options: CreateRelayOptions = {}): Relay {\n\treturn startRelay(options, undefined);\n}\n\n/**\n * A relay with test hooks. Only for this repository's tests: it refuses to\n * start outside development and logs a warning.\n */\nexport function createTestRelay(\n\toptions: CreateRelayOptions,\n\thooks: RelayTestHooks,\n): Relay {\n\tif (options.development !== true) {\n\t\tthrow new Error(\"test hooks need development: true\");\n\t}\n\treturn startRelay(options, hooks);\n}\n\nfunction startRelay(\n\toptions: CreateRelayOptions,\n\thooks: RelayTestHooks | undefined,\n): Relay {\n\tconst { store: storeOption, logger: givenLogger, ...partial } = options;\n\tconst tokenStore = typeof storeOption === \"object\" ? storeOption : undefined;\n\tconst config = resolveConfig(\n\t\ttypeof storeOption === \"string\"\n\t\t\t? { ...partial, store: storeOption }\n\t\t\t: partial,\n\t);\n\tconst logger = givenLogger ?? createLogger(config.logLevel);\n\tconst ownsStore = tokenStore === undefined;\n\tconst store: TokenStore =\n\t\ttokenStore ??\n\t\t(config.store === \"sqlite\"\n\t\t\t? new SqliteTokenStore(config.sqlitePath)\n\t\t\t: new MemoryTokenStore());\n\n\tconst sessions = new Map<string, TabSession>();\n\tconst allSessions = new Set<TabSession>();\n\tconst perIp = new Map<string, number>();\n\t/** Requests waiting for their page, per address (DEC-074). */\n\tconst waiters = new Map<string, Set<(s: TabSession | undefined) => void>>();\n\tlet waitingCount = 0;\n\t/**\n\t * Each address's last session: its app name, for \"open <name>\", and its\n\t * site's concurrency limit, for requests that wait for the page.\n\t */\n\tconst lastSeen = new Map<\n\t\tstring,\n\t\t{ appName: string | undefined; maxConcurrentRequests: number }\n\t>();\n\tlet claudeWorkarounds = 0;\n\tlet publicUrl = config.publicUrl ?? \"\";\n\t/** Tab assertions (identity binding, DEC-076), when configured. */\n\tconst assertions =\n\t\tconfig.oidc === undefined\n\t\t\t? undefined\n\t\t\t: new TabAssertionVerifier(\n\t\t\t\t\tconfig.oidc,\n\t\t\t\t\thooks?.assertionKeys,\n\t\t\t\t\thooks?.maxSeenAssertions,\n\t\t\t\t);\n\n\tconst corsHeaders: Record<string, string> = config.cors\n\t\t? {\n\t\t\t\t\"access-control-allow-origin\": \"*\",\n\t\t\t\t\"access-control-expose-headers\":\n\t\t\t\t\t\"www-authenticate, mcp-protocol-version\",\n\t\t\t}\n\t\t: {};\n\n\t/** Tombstones outlive every token issued before the revocation (DEC-063). */\n\tconst revokeOptions = () => {\n\t\tconst now = Date.now();\n\t\treturn { now, keepUntil: now + config.grantLifetimeMs };\n\t};\n\n\tfunction grantRemoved(\n\t\taddressId: string,\n\t\tgrantId: string,\n\t\treason: \"revoked\" | \"reuse_detected\" | \"expired\",\n\t): void {\n\t\tconst session = sessions.get(addressId);\n\t\tif (session?.ready)\n\t\t\tsession.send({ type: \"grant.removed\", grantId, reason });\n\t}\n\n\tconst host = {\n\t\tconfig,\n\t\tlogger,\n\t\tstore,\n\t\t...(hooks?.pairingCodeTtlMs === undefined\n\t\t\t? {}\n\t\t\t: { pairingCodeTtlMs: hooks.pairingCodeTtlMs }),\n\t\tpublicUrl: () => publicUrl,\n\t\tasync revokeGrant(session: TabSession, grantId: string): Promise<boolean> {\n\t\t\tconst addressId = session.addressId;\n\t\t\tif (addressId === undefined) return false;\n\t\t\tconst grants = await store.listGrants(addressId, Date.now());\n\t\t\tif (!grants.some((g) => g.grantId === grantId)) return false;\n\t\t\tawait store.revoke({ grantId }, revokeOptions());\n\t\t\tlogger.info(\"oauth.revoked\", {\n\t\t\t\taddress: shortAddress(addressId),\n\t\t\t\tby: \"tab\",\n\t\t\t});\n\t\t\tgrantRemoved(addressId, grantId, \"revoked\");\n\t\t\treturn true;\n\t\t},\n\t\tasync revokeAll(session: TabSession): Promise<void> {\n\t\t\tconst addressId = session.addressId;\n\t\t\tif (addressId === undefined) return;\n\t\t\tconst grants = await store.listGrants(addressId, Date.now());\n\t\t\tawait store.revoke({ addressId }, revokeOptions());\n\t\t\tlogger.info(\"oauth.revoked_all\", {\n\t\t\t\taddress: shortAddress(addressId),\n\t\t\t\tgrants: grants.length,\n\t\t\t});\n\t\t\tfor (const g of grants) grantRemoved(addressId, g.grantId, \"revoked\");\n\t\t},\n\t\t/**\n\t\t * Called one at a time per session (the session chains `identity` and\n\t\t * `identity.logout`), so a slow check never lands after a later sign-out.\n\t\t * Always answers the tab once: `identity.bound` or `identity_refused`.\n\t\t */\n\t\tasync bindIdentity(\n\t\t\tsession: TabSession,\n\t\t\tassertion: string,\n\t\t\tround?: number,\n\t\t): Promise<void> {\n\t\t\tconst addressId = session.addressId;\n\t\t\tif (addressId === undefined) return;\n\t\t\tconst echo = round === undefined ? {} : { round };\n\t\t\t// The page waits for this answer; a dropped one (backpressure) is\n\t\t\t// logged, and the page's timeout gives up on it (the round tells a late\n\t\t\t// answer from a new one).\n\t\t\tconst answer = (message: RelayMessage) => {\n\t\t\t\tif (!session.send(message)) {\n\t\t\t\t\tlogger.warn(\"identity.answer_dropped\", {\n\t\t\t\t\t\taddress: shortAddress(addressId),\n\t\t\t\t\t\ttype: message.type,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst refuse = (reason: string, message: string) => {\n\t\t\t\t// Fail closed: a refused assertion also ends an earlier binding,\n\t\t\t\t// and the requests made under it. When the relay could not check\n\t\t\t\t// (keys or store unavailable), the AI app is told to try again,\n\t\t\t\t// not to sign in again, until an assertion is checked.\n\t\t\t\tconst transient = TRANSIENT_REFUSALS.has(reason);\n\t\t\t\tsession.identityUnchecked = transient;\n\t\t\t\tif (session.identity !== undefined) {\n\t\t\t\t\tsession.identity = undefined;\n\t\t\t\t\tif (transient) {\n\t\t\t\t\t\tfailPending(session, UNCHECKED_TEXT, true);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfailPending(session, \"The page's user is no longer signed in.\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlogger.info(\"identity.refused\", {\n\t\t\t\t\taddress: shortAddress(addressId),\n\t\t\t\t\treason,\n\t\t\t\t});\n\t\t\t\tanswer({ type: \"error\", code: \"identity_refused\", message, ...echo });\n\t\t\t};\n\t\t\tif (session.site.pairing !== \"oidc\" || assertions === undefined) {\n\t\t\t\trefuse(\"not_oidc\", \"this page's site does not use identity binding\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlet key: string;\n\t\t\ttry {\n\t\t\t\tkey = await assertions.verify(\n\t\t\t\t\tassertion,\n\t\t\t\t\t`${publicUrl}/a/${addressId}/mcp`,\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\trefuse(\n\t\t\t\t\terror instanceof JwtError ? error.reason : \"error\",\n\t\t\t\t\t`the identity assertion was refused: ${error instanceof JwtError ? error.message : \"the relay could not check it\"}`,\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!session.ready) return; // closed meanwhile\n\t\t\tconst changed = session.identity !== key;\n\t\t\tif (changed && session.identity !== undefined) {\n\t\t\t\t// Another person now: nothing more for the old one, before any I/O.\n\t\t\t\tsession.identity = undefined;\n\t\t\t\tfailPending(session, \"The page's user changed.\");\n\t\t\t}\n\t\t\t// Grants made for someone else (or with a code) end now (DEC-077).\n\t\t\tlet revoked = 0;\n\t\t\ttry {\n\t\t\t\tconst grants = await store.listGrants(addressId, Date.now());\n\t\t\t\tfor (const g of grants.filter((g) => g.subject !== key)) {\n\t\t\t\t\tawait store.revoke({ grantId: g.grantId }, revokeOptions());\n\t\t\t\t\tgrantRemoved(addressId, g.grantId, \"revoked\");\n\t\t\t\t\trevoked++;\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"store.error\", {\n\t\t\t\t\top: \"identity\",\n\t\t\t\t\terror: errorName(error),\n\t\t\t\t});\n\t\t\t\trefuse(\"store_unavailable\", \"the relay cannot check grants right now\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!session.ready) return;\n\t\t\tsession.identity = key;\n\t\t\tsession.identityUnchecked = false;\n\t\t\tanswer({ type: \"identity.bound\", ...echo });\n\t\t\tlogger.info(\"identity.bound\", {\n\t\t\t\taddress: shortAddress(addressId),\n\t\t\t\tchanged,\n\t\t\t\trevoked,\n\t\t\t});\n\t\t\thost.ready(session); // requests waiting for a signed-in page go on\n\t\t},\n\t\tasync signOut(session: TabSession): Promise<void> {\n\t\t\tconst addressId = session.addressId;\n\t\t\tif (addressId === undefined) return;\n\t\t\tif (session.site.pairing !== \"oidc\") {\n\t\t\t\tsession.send({\n\t\t\t\t\ttype: \"error\",\n\t\t\t\t\tcode: \"identity_refused\",\n\t\t\t\t\tmessage: \"this page's site does not use identity binding\",\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// First the binding and the requests in flight: they end even if the\n\t\t\t// store fails below.\n\t\t\tsession.identity = undefined;\n\t\t\tsession.identityUnchecked = false;\n\t\t\tfailPending(session, \"The page's user signed out.\");\n\t\t\ttry {\n\t\t\t\tconst grants = await store.listGrants(addressId, Date.now());\n\t\t\t\tawait store.revoke({ addressId }, revokeOptions());\n\t\t\t\tlogger.info(\"identity.signed_out\", {\n\t\t\t\t\taddress: shortAddress(addressId),\n\t\t\t\t\tgrants: grants.length,\n\t\t\t\t});\n\t\t\t\tfor (const g of grants) grantRemoved(addressId, g.grantId, \"revoked\");\n\t\t\t} catch (error) {\n\t\t\t\t// The grants stay, but work only for a page bound to their person.\n\t\t\t\tlogger.error(\"store.error\", { op: \"signOut\", error: errorName(error) });\n\t\t\t}\n\t\t},\n\t\tclaimAddress(session: TabSession): TabSession | undefined {\n\t\t\tconst id = session.addressId;\n\t\t\tif (id === undefined) return undefined;\n\t\t\tconst previous = sessions.get(id);\n\t\t\tsessions.set(id, session);\n\t\t\treturn previous === session ? undefined : previous;\n\t\t},\n\t\treleased(session: TabSession): void {\n\t\t\tallSessions.delete(session);\n\t\t\tif (\n\t\t\t\tsession.addressId !== undefined &&\n\t\t\t\tsessions.get(session.addressId) === session\n\t\t\t) {\n\t\t\t\tsessions.delete(session.addressId);\n\t\t\t}\n\t\t\treleaseIp(session.ip);\n\t\t},\n\t\tready(session: TabSession): void {\n\t\t\tconst id = session.addressId;\n\t\t\tif (id === undefined) return;\n\t\t\tconst appName = session.appName ?? lastSeen.get(id)?.appName;\n\t\t\tlastSeen.delete(id);\n\t\t\tlastSeen.set(id, {\n\t\t\t\tappName,\n\t\t\t\tmaxConcurrentRequests: session.limits.maxConcurrentRequests,\n\t\t\t});\n\t\t\t// Bounded: forget the oldest addresses first.\n\t\t\tif (lastSeen.size > config.maxSessions * 2) {\n\t\t\t\tconst oldest = lastSeen.keys().next().value;\n\t\t\t\tif (oldest !== undefined) lastSeen.delete(oldest);\n\t\t\t}\n\t\t\tconst waiting = waiters.get(id);\n\t\t\tif (waiting !== undefined) for (const wake of [...waiting]) wake(session);\n\t\t},\n\t};\n\n\t/**\n\t * End a session's requests in flight with `-31009`; the page is told to stop\n\t * them. 401 with `WWW-Authenticate`, or, when the relay could not check\n\t * (`transient`), 503 with `Retry-After`, so AI apps keep their tokens.\n\t */\n\tfunction failPending(\n\t\tsession: TabSession,\n\t\tmessage: string,\n\t\ttransient = false,\n\t): void {\n\t\tconst addressId = session.addressId;\n\t\tconst headers: Record<string, string> = transient\n\t\t\t? { \"retry-after\": RETRY_AFTER_S }\n\t\t\t: addressId === undefined\n\t\t\t\t? {}\n\t\t\t\t: { \"www-authenticate\": wwwAuthenticate(addressId, true) };\n\t\tfor (const exchange of [...session.pending.values()]) {\n\t\t\texchange.fail(\n\t\t\t\ttransient ? 503 : 401,\n\t\t\t\tRelayErrorCode.signedOut,\n\t\t\t\tmessage,\n\t\t\t\ttrue,\n\t\t\t\theaders,\n\t\t\t);\n\t\t}\n\t}\n\n\tfunction readySession(\n\t\taddressId: string,\n\t\tusable: (s: TabSession) => boolean = () => true,\n\t): TabSession | undefined {\n\t\tconst s = sessions.get(addressId);\n\t\treturn s?.ready === true && usable(s) ? s : undefined;\n\t}\n\n\t/**\n\t * Whether a session can take a grant's requests: a grant with a subject, or\n\t * any grant on an `oidc` site, needs a page that proved who its user is\n\t * (DEC-077). Whether it is the same person is checked after the wait.\n\t */\n\tfunction usableFor(subject: string | undefined) {\n\t\treturn (s: TabSession) =>\n\t\t\t(subject === undefined && s.site.pairing === \"code\") ||\n\t\t\ts.identity !== undefined;\n\t}\n\n\t/**\n\t * The page's ready session, waiting up to `waitMs` for it (DEC-074).\n\t * `undefined` when it does not come in time or too many requests wait\n\t * already; `\"aborted\"` when the AI app gave up.\n\t */\n\tfunction waitForPage(\n\t\taddressId: string,\n\t\tsignal: AbortSignal,\n\t\twaitMs: number,\n\t\tusable: (s: TabSession) => boolean,\n\t): Promise<TabSession | undefined | \"aborted\"> {\n\t\tconst now = readySession(addressId, usable);\n\t\tif (now !== undefined) return Promise.resolve(now);\n\t\tif (waitMs === 0 || closing) {\n\t\t\treturn Promise.resolve(undefined);\n\t\t}\n\t\tconst set = waiters.get(addressId) ?? new Set();\n\t\t// A waiting request holds its body and a socket like a forwarded one: at\n\t\t// most maxConcurrentRequests per address (its site's, as far as known,\n\t\t// so none gets 429 when the page comes), maxSessions in all.\n\t\tconst limit =\n\t\t\tsessions.get(addressId)?.limits.maxConcurrentRequests ??\n\t\t\tlastSeen.get(addressId)?.maxConcurrentRequests ??\n\t\t\tconfig.maxConcurrentRequests;\n\t\tif (set.size >= limit || waitingCount >= config.maxSessions) {\n\t\t\treturn Promise.resolve(undefined);\n\t\t}\n\t\treturn new Promise((resolve) => {\n\t\t\tlet timer: Timer | undefined;\n\t\t\tlet settled = false;\n\t\t\tconst done = (result: TabSession | undefined | \"aborted\") => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\tset.delete(wake);\n\t\t\t\twaitingCount--;\n\t\t\t\tif (set.size === 0 && waiters.get(addressId) === set) {\n\t\t\t\t\twaiters.delete(addressId);\n\t\t\t\t}\n\t\t\t\tresolve(result);\n\t\t\t};\n\t\t\tconst wake = (session: TabSession | undefined) => {\n\t\t\t\tif (session === undefined || usable(session)) done(session);\n\t\t\t};\n\t\t\tconst onAbort = () => done(\"aborted\");\n\t\t\tset.add(wake);\n\t\t\twaiters.set(addressId, set);\n\t\t\twaitingCount++;\n\t\t\ttimer = setTimeout(() => done(undefined), waitMs);\n\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\tif (signal.aborted) onAbort();\n\t\t});\n\t}\n\n\tfunction releaseIp(ip: string): void {\n\t\tconst n = (perIp.get(ip) ?? 1) - 1;\n\t\tif (n <= 0) perIp.delete(ip);\n\t\telse perIp.set(ip, n);\n\t}\n\n\tfunction clientIp(req: Request, server: Server<WsData>): string {\n\t\tif (config.trustProxy === \"x-real-ip\") {\n\t\t\tconst v = req.headers.get(\"x-real-ip\")?.trim();\n\t\t\tif (v) return v;\n\t\t} else if (config.trustProxy === \"x-forwarded-for\") {\n\t\t\tconst parts = (req.headers.get(\"x-forwarded-for\") ?? \"\")\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim())\n\t\t\t\t.filter((s) => s !== \"\");\n\t\t\tconst last = parts.at(-1);\n\t\t\tif (last !== undefined) return last;\n\t\t}\n\t\treturn server.requestIP(req)?.address ?? \"unknown\";\n\t}\n\n\tconst auth = new AuthorizationServer(\n\t\t{\n\t\t\tconfig,\n\t\t\tlogger,\n\t\t\tstore,\n\t\t\tpublicUrl: () => publicUrl,\n\t\t\tsession: (addressId) => {\n\t\t\t\tconst s = sessions.get(addressId);\n\t\t\t\treturn s?.ready === true ? s : undefined;\n\t\t\t},\n\t\t\tgrantAdded: (addressId: string, grant: GrantInfo) => {\n\t\t\t\tconst session = sessions.get(addressId);\n\t\t\t\tif (session?.ready) session.send({ type: \"grant.added\", grant });\n\t\t\t},\n\t\t\tgrantRemoved: (addressId, grantId, reason) =>\n\t\t\t\tgrantRemoved(\n\t\t\t\t\taddressId,\n\t\t\t\t\tgrantId,\n\t\t\t\t\treason as \"revoked\" | \"reuse_detected\" | \"expired\",\n\t\t\t\t),\n\t\t},\n\t\thooks,\n\t);\n\tif (hooks !== undefined) {\n\t\tlogger.warn(\"relay.test_hooks\", {\n\t\t\tmessage: \"test hooks are on: never use this relay outside tests\",\n\t\t});\n\t}\n\n\tfunction handleTab(\n\t\treq: Request,\n\t\tserver: Server<WsData>,\n\t): Response | undefined {\n\t\tconst origin = req.headers.get(\"origin\");\n\t\tconst site = siteFor(config, origin);\n\t\tif (site === undefined) {\n\t\t\tlogger.info(\"tab.refused\", { reason: \"origin\" });\n\t\t\treturn json(403, { error: \"origin_not_allowed\" });\n\t\t}\n\t\tconst offered = (req.headers.get(\"sec-websocket-protocol\") ?? \"\")\n\t\t\t.split(\",\")\n\t\t\t.map((s) => s.trim());\n\t\tif (!offered.includes(SUBPROTOCOL)) {\n\t\t\treturn json(426, {\n\t\t\t\terror: \"unsupported_protocol\",\n\t\t\t\tsupported: [SUBPROTOCOL],\n\t\t\t});\n\t\t}\n\t\t// The address id for a load balancer to route by (DEC-098). Optional\n\t\t// (libraries before 0.8 do not send it); checked against the secret\n\t\t// in hello. Never the secret itself: URLs end up in access logs.\n\t\tconst address = rawAddressParam(new URL(req.url).search);\n\t\tif (address === false) {\n\t\t\tlogger.info(\"tab.refused\", { reason: \"bad_address\" });\n\t\t\treturn json(400, { error: \"bad_address\" });\n\t\t}\n\t\tconst realIp = clientIp(req, server);\n\t\t// Counted per /64 for IPv6 (DEC-061): one subscriber owns a whole /64.\n\t\tconst ip = ipPrefixKey(realIp);\n\t\tif (allSessions.size >= config.maxSessions) {\n\t\t\tlogger.warn(\"tab.refused\", { reason: \"max_sessions\" });\n\t\t\treturn json(429, { error: \"too_many_sessions\" });\n\t\t}\n\t\tconst count = perIp.get(ip) ?? 0;\n\t\tif (count >= config.maxSessionsPerIp) {\n\t\t\tlogger.warn(\"tab.refused\", {\n\t\t\t\treason: \"max_sessions_per_ip\",\n\t\t\t\tip: truncateIp(realIp),\n\t\t\t});\n\t\t\treturn json(429, { error: \"too_many_sessions\" });\n\t\t}\n\t\tperIp.set(ip, count + 1);\n\t\tconst ok = server.upgrade(req, {\n\t\t\tdata: {\n\t\t\t\tip,\n\t\t\t\torigin: origin ?? \"\",\n\t\t\t\tsite,\n\t\t\t\t...(address === undefined ? {} : { address }),\n\t\t\t},\n\t\t\theaders: { \"Sec-WebSocket-Protocol\": SUBPROTOCOL },\n\t\t});\n\t\tif (ok) return undefined;\n\t\treleaseIp(ip);\n\t\treturn json(400, { error: \"websocket_upgrade_expected\" });\n\t}\n\n\tfunction wwwAuthenticate(id: string, presented: boolean): string {\n\t\tconst metadata = `${publicUrl}/.well-known/oauth-protected-resource/a/${id}/mcp`;\n\t\tconst error = presented ? ', error=\"invalid_token\"' : \"\";\n\t\treturn `Bearer resource_metadata=\"${metadata}\", scope=\"tools\"${error}`;\n\t}\n\n\tasync function authenticate(\n\t\treq: Request,\n\t\taddressId: string,\n\t): Promise<TokenRecord | \"missing\" | \"invalid\" | \"unavailable\"> {\n\t\tconst header = req.headers.get(\"authorization\");\n\t\tif (header === null) return \"missing\";\n\t\tconst match = /^Bearer ([A-Za-z0-9._~+/-]+=*)$/i.exec(header.trim());\n\t\tconst token = match?.[1];\n\t\tif (token === undefined) return \"invalid\";\n\t\tlet record: TokenRecord | undefined;\n\t\ttry {\n\t\t\trecord = await store.get(hashToken(token));\n\t\t} catch (error) {\n\t\t\tlogger.error(\"store.error\", { op: \"get\", error: errorName(error) });\n\t\t\treturn \"unavailable\";\n\t\t}\n\t\tif (\n\t\t\trecord === undefined ||\n\t\t\trecord.kind !== \"access\" ||\n\t\t\trecord.addressId !== addressId ||\n\t\t\trecord.expiresAt <= Date.now() ||\n\t\t\t!record.scopes.includes(\"tools\")\n\t\t) {\n\t\t\treturn \"invalid\";\n\t\t}\n\t\treturn record;\n\t}\n\n\tasync function readBody(\n\t\treq: Request,\n\t\tmaxBytes: number,\n\t): Promise<Body | Response> {\n\t\tconst length = Number(req.headers.get(\"content-length\") ?? \"0\");\n\t\tif (length > maxBytes) {\n\t\t\treturn rpcError(\n\t\t\t\t413,\n\t\t\t\tundefined,\n\t\t\t\t-32600,\n\t\t\t\t\"Request body too large.\",\n\t\t\t\tcorsHeaders,\n\t\t\t);\n\t\t}\n\t\tlet bytes: ArrayBuffer;\n\t\ttry {\n\t\t\t// Bun's idle timeout does not fire while a body is being read, so a\n\t\t\t// client that stalls mid-body would hold the socket; our own deadline\n\t\t\t// answers 408 and closes the connection.\n\t\t\tconst reading = req.arrayBuffer();\n\t\t\treading.catch(() => {}); // rejects once the socket is closed\n\t\t\tlet timer: Timer | undefined;\n\t\t\tconst deadline = new Promise<\"timeout\">((resolve) => {\n\t\t\t\ttimer = setTimeout(() => resolve(\"timeout\"), config.bodyTimeoutMs);\n\t\t\t});\n\t\t\tlet result: ArrayBuffer | \"timeout\";\n\t\t\ttry {\n\t\t\t\tresult = await Promise.race([reading, deadline]);\n\t\t\t} finally {\n\t\t\t\tclearTimeout(timer);\n\t\t\t}\n\t\t\tif (result === \"timeout\") {\n\t\t\t\treturn rpcError(\n\t\t\t\t\t408,\n\t\t\t\t\tundefined,\n\t\t\t\t\t-32600,\n\t\t\t\t\t\"The request body did not arrive in time.\",\n\t\t\t\t\t{ ...corsHeaders, connection: \"close\" },\n\t\t\t\t);\n\t\t\t}\n\t\t\tbytes = result;\n\t\t} catch {\n\t\t\treturn rpcError(\n\t\t\t\t400,\n\t\t\t\tundefined,\n\t\t\t\t-32700,\n\t\t\t\t\"Could not read the request body.\",\n\t\t\t\tcorsHeaders,\n\t\t\t);\n\t\t}\n\t\tif (bytes.byteLength > maxBytes) {\n\t\t\treturn rpcError(\n\t\t\t\t413,\n\t\t\t\tundefined,\n\t\t\t\t-32600,\n\t\t\t\t\"Request body too large.\",\n\t\t\t\tcorsHeaders,\n\t\t\t);\n\t\t}\n\t\tlet text: string;\n\t\tlet value: unknown;\n\t\ttry {\n\t\t\ttext = new TextDecoder(\"utf-8\", { fatal: true }).decode(bytes);\n\t\t\tvalue = JSON.parse(text);\n\t\t} catch {\n\t\t\treturn rpcError(400, undefined, -32700, \"Parse error.\", corsHeaders);\n\t\t}\n\t\tif (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n\t\t\treturn rpcError(\n\t\t\t\t400,\n\t\t\t\tundefined,\n\t\t\t\t-32600,\n\t\t\t\t\"The body must be one JSON-RPC message (no batches).\",\n\t\t\t\tcorsHeaders,\n\t\t\t);\n\t\t}\n\t\treturn { value: value as Record<string, unknown>, text };\n\t}\n\n\t/** DEC-033 / DEC-040: the protocol-version pre-check. */\n\tfunction checkVersion(\n\t\treq: Request,\n\t\tbody: Record<string, unknown>,\n\t\trpcId: RpcId | undefined,\n\t): Response | { forwardVersion: string } {\n\t\tconst header = req.headers.get(\"mcp-protocol-version\");\n\t\t// An initialize in a 2026-07-28 envelope is an ordinary request for a\n\t\t// method the tab does not have: forwarded, so the tab answers 404 and\n\t\t// -32601 like any removed method.\n\t\tif (\n\t\t\tbody[\"method\"] === \"initialize\" &&\n\t\t\t!(\n\t\t\t\theader === MCP_PROTOCOL_VERSION &&\n\t\t\t\tmetaVersion(body) === MCP_PROTOCOL_VERSION\n\t\t\t)\n\t\t) {\n\t\t\tconst params = body[\"params\"] as Record<string, unknown> | undefined;\n\t\t\tconst requested =\n\t\t\t\ttypeof params?.[\"protocolVersion\"] === \"string\"\n\t\t\t\t\t? params[\"protocolVersion\"]\n\t\t\t\t\t: (header ?? null);\n\t\t\treturn rpcError(\n\t\t\t\t400,\n\t\t\t\trpcId,\n\t\t\t\t-32022,\n\t\t\t\t`Unsupported protocol version: ${String(requested)}. This server supports only ${MCP_PROTOCOL_VERSION}.`,\n\t\t\t\tcorsHeaders,\n\t\t\t\t{ supported: [MCP_PROTOCOL_VERSION], requested },\n\t\t\t);\n\t\t}\n\t\tif (header === MCP_PROTOCOL_VERSION) return { forwardVersion: header };\n\t\tif (\n\t\t\theader === CLAUDE_MISMATCHED_HEADER &&\n\t\t\tmetaVersion(body) === MCP_PROTOCOL_VERSION\n\t\t) {\n\t\t\t// Logged once per process; the running count is in /healthz.\n\t\t\tif (++claudeWorkarounds === 1) {\n\t\t\t\tlogger.info(\"mcp.claude_header_workaround\", {\n\t\t\t\t\tmessage:\n\t\t\t\t\t\t\"accepting MCP-Protocol-Version 2025-11-25 with a 2026-07-28 body (claude-code #93290); counted in /healthz\",\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn { forwardVersion: MCP_PROTOCOL_VERSION };\n\t\t}\n\t\tif (header === null) {\n\t\t\treturn rpcError(\n\t\t\t\t400,\n\t\t\t\trpcId,\n\t\t\t\t-32020,\n\t\t\t\t\"Missing MCP-Protocol-Version header.\",\n\t\t\t\tcorsHeaders,\n\t\t\t);\n\t\t}\n\t\treturn rpcError(\n\t\t\t400,\n\t\t\trpcId,\n\t\t\t-32022,\n\t\t\t`Unsupported protocol version: ${header}. This server supports only ${MCP_PROTOCOL_VERSION}.`,\n\t\t\tcorsHeaders,\n\t\t\t{ supported: [MCP_PROTOCOL_VERSION], requested: header },\n\t\t);\n\t}\n\n\tasync function handleMcp(\n\t\treq: Request,\n\t\tserver: Server<WsData>,\n\t\taddressId: string,\n\t): Promise<Response> {\n\t\tconst started = Date.now();\n\t\tconst logDone = (\n\t\t\tstatus: number,\n\t\t\tmethod: string,\n\t\t\textra: Record<string, string | number> = {},\n\t\t) =>\n\t\t\tlogger.info(\"mcp.request\", {\n\t\t\t\taddress: shortAddress(addressId),\n\t\t\t\tmethod,\n\t\t\t\tstatus,\n\t\t\t\tdurationMs: Date.now() - started,\n\t\t\t\t...extra,\n\t\t\t});\n\n\t\t// The page's own limit when it is connected; else the instance's (the\n\t\t// request then ends with 401 or 503 anyway).\n\t\tconst body = await readBody(\n\t\t\treq,\n\t\t\tsessions.get(addressId)?.limits.maxMessageBytes ?? config.maxMessageBytes,\n\t\t);\n\t\tif (body instanceof Response) {\n\t\t\tlogDone(body.status, \"?\");\n\t\t\treturn body;\n\t\t}\n\t\tconst rpcId = rpcIdOf(body.value);\n\t\tconst method = methodForLog(body.value);\n\n\t\tconst version = checkVersion(req, body.value, rpcId);\n\t\tif (version instanceof Response) {\n\t\t\tlogDone(version.status, method);\n\t\t\treturn version;\n\t\t}\n\n\t\tconst auth = await authenticate(req, addressId);\n\t\tif (auth === \"unavailable\") {\n\t\t\t// Not the token's fault: a 401 would make clients drop valid tokens.\n\t\t\tlogDone(503, method, { reason: \"store_unavailable\" });\n\t\t\treturn rpcError(\n\t\t\t\t503,\n\t\t\t\trpcId,\n\t\t\t\tRelayErrorCode.storeUnavailable,\n\t\t\t\t\"The relay cannot check tokens right now. Try again shortly.\",\n\t\t\t\t{ ...corsHeaders, \"retry-after\": RETRY_AFTER_S },\n\t\t\t);\n\t\t}\n\t\tif (typeof auth === \"string\") {\n\t\t\tlogDone(401, method);\n\t\t\treturn json(\n\t\t\t\t401,\n\t\t\t\t{\n\t\t\t\t\terror: \"invalid_token\",\n\t\t\t\t\terror_description:\n\t\t\t\t\t\tauth === \"missing\"\n\t\t\t\t\t\t\t? \"Authorization required.\"\n\t\t\t\t\t\t\t: \"The access token is not valid.\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t...corsHeaders,\n\t\t\t\t\t\"www-authenticate\": wwwAuthenticate(addressId, auth === \"invalid\"),\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\n\t\tconst headers: Record<string, string> = {};\n\t\tfor (const [k, v] of req.headers) {\n\t\t\tconst key = k.toLowerCase();\n\t\t\tif (FORWARDED_HEADERS.has(key) || key.startsWith(\"mcp-param-\"))\n\t\t\t\theaders[key] = v;\n\t\t}\n\t\theaders[\"mcp-protocol-version\"] = version.forwardVersion;\n\n\t\tconst clientHostName = (() => {\n\t\t\ttry {\n\t\t\t\treturn new URL(auth.clientId).host;\n\t\t\t} catch {\n\t\t\t\treturn \"\";\n\t\t\t}\n\t\t})();\n\t\tconst isListen = body.value[\"method\"] === \"subscriptions/listen\";\n\t\t// `server/discover` does not wait: clients use it as the protocol-era\n\t\t// probe with a short timeout (Claude Code: 5 s, then it falls back to\n\t\t// the legacy handshake), and the stand-in answer has `ttlMs: 0`.\n\t\tconst waitMs =\n\t\t\tbody.value[\"method\"] === \"server/discover\" ||\n\t\t\t// Only small requests wait: a waiting request holds its body, and\n\t\t\t// tool calls are small (review of iteration 8).\n\t\t\tBuffer.byteLength(body.text) > MIN_MESSAGE_BYTES\n\t\t\t\t? 0\n\t\t\t\t: config.pageWaitMs;\n\t\tconst closed = () => {\n\t\t\tlogDone(499, method, { outcome: \"client_closed\" });\n\t\t\treturn new Response(null, { status: 499 });\n\t\t};\n\n\t\t// Only now, for an authenticated request, switch off Bun's idle timer:\n\t\t// our own timers (the page wait, the request timer) and keep-alives take\n\t\t// over (Bun research, finding 1). Body reading and every unauthenticated\n\t\t// path keep the idle timeout, so a stalled client cannot hold a socket.\n\t\t// It is switched on again on every exit, while the response is still in\n\t\t// progress: Bun ignores a timeout set once the response has finished.\n\t\tconst idle = (on: boolean) =>\n\t\t\tserver.timeout(req, on ? config.httpIdleTimeoutS : 0);\n\t\tconst usable = usableFor(auth.subject);\n\n\t\t/** The page's session to forward to, or the answer when there is none. */\n\t\tconst admit = async (): Promise<TabSession | Response> => {\n\t\t\tconst found = await waitForPage(addressId, req.signal, waitMs, usable);\n\t\t\t// The AI app may have gone while the body was read, the token checked\n\t\t\t// or the page awaited: then forward nothing (the abort event has\n\t\t\t// already fired and would not cancel the exchange, which would hold a\n\t\t\t// slot until the timeout).\n\t\t\tif (found === \"aborted\" || req.signal.aborted) return closed();\n\t\t\tif (found === undefined) {\n\t\t\t\treturn pageNotOpen(body.value, rpcId, addressId, logDone, method);\n\t\t\t}\n\t\t\tconst session = found;\n\t\t\t// Identity binding: only the person the grant was made for (DEC-077).\n\t\t\tif (\n\t\t\t\t(auth.subject !== undefined || session.site.pairing === \"oidc\") &&\n\t\t\t\tsession.identity !== auth.subject\n\t\t\t) {\n\t\t\t\tlogDone(401, method, { reason: \"identity_mismatch\" });\n\t\t\t\treturn json(\n\t\t\t\t\t401,\n\t\t\t\t\t{ error: \"invalid_token\", error_description: MISMATCH_TEXT },\n\t\t\t\t\t{\n\t\t\t\t\t\t...corsHeaders,\n\t\t\t\t\t\t\"www-authenticate\": `${wwwAuthenticate(addressId, true)}, error_description=\"${MISMATCH_TEXT}\"`,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t\t// The body was read with the instance's limit if the page was not\n\t\t\t// open yet; its site may allow less.\n\t\t\tif (Buffer.byteLength(body.text) > session.limits.maxMessageBytes) {\n\t\t\t\tlogDone(413, method);\n\t\t\t\treturn rpcError(\n\t\t\t\t\t413,\n\t\t\t\t\trpcId,\n\t\t\t\t\t-32600,\n\t\t\t\t\t\"Request body too large.\",\n\t\t\t\t\tcorsHeaders,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (session.pending.size >= session.limits.maxConcurrentRequests) {\n\t\t\t\tlogDone(429, method);\n\t\t\t\treturn rpcError(\n\t\t\t\t\t429,\n\t\t\t\t\trpcId,\n\t\t\t\t\tRelayErrorCode.overloaded,\n\t\t\t\t\t\"Too many requests at once for this page.\",\n\t\t\t\t\tcorsHeaders,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (\n\t\t\t\tisListen &&\n\t\t\t\tsession.listenStreams(auth.grantId) >= MAX_LISTEN_STREAMS_PER_GRANT\n\t\t\t) {\n\t\t\t\tlogDone(429, method, { reason: \"listen_streams\" });\n\t\t\t\treturn rpcError(\n\t\t\t\t\t429,\n\t\t\t\t\trpcId,\n\t\t\t\t\tRelayErrorCode.overloaded,\n\t\t\t\t\t\"Too many listen streams at once for this AI app.\",\n\t\t\t\t\tcorsHeaders,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn session;\n\t\t};\n\n\t\tif (readySession(addressId, usable) === undefined && waitMs > 0) {\n\t\t\tidle(false);\n\t\t}\n\t\tlet retried = false;\n\t\tfor (;;) {\n\t\t\tconst admitted = await admit();\n\t\t\tif (admitted instanceof Response) {\n\t\t\t\tidle(true);\n\t\t\t\treturn admitted;\n\t\t\t}\n\t\t\tconst session = admitted;\n\t\t\tidle(false);\n\t\t\tlet retry: () => void = () => {};\n\t\t\tconst retrying = new Promise<typeof RETRY>((resolve) => {\n\t\t\t\tretry = () => resolve(RETRY);\n\t\t\t});\n\t\t\tconst mayRetry =\n\t\t\t\t!retried && waitMs > 0 && isRetryable(body.value[\"method\"]);\n\t\t\tconst exchange = session.forward({\n\t\t\t\theaders,\n\t\t\t\tbody: body.text,\n\t\t\t\trpcId,\n\t\t\t\tisListen,\n\t\t\t\tgrant: {\n\t\t\t\t\tgrantId: auth.grantId,\n\t\t\t\t\tclientId: auth.clientId,\n\t\t\t\t\tscopes: auth.scopes,\n\t\t\t\t},\n\t\t\t\textraHeaders: corsHeaders,\n\t\t\t\tonDone: (e: Exchange) => {\n\t\t\t\t\tif (e.outcome === \"page_gone_retry\") return; // logged once, at the end\n\t\t\t\t\tidle(true);\n\t\t\t\t\tlogDone(e.status, method, {\n\t\t\t\t\t\tsession: session.sessionId,\n\t\t\t\t\t\tclient: clientHostName,\n\t\t\t\t\t\toutcome: e.outcome,\n\t\t\t\t\t\t...(e.outcome === \"page_gone\" ? { reason: \"page_not_open\" } : {}),\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tpageGone: (waiting) => {\n\t\t\t\t\tif (waiting && mayRetry && !req.signal.aborted) {\n\t\t\t\t\t\tretry();\n\t\t\t\t\t\treturn { retry: true };\n\t\t\t\t\t}\n\t\t\t\t\tconst answer = notOpenAnswer(\n\t\t\t\t\t\tbody.value,\n\t\t\t\t\t\trpcId,\n\t\t\t\t\t\tsession.appName,\n\t\t\t\t\t\tclosing ? \"restarting_gone\" : \"gone\",\n\t\t\t\t\t\tRELAY_INFO,\n\t\t\t\t\t);\n\t\t\t\t\tif (answer !== undefined) return { retry: false, body: answer };\n\t\t\t\t\t// A notification: an HTTP error, which says \"restarting\" too.\n\t\t\t\t\treturn !closing\n\t\t\t\t\t\t? { retry: false }\n\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\tretry: false,\n\t\t\t\t\t\t\t\terror: {\n\t\t\t\t\t\t\t\t\tstatus: 503,\n\t\t\t\t\t\t\t\t\tcode: RelayErrorCode.restarting,\n\t\t\t\t\t\t\t\t\tmessage: \"The relay is restarting.\",\n\t\t\t\t\t\t\t\t\theaders: { \"retry-after\": RETRY_AFTER_S },\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t});\n\t\t\tconst onAbort = () => exchange.clientClosed();\n\t\t\treq.signal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\tconst result = await Promise.race([exchange.response, retrying]);\n\t\t\tif (result !== RETRY) return result;\n\t\t\treq.signal.removeEventListener(\"abort\", onAbort);\n\t\t\tretried = true;\n\t\t}\n\t}\n\n\t/**\n\t * DEC-074: HTTP 200 and a JSON-RPC message, not an HTTP error status. While\n\t * the relay stops, the answer says it restarts (iteration 11, finding 5).\n\t */\n\tfunction pageNotOpen(\n\t\tvalue: Record<string, unknown>,\n\t\trpcId: RpcId | undefined,\n\t\taddressId: string,\n\t\tlogDone: (\n\t\t\tstatus: number,\n\t\t\tmethod: string,\n\t\t\textra?: Record<string, string | number>,\n\t\t) => void,\n\t\tmethod: string,\n\t): Response {\n\t\t// Open but not signed in (identity binding) reads differently.\n\t\tconst open = sessions.get(addressId);\n\t\tif (\n\t\t\t!closing &&\n\t\t\topen?.ready === true &&\n\t\t\topen.identity === undefined &&\n\t\t\topen.identityUnchecked\n\t\t) {\n\t\t\t// The relay could not check the page's user: not the user's errand.\n\t\t\tlogDone(503, method, { reason: \"identity_unchecked\" });\n\t\t\treturn rpcError(503, rpcId, RelayErrorCode.signedOut, UNCHECKED_TEXT, {\n\t\t\t\t...corsHeaders,\n\t\t\t\t\"retry-after\": RETRY_AFTER_S,\n\t\t\t});\n\t\t}\n\t\tconst phase: NotOpenPhase = closing\n\t\t\t? \"restarting\"\n\t\t\t: open?.ready === true &&\n\t\t\t\t\topen.identity === undefined &&\n\t\t\t\t\topen.site.pairing === \"oidc\"\n\t\t\t\t? \"signed_out\"\n\t\t\t\t: \"not_open\";\n\t\tconst reason = phase === \"restarting\" ? \"restarting\" : \"page_not_open\";\n\t\tconst answer = notOpenAnswer(\n\t\t\tvalue,\n\t\t\trpcId,\n\t\t\topen?.appName ?? lastSeen.get(addressId)?.appName,\n\t\t\tphase,\n\t\t\tRELAY_INFO,\n\t\t);\n\t\tif (answer === undefined) {\n\t\t\t// A notification: the spec requires an HTTP error status.\n\t\t\tlogDone(503, method, { reason });\n\t\t\treturn phase === \"restarting\"\n\t\t\t\t? rpcError(\n\t\t\t\t\t\t503,\n\t\t\t\t\t\trpcId,\n\t\t\t\t\t\tRelayErrorCode.restarting,\n\t\t\t\t\t\t\"The relay is restarting.\",\n\t\t\t\t\t\t{ ...corsHeaders, \"retry-after\": RETRY_AFTER_S },\n\t\t\t\t\t)\n\t\t\t\t: rpcError(\n\t\t\t\t\t\t503,\n\t\t\t\t\t\trpcId,\n\t\t\t\t\t\tRelayErrorCode.pageNotOpen,\n\t\t\t\t\t\t\"The page is not open.\",\n\t\t\t\t\t\tcorsHeaders,\n\t\t\t\t\t);\n\t\t}\n\t\tlogDone(200, method, { reason });\n\t\treturn new Response(answer, {\n\t\t\tstatus: 200,\n\t\t\theaders: { ...corsHeaders, \"content-type\": \"application/json\" },\n\t\t});\n\t}\n\n\tfunction preflight(req: Request): Response {\n\t\tif (!config.cors)\n\t\t\treturn new Response(null, { status: 405, headers: { allow: \"POST\" } });\n\t\tconst requested = req.headers.get(\"access-control-request-headers\") ?? \"\";\n\t\treturn new Response(null, {\n\t\t\tstatus: 204,\n\t\t\theaders: {\n\t\t\t\t...corsHeaders,\n\t\t\t\t\"access-control-allow-methods\": \"POST, OPTIONS\",\n\t\t\t\t\"access-control-allow-headers\":\n\t\t\t\t\trequested !== \"\"\n\t\t\t\t\t\t? requested\n\t\t\t\t\t\t: \"authorization, content-type, accept, mcp-protocol-version, mcp-method, mcp-name\",\n\t\t\t\t\"access-control-max-age\": \"600\",\n\t\t\t},\n\t\t});\n\t}\n\n\tconst methodNotAllowed = () =>\n\t\tnew Response(null, {\n\t\t\tstatus: 405,\n\t\t\theaders: { ...corsHeaders, allow: \"POST\" },\n\t\t});\n\n\tconst postOnly = () =>\n\t\tnew Response(null, { status: 405, headers: { allow: \"POST, OPTIONS\" } });\n\n\t/**\n\t * Whether the token store answers (DEC-099): one cheap read of a hash that\n\t * never exists, with a deadline. One probe at a time, and its answer is\n\t * reused for a second, so a flood of `/healthz` does not reach the store.\n\t * While a read that missed its deadline still hangs, a new one starts only\n\t * every `healthRetryMs` (30 s): a store that lost one command recovers, and\n\t * a hung store holds at most one read per window.\n\t */\n\tconst healthRetryMs = hooks?.healthRetryMs ?? HEALTH_HUNG_RETRY_MS;\n\tlet probe: Promise<StoreHealth> | undefined;\n\tlet probed: { at: number; result: StoreHealth } | undefined;\n\tlet hungReads = 0;\n\tlet lastHungAt = 0;\n\tasync function runProbe(): Promise<StoreHealth> {\n\t\tlet timer: Timer | undefined;\n\t\tconst deadline = new Promise<\"store_timeout\">((resolve) => {\n\t\t\ttimer = setTimeout(\n\t\t\t\t() => resolve(\"store_timeout\"),\n\t\t\t\tHEALTH_STORE_TIMEOUT_MS,\n\t\t\t);\n\t\t});\n\t\t// Inside a promise chain, so a store that throws synchronously is a\n\t\t// failed probe like any other.\n\t\tconst read = Promise.resolve()\n\t\t\t.then(() => store.get(HEALTH_PROBE_HASH))\n\t\t\t.then(() => \"ok\" as const);\n\t\tread.catch(() => {}); // a late rejection after the deadline\n\t\ttry {\n\t\t\tconst result = await Promise.race([read, deadline]);\n\t\t\tif (result === \"store_timeout\") {\n\t\t\t\tlogger.warn(\"health.store\", { error: \"timeout\" });\n\t\t\t\thungReads++;\n\t\t\t\tlastHungAt = Date.now();\n\t\t\t\tconst settled = () => {\n\t\t\t\t\thungReads--;\n\t\t\t\t};\n\t\t\t\tread.then(settled, settled);\n\t\t\t}\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tlogger.warn(\"health.store\", { error: errorName(error) });\n\t\t\treturn \"store_unavailable\";\n\t\t} finally {\n\t\t\tclearTimeout(timer);\n\t\t}\n\t}\n\tfunction storeHealth(): Promise<StoreHealth> {\n\t\tif (probe !== undefined) return probe;\n\t\tconst now = Date.now();\n\t\tif (probed !== undefined && now - probed.at < HEALTH_REUSE_MS) {\n\t\t\treturn Promise.resolve(probed.result);\n\t\t}\n\t\tif (hungReads > 0 && now - lastHungAt < healthRetryMs) {\n\t\t\treturn Promise.resolve(\"store_timeout\");\n\t\t}\n\t\tconst current = runProbe().catch((): StoreHealth => \"store_unavailable\");\n\t\tprobe = current;\n\t\tvoid current.then((result) => {\n\t\t\tprobed = { at: Date.now(), result };\n\t\t\tif (probe === current) probe = undefined;\n\t\t});\n\t\treturn current;\n\t}\n\n\tconst largest = largestMessageBytes(config);\n\tconst ipOf = (req: Request, srv: Server<WsData>) =>\n\t\tipPrefixKey(clientIp(req, srv));\n\tconst server = Bun.serve({\n\t\tport: config.port,\n\t\thostname: config.host,\n\t\tdevelopment: false,\n\t\tmaxRequestBodySize: largest + 1024,\n\t\tidleTimeout: config.httpIdleTimeoutS,\n\t\troutes: {\n\t\t\t\"/healthz\": {\n\t\t\t\t// no-store: a CDN in front caches answers without cache headers\n\t\t\t\t// (bunny for 30 days), and a deploy check would read the old version.\n\t\t\t\tGET: async () => {\n\t\t\t\t\tconst store = await storeHealth();\n\t\t\t\t\tif (store !== \"ok\") {\n\t\t\t\t\t\t// A reason code only: never the store's error (DEC-099).\n\t\t\t\t\t\treturn json(\n\t\t\t\t\t\t\t503,\n\t\t\t\t\t\t\t{ status: \"unhealthy\", reason: store, version: VERSION },\n\t\t\t\t\t\t\t{ \"cache-control\": \"no-store\" },\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn json(\n\t\t\t\t\t\t200,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstatus: \"ok\",\n\t\t\t\t\t\t\tversion: VERSION,\n\t\t\t\t\t\t\tcounters: { claudeHeaderWorkaround: claudeWorkarounds },\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ \"cache-control\": \"no-store\" },\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"/\": {\n\t\t\t\tGET: () =>\n\t\t\t\t\tnew Response(INDEX_HTML, {\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\"content-type\": \"text/html; charset=utf-8\",\n\t\t\t\t\t\t\t\"content-security-policy\":\n\t\t\t\t\t\t\t\t\"default-src 'none'; frame-ancestors 'none'\",\n\t\t\t\t\t\t\t\"x-content-type-options\": \"nosniff\",\n\t\t\t\t\t\t\t\"cache-control\": \"public, max-age=3600\",\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t},\n\t\t\t\"/tab\": (req, srv) => handleTab(req, srv),\n\t\t\t\"/.well-known/oauth-authorization-server\": {\n\t\t\t\tGET: () => auth.metadata(),\n\t\t\t\tOPTIONS: () => auth.preflight(\"GET\"),\n\t\t\t},\n\t\t\t\"/.well-known/oauth-protected-resource/a/:id/mcp\": {\n\t\t\t\tGET: (req) => auth.protectedResource(req.params.id),\n\t\t\t\tOPTIONS: () => auth.preflight(\"GET\"),\n\t\t\t},\n\t\t\t\"/authorize\": {\n\t\t\t\tGET: (req, srv) => auth.authorize(req, ipOf(req, srv)),\n\t\t\t\tPOST: (req, srv) => auth.authorizeSubmit(req, ipOf(req, srv)),\n\t\t\t},\n\t\t\t\"/authorize/callback\": {\n\t\t\t\tGET: (req, srv) => auth.authorizeCallback(req, ipOf(req, srv)),\n\t\t\t},\n\t\t\t\"/authorize.css\": { GET: () => auth.stylesheet() },\n\t\t\t\"/token\": {\n\t\t\t\tPOST: (req, srv) => auth.token(req, ipOf(req, srv)),\n\t\t\t\tOPTIONS: () => auth.preflight(\"POST\"),\n\t\t\t\tGET: postOnly,\n\t\t\t},\n\t\t\t\"/revoke\": {\n\t\t\t\tPOST: (req, srv) => auth.revoke(req, ipOf(req, srv)),\n\t\t\t\tOPTIONS: () => auth.preflight(\"POST\"),\n\t\t\t\tGET: postOnly,\n\t\t\t},\n\t\t\t\"/a/:id/mcp\": {\n\t\t\t\tPOST: (req, srv) => {\n\t\t\t\t\tconst id = req.params.id;\n\t\t\t\t\tif (!isAddressId(id))\n\t\t\t\t\t\treturn new Response(\"Not found\", { status: 404 });\n\t\t\t\t\treturn handleMcp(req, srv, id);\n\t\t\t\t},\n\t\t\t\tOPTIONS: (req) => preflight(req),\n\t\t\t\tGET: methodNotAllowed,\n\t\t\t\tDELETE: methodNotAllowed,\n\t\t\t\tPUT: methodNotAllowed,\n\t\t\t\tPATCH: methodNotAllowed,\n\t\t\t},\n\t\t},\n\t\tfetch: () => new Response(\"Not found\", { status: 404 }),\n\t\twebsocket: {\n\t\t\tdata: {} as WsData,\n\t\t\tmaxPayloadLength: largest * FRAME_HEADROOM,\n\t\t\tbackpressureLimit: config.backpressureLimitBytes,\n\t\t\tcloseOnBackpressureLimit: false,\n\t\t\tidleTimeout: 120,\n\t\t\tsendPings: true,\n\t\t\tperMessageDeflate: false,\n\t\t\topen(ws: ServerWebSocket<WsData>) {\n\t\t\t\tconst session = new TabSession(\n\t\t\t\t\tws,\n\t\t\t\t\tws.data.ip,\n\t\t\t\t\tws.data.origin,\n\t\t\t\t\tws.data.site,\n\t\t\t\t\thost,\n\t\t\t\t\tws.data.address,\n\t\t\t\t);\n\t\t\t\tws.data.session = session;\n\t\t\t\tallSessions.add(session);\n\t\t\t},\n\t\t\tmessage(ws: ServerWebSocket<WsData>, message: string | Buffer) {\n\t\t\t\tws.data.session?.handleFrame(\n\t\t\t\t\ttypeof message === \"string\" ? message : new Uint8Array(message),\n\t\t\t\t);\n\t\t\t},\n\t\t\tclose(ws: ServerWebSocket<WsData>, code: number) {\n\t\t\t\tws.data.session?.closed(code);\n\t\t\t},\n\t\t},\n\t});\n\n\tlet stopping: Promise<void> | undefined;\n\t/** Set at once by `stop()`, before the sessions end (their requests read it). */\n\tlet closing = false;\n\tconst port = server.port ?? config.port;\n\tif (publicUrl === \"\") publicUrl = `http://localhost:${port}`;\n\n\tconst sweep = setInterval(() => {\n\t\tauth.sweep();\n\t\tstore\n\t\t\t.deleteExpired(Date.now())\n\t\t\t.then((n) => {\n\t\t\t\tif (n > 0) logger.debug(\"store.swept\", { deleted: n });\n\t\t\t})\n\t\t\t.catch((error: unknown) =>\n\t\t\t\tlogger.error(\"store.error\", {\n\t\t\t\t\top: \"deleteExpired\",\n\t\t\t\t\terror: errorName(error),\n\t\t\t\t}),\n\t\t\t);\n\t}, config.sweepIntervalMs);\n\n\tconst siteCount =\n\t\tconfig.allowedOrigins === \"*\"\n\t\t\t? \"*\"\n\t\t\t: config.allowedOrigins.length + config.sites.length;\n\tif (config.allowedOrigins === \"*\") {\n\t\tlogger.warn(\"relay.open_relay\", {\n\t\t\tmessage:\n\t\t\t\t\"TAB_MCP_ALLOWED_ORIGINS=* lets any website open tab sessions on this relay\",\n\t\t});\n\t} else if (siteCount === 0) {\n\t\tlogger.warn(\"relay.no_origins\", {\n\t\t\tmessage:\n\t\t\t\t\"TAB_MCP_ALLOWED_ORIGINS and TAB_MCP_SITES are empty: no page can connect\",\n\t\t});\n\t}\n\tlogger.info(\"relay.start\", {\n\t\tversion: VERSION,\n\t\turl: publicUrl,\n\t\tport,\n\t\tstore: ownsStore ? config.store : \"custom\",\n\t\torigins: siteCount,\n\t});\n\n\treturn {\n\t\turl: publicUrl,\n\t\tport,\n\t\tconfig,\n\t\taddressFor: (secret) => `${publicUrl}/a/${addressIdFromSecret(secret)}/mcp`,\n\t\tget sessionCount() {\n\t\t\treturn allSessions.size;\n\t\t},\n\t\tstop() {\n\t\t\tclosing = true;\n\t\t\tstopping ??= (async () => {\n\t\t\t\tclearInterval(sweep);\n\t\t\t\tfor (const set of [...waiters.values()]) {\n\t\t\t\t\tfor (const wake of [...set]) wake(undefined);\n\t\t\t\t}\n\t\t\t\tfor (const session of [...allSessions]) {\n\t\t\t\t\tsession.end(\n\t\t\t\t\t\tCloseCode.shuttingDown,\n\t\t\t\t\t\t\"relay shutting down\",\n\t\t\t\t\t\t\"shutdown\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tawait Bun.sleep(20); // let close frames leave\n\t\t\t\tawait server.stop(true);\n\t\t\t\tif (ownsStore) await store.close?.();\n\t\t\t\tlogger.info(\"relay.stop\", {});\n\t\t\t})();\n\t\t\treturn stopping;\n\t\t},\n\t};\n}\n"
25
+ "import type { Server, ServerWebSocket } from \"bun\";\nimport { version } from \"../package.json\" with { type: \"json\" };\nimport { addressIdFromSecret, isAddressId, shortAddress } from \"./address.ts\";\nimport {\n\tlargestMessageBytes,\n\tMIN_MESSAGE_BYTES,\n\ttype RelayConfig,\n\tresolveConfig,\n\ttype Site,\n\ttype StoreKind,\n\tsiteFor,\n} from \"./config.ts\";\nimport {\n\ttype Exchange,\n\tRelayErrorCode,\n\ttype RpcId,\n\trpcErrorBody,\n} from \"./exchange.ts\";\nimport { APPLE_TOUCH_ICON, FAVICON_ICO, FAVICON_SVG } from \"./icons.ts\";\nimport { MISMATCH_TEXT, TabAssertionVerifier } from \"./identity.ts\";\nimport { ipPrefixKey } from \"./ip.ts\";\nimport { JwtError, type KeySource } from \"./jwt.ts\";\nimport { createLogger, errorName, type Logger, truncateIp } from \"./log.ts\";\nimport {\n\tisRetryable,\n\ttype NotOpenPhase,\n\tnotOpenAnswer,\n\ttype RelayInfo,\n} from \"./notopen.ts\";\nimport {\n\tAuthorizationServer,\n\ttype AuthorizationTestMode,\n} from \"./oauth/server.ts\";\nimport {\n\tCloseCode,\n\ttype GrantInfo,\n\tMCP_PROTOCOL_VERSION,\n\tPROTOCOL_VERSION_META_KEY,\n\ttype RelayMessage,\n\tSUBPROTOCOL,\n} from \"./protocol.ts\";\nimport { TabSession } from \"./session.ts\";\nimport { MemoryTokenStore } from \"./store/memory.ts\";\nimport { SqliteTokenStore } from \"./store/sqlite.ts\";\nimport type { TokenRecord, TokenStore } from \"./store/types.ts\";\nimport { hashToken } from \"./tokens.ts\";\n\nexport const VERSION: string = version;\n\nconst RELAY_INFO: RelayInfo = { name: \"tab-mcp\", version };\n\n/** Settles the race between an exchange and its page going away. */\nconst RETRY = Symbol(\"retry\");\n\n/** The one mismatched header Claude sends today (claude-code #93290, DEC-033). */\nconst CLAUDE_MISMATCHED_HEADER = \"2025-11-25\";\n\n/**\n * Listen streams one grant may hold on a page at once: they have no request\n * timer, so without a cap one AI app could take every concurrency slot.\n */\nconst MAX_LISTEN_STREAMS_PER_GRANT = 2;\n\n/**\n * Bun closes a WebSocket whose frame is over `maxPayloadLength` (1009). Frames\n * up to this many times the largest site limit get a `too_large` error instead\n * and the session stays; they are refused by length, before parsing.\n */\nconst FRAME_HEADROOM = 4;\n\n/**\n * Refusals of a tab assertion that say nothing about the user: the relay could\n * not check (signing keys or store unavailable, an unexpected error).\n */\nconst TRANSIENT_REFUSALS = new Set([\n\t\"jwks_unavailable\",\n\t\"store_unavailable\",\n\t\"relay_busy\",\n\t\"error\",\n]);\n\n/** The text for requests that cannot be checked against the page's user. */\nconst UNCHECKED_TEXT =\n\t\"The relay cannot check the page's user right now. Try again shortly.\";\n\n/** `Retry-After` (seconds) for answers that ask an AI app to try again soon. */\nconst RETRY_AFTER_S = \"5\";\n\n/** Request headers forwarded to the tab (protocol: tunnelled MCP requests). */\nconst FORWARDED_HEADERS = new Set([\n\t\"content-type\",\n\t\"accept\",\n\t\"mcp-method\",\n\t\"mcp-name\",\n\t\"traceparent\",\n\t\"tracestate\",\n]);\n\nexport interface CreateRelayOptions\n\textends Omit<Partial<RelayConfig>, \"store\"> {\n\t/**\n\t * The token store: a `TokenStore` instance (e.g. Prisma, Redis), or the name\n\t * of a built-in one (`\"sqlite\"`, the default, at `sqlitePath`; `\"memory\"`).\n\t */\n\tstore?: StoreKind | TokenStore;\n\t/** Logger; defaults to JSON lines on stdout at `logLevel`. */\n\tlogger?: Logger;\n}\n\nexport interface Relay {\n\t/** The external origin (issuer and address base). */\n\treadonly url: string;\n\t/** The port the server listens on. */\n\treadonly port: number;\n\treadonly config: RelayConfig;\n\t/** The MCP address a page with this secret gets. */\n\taddressFor(secret: string): string;\n\t/** Number of connected tab sessions. */\n\treadonly sessionCount: number;\n\t/** Close all sessions (bye `shutdown`, close 4004) and stop the server. */\n\tstop(): Promise<void>;\n}\n\n/** What `/healthz` says about the token store (DEC-099). */\ntype StoreHealth = \"ok\" | \"store_unavailable\" | \"store_timeout\";\n/** How long the health probe waits for the store. */\nconst HEALTH_STORE_TIMEOUT_MS = 1000;\n/** How long a probe's answer is reused. */\nconst HEALTH_REUSE_MS = 1000;\n/** While an earlier read hangs, how long before a new one is tried. */\nconst HEALTH_HUNG_RETRY_MS = 30_000;\n/** A store key no token ever has (a token's hash is of `tmcp_…`). */\nconst HEALTH_PROBE_HASH = hashToken(\"tab-mcp /healthz probe\");\n\n/**\n * The `a` parameter of a `/tab` query, read from the raw text: `undefined`\n * when absent, `false` when malformed or repeated. Only the literal id\n * counts, never a percent-encoded one, so the relay agrees with a load\n * balancer that matches the URL as sent (review of PR 38).\n */\nfunction rawAddressParam(search: string): string | undefined | false {\n\tlet found: string | undefined;\n\tfor (const pair of search.replace(/^\\?/, \"\").split(\"&\")) {\n\t\tif (pair === \"\") continue;\n\t\tconst eq = pair.indexOf(\"=\");\n\t\tconst rawName = eq < 0 ? pair : pair.slice(0, eq);\n\t\tlet name: string;\n\t\ttry {\n\t\t\tname = decodeURIComponent(rawName.replaceAll(\"+\", \" \"));\n\t\t} catch {\n\t\t\tcontinue; // not ours: other parameters are ignored\n\t\t}\n\t\tif (name !== \"a\") continue;\n\t\tconst value = eq < 0 ? \"\" : pair.slice(eq + 1);\n\t\tif (rawName !== \"a\" || found !== undefined || !isAddressId(value)) {\n\t\t\treturn false;\n\t\t}\n\t\tfound = value;\n\t}\n\treturn found;\n}\n\ninterface WsData {\n\tip: string;\n\torigin: string;\n\tsite: Site;\n\t/** The address id the URL named (`/tab?a=`, DEC-098). */\n\taddress?: string;\n\tsession?: TabSession;\n}\n\n/**\n * Test-only relaxations, never reachable from configuration or the package's\n * public API (`createTestRelay` is not exported from the package): CIMD\n * fetches from loopback test servers, shorter code lifetimes.\n */\nexport interface RelayTestHooks extends AuthorizationTestMode {\n\tpairingCodeTtlMs?: number;\n\t/** Keys for tab assertions instead of fetching the JWKS URL. */\n\tassertionKeys?: KeySource;\n\t/** A smaller relay-wide replay cache for tab assertions. */\n\tmaxSeenAssertions?: number;\n\t/** How long `/healthz` waits before a new read while one hangs. */\n\thealthRetryMs?: number;\n}\n\ninterface Body {\n\tvalue: Record<string, unknown>;\n\ttext: string;\n}\n\nfunction json(\n\tstatus: number,\n\tvalue: unknown,\n\theaders?: Record<string, string>,\n): Response {\n\tconst h = new Headers(headers);\n\th.set(\"content-type\", \"application/json\");\n\treturn new Response(JSON.stringify(value), { status, headers: h });\n}\n\nfunction rpcError(\n\tstatus: number,\n\trpcId: RpcId | undefined,\n\tcode: number,\n\tmessage: string,\n\theaders: Record<string, string>,\n\tdata?: unknown,\n): Response {\n\treturn new Response(rpcErrorBody(rpcId, code, message, data), {\n\t\tstatus,\n\t\theaders: { ...headers, \"content-type\": \"application/json\" },\n\t});\n}\n\nfunction rpcIdOf(body: Record<string, unknown>): RpcId | undefined {\n\tif (!(\"id\" in body)) return undefined;\n\tconst id = body[\"id\"];\n\treturn typeof id === \"string\" || typeof id === \"number\" ? id : null;\n}\n\n/** A loggable MCP method name (attacker-controlled input, so constrained). */\nfunction methodForLog(body: Record<string, unknown>): string {\n\tconst m = body[\"method\"];\n\treturn typeof m === \"string\" && /^[A-Za-z0-9_/.-]{1,64}$/.test(m) ? m : \"?\";\n}\n\nfunction metaVersion(body: Record<string, unknown>): unknown {\n\tconst params = body[\"params\"];\n\tif (typeof params !== \"object\" || params === null) return undefined;\n\tconst meta = (params as Record<string, unknown>)[\"_meta\"];\n\tif (typeof meta !== \"object\" || meta === null) return undefined;\n\treturn (meta as Record<string, unknown>)[PROTOCOL_VERSION_META_KEY];\n}\n\nconst INDEX_HTML = `<!doctype html>\n<html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>tab-mcp relay</title>\n<link rel=\"icon\" href=\"/favicon.ico\" sizes=\"32x32\"><link rel=\"icon\" href=\"/favicon.svg\" type=\"image/svg+xml\">\n<link rel=\"apple-touch-icon\" href=\"/apple-touch-icon.png\"></head>\n<body><h1>tab-mcp relay</h1>\n<p>This server relays AI apps' MCP requests to tools offered by web pages open in a browser tab.\nIt does not log request contents. Source and documentation:\n<a href=\"https://github.com/ractive/tab-mcp\">github.com/ractive/tab-mcp</a>.</p>\n</body></html>`;\n\nfunction icon(body: string | Uint8Array<ArrayBuffer>, type: string): Response {\n\treturn new Response(body, {\n\t\theaders: {\n\t\t\t\"content-type\": type,\n\t\t\t\"content-security-policy\": \"default-src 'none'\",\n\t\t\t\"x-content-type-options\": \"nosniff\",\n\t\t\t\"cache-control\": \"public, max-age=86400\",\n\t\t},\n\t});\n}\n\n/** Start a relay. Returns once the server listens. */\nexport function createRelay(options: CreateRelayOptions = {}): Relay {\n\treturn startRelay(options, undefined);\n}\n\n/**\n * A relay with test hooks. Only for this repository's tests: it refuses to\n * start outside development and logs a warning.\n */\nexport function createTestRelay(\n\toptions: CreateRelayOptions,\n\thooks: RelayTestHooks,\n): Relay {\n\tif (options.development !== true) {\n\t\tthrow new Error(\"test hooks need development: true\");\n\t}\n\treturn startRelay(options, hooks);\n}\n\nfunction startRelay(\n\toptions: CreateRelayOptions,\n\thooks: RelayTestHooks | undefined,\n): Relay {\n\tconst { store: storeOption, logger: givenLogger, ...partial } = options;\n\tconst tokenStore = typeof storeOption === \"object\" ? storeOption : undefined;\n\tconst config = resolveConfig(\n\t\ttypeof storeOption === \"string\"\n\t\t\t? { ...partial, store: storeOption }\n\t\t\t: partial,\n\t);\n\tconst logger = givenLogger ?? createLogger(config.logLevel);\n\tconst ownsStore = tokenStore === undefined;\n\tconst store: TokenStore =\n\t\ttokenStore ??\n\t\t(config.store === \"sqlite\"\n\t\t\t? new SqliteTokenStore(config.sqlitePath)\n\t\t\t: new MemoryTokenStore());\n\n\tconst sessions = new Map<string, TabSession>();\n\tconst allSessions = new Set<TabSession>();\n\tconst perIp = new Map<string, number>();\n\t/** Requests waiting for their page, per address (DEC-074). */\n\tconst waiters = new Map<string, Set<(s: TabSession | undefined) => void>>();\n\tlet waitingCount = 0;\n\t/**\n\t * Each address's last session: its app name, for \"open <name>\", and its\n\t * site's concurrency limit, for requests that wait for the page.\n\t */\n\tconst lastSeen = new Map<\n\t\tstring,\n\t\t{ appName: string | undefined; maxConcurrentRequests: number }\n\t>();\n\tlet claudeWorkarounds = 0;\n\tlet publicUrl = config.publicUrl ?? \"\";\n\t/** Tab assertions (identity binding, DEC-076), when configured. */\n\tconst assertions =\n\t\tconfig.oidc === undefined\n\t\t\t? undefined\n\t\t\t: new TabAssertionVerifier(\n\t\t\t\t\tconfig.oidc,\n\t\t\t\t\thooks?.assertionKeys,\n\t\t\t\t\thooks?.maxSeenAssertions,\n\t\t\t\t);\n\n\tconst corsHeaders: Record<string, string> = config.cors\n\t\t? {\n\t\t\t\t\"access-control-allow-origin\": \"*\",\n\t\t\t\t\"access-control-expose-headers\":\n\t\t\t\t\t\"www-authenticate, mcp-protocol-version\",\n\t\t\t}\n\t\t: {};\n\n\t/** Tombstones outlive every token issued before the revocation (DEC-063). */\n\tconst revokeOptions = () => {\n\t\tconst now = Date.now();\n\t\treturn { now, keepUntil: now + config.grantLifetimeMs };\n\t};\n\n\tfunction grantRemoved(\n\t\taddressId: string,\n\t\tgrantId: string,\n\t\treason: \"revoked\" | \"reuse_detected\" | \"expired\",\n\t): void {\n\t\tconst session = sessions.get(addressId);\n\t\tif (session?.ready)\n\t\t\tsession.send({ type: \"grant.removed\", grantId, reason });\n\t}\n\n\tconst host = {\n\t\tconfig,\n\t\tlogger,\n\t\tstore,\n\t\t...(hooks?.pairingCodeTtlMs === undefined\n\t\t\t? {}\n\t\t\t: { pairingCodeTtlMs: hooks.pairingCodeTtlMs }),\n\t\tpublicUrl: () => publicUrl,\n\t\tasync revokeGrant(session: TabSession, grantId: string): Promise<boolean> {\n\t\t\tconst addressId = session.addressId;\n\t\t\tif (addressId === undefined) return false;\n\t\t\tconst grants = await store.listGrants(addressId, Date.now());\n\t\t\tif (!grants.some((g) => g.grantId === grantId)) return false;\n\t\t\tawait store.revoke({ grantId }, revokeOptions());\n\t\t\tlogger.info(\"oauth.revoked\", {\n\t\t\t\taddress: shortAddress(addressId),\n\t\t\t\tby: \"tab\",\n\t\t\t});\n\t\t\tgrantRemoved(addressId, grantId, \"revoked\");\n\t\t\treturn true;\n\t\t},\n\t\tasync revokeAll(session: TabSession): Promise<void> {\n\t\t\tconst addressId = session.addressId;\n\t\t\tif (addressId === undefined) return;\n\t\t\tconst grants = await store.listGrants(addressId, Date.now());\n\t\t\tawait store.revoke({ addressId }, revokeOptions());\n\t\t\tlogger.info(\"oauth.revoked_all\", {\n\t\t\t\taddress: shortAddress(addressId),\n\t\t\t\tgrants: grants.length,\n\t\t\t});\n\t\t\tfor (const g of grants) grantRemoved(addressId, g.grantId, \"revoked\");\n\t\t},\n\t\t/**\n\t\t * Called one at a time per session (the session chains `identity` and\n\t\t * `identity.logout`), so a slow check never lands after a later sign-out.\n\t\t * Always answers the tab once: `identity.bound` or `identity_refused`.\n\t\t */\n\t\tasync bindIdentity(\n\t\t\tsession: TabSession,\n\t\t\tassertion: string,\n\t\t\tround?: number,\n\t\t): Promise<void> {\n\t\t\tconst addressId = session.addressId;\n\t\t\tif (addressId === undefined) return;\n\t\t\tconst echo = round === undefined ? {} : { round };\n\t\t\t// The page waits for this answer; a dropped one (backpressure) is\n\t\t\t// logged, and the page's timeout gives up on it (the round tells a late\n\t\t\t// answer from a new one).\n\t\t\tconst answer = (message: RelayMessage) => {\n\t\t\t\tif (!session.send(message)) {\n\t\t\t\t\tlogger.warn(\"identity.answer_dropped\", {\n\t\t\t\t\t\taddress: shortAddress(addressId),\n\t\t\t\t\t\ttype: message.type,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst refuse = (reason: string, message: string) => {\n\t\t\t\t// Fail closed: a refused assertion also ends an earlier binding,\n\t\t\t\t// and the requests made under it. When the relay could not check\n\t\t\t\t// (keys or store unavailable), the AI app is told to try again,\n\t\t\t\t// not to sign in again, until an assertion is checked.\n\t\t\t\tconst transient = TRANSIENT_REFUSALS.has(reason);\n\t\t\t\tsession.identityUnchecked = transient;\n\t\t\t\tif (session.identity !== undefined) {\n\t\t\t\t\tsession.identity = undefined;\n\t\t\t\t\tif (transient) {\n\t\t\t\t\t\tfailPending(session, UNCHECKED_TEXT, true);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfailPending(session, \"The page's user is no longer signed in.\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlogger.info(\"identity.refused\", {\n\t\t\t\t\taddress: shortAddress(addressId),\n\t\t\t\t\treason,\n\t\t\t\t});\n\t\t\t\tanswer({ type: \"error\", code: \"identity_refused\", message, ...echo });\n\t\t\t};\n\t\t\tif (session.site.pairing !== \"oidc\" || assertions === undefined) {\n\t\t\t\trefuse(\"not_oidc\", \"this page's site does not use identity binding\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlet key: string;\n\t\t\ttry {\n\t\t\t\tkey = await assertions.verify(\n\t\t\t\t\tassertion,\n\t\t\t\t\t`${publicUrl}/a/${addressId}/mcp`,\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\trefuse(\n\t\t\t\t\terror instanceof JwtError ? error.reason : \"error\",\n\t\t\t\t\t`the identity assertion was refused: ${error instanceof JwtError ? error.message : \"the relay could not check it\"}`,\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!session.ready) return; // closed meanwhile\n\t\t\tconst changed = session.identity !== key;\n\t\t\tif (changed && session.identity !== undefined) {\n\t\t\t\t// Another person now: nothing more for the old one, before any I/O.\n\t\t\t\tsession.identity = undefined;\n\t\t\t\tfailPending(session, \"The page's user changed.\");\n\t\t\t}\n\t\t\t// Grants made for someone else (or with a code) end now (DEC-077).\n\t\t\tlet revoked = 0;\n\t\t\ttry {\n\t\t\t\tconst grants = await store.listGrants(addressId, Date.now());\n\t\t\t\tfor (const g of grants.filter((g) => g.subject !== key)) {\n\t\t\t\t\tawait store.revoke({ grantId: g.grantId }, revokeOptions());\n\t\t\t\t\tgrantRemoved(addressId, g.grantId, \"revoked\");\n\t\t\t\t\trevoked++;\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"store.error\", {\n\t\t\t\t\top: \"identity\",\n\t\t\t\t\terror: errorName(error),\n\t\t\t\t});\n\t\t\t\trefuse(\"store_unavailable\", \"the relay cannot check grants right now\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!session.ready) return;\n\t\t\tsession.identity = key;\n\t\t\tsession.identityUnchecked = false;\n\t\t\tanswer({ type: \"identity.bound\", ...echo });\n\t\t\tlogger.info(\"identity.bound\", {\n\t\t\t\taddress: shortAddress(addressId),\n\t\t\t\tchanged,\n\t\t\t\trevoked,\n\t\t\t});\n\t\t\thost.ready(session); // requests waiting for a signed-in page go on\n\t\t},\n\t\tasync signOut(session: TabSession): Promise<void> {\n\t\t\tconst addressId = session.addressId;\n\t\t\tif (addressId === undefined) return;\n\t\t\tif (session.site.pairing !== \"oidc\") {\n\t\t\t\tsession.send({\n\t\t\t\t\ttype: \"error\",\n\t\t\t\t\tcode: \"identity_refused\",\n\t\t\t\t\tmessage: \"this page's site does not use identity binding\",\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// First the binding and the requests in flight: they end even if the\n\t\t\t// store fails below.\n\t\t\tsession.identity = undefined;\n\t\t\tsession.identityUnchecked = false;\n\t\t\tfailPending(session, \"The page's user signed out.\");\n\t\t\ttry {\n\t\t\t\tconst grants = await store.listGrants(addressId, Date.now());\n\t\t\t\tawait store.revoke({ addressId }, revokeOptions());\n\t\t\t\tlogger.info(\"identity.signed_out\", {\n\t\t\t\t\taddress: shortAddress(addressId),\n\t\t\t\t\tgrants: grants.length,\n\t\t\t\t});\n\t\t\t\tfor (const g of grants) grantRemoved(addressId, g.grantId, \"revoked\");\n\t\t\t} catch (error) {\n\t\t\t\t// The grants stay, but work only for a page bound to their person.\n\t\t\t\tlogger.error(\"store.error\", { op: \"signOut\", error: errorName(error) });\n\t\t\t}\n\t\t},\n\t\tclaimAddress(session: TabSession): TabSession | undefined {\n\t\t\tconst id = session.addressId;\n\t\t\tif (id === undefined) return undefined;\n\t\t\tconst previous = sessions.get(id);\n\t\t\tsessions.set(id, session);\n\t\t\treturn previous === session ? undefined : previous;\n\t\t},\n\t\treleased(session: TabSession): void {\n\t\t\tallSessions.delete(session);\n\t\t\tif (\n\t\t\t\tsession.addressId !== undefined &&\n\t\t\t\tsessions.get(session.addressId) === session\n\t\t\t) {\n\t\t\t\tsessions.delete(session.addressId);\n\t\t\t}\n\t\t\treleaseIp(session.ip);\n\t\t},\n\t\tready(session: TabSession): void {\n\t\t\tconst id = session.addressId;\n\t\t\tif (id === undefined) return;\n\t\t\tconst appName = session.appName ?? lastSeen.get(id)?.appName;\n\t\t\tlastSeen.delete(id);\n\t\t\tlastSeen.set(id, {\n\t\t\t\tappName,\n\t\t\t\tmaxConcurrentRequests: session.limits.maxConcurrentRequests,\n\t\t\t});\n\t\t\t// Bounded: forget the oldest addresses first.\n\t\t\tif (lastSeen.size > config.maxSessions * 2) {\n\t\t\t\tconst oldest = lastSeen.keys().next().value;\n\t\t\t\tif (oldest !== undefined) lastSeen.delete(oldest);\n\t\t\t}\n\t\t\tconst waiting = waiters.get(id);\n\t\t\tif (waiting !== undefined) for (const wake of [...waiting]) wake(session);\n\t\t},\n\t};\n\n\t/**\n\t * End a session's requests in flight with `-31009`; the page is told to stop\n\t * them. 401 with `WWW-Authenticate`, or, when the relay could not check\n\t * (`transient`), 503 with `Retry-After`, so AI apps keep their tokens.\n\t */\n\tfunction failPending(\n\t\tsession: TabSession,\n\t\tmessage: string,\n\t\ttransient = false,\n\t): void {\n\t\tconst addressId = session.addressId;\n\t\tconst headers: Record<string, string> = transient\n\t\t\t? { \"retry-after\": RETRY_AFTER_S }\n\t\t\t: addressId === undefined\n\t\t\t\t? {}\n\t\t\t\t: { \"www-authenticate\": wwwAuthenticate(addressId, true) };\n\t\tfor (const exchange of [...session.pending.values()]) {\n\t\t\texchange.fail(\n\t\t\t\ttransient ? 503 : 401,\n\t\t\t\tRelayErrorCode.signedOut,\n\t\t\t\tmessage,\n\t\t\t\ttrue,\n\t\t\t\theaders,\n\t\t\t);\n\t\t}\n\t}\n\n\tfunction readySession(\n\t\taddressId: string,\n\t\tusable: (s: TabSession) => boolean = () => true,\n\t): TabSession | undefined {\n\t\tconst s = sessions.get(addressId);\n\t\treturn s?.ready === true && usable(s) ? s : undefined;\n\t}\n\n\t/**\n\t * Whether a session can take a grant's requests: a grant with a subject, or\n\t * any grant on an `oidc` site, needs a page that proved who its user is\n\t * (DEC-077). Whether it is the same person is checked after the wait.\n\t */\n\tfunction usableFor(subject: string | undefined) {\n\t\treturn (s: TabSession) =>\n\t\t\t(subject === undefined && s.site.pairing === \"code\") ||\n\t\t\ts.identity !== undefined;\n\t}\n\n\t/**\n\t * The page's ready session, waiting up to `waitMs` for it (DEC-074).\n\t * `undefined` when it does not come in time or too many requests wait\n\t * already; `\"aborted\"` when the AI app gave up.\n\t */\n\tfunction waitForPage(\n\t\taddressId: string,\n\t\tsignal: AbortSignal,\n\t\twaitMs: number,\n\t\tusable: (s: TabSession) => boolean,\n\t): Promise<TabSession | undefined | \"aborted\"> {\n\t\tconst now = readySession(addressId, usable);\n\t\tif (now !== undefined) return Promise.resolve(now);\n\t\tif (waitMs === 0 || closing) {\n\t\t\treturn Promise.resolve(undefined);\n\t\t}\n\t\tconst set = waiters.get(addressId) ?? new Set();\n\t\t// A waiting request holds its body and a socket like a forwarded one: at\n\t\t// most maxConcurrentRequests per address (its site's, as far as known,\n\t\t// so none gets 429 when the page comes), maxSessions in all.\n\t\tconst limit =\n\t\t\tsessions.get(addressId)?.limits.maxConcurrentRequests ??\n\t\t\tlastSeen.get(addressId)?.maxConcurrentRequests ??\n\t\t\tconfig.maxConcurrentRequests;\n\t\tif (set.size >= limit || waitingCount >= config.maxSessions) {\n\t\t\treturn Promise.resolve(undefined);\n\t\t}\n\t\treturn new Promise((resolve) => {\n\t\t\tlet timer: Timer | undefined;\n\t\t\tlet settled = false;\n\t\t\tconst done = (result: TabSession | undefined | \"aborted\") => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\tset.delete(wake);\n\t\t\t\twaitingCount--;\n\t\t\t\tif (set.size === 0 && waiters.get(addressId) === set) {\n\t\t\t\t\twaiters.delete(addressId);\n\t\t\t\t}\n\t\t\t\tresolve(result);\n\t\t\t};\n\t\t\tconst wake = (session: TabSession | undefined) => {\n\t\t\t\tif (session === undefined || usable(session)) done(session);\n\t\t\t};\n\t\t\tconst onAbort = () => done(\"aborted\");\n\t\t\tset.add(wake);\n\t\t\twaiters.set(addressId, set);\n\t\t\twaitingCount++;\n\t\t\ttimer = setTimeout(() => done(undefined), waitMs);\n\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\tif (signal.aborted) onAbort();\n\t\t});\n\t}\n\n\tfunction releaseIp(ip: string): void {\n\t\tconst n = (perIp.get(ip) ?? 1) - 1;\n\t\tif (n <= 0) perIp.delete(ip);\n\t\telse perIp.set(ip, n);\n\t}\n\n\tfunction clientIp(req: Request, server: Server<WsData>): string {\n\t\tif (config.trustProxy === \"x-real-ip\") {\n\t\t\tconst v = req.headers.get(\"x-real-ip\")?.trim();\n\t\t\tif (v) return v;\n\t\t} else if (config.trustProxy === \"x-forwarded-for\") {\n\t\t\tconst parts = (req.headers.get(\"x-forwarded-for\") ?? \"\")\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim())\n\t\t\t\t.filter((s) => s !== \"\");\n\t\t\tconst last = parts.at(-1);\n\t\t\tif (last !== undefined) return last;\n\t\t}\n\t\treturn server.requestIP(req)?.address ?? \"unknown\";\n\t}\n\n\tconst auth = new AuthorizationServer(\n\t\t{\n\t\t\tconfig,\n\t\t\tlogger,\n\t\t\tstore,\n\t\t\tpublicUrl: () => publicUrl,\n\t\t\tsession: (addressId) => {\n\t\t\t\tconst s = sessions.get(addressId);\n\t\t\t\treturn s?.ready === true ? s : undefined;\n\t\t\t},\n\t\t\tgrantAdded: (addressId: string, grant: GrantInfo) => {\n\t\t\t\tconst session = sessions.get(addressId);\n\t\t\t\tif (session?.ready) session.send({ type: \"grant.added\", grant });\n\t\t\t},\n\t\t\tgrantRemoved: (addressId, grantId, reason) =>\n\t\t\t\tgrantRemoved(\n\t\t\t\t\taddressId,\n\t\t\t\t\tgrantId,\n\t\t\t\t\treason as \"revoked\" | \"reuse_detected\" | \"expired\",\n\t\t\t\t),\n\t\t},\n\t\thooks,\n\t);\n\tif (hooks !== undefined) {\n\t\tlogger.warn(\"relay.test_hooks\", {\n\t\t\tmessage: \"test hooks are on: never use this relay outside tests\",\n\t\t});\n\t}\n\n\tfunction handleTab(\n\t\treq: Request,\n\t\tserver: Server<WsData>,\n\t): Response | undefined {\n\t\tconst origin = req.headers.get(\"origin\");\n\t\tconst site = siteFor(config, origin);\n\t\tif (site === undefined) {\n\t\t\tlogger.info(\"tab.refused\", { reason: \"origin\" });\n\t\t\treturn json(403, { error: \"origin_not_allowed\" });\n\t\t}\n\t\tconst offered = (req.headers.get(\"sec-websocket-protocol\") ?? \"\")\n\t\t\t.split(\",\")\n\t\t\t.map((s) => s.trim());\n\t\tif (!offered.includes(SUBPROTOCOL)) {\n\t\t\treturn json(426, {\n\t\t\t\terror: \"unsupported_protocol\",\n\t\t\t\tsupported: [SUBPROTOCOL],\n\t\t\t});\n\t\t}\n\t\t// The address id for a load balancer to route by (DEC-098). Optional\n\t\t// (libraries before 0.8 do not send it); checked against the secret\n\t\t// in hello. Never the secret itself: URLs end up in access logs.\n\t\tconst address = rawAddressParam(new URL(req.url).search);\n\t\tif (address === false) {\n\t\t\tlogger.info(\"tab.refused\", { reason: \"bad_address\" });\n\t\t\treturn json(400, { error: \"bad_address\" });\n\t\t}\n\t\tconst realIp = clientIp(req, server);\n\t\t// Counted per /64 for IPv6 (DEC-061): one subscriber owns a whole /64.\n\t\tconst ip = ipPrefixKey(realIp);\n\t\tif (allSessions.size >= config.maxSessions) {\n\t\t\tlogger.warn(\"tab.refused\", { reason: \"max_sessions\" });\n\t\t\treturn json(429, { error: \"too_many_sessions\" });\n\t\t}\n\t\tconst count = perIp.get(ip) ?? 0;\n\t\tif (count >= config.maxSessionsPerIp) {\n\t\t\tlogger.warn(\"tab.refused\", {\n\t\t\t\treason: \"max_sessions_per_ip\",\n\t\t\t\tip: truncateIp(realIp),\n\t\t\t});\n\t\t\treturn json(429, { error: \"too_many_sessions\" });\n\t\t}\n\t\tperIp.set(ip, count + 1);\n\t\tconst ok = server.upgrade(req, {\n\t\t\tdata: {\n\t\t\t\tip,\n\t\t\t\torigin: origin ?? \"\",\n\t\t\t\tsite,\n\t\t\t\t...(address === undefined ? {} : { address }),\n\t\t\t},\n\t\t\theaders: { \"Sec-WebSocket-Protocol\": SUBPROTOCOL },\n\t\t});\n\t\tif (ok) return undefined;\n\t\treleaseIp(ip);\n\t\treturn json(400, { error: \"websocket_upgrade_expected\" });\n\t}\n\n\tfunction wwwAuthenticate(id: string, presented: boolean): string {\n\t\tconst metadata = `${publicUrl}/.well-known/oauth-protected-resource/a/${id}/mcp`;\n\t\tconst error = presented ? ', error=\"invalid_token\"' : \"\";\n\t\treturn `Bearer resource_metadata=\"${metadata}\", scope=\"tools\"${error}`;\n\t}\n\n\tasync function authenticate(\n\t\treq: Request,\n\t\taddressId: string,\n\t): Promise<TokenRecord | \"missing\" | \"invalid\" | \"unavailable\"> {\n\t\tconst header = req.headers.get(\"authorization\");\n\t\tif (header === null) return \"missing\";\n\t\tconst match = /^Bearer ([A-Za-z0-9._~+/-]+=*)$/i.exec(header.trim());\n\t\tconst token = match?.[1];\n\t\tif (token === undefined) return \"invalid\";\n\t\tlet record: TokenRecord | undefined;\n\t\ttry {\n\t\t\trecord = await store.get(hashToken(token));\n\t\t} catch (error) {\n\t\t\tlogger.error(\"store.error\", { op: \"get\", error: errorName(error) });\n\t\t\treturn \"unavailable\";\n\t\t}\n\t\tif (\n\t\t\trecord === undefined ||\n\t\t\trecord.kind !== \"access\" ||\n\t\t\trecord.addressId !== addressId ||\n\t\t\trecord.expiresAt <= Date.now() ||\n\t\t\t!record.scopes.includes(\"tools\")\n\t\t) {\n\t\t\treturn \"invalid\";\n\t\t}\n\t\treturn record;\n\t}\n\n\tasync function readBody(\n\t\treq: Request,\n\t\tmaxBytes: number,\n\t): Promise<Body | Response> {\n\t\tconst length = Number(req.headers.get(\"content-length\") ?? \"0\");\n\t\tif (length > maxBytes) {\n\t\t\treturn rpcError(\n\t\t\t\t413,\n\t\t\t\tundefined,\n\t\t\t\t-32600,\n\t\t\t\t\"Request body too large.\",\n\t\t\t\tcorsHeaders,\n\t\t\t);\n\t\t}\n\t\tlet bytes: ArrayBuffer;\n\t\ttry {\n\t\t\t// Bun's idle timeout does not fire while a body is being read, so a\n\t\t\t// client that stalls mid-body would hold the socket; our own deadline\n\t\t\t// answers 408 and closes the connection.\n\t\t\tconst reading = req.arrayBuffer();\n\t\t\treading.catch(() => {}); // rejects once the socket is closed\n\t\t\tlet timer: Timer | undefined;\n\t\t\tconst deadline = new Promise<\"timeout\">((resolve) => {\n\t\t\t\ttimer = setTimeout(() => resolve(\"timeout\"), config.bodyTimeoutMs);\n\t\t\t});\n\t\t\tlet result: ArrayBuffer | \"timeout\";\n\t\t\ttry {\n\t\t\t\tresult = await Promise.race([reading, deadline]);\n\t\t\t} finally {\n\t\t\t\tclearTimeout(timer);\n\t\t\t}\n\t\t\tif (result === \"timeout\") {\n\t\t\t\treturn rpcError(\n\t\t\t\t\t408,\n\t\t\t\t\tundefined,\n\t\t\t\t\t-32600,\n\t\t\t\t\t\"The request body did not arrive in time.\",\n\t\t\t\t\t{ ...corsHeaders, connection: \"close\" },\n\t\t\t\t);\n\t\t\t}\n\t\t\tbytes = result;\n\t\t} catch {\n\t\t\treturn rpcError(\n\t\t\t\t400,\n\t\t\t\tundefined,\n\t\t\t\t-32700,\n\t\t\t\t\"Could not read the request body.\",\n\t\t\t\tcorsHeaders,\n\t\t\t);\n\t\t}\n\t\tif (bytes.byteLength > maxBytes) {\n\t\t\treturn rpcError(\n\t\t\t\t413,\n\t\t\t\tundefined,\n\t\t\t\t-32600,\n\t\t\t\t\"Request body too large.\",\n\t\t\t\tcorsHeaders,\n\t\t\t);\n\t\t}\n\t\tlet text: string;\n\t\tlet value: unknown;\n\t\ttry {\n\t\t\ttext = new TextDecoder(\"utf-8\", { fatal: true }).decode(bytes);\n\t\t\tvalue = JSON.parse(text);\n\t\t} catch {\n\t\t\treturn rpcError(400, undefined, -32700, \"Parse error.\", corsHeaders);\n\t\t}\n\t\tif (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n\t\t\treturn rpcError(\n\t\t\t\t400,\n\t\t\t\tundefined,\n\t\t\t\t-32600,\n\t\t\t\t\"The body must be one JSON-RPC message (no batches).\",\n\t\t\t\tcorsHeaders,\n\t\t\t);\n\t\t}\n\t\treturn { value: value as Record<string, unknown>, text };\n\t}\n\n\t/** DEC-033 / DEC-040: the protocol-version pre-check. */\n\tfunction checkVersion(\n\t\treq: Request,\n\t\tbody: Record<string, unknown>,\n\t\trpcId: RpcId | undefined,\n\t): Response | { forwardVersion: string } {\n\t\tconst header = req.headers.get(\"mcp-protocol-version\");\n\t\t// An initialize in a 2026-07-28 envelope is an ordinary request for a\n\t\t// method the tab does not have: forwarded, so the tab answers 404 and\n\t\t// -32601 like any removed method.\n\t\tif (\n\t\t\tbody[\"method\"] === \"initialize\" &&\n\t\t\t!(\n\t\t\t\theader === MCP_PROTOCOL_VERSION &&\n\t\t\t\tmetaVersion(body) === MCP_PROTOCOL_VERSION\n\t\t\t)\n\t\t) {\n\t\t\tconst params = body[\"params\"] as Record<string, unknown> | undefined;\n\t\t\tconst requested =\n\t\t\t\ttypeof params?.[\"protocolVersion\"] === \"string\"\n\t\t\t\t\t? params[\"protocolVersion\"]\n\t\t\t\t\t: (header ?? null);\n\t\t\treturn rpcError(\n\t\t\t\t400,\n\t\t\t\trpcId,\n\t\t\t\t-32022,\n\t\t\t\t`Unsupported protocol version: ${String(requested)}. This server supports only ${MCP_PROTOCOL_VERSION}.`,\n\t\t\t\tcorsHeaders,\n\t\t\t\t{ supported: [MCP_PROTOCOL_VERSION], requested },\n\t\t\t);\n\t\t}\n\t\tif (header === MCP_PROTOCOL_VERSION) return { forwardVersion: header };\n\t\tif (\n\t\t\theader === CLAUDE_MISMATCHED_HEADER &&\n\t\t\tmetaVersion(body) === MCP_PROTOCOL_VERSION\n\t\t) {\n\t\t\t// Logged once per process; the running count is in /healthz.\n\t\t\tif (++claudeWorkarounds === 1) {\n\t\t\t\tlogger.info(\"mcp.claude_header_workaround\", {\n\t\t\t\t\tmessage:\n\t\t\t\t\t\t\"accepting MCP-Protocol-Version 2025-11-25 with a 2026-07-28 body (claude-code #93290); counted in /healthz\",\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn { forwardVersion: MCP_PROTOCOL_VERSION };\n\t\t}\n\t\tif (header === null) {\n\t\t\treturn rpcError(\n\t\t\t\t400,\n\t\t\t\trpcId,\n\t\t\t\t-32020,\n\t\t\t\t\"Missing MCP-Protocol-Version header.\",\n\t\t\t\tcorsHeaders,\n\t\t\t);\n\t\t}\n\t\treturn rpcError(\n\t\t\t400,\n\t\t\trpcId,\n\t\t\t-32022,\n\t\t\t`Unsupported protocol version: ${header}. This server supports only ${MCP_PROTOCOL_VERSION}.`,\n\t\t\tcorsHeaders,\n\t\t\t{ supported: [MCP_PROTOCOL_VERSION], requested: header },\n\t\t);\n\t}\n\n\tasync function handleMcp(\n\t\treq: Request,\n\t\tserver: Server<WsData>,\n\t\taddressId: string,\n\t): Promise<Response> {\n\t\tconst started = Date.now();\n\t\tconst logDone = (\n\t\t\tstatus: number,\n\t\t\tmethod: string,\n\t\t\textra: Record<string, string | number> = {},\n\t\t) =>\n\t\t\tlogger.info(\"mcp.request\", {\n\t\t\t\taddress: shortAddress(addressId),\n\t\t\t\tmethod,\n\t\t\t\tstatus,\n\t\t\t\tdurationMs: Date.now() - started,\n\t\t\t\t...extra,\n\t\t\t});\n\n\t\t// The page's own limit when it is connected; else the instance's (the\n\t\t// request then ends with 401 or 503 anyway).\n\t\tconst body = await readBody(\n\t\t\treq,\n\t\t\tsessions.get(addressId)?.limits.maxMessageBytes ?? config.maxMessageBytes,\n\t\t);\n\t\tif (body instanceof Response) {\n\t\t\tlogDone(body.status, \"?\");\n\t\t\treturn body;\n\t\t}\n\t\tconst rpcId = rpcIdOf(body.value);\n\t\tconst method = methodForLog(body.value);\n\n\t\tconst version = checkVersion(req, body.value, rpcId);\n\t\tif (version instanceof Response) {\n\t\t\tlogDone(version.status, method);\n\t\t\treturn version;\n\t\t}\n\n\t\tconst auth = await authenticate(req, addressId);\n\t\tif (auth === \"unavailable\") {\n\t\t\t// Not the token's fault: a 401 would make clients drop valid tokens.\n\t\t\tlogDone(503, method, { reason: \"store_unavailable\" });\n\t\t\treturn rpcError(\n\t\t\t\t503,\n\t\t\t\trpcId,\n\t\t\t\tRelayErrorCode.storeUnavailable,\n\t\t\t\t\"The relay cannot check tokens right now. Try again shortly.\",\n\t\t\t\t{ ...corsHeaders, \"retry-after\": RETRY_AFTER_S },\n\t\t\t);\n\t\t}\n\t\tif (typeof auth === \"string\") {\n\t\t\tlogDone(401, method);\n\t\t\treturn json(\n\t\t\t\t401,\n\t\t\t\t{\n\t\t\t\t\terror: \"invalid_token\",\n\t\t\t\t\terror_description:\n\t\t\t\t\t\tauth === \"missing\"\n\t\t\t\t\t\t\t? \"Authorization required.\"\n\t\t\t\t\t\t\t: \"The access token is not valid.\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t...corsHeaders,\n\t\t\t\t\t\"www-authenticate\": wwwAuthenticate(addressId, auth === \"invalid\"),\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\n\t\tconst headers: Record<string, string> = {};\n\t\tfor (const [k, v] of req.headers) {\n\t\t\tconst key = k.toLowerCase();\n\t\t\tif (FORWARDED_HEADERS.has(key) || key.startsWith(\"mcp-param-\"))\n\t\t\t\theaders[key] = v;\n\t\t}\n\t\theaders[\"mcp-protocol-version\"] = version.forwardVersion;\n\n\t\tconst clientHostName = (() => {\n\t\t\ttry {\n\t\t\t\treturn new URL(auth.clientId).host;\n\t\t\t} catch {\n\t\t\t\treturn \"\";\n\t\t\t}\n\t\t})();\n\t\tconst isListen = body.value[\"method\"] === \"subscriptions/listen\";\n\t\t// `server/discover` does not wait: clients use it as the protocol-era\n\t\t// probe with a short timeout (Claude Code: 5 s, then it falls back to\n\t\t// the legacy handshake), and the stand-in answer has `ttlMs: 0`.\n\t\tconst waitMs =\n\t\t\tbody.value[\"method\"] === \"server/discover\" ||\n\t\t\t// Only small requests wait: a waiting request holds its body, and\n\t\t\t// tool calls are small (review of iteration 8).\n\t\t\tBuffer.byteLength(body.text) > MIN_MESSAGE_BYTES\n\t\t\t\t? 0\n\t\t\t\t: config.pageWaitMs;\n\t\tconst closed = () => {\n\t\t\tlogDone(499, method, { outcome: \"client_closed\" });\n\t\t\treturn new Response(null, { status: 499 });\n\t\t};\n\n\t\t// Only now, for an authenticated request, switch off Bun's idle timer:\n\t\t// our own timers (the page wait, the request timer) and keep-alives take\n\t\t// over (Bun research, finding 1). Body reading and every unauthenticated\n\t\t// path keep the idle timeout, so a stalled client cannot hold a socket.\n\t\t// It is switched on again on every exit, while the response is still in\n\t\t// progress: Bun ignores a timeout set once the response has finished.\n\t\tconst idle = (on: boolean) =>\n\t\t\tserver.timeout(req, on ? config.httpIdleTimeoutS : 0);\n\t\tconst usable = usableFor(auth.subject);\n\n\t\t/** The page's session to forward to, or the answer when there is none. */\n\t\tconst admit = async (): Promise<TabSession | Response> => {\n\t\t\tconst found = await waitForPage(addressId, req.signal, waitMs, usable);\n\t\t\t// The AI app may have gone while the body was read, the token checked\n\t\t\t// or the page awaited: then forward nothing (the abort event has\n\t\t\t// already fired and would not cancel the exchange, which would hold a\n\t\t\t// slot until the timeout).\n\t\t\tif (found === \"aborted\" || req.signal.aborted) return closed();\n\t\t\tif (found === undefined) {\n\t\t\t\treturn pageNotOpen(body.value, rpcId, addressId, logDone, method);\n\t\t\t}\n\t\t\tconst session = found;\n\t\t\t// Identity binding: only the person the grant was made for (DEC-077).\n\t\t\tif (\n\t\t\t\t(auth.subject !== undefined || session.site.pairing === \"oidc\") &&\n\t\t\t\tsession.identity !== auth.subject\n\t\t\t) {\n\t\t\t\tlogDone(401, method, { reason: \"identity_mismatch\" });\n\t\t\t\treturn json(\n\t\t\t\t\t401,\n\t\t\t\t\t{ error: \"invalid_token\", error_description: MISMATCH_TEXT },\n\t\t\t\t\t{\n\t\t\t\t\t\t...corsHeaders,\n\t\t\t\t\t\t\"www-authenticate\": `${wwwAuthenticate(addressId, true)}, error_description=\"${MISMATCH_TEXT}\"`,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t\t// The body was read with the instance's limit if the page was not\n\t\t\t// open yet; its site may allow less.\n\t\t\tif (Buffer.byteLength(body.text) > session.limits.maxMessageBytes) {\n\t\t\t\tlogDone(413, method);\n\t\t\t\treturn rpcError(\n\t\t\t\t\t413,\n\t\t\t\t\trpcId,\n\t\t\t\t\t-32600,\n\t\t\t\t\t\"Request body too large.\",\n\t\t\t\t\tcorsHeaders,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (session.pending.size >= session.limits.maxConcurrentRequests) {\n\t\t\t\tlogDone(429, method);\n\t\t\t\treturn rpcError(\n\t\t\t\t\t429,\n\t\t\t\t\trpcId,\n\t\t\t\t\tRelayErrorCode.overloaded,\n\t\t\t\t\t\"Too many requests at once for this page.\",\n\t\t\t\t\tcorsHeaders,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (\n\t\t\t\tisListen &&\n\t\t\t\tsession.listenStreams(auth.grantId) >= MAX_LISTEN_STREAMS_PER_GRANT\n\t\t\t) {\n\t\t\t\tlogDone(429, method, { reason: \"listen_streams\" });\n\t\t\t\treturn rpcError(\n\t\t\t\t\t429,\n\t\t\t\t\trpcId,\n\t\t\t\t\tRelayErrorCode.overloaded,\n\t\t\t\t\t\"Too many listen streams at once for this AI app.\",\n\t\t\t\t\tcorsHeaders,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn session;\n\t\t};\n\n\t\tif (readySession(addressId, usable) === undefined && waitMs > 0) {\n\t\t\tidle(false);\n\t\t}\n\t\tlet retried = false;\n\t\tfor (;;) {\n\t\t\tconst admitted = await admit();\n\t\t\tif (admitted instanceof Response) {\n\t\t\t\tidle(true);\n\t\t\t\treturn admitted;\n\t\t\t}\n\t\t\tconst session = admitted;\n\t\t\tidle(false);\n\t\t\tlet retry: () => void = () => {};\n\t\t\tconst retrying = new Promise<typeof RETRY>((resolve) => {\n\t\t\t\tretry = () => resolve(RETRY);\n\t\t\t});\n\t\t\tconst mayRetry =\n\t\t\t\t!retried && waitMs > 0 && isRetryable(body.value[\"method\"]);\n\t\t\tconst exchange = session.forward({\n\t\t\t\theaders,\n\t\t\t\tbody: body.text,\n\t\t\t\trpcId,\n\t\t\t\tisListen,\n\t\t\t\tgrant: {\n\t\t\t\t\tgrantId: auth.grantId,\n\t\t\t\t\tclientId: auth.clientId,\n\t\t\t\t\tscopes: auth.scopes,\n\t\t\t\t},\n\t\t\t\textraHeaders: corsHeaders,\n\t\t\t\tonDone: (e: Exchange) => {\n\t\t\t\t\tif (e.outcome === \"page_gone_retry\") return; // logged once, at the end\n\t\t\t\t\tidle(true);\n\t\t\t\t\tlogDone(e.status, method, {\n\t\t\t\t\t\tsession: session.sessionId,\n\t\t\t\t\t\tclient: clientHostName,\n\t\t\t\t\t\toutcome: e.outcome,\n\t\t\t\t\t\t...(e.outcome === \"page_gone\" ? { reason: \"page_not_open\" } : {}),\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tpageGone: (waiting) => {\n\t\t\t\t\tif (waiting && mayRetry && !req.signal.aborted) {\n\t\t\t\t\t\tretry();\n\t\t\t\t\t\treturn { retry: true };\n\t\t\t\t\t}\n\t\t\t\t\tconst answer = notOpenAnswer(\n\t\t\t\t\t\tbody.value,\n\t\t\t\t\t\trpcId,\n\t\t\t\t\t\tsession.appName,\n\t\t\t\t\t\tclosing ? \"restarting_gone\" : \"gone\",\n\t\t\t\t\t\tRELAY_INFO,\n\t\t\t\t\t);\n\t\t\t\t\tif (answer !== undefined) return { retry: false, body: answer };\n\t\t\t\t\t// A notification: an HTTP error, which says \"restarting\" too.\n\t\t\t\t\treturn !closing\n\t\t\t\t\t\t? { retry: false }\n\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\tretry: false,\n\t\t\t\t\t\t\t\terror: {\n\t\t\t\t\t\t\t\t\tstatus: 503,\n\t\t\t\t\t\t\t\t\tcode: RelayErrorCode.restarting,\n\t\t\t\t\t\t\t\t\tmessage: \"The relay is restarting.\",\n\t\t\t\t\t\t\t\t\theaders: { \"retry-after\": RETRY_AFTER_S },\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t});\n\t\t\tconst onAbort = () => exchange.clientClosed();\n\t\t\treq.signal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\tconst result = await Promise.race([exchange.response, retrying]);\n\t\t\tif (result !== RETRY) return result;\n\t\t\treq.signal.removeEventListener(\"abort\", onAbort);\n\t\t\tretried = true;\n\t\t}\n\t}\n\n\t/**\n\t * DEC-074: HTTP 200 and a JSON-RPC message, not an HTTP error status. While\n\t * the relay stops, the answer says it restarts (iteration 11, finding 5).\n\t */\n\tfunction pageNotOpen(\n\t\tvalue: Record<string, unknown>,\n\t\trpcId: RpcId | undefined,\n\t\taddressId: string,\n\t\tlogDone: (\n\t\t\tstatus: number,\n\t\t\tmethod: string,\n\t\t\textra?: Record<string, string | number>,\n\t\t) => void,\n\t\tmethod: string,\n\t): Response {\n\t\t// Open but not signed in (identity binding) reads differently.\n\t\tconst open = sessions.get(addressId);\n\t\tif (\n\t\t\t!closing &&\n\t\t\topen?.ready === true &&\n\t\t\topen.identity === undefined &&\n\t\t\topen.identityUnchecked\n\t\t) {\n\t\t\t// The relay could not check the page's user: not the user's errand.\n\t\t\tlogDone(503, method, { reason: \"identity_unchecked\" });\n\t\t\treturn rpcError(503, rpcId, RelayErrorCode.signedOut, UNCHECKED_TEXT, {\n\t\t\t\t...corsHeaders,\n\t\t\t\t\"retry-after\": RETRY_AFTER_S,\n\t\t\t});\n\t\t}\n\t\tconst phase: NotOpenPhase = closing\n\t\t\t? \"restarting\"\n\t\t\t: open?.ready === true &&\n\t\t\t\t\topen.identity === undefined &&\n\t\t\t\t\topen.site.pairing === \"oidc\"\n\t\t\t\t? \"signed_out\"\n\t\t\t\t: \"not_open\";\n\t\tconst reason = phase === \"restarting\" ? \"restarting\" : \"page_not_open\";\n\t\tconst answer = notOpenAnswer(\n\t\t\tvalue,\n\t\t\trpcId,\n\t\t\topen?.appName ?? lastSeen.get(addressId)?.appName,\n\t\t\tphase,\n\t\t\tRELAY_INFO,\n\t\t);\n\t\tif (answer === undefined) {\n\t\t\t// A notification: the spec requires an HTTP error status.\n\t\t\tlogDone(503, method, { reason });\n\t\t\treturn phase === \"restarting\"\n\t\t\t\t? rpcError(\n\t\t\t\t\t\t503,\n\t\t\t\t\t\trpcId,\n\t\t\t\t\t\tRelayErrorCode.restarting,\n\t\t\t\t\t\t\"The relay is restarting.\",\n\t\t\t\t\t\t{ ...corsHeaders, \"retry-after\": RETRY_AFTER_S },\n\t\t\t\t\t)\n\t\t\t\t: rpcError(\n\t\t\t\t\t\t503,\n\t\t\t\t\t\trpcId,\n\t\t\t\t\t\tRelayErrorCode.pageNotOpen,\n\t\t\t\t\t\t\"The page is not open.\",\n\t\t\t\t\t\tcorsHeaders,\n\t\t\t\t\t);\n\t\t}\n\t\tlogDone(200, method, { reason });\n\t\treturn new Response(answer, {\n\t\t\tstatus: 200,\n\t\t\theaders: { ...corsHeaders, \"content-type\": \"application/json\" },\n\t\t});\n\t}\n\n\tfunction preflight(req: Request): Response {\n\t\tif (!config.cors)\n\t\t\treturn new Response(null, { status: 405, headers: { allow: \"POST\" } });\n\t\tconst requested = req.headers.get(\"access-control-request-headers\") ?? \"\";\n\t\treturn new Response(null, {\n\t\t\tstatus: 204,\n\t\t\theaders: {\n\t\t\t\t...corsHeaders,\n\t\t\t\t\"access-control-allow-methods\": \"POST, OPTIONS\",\n\t\t\t\t\"access-control-allow-headers\":\n\t\t\t\t\trequested !== \"\"\n\t\t\t\t\t\t? requested\n\t\t\t\t\t\t: \"authorization, content-type, accept, mcp-protocol-version, mcp-method, mcp-name\",\n\t\t\t\t\"access-control-max-age\": \"600\",\n\t\t\t},\n\t\t});\n\t}\n\n\tconst methodNotAllowed = () =>\n\t\tnew Response(null, {\n\t\t\tstatus: 405,\n\t\t\theaders: { ...corsHeaders, allow: \"POST\" },\n\t\t});\n\n\tconst postOnly = () =>\n\t\tnew Response(null, { status: 405, headers: { allow: \"POST, OPTIONS\" } });\n\n\t/**\n\t * Whether the token store answers (DEC-099): one cheap read of a hash that\n\t * never exists, with a deadline. One probe at a time, and its answer is\n\t * reused for a second, so a flood of `/healthz` does not reach the store.\n\t * While a read that missed its deadline still hangs, a new one starts only\n\t * every `healthRetryMs` (30 s): a store that lost one command recovers, and\n\t * a hung store holds at most one read per window.\n\t */\n\tconst healthRetryMs = hooks?.healthRetryMs ?? HEALTH_HUNG_RETRY_MS;\n\tlet probe: Promise<StoreHealth> | undefined;\n\tlet probed: { at: number; result: StoreHealth } | undefined;\n\tlet hungReads = 0;\n\tlet lastHungAt = 0;\n\tasync function runProbe(): Promise<StoreHealth> {\n\t\tlet timer: Timer | undefined;\n\t\tconst deadline = new Promise<\"store_timeout\">((resolve) => {\n\t\t\ttimer = setTimeout(\n\t\t\t\t() => resolve(\"store_timeout\"),\n\t\t\t\tHEALTH_STORE_TIMEOUT_MS,\n\t\t\t);\n\t\t});\n\t\t// Inside a promise chain, so a store that throws synchronously is a\n\t\t// failed probe like any other.\n\t\tconst read = Promise.resolve()\n\t\t\t.then(() => store.get(HEALTH_PROBE_HASH))\n\t\t\t.then(() => \"ok\" as const);\n\t\tread.catch(() => {}); // a late rejection after the deadline\n\t\ttry {\n\t\t\tconst result = await Promise.race([read, deadline]);\n\t\t\tif (result === \"store_timeout\") {\n\t\t\t\tlogger.warn(\"health.store\", { error: \"timeout\" });\n\t\t\t\thungReads++;\n\t\t\t\tlastHungAt = Date.now();\n\t\t\t\tconst settled = () => {\n\t\t\t\t\thungReads--;\n\t\t\t\t};\n\t\t\t\tread.then(settled, settled);\n\t\t\t}\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tlogger.warn(\"health.store\", { error: errorName(error) });\n\t\t\treturn \"store_unavailable\";\n\t\t} finally {\n\t\t\tclearTimeout(timer);\n\t\t}\n\t}\n\tfunction storeHealth(): Promise<StoreHealth> {\n\t\tif (probe !== undefined) return probe;\n\t\tconst now = Date.now();\n\t\tif (probed !== undefined && now - probed.at < HEALTH_REUSE_MS) {\n\t\t\treturn Promise.resolve(probed.result);\n\t\t}\n\t\tif (hungReads > 0 && now - lastHungAt < healthRetryMs) {\n\t\t\treturn Promise.resolve(\"store_timeout\");\n\t\t}\n\t\tconst current = runProbe().catch((): StoreHealth => \"store_unavailable\");\n\t\tprobe = current;\n\t\tvoid current.then((result) => {\n\t\t\tprobed = { at: Date.now(), result };\n\t\t\tif (probe === current) probe = undefined;\n\t\t});\n\t\treturn current;\n\t}\n\n\tconst largest = largestMessageBytes(config);\n\tconst ipOf = (req: Request, srv: Server<WsData>) =>\n\t\tipPrefixKey(clientIp(req, srv));\n\tconst server = Bun.serve({\n\t\tport: config.port,\n\t\thostname: config.host,\n\t\tdevelopment: false,\n\t\tmaxRequestBodySize: largest + 1024,\n\t\tidleTimeout: config.httpIdleTimeoutS,\n\t\troutes: {\n\t\t\t\"/healthz\": {\n\t\t\t\t// no-store: a CDN in front caches answers without cache headers\n\t\t\t\t// (bunny for 30 days), and a deploy check would read the old version.\n\t\t\t\tGET: async () => {\n\t\t\t\t\tconst store = await storeHealth();\n\t\t\t\t\tif (store !== \"ok\") {\n\t\t\t\t\t\t// A reason code only: never the store's error (DEC-099).\n\t\t\t\t\t\treturn json(\n\t\t\t\t\t\t\t503,\n\t\t\t\t\t\t\t{ status: \"unhealthy\", reason: store, version: VERSION },\n\t\t\t\t\t\t\t{ \"cache-control\": \"no-store\" },\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn json(\n\t\t\t\t\t\t200,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstatus: \"ok\",\n\t\t\t\t\t\t\tversion: VERSION,\n\t\t\t\t\t\t\tcounters: { claudeHeaderWorkaround: claudeWorkarounds },\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ \"cache-control\": \"no-store\" },\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"/\": {\n\t\t\t\tGET: () =>\n\t\t\t\t\tnew Response(INDEX_HTML, {\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\"content-type\": \"text/html; charset=utf-8\",\n\t\t\t\t\t\t\t\"content-security-policy\":\n\t\t\t\t\t\t\t\t\"default-src 'none'; img-src 'self'; frame-ancestors 'none'\",\n\t\t\t\t\t\t\t\"x-content-type-options\": \"nosniff\",\n\t\t\t\t\t\t\t\"cache-control\": \"public, max-age=3600\",\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t},\n\t\t\t// The relay's icon, for the AI apps' connector lists and browser tabs.\n\t\t\t\"/favicon.ico\": { GET: () => icon(FAVICON_ICO, \"image/x-icon\") },\n\t\t\t\"/favicon.svg\": { GET: () => icon(FAVICON_SVG, \"image/svg+xml\") },\n\t\t\t\"/apple-touch-icon.png\": {\n\t\t\t\tGET: () => icon(APPLE_TOUCH_ICON, \"image/png\"),\n\t\t\t},\n\t\t\t\"/tab\": (req, srv) => handleTab(req, srv),\n\t\t\t\"/.well-known/oauth-authorization-server\": {\n\t\t\t\tGET: () => auth.metadata(),\n\t\t\t\tOPTIONS: () => auth.preflight(\"GET\"),\n\t\t\t},\n\t\t\t\"/.well-known/oauth-protected-resource/a/:id/mcp\": {\n\t\t\t\tGET: (req) => auth.protectedResource(req.params.id),\n\t\t\t\tOPTIONS: () => auth.preflight(\"GET\"),\n\t\t\t},\n\t\t\t\"/authorize\": {\n\t\t\t\tGET: (req, srv) => auth.authorize(req, ipOf(req, srv)),\n\t\t\t\tPOST: (req, srv) => auth.authorizeSubmit(req, ipOf(req, srv)),\n\t\t\t},\n\t\t\t\"/authorize/callback\": {\n\t\t\t\tGET: (req, srv) => auth.authorizeCallback(req, ipOf(req, srv)),\n\t\t\t},\n\t\t\t\"/authorize.css\": { GET: () => auth.stylesheet() },\n\t\t\t\"/token\": {\n\t\t\t\tPOST: (req, srv) => auth.token(req, ipOf(req, srv)),\n\t\t\t\tOPTIONS: () => auth.preflight(\"POST\"),\n\t\t\t\tGET: postOnly,\n\t\t\t},\n\t\t\t\"/revoke\": {\n\t\t\t\tPOST: (req, srv) => auth.revoke(req, ipOf(req, srv)),\n\t\t\t\tOPTIONS: () => auth.preflight(\"POST\"),\n\t\t\t\tGET: postOnly,\n\t\t\t},\n\t\t\t\"/a/:id/mcp\": {\n\t\t\t\tPOST: (req, srv) => {\n\t\t\t\t\tconst id = req.params.id;\n\t\t\t\t\tif (!isAddressId(id))\n\t\t\t\t\t\treturn new Response(\"Not found\", { status: 404 });\n\t\t\t\t\treturn handleMcp(req, srv, id);\n\t\t\t\t},\n\t\t\t\tOPTIONS: (req) => preflight(req),\n\t\t\t\tGET: methodNotAllowed,\n\t\t\t\tDELETE: methodNotAllowed,\n\t\t\t\tPUT: methodNotAllowed,\n\t\t\t\tPATCH: methodNotAllowed,\n\t\t\t},\n\t\t},\n\t\tfetch: () => new Response(\"Not found\", { status: 404 }),\n\t\twebsocket: {\n\t\t\tdata: {} as WsData,\n\t\t\tmaxPayloadLength: largest * FRAME_HEADROOM,\n\t\t\tbackpressureLimit: config.backpressureLimitBytes,\n\t\t\tcloseOnBackpressureLimit: false,\n\t\t\tidleTimeout: 120,\n\t\t\tsendPings: true,\n\t\t\tperMessageDeflate: false,\n\t\t\topen(ws: ServerWebSocket<WsData>) {\n\t\t\t\tconst session = new TabSession(\n\t\t\t\t\tws,\n\t\t\t\t\tws.data.ip,\n\t\t\t\t\tws.data.origin,\n\t\t\t\t\tws.data.site,\n\t\t\t\t\thost,\n\t\t\t\t\tws.data.address,\n\t\t\t\t);\n\t\t\t\tws.data.session = session;\n\t\t\t\tallSessions.add(session);\n\t\t\t},\n\t\t\tmessage(ws: ServerWebSocket<WsData>, message: string | Buffer) {\n\t\t\t\tws.data.session?.handleFrame(\n\t\t\t\t\ttypeof message === \"string\" ? message : new Uint8Array(message),\n\t\t\t\t);\n\t\t\t},\n\t\t\tclose(ws: ServerWebSocket<WsData>, code: number) {\n\t\t\t\tws.data.session?.closed(code);\n\t\t\t},\n\t\t},\n\t});\n\n\tlet stopping: Promise<void> | undefined;\n\t/** Set at once by `stop()`, before the sessions end (their requests read it). */\n\tlet closing = false;\n\tconst port = server.port ?? config.port;\n\tif (publicUrl === \"\") publicUrl = `http://localhost:${port}`;\n\n\tconst sweep = setInterval(() => {\n\t\tauth.sweep();\n\t\tstore\n\t\t\t.deleteExpired(Date.now())\n\t\t\t.then((n) => {\n\t\t\t\tif (n > 0) logger.debug(\"store.swept\", { deleted: n });\n\t\t\t})\n\t\t\t.catch((error: unknown) =>\n\t\t\t\tlogger.error(\"store.error\", {\n\t\t\t\t\top: \"deleteExpired\",\n\t\t\t\t\terror: errorName(error),\n\t\t\t\t}),\n\t\t\t);\n\t}, config.sweepIntervalMs);\n\n\tconst siteCount =\n\t\tconfig.allowedOrigins === \"*\"\n\t\t\t? \"*\"\n\t\t\t: config.allowedOrigins.length + config.sites.length;\n\tif (config.allowedOrigins === \"*\") {\n\t\tlogger.warn(\"relay.open_relay\", {\n\t\t\tmessage:\n\t\t\t\t\"TAB_MCP_ALLOWED_ORIGINS=* lets any website open tab sessions on this relay\",\n\t\t});\n\t} else if (siteCount === 0) {\n\t\tlogger.warn(\"relay.no_origins\", {\n\t\t\tmessage:\n\t\t\t\t\"TAB_MCP_ALLOWED_ORIGINS and TAB_MCP_SITES are empty: no page can connect\",\n\t\t});\n\t}\n\tlogger.info(\"relay.start\", {\n\t\tversion: VERSION,\n\t\turl: publicUrl,\n\t\tport,\n\t\tstore: ownsStore ? config.store : \"custom\",\n\t\torigins: siteCount,\n\t});\n\n\treturn {\n\t\turl: publicUrl,\n\t\tport,\n\t\tconfig,\n\t\taddressFor: (secret) => `${publicUrl}/a/${addressIdFromSecret(secret)}/mcp`,\n\t\tget sessionCount() {\n\t\t\treturn allSessions.size;\n\t\t},\n\t\tstop() {\n\t\t\tclosing = true;\n\t\t\tstopping ??= (async () => {\n\t\t\t\tclearInterval(sweep);\n\t\t\t\tfor (const set of [...waiters.values()]) {\n\t\t\t\t\tfor (const wake of [...set]) wake(undefined);\n\t\t\t\t}\n\t\t\t\tfor (const session of [...allSessions]) {\n\t\t\t\t\tsession.end(\n\t\t\t\t\t\tCloseCode.shuttingDown,\n\t\t\t\t\t\t\"relay shutting down\",\n\t\t\t\t\t\t\"shutdown\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tawait Bun.sleep(20); // let close frames leave\n\t\t\t\tawait server.stop(true);\n\t\t\t\tif (ownsStore) await store.close?.();\n\t\t\t\tlogger.info(\"relay.stop\", {});\n\t\t\t})();\n\t\t\treturn stopping;\n\t\t},\n\t};\n}\n"
25
26
  ],
26
- "mappings": "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",
27
- "debugId": "C9E94078D468D4A064756E2164756E21",
27
+ "mappings": ";;AAKA,IAAM,kBAAkB;AAGjB,SAAS,MAAM,CAAC,OAA2B;AAAA,EACjD,IAAI,MAAM;AAAA,EACV,IAAI,SAAS;AAAA,EACb,IAAI,OAAO;AAAA,EACX,WAAW,QAAQ,OAAO;AAAA,IACzB,SAAU,UAAU,IAAK;AAAA,IACzB,QAAQ;AAAA,IACR,OAAO,QAAQ,GAAG;AAAA,MACjB,QAAQ;AAAA,MACR,OAAO,gBAAiB,WAAW,OAAQ;AAAA,IAC5C;AAAA,IACA,WAAW,KAAK,QAAQ;AAAA,EACzB;AAAA,EACA,IAAI,OAAO;AAAA,IAAG,OAAO,gBAAiB,UAAW,IAAI,OAAS;AAAA,EAC9D,OAAO;AAAA;AAIR,IAAM,iBAAiB;AAGvB,IAAM,qBAAqB;AAEpB,SAAS,kBAAkB,CAAC,QAAyB;AAAA,EAC3D,OAAO,eAAe,KAAK,MAAM;AAAA;AAG3B,SAAS,WAAW,CAAC,IAAqB;AAAA,EAChD,OAAO,mBAAmB,KAAK,EAAE;AAAA;AAI3B,SAAS,mBAAmB,CAAC,QAAwB;AAAA,EAC3D,MAAM,SAAS,IAAI,IAAI,aAAa,QAAQ,EAAE,OAAO,MAAM,EAAE,OAAO;AAAA,EACpE,OAAO,OACN,IAAI,WAAW,OAAO,QAAQ,OAAO,YAAY,OAAO,MAAM,CAC/D;AAAA;AAIM,SAAS,SAAS,GAAW;AAAA,EACnC,OAAO,OACL,gBAAgB,IAAI,WAAW,EAAE,CAAC,EAClC,SAAS,EAAE,UAAU,aAAa,aAAa,KAAK,CAAC;AAAA;AAIjD,SAAS,YAAY,CAAC,IAAoB;AAAA,EAChD,OAAO,GAAG,MAAM,GAAG,CAAC;AAAA;;ACgBd,IAAM,oBAAoB;AAG1B,IAAM,mBAAmB;AAGzB,IAAM,eAAe;AAgErB,IAAM,iBAAwC;AAAA,EACpD,MAAM;AAAA,EACN,MAAM;AAAA,EACN,gBAAgB,CAAC;AAAA,EACjB,OAAO,CAAC;AAAA,EACR,UAAU;AAAA,EACV,eAAe,CAAC;AAAA,EAChB,YAAY;AAAA,EACZ,MAAM;AAAA,EACN,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB,uBAAuB;AAAA,EACvB,kBAAkB;AAAA,EAClB,aAAa;AAAA,EACb,eAAe;AAAA,EACf,mBAAmB;AAAA,EACnB,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,wBAAwB,IAAI;AAAA,EAC5B,kBAAkB;AAAA,EAClB,UAAU;AAAA,EACV,aAAa;AACd;AAAA;AAEO,MAAM,oBAAoB,MAAM;AAAA,EAC7B,OAAO;AACjB;AAGO,SAAS,eAAe,CAAC,OAAuB;AAAA,EACtD,IAAI;AAAA,EACJ,IAAI;AAAA,IACH,MAAM,IAAI,IAAI,KAAK;AAAA,IAClB,MAAM;AAAA,IACP,MAAM,IAAI,YAAY,kBAAkB,OAAO;AAAA;AAAA,EAEhD,IAAI,IAAI,aAAa,YAAY,IAAI,aAAa,SAAS;AAAA,IAC1D,MAAM,IAAI,YAAY,iCAAiC,OAAO;AAAA,EAC/D;AAAA,EACA,IACE,IAAI,aAAa,OAAO,IAAI,aAAa,MAC1C,IAAI,WAAW,MACf,IAAI,SAAS,MACb,IAAI,aAAa,MACjB,IAAI,aAAa,IAChB;AAAA,IACD,MAAM,IAAI,YACT,gFAAgF,OACjF;AAAA,EACD;AAAA,EACA,OAAO,IAAI;AAAA;AAIL,SAAS,aAAa,CAAC,QAA8B,CAAC,GAAgB;AAAA,EAC5E,MAAM,SAAsB,KAAK,mBAAmB,MAAM;AAAA,EAE1D,IAAI,OAAO,cAAc,WAAW;AAAA,IACnC,MAAM,SAAS,gBAAgB,OAAO,SAAS;AAAA,IAC/C,IAAI,CAAC,OAAO,WAAW,QAAQ,KAAK,CAAC,OAAO,aAAa;AAAA,MACxD,MAAM,IAAI,YACT,sDACD;AAAA,IACD;AAAA,IACA,OAAO,YAAY;AAAA,EACpB,EAAO,SAAI,CAAC,OAAO,aAAa;AAAA,IAC/B,MAAM,IAAI,YAAY,gCAAgC;AAAA,EACvD;AAAA,EAEA,IAAI,OAAO,mBAAmB,KAAK;AAAA,IAClC,OAAO,iBAAiB,OAAO,eAAe,IAAI,eAAe;AAAA,EAClE;AAAA,EACA,OAAO,QAAQ,OAAO,MAAM,IAAI,CAAC,SAAS,aAAa,IAAI,CAAC;AAAA,EAC5D,MAAM,OAAO,IAAI,IAChB,OAAO,mBAAmB,MAAM,CAAC,IAAI,OAAO,cAC7C;AAAA,EACA,WAAW,QAAQ,OAAO,OAAO;AAAA,IAChC,IAAI,KAAK,IAAI,KAAK,MAAM,GAAG;AAAA,MAC1B,MAAM,IAAI,YAAY,4BAA4B,KAAK,QAAQ;AAAA,IAChE;AAAA,IACA,KAAK,IAAI,KAAK,MAAM;AAAA,EACrB;AAAA,EACA,iBAAiB,MAAM;AAAA,EACvB,OAAO,gBAAgB,OAAO,cAAc,IAAI,CAAC,MAAM;AAAA,IACtD,MAAM,OAAO,EAAE,KAAK,EAAE,YAAY;AAAA,IAClC,IAAI,CAAC,uBAAuB,KAAK,IAAI,GAAG;AAAA,MACvC,MAAM,IAAI,YAAY,oBAAoB,GAAG;AAAA,IAC9C;AAAA,IACA,OAAO;AAAA,GACP;AAAA,EAED,MAAM,WAAkC;AAAA,IACvC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AAAA,EACA,WAAW,OAAO,UAAU;AAAA,IAC3B,MAAM,IAAI,OAAO;AAAA,IACjB,IAAI,OAAO,MAAM,YAAY,CAAC,OAAO,SAAS,CAAC,KAAK,KAAK,GAAG;AAAA,MAC3D,MAAM,IAAI,YAAY,GAAG,+BAA+B;AAAA,IACzD;AAAA,EACD;AAAA,EACA,IACC,OAAO,OAAO,eAAe,YAC7B,CAAC,OAAO,SAAS,OAAO,UAAU,KAClC,OAAO,aAAa,KACpB,OAAO,aAAa,kBACnB;AAAA,IACD,MAAM,IAAI,YACT,wBAAwB,uBAAuB,mBAAmB,eACnE;AAAA,EACD;AAAA,EACA,IAAI,OAAO,kBAAkB,mBAAmB;AAAA,IAC/C,MAAM,IAAI,YACT,oCAAoC,4BACrC;AAAA,EACD;AAAA,EACA,IAAI,OAAO,mBAAmB,KAAK;AAAA,IAClC,MAAM,IAAI,YAAY,sCAAsC;AAAA,EAC7D;AAAA,EACA,IACC,CAAC,OAAO,UAAU,OAAO,IAAI,KAC7B,OAAO,OAAO,KACd,OAAO,OAAO,OACb;AAAA,IACD,MAAM,IAAI,YAAY,sBAAsB;AAAA,EAC7C;AAAA,EACA,OAAO;AAAA;AAGR,IAAM,YAAY,IAAI,IAAI,CAAC,UAAU,QAAQ,WAAW,QAAQ,CAAC;AACjE,IAAM,aAA4C;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD;AAGO,SAAS,SAAS,CAAC,OAAiC;AAAA,EAC1D,OACC,OAAO,UAAU,YACjB,MAAM,KAAK,EAAE,SAAS,KACtB,MAAM,UAAU,gBAChB,CAAC,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,OAAO;AAAA,IACxB,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK;AAAA,IAC/B,OAAO,IAAI,MAAS,KAAK,OAAQ,KAAK;AAAA,GACtC;AAAA;AAIH,SAAS,YAAY,CAAC,OAA4B;AAAA,EACjD,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GAAG;AAAA,IACxE,MAAM,IAAI,YAAY,yCAAyC;AAAA,EAChE;AAAA,EACA,MAAM,OAAO;AAAA,EACb,WAAW,OAAO,OAAO,KAAK,IAAI,GAAG;AAAA,IACpC,IAAI,CAAC,UAAU,IAAI,GAAG;AAAA,MAAG,MAAM,IAAI,YAAY,qBAAqB,KAAK;AAAA,EAC1E;AAAA,EACA,IAAI,OAAO,KAAK,cAAc,UAAU;AAAA,IACvC,MAAM,IAAI,YAAY,wBAAwB;AAAA,EAC/C;AAAA,EACA,MAAM,MAAkB,EAAE,QAAQ,gBAAgB,KAAK,SAAS,EAAE;AAAA,EAClE,IAAI,KAAK,YAAY,WAAW;AAAA,IAC/B,IAAI,CAAC,UAAU,KAAK,OAAO,GAAG;AAAA,MAC7B,MAAM,IAAI,YACT,uBAAuB,4BAA4B,IAAI,QACxD;AAAA,IACD;AAAA,IACA,IAAI,OAAO,KAAK;AAAA,EACjB;AAAA,EACA,MAAM,UAAU,KAAK;AAAA,EACrB,IAAI,YAAY,WAAW;AAAA,IAC1B,IAAI,YAAY,UAAU,YAAY,QAAQ;AAAA,MAC7C,MAAM,IAAI,YAAY,qCAAqC,IAAI,QAAQ;AAAA,IACxE;AAAA,IACA,IAAI,UAAU;AAAA,EACf;AAAA,EACA,MAAM,SAAS,KAAK;AAAA,EACpB,IAAI,WAAW,WAAW;AAAA,IACzB,IAAI,OAAO,WAAW,YAAY,WAAW,MAAM;AAAA,MAClD,MAAM,IAAI,YAAY,kCAAkC,IAAI,QAAQ;AAAA,IACrE;AAAA,IACA,MAAM,QAAQ;AAAA,IACd,MAAM,SAA8B,CAAC;AAAA,IACrC,YAAY,KAAK,UAAU,OAAO,QAAQ,KAAK,GAAG;AAAA,MACjD,IAAI,CAAE,WAAiC,SAAS,GAAG,GAAG;AAAA,QACrD,MAAM,IAAI,YAAY,uBAAuB,KAAK;AAAA,MACnD;AAAA,MACA,IAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,KAAK,SAAS,GAAG;AAAA,QACvE,MAAM,IAAI,YAAY,cAAc,+BAA+B;AAAA,MACpE;AAAA,MACA,OAAO,OAA2B;AAAA,IACnC;AAAA,IACA,IACC,OAAO,oBAAoB,aAC3B,OAAO,kBAAkB,mBACxB;AAAA,MACD,MAAM,IAAI,YACT,+CAA+C,mBAChD;AAAA,IACD;AAAA,IACA,IAAI,SAAS;AAAA,EACd;AAAA,EACA,OAAO;AAAA;AAIR,SAAS,QAAQ,CAAC,OAAgB,MAAc,aAA8B;AAAA,EAC7E,IAAI,OAAO,UAAU,YAAY,UAAU,IAAI;AAAA,IAC9C,MAAM,IAAI,YAAY,GAAG,uCAAuC;AAAA,EACjE;AAAA,EACA,IAAI;AAAA,EACJ,IAAI;AAAA,IACH,MAAM,IAAI,IAAI,KAAK;AAAA,IAClB,MAAM;AAAA,IACP,MAAM,IAAI,YAAY,GAAG,sBAAsB,OAAO;AAAA;AAAA,EAEvD,IAAI,IAAI,aAAa,YAAY,EAAE,eAAe,IAAI,aAAa,UAAU;AAAA,IAC5E,MAAM,IAAI,YAAY,GAAG,uBAAuB,OAAO;AAAA,EACxD;AAAA,EACA,IACC,IAAI,WAAW,MACf,IAAI,SAAS,MACb,IAAI,aAAa,MACjB,IAAI,aAAa,IAChB;AAAA,IACD,MAAM,IAAI,YACT,GAAG,+CAA+C,OACnD;AAAA,EACD;AAAA,EACA,OAAO;AAAA;AAIR,SAAS,gBAAgB,CAAC,QAA2B;AAAA,EACpD,IAAI,OAAO,aAAa,UAAU,OAAO,aAAa,QAAQ;AAAA,IAC7D,MAAM,IAAI,YAAY,mCAAmC;AAAA,EAC1D;AAAA,EACA,MAAM,OACL,OAAO,MAAM,KAAK,CAAC,OAAO,EAAE,WAAW,OAAO,cAAc,MAAM,KACjE,OAAO,aAAa,UACpB,OAAO,mBAAmB,OAC1B,OAAO,eAAe,SAAS;AAAA,EACjC,IAAI,OAAO,aAAa,UAAU,OAAO,mBAAmB,KAAK;AAAA,IAChE,MAAM,IAAI,YACT,yHACD;AAAA,EACD;AAAA,EACA,MAAM,OAAO,OAAO;AAAA,EACpB,IAAI,SAAS,WAAW;AAAA,IACvB,IAAI,MAAM;AAAA,MACT,MAAM,IAAI,YACT,4IACD;AAAA,IACD;AAAA,IACA;AAAA,EACD;AAAA,EACA,MAAM,MAAM,OAAO;AAAA,EACnB,SAAS,KAAK,QAAQ,uBAAuB,GAAG;AAAA,EAChD,SAAS,KAAK,kBAAkB,kCAAkC,GAAG;AAAA,EACrE,IAAI,OAAO,KAAK,aAAa,YAAY,KAAK,aAAa,IAAI;AAAA,IAC9D,MAAM,IAAI,YACT,yDACD;AAAA,EACD;AAAA,EACA,IACC,KAAK,iBAAiB,aACtB,OAAO,KAAK,iBAAiB,UAC5B;AAAA,IACD,MAAM,IAAI,YAAY,6CAA6C;AAAA,EACpE;AAAA,EACA,IAAI,OAAO,KAAK,oBAAoB,YAAY,KAAK,oBAAoB,IAAI;AAAA,IAC5E,MAAM,IAAI,YACT,+DACD;AAAA,EACD;AAAA,EACA,MAAM,QAAQ,KAAK,gBAAgB;AAAA,EACnC,IAAI,UAAU,SAAS,UAAU,OAAO;AAAA,IACvC,MAAM,IAAI,YACT,qGACD;AAAA,EACD;AAAA,EACA,OAAO,OAAO,KAAK,MAAM,cAAc,MAAM;AAAA;AAIvC,SAAS,aAAa,CAAC,QAAiC;AAAA,EAC9D,OAAO;AAAA,IACN,iBAAiB,OAAO;AAAA,IACxB,uBAAuB,OAAO;AAAA,IAC9B,kBAAkB,OAAO;AAAA,IACzB,aAAa,OAAO;AAAA,IACpB,eAAe,OAAO;AAAA,IACtB,mBAAmB,OAAO;AAAA,IAC1B,aAAa,OAAO;AAAA,EACrB;AAAA;AAQM,SAAS,OAAO,CACtB,QACA,QACmB;AAAA,EACnB,MAAM,WAAW,cAAc,MAAM;AAAA,EACrC,MAAM,aACL,WAAW,OAAO,YAAY,OAAO,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,MAAM;AAAA,EAC3E,IAAI,eAAe,WAAW;AAAA,IAC7B,MAAM,OAAa;AAAA,MAClB,QAAQ,WAAW;AAAA,MACnB,SAAS,WAAW,WAAW,OAAO;AAAA,MACtC,QAAQ,KAAK,aAAa,WAAW,OAAO;AAAA,IAC7C;AAAA,IACA,IAAI,WAAW,SAAS;AAAA,MAAW,KAAK,OAAO,WAAW;AAAA,IAC1D,OAAO;AAAA,EACR;AAAA,EACA,IACC,OAAO,mBAAmB,OACzB,WAAW,QAAQ,OAAO,eAAe,SAAS,MAAM,GACxD;AAAA,IACD,OAAO;AAAA,MACN,QAAQ,OAAO,mBAAmB,MAAM,MAAO,UAAU;AAAA,MACzD,SAAS,OAAO,mBAAmB,MAAM,SAAS,OAAO;AAAA,MACzD,QAAQ;AAAA,IACT;AAAA,EACD;AAAA,EACA;AAAA;AAIM,SAAS,mBAAmB,CAAC,QAA6B;AAAA,EAChE,OAAO,KAAK,IACX,OAAO,iBACP,GAAG,OAAO,MAAM,IAAI,CAAC,MAAM,EAAE,QAAQ,mBAAmB,CAAC,CAC1D;AAAA;AAKD,SAAS,OAAO,CAAC,KAAU,MAAkC;AAAA,EAC5D,MAAM,MAAM,IAAI;AAAA,EAChB,IAAI,QAAQ,aAAa,QAAQ;AAAA,IAAI;AAAA,EACrC,MAAM,IAAI,OAAO,GAAG;AAAA,EACpB,IAAI,CAAC,OAAO,SAAS,CAAC,KAAK,KAAK,GAAG;AAAA,IAClC,MAAM,IAAI,YAAY,GAAG,2CAA2C;AAAA,EACrE;AAAA,EACA,OAAO,KAAK,MAAM,IAAI,IAAI;AAAA;AAI3B,SAAS,aAAa,CAAC,KAAU,MAAkC;AAAA,EAClE,MAAM,MAAM,IAAI;AAAA,EAChB,IAAI,QAAQ,aAAa,QAAQ;AAAA,IAAI;AAAA,EACrC,MAAM,IAAI,OAAO,GAAG;AAAA,EACpB,IAAI,CAAC,OAAO,SAAS,CAAC,KAAK,IAAI,GAAG;AAAA,IACjC,MAAM,IAAI,YAAY,GAAG,gDAAgD;AAAA,EAC1E;AAAA,EACA,OAAO,KAAK,MAAM,IAAI,IAAI;AAAA;AAG3B,SAAS,OAAO,CAAC,KAAU,MAAkC;AAAA,EAC5D,MAAM,MAAM,IAAI;AAAA,EAChB,IAAI,QAAQ,aAAa,QAAQ;AAAA,IAAI;AAAA,EACrC,MAAM,IAAI,OAAO,GAAG;AAAA,EACpB,IAAI,CAAC,OAAO,UAAU,CAAC,KAAK,IAAI,GAAG;AAAA,IAClC,MAAM,IAAI,YAAY,GAAG,6BAA6B;AAAA,EACvD;AAAA,EACA,OAAO;AAAA;AAGR,SAAS,KAAuB,CAC/B,KACA,MACA,QACgB;AAAA,EAChB,MAAM,MAAM,IAAI;AAAA,EAChB,IAAI,QAAQ,aAAa,QAAQ;AAAA,IAAI;AAAA,EACrC,IAAI,CAAE,OAA6B,SAAS,GAAG,GAAG;AAAA,IACjD,MAAM,IAAI,YAAY,GAAG,uBAAuB,OAAO,KAAK,IAAI,GAAG;AAAA,EACpE;AAAA,EACA,OAAO;AAAA;AAID,SAAS,aAAa,CAAC,KAAgC;AAAA,EAC7D,MAAM,MAA4B,CAAC;AAAA,EACnC,MAAM,MAAM,CACX,KACA,UACI;AAAA,IACJ,IAAI,UAAU;AAAA,MAAW,IAAI,OAAO;AAAA;AAAA,EAGrC,IAAI,eAAe,IAAI,gBAAgB,gBAAgB,OAAO,SAAS;AAAA,EACvE,MAAM,YAAY,IAAI;AAAA,EACtB,IAAI,cAAc,aAAa,cAAc;AAAA,IAAI,IAAI,YAAY;AAAA,EACjE,IAAI,QAAQ,QAAQ,KAAK,cAAc,CAAC;AAAA,EACxC,MAAM,OAAO,IAAI;AAAA,EACjB,IAAI,SAAS,aAAa,SAAS;AAAA,IAAI,IAAI,OAAO;AAAA,EAElD,MAAM,UAAU,IAAI;AAAA,EACpB,IAAI,YAAY,WAAW;AAAA,IAC1B,MAAM,UAAU,QAAQ,KAAK;AAAA,IAC7B,IAAI,iBACH,YAAY,MACT,MACA,QACC,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,CAAC,MAAM,MAAM,EAAE;AAAA,EAC5B;AAAA,EAEA,MAAM,QAAQ,IAAI;AAAA,EAClB,IAAI,UAAU,aAAa,MAAM,KAAK,MAAM,IAAI;AAAA,IAC/C,IAAI;AAAA,IACJ,IAAI;AAAA,MACH,SAAS,KAAK,MAAM,KAAK;AAAA,MACxB,MAAM;AAAA,MACP,MAAM,IAAI,YAAY,6CAA6C;AAAA;AAAA,IAEpE,IAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;AAAA,MAC3B,MAAM,IAAI,YAAY,6CAA6C;AAAA,IACpE;AAAA,IACA,IAAI,QAAQ;AAAA,EACb;AAAA,EACA,MAAM,QAAQ,IAAI;AAAA,EAClB,IAAI,UAAU,aAAa,MAAM,KAAK,MAAM,IAAI;AAAA,IAC/C,IAAI,gBAAgB,MAClB,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,CAAC,MAAM,MAAM,EAAE;AAAA,EACzB;AAAA,EAEA,IAAI,YAAY,MAAM,KAAK,oBAAoB,CAAC,QAAQ,MAAM,CAAU,CAAC;AAAA,EACzE,MAAM,WAAW;AAAA,IAChB,QAAQ,IAAI;AAAA,IACZ,UAAU,IAAI;AAAA,IACd,cAAc,IAAI;AAAA,IAClB,cAAc,IAAI;AAAA,IAClB,iBAAiB,IAAI;AAAA,IACrB,kBAAkB,IAAI;AAAA,EACvB;AAAA,EACA,IAAI,OAAO,OAAO,QAAQ,EAAE,KAAK,CAAC,MAAM,MAAM,aAAa,MAAM,EAAE,GAAG;AAAA,IACrE,MAAM,OAAmB;AAAA,MACxB,QAAQ,SAAS,UAAU;AAAA,MAC3B,UAAU,SAAS,YAAY;AAAA,MAC/B,iBAAiB,SAAS,mBAAmB;AAAA,MAC7C,kBAAkB,SAAS,oBAAoB;AAAA,IAChD;AAAA,IACA,IAAI,SAAS,iBAAiB,aAAa,SAAS,iBAAiB,IAAI;AAAA,MACxE,KAAK,eAAe,SAAS;AAAA,IAC9B;AAAA,IACA,IAAI,SAAS,iBAAiB,aAAa,SAAS,iBAAiB,IAAI;AAAA,MACxE,KAAK,eAAe,SAAS;AAAA,IAC9B;AAAA,IACA,IAAI,OAAO;AAAA,EACZ;AAAA,EACA,IACC,cACA,MAAM,KAAK,uBAAuB;AAAA,IACjC;AAAA,IACA;AAAA,IACA;AAAA,EACD,CAAU,CACX;AAAA,EACA,MAAM,OAAO,MAAM,KAAK,gBAAgB,CAAC,MAAM,KAAK,CAAU;AAAA,EAC9D,IAAI,SAAS;AAAA,IAAW,IAAI,OAAO,SAAS;AAAA,EAC5C,IAAI,SAAS,MAAM,KAAK,iBAAiB,CAAC,UAAU,QAAQ,CAAU,CAAC;AAAA,EACvE,MAAM,aAAa,IAAI;AAAA,EACvB,IAAI,eAAe,aAAa,eAAe;AAAA,IAC9C,IAAI,aAAa;AAAA,EAElB,IAAI,eAAe,QAAQ,KAAK,sBAAsB,CAAC;AAAA,EACvD,IAAI,oBAAoB,QAAQ,KAAK,6BAA6B,CAAC;AAAA,EACnE,IAAI,yBAAyB,QAAQ,KAAK,iCAAiC,CAAC;AAAA,EAC5E,IAAI,oBAAoB,QAAQ,KAAK,2BAA2B,CAAC;AAAA,EACjE,IAAI,eAAe,QAAQ,KAAK,qBAAqB,CAAC;AAAA,EACtD,IAAI,iBAAiB,QAAQ,KAAK,wBAAwB,CAAC;AAAA,EAC3D,IAAI,qBAAqB,QAAQ,KAAK,4BAA4B,CAAC;AAAA,EACnE,IAAI,eAAe,QAAQ,KAAK,qBAAqB,CAAC;AAAA,EACtD,IAAI,iBAAiB,QAAQ,KAAK,wBAAwB,CAAC;AAAA,EAC3D,IAAI,cAAc,cAAc,KAAK,qBAAqB,CAAC;AAAA,EAC3D,IAAI,mBAAmB,QAAQ,KAAK,2BAA2B,CAAC;AAAA,EAChE,IAAI,oBAAoB,QAAQ,KAAK,4BAA4B,CAAC;AAAA,EAClE,IAAI,qBAAqB,QAAQ,KAAK,6BAA6B,CAAC;AAAA,EACpE,IAAI,mBAAmB,QAAQ,KAAK,0BAA0B,CAAC;AAAA,EAC/D,IACC,YACA,MAAM,KAAK,qBAAqB;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,CAAU,CACX;AAAA,EACA,OAAO;AAAA;;ACnpBD,IAAM,iBAAiB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD;AAIO,IAAM,gBAAgB;AAC7B,IAAM,iBAAiB;AACvB,IAAM,cAAc,KAAK;AACzB,IAAM,kBAAkB;AAExB,IAAM,gBAAgB,KAAK;AAC3B,IAAM,mBAAmB;AAAA;AAElB,MAAM,iBAAiB,MAAM;AAAA,EAC1B,OAAO;AAAA,EAEP;AAAA,EACT,WAAW,CAAC,QAAgB,SAAiB;AAAA,IAC5C,MAAM,OAAO;AAAA,IACb,KAAK,SAAS;AAAA;AAEhB;AAsBA,SAAS,aAAa,CAAC,MAAuC;AAAA,EAC7D,IAAI,CAAC,mBAAmB,KAAK,IAAI,GAAG;AAAA,IACnC,MAAM,IAAI,SAAS,aAAa,4BAA4B;AAAA,EAC7D;AAAA,EACA,OAAO,WAAW,WAAW,MAAM,EAAE,UAAU,YAAY,CAAC;AAAA;AAG7D,SAAS,QAAQ,CAAC,MAAc,MAAuC;AAAA,EACtE,IAAI;AAAA,EACJ,IAAI;AAAA,IACH,QAAQ,KAAK,MACZ,IAAI,YAAY,SAAS,EAAE,OAAO,KAAK,CAAC,EAAE,OAAO,cAAc,IAAI,CAAC,CACrE;AAAA,IACC,MAAM;AAAA,IACP,MAAM,IAAI,SAAS,aAAa,eAAe,kBAAkB;AAAA;AAAA,EAElE,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GAAG;AAAA,IACxE,MAAM,IAAI,SAAS,aAAa,eAAe,2BAA2B;AAAA,EAC3E;AAAA,EACA,OAAO;AAAA;AAID,SAAS,SAAS,CAAC,OAA2B;AAAA,EACpD,IAAI,OAAO,UAAU,YAAY,MAAM,SAAS,eAAe;AAAA,IAC9D,MAAM,IAAI,SAAS,aAAa,wBAAwB;AAAA,EACzD;AAAA,EACA,MAAM,QAAQ,MAAM,MAAM,GAAG;AAAA,EAC7B,IAAI,MAAM,WAAW,GAAG;AAAA,IACvB,MAAM,IAAI,SAAS,aAAa,+BAA+B;AAAA,EAChE;AAAA,EACA,OAAO,IAAI,IAAI,IAAI,IAAI,IAAI,MAAM;AAAA,EACjC,OAAO;AAAA,IACN,QAAQ,SAAS,GAAG,QAAQ;AAAA,IAC5B,SAAS,SAAS,GAAG,SAAS;AAAA,IAC9B,cAAc,IAAI,YAAY,EAAE,OAAO,GAAG,KAAK,GAAG;AAAA,IAClD,WAAW,cAAc,CAAC;AAAA,EAC3B;AAAA;AAaD,SAAS,IAAI,CAAC,KAAkC;AAAA,EAC/C,MAAM,OAAO,IAAI,MAAM,CAAC;AAAA,EACxB,MAAM,OAAO,OAAO;AAAA,EACpB,QAAQ,IAAI,MAAM,GAAG,CAAC;AAAA,SAChB;AAAA,MACJ,OAAO;AAAA,QACN,KAAK;AAAA,QACL,cAAc,EAAE,MAAM,qBAAqB,KAAK;AAAA,QAChD,cAAc,EAAE,MAAM,oBAAoB;AAAA,MAC3C;AAAA,SACI;AAAA,MACJ,OAAO;AAAA,QACN,KAAK;AAAA,QACL,cAAc,EAAE,MAAM,WAAW,KAAK;AAAA,QACtC,cAAc;AAAA,UACb,MAAM;AAAA,UACN,YAAY,OAAO,IAAI,IAAI;AAAA,QAC5B;AAAA,MACD;AAAA,SACI,MAAM;AAAA,MACV,MAAM,MAAM,SAAS,QAAQ,UAAU,KAAK;AAAA,MAC5C,OAAO;AAAA,QACN,KAAK;AAAA,QACL;AAAA,QACA,cAAc,EAAE,MAAM,SAAS,YAAY,IAAI;AAAA,QAC/C,cAAc,EAAE,MAAM,SAAS,KAAK;AAAA,MACrC;AAAA,IACD;AAAA;AAAA,MAEC,OAAO;AAAA,QACN,KAAK;AAAA,QACL,KAAK;AAAA,QACL,cAAc,EAAE,MAAM,UAAU;AAAA,QAChC,cAAc,EAAE,MAAM,UAAU;AAAA,MACjC;AAAA;AAAA;AAIH,SAAS,WAAW,CAAC,GAA+B;AAAA,EACnD,OAAQ,eAAsC,SAAS,CAAC;AAAA;AAIzD,SAAS,OAAO,CAAC,KAAU,KAA4B;AAAA,EACtD,MAAM,IAAI,KAAK,GAAG;AAAA,EAClB,IAAI,IAAI,QAAQ,EAAE;AAAA,IAAK,OAAO;AAAA,EAC9B,IAAI,EAAE,QAAQ,aAAa,IAAI,QAAQ,EAAE;AAAA,IAAK,OAAO;AAAA,EACrD,IAAI,IAAI,QAAQ,aAAa,IAAI,QAAQ;AAAA,IAAO,OAAO;AAAA,EACvD,IAAI,IAAI,QAAQ,aAAa,IAAI,QAAQ;AAAA,IAAK,OAAO;AAAA,EACrD,OAAO;AAAA;AAIR,SAAS,SAAS,CAAC,KAAkC;AAAA,EACpD,MAAM,MAA8B,EAAE,KAAK,IAAI,IAAc;AAAA,EAC7D,WAAW,KAAK,CAAC,KAAK,KAAK,OAAO,KAAK,GAAG,GAAY;AAAA,IACrD,MAAM,IAAI,IAAI;AAAA,IACd,IAAI,OAAO,MAAM;AAAA,MAAU,IAAI,KAAK;AAAA,EACrC;AAAA,EACA,OAAO;AAAA;AAUR,eAAsB,SAAS,CAC9B,KACA,OAAoB,CAAC,GACrB,WAAmB,gBACA;AAAA,EACnB,MAAM,MAAM,MAAM,MAAM,KAAK;AAAA,OACzB;AAAA,IACH,UAAU;AAAA,IACV,QAAQ,YAAY,QAAQ,gBAAgB;AAAA,IAC5C,SAAS,EAAE,QAAQ,uBAAwB,KAAK,WAAW,CAAC,EAAG;AAAA,EAChE,CAAC;AAAA,EACD,MAAM,SAAS,OAAO,IAAI,QAAQ,IAAI,gBAAgB,KAAK,GAAG;AAAA,EAC9D,IAAI,SAAS;AAAA,IAAU,MAAM,IAAI,MAAM,uBAAuB,MAAM;AAAA,EAGpE,MAAM,SAAuB,CAAC;AAAA,EAC9B,IAAI,OAAO;AAAA,EACX,MAAM,SAAS,IAAI,MAAM,UAAU;AAAA,EACnC,OAAO,WAAW,WAAW;AAAA,IAC5B,QAAQ,MAAM,UAAU,MAAM,OAAO,KAAK;AAAA,IAC1C,IAAI;AAAA,MAAM;AAAA,IACV,QAAQ,MAAM;AAAA,IACd,IAAI,OAAO,UAAU;AAAA,MACpB,MAAM,OAAO,OAAO;AAAA,MACpB,MAAM,IAAI,MAAM,uBAAuB,MAAM;AAAA,IAC9C;AAAA,IACA,OAAO,KAAK,KAAK;AAAA,EAClB;AAAA,EACA,MAAM,QAAQ,IAAI,WAAW,IAAI;AAAA,EACjC,IAAI,SAAS;AAAA,EACb,WAAW,SAAS,QAAQ;AAAA,IAC3B,MAAM,IAAI,OAAO,MAAM;AAAA,IACvB,UAAU,MAAM;AAAA,EACjB;AAAA,EACA,MAAM,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK;AAAA,EAC3C,IAAI;AAAA,EACJ,IAAI;AAAA,IACH,QAAQ,KAAK,MAAM,IAAI;AAAA,IACtB,MAAM;AAAA,IACP,MAAM,IAAI,MAAM,aAAa,aAAa,IAAI,SAAS;AAAA;AAAA,EAExD,IAAI,CAAC,IAAI,IAAI;AAAA,IACZ,MAAM,QAAS,QAA2C;AAAA,IAC1D,MAAM,IAAI,cACT,IAAI,QACJ,OAAO,UAAU,WAAW,QAAQ,IACpC,GACD;AAAA,EACD;AAAA,EACA,OAAO;AAAA;AAAA;AAGD,MAAM,sBAAsB,MAAM;AAAA,EAC/B,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACT,WAAW,CAAC,QAAgB,OAAe,KAAa;AAAA,IACvD,MAAM,QAAQ,SAAS,UAAU,KAAK,KAAK,IAAI,YAAY,MAAM;AAAA,IACjE,KAAK,SAAS;AAAA,IACd,KAAK,QAAQ;AAAA;AAEf;AAAA;AAQO,MAAM,UAA+B;AAAA,EAClC;AAAA,EACA;AAAA,EACT,QAAe,CAAC;AAAA,EAChB,aAAa;AAAA,EACb,eAAe,OAAO;AAAA,EACtB;AAAA,EACA;AAAA,EAEA,WAAW,CACV,KACA,UAAkC,CAAC,GAClC;AAAA,IACD,KAAK,OAAO,OAAO,QAAQ,WAAW,MAAM,QAAQ,QAAQ,GAAG,IAAI;AAAA,IACnE,KAAK,OAAO,QAAQ,OAAO,KAAK;AAAA;AAAA,OAG3B,KAAI,CAAC,KAAyC;AAAA,IAInD,IAAI,KAAK,cAAc;AAAA,MAAW,MAAM,KAAK,UAAU,MAAM,MAAM,EAAE;AAAA,IACrE,MAAM,MAAM,KAAK,KAAK;AAAA,IACtB,MAAM,QAAQ,MAAM,KAAK,cAAc;AAAA,IACvC,MAAM,UAAU,QAAQ,aAAa,CAAC,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,QAAQ,GAAG;AAAA,IAC1E,KAAK,SAAS,YAAY,MAAM,KAAK,gBAAgB,iBAAiB;AAAA,MACrE,IAAI;AAAA,QACH,MAAM,KAAK,SAAS;AAAA,QACnB,OAAO,OAAO;AAAA,QACf,KAAK,aAAa,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,MAAM;AAAA;AAAA,IAErE;AAAA,IACA,IAAI,KAAK,KAAK,IAAI,KAAK,cAAc,cAAc,eAAe;AAAA,MAEjE,MAAM,KAAK,cAAc,IAAI,MAAM,8BAA8B;AAAA,IAClE;AAAA,IACA,OAAO,QAAQ,YACZ,KAAK,QACL,KAAK,MAAM,OAAO,CAAC,MAAM,EAAE,QAAQ,GAAG;AAAA;AAAA,EAG1C,QAAQ,GAAkB;AAAA,IACzB,KAAK,eAAe,YAAY;AAAA,MAC/B,KAAK,eAAe,KAAK,KAAK;AAAA,MAC9B,IAAI;AAAA,QACH,MAAM,MAAM,MAAM,UAAU,MAAM,KAAK,KAAK,CAAC;AAAA,QAC7C,MAAM,OAAQ,KAAmC;AAAA,QACjD,IAAI,CAAC,MAAM,QAAQ,IAAI;AAAA,UAAG,MAAM,IAAI,MAAM,mBAAmB;AAAA,QAC7D,KAAK,QAAQ,KAAK,OACjB,CAAC,MAAgB,OAAO,MAAM,YAAY,MAAM,IACjD;AAAA,QACA,KAAK,aAAa,KAAK,KAAK;AAAA,QAC5B,KAAK,aAAa;AAAA,gBACjB;AAAA,QACD,KAAK,YAAY;AAAA;AAAA,OAEhB;AAAA,IACH,OAAO,KAAK;AAAA;AAEd;AAUA,eAAsB,SAAS,CAC9B,OACA,QACA,UAAyB,CAAC,GACJ;AAAA,EACtB,MAAM,MAAM,UAAU,KAAK;AAAA,EAC3B,QAAQ,WAAW;AAAA,EACnB,MAAM,MAAM,OAAO;AAAA,EACnB,MAAM,UAAU,QAAQ,cAAc;AAAA,EACtC,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,QAAQ,SAAS,GAAG,GAAG;AAAA,IAChD,MAAM,IAAI,SACT,OACA,0CAA0C,OAAO,GAAG,EAAE,MAAM,GAAG,EAAE,IAClE;AAAA,EACD;AAAA,EACA,IAAI,OAAO,YAAY,WAAW;AAAA,IACjC,MAAM,IAAI,SAAS,QAAQ,0CAA0C;AAAA,EACtE;AAAA,EACA,IAAI,QAAQ,QAAQ,aAAa,OAAO,WAAW,QAAQ,KAAK;AAAA,IAC/D,MAAM,IAAI,SAAS,OAAO,4BAA4B,QAAQ,KAAK;AAAA,EACpE;AAAA,EACA,MAAM,MAAM,OAAO;AAAA,EACnB,IAAI,QAAQ,aAAa,OAAO,QAAQ,UAAU;AAAA,IACjD,MAAM,IAAI,SAAS,aAAa,iCAAiC;AAAA,EAClE;AAAA,EACA,IAAI;AAAA,EACJ,IAAI;AAAA,IACH,cAAc,MAAM,OAAO,KAAK,GAAG,GAAG,OAAO,CAAC,MAAM,QAAQ,GAAG,GAAG,CAAC;AAAA,IAClE,OAAO,OAAO;AAAA,IACf,MAAM,IAAI,SACT,oBACA,yCAAyC,iBAAiB,QAAQ,MAAM,UAAU,WACnF;AAAA;AAAA,EAGD,IAAI,WAAW,WAAW,KAAM,QAAQ,aAAa,WAAW,SAAS,GAAI;AAAA,IAC5E,MAAM,IAAI,SAAS,OAAO,yBAAyB;AAAA,EACpD;AAAA,EACA,MAAM,IAAI,KAAK,GAAG;AAAA,EAClB,WAAW,OAAO,YAAY;AAAA,IAC7B,IAAI;AAAA,IACJ,IAAI;AAAA,MACH,MAAM,MAAM,OAAO,OAAO,UACzB,OACA,UAAU,GAAG,GACb,EAAE,cACF,OACA,CAAC,QAAQ,CACV;AAAA,MACC,MAAM;AAAA,MACP;AAAA;AAAA,IAED,MAAM,KAAK,MAAM,OAAO,OACtB,OAAO,EAAE,cAAc,KAAK,IAAI,WAAW,IAAI,YAAY,EAC3D,MAAM,MAAM,KAAK;AAAA,IACnB,IAAI;AAAA,MAAI,OAAO;AAAA,EAChB;AAAA,EACA,MAAM,IAAI,SAAS,aAAa,oCAAoC;AAAA;AAI9D,SAAS,WAAW,CAC1B,SACA,MACqB;AAAA,EACrB,MAAM,IAAI,QAAQ;AAAA,EAClB,IAAI,MAAM;AAAA,IAAW;AAAA,EACrB,IAAI,OAAO,MAAM,YAAY,CAAC,OAAO,SAAS,CAAC,GAAG;AAAA,IACjD,MAAM,IAAI,SAAS,UAAU,GAAG,uBAAuB;AAAA,EACxD;AAAA,EACA,OAAO,IAAI;AAAA;AAIL,SAAS,SAAS,CAAC,SAA4C;AAAA,EACrE,MAAM,MAAM,QAAQ;AAAA,EACpB,IAAI,OAAO,QAAQ;AAAA,IAAU,OAAO,CAAC,GAAG;AAAA,EACxC,IAAI,MAAM,QAAQ,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,OAAO,MAAM,QAAQ,GAAG;AAAA,IAClE,OAAO;AAAA,EACR;AAAA,EACA,MAAM,IAAI,SAAS,UAAU,gBAAgB;AAAA;;;AC9XvC,IAAM,oBAAoB;AAE1B,IAAM,gCAAgC;AAEtC,IAAM,kBAAkB;AAC/B,IAAM,cAAc;AACpB,IAAM,UAAU;AAChB,IAAM,eAAe;AAMrB,IAAM,qBAAqB;AAGpB,IAAM,gBACZ;AAMM,SAAS,WAAW,CAAC,QAAgB,SAAyB;AAAA,EACpE,OAAO,IAAI,IAAI,aAAa,QAAQ,EAClC,OAAO,GAAG;AAAA,EAAW,SAAS,EAC9B,OAAO,EACP,SAAS,EAAE,UAAU,aAAa,aAAa,KAAK,CAAC;AAAA;AAAA;AAIjD,MAAM,qBAAqB;AAAA,EACxB;AAAA,EACA;AAAA,EAGA,QAAQ,IAAI;AAAA,EAEZ,aAAa,IAAI;AAAA,EAC1B,WAAW,OAAO;AAAA,EACT;AAAA,EAGT,WAAW,CACV,MACA,MACA,UAAkB,cACjB;AAAA,IACD,KAAK,QAAQ;AAAA,IACb,KAAK,QAAQ,QAAQ,IAAI,UAAU,KAAK,gBAAgB;AAAA,IACxD,KAAK,WAAW;AAAA;AAAA,OAOX,OAAM,CACX,OACA,SACA,MAAc,KAAK,IAAI,GACL;AAAA,IAClB,QAAQ,YAAY,MAAM,UAAU,OAAO,KAAK,OAAO;AAAA,MACtD,KAAK;AAAA,IACN,CAAC;AAAA,IACD,IAAI,QAAQ,WAAW,KAAK,MAAM,iBAAiB;AAAA,MAClD,MAAM,IAAI,SACT,OACA,kDACD;AAAA,IACD;AAAA,IACA,MAAM,MAAM,UAAU,OAAO;AAAA,IAC7B,IAAI,IAAI,WAAW,KAAK,IAAI,OAAO,SAAS;AAAA,MAC3C,MAAM,IAAI,SAAS,OAAO,uCAAuC;AAAA,IAClE;AAAA,IACA,MAAM,MAAM,YAAY,SAAS,KAAK;AAAA,IACtC,IAAI,QAAQ;AAAA,MACX,MAAM,IAAI,SAAS,OAAO,0BAA0B;AAAA,IACrD,IAAI,OAAO,MAAM,iBAAiB;AAAA,MACjC,MAAM,IAAI,SAAS,WAAW,2BAA2B;AAAA,IAC1D;AAAA,IACA,IAAI,MAAM,MAAM,gCAAgC,iBAAiB;AAAA,MAChE,MAAM,IAAI,SACT,YACA,4CACD;AAAA,IACD;AAAA,IACA,MAAM,MAAM,YAAY,SAAS,KAAK;AAAA,IACtC,IAAI,QAAQ,aAAa,MAAM,MAAM,iBAAiB;AAAA,MACrD,MAAM,IAAI,SAAS,OAAO,wCAAwC;AAAA,IACnE;AAAA,IACA,MAAM,MAAM,YAAY,SAAS,KAAK;AAAA,IACtC,IAAI,QAAQ,aAAa,MAAM,MAAM,iBAAiB;AAAA,MACrD,MAAM,IAAI,SAAS,OAAO,gCAAgC;AAAA,IAC3D;AAAA,IACA,MAAM,MAAM,QAAQ;AAAA,IACpB,IAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM,IAAI,SAAS,aAAa;AAAA,MACtE,MAAM,IAAI,SAAS,OAAO,+BAA+B;AAAA,IAC1D;AAAA,IACA,MAAM,MAAM,QAAQ;AAAA,IACpB,IAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM,IAAI,SAAS,SAAS;AAAA,MAClE,MAAM,IAAI,SAAS,OAAO,2BAA2B;AAAA,IACtD;AAAA,IACA,KAAK,OAAO,GAAG;AAAA,IAEf,MAAM,MAAM,YAAY,KAAK,MAAM,QAAQ,GAAG;AAAA,IAC9C,MAAM,UAAU,GAAG;AAAA,EAAQ;AAAA,IAC3B,IAAI,KAAK,MAAM,IAAI,OAAO,GAAG;AAAA,MAC5B,MAAM,IAAI,SAAS,YAAY,gCAAgC;AAAA,IAChE;AAAA,IACA,MAAM,OAAO,KAAK,WAAW,IAAI,GAAG,KAAK;AAAA,IACzC,IAAI,QAAQ,oBAAoB;AAAA,MAC/B,MAAM,IAAI,SAAS,QAAQ,6BAA6B;AAAA,IACzD;AAAA,IAEA,IAAI,KAAK,MAAM,QAAQ,KAAK,UAAU;AAAA,MACrC,MAAM,IAAI,SACT,cACA,8DACD;AAAA,IACD;AAAA,IACA,KAAK,MAAM,IAAI,SAAS,MAAM,eAAe;AAAA,IAC7C,KAAK,WAAW,IAAI,KAAK,OAAO,CAAC;AAAA,IACjC,OAAO;AAAA;AAAA,EAQR,MAAM,CAAC,KAAmB;AAAA,IACzB,IAAI,MAAM,KAAK,WAAW,QAAQ,KAAK,MAAM,OAAO,KAAK;AAAA,MAAU;AAAA,IACnE,KAAK,WAAW;AAAA,IAChB,YAAY,SAAS,UAAU,KAAK,OAAO;AAAA,MAC1C,IAAI,QAAQ;AAAA,QAAK;AAAA,MACjB,KAAK,MAAM,OAAO,OAAO;AAAA,MACzB,MAAM,SAAS,QAAQ,MAAM,GAAG,QAAQ,QAAQ;AAAA,CAAI,CAAC;AAAA,MACrD,MAAM,QAAQ,KAAK,WAAW,IAAI,MAAM,KAAK,KAAK;AAAA,MAClD,IAAI,OAAO;AAAA,QAAG,KAAK,WAAW,IAAI,QAAQ,IAAI;AAAA,MACzC;AAAA,aAAK,WAAW,OAAO,MAAM;AAAA,IACnC;AAAA;AAEF;;ACzJO,SAAS,SAAS,CAAC,IAAkC;AAAA,EAC3D,MAAM,QAAQ,GAAG,MAAM,GAAG;AAAA,EAC1B,IAAI,MAAM,WAAW;AAAA,IAAG;AAAA,EACxB,MAAM,SAAS,MAAM,IAAI,CAAC,MAAO,YAAY,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,EAAG;AAAA,EACtE,OAAO,OAAO,MAAM,CAAC,MAAM,KAAK,KAAK,KAAK,GAAG,IAAI,SAAS;AAAA;AAIpD,SAAS,SAAS,CAAC,IAAkC;AAAA,EAC3D,MAAM,UAAU,GAAG,MAAM,GAAG,EAAE,MAAM;AAAA,EACpC,MAAM,SAAS,QAAQ,MAAM,IAAI;AAAA,EACjC,IAAI,OAAO,SAAS;AAAA,IAAG;AAAA,EACvB,MAAM,YAAY,CAAC,SAAuC;AAAA,IACzD,IAAI,SAAS;AAAA,MAAI,OAAO,CAAC;AAAA,IACzB,MAAM,SAAmB,CAAC;AAAA,IAC1B,MAAM,QAAQ,KAAK,MAAM,GAAG;AAAA,IAC5B,YAAY,GAAG,SAAS,MAAM,QAAQ,GAAG;AAAA,MACxC,IAAI,MAAM,MAAM,SAAS,KAAK,KAAK,SAAS,GAAG,GAAG;AAAA,QACjD,MAAM,KAAK,UAAU,IAAI;AAAA,QACzB,IAAI,OAAO;AAAA,UAAW;AAAA,QACtB,OAAO,MACJ,GAAG,MAAM,MAAM,KAAM,GAAG,MAAM,KAC9B,GAAG,MAAM,MAAM,KAAM,GAAG,MAAM,EACjC;AAAA,MACD,EAAO,SAAI,qBAAqB,KAAK,IAAI,GAAG;AAAA,QAC3C,OAAO,KAAK,OAAO,SAAS,MAAM,EAAE,CAAC;AAAA,MACtC,EAAO;AAAA,QACN;AAAA;AAAA,IAEF;AAAA,IACA,OAAO;AAAA;AAAA,EAER,MAAM,OAAO,UAAU,OAAO,MAAM,EAAE;AAAA,EACtC,MAAM,OAAO,OAAO,WAAW,IAAI,UAAU,OAAO,MAAM,EAAE,IAAI,CAAC;AAAA,EACjE,IAAI,SAAS,aAAa,SAAS;AAAA,IAAW;AAAA,EAC9C,IAAI,OAAO,WAAW;AAAA,IAAG,OAAO,KAAK,WAAW,IAAI,OAAO;AAAA,EAC3D,MAAM,UAAU,IAAI,KAAK,SAAS,KAAK;AAAA,EACvC,IAAI,UAAU;AAAA,IAAG;AAAA,EACjB,OAAO,CAAC,GAAG,MAAM,GAAG,IAAI,MAAc,OAAO,EAAE,KAAK,CAAC,GAAG,GAAG,IAAI;AAAA;AAIhE,IAAM,aAAyD;AAAA,EAC9D,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA,EACd,CAAC,IAAI,GAAG,GAAG,GAAG,CAAC;AAAA,EACf,CAAC,KAAK,IAAI,GAAG,GAAG,EAAE;AAAA,EAClB,CAAC,KAAK,GAAG,GAAG,GAAG,CAAC;AAAA,EAChB,CAAC,KAAK,KAAK,GAAG,GAAG,EAAE;AAAA,EACnB,CAAC,KAAK,IAAI,GAAG,GAAG,EAAE;AAAA,EAClB,CAAC,KAAK,GAAG,GAAG,GAAG,EAAE;AAAA,EACjB,CAAC,KAAK,GAAG,GAAG,GAAG,EAAE;AAAA,EACjB,CAAC,KAAK,IAAI,IAAI,GAAG,EAAE;AAAA,EACnB,CAAC,KAAK,KAAK,GAAG,GAAG,EAAE;AAAA,EACnB,CAAC,KAAK,IAAI,GAAG,GAAG,EAAE;AAAA,EAClB,CAAC,KAAK,IAAI,KAAK,GAAG,EAAE;AAAA,EACpB,CAAC,KAAK,GAAG,KAAK,GAAG,EAAE;AAAA,EACnB,CAAC,KAAK,GAAG,GAAG,GAAG,CAAC;AAAA,EAChB,CAAC,KAAK,GAAG,GAAG,GAAG,CAAC;AACjB;AAEA,SAAS,QAAQ,CAAC,GAAqB;AAAA,EACtC,SACI,EAAE,MAAM,MAAM,OAAQ,OACvB,EAAE,MAAM,MAAM,QACd,EAAE,MAAM,MAAM,MACf,EAAE,MAAM;AAAA;AAIX,SAAS,UAAU,CAAC,QAA2B;AAAA,EAC9C,MAAM,IAAI,SAAS,MAAM;AAAA,EACzB,OAAO,WAAW,MAAM,EAAE,GAAG,GAAG,GAAG,GAAG,UAAU;AAAA,IAC/C,MAAM,OAAO,SAAS,IAAI,IAAK,cAAe,KAAK,SAAW;AAAA,IAC9D,QAAQ,IAAI,UAAU,OAAO,SAAS,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,IAAI,UAAU;AAAA,GAChE;AAAA;AAGF,SAAS,UAAU,CAAC,GAAsB;AAAA,EACzC,OAAO,KAAK,GAAG,KAAK,KAAK;AAAA,EAGzB,MAAM,WAAW;AAAA,KACf,EAAE,MAAM,MAAM;AAAA,KACd,EAAE,MAAM,KAAK;AAAA,KACb,EAAE,MAAM,MAAM;AAAA,KACd,EAAE,MAAM,KAAK;AAAA,EACf;AAAA,EACA,IAAI,EAAE,MAAM,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,SAAU,EAAE,OAAO,IAAI;AAAA,IAC3E,OAAO,EAAE,OAAO,SAAU,WAAW,QAAQ;AAAA,EAC9C;AAAA,EACA,IAAI,OAAO,OAAQ,OAAO,SAAU,EAAE,MAAM,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,MAAM,CAAC,GAAG;AAAA,IACxE,OAAO,WAAW,QAAQ;AAAA,EAC3B;AAAA,EAEA,KAAK,KAAK,WAAY;AAAA,IAAQ,OAAO;AAAA,EAErC,IAAI,OAAO,QAAU,KAAK;AAAA,IAAQ,OAAO;AAAA,EACzC,IAAI,OAAO,QAAU,OAAO;AAAA,IAAQ,OAAO;AAAA,EAC3C,IAAI,OAAO;AAAA,IAAQ,OAAO;AAAA,EAC1B,IAAI,OAAO,SAAU,KAAK;AAAA,IAAQ,OAAO;AAAA,EACzC,OAAO;AAAA;AAOD,SAAS,UAAU,CAAC,IAAqB;AAAA,EAC/C,MAAM,KAAK,UAAU,EAAE;AAAA,EACvB,IAAI,OAAO;AAAA,IAAW,OAAO,WAAW,EAAE;AAAA,EAC1C,MAAM,KAAK,UAAU,GAAG,QAAQ,YAAY,EAAE,CAAC;AAAA,EAC/C,IAAI,OAAO;AAAA,IAAW,OAAO,WAAW,EAAE;AAAA,EAC1C,OAAO;AAAA;AAID,SAAS,cAAc,CAAC,UAA2B;AAAA,EACzD,MAAM,IAAI,SAAS,QAAQ,YAAY,EAAE,EAAE,YAAY;AAAA,EACvD,IAAI,MAAM,eAAe,EAAE,SAAS,YAAY;AAAA,IAAG,OAAO;AAAA,EAC1D,MAAM,KAAK,UAAU,CAAC;AAAA,EACtB,IAAI,OAAO;AAAA,IAAW,OAAO,GAAG,OAAO;AAAA,EACvC,MAAM,KAAK,UAAU,CAAC;AAAA,EACtB,OAAO,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,MAAM,CAAC,MAAM,QAAQ,GAAG,OAAO;AAAA;AAS7D,SAAS,WAAW,CAAC,IAAoB;AAAA,EAC/C,MAAM,KAAK,UAAU,EAAE;AAAA,EACvB,IAAI,OAAO;AAAA,IAAW,OAAO,GAAG,KAAK,GAAG;AAAA,EACxC,MAAM,KAAK,UAAU,GAAG,QAAQ,YAAY,EAAE,CAAC;AAAA,EAC/C,IAAI,OAAO;AAAA,IAAW,OAAO;AAAA,EAC7B,IAAI,GAAG,MAAM,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,MAAM,CAAC,KAAK,GAAG,OAAO,OAAQ;AAAA,IAC7D,MAAM,KAAK,GAAG,MAAM;AAAA,IACpB,MAAM,KAAK,GAAG,MAAM;AAAA,IACpB,OAAO,GAAG,MAAM,KAAK,KAAK,OAAQ,MAAM,KAAK,KAAK;AAAA,EACnD;AAAA,EACA,OAAO,GAAG,GACR,MAAM,GAAG,CAAC,EACV,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,EACzB,KAAK,GAAG;AAAA;;;ACnIX,IAAM,QAAkC;AAAA,EACvC,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AACR;AAGO,SAAS,YAAY,CAC3B,OACA,OAA+B,CAAC,SAAS;AAAA,EACxC,QAAQ,OAAO,MAAM,GAAG;AAAA,CAAQ;AAAA,GAExB;AAAA,EACT,MAAM,MAAM,MAAM;AAAA,EAClB,MAAM,QAAQ,CAAC,KAAe,OAAe,WAAuB;AAAA,IACnE,IAAI,MAAM,OAAO;AAAA,MAAK;AAAA,IACtB,KACC,KAAK,UAAU;AAAA,MACd,MAAM,IAAI,KAAK,EAAE,YAAY;AAAA,MAC7B,OAAO;AAAA,MACP;AAAA,SACG;AAAA,IACJ,CAAC,CACF;AAAA;AAAA,EAED,OAAO;AAAA,IACN,OAAO,CAAC,GAAG,MAAM,MAAM,SAAS,GAAG,CAAC;AAAA,IACpC,MAAM,CAAC,GAAG,MAAM,MAAM,QAAQ,GAAG,CAAC;AAAA,IAClC,MAAM,CAAC,GAAG,MAAM,MAAM,QAAQ,GAAG,CAAC;AAAA,IAClC,OAAO,CAAC,GAAG,MAAM,MAAM,SAAS,GAAG,CAAC;AAAA,EACrC;AAAA;AAOM,SAAS,UAAU,CAAC,IAAoB;AAAA,EAC9C,MAAM,KAAK,UAAU,EAAE;AAAA,EACvB,IAAI,OAAO;AAAA,IAAW,OAAO,GAAG,GAAG,MAAM,GAAG,CAAC,EAAE,KAAK,GAAG;AAAA,EACvD,MAAM,KAAK,UAAU,EAAE;AAAA,EACvB,IAAI,OAAO;AAAA,IAAW,OAAO;AAAA,EAC7B,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,MAAM,CAAC,KAAK,GAAG,OAAO;AAAA,EACjE,IAAI,QAAQ;AAAA,IACX,MAAM,KAAK,GAAG,MAAM;AAAA,IACpB,OAAO,GAAG,MAAM,KAAK,KAAK,QAAS,GAAG,MAAM,MAAM;AAAA,EACnD;AAAA,EACA,OAAO,GAAG,GACR,MAAM,GAAG,CAAC,EACV,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,EACzB,KAAK,GAAG;AAAA;AAOJ,SAAS,SAAS,CAAC,OAAwB;AAAA,EACjD,OAAO,iBAAiB,QAAQ,MAAM,OAAO,OAAO;AAAA;AAc9C,SAAS,mBAAmB,CAClC,QACA,OAA+B,CAAC,SAAS,QAAQ,KAAK,IAAI,GAC7C;AAAA,EACb,MAAM,cAAc,CAAC,UAAmB;AAAA,IACvC,OAAO,MAAM,+BAA+B,EAAE,OAAO,UAAU,KAAK,EAAE,CAAC;AAAA;AAAA,EAExE,MAAM,cAAc,CAAC,UAAmB;AAAA,IACvC,OAAO,MAAM,8BAA8B,EAAE,OAAO,UAAU,KAAK,EAAE,CAAC;AAAA,IACtE,KAAK,CAAC;AAAA;AAAA,EAEP,QAAQ,GAAG,sBAAsB,WAAW;AAAA,EAC5C,QAAQ,GAAG,qBAAqB,WAAW;AAAA,EAC3C,OAAO,MAAM;AAAA,IACZ,QAAQ,IAAI,sBAAsB,WAAW;AAAA,IAC7C,QAAQ,IAAI,qBAAqB,WAAW;AAAA;AAAA;;ACjGvC,IAAM,cAAc;AAGpB,IAAM,uBAAuB;AAG7B,IAAM,4BACZ;AAEM,IAAM,YAAY;AAAA,EACxB,QAAQ;AAAA,EACR,iBAAiB;AAAA,EACjB,UAAU;AAAA,EACV,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,eAAe;AAAA,EACf,cAAc;AAAA,EACd,UAAU;AAAA,EAEV,aAAa;AAAA,EAEb,iBAAiB;AAClB;AAiNA,IAAM,YAAY;AAClB,IAAM,WAAW;AACjB,IAAM,SAAS;AACf,IAAM,mBAAmB;AACzB,IAAM,mBAAmB;AAOzB,IAAM,cAAc;AAIpB,SAAS,QAAQ,CAAC,GAAuB;AAAA,EACxC,OAAO,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,MAAM,QAAQ,CAAC;AAAA;AAG/D,SAAS,QAAQ,CAAC,GAAY,KAA0B;AAAA,EACvD,OAAO,OAAO,MAAM,YAAY,EAAE,UAAU;AAAA;AAG7C,SAAS,IAAI,CAAC,GAAyB;AAAA,EACtC,OAAO,OAAO,MAAM,YAAY,EAAE,SAAS,KAAK,EAAE,UAAU;AAAA;AAG7D,SAAS,QAAQ,CAAC,GAAyB;AAAA,EAC1C,OAAO,OAAO,MAAM,YAAY,OAAO,UAAU,CAAC,KAAK,KAAK,OAAO,KAAK;AAAA;AAGzE,SAAS,SAAS,CAAC,GAAyC;AAAA,EAC3D,IAAI,CAAC,SAAS,CAAC;AAAA,IAAG,OAAO;AAAA,EACzB,MAAM,UAAU,OAAO,QAAQ,CAAC;AAAA,EAChC,IAAI,QAAQ,SAAS;AAAA,IAAkB,OAAO;AAAA,EAC9C,OAAO,QAAQ,MACd,EAAE,GAAG,SACJ,oBAAoB,KAAK,CAAC,KAC1B,SAAS,KAAK,gBAAgB,KAC9B,YAAY,KAAK,GAAG,CACtB;AAAA;AAGD,SAAS,IAAI,CAAC,GAA6B;AAAA,EAC1C,OAAO,KAAK,EAAE,KAAK,IAAI,EAAE,QAAQ;AAAA;AAO3B,SAAS,eAAe,CAAC,MAA2B;AAAA,EAC1D,IAAI;AAAA,EACJ,IAAI;AAAA,IACH,IAAI,KAAK,MAAM,IAAI;AAAA,IAClB,MAAM;AAAA,IACP,OAAO,EAAE,IAAI,OAAO,OAAO,WAAW;AAAA;AAAA,EAEvC,IAAI,CAAC,SAAS,CAAC;AAAA,IAAG,OAAO,EAAE,IAAI,OAAO,OAAO,oBAAoB;AAAA,EACjE,MAAM,OAAO,EAAE;AAAA,EACf,IAAI,OAAO,SAAS,YAAY,KAAK,WAAW,KAAK,KAAK,SAAS,IAAI;AAAA,IACtE,OAAO,EAAE,IAAI,OAAO,OAAO,eAAe;AAAA,EAC3C;AAAA,EACA,MAAM,KAAK,KAAK,CAAC;AAAA,EACjB,MAAM,MAAM,CAAC,UACZ,OAAO,YAAY,EAAE,IAAI,OAAO,MAAM,IAAI,EAAE,IAAI,OAAO,OAAO,GAAG;AAAA,EAElE,QAAQ;AAAA,SACF,SAAS;AAAA,MACb,MAAM,UAAU,EAAE;AAAA,MAClB,MAAM,OAAO,EAAE;AAAA,MACf,IACC,CAAC,SAAS,OAAO,KACjB,CAAC,SAAS,QAAQ,SAAS,QAAQ,KACnC,CAAC,SAAS,QAAQ,YAAY,QAAQ,GACrC;AAAA,QACD,OAAO,IAAI,uCAAuC;AAAA,MACnD;AAAA,MACA,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,KAAK,UAAU,SAAS,GAAG;AAAA,QAC3D,OAAO,IAAI,4BAA4B;AAAA,MACxC;AAAA,MACA,IAAI,OAAO,EAAE,cAAc;AAAA,QAAU,OAAO,IAAI,sBAAsB;AAAA,MACtE,MAAM,MAAM,EAAE;AAAA,MACd,IAAI,QAAQ,cAAc,CAAC,SAAS,GAAG,KAAK,CAAC,UAAU,IAAI,OAAO,IAAI;AAAA,QACrE,OAAO,IAAI,4BAA4B,yBAAyB;AAAA,MACjE;AAAA,MACA,MAAM,YAAY,EAAE;AAAA,MACpB,IAAI,cAAc,aAAa,OAAO,cAAc,WAAW;AAAA,QAC9D,OAAO,IAAI,mCAAmC;AAAA,MAC/C;AAAA,MACA,MAAM,QAAsB;AAAA,QAC3B;AAAA,QACA,SAAS,EAAE,MAAM,QAAQ,SAAS,SAAS,QAAQ,WAAW;AAAA,QAC9D,MAAM,EAAE,OAAO,KAAK,SAAS;AAAA,QAC7B,QAAQ,EAAE;AAAA,MACX;AAAA,MACA,IAAI,SAAS,GAAG,KAAK,UAAU,IAAI,OAAO,GAAG;AAAA,QAC5C,MAAM,MAAM,EAAE,MAAM,IAAI,QAAQ;AAAA,MACjC;AAAA,MACA,IAAI,cAAc;AAAA,QAAM,MAAM,YAAY;AAAA,MAC1C,OAAO,EAAE,IAAI,MAAM,SAAS,MAAM;AAAA,IACnC;AAAA,SACK,QAAQ;AAAA,MACZ,MAAM,IAAI,EAAE;AAAA,MACZ,IAAI,OAAO,MAAM;AAAA,QAAU,OAAO,IAAI,yBAAyB;AAAA,MAC/D,OAAO,EAAE,IAAI,MAAM,SAAS,EAAE,MAAM,EAAE,EAAE;AAAA,IACzC;AAAA,SACK,OAAO;AAAA,MACX,MAAM,SAAS,EAAE;AAAA,MACjB,OAAO;AAAA,QACN,IAAI;AAAA,QACJ,SAAS;AAAA,UACR;AAAA,UACA,QAAQ,SAAS,QAAQ,QAAQ,IAAI,SAAS;AAAA,QAC/C;AAAA,MACD;AAAA,IACD;AAAA,SACK,iBAAiB;AAAA,MACrB,IAAI,OAAO;AAAA,QAAW,OAAO,IAAI,0BAA0B;AAAA,MAC3D,QAAQ,QAAQ,SAAS,SAAS;AAAA,MAClC,IAAI,CAAC,SAAS,MAAM;AAAA,QAAG,OAAO,IAAI,8BAA8B;AAAA,MAChE,IAAI,CAAC,UAAU,OAAO;AAAA,QAAG,OAAO,IAAI,+BAA+B;AAAA,MACnE,IAAI,OAAO,SAAS;AAAA,QAAU,OAAO,IAAI,4BAA4B;AAAA,MACrE,OAAO,EAAE,IAAI,MAAM,SAAS,EAAE,MAAM,IAAI,QAAQ,SAAS,KAAK,EAAE;AAAA,IACjE;AAAA,SACK,uBAAuB;AAAA,MAC3B,IAAI,OAAO;AAAA,QAAW,OAAO,IAAI,gCAAgC;AAAA,MACjE,QAAQ,QAAQ,YAAY;AAAA,MAC5B,IAAI,CAAC,SAAS,MAAM;AAAA,QAAG,OAAO,IAAI,oCAAoC;AAAA,MACtE,IAAI,CAAC,UAAU,OAAO;AAAA,QACrB,OAAO,IAAI,qCAAqC;AAAA,MACjD,OAAO,EAAE,IAAI,MAAM,SAAS,EAAE,MAAM,IAAI,QAAQ,QAAQ,EAAE;AAAA,IAC3D;AAAA,SACK,uBAAuB;AAAA,MAC3B,IAAI,OAAO;AAAA,QAAW,OAAO,IAAI,gCAAgC;AAAA,MACjE,MAAM,OAAO,EAAE;AAAA,MACf,IAAI,OAAO,SAAS;AAAA,QACnB,OAAO,IAAI,kCAAkC;AAAA,MAC9C,OAAO,EAAE,IAAI,MAAM,SAAS,EAAE,MAAM,IAAI,KAAK,EAAE;AAAA,IAChD;AAAA,SACK,qBAAqB;AAAA,MACzB,IAAI,OAAO;AAAA,QAAW,OAAO,IAAI,8BAA8B;AAAA,MAC/D,OAAO,EAAE,IAAI,MAAM,SAAS,EAAE,MAAM,GAAG,EAAE;AAAA,IAC1C;AAAA,SACK;AAAA,SACA;AAAA,SACA;AAAA,SACA;AAAA,MACJ,OAAO,EAAE,IAAI,MAAM,SAAS,EAAE,KAAK,EAAE;AAAA,SACjC,YAAY;AAAA,MAChB,MAAM,YAAY,EAAE;AAAA,MACpB,IACC,OAAO,cAAc,YACrB,cAAc,MACd,UAAU,SAAS,eAClB;AAAA,QACD,OAAO,IACN,+CAA+C,qBAChD;AAAA,MACD;AAAA,MACA,MAAM,QAAQ,EAAE;AAAA,MAChB,IACC,UAAU,aACV,EAAE,OAAO,cAAc,KAAK,KAAM,SAAoB,IACrD;AAAA,QACD,OAAO,IAAI,+CAA+C;AAAA,MAC3D;AAAA,MACA,OAAO,UAAU,YACd,EAAE,IAAI,MAAM,SAAS,EAAE,MAAM,UAAU,EAAE,IACzC,EAAE,IAAI,MAAM,SAAS,EAAE,MAAM,WAAW,MAAuB,EAAE;AAAA,IACrE;AAAA,SACK,gBAAgB;AAAA,MACpB,MAAM,UAAU,EAAE;AAAA,MAClB,IAAI,CAAC,KAAK,OAAO;AAAA,QAAG,OAAO,IAAI,8BAA8B;AAAA,MAC7D,OAAO,EAAE,IAAI,MAAM,SAAS,EAAE,MAAM,QAAQ,EAAE;AAAA,IAC/C;AAAA,SACK,SAAS;AAAA,MACb,MAAM,OAAO,EAAE;AAAA,MACf,MAAM,UAAU,EAAE;AAAA,MAClB,IAAI,CAAC,SAAS,MAAM,QAAQ;AAAA,QAAG,OAAO,IAAI,oBAAoB;AAAA,MAC9D,MAAM,IAAqB;AAAA,QAC1B;AAAA,QACA;AAAA,QACA,SAAS,SAAS,SAAS,IAAI,IAAI,UAAU;AAAA,MAC9C;AAAA,MACA,IAAI,OAAO;AAAA,QAAW,EAAE,KAAK;AAAA,MAC7B,OAAO,EAAE,IAAI,MAAM,SAAS,EAAE;AAAA,IAC/B;AAAA;AAAA,MAEC,OAAO,OAAO,YACX,EAAE,IAAI,MAAM,SAAS,MAAM,KAAK,IAChC,EAAE,IAAI,MAAM,SAAS,MAAM,MAAM,GAAG;AAAA;AAAA;;;;;AClanC,IAAM,iBAAiB;AAAA,EAC7B,aAAa;AAAA,EACb,SAAS;AAAA,EACT,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB,WAAW;AAAA,EACX,YAAY;AACb;AAiDA,IAAM,UAAU,IAAI;AAGpB,IAAM,qBAAqB,IAAI,IAAI,CAAC,KAAK,KAAK,GAAG,CAAC;AAGlD,IAAM,0BAA0B,IAAI,IAAI,CAAC,gBAAgB,eAAe,CAAC;AAEzE,SAAS,aAAa,CAAC,SAA0C;AAAA,EAChE,QAAQ,QAAQ,mBAAmB,IACjC,YAAY,EACZ,WAAW,mBAAmB;AAAA;AAGjC,SAAS,cAAc,CAAC,MAAuB;AAAA,EAC9C,OACC,KAAK,SAAS;AAAA;AAAA,CAAM,KAAK,KAAK,SAAS;AAAA;AAAA,CAAU,KAAK,KAAK,SAAS,MAAM;AAAA;AAKrE,SAAS,QAAQ,CAAC,MAAsB;AAAA,EAC9C,MAAM,QAAQ,KAAK,MAAM,YAAY;AAAA,EACrC,OAAO;AAAA,EAAmB,MAAM,IAAI,CAAC,MAAM,SAAS,GAAG,EAAE,KAAK;AAAA,CAAI;AAAA;AAAA;AAAA;AAG5D,SAAS,YAAY,CAC3B,OACA,MACA,SACA,MACS;AAAA,EACT,MAAM,QAAiC,EAAE,MAAM,QAAQ;AAAA,EACvD,IAAI,SAAS;AAAA,IAAW,MAAM,UAAU;AAAA,EACxC,OAAO,KAAK,UAAU,EAAE,SAAS,OAAO,IAAI,SAAS,MAAM,MAAM,CAAC;AAAA;AAmBnE,IAAM,cAAkC,IAAI,IAAI;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AACD,CAAC;AAAA;AAEM,MAAM,SAAS;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EAET,SAAS;AAAA,EAET,UAAU;AAAA,EAEV;AAAA,EAES;AAAA,EACT;AAAA,EACA,SAAgB;AAAA,EAEhB,WAAW;AAAA,EACX;AAAA,EAEA,cAAc;AAAA,EAEd,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EAEA,WAAW,CAAC,SAA0B;AAAA,IACrC,KAAK,WAAW;AAAA,IAChB,KAAK,KAAK,QAAQ;AAAA,IAClB,KAAK,WAAW,QAAQ;AAAA,IACxB,KAAK,WAAW,IAAI,QAAQ,CAAC,YAAY;AAAA,MACxC,KAAK,WAAW;AAAA,KAChB;AAAA,IACD,IAAI,QAAQ,UAAU,WAAW;AAAA,MAChC,KAAK,cAAc,WAClB,MAAM,KAAK,kBAAkB,GAC7B,QAAQ,WACT;AAAA,IACD;AAAA,IACA,IAAI,CAAC,QAAQ,UAAU;AAAA,MACtB,KAAK,gBAAgB,WACpB,MAAM,KAAK,SAAS,GACpB,QAAQ,gBACT;AAAA,IACD;AAAA;AAAA,MAGG,IAAI,GAAY;AAAA,IACnB,OAAO,KAAK,WAAW;AAAA;AAAA,EAIxB,UAAU,CAAC,KAAgC;AAAA,IAC1C,IAAI,YAAY,IAAI,KAAK,MAAM,GAAG;AAAA,MACjC,KAAK,aAAa,yCAAyC;AAAA,MAC3D;AAAA,IACD;AAAA,IACA,IAAI,KAAK,WAAW,WAAW;AAAA,MAC9B,IAAI,CAAC,KAAK,SAAS,IAAI,IAAI;AAAA,QAAG;AAAA,MAC9B,IAAI,mBAAmB,IAAI,IAAI,MAAM,KAAK,IAAI,SAAS,IAAI;AAAA,QAC1D,KAAK,aAAa,UAAU,IAAI,6BAA6B;AAAA,QAC7D;AAAA,MACD;AAAA,MACA,IAAI;AAAA,MACJ,IAAI;AAAA,QACH,WAAW,IAAI,SAAS,IAAI,SAAS,KAAK,OAAO,IAAI,MAAM;AAAA,UAC1D,QAAQ,IAAI;AAAA,UACZ,SAAS,KAAK,SAAS,IAAI,OAAO;AAAA,QACnC,CAAC;AAAA,QACA,MAAM;AAAA,QACP,KAAK,aAAa,iCAAiC;AAAA,QACnD;AAAA;AAAA,MAED,KAAK,SAAS,UAAU,IAAI,MAAM;AAAA,MAClC,KAAK,QAAQ,IAAI;AAAA,IAClB,EAAO,SAAI,KAAK,WAAW,gBAAgB;AAAA,MAC1C,IAAI,CAAC,KAAK,SAAS,IAAI,IAAI;AAAA,QAAG;AAAA,MAC9B,IAAI,IAAI,SAAS;AAAA,QAAI,KAAK,OAAO,SAAS,IAAI,IAAI,CAAC;AAAA,MACnD,KAAK,QAAQ,IAAI;AAAA,IAClB;AAAA;AAAA,EAGD,OAAO,CAAC,KAAqC;AAAA,IAC5C,IAAI,KAAK,WAAW;AAAA,MAAQ;AAAA,IAC5B,IAAI,YAAY,IAAI,KAAK,MAAM,GAAG;AAAA,MACjC,KAAK,aAAa,gCAAgC;AAAA,MAClD;AAAA,IACD;AAAA,IAGA,MAAM,cAAc,cAAc,IAAI,OAAO;AAAA,IAC7C,IAAI,KAAK,YAAY,CAAC,aAAa;AAAA,MAClC,KAAK,aAAa,2CAA2C;AAAA,MAC7D;AAAA,IACD;AAAA,IACA,IAAI,KAAK,WAAW,WAAW;AAAA,MAC9B,IAAI,mBAAmB,IAAI,IAAI,MAAM,GAAG;AAAA,QACvC,KAAK,aAAa,UAAU,IAAI,2BAA2B;AAAA,QAC3D;AAAA,MACD;AAAA,MACA,IAAI;AAAA,MACJ,IAAI;AAAA,QACH,UAAU,KAAK,SAAS,IAAI,OAAO;AAAA,QAClC,MAAM;AAAA,QACP,KAAK,aAAa,kCAAkC;AAAA,QACpD;AAAA;AAAA,MAED,KAAK,YAAY,IAAI,QAAQ,SAAS,YAAY;AAAA,IACnD,EAAO;AAAA,MACN,KAAK,SAAS,cAAc,iBAAiB;AAAA;AAAA;AAAA,EAI/C,OAAO,CAAC,MAAoB;AAAA,IAC3B,IAAI,CAAC,KAAK;AAAA,MAAY;AAAA,IACtB,IAAI,KAAK,WAAW,gBAAgB;AAAA,MACnC,KAAK,aAAa,gDAAgD;AAAA,MAClE;AAAA,IACD;AAAA,IACA,IAAI,CAAC,KAAK,SAAS,IAAI;AAAA,MAAG;AAAA,IAC1B,IAAI,KAAK,WAAW;AAAA,MAAiB,KAAK,YAAY;AAAA,IACjD;AAAA,WAAK,OAAO,IAAI;AAAA;AAAA,EAGtB,KAAK,GAAS;AAAA,IACb,IAAI,CAAC,KAAK;AAAA,MAAY;AAAA,IACtB,IAAI,KAAK,WAAW,mBAAmB,KAAK,aAAa;AAAA,MACxD,KAAK,OAAO,SAAS,KAAK,QAAQ,CAAC;AAAA,IACpC,KAAK,QAAQ,IAAI;AAAA;AAAA,EAIlB,YAAY,GAAS;AAAA,IACpB,IAAI,KAAK,WAAW;AAAA,MAAQ;AAAA,IAC5B,IAAI,KAAK,WAAW;AAAA,MACnB,KAAK,SAAS,IAAI,SAAS,MAAM,EAAE,QAAQ,IAAI,CAAC,GAAG,CAAC;AAAA,IACrD,KAAK,SAAS,OAAO,eAAe;AAAA,IACpC,KAAK,QAAQ,iBAAiB,KAAK;AAAA;AAAA,EAQpC,OAAO,GAAS;AAAA,IACf,IAAI,KAAK,WAAW;AAAA,MAAQ;AAAA,IAC5B,MAAM,UAAU,KAAK,WAAW;AAAA,IAChC,MAAM,QAAQ,KAAK,SAAS,WAAW,OAAO;AAAA,IAC9C,IAAI,OAAO,UAAU,QAAQ,SAAS;AAAA,MACrC,aAAa,KAAK,WAAW;AAAA,MAC7B,KAAK,QAAQ,iBAAiB;AAAA,MAC9B;AAAA,IACD;AAAA,IACA,IAAI,UAAU,aAAa,WAAW,OAAO;AAAA,MAC5C,MAAM,IAAI,MAAM;AAAA,MAChB,KAAK,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,OAAO,EAAE,OAAO;AAAA,MACvD;AAAA,IACD;AAAA,IACA,MAAM,OAAO,OAAO,UAAU,QAAQ,MAAM,OAAO;AAAA,IACnD,IAAI,SAAS,WAAW;AAAA,MACvB,KAAK,KACJ,KACA,eAAe,SACf,gDACA,KACD;AAAA,MACA;AAAA,IACD;AAAA,IACA,IAAI,SAAS;AAAA,MACZ,KAAK,SACJ,IAAI,SAAS,MAAM;AAAA,QAClB,QAAQ;AAAA,QACR,SAAS,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,CAAC;AAAA,MAC9D,CAAC,GACD,GACD;AAAA,IACD,EAAO,SAAI,KAAK,aAAa;AAAA,MAC5B,KAAK,OAAO,SAAS,IAAI,CAAC;AAAA,IAC3B;AAAA,IACA,KAAK,QAAQ,WAAW;AAAA;AAAA,EAQzB,IAAI,CACH,QACA,MACA,SACA,WACA,UAAkC,CAAC,GAC5B;AAAA,IACP,IAAI,KAAK,WAAW;AAAA,MAAQ;AAAA,IAC5B,IAAI,KAAK,WAAW,WAAW;AAAA,MAC9B,KAAK,SACJ,KAAK,eAAe,QAAQ,MAAM,SAAS,OAAO,GAClD,MACD;AAAA,IACD,EAAO,SAAI,KAAK,eAAe,KAAK,SAAS,UAAU,WAAW;AAAA,MACjE,KAAK,OAAO,SAAS,aAAa,KAAK,SAAS,OAAO,MAAM,OAAO,CAAC,CAAC;AAAA,IACvE;AAAA,IACA,IAAI;AAAA,MAAW,KAAK,SAAS,OAAO,OAAO;AAAA,IAC3C,KAAK,QAAQ,SAAS,MAAM;AAAA;AAAA,EAO7B,YAAY,CAAC,QAAsB;AAAA,IAClC,KAAK,oBAAoB;AAAA,IACzB,KAAK,KACJ,KACA,eAAe,aACf,sCACA,IACD;AAAA;AAAA,EAQD,QAAQ,CAAC,MAAuB;AAAA,IAC/B,KAAK,cAAc,OAAO,WAAW,IAAI;AAAA,IACzC,MAAM,YACL,KAAK,aACJ,KAAK,WAAW,gBAAgB,KAAK,WAAW;AAAA,IAClD,IAAI,aAAa,KAAK,cAAc,KAAK,SAAS,cAAc;AAAA,MAC/D,OAAO;AAAA,IACR;AAAA,IACA,KAAK,KACJ,KACA,eAAe,UACf,+CACA,IACD;AAAA,IACA,OAAO;AAAA;AAAA,EAGR,QAAQ,GAAS;AAAA,IAChB,IAAI,KAAK,WAAW;AAAA,MAAQ;AAAA,IAC5B,KAAK,KACJ,KACA,eAAe,SACf,oCACA,KACD;AAAA,IACA,KAAK,SAAS,OAAO,SAAS;AAAA;AAAA,EAG/B,iBAAiB,GAAS;AAAA,IACzB,IAAI,KAAK,WAAW;AAAA,MAAW;AAAA,IAC/B,KAAK,YACJ,KACA,KAAK,SAAS,EAAE,gBAAgB,oBAAoB,CAAC,GACrD,cACD;AAAA;AAAA,EAGD,WAAW,CACV,QACA,SACA,OACO;AAAA,IAGP,MAAM,SAAS,IAAI,eAClB;AAAA,MACC,OAAO,CAAC,eAAe;AAAA,QACtB,KAAK,cAAc;AAAA;AAAA,MAEpB,QAAQ,MAAM,KAAK,aAAa;AAAA,IACjC,GACA,IAAI,0BAA0B;AAAA,MAC7B,eAAe,KAAK,SAAS;AAAA,IAC9B,CAAC,CACF;AAAA,IACA,IAAI,cAAc,OAAO,YAAY,OAAO,CAAC,GAAG;AAAA,MAC/C,QAAQ,IAAI,qBAAqB,IAAI;AAAA,MACrC,IAAI,CAAC,QAAQ,IAAI,eAAe;AAAA,QAC/B,QAAQ,IAAI,iBAAiB,UAAU;AAAA,IACzC;AAAA,IACA,IAAI;AAAA,IACJ,IAAI;AAAA,MACH,WAAW,IAAI,SAAS,QAAQ,EAAE,QAAQ,QAAQ,CAAC;AAAA,MAClD,MAAM;AAAA,MACP,KAAK,aAAa,iCAAiC;AAAA,MACnD;AAAA;AAAA,IAED,KAAK,SAAS;AAAA,IACd,KAAK,SAAS,UAAU,MAAM;AAAA,IAC9B,KAAK,mBAAmB;AAAA;AAAA,EAGzB,MAAM,CAAC,MAAoB;AAAA,IAC1B,IAAI,CAAC,KAAK,cAAc,KAAK,gBAAgB,aAAa,SAAS;AAAA,MAClE;AAAA,IACD,IAAI;AAAA,MACH,KAAK,YAAY,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,MAC5C,MAAM;AAAA,MACP,KAAK,aAAa;AAAA,MAClB;AAAA;AAAA,IAED,KAAK,cAAc,eAAe,IAAI;AAAA,IACtC,MAAM,OAAO,KAAK,YAAY;AAAA,IAC9B,IAAI,SAAS,QAAQ,OAAO,GAAG;AAAA,MAG9B,KAAK,SAAS,OAAO,OAAO;AAAA,MAC5B,KAAK,QAAQ,cAAc;AAAA,MAC3B;AAAA,IACD;AAAA,IACA,KAAK,mBAAmB;AAAA;AAAA,MAIrB,UAAU,GAAY;AAAA,IACzB,OAAO,KAAK,WAAW,aAAa,KAAK,WAAW;AAAA;AAAA,EAIrD,kBAAkB,GAAS;AAAA,IAC1B,aAAa,KAAK,eAAe;AAAA,IACjC,IAAI,CAAC,KAAK;AAAA,MAAY;AAAA,IACtB,IAAI,KAAK,WAAW,iBAAiB;AAAA,MACpC,KAAK,kBAAkB,WAAW,MAAM;AAAA,QAGvC,KAAK,OAAO;AAAA;AAAA,CAAkB;AAAA,SAC5B,KAAK,SAAS,WAAW;AAAA,MAC5B;AAAA,IACD;AAAA,IACA,KAAK,kBAAkB,WAAW,MAAM;AAAA,MACvC,IAAI,KAAK;AAAA,QAAa,KAAK,OAAO;AAAA;AAAA,CAAkB;AAAA,MAC/C;AAAA,aAAK,mBAAmB;AAAA,OAC3B,KAAK,SAAS,WAAW;AAAA;AAAA,EAG7B,QAAQ,CAAC,SAA0C;AAAA,IAClD,MAAM,UAAU,IAAI,QAAQ,KAAK,SAAS,YAAY;AAAA,IACtD,YAAY,GAAG,MAAM,OAAO,QAAQ,OAAO,GAAG;AAAA,MAC7C,IAAI,wBAAwB,IAAI,CAAC;AAAA,QAAG,QAAQ,IAAI,GAAG,CAAC;AAAA,IACrD;AAAA,IACA,OAAO;AAAA;AAAA,EAGR,cAAc,CACb,QACA,MACA,SACA,OACW;AAAA,IACX,MAAM,UAAU,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,CAAC;AAAA,IACpE,YAAY,GAAG,MAAM,OAAO,QAAQ,KAAK;AAAA,MAAG,QAAQ,IAAI,GAAG,CAAC;AAAA,IAC5D,OAAO,IAAI,SAAS,aAAa,KAAK,SAAS,OAAO,MAAM,OAAO,GAAG;AAAA,MACrE;AAAA,MACA;AAAA,IACD,CAAC;AAAA;AAAA,EAGF,QAAQ,CAAC,UAAoB,QAAsB;AAAA,IAClD,aAAa,KAAK,WAAW;AAAA,IAC7B,KAAK,SAAS;AAAA,IACd,KAAK,SAAS,QAAQ;AAAA;AAAA,EAGvB,OAAO,CAAC,SAAiB,cAAc,MAAY;AAAA,IAClD,IAAI,KAAK,WAAW;AAAA,MAAQ;AAAA,IAC5B,MAAM,eAAe,KAAK;AAAA,IAC1B,KAAK,SAAS;AAAA,IACd,KAAK,UAAU;AAAA,IACf,aAAa,KAAK,WAAW;AAAA,IAC7B,aAAa,KAAK,aAAa;AAAA,IAC/B,aAAa,KAAK,eAAe;AAAA,IACjC,IAAI,gBAAgB,aAAa;AAAA,MAChC,IAAI;AAAA,QACH,KAAK,aAAa,MAAM;AAAA,QACvB,MAAM;AAAA,IAGT;AAAA,IACA,KAAK,SAAS,OAAO,IAAI;AAAA;AAE3B;;;ACrgBO,IAAM,cACZ;AAGM,IAAM,cAAuC,IAAI,WACvD,OAAO,KACN,wpnBACA,QACD,CACD;AAGO,IAAM,mBAA4C,IAAI,WAC5D,OAAO,KACN,wnmBACA,QACD,CACD;;;ACYA,IAAM,YAAY,IAAI,IAAI,CAAC,YAAY,CAAC;AAEjC,SAAS,WAAW,CAAC,QAA0B;AAAA,EACrD,OAAO,OAAO,WAAW,YAAY,UAAU,IAAI,MAAM;AAAA;AAG1D,SAAS,QAAQ,CAAC,SAAqC;AAAA,EACtD,OAAO,WAAW;AAAA;AAIZ,SAAS,WAAW,CAAC,SAAqC;AAAA,EAChE,OAAO,+DAA+D,SAAS,OAAO;AAAA;AAIhF,SAAS,aAAa,CAAC,SAAqC;AAAA,EAClE,OAAO,+EAA+E,SAAS,OAAO;AAAA;AAIhG,SAAS,cAAc,GAAW;AAAA,EACxC,OAAO;AAAA;AAGR,SAAS,SAAS,CAAC,OAAqB,SAAqC;AAAA,EAC5E,IAAI,UAAU,gBAAgB,UAAU,mBAAmB;AAAA,IAC1D,OAAO,eAAe;AAAA,EACvB;AAAA,EACA,OAAO,UAAU,eAAe,cAAc,OAAO,IAAI,YAAY,OAAO;AAAA;AAItE,SAAS,kBAAkB,CAAC,SAAqC;AAAA,EACvE,OAAO,wGAAwG,SAAS,OAAO;AAAA;AAIzH,SAAS,uBAAuB,GAAW;AAAA,EACjD,OAAO;AAAA;AAQD,SAAS,aAAa,CAC5B,MACA,OACA,SACA,OACA,OACqB;AAAA,EACrB,IAAI,UAAU;AAAA,IAAW;AAAA,EACzB,MAAM,KAAK;AAAA,EACX,MAAM,SAAS,KAAK;AAAA,EACpB,IAAI,WAAW,cAAc;AAAA,IAC5B,MAAM,OACL,UAAU,SACP,mBAAmB,OAAO,IAC1B,UAAU,oBACT,wBAAwB,IACxB,UAAU,OAAO,OAAO;AAAA,IAC7B,OAAO,KAAK,UAAU;AAAA,MACrB,SAAS;AAAA,MACT;AAAA,MACA,QAAQ;AAAA,QACP,YAAY;AAAA,QACZ,SAAS,CAAC,EAAE,MAAM,QAAQ,KAAK,CAAC;AAAA,QAChC,SAAS;AAAA,MACV;AAAA,IACD,CAAC;AAAA,EACF;AAAA,EACA,IAAI,WAAW,mBAAmB;AAAA,IAIjC,OAAO,KAAK,UAAU;AAAA,MACrB,SAAS;AAAA,MACT;AAAA,MACA,QAAQ;AAAA,QACP,YAAY;AAAA,QACZ,mBAAmB,CAAC,oBAAoB;AAAA,QACxC,cAAc,EAAE,OAAO,EAAE,aAAa,KAAK,EAAE;AAAA,QAC7C,cAAc,UAAU,OAAO,OAAO;AAAA,QACtC,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,OAAO;AAAA,UACN,sCAAsC;AAAA,YACrC,MAAM,MAAM;AAAA,YACZ,SAAS,MAAM;AAAA,UAChB;AAAA,QACD;AAAA,MACD;AAAA,IACD,CAAC;AAAA,EACF;AAAA,EACA,OAAO,KAAK,UAAU;AAAA,IACrB,SAAS;AAAA,IACT;AAAA,IACA,OAAO;AAAA,MACN,MACC,UAAU,SACP,eAAe,UACf,UAAU,gBAAgB,UAAU,oBACnC,eAAe,aACf,eAAe;AAAA,MACpB,SAAS,UAAU,OAAO,OAAO;AAAA,IAClC;AAAA,EACD,CAAC;AAAA;;;AChIF,4BAAS;;;ACOF,MAAM,YAAY;AAAA,EACf,WAAW,IAAI;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EAET,WAAW,CAAC,SAA2B;AAAA,IACtC,KAAK,YAAY,QAAQ;AAAA,IACzB,KAAK,UAAU,QAAQ;AAAA,IACvB,KAAK,WAAW,QAAQ,WAAW;AAAA;AAAA,EAIpC,IAAI,CAAC,KAAa,MAAc,KAAK,IAAI,GAAY;AAAA,IACpD,IAAI,SAAS,KAAK,SAAS,IAAI,GAAG;AAAA,IAClC,IAAI,WAAW,WAAW;AAAA,MACzB,IAAI,KAAK,SAAS,QAAQ,KAAK,UAAU;AAAA,QACxC,MAAM,SAAS,KAAK,SAAS,KAAK,EAAE,KAAK,EAAE;AAAA,QAC3C,IAAI,WAAW;AAAA,UAAW,KAAK,SAAS,OAAO,MAAM;AAAA,MACtD;AAAA,MACA,SAAS,EAAE,QAAQ,KAAK,WAAW,WAAW,IAAI;AAAA,MAClD,KAAK,SAAS,IAAI,KAAK,MAAM;AAAA,IAC9B,EAAO;AAAA,MACN,MAAM,UAAU,KAAK,IAAI,GAAG,MAAM,OAAO,SAAS,IAAI;AAAA,MACtD,OAAO,SAAS,KAAK,IACpB,KAAK,WACL,OAAO,SAAS,UAAU,KAAK,OAChC;AAAA,MACA,OAAO,YAAY;AAAA;AAAA,IAEpB,IAAI,OAAO,SAAS;AAAA,MAAG,OAAO;AAAA,IAC9B,OAAO,UAAU;AAAA,IACjB,OAAO;AAAA;AAAA,EAIR,SAAS,CAAC,KAAa,MAAc,KAAK,IAAI,GAAY;AAAA,IACzD,MAAM,SAAS,KAAK,SAAS,IAAI,GAAG;AAAA,IACpC,IAAI,WAAW;AAAA,MAAW,OAAO,KAAK,aAAa;AAAA,IACnD,MAAM,UAAU,KAAK,IAAI,GAAG,MAAM,OAAO,SAAS,IAAI;AAAA,IACtD,OACC,KAAK,IAAI,KAAK,WAAW,OAAO,SAAS,UAAU,KAAK,OAAO,KAAK;AAAA;AAAA,EAKtE,KAAK,CAAC,MAAc,KAAK,IAAI,GAAS;AAAA,IACrC,YAAY,KAAK,MAAM,KAAK,UAAU;AAAA,MACrC,MAAM,UAAU,KAAK,IAAI,GAAG,MAAM,EAAE,SAAS,IAAI;AAAA,MACjD,IAAI,EAAE,SAAS,UAAU,KAAK,WAAW,KAAK,WAAW;AAAA,QACxD,KAAK,SAAS,OAAO,GAAG;AAAA,MACzB;AAAA,IACD;AAAA;AAEF;;;ACvEA,IAAM,SAAoC;AAAA,EACzC,QAAQ;AAAA,EACR,SAAS;AACV;AAEA,SAAS,MAAM,CAAC,OAAuB;AAAA,EACtC,OAAO,OACL,gBAAgB,IAAI,WAAW,KAAK,CAAC,EACrC,SAAS,EAAE,UAAU,aAAa,aAAa,KAAK,CAAC;AAAA;AAIjD,SAAS,QAAQ,CAAC,MAAyB;AAAA,EACjD,OAAO,OAAO,QAAQ,OAAO,EAAE;AAAA;AAIzB,SAAS,KAAK,CAAC,QAAwB;AAAA,EAC7C,OAAO,GAAG,UAAU,OAAO,EAAE;AAAA;AAIvB,SAAS,SAAS,CAAC,OAAuB;AAAA,EAChD,OAAO,IAAI,IAAI,aAAa,QAAQ,EAClC,OAAO,KAAK,EACZ,OAAO,EACP,SAAS,EAAE,UAAU,aAAa,aAAa,KAAK,CAAC;AAAA;AAiDxD,eAAsB,cAAc,CACnC,OACA,OAIA,SAQC;AAAA,EACD,MAAM,MAAM,QAAQ,OAAO,KAAK,IAAI;AAAA,EACpC,MAAM,cAAc,SAAS,QAAQ;AAAA,EACrC,MAAM,eAAe,SAAS,SAAS;AAAA,EACvC,MAAM,OAAO;AAAA,IACZ,SAAS,MAAM;AAAA,IACf,WAAW,MAAM;AAAA,IACjB,UAAU,MAAM;AAAA,IAChB,YAAY,MAAM;AAAA,IAClB,QAAQ,MAAM;AAAA,IACd,gBAAgB,MAAM;AAAA,IACtB,UAAU;AAAA,OACN,MAAM,YAAY,YAAY,CAAC,IAAI,EAAE,SAAS,MAAM,QAAQ;AAAA,EACjE;AAAA,EACA,MAAM,gBAAgB,KAAK,IAC1B,MAAM,QAAQ,aACd,QAAQ,WACT;AAAA,EAIA,MAAM,gBAAgB,MAAM,MAAM,IAAI;AAAA,OAClC;AAAA,IACH,MAAM,UAAU,YAAY;AAAA,IAC5B,MAAM;AAAA,IACN,WAAW,KAAK,IAAI,MAAM,QAAQ,cAAc,QAAQ,WAAW;AAAA,EACpE,CAAC;AAAA,EACD,IAAI,CAAC;AAAA,IAAe;AAAA,EACpB,MAAM,eAAe,MAAM,MAAM,IAAI;AAAA,OACjC;AAAA,IACH,MAAM,UAAU,WAAW;AAAA,IAC3B,MAAM;AAAA,IACN,WAAW;AAAA,EACZ,CAAC;AAAA,EACD,IAAI,CAAC;AAAA,IAAc;AAAA,EACnB,OAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA,WAAW,KAAK,IAAI,GAAG,KAAK,OAAO,gBAAgB,OAAO,IAAI,CAAC;AAAA,EAChE;AAAA;;;ACvGM,MAAM,4BAA4B,MAAM;AAAA,EACrC,OAAO;AAAA,EACP;AAAA,EACT,WAAW,CAAC,QAAgB,SAAiB;AAAA,IAC5C,MAAM,OAAO;AAAA,IACb,KAAK,SAAS;AAAA;AAEhB;AAuBA,IAAM,uBAAuB;AAC7B,IAAM,kBAAkB;AACxB,IAAM,oBAAoB;AAC1B,IAAM,eAAe,IAAI;AACzB,IAAM,mBAAmB,KAAK;AAC9B,IAAM,eAAe,KAAK,KAAK;AAC/B,IAAM,oBAAoB;AAE1B,eAAe,aAAa,CAAC,UAAqC;AAAA,EACjE,MAAM,UAAU,MAAM,IAAI,IAAI,OAAO,UAAU,CAAC,CAAC;AAAA,EACjD,OAAO,QAAQ,IAAI,CAAC,MAAM,EAAE,OAAO;AAAA;AAQpC,IAAM,YACL;AAQM,SAAS,WAAW,CAAC,KAAqB;AAAA,EAChD,IAAI,UAAU,IACZ,UAAU,KAAK,EACf,QAAQ,0BAA0B,GAAG,EACrC,QAAQ,YAAY,EAAE,EACtB,QAAQ,WAAW,EAAE;AAAA,EACvB,UAAU,QAAQ,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAAA,EAC5C,MAAM,QAAQ,CAAC,GAAG,OAAO;AAAA,EACzB,OAAO,MAAM,SAAS,kBACnB,GAAG,MAAM,MAAM,GAAG,kBAAkB,CAAC,EAAE,KAAK,EAAE,YAC9C;AAAA;AAIJ,SAAS,OAAO,CAAC,QAA+B;AAAA,EAC/C,IAAI,WAAW;AAAA,IAAM,OAAO;AAAA,EAC5B,MAAM,aAAa,OACjB,YAAY,EACZ,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AAAA,EACrB,IAAI,WAAW,SAAS,UAAU,KAAK,WAAW,SAAS,UAAU,GAAG;AAAA,IACvE,OAAO;AAAA,EACR;AAAA,EACA,MAAM,SAAS,WACb,IAAI,CAAC,MAAM,kBAAkB,KAAK,CAAC,IAAI,EAAE,EACzC,KAAK,CAAC,MAAM,MAAM,SAAS;AAAA,EAC7B,IAAI,WAAW;AAAA,IAAW,OAAO;AAAA,EACjC,OAAO,KAAK,IAAI,cAAc,KAAK,IAAI,cAAc,OAAO,MAAM,IAAI,IAAI,CAAC;AAAA;AAG5E,SAAS,WAAW,CAAC,UAA2B;AAAA,EAC/C,MAAM,IAAI,SAAS,QAAQ,YAAY,EAAE;AAAA,EACzC,OAAO,UAAU,CAAC,MAAM,aAAa,UAAU,CAAC,MAAM;AAAA;AAUhD,SAAS,QAAQ,CAAC,UAA0B;AAAA,EAClD,MAAM,IAAI,SAAS,QAAQ,YAAY,EAAE,EAAE,QAAQ,OAAO,EAAE;AAAA,EAC5D,IAAI,YAAY,CAAC;AAAA,IAAG,OAAO;AAAA,EAC3B,OAAO,EAAE,MAAM,GAAG,EAAE,MAAM,EAAE,EAAE,KAAK,GAAG;AAAA;AAAA;AAIhC,MAAM,sBAAsB;AAAA,EACzB,SAAS,IAAI;AAAA,EACb,WAAW,IAAI,YAAY,EAAE,UAAU,GAAG,iBAAiB,IAAI,CAAC;AAAA,EAEhE,aAAa,IAAI,YAAY,EAAE,UAAU,IAAI,iBAAiB,IAAI,CAAC;AAAA,EAEnE,UAAU,IAAI,YAAY,EAAE,UAAU,IAAI,iBAAiB,EAAE,CAAC;AAAA,EAC9D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,WAAW,CAAC,UAAwC,CAAC,GAAG;AAAA,IACvD,KAAK,gBAAgB,QAAQ,gBAAgB,CAAC;AAAA,IAC9C,KAAK,UAAU,QAAQ;AAAA,IACvB,KAAK,aAAa,QAAQ,aAAa;AAAA,IACvC,KAAK,YAAY,QAAQ,YAAY;AAAA,IACrC,KAAK,UAAU,QAAQ,UAAU;AAAA,IACjC,KAAK,SAAS,QAAQ,SAAS;AAAA,IAC/B,KAAK,YAAY,QAAQ;AAAA,IACzB,KAAK,OAAO,QAAQ,OAAO,KAAK;AAAA;AAAA,OAI3B,IAAG,CAAC,UAA2C;AAAA,IACpD,MAAM,MAAM,KAAK,UAAU,QAAQ;AAAA,IACnC,MAAM,MAAM,KAAK,KAAK;AAAA,IACtB,MAAM,SAAS,KAAK,OAAO,IAAI,QAAQ;AAAA,IACvC,IAAI,WAAW,aAAa,OAAO,QAAQ,KAAK;AAAA,MAE/C,KAAK,OAAO,OAAO,QAAQ;AAAA,MAC3B,KAAK,OAAO,IAAI,UAAU,MAAM;AAAA,MAChC,OAAO,OAAO;AAAA,IACf;AAAA,IAGA,MAAM,MAAM,SAAS,IAAI,QAAQ;AAAA,IACjC,IACC,CAAC,KAAK,SAAS,UAAU,IAAI,MAAM,GAAG,KACtC,CAAC,KAAK,WAAW,UAAU,KAAK,GAAG,GAClC;AAAA,MACD,MAAM,IAAI,oBACT,gBACA,qEACD;AAAA,IACD;AAAA,IACA,IAAI,CAAC,KAAK,QAAQ,KAAK,OAAO,GAAG,GAAG;AAAA,MACnC,MAAM,IAAI,oBACT,gBACA,2CACD;AAAA,IACD;AAAA,IACA,KAAK,SAAS,KAAK,IAAI,MAAM,GAAG;AAAA,IAChC,KAAK,WAAW,KAAK,KAAK,GAAG;AAAA,IAC7B,MAAM,UAAU,MAAM,KAAK,eAAe,GAAG;AAAA,IAC7C,QAAQ,MAAM,UAAU,MAAM,KAAK,eAAe,KAAK,UAAU,OAAO;AAAA,IACxE,KAAK,OAAO,OAAO,QAAQ;AAAA,IAC3B,IAAI,KAAK,OAAO,QAAQ,mBAAmB;AAAA,MAC1C,MAAM,SAAS,KAAK,OAAO,KAAK,EAAE,KAAK,EAAE;AAAA,MACzC,IAAI,WAAW;AAAA,QAAW,KAAK,OAAO,OAAO,MAAM;AAAA,IACpD;AAAA,IACA,KAAK,OAAO,IAAI,UAAU,EAAE,MAAM,OAAO,MAAM,MAAM,CAAC;AAAA,IACtD,OAAO;AAAA;AAAA,EAIR,SAAS,CAAC,UAAuB;AAAA,IAChC,MAAM,SAAS,CAAC,YACf,IAAI,oBAAoB,qBAAqB,OAAO;AAAA,IACrD,IAAI,SAAS,WAAW,KAAK,SAAS,SAAS,sBAAsB;AAAA,MACpE,MAAM,OAAO,gDAAgD;AAAA,IAC9D;AAAA,IACA,IAAI;AAAA,IACJ,IAAI;AAAA,MACH,MAAM,IAAI,IAAI,QAAQ;AAAA,MACrB,MAAM;AAAA,MACP,MAAM,OAAO,sCAAsC;AAAA;AAAA,IAEpD,MAAM,OAAO,KAAK,cAAc;AAAA,IAChC,MAAM,SACL,IAAI,aAAa,YAAa,QAAQ,IAAI,aAAa;AAAA,IACxD,IAAI,CAAC,QAAQ;AAAA,MACZ,MAAM,OAAO,iDAAiD;AAAA,IAC/D;AAAA,IAGA,IAAI,IAAI,SAAS,UAAU;AAAA,MAC1B,MAAM,OAAO,gDAAgD;AAAA,IAC9D;AAAA,IACA,IAAI,IAAI,aAAa,MAAM,IAAI,aAAa,MAAM,IAAI,SAAS,IAAI;AAAA,MAClE,MAAM,OACL,oEACD;AAAA,IACD;AAAA,IACA,IAAI,IAAI,aAAa,OAAO,IAAI,aAAa,IAAI;AAAA,MAChD,MAAM,OAAO,0CAA0C;AAAA,IACxD;AAAA,IACA,IAAI,IAAI,SAAS,MAAM,CAAC,MAAM;AAAA,MAC7B,MAAM,OAAO,mDAAmD;AAAA,IACjE;AAAA,IACA,IACC,KAAK,cAAc,SAAS,KAC5B,CAAC,KAAK,cAAc,SAAS,IAAI,IAAI,GACpC;AAAA,MACD,MAAM,IAAI,oBACT,oBACA,2CAA2C,IAAI,OAChD;AAAA,IACD;AAAA,IACA,IAAI,YAAY,IAAI,QAAQ,KAAK,CAAC,KAAK,gBAAgB,IAAI,QAAQ,GAAG;AAAA,MACrE,MAAM,KAAK,WAAW,mBAAmB,GAAG;AAAA,IAC7C;AAAA,IACA,OAAO;AAAA;AAAA,EAGR,eAAe,CAAC,SAA0B;AAAA,IACzC,IAAI,WAAW,OAAO;AAAA,MAAG,OAAO;AAAA,IAChC,OAAO,KAAK,cAAc,aAAa,eAAe,OAAO;AAAA;AAAA,EAQ9D,UAAU,CAAC,QAAgB,KAAU,SAAS,QAA6B;AAAA,IAC1E,KAAK,SAAS,KAAK,qBAAqB,EAAE,MAAM,IAAI,MAAM,QAAQ,OAAO,CAAC;AAAA,IAC1E,OAAO,IAAI,oBACV,QACA,iDAAiD,IAAI,OACtD;AAAA;AAAA,OAQK,cAAc,CAAC,KAA2B;AAAA,IAC/C,MAAM,WAAW,IAAI,SAAS,QAAQ,YAAY,EAAE;AAAA,IACpD,IAAI,YAAY,QAAQ;AAAA,MAAG,OAAO;AAAA,IAClC,IAAI;AAAA,IACJ,IAAI;AAAA,MACH,YAAY,MAAM,KAAK,QAAQ,QAAQ;AAAA,MACtC,MAAM;AAAA,MACP,MAAM,KAAK,WAAW,gBAAgB,GAAG;AAAA;AAAA,IAE1C,IACC,UAAU,WAAW,KACrB,CAAC,UAAU,MAAM,CAAC,MAAM,KAAK,gBAAgB,CAAC,CAAC,GAC9C;AAAA,MACD,MAAM,KAAK,WAAW,mBAAmB,GAAG;AAAA,IAC7C;AAAA,IACA,OACC,UAAU,KAAK,CAAC,MAAM,UAAU,CAAC,MAAM,SAAS,KAAK,UAAU,MAAM;AAAA;AAAA,OAIjE,cAAc,CACnB,KACA,UACA,SACmD;AAAA,IACnD,MAAM,OAAO,CAAC,WACb,KAAK,WAAW,gBAAgB,KAAK,MAAM;AAAA,IAG5C,MAAM,SAAS,IAAI,IAAI,QAAQ;AAAA,IAC/B,OAAO,WAAW,QAAQ,SAAS,GAAG,IAAI,IAAI,aAAa;AAAA,IAC3D,MAAM,WAAW,IAAI,SAAS,QAAQ,YAAY,EAAE;AAAA,IACpD,MAAM,MACL,IAAI,aAAa,WACd;AAAA,MACA,KAAK;AAAA,WACA,YAAY,QAAQ,IAAI,CAAC,IAAI,EAAE,YAAY,SAAS;AAAA,WACpD,KAAK,WAAW,OAAO,YACxB,CAAC,IACD,EAAE,IAAI,KAAK,UAAU,GAAG;AAAA,MAC5B;AAAA,IACD,IACC,CAAC;AAAA,IACL,IAAI;AAAA,IACJ,IAAI;AAAA,MACH,WAAW,MAAM,KAAK,OAAO,OAAO,MAAM;AAAA,QACzC,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,SAAS,EAAE,QAAQ,oBAAoB,MAAM,IAAI,KAAK;AAAA,QACtD,QAAQ,YAAY,QAAQ,KAAK,UAAU;AAAA,WACxC;AAAA,MACJ,CAAgB;AAAA,MACf,OAAO,OAAO;AAAA,MACf,MAAM,KACL,gBAAgB,iBAAiB,QAAQ,MAAM,OAAO,WACvD;AAAA;AAAA,IAED,IAAI;AAAA,MACH,IAAI,SAAS,WAAW;AAAA,QAAK,MAAM,KAAK,UAAU,SAAS,QAAQ;AAAA,MACnE,MAAM,QAAQ,SAAS,QAAQ,IAAI,cAAc,KAAK,IACpD,MAAM,GAAG,EAAE,IACV,KAAK,EACN,YAAY;AAAA,MACd,IAAI,SAAS;AAAA,QAAoB,MAAM,KAAK,UAAU;AAAA,MACtD,MAAM,OAAO,MAAM,KAAK,aAAa,UAAU,GAAG;AAAA,MAClD,IAAI;AAAA,MACJ,IAAI;AAAA,QACH,MAAM,KAAK,MAAM,IAAI;AAAA,QACpB,MAAM;AAAA,QACP,MAAM,KAAK,UAAU;AAAA;AAAA,MAEtB,MAAM,OAAO,iBAAiB,KAAK,UAAU,GAAG;AAAA,MAChD,OAAO,EAAE,MAAM,OAAO,QAAQ,SAAS,QAAQ,IAAI,eAAe,CAAC,EAAE;AAAA,cACpE;AAAA,MACD,IAAI,CAAC,SAAS;AAAA,QAAU,SAAS,MAAM,OAAO,EAAE,MAAM,MAAM,EAAE;AAAA;AAAA;AAAA,OAI1D,YAAY,CAAC,UAAoB,KAA2B;AAAA,IACjE,MAAM,WAAW,MAAM,KAAK,WAAW,aAAa,GAAG;AAAA,IACvD,MAAM,SAAS,OAAO,SAAS,QAAQ,IAAI,gBAAgB,KAAK,GAAG;AAAA,IACnE,IAAI,SAAS,KAAK;AAAA,MAAW,MAAM,SAAS;AAAA,IAC5C,MAAM,SAAS,SAAS,MAAM,UAAU;AAAA,IACxC,IAAI,WAAW;AAAA,MAAW,OAAO;AAAA,IACjC,MAAM,SAAuB,CAAC;AAAA,IAC9B,IAAI,QAAQ;AAAA,IACZ,UAAS;AAAA,MACR,QAAQ,MAAM,UAAU,MAAM,OAAO,KAAK;AAAA,MAC1C,IAAI;AAAA,QAAM;AAAA,MACV,SAAS,MAAM;AAAA,MACf,IAAI,QAAQ,KAAK,WAAW;AAAA,QAC3B,MAAM,OAAO,OAAO,EAAE,MAAM,MAAM,EAAE;AAAA,QACpC,MAAM,SAAS;AAAA,MAChB;AAAA,MACA,OAAO,KAAK,KAAK;AAAA,IAClB;AAAA,IACA,IAAI;AAAA,MACH,OAAO,IAAI,YAAY,SAAS,EAAE,OAAO,KAAK,CAAC,EAAE,OAChD,OAAO,OAAO,MAAM,CACrB;AAAA,MACC,MAAM;AAAA,MACP,MAAM,KAAK,WAAW,gBAAgB,KAAK,UAAU;AAAA;AAAA;AAGxD;AAGA,IAAM,gBACL;AAOD,SAAS,UAAU,CAAC,MAAsB;AAAA,EACzC,OAAO,KACL,UAAU,MAAM,EAChB,QAAQ,WAAW,EAAE,EACrB,QAAQ,yBAAU,GAAG,EACrB,YAAY;AAAA;AAIf,SAAS,SAAS,CAAC,OAAuB;AAAA,EACzC,IAAI;AAAA,IACH,OAAO,IAAI,IAAI,WAAW,QAAQ,EAAE;AAAA,IACnC,MAAM;AAAA,IACP,OAAO;AAAA;AAAA;AASF,SAAS,aAAa,CAAC,MAAc,UAA2B;AAAA,EACtE,MAAM,OAAO,SAAS,YAAY;AAAA,EAClC,YAAY,UAAU,WAAW,IAAI,EAAE,SAAS,aAAa,GAAG;AAAA,IAC/D,MAAM,QAAQ,UAAU,KAAK;AAAA,IAC7B,MAAM,MACL,UAAU,QACV,KAAK,SAAS,IAAI,OAAO,KACzB,MAAM,SAAS,IAAI,MAAM;AAAA,IAC1B,IAAI,CAAC;AAAA,MAAK,OAAO;AAAA,EAClB;AAAA,EACA,OAAO;AAAA;AAID,SAAS,gBAAgB,CAC/B,KACA,UACA,KACiB;AAAA,EACjB,MAAM,UAAU,CAAC,YAChB,IAAI,oBAAoB,oBAAoB,OAAO;AAAA,EACpD,IAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,MAAM,QAAQ,GAAG,GAAG;AAAA,IAClE,MAAM,QAAQ,6CAA6C;AAAA,EAC5D;AAAA,EACA,MAAM,IAAI;AAAA,EACV,IAAI,EAAE,iBAAiB,UAAU;AAAA,IAChC,MAAM,QAAQ,kDAAkD;AAAA,EACjE;AAAA,EACA,IACC,EAAE,qBAAqB,aACvB,EAAE,gCAAgC,WACjC;AAAA,IACD,MAAM,QAAQ,wDAAwD;AAAA,EACvE;AAAA,EACA,MAAM,OAAO,EAAE;AAAA,EACf,IAAI,OAAO,SAAS,YAAY,YAAY,IAAI,MAAM,IAAI;AAAA,IACzD,MAAM,QAAQ,2CAA2C;AAAA,EAC1D;AAAA,EAEA,IACC,6CAA6C,KAC5C,WAAW,YAAY,IAAI,CAAC,CAC7B,GACC;AAAA,IACD,MAAM,QACL,0FACD;AAAA,EACD;AAAA,EAEA,IAAI,cAAc,YAAY,IAAI,GAAG,IAAI,QAAQ,GAAG;AAAA,IACnD,MAAM,QACL,8FACD;AAAA,EACD;AAAA,EACA,MAAM,OAAO,EAAE;AAAA,EACf,IACC,CAAC,MAAM,QAAQ,IAAI,KACnB,KAAK,WAAW,KAChB,KAAK,SAAS,qBACd,CAAC,KAAK,MAAM,CAAC,MAAM,OAAO,MAAM,YAAY,cAAc,CAAC,CAAC,GAC3D;AAAA,IACD,MAAM,QAAQ,mDAAmD;AAAA,EAClE;AAAA,EAKA,MAAM,SAAS,EAAE;AAAA,EACjB,MAAM,YAAY,EAAE;AAAA,EACpB,IACC,WAAW,aACX,WAAW,UACX,EAAE,MAAM,QAAQ,SAAS,KAAK,UAAU,SAAS,MAAM,IACtD;AAAA,IACD,MAAM,QACL,iIACD;AAAA,EACD;AAAA,EACA,MAAM,SAAS,EAAE;AAAA,EACjB,IACC,WAAW,cACV,CAAC,MAAM,QAAQ,MAAM,KAAK,CAAC,OAAO,SAAS,oBAAoB,IAC/D;AAAA,IACD,MAAM,QACL,iEACD;AAAA,EACD;AAAA,EACA,MAAM,YAAY,EAAE;AAAA,EACpB,IACC,cAAc,cACb,CAAC,MAAM,QAAQ,SAAS,KAAK,CAAC,UAAU,SAAS,MAAM,IACvD;AAAA,IACD,MAAM,QAAQ,yDAA0D;AAAA,EACzE;AAAA,EACA,OAAO;AAAA,IACN;AAAA,IACA,MAAM,YAAY,IAAI;AAAA,IACtB,MAAM,IAAI;AAAA,IACV,cAAc;AAAA,EACf;AAAA;AAID,IAAM,qBAAqB;AASpB,SAAS,aAAa,CAAC,OAAwB;AAAA,EACrD,IAAI,MAAM,SAAS,QAAQ,MAAM,SAAS,GAAG;AAAA,IAAG,OAAO;AAAA,EACvD,IAAI;AAAA,EACJ,IAAI;AAAA,IACH,IAAI,IAAI,IAAI,KAAK;AAAA,IAChB,MAAM;AAAA,IACP,OAAO;AAAA;AAAA,EAER,IAAI,EAAE,aAAa,MAAM,EAAE,aAAa;AAAA,IAAI,OAAO;AAAA,EACnD,IAAI,EAAE,aAAa;AAAA,IAAU,OAAO,EAAE,aAAa;AAAA,EACnD,IAAI,EAAE,aAAa;AAAA,IAAS,OAAO,wBAAwB,IAAI,EAAE,QAAQ;AAAA,EACzE,OAAO,mBAAmB,KAAK,EAAE,QAAQ;AAAA;AAG1C,IAAM,0BAA0B,IAAI,IAAI,CAAC,aAAa,aAAa,OAAO,CAAC;AAOpE,SAAS,kBAAkB,CACjC,WACA,YACU;AAAA,EACV,IAAI,cAAc;AAAA,IAAY,OAAO;AAAA,EACrC,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,IACH,IAAI,IAAI,IAAI,SAAS;AAAA,IACrB,IAAI,IAAI,IAAI,UAAU;AAAA,IACrB,MAAM;AAAA,IACP,OAAO;AAAA;AAAA,EAER,IAAI,EAAE,aAAa,WAAW,EAAE,aAAa;AAAA,IAAS,OAAO;AAAA,EAC7D,IAAI,CAAC,wBAAwB,IAAI,EAAE,QAAQ,KAAK,EAAE,aAAa,EAAE,UAAU;AAAA,IAC1E,OAAO;AAAA,EACR;AAAA,EAGA,IACC,EAAE,SAAS,aACX,EAAE,aAAa,MACf,EAAE,aAAa,MACf,EAAE,SAAS,IACV;AAAA,IACD,OAAO;AAAA,EACR;AAAA,EACA,EAAE,OAAO;AAAA,EACT,EAAE,OAAO;AAAA,EACT,OAAO,EAAE,SAAS,EAAE;AAAA;;;ACzjBrB,IAAM,UAAkC;AAAA,EACvC,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACN;AAGO,SAAS,UAAU,CAAC,MAAsB;AAAA,EAChD,OAAO,KAAK,QAAQ,YAAY,CAAC,MAAM,QAAQ,MAAM,CAAC;AAAA;AAIhD,IAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqBtB,SAAS,WAAW,CAAC,cAAiC,CAAC,GAAY;AAAA,EAGzE,MAAM,aAAa,CAAC,UAAU,GAAG,WAAW,EAAE,KAAK,GAAG;AAAA,EACtD,OAAO,IAAI,QAAQ;AAAA,IAClB,gBAAgB;AAAA,IAChB,2BAA2B,8GAA8G;AAAA,IACzI,mBAAmB;AAAA,IACnB,0BAA0B;AAAA,IAI1B,mBAAmB;AAAA,IACnB,iBAAiB;AAAA,EAClB,CAAC;AAAA;AAIK,SAAS,UAAU,CAAC,OAAe,MAAsB;AAAA,EAC/D,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAMC,WAAW,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQvB;AAAA;AAAA;AAAA;AAAA;AAAA;;;AC9CF,IAAM,cAAc,KAAK;AACzB,IAAM,YAAY;AAClB,IAAM,kBAAkB,KAAK;AAC7B,IAAM,2BAA2B;AAAA;AAoB1B,MAAM,kBAAkB,MAAM;AAAA,EAC3B,OAAO;AAAA,EACP;AAAA,EACT,WAAW,CAAC,QAAgB,SAAiB;AAAA,IAC5C,MAAM,OAAO;AAAA,IACb,KAAK,SAAS;AAAA;AAEhB;AAEA,SAAS,OAAM,CAAC,OAAuB;AAAA,EACtC,OAAO,OACL,gBAAgB,IAAI,WAAW,KAAK,CAAC,EACrC,SAAS,EAAE,UAAU,aAAa,aAAa,KAAK,CAAC;AAAA;AAGxD,SAAS,IAAI,CAAC,UAA0B;AAAA,EACvC,OAAO,IAAI,IAAI,aAAa,QAAQ,EAClC,OAAO,QAAQ,EACf,OAAO,EACP,SAAS,EAAE,UAAU,aAAa,aAAa,KAAK,CAAC;AAAA;AAGxD,SAAS,GAAG,CAAC,GAAgC;AAAA,EAC5C,OAAO,OAAO,MAAM,YAAY,MAAM,KAAK,IAAI;AAAA;AAGhD,SAAS,QAAQ,CAAC,KAAiC;AAAA,EAClD,IAAI;AAAA,IACH,OAAO,IAAI,IAAI,GAAG,EAAE;AAAA,IACnB,MAAM;AAAA,IACP;AAAA;AAAA;AAAA;AAKK,MAAM,kBAAkB;AAAA,EACrB;AAAA,EACA;AAAA,EACT;AAAA,EACA,aAAa;AAAA,EACb;AAAA,EAEA,WAAW,CAAC,QAAgB,aAAsB;AAAA,IACjD,KAAK,UAAU;AAAA,IACf,KAAK,eAAe;AAAA;AAAA,MAIjB,MAAM,GAAiC;AAAA,IAC1C,OAAO,KAAK;AAAA;AAAA,OAGP,IAAG,GAA8B;AAAA,IACtC,IACC,KAAK,cAAc,aACnB,KAAK,IAAI,IAAI,KAAK,aAAa,iBAC9B;AAAA,MACD,OAAO,KAAK;AAAA,IACb;AAAA,IACA,KAAK,cAAc,KAAK,MAAM,EAAE,QAAQ,MAAM;AAAA,MAC7C,KAAK,YAAY;AAAA,KACjB;AAAA,IACD,OAAO,KAAK;AAAA;AAAA,OAGP,KAAK,GAA8B;AAAA,IACxC,MAAM,MAAM,GAAG,KAAK,QAAQ,QAAQ,QAAQ,EAAE;AAAA,IAC9C,MAAM,MAAO,MAAM,UAAU,GAAG;AAAA,IAChC,IAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AAAA,MAC5C,MAAM,IAAI,UACT,aACA,0CACD;AAAA,IACD;AAAA,IAEA,IAAI,IAAI,cAAc,KAAK,SAAS;AAAA,MACnC,MAAM,IAAI,UACT,oBACA,8CACD;AAAA,IACD;AAAA,IACA,MAAM,WAAW,CAAC,SAAyB;AAAA,MAC1C,MAAM,IAAI,IAAI,IAAI,KAAK;AAAA,MACvB,MAAM,KACL,MAAM,cACL,EAAE,WAAW,UAAU,KACtB,KAAK,gBAAgB,EAAE,WAAW,SAAS;AAAA,MAC9C,IAAI,CAAC,IAAI;AAAA,QACR,MAAM,IAAI,UACT,aACA,iCAAiC,MAClC;AAAA,MACD;AAAA,MACA,OAAO;AAAA;AAAA,IAER,MAAM,UAAU,IAAI;AAAA,IACpB,MAAM,YACL,MAAM,QAAQ,OAAO,KACrB,CAAC,QAAQ,SAAS,qBAAqB,KACvC,QAAQ,SAAS,oBAAoB,IAClC,uBACA;AAAA,IACJ,MAAM,WAA6B;AAAA,MAClC,QAAQ,KAAK;AAAA,MACb,uBAAuB,SAAS,wBAAwB;AAAA,MACxD,eAAe,SAAS,gBAAgB;AAAA,MACxC,SAAS,SAAS,UAAU;AAAA,MAC5B;AAAA,IACD;AAAA,IACA,KAAK,YAAY;AAAA,IACjB,KAAK,aAAa,KAAK,IAAI;AAAA,IAC3B,OAAO;AAAA;AAET;AAAA;AAaO,MAAM,YAAqC;AAAA,EACxC,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,SAAS,IAAI;AAAA,EAMb,UAAU,IAAI;AAAA,EAEd,cAAc,IAAI;AAAA,EAE3B,WAAW,CAAC,SAA6B;AAAA,IACxC,KAAK,UAAU,QAAQ;AAAA,IACvB,KAAK,YAAY,QAAQ,YAAY;AAAA,IACrC,KAAK,aAAa,QAAQ;AAAA,IAC1B,KAAK,UAAU,QAAQ;AAAA,IACvB,KAAK,aAAa,IAAI,kBACrB,QAAQ,OAAO,QACf,QAAQ,WACT;AAAA,IACA,KAAK,QAAQ,IAAI,UAChB,aAAa,MAAM,KAAK,WAAW,IAAI,GAAG,OAC3C;AAAA;AAAA,MAGG,aAAa,GAAW;AAAA,IAC3B,IAAI;AAAA,MACH,OAAO,IAAI,IAAI,KAAK,QAAQ,MAAM,EAAE;AAAA,MACnC,MAAM;AAAA,MACP,OAAO,KAAK,QAAQ;AAAA;AAAA;AAAA,MAIlB,WAAW,GAAW;AAAA,IACzB,OAAO,GAAG,KAAK,WAAW;AAAA;AAAA,OAIrB,QAAO,GAAkB;AAAA,IAC9B,MAAM,KAAK,WAAW,IAAI;AAAA;AAAA,EAI3B,WAAW,GAAa;AAAA,IACvB,MAAM,MAAM,IAAI;AAAA,IAChB,MAAM,SAAS,SAAS,KAAK,QAAQ,MAAM;AAAA,IAC3C,IAAI,WAAW;AAAA,MAAW,IAAI,IAAI,MAAM;AAAA,IACxC,MAAM,OAAO,KAAK,WAAW,QAAQ;AAAA,IACrC,MAAM,SAAS,SAAS,YAAY,YAAY,SAAS,IAAI;AAAA,IAC7D,IAAI,WAAW;AAAA,MAAW,IAAI,IAAI,MAAM;AAAA,IACxC,OAAO,CAAC,GAAG,GAAG;AAAA;AAAA,EAGf,MAAM,CAAC,QAA+B;AAAA,IACrC,MAAM,OAAO,WAAW,KAAK,aAAa;AAAA,IAC1C,IAAI,OAAO,aAAa,WAAW;AAAA,MAClC,OAAO;AAAA,IACR;AAAA,IACA,OAAO,iDAAiD;AAAA;AAAA,OAGnD,MAAK,CACV,QACA,OACA,OACA,SACyB;AAAA,IACzB,IAAI,CAAC,OAAO,aAAa;AAAA,MACxB,OAAO;AAAA,QACN,IAAI;AAAA,QACJ,SACC;AAAA,QACD,QAAQ;AAAA,MACT;AAAA,IACD;AAAA,IACA,IAAI,OAAO,aAAa,WAAW;AAAA,MAClC,OAAO;AAAA,QACN,IAAI;AAAA,QACJ,SACC;AAAA,QACD,QAAQ;AAAA,MACT;AAAA,IACD;AAAA,IACA,IAAI,YAAY,WAAW;AAAA,MAC1B,OAAO,EAAE,IAAI,OAAO,SAAS,yBAAyB,QAAQ,UAAU;AAAA,IACzE;AAAA,IACA,IAAI;AAAA,IACJ,IAAI;AAAA,MACH,WAAW,MAAM,KAAK,WAAW,IAAI;AAAA,MACpC,OAAO,OAAO;AAAA,MACf,OAAO,KAAK,aAAa,KAAK;AAAA;AAAA,IAE/B,KAAK,OAAO;AAAA,IACZ,KAAK,UAAU,QAAQ,SAAS;AAAA,IAChC,IAAI,KAAK,OAAO,QAAQ,KAAK,WAAW;AAAA,MACvC,OAAO;AAAA,QACN,IAAI;AAAA,QACJ,SACC;AAAA,QACD,QAAQ;AAAA,MACT;AAAA,IACD;AAAA,IAGA,IAAI,CAAC,MAAM,GAAG;AAAA,MACb,OAAO;AAAA,QACN,IAAI;AAAA,QACJ,SACC;AAAA,QACD,QAAQ;AAAA,MACT;AAAA,IACD;AAAA,IAIA,MAAM,QAAQ,GAAG,QAAQ,aAAa,QAAO,EAAE;AAAA,IAC/C,MAAM,QAAQ,QAAO,EAAE;AAAA,IACvB,MAAM,WAAW,QAAO,EAAE;AAAA,IAC1B,KAAK,QAAQ,IAAI,QAAQ,WAAW,KAAK;AAAA,IACzC,KAAK,OAAO,IAAI,OAAO;AAAA,MACtB,WAAW,QAAQ;AAAA,MACnB,WAAW,QAAQ;AAAA,MACnB;AAAA,MACA;AAAA,MACA,WAAW,KAAK,IAAI,IAAI;AAAA,IACzB,CAAC;AAAA,IACD,MAAM,MAAM,IAAI,IAAI,SAAS,qBAAqB;AAAA,IAClD,MAAM,SAAiC;AAAA,MACtC,eAAe;AAAA,MACf,WAAW,KAAK,QAAQ;AAAA,MACxB,cAAc,KAAK;AAAA,MACnB,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA,gBAAgB,KAAK,QAAQ;AAAA,MAC7B,uBAAuB;AAAA,IACxB;AAAA,IACA,IAAI,KAAK,YAAY,IAAI,QAAQ,SAAS;AAAA,MAAG,OAAO,YAAY;AAAA,IAChE,YAAY,GAAG,MAAM,OAAO,QAAQ,MAAM;AAAA,MAAG,IAAI,aAAa,IAAI,GAAG,CAAC;AAAA,IACtE,OAAO,EAAE,IAAI,YAAY,UAAU,IAAI,KAAK;AAAA;AAAA,OAOvC,SAAQ,CACb,QACA,WACA,WACyD;AAAA,IACzD,KAAK,OAAO;AAAA,IACZ,MAAM,QAAQ,OAAO,IAAI,OAAO,KAAK;AAAA,IACrC,MAAM,OAAO,KAAK,OAAO,IAAI,KAAK;AAAA,IAClC,IAAI,SAAS,aAAa,KAAK,aAAa,KAAK,IAAI,GAAG;AAAA,MACvD,OAAO;AAAA,QACN,QAAQ;AAAA,UACP,IAAI;AAAA,UACJ,SACC;AAAA,UACD,QAAQ;AAAA,QACT;AAAA,MACD;AAAA,IACD;AAAA,IACA,KAAK,OAAO,OAAO,KAAK;AAAA,IACxB,MAAM,YAAY,KAAK;AAAA,IACvB,KAAK,QAAQ,OAAO,SAAS;AAAA,IAC7B,MAAM,OAAO,CAAC,QAAgB,aAAqB;AAAA,MAClD;AAAA,MACA,QAAQ,EAAE,IAAI,OAAgB,SAAS,OAAO;AAAA,IAC/C;AAAA,IACA,IAAI,KAAK,cAAc,WAAW;AAAA,MACjC,OAAO,KACN,WACA,4EACD;AAAA,IACD;AAAA,IAEA,MAAM,MAAM,OAAO,IAAI,KAAK;AAAA,IAC5B,IAAI,QAAQ,QAAQ,QAAQ,KAAK,QAAQ,QAAQ;AAAA,MAChD,OAAO,KAAK,OAAO,oDAAoD;AAAA,IACxE;AAAA,IACA,MAAM,QAAQ,OAAO,IAAI,OAAO;AAAA,IAChC,IAAI,UAAU,MAAM;AAAA,MACnB,KAAK,QAAQ,KAAK,uBAAuB,EAAE,OAAO,MAAM,MAAM,GAAG,EAAE,EAAE,CAAC;AAAA,MACtE,OAAO,KACN,YAAY,MAAM,MAAM,GAAG,EAAE,KAC7B,kBAAkB,KAAK,2DACxB;AAAA,IACD;AAAA,IACA,MAAM,OAAO,OAAO,IAAI,MAAM;AAAA,IAC9B,IAAI,SAAS,QAAQ,SAAS,IAAI;AAAA,MACjC,OAAO,KACN,WACA,kEACD;AAAA,IACD;AAAA,IACA,IAAI;AAAA,IACJ,IAAI;AAAA,MACH,UAAU,MAAM,KAAK,QAAQ,MAAM,IAAI;AAAA,MACtC,OAAO,GAAG;AAAA,MACX,MAAM,SACL,aAAa,aAAa,aAAa,WAAW,EAAE,SAAS;AAAA,MAC9D,KAAK,QAAQ,KAAK,uBAAuB;AAAA,QACxC;AAAA,QACA,SAAS,aAAa,QAAQ,EAAE,QAAQ,MAAM,GAAG,GAAG,IAAI;AAAA,MACzD,CAAC;AAAA,MACD,OAAO,KACN,QACA,kBAAkB,KAAK,iEACxB;AAAA;AAAA,IAGD,MAAM,SAAS,UAAU,SAAS;AAAA,IAClC,IAAI,WAAW,WAAW;AAAA,MACzB,OAAO,KACN,eACA,uDACD;AAAA,IACD;AAAA,IACA,IAAI,OAAO,aAAa,WAAW;AAAA,MAClC,OAAO,KACN,cACA,+FACD;AAAA,IACD;AAAA,IACA,MAAM,MAAM,YAAY,KAAK,QAAQ,QAAQ,OAAO;AAAA,IACpD,IAAI,QAAQ,OAAO,UAAU;AAAA,MAC5B,KAAK,YAAY,IAAI,SAAS;AAAA,MAC9B,IAAI,KAAK,YAAY,OAAO,WAAW;AAAA,QACtC,MAAM,SAAS,KAAK,YAAY,OAAO,EAAE,KAAK,EAAE;AAAA,QAChD,IAAI,WAAW;AAAA,UAAW,KAAK,YAAY,OAAO,MAAM;AAAA,MACzD;AAAA,MACA,OAAO,KACN,YACA,GAAG,4EACJ;AAAA,IACD;AAAA,IACA,KAAK,YAAY,OAAO,SAAS;AAAA,IACjC,OAAO,EAAE,WAAW,QAAQ,EAAE,IAAI,MAAM,SAAS,IAAI,EAAE;AAAA;AAAA,OAIlD,OAAO,CAAC,MAAc,MAA6B;AAAA,IACxD,MAAM,WAAW,MAAM,KAAK,WAAW,IAAI;AAAA,IAC3C,MAAM,OAAO,IAAI,gBAAgB;AAAA,MAChC,YAAY;AAAA,MACZ;AAAA,MACA,cAAc,KAAK;AAAA,MACnB,eAAe,KAAK;AAAA,IACrB,CAAC;AAAA,IACD,MAAM,UAAkC;AAAA,MACvC,gBAAgB;AAAA,IACjB;AAAA,IACA,MAAM,SAAS,KAAK,QAAQ;AAAA,IAC5B,IAAI,WAAW,aAAa,SAAS,cAAc,uBAAuB;AAAA,MAEzE,MAAM,MAAM,CAAC,MAAc,mBAAmB,CAAC,EAAE,QAAQ,QAAQ,GAAG;AAAA,MACpE,QAAQ,mBACP,SAAS,KAAK,GAAG,IAAI,KAAK,QAAQ,QAAQ,KAAK,IAAI,MAAM,GAAG;AAAA,IAC9D,EAAO;AAAA,MACN,KAAK,IAAI,aAAa,KAAK,QAAQ,QAAQ;AAAA,MAC3C,IAAI,WAAW;AAAA,QAAW,KAAK,IAAI,iBAAiB,MAAM;AAAA;AAAA,IAE3D,IAAI;AAAA,IACJ,IAAI;AAAA,MACH,WAAW,MAAM,UAChB,SAAS,eACT,EAAE,QAAQ,QAAQ,SAAS,KAAK,GAChC,wBACD;AAAA,MACC,OAAO,GAAG;AAAA,MACX,IAAI,aAAa,eAAe;AAAA,QAC/B,MAAM,IAAI,UAAU,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO;AAAA,MAC9D;AAAA,MACA,MAAM;AAAA;AAAA,IAEP,MAAM,UAAU,IACd,WAA8C,WAChD;AAAA,IACA,IAAI,YAAY,WAAW;AAAA,MAC1B,MAAM,IAAI,UAAU,eAAe,oCAAoC;AAAA,IACxE;AAAA,IACA,QAAQ,YAAY,MAAM,UAAU,SAAS,KAAK,KAAK;AAAA,IACvD,MAAM,MAAM,KAAK,IAAI;AAAA,IACrB,IAAI,QAAQ,WAAW,SAAS,QAAQ;AAAA,MACvC,MAAM,IAAI,UAAU,gBAAgB,gCAAgC;AAAA,IACrE;AAAA,IACA,MAAM,MAAM,UAAU,OAAO;AAAA,IAC7B,IAAI,CAAC,IAAI,SAAS,KAAK,QAAQ,QAAQ,GAAG;AAAA,MACzC,MAAM,IAAI,UAAU,gBAAgB,oCAAoC;AAAA,IACzE;AAAA,IACA,MAAM,MAAM,QAAQ;AAAA,IACpB,KACE,IAAI,SAAS,KAAK,QAAQ,cAC3B,QAAQ,KAAK,QAAQ,UACpB;AAAA,MACD,MAAM,IAAI,UACT,gBACA,sCACD;AAAA,IACD;AAAA,IACA,MAAM,MAAM,YAAY,SAAS,KAAK;AAAA,IACtC,IAAI,QAAQ,aAAa,OAAO,MAAM,iBAAiB;AAAA,MACtD,MAAM,IAAI,UAAU,gBAAgB,0BAA0B;AAAA,IAC/D;AAAA,IACA,MAAM,MAAM,YAAY,SAAS,KAAK;AAAA,IACtC,IAAI,QAAQ,aAAa,MAAM,MAAM,iBAAiB;AAAA,MACrD,MAAM,IAAI,UACT,gBACA,gDACD;AAAA,IACD;AAAA,IACA,IAAI,QAAQ,aAAa,KAAK,OAAO;AAAA,MACpC,MAAM,IAAI,UACT,kBACA,qCACD;AAAA,IACD;AAAA,IACA,MAAM,QAAQ,KAAK,QAAQ,gBAAgB;AAAA,IAC3C,MAAM,UAAU,QAAQ;AAAA,IACxB,IAAI,OAAO,YAAY,YAAY,YAAY,MAAM,QAAQ,SAAS,KAAK;AAAA,MAC1E,MAAM,IAAI,UAAU,oBAAoB,uBAAuB,OAAO;AAAA,IACvE;AAAA,IACA,OAAO;AAAA;AAAA,EAGR,YAAY,CAAC,OAA+B;AAAA,IAC3C,KAAK,QAAQ,KAAK,yBAAyB;AAAA,MAC1C,QAAQ,iBAAiB,YAAY,MAAM,SAAS;AAAA,MACpD,SAAS,iBAAiB,QAAQ,MAAM,QAAQ,MAAM,GAAG,GAAG,IAAI;AAAA,IACjE,CAAC;AAAA,IACD,OAAO;AAAA,MACN,IAAI;AAAA,MACJ,SAAS,wBAAwB,KAAK;AAAA,MACtC,QAAQ;AAAA,IACT;AAAA;AAAA,EAID,MAAM,CAAC,WAAyB;AAAA,IAC/B,KAAK,UAAU,SAAS;AAAA,IACxB,KAAK,YAAY,OAAO,SAAS;AAAA;AAAA,EAGlC,SAAS,CAAC,WAAyB;AAAA,IAClC,MAAM,QAAQ,KAAK,QAAQ,IAAI,SAAS;AAAA,IACxC,IAAI,UAAU;AAAA,MAAW,KAAK,OAAO,OAAO,KAAK;AAAA,IACjD,KAAK,QAAQ,OAAO,SAAS;AAAA;AAAA,EAG9B,MAAM,GAAS;AAAA,IACd,MAAM,MAAM,KAAK,IAAI;AAAA,IACrB,YAAY,OAAO,SAAS,KAAK,QAAQ;AAAA,MACxC,IAAI,KAAK,YAAY;AAAA,QAAK;AAAA,MAC1B,KAAK,OAAO,OAAO,KAAK;AAAA,MACxB,IAAI,KAAK,QAAQ,IAAI,KAAK,SAAS,MAAM,OAAO;AAAA,QAC/C,KAAK,QAAQ,OAAO,KAAK,SAAS;AAAA,MACnC;AAAA,IACD;AAAA;AAEF;;;AC1hBA;AAsEO,IAAM,sBAAsB;AAC5B,IAAM,uBAAuB;AAY7B,SAAS,cAAc,GAAW;AAAA,EAGxC,MAAM,SAAS,IAAI,YAAY,CAAC;AAAA,EAChC,UAAS;AAAA,IACR,OAAO,gBAAgB,MAAM;AAAA,IAC7B,MAAM,IAAI,OAAO,MAAM;AAAA,IACvB,IAAI,IAAI;AAAA,MAAe,OAAO,OAAO,IAAI,GAAS,EAAE,SAAS,GAAG,GAAG;AAAA,EACpE;AAAA;AAGD,SAAS,QAAQ,CAAC,GAAW,GAAoB;AAAA,EAChD,MAAM,IAAI,OAAO,KAAK,CAAC;AAAA,EACvB,MAAM,IAAI,OAAO,KAAK,CAAC;AAAA,EACvB,OAAO,EAAE,WAAW,EAAE,UAAU,gBAAgB,GAAG,CAAC;AAAA;AAAA;AAQ9C,MAAM,aAAa;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EAEA,WAAW,CACV,MACA,UAAoD,CAAC,GACpD;AAAA,IACD,KAAK,QAAQ;AAAA,IACb,KAAK,SAAS,QAAQ,SAAS;AAAA,IAC/B,KAAK,eAAe,QAAQ,eAAe;AAAA;AAAA,MAIxC,MAAM,GAAY;AAAA,IACrB,OAAO,KAAK,aAAa;AAAA;AAAA,MAItB,YAAY,GAAW;AAAA,IAC1B,OAAO,KAAK,aAAa,YACtB,IACA,KAAK,eAAe,KAAK,SAAS;AAAA;AAAA,EAGtC,KAAK,GAAS;AAAA,IACb,IAAI,KAAK,aAAa,WAAW;AAAA,MAEhC,KAAK,MAAM,KAAK,SAAS,MAAM,KAAK,SAAS,SAAS;AAAA,MACtD;AAAA,IACD;AAAA,IACA,KAAK,OAAO;AAAA;AAAA,EAGb,IAAI,GAAS;AAAA,IACZ,aAAa,KAAK,MAAM;AAAA,IACxB,KAAK,SAAS;AAAA,IACd,KAAK,WAAW;AAAA,IAChB,KAAK,YAAY;AAAA;AAAA,EAOlB,KAAK,CACJ,OACA,MAAc,KAAK,IAAI,GACvB,QAAuB,MAAM,MACjB;AAAA,IACZ,MAAM,UAAU,KAAK;AAAA,IACrB,IAAI,YAAY;AAAA,MAAW,OAAO;AAAA,IAClC,MAAM,QAAQ,MAAM,QAAQ,UAAU,EAAE;AAAA,IACxC,IAAI,CAAC,UAAU,KAAK,KAAK;AAAA,MAAG,OAAO;AAAA,IACnC,IAAI,CAAC,MAAM;AAAA,MAAG,OAAO;AAAA,IACrB,IAAI,OAAO,QAAQ,WAAW;AAAA,MAC7B,KAAK,YAAY,QAAQ;AAAA,MACzB,KAAK,OAAO;AAAA,MACZ,OAAO;AAAA,IACR;AAAA,IACA,IAAI,SAAS,OAAO,QAAQ,IAAI,GAAG;AAAA,MAClC,KAAK,YAAY;AAAA,MACjB,KAAK,OAAO;AAAA,MACZ,OAAO;AAAA,IACR;AAAA,IACA,QAAQ;AAAA,IACR,MAAM,UACL,KAAK,cAAc,aAAa,SAAS,OAAO,KAAK,SAAS;AAAA,IAC/D,IAAI,QAAQ,YAAY,KAAK,cAAc;AAAA,MAC1C,KAAK,YAAY;AAAA,MACjB,KAAK,OAAO;AAAA,MACZ,OAAO;AAAA,IACR;AAAA,IACA,OAAO,UAAU,YAAY;AAAA;AAAA,EAG9B,MAAM,GAAS;AAAA,IACd,aAAa,KAAK,MAAM;AAAA,IACxB,MAAM,YAAY,KAAK,IAAI,IAAI,KAAK;AAAA,IACpC,KAAK,WAAW,EAAE,MAAM,eAAe,GAAG,WAAW,UAAU,EAAE;AAAA,IACjE,KAAK,SAAS,WAAW,MAAM;AAAA,MAC9B,IAAI,KAAK,aAAa;AAAA,QAAW;AAAA,MACjC,KAAK,YAAY,KAAK,SAAS;AAAA,MAC/B,KAAK,OAAO;AAAA,OACV,KAAK,MAAM;AAAA,IACd,KAAK,MAAM,KAAK,SAAS,MAAM,SAAS;AAAA;AAE1C;AAEA,IAAM,WAAqD;AAAA,EAC1D,OACC;AAAA,EACD,SACC;AAAA,EACD,QACC;AAAA,EACD,UACC;AAAA,EACD,WAAW;AAAA,EACX,SACC;AACF;AAGO,IAAM,cAA6B;AAAA,EACzC,MAAM;AAAA,EACN,MAAM,GAAW;AAAA,IAChB,OAAO;AAAA;AAAA;AAAA;AAAA,EAIR,KAAK,CAAC,QAAQ,MAAM,OAAsB;AAAA,IACzC,MAAM,SAAS,OAAO,MAAM,MAC3B,KAAK,IAAI,MAAM,KAAK,IACpB,KAAK,IAAI,GACT,KACD;AAAA,IACA,IAAI,WAAW;AAAA,MAAM,OAAO,EAAE,IAAI,KAAK;AAAA,IACvC,IAAI,UAAU,SAAS;AAAA,IACvB,IAAI,WAAW,SAAS;AAAA,MACvB,MAAM,OAAO,OAAO,MAAM;AAAA,MAC1B,WAAW,IAAI,SAAS,IAAI,aAAa,GAAG;AAAA,IAC7C;AAAA,IACA,OAAO;AAAA,MACN,IAAI;AAAA,MACJ;AAAA,MACA,QAAQ,WAAW,YAAY,iBAAiB;AAAA,IACjD;AAAA;AAEF;AAGO,IAAM,kBAA+D;AAAA,EAC3E,MAAM;AACP;;;ANrNO,IAAM,QAAQ;AAGrB,IAAM,iBAAiB,KAAK;AAE5B,IAAM,mBAAmB;AACzB,IAAM,cAAc;AAEpB,IAAM,qBAAqB;AAC3B,IAAM,0BAA0B;AAEhC,IAAM,6BAA6B;AAEnC,IAAM,0BAA0B,KAAK,KAAK;AAC1C,IAAM,YAAY;AAClB,IAAM,iBAAiB;AACvB,IAAM,mBAAmB;AAAA;AAwDzB,MAAM,mBAAmB,MAAM;AAAA,EACrB;AAAA,EACA;AAAA,EACT,WAAW,CAAC,QAAgB,MAAc,aAAqB;AAAA,IAC9D,MAAM,WAAW;AAAA,IACjB,KAAK,SAAS;AAAA,IACd,KAAK,OAAO;AAAA;AAEd;AAEA,SAAS,iBAAiB,CAAC,GAAW,GAAoB;AAAA,EACzD,MAAM,IAAI,OAAO,KAAK,CAAC;AAAA,EACvB,MAAM,IAAI,OAAO,KAAK,CAAC;AAAA,EACvB,OAAO,EAAE,WAAW,EAAE,UAAU,iBAAgB,GAAG,CAAC;AAAA;AAI9C,SAAS,KAAI,CAAC,UAA0B;AAAA,EAC9C,OAAO,IAAI,IAAI,aAAa,QAAQ,EAClC,OAAO,QAAQ,EACf,OAAO,EACP,SAAS,EAAE,UAAU,aAAa,aAAa,KAAK,CAAC;AAAA;AAIxD,IAAM,WAAW;AAGjB,SAAS,MAAM,CACd,QACA,OAC6D;AAAA,EAC7D,MAAM,MAA0C,CAAC;AAAA,EACjD,WAAW,QAAQ,OAAO;AAAA,IACzB,MAAM,SAAS,OAAO,OAAO,IAAI;AAAA,IACjC,IAAI,OAAO,SAAS;AAAA,MAAG,OAAO,EAAE,WAAW,KAAK;AAAA,IAChD,MAAM,QAAQ,OAAO;AAAA,IACrB,IAAI,QAAQ,UAAU,aAAa,UAAU,KAAK,YAAY;AAAA,EAC/D;AAAA,EACA,OAAO;AAAA;AAGR,SAAS,OAAM,CAAC,OAAuB;AAAA,EACtC,OAAO,OACL,gBAAgB,IAAI,WAAW,KAAK,CAAC,EACrC,SAAS,EAAE,UAAU,aAAa,aAAa,KAAK,CAAC;AAAA;AAIxD,SAAS,UAAU,CAAC,aAA6B;AAAA,EAChD,IAAI;AAAA,IACH,MAAM,IAAI,IAAI,IAAI,WAAW;AAAA,IAC7B,OAAO,EAAE,aAAa,WAAW,EAAE,aAAa,WAC7C,EAAE,SACF,EAAE;AAAA,IACJ,MAAM;AAAA,IACP,OAAO;AAAA;AAAA;AAIT,SAAS,MAAM,CAAC,KAAqB;AAAA,EACpC,IAAI;AAAA,IACH,MAAM,IAAI,IAAI,IAAI,GAAG;AAAA,IACrB,OAAO,EAAE,QAAQ,EAAE;AAAA,IAClB,MAAM;AAAA,IACP,OAAO;AAAA;AAAA;AAAA;AAKF,MAAM,oBAAoB;AAAA,EACvB;AAAA,EACA;AAAA,EAEA,WAAW,IAAI;AAAA,EACf,gBAAgB,IAAI;AAAA,EACpB,qBAAqB,IAAI;AAAA,EACzB,SAAS,IAAI;AAAA,EACb;AAAA,EACA;AAAA,EACA,cAAc,QAAO,EAAE;AAAA,EAEvB,cAAc,IAAI,YAAY;AAAA,IACtC,UAAU;AAAA,IACV,iBAAiB;AAAA,EAClB,CAAC;AAAA,EAEQ,iBAAiB,IAAI,YAAY;AAAA,IACzC,UAAU;AAAA,IACV,iBAAiB;AAAA,EAClB,CAAC;AAAA,EAKQ,uBAAuB,IAAI,YAAY;AAAA,IAC/C,UAAU;AAAA,IACV,iBAAiB,IAAI;AAAA,EACtB,CAAC;AAAA,EAEQ,qBAAqB,IAAI,YAAY;AAAA,IAC7C,UAAU;AAAA,IACV,iBAAiB,IAAI;AAAA,EACtB,CAAC;AAAA,EACQ,cAAc,IAAI,YAAY,EAAE,UAAU,IAAI,iBAAiB,EAAE,CAAC;AAAA,EAElE,qBAAqB,IAAI,YAAY;AAAA,IAC7C,UAAU;AAAA,IACV,iBAAiB,IAAI;AAAA,EACtB,CAAC;AAAA,EAED,WAAW,CAAC,MAAyB,UAAkC;AAAA,IACtE,KAAK,QAAQ;AAAA,IACb,KAAK,iBAAiB,UAAU,iBAAiB;AAAA,IACjD,MAAM,OAAO,KAAK,OAAO;AAAA,IACzB,KAAK,WAAW;AAAA,SACZ;AAAA,SACC,SAAS,YACV,CAAC,IACD;AAAA,QACA,MAAM,IAAI,YAAY;AAAA,UACrB,QAAQ;AAAA,UACR,WAAW,MAAM,KAAK,UAAU;AAAA,UAChC,QAAQ,KAAK;AAAA,UACb,aAAa,KAAK,OAAO;AAAA,aACrB,UAAU,iBAAiB,YAC5B,CAAC,IACD,EAAE,UAAU,SAAS,aAAa;AAAA,QACtC,CAAC;AAAA,MACF;AAAA,SACC,UAAU;AAAA,IACd;AAAA,IACA,KAAK,QAAQ,IAAI,sBAAsB;AAAA,MACtC,cAAc,KAAK,OAAO;AAAA,MAC1B,QAAQ,KAAK;AAAA,SACT,UAAU,SAAS,YAAY,CAAC,IAAI,EAAE,UAAU,SAAS,KAAK;AAAA,IACnE,CAAC;AAAA;AAAA,MAGE,OAAO,GAAW;AAAA,IACrB,OAAO,KAAK,MAAM,UAAU;AAAA;AAAA,EAG7B,KAAK,GAA2B;AAAA,IAC/B,OAAO,KAAK,MAAM,OAAO,OAAO,EAAE,+BAA+B,IAAI,IAAI,CAAC;AAAA;AAAA,EAG3E,KAAK,CACJ,QACA,OACA,UAAkC,CAAC,GACxB;AAAA,IACX,OAAO,IAAI,SAAS,KAAK,UAAU,KAAK,GAAG;AAAA,MAC1C;AAAA,MACA,SAAS;AAAA,QACR,gBAAgB;AAAA,WACb,KAAK,MAAM;AAAA,WACX;AAAA,MACJ;AAAA,IACD,CAAC;AAAA;AAAA,EAIF,SAAS,CAAC,SAA2B;AAAA,IACpC,IAAI,CAAC,KAAK,MAAM,OAAO,MAAM;AAAA,MAC5B,OAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,KAAK,SAAS,EAAE,OAAO,QAAQ,EAAE,CAAC;AAAA,IACvE;AAAA,IACA,OAAO,IAAI,SAAS,MAAM;AAAA,MACzB,QAAQ;AAAA,MACR,SAAS;AAAA,WACL,KAAK,MAAM;AAAA,QACd,gCAAgC,GAAG;AAAA,QACnC,gCACC;AAAA,QACD,0BAA0B;AAAA,MAC3B;AAAA,IACD,CAAC;AAAA;AAAA,EAMF,iBAAiB,CAAC,WAA6B;AAAA,IAC9C,IAAI,CAAC,YAAY,SAAS;AAAA,MACzB,OAAO,IAAI,SAAS,aAAa,EAAE,QAAQ,IAAI,CAAC;AAAA,IACjD,OAAO,KAAK,MACX,KACA;AAAA,MACC,UAAU,GAAG,KAAK,aAAa;AAAA,MAC/B,uBAAuB,CAAC,KAAK,OAAO;AAAA,MACpC,kBAAkB,CAAC,KAAK;AAAA,MACxB,0BAA0B,CAAC,QAAQ;AAAA,MACnC,eAAe;AAAA,IAChB,GACA,EAAE,iBAAiB,uBAAuB,CAC3C;AAAA;AAAA,EAID,QAAQ,GAAa;AAAA,IACpB,MAAM,SAAS,KAAK;AAAA,IACpB,OAAO,KAAK,MACX,KACA;AAAA,MACC;AAAA,MACA,wBAAwB,GAAG;AAAA,MAC3B,gBAAgB,GAAG;AAAA,MACnB,qBAAqB,GAAG;AAAA,MACxB,0BAA0B,CAAC,MAAM;AAAA,MACjC,0BAA0B,CAAC,OAAO;AAAA,MAClC,uBAAuB,CAAC,sBAAsB,eAAe;AAAA,MAC7D,kCAAkC,CAAC,MAAM;AAAA,MACzC,uCAAuC,CAAC,MAAM;AAAA,MAC9C,4CAA4C,CAAC,MAAM;AAAA,MACnD,kBAAkB,CAAC,KAAK;AAAA,MACxB,uCAAuC;AAAA,MACvC,gDAAgD;AAAA,MAChD,uBAAuB;AAAA,IACxB,GACA,EAAE,iBAAiB,uBAAuB,CAC3C;AAAA;AAAA,EAGD,UAAU,GAAa;AAAA,IACtB,OAAO,IAAI,SAAS,eAAe;AAAA,MAClC,SAAS;AAAA,QACR,gBAAgB;AAAA,QAChB,iBAAiB;AAAA,QACjB,0BAA0B;AAAA,MAC3B;AAAA,IACD,CAAC;AAAA;AAAA,EAKF,KAAK,CACJ,QACA,OACA,MACA,cAAiC,CAAC,GAClC,eAAuC,CAAC,GAC7B;AAAA,IACX,MAAM,UAAU,YAAY,WAAW;AAAA,IACvC,YAAY,GAAG,MAAM,OAAO,QAAQ,YAAY;AAAA,MAAG,QAAQ,OAAO,GAAG,CAAC;AAAA,IACtE,OAAO,IAAI,SAAS,WAAW,OAAO,IAAI,GAAG,EAAE,QAAQ,QAAQ,CAAC;AAAA;AAAA,EAIjE,UAAU,CAAC,QAAgB,SAA2B;AAAA,IACrD,OAAO,KAAK,MACX,QACA,kCACA;AAAA,kBACe,WAAW,OAAO;AAAA,6GAElC;AAAA;AAAA,EAID,SAAS,CACR,aACA,OACA,OACA,aACS;AAAA,IACT,MAAM,MAAM,IAAI,IAAI,WAAW;AAAA,IAC/B,MAAM,SAAiC;AAAA,MACtC;AAAA,MACA,mBAAmB;AAAA,SACf,UAAU,YAAY,CAAC,IAAI,EAAE,MAAM;AAAA,MACvC,KAAK,KAAK;AAAA,IACX;AAAA,IACA,YAAY,GAAG,MAAM,OAAO,QAAQ,MAAM;AAAA,MAAG,IAAI,aAAa,OAAO,GAAG,CAAC;AAAA,IACzE,OAAO,IAAI;AAAA;AAAA,EAQZ,mBAAmB,CAClB,aACA,OACA,OACA,aACW;AAAA,IACX,MAAM,MAAM,KAAK,UAAU,aAAa,OAAO,OAAO,WAAW;AAAA,IACjE,MAAM,OAAO,OAAO,WAAW;AAAA,IAC/B,OAAO,KAAK,MACX,KACA,kCACA;AAAA,sEACmE,WAAW,WAAW,MAAM,WAAW,KAAK;AAAA,sCAC5E,WAAW,IAAI;AAAA,+CACN,WAAW,GAAG,iBAAiB,WAAW,IAAI,aAC3F;AAAA;AAAA,EAID,cAAc,CACb,aACA,OACA,OACA,aACW;AAAA,IACX,OAAO,IAAI,SAAS,MAAM;AAAA,MACzB,QAAQ;AAAA,MACR,SAAS;AAAA,QACR,UAAU,KAAK,UAAU,aAAa,OAAO,OAAO,WAAW;AAAA,QAC/D,iBAAiB;AAAA,QACjB,mBAAmB;AAAA,MACpB;AAAA,IACD,CAAC;AAAA;AAAA,EAGF,SAAS,CAAC,aAAqB,QAA0C;AAAA,IACxE,MAAM,MAAM,IAAI,IAAI,WAAW;AAAA,IAC/B,YAAY,GAAG,MAAM,OAAO,QAAQ,MAAM;AAAA,MAAG,IAAI,aAAa,OAAO,GAAG,CAAC;AAAA,IACzE,OAAO,IAAI,SAAS,MAAM;AAAA,MACzB,QAAQ;AAAA,MACR,SAAS;AAAA,QACR,UAAU,IAAI;AAAA,QACd,iBAAiB;AAAA,QACjB,mBAAmB;AAAA,MACpB;AAAA,IACD,CAAC;AAAA;AAAA,OAII,UAAS,CAAC,KAAc,IAA+B;AAAA,IAC5D,IAAI,CAAC,KAAK,YAAY,KAAK,EAAE,GAAG;AAAA,MAC/B,OAAO,KAAK,WACX,KACA,mEACD;AAAA,IACD;AAAA,IACA,MAAM,QAAQ,IAAI,IAAI,IAAI,GAAG,EAAE;AAAA,IAC/B,MAAM,IAAI,OAAO,OAAO;AAAA,MACvB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD,CAAC;AAAA,IACD,IAAI,eAAe,GAAG;AAAA,MACrB,IAAI,EAAE,cAAc,eAAe,EAAE,cAAc,gBAAgB;AAAA,QAClE,OAAO,KAAK,WAAW,KAAK,qBAAqB,EAAE,kBAAkB;AAAA,MACtE;AAAA,IACD;AAAA,IACA,MAAM,WAAW,eAAe,IAAI,MAAM,IAAI,WAAW,IAAI,EAAE;AAAA,IAC/D,MAAM,cACL,eAAe,IAAI,MAAM,IAAI,cAAc,IAAI,EAAE;AAAA,IAClD,IAAI,aAAa,aAAa,aAAa,MAAM;AAAA,MAChD,OAAO,KAAK,WAAW,KAAK,+BAA+B;AAAA,IAC5D;AAAA,IACA,IAAI;AAAA,IACJ,IAAI;AAAA,MACH,SAAS,MAAM,KAAK,MAAM,IAAI,QAAQ;AAAA,MACrC,OAAO,OAAO;AAAA,MACf,IAAI,iBAAiB,qBAAqB;AAAA,QACzC,KAAK,MAAM,OAAO,KAAK,wBAAwB;AAAA,UAC9C,QAAQ,MAAM;AAAA,UAEd,MAAM,IAAI,SAAS,QAAQ,IACxB,OAAO,QAAQ,EAAE,MAAM,GAAG,GAAG,IAC7B;AAAA,QACJ,CAAC;AAAA,QACD,OAAO,KAAK,WAAW,KAAK,MAAM,OAAO;AAAA,MAC1C;AAAA,MACA,MAAM;AAAA;AAAA,IAEP,IAAI,gBAAgB,aAAa,gBAAgB,MAAM;AAAA,MACtD,OAAO,KAAK,WAAW,KAAK,kCAAkC;AAAA,IAC/D;AAAA,IACA,IAAI,CAAC,OAAO,aAAa,KAAK,CAAC,MAAM,mBAAmB,aAAa,CAAC,CAAC,GAAG;AAAA,MACzE,KAAK,MAAM,OAAO,KAAK,wBAAwB;AAAA,QAC9C,QAAQ;AAAA,QACR,MAAM,OAAO;AAAA,MACd,CAAC;AAAA,MACD,OAAO,KAAK,WACX,KACA,GAAG,OAAO,6DAA6D,OAAO,WAAW,KAC1F;AAAA,IACD;AAAA,IAEA,MAAM,QAAQ,eAAe,IAAI,YAAY,EAAE;AAAA,IAC/C,MAAM,OAAO,CAAC,OAAe,gBAC5B,KAAK,oBAAoB,aAAa,OAAO,OAAO,WAAW;AAAA,IAChE,IAAI,eAAe,GAAG;AAAA,MACrB,OAAO,KAAK,mBAAmB,GAAG,EAAE,mCAAmC;AAAA,IACxE;AAAA,IACA,IAAI,UAAU,aAAa,MAAM,SAAS,kBAAkB;AAAA,MAC3D,OAAO,KAAK,mBAAmB,mBAAmB;AAAA,IACnD;AAAA,IACA,IAAI,EAAE,qBAAqB,QAAQ;AAAA,MAClC,OAAO,KACN,6BACA,sCACD;AAAA,IACD;AAAA,IACA,MAAM,YAAY,EAAE;AAAA,IACpB,IAAI,cAAc,WAAW;AAAA,MAC5B,OAAO,KAAK,mBAAmB,mCAAmC;AAAA,IACnE;AAAA,IACA,IAAI,EAAE,6BAA6B,QAAQ;AAAA,MAC1C,OAAO,KAAK,mBAAmB,oCAAoC;AAAA,IACpE;AAAA,IACA,IAAI,CAAC,6BAA6B,KAAK,SAAS,GAAG;AAAA,MAClD,OAAO,KAAK,mBAAmB,6BAA6B;AAAA,IAC7D;AAAA,IACA,MAAM,WAAW,EAAE;AAAA,IACnB,MAAM,YAAY,KAAK,WAAW,QAAQ;AAAA,IAC1C,IAAI,aAAa,aAAa,cAAc,WAAW;AAAA,MACtD,OAAO,KACN,kBACA,0DACD;AAAA,IACD;AAAA,IACA,MAAM,SAAS,KAAK,eAAe,EAAE,QAAQ;AAAA,IAC7C,IAAI,WAAW,WAAW;AAAA,MACzB,OAAO,KAAK,iBAAiB,sBAAsB,QAAQ;AAAA,IAC5D;AAAA,IAKA,MAAM,UAAU,KAAK,MAAM,QAAQ,SAAS;AAAA,IAC5C,IAAI,YAAY,aAAa,CAAC,QAAQ,aAAa;AAAA,MAClD,OAAO,KAAK,aACX,QACA,aAAa,IAAI,IAAI,IAAI,GAAG,EAAE,UAC9B,KAAK,UACJ,aACA,OACA,iBACA,mCACD,GACA,YAAY,SACb;AAAA,IACD;AAAA,IACA,MAAM,SAAS,KAAK,SAAS,QAAQ,KAAK;AAAA,IAC1C,IAAI,QAAQ,YAAY,WAAW;AAAA,MAClC,IAAI;AAAA,QACH,MAAM,OAAO,QAAQ;AAAA,QACpB,OAAO,OAAO;AAAA,QACf,KAAK,MAAM,OAAO,KAAK,yBAAyB;AAAA,UAC/C,SACC,iBAAiB,QAAQ,MAAM,QAAQ,MAAM,GAAG,GAAG,IAAI;AAAA,QACzD,CAAC;AAAA,QACD,OAAO,KAAK,WACX,KACA,6FACD;AAAA;AAAA,IAEF;AAAA,IACA,KAAK,cAAc;AAAA,IACnB,IACC,KAAK,SAAS,QAAQ,gBACrB,KAAK,cAAc,IAAI,EAAE,KAAK,MAAM,oBACpC;AAAA,MACD,OAAO,KAAK,WACX,KACA,oFACD;AAAA,IACD;AAAA,IACA,KAAK,UAAU,WAAW,EAAE;AAAA,IAC5B,MAAM,UAAmB;AAAA,MACxB,IAAI,QAAO,EAAE;AAAA,MACb,WAAW,KAAK,IAAI,IAAI;AAAA,MACxB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,eAAe;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,IACA,KAAK,YAAY,OAAO;AAAA,IACxB,MAAM,UAAU,KAAK,WAAW,GAAG;AAAA,IACnC,OAAO,KAAK,aACX,SACA,QAAQ,IACR,WACA,KACA,QAAQ,MACT;AAAA;AAAA,EAGD,WAAW,CAAC,GAAkB;AAAA,IAC7B,KAAK,SAAS,IAAI,EAAE,IAAI,CAAC;AAAA,IACzB,KAAK,cAAc,IAAI,EAAE,KAAK,KAAK,cAAc,IAAI,EAAE,EAAE,KAAK,KAAK,CAAC;AAAA,IACpE,KAAK,mBAAmB,IACvB,EAAE,YACD,KAAK,mBAAmB,IAAI,EAAE,SAAS,KAAK,KAAK,CACnD;AAAA;AAAA,EASD,SAAS,CAAC,WAAmB,IAAkB;AAAA,IAC9C,MAAM,QAAQ,KAAK,mBAAmB,IAAI,SAAS,KAAK;AAAA,IACxD,IAAI,QAAQ;AAAA,MAA4B;AAAA,IACxC,MAAM,OAAO,IAAI;AAAA,IACjB,WAAW,KAAK,KAAK,SAAS,OAAO,GAAG;AAAA,MACvC,IAAI,EAAE,cAAc;AAAA,QAAW;AAAA,MAC/B,MAAM,OAAO,KAAK,IAAI,EAAE,EAAE;AAAA,MAC1B,IAAI,SAAS;AAAA,QAAW,KAAK,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;AAAA,MACrC;AAAA,aAAK,KAAK,CAAC;AAAA,IACjB;AAAA,IACA,MAAM,MAAM,KAAK,IAAI,EAAE,KAAK,CAAC;AAAA,IAC7B,IAAI,IAAI,UAAU,4BAA4B;AAAA,MAC7C,IAAI,IAAI,OAAO;AAAA,QAAW,KAAK,aAAa,IAAI,EAAE;AAAA,MAClD;AAAA,IACD;AAAA,IACA,IAAI,QAAQ;AAAA,MAAyB;AAAA,IAIrC,IAAI,OAAkB,CAAC;AAAA,IACvB,WAAW,QAAQ,KAAK,OAAO,GAAG;AAAA,MACjC,IAAI,KAAK,UAAU,KAAK;AAAA,QAAQ,OAAO;AAAA,IACxC;AAAA,IACA,IAAI,KAAK,OAAO;AAAA,MAAW,KAAK,aAAa,KAAK,EAAE;AAAA;AAAA,EAGrD,YAAY,CAAC,GAAkB;AAAA,IAC9B,IAAI,CAAC,KAAK,SAAS,OAAO,EAAE,EAAE;AAAA,MAAG;AAAA,IACjC,MAAM,MAAM,CAAC,KAA0B,QAAgB;AAAA,MACtD,MAAM,KAAK,IAAI,IAAI,GAAG,KAAK,KAAK;AAAA,MAChC,IAAI,KAAK;AAAA,QAAG,IAAI,OAAO,GAAG;AAAA,MACrB;AAAA,YAAI,IAAI,KAAK,CAAC;AAAA;AAAA,IAEpB,IAAI,KAAK,eAAe,EAAE,EAAE;AAAA,IAC5B,IAAI,KAAK,oBAAoB,EAAE,SAAS;AAAA,IACxC,WAAW,UAAU,OAAO,OAAO,KAAK,QAAQ;AAAA,MAAG,QAAQ,SAAS,EAAE,EAAE;AAAA;AAAA,EAOzE,YAAY,CACX,QACA,UACA,WACA,YAAY,OACD;AAAA,IACX,MAAM,MAAM,WAAW,WAAW,OAAO,IAAI,eAAe,WAAW,OAAO,IAAI;AAAA,IAClF,MAAM,QAAQ,YACX,+CACA;AAAA,IACH,MAAM,QAAQ,YACX,MAAM;AAAA,mFAEN,MAAM;AAAA;AAAA,IAET,MAAM,OAAO,OAAO;AAAA,EACpB;AAAA;AAAA,kCAEgC,WAAW,QAAQ;AAAA,0BAC3B,WAAW,SAAS;AAAA;AAAA,IAE5C,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI;AAAA;AAAA,OAI7B,gBAAe,CAAC,KAAc,IAA+B;AAAA,IAElE,MAAM,SAAS,IAAI,QAAQ,IAAI,QAAQ;AAAA,IACvC,MAAM,OAAO,IAAI,QAAQ,IAAI,gBAAgB;AAAA,IAC7C,IACE,WAAW,QAAQ,WAAW,KAAK,WACnC,SAAS,QAAQ,SAAS,eAC1B;AAAA,MACD,OAAO,KAAK,WAAW,KAAK,4CAA4C;AAAA,IACzE;AAAA,IACA,IAAI,CAAC,KAAK,eAAe,KAAK,EAAE,GAAG;AAAA,MAClC,OAAO,KAAK,WACX,KACA,6FACD;AAAA,IACD;AAAA,IACA,MAAM,QAAQ,IAAI,QAAQ,IAAI,cAAc,KAAK,IAAI,MAAM,GAAG,EAAE,IAAI,KAAK;AAAA,IACzE,IAAI,SAAS,qCAAqC;AAAA,MACjD,OAAO,KAAK,WAAW,KAAK,kCAAkC;AAAA,IAC/D;AAAA,IACA,MAAM,OAAO,MAAM,KAAK,UAAU,GAAG;AAAA,IACrC,IAAI,SAAS,WAAW;AAAA,MACvB,OAAO,KAAK,WAAW,KAAK,yBAAyB;AAAA,IACtD;AAAA,IACA,MAAM,OAAO,IAAI,gBAAgB,IAAI;AAAA,IACrC,MAAM,UAAU,KAAK,SAAS,IAAI,KAAK,IAAI,YAAY,KAAK,EAAE;AAAA,IAC9D,IAAI,YAAY,aAAa,QAAQ,aAAa,KAAK,IAAI,GAAG;AAAA,MAC7D,OAAO,KAAK,WACX,KACA,0DACD;AAAA,IACD;AAAA,IACA,MAAM,UAAU,KAAK,WAAW,GAAG;AAAA,IACnC,MAAM,OAAO,KAAK,IAAI,MAAM,KAAK;AAAA,IACjC,IACC,QAAQ,WAAW,aACnB,CAAC,IAAI,KAAK,OAAO,MAAM;AAAA,MACtB,QAAQ,KAAK;AAAA,MACb,WAAW,GAAG,QAAQ,MAAM,QAAQ;AAAA,MACpC,QAAQ;AAAA,IACT,CAAC,GACA;AAAA,MAED,OAAO,KAAK,WACX,KACA,8EACD;AAAA,IACD;AAAA,IAEA,MAAM,SAAS,KAAK,IAAI,QAAQ;AAAA,IAChC,IAAI,WAAW,UAAU;AAAA,MACxB,KAAK,aAAa,OAAO;AAAA,MACzB,KAAK,MAAM,OAAO,KAAK,mBAAmB;AAAA,QACzC,SAAS,aAAa,QAAQ,SAAS;AAAA,QACvC,QAAQ,QAAQ,OAAO;AAAA,MACxB,CAAC;AAAA,MACD,OAAO,KAAK,eACX,QAAQ,aACR,QAAQ,OACR,iBACA,mCACD;AAAA,IACD;AAAA,IACA,IAAI,WAAW,WAAW;AAAA,MACzB,OAAO,KAAK,aAAa,SAAS,QAAQ,EAAE;AAAA,IAC7C;AAAA,IAEA,MAAM,UAAU,KAAK,MAAM,QAAQ,QAAQ,SAAS;AAAA,IACpD,IAAI,YAAY,WAAW;AAAA,MAC1B,OAAO,KAAK,aACX,SACA,QAAQ,IACR,6BACD;AAAA,IACD;AAAA,IACA,MAAM,SAAS,KAAK,SAAS,QAAQ,KAAK;AAAA,IAC1C,IAAI,WAAW,WAAW;AAAA,MACzB,OAAO,KAAK,WACX,KACA,8CACD;AAAA,IACD;AAAA,IAGA,MAAM,QAAQ,MACb,KAAK,qBAAqB,KAAK,GAAG,QAAQ,aAAa,IAAI,KAC3D,KAAK,mBAAmB,KAAK,QAAQ,SAAS;AAAA,IAC/C,MAAM,SAAS,MAAM,OAAO,MAAM,SAAS,MAAM,OAAO;AAAA,MACvD,WAAW,QAAQ;AAAA,MACnB,WAAW,QAAQ;AAAA,MACnB,WAAW,QAAQ;AAAA,IACpB,CAAC;AAAA,IACD,IAAI,OAAO,OAAO,YAAY;AAAA,MAC7B,KAAK,MAAM,OAAO,KAAK,0BAA0B;AAAA,QAChD,SAAS,aAAa,QAAQ,SAAS;AAAA,QACvC,QAAQ,QAAQ,OAAO;AAAA,QACvB,QAAQ,OAAO;AAAA,MAChB,CAAC;AAAA,MACD,OAAO,IAAI,SAAS,MAAM;AAAA,QACzB,QAAQ;AAAA,QACR,SAAS;AAAA,UACR,UAAU,OAAO;AAAA,UACjB,iBAAiB;AAAA,UACjB,mBAAmB;AAAA,QACpB;AAAA,MACD,CAAC;AAAA,IACF;AAAA,IACA,IAAI,CAAC,OAAO,IAAI;AAAA,MACf,KAAK,MAAM,OAAO,KAAK,wBAAwB;AAAA,QAC9C,SAAS,aAAa,QAAQ,SAAS;AAAA,QACvC,QAAQ,QAAQ,OAAO;AAAA,QACvB,QAAQ,OAAO;AAAA,MAChB,CAAC;AAAA,MACD,OAAO,KAAK,aACX,SACA,QAAQ,IACR,OAAO,SACP,OAAO,WAAW,kBAAkB,OAAO,WAAW,SACnD,MACA,GACJ;AAAA,IACD;AAAA,IAEA,OAAO,KAAK,QAAQ,SAAS,OAAO,MAAM,MAAM;AAAA;AAAA,EAIjD,OAAO,CACN,SACA,MACA,QACW;AAAA,IACX,KAAK,aAAa,OAAO;AAAA,IAGzB,MAAM,OAAO,GAAG,QAAQ,aAAa,QAAO,EAAE;AAAA,IAC9C,IAAI,KAAK,OAAO,QAAQ;AAAA,MAAW,KAAK,YAAY,IAAI;AAAA,IACxD,QAAQ,IAAI,KAAK,WAAW,UAAU,IAAI,QAAQ,YAAY;AAAA,IAC9D,KAAK,OAAO,IAAI,UAAU,IAAI,GAAG;AAAA,SAC7B;AAAA,MACH,WAAW,KAAK,IAAI,IAAI,KAAK;AAAA,MAC7B,MAAM;AAAA,SACF,OAAO,YAAY,YAAY,CAAC,IAAI,EAAE,SAAS,OAAO,QAAQ;AAAA,IACnE,CAAC;AAAA,IACD,KAAK,MAAM,OAAO,KAAK,gBAAgB;AAAA,MACtC,SAAS,aAAa,QAAQ,SAAS;AAAA,MACvC,QAAQ,QAAQ,OAAO;AAAA,MACvB,QAAQ;AAAA,IACT,CAAC;AAAA,IACD,OAAO,KAAK,UAAU,QAAQ,aAAa;AAAA,MAC1C;AAAA,SACI,QAAQ,UAAU,YAAY,CAAC,IAAI,EAAE,OAAO,QAAQ,MAAM;AAAA,MAC9D,KAAK,KAAK;AAAA,IACX,CAAC;AAAA;AAAA,OAII,kBAAiB,CAAC,KAAc,IAA+B;AAAA,IACpE,IAAI,CAAC,KAAK,YAAY,KAAK,EAAE,GAAG;AAAA,MAC/B,OAAO,KAAK,WACX,KACA,mEACD;AAAA,IACD;AAAA,IACA,MAAM,SAAS,KAAK,SAAS;AAAA,IAC7B,IAAI,QAAQ,aAAa,WAAW;AAAA,MACnC,OAAO,IAAI,SAAS,aAAa,EAAE,QAAQ,IAAI,CAAC;AAAA,IACjD;AAAA,IACA,MAAM,UAAU,KAAK,WAAW,GAAG;AAAA,IACnC,IAAI,QAAQ,WAAW,WAAW;AAAA,MAEjC,OAAO,KAAK,WACX,KACA,+GACD;AAAA,IACD;AAAA,IACA,KAAK,cAAc;AAAA,IACnB,MAAM,SAAS,IAAI,IAAI,IAAI,GAAG,EAAE;AAAA,IAChC,QAAQ,WAAW,WAAW,MAAM,OAAO,SAC1C,QACA,QAAQ,IACR,CAAC,OAAO;AAAA,MACP,MAAM,IAAI,KAAK,SAAS,IAAI,EAAE;AAAA,MAC9B,OAAO,MAAM,YAAY,YAAY,KAAK,MAAM,QAAQ,EAAE,SAAS;AAAA,KAErE;AAAA,IACA,MAAM,UACL,cAAc,YAAY,YAAY,KAAK,SAAS,IAAI,SAAS;AAAA,IAClE,IAAI,YAAY,aAAa,QAAQ,aAAa,KAAK,IAAI,GAAG;AAAA,MAC7D,MAAM,UACL,OAAO,OAAO,QACX,OAAO,UACP;AAAA,MACJ,OAAO,KAAK,WAAW,KAAK,OAAO;AAAA,IACpC;AAAA,IACA,IAAI,OAAO,OAAO;AAAA,MAAM,OAAO,KAAK,QAAQ,SAAS,OAAO,MAAM,MAAM;AAAA,IACxE,MAAM,UACL,OAAO,OAAO,QAAQ,OAAO,UAAU;AAAA,IACxC,MAAM,SAAS,OAAO,OAAO,QAAQ,OAAO,SAAS;AAAA,IACrD,KAAK,MAAM,OAAO,KAAK,wBAAwB;AAAA,MAC9C,SAAS,aAAa,QAAQ,SAAS;AAAA,MACvC,QAAQ,QAAQ,OAAO;AAAA,MACvB;AAAA,IACD,CAAC;AAAA,IACD,OAAO,KAAK,aACX,SACA,QAAQ,IACR,SACA,WAAW,aAAa,MAAM,GAC/B;AAAA;AAAA,EAGD,UAAU,CAAC,UAAkD;AAAA,IAC5D,IAAI,aAAa;AAAA,MAAW;AAAA,IAC5B,MAAM,SAAS,GAAG,KAAK;AAAA,IACvB,IAAI,CAAC,SAAS,WAAW,MAAM,KAAK,CAAC,SAAS,SAAS,MAAM,GAAG;AAAA,MAC/D;AAAA,IACD;AAAA,IACA,MAAM,KAAK,SAAS,MAAM,OAAO,QAAQ,CAAC,OAAO,MAAM;AAAA,IACvD,OAAO,YAAY,EAAE,IAAI,KAAK;AAAA;AAAA,EAI/B,cAAc,CAAC,OAAiD;AAAA,IAC/D,IAAI,UAAU;AAAA,MAAW,OAAO,CAAC,KAAK;AAAA,IACtC,MAAM,YAAY,MAAM,MAAM,GAAG,EAAE,OAAO,CAAC,MAAM,MAAM,EAAE;AAAA,IACzD,IAAI,UAAU,WAAW;AAAA,MAAG,OAAO,CAAC,KAAK;AAAA,IACzC,OAAO,UAAU,SAAS,KAAK,IAAI,CAAC,KAAK,IAAI;AAAA;AAAA,EAI9C,UAAU,CAAC,KAA+C;AAAA,IACzD,MAAM,OAAO,KAAK,YAAY;AAAA,IAC9B,MAAM,SAAS,IAAI,QAAQ,IAAI,QAAQ,KAAK;AAAA,IAC5C,WAAW,QAAQ,OAAO,MAAM,GAAG,GAAG;AAAA,MACrC,OAAO,GAAG,KAAK,KAAK,KAAK,EAAE,MAAM,GAAG;AAAA,MACpC,IAAI,MAAM,QAAQ,MAAM,aAAa,sBAAsB,KAAK,CAAC,GAAG;AAAA,QACnE,OAAO,EAAE,IAAI,EAAE;AAAA,MAChB;AAAA,IACD;AAAA,IACA,MAAM,KAAK,QAAO,EAAE;AAAA,IACpB,MAAM,SAAS,KAAK,QAAQ,WAAW,QAAQ,IAAI,aAAa;AAAA,IAChE,OAAO;AAAA,MACN;AAAA,MACA,QAAQ,GAAG,QAAQ,+CAA+C,iBAAiB,OAAO;AAAA,IAC3F;AAAA;AAAA,EAGD,WAAW,GAAW;AAAA,IACrB,OAAO,KAAK,QAAQ,WAAW,QAAQ,IACpC,6BACA;AAAA;AAAA,OAGE,SAAS,CAAC,KAA2C;AAAA,IAC1D,MAAM,SAAS,OAAO,IAAI,QAAQ,IAAI,gBAAgB,KAAK,GAAG;AAAA,IAC9D,IAAI,SAAS;AAAA,MAAgB;AAAA,IAC7B,MAAM,QAAQ,MAAM,IAAI,YAAY,EAAE,MAAM,MAAM,IAAI,YAAY,CAAC,CAAC;AAAA,IACpE,IAAI,MAAM,aAAa;AAAA,MAAgB;AAAA,IACvC,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK;AAAA;AAAA,EAGtC,YAAY,CACX,SACA,WACA,OACA,SAAS,KACT,QACW;AAAA,IACX,MAAM,OAAO,IAAI,KAAK,SAAS,KAAK,aAAa;AAAA,MAChD,WAAW,GAAG,QAAQ,MAAM;AAAA,MAC5B,WAAW;AAAA,IACZ,CAAC;AAAA,IACD,MAAM,SAAS,QAAQ;AAAA,IACvB,MAAM,cAAc,WAAW,WAAW,OAAO,IAAI,eAAe,WAAW,OAAO,IAAI;AAAA,IAC1F,MAAM,SAAS,iDAAiD,WAAW,QAAQ,EAAE;AAAA,0CAC7C,WAAW,IAAI;AAAA,IACvD,MAAM,YACL,UAAU,YACP,KACA,4CAA4C,WAAW,KAAK;AAAA,IAChE,MAAM,QAAQ,WAAW,YAAY,CAAC,IAAI,EAAE,cAAc,OAAO;AAAA,IACjE,MAAM,UAAoB,CAAC,WAAW,QAAQ,WAAW,CAAC;AAAA,IAC1D,MAAM,SAAS;AAAA,IAEf,MAAM,UAAU,KAAK,MAAM,QAAQ,QAAQ,SAAS;AAAA,IACpD,IAAI,YAAY,WAAW;AAAA,MAG1B,MAAM,OAAO;AAAA,EACd;AAAA,KACG;AAAA;AAAA,2CAEsC,QAAQ;AAAA,EACjD;AAAA;AAAA;AAAA,EAGA;AAAA;AAAA;AAAA,MAGC,OAAO,KAAK,MAAM,QAAQ,uBAAuB,MAAM,SAAS,KAAK;AAAA,IACtE;AAAA,IAEA,MAAM,SAAS,KAAK,SAAS,QAAQ,KAAK;AAAA,IAC1C,IAAI,WAAW,WAAW;AAAA,MACzB,OAAO,KAAK,WACX,KACA,8CACD;AAAA,IACD;AAAA,IACA,QAAQ,KAAK,GAAI,OAAO,cAAc,KAAK,CAAC,CAAE;AAAA,IAG9C,MAAM,OACL,QAAQ,WAAW,KAChB,0CACA,wBAAwB,WAAW,QAAQ,MAAM;AAAA,IACrD,MAAM,SACL,QAAQ,YAAY,YACjB,cAAc,SACd,WAAW,WAAW,QAAQ,OAAO,iBAAiB;AAAA,IAG1D,MAAM,UAAU,WAAW,OAAO,aAAa,OAAO;AAAA,IACtD,MAAM,OAAO,OAAO,WAAW,OAAO;AAAA,uBACjB,kBAAkB;AAAA,KACpC,WAAW,OAAO,IAAI;AAAA,EACzB;AAAA,2CACyC,QAAQ;AAAA,EACjD;AAAA,EACA,OAAO,OAAO,OAAO;AAAA;AAAA;AAAA,EAGrB;AAAA;AAAA;AAAA,+DAG6D,WAAW,OAAO,QAAQ,WAAW,CAAC;AAAA,IACnG,OAAO,KAAK,MAAM,QAAQ,SAAS,MAAM,SAAS,KAAK;AAAA;AAAA,OAMlD,MAAK,CAAC,KAAc,IAA+B;AAAA,IACxD,MAAM,UAAU,EAAE,iBAAiB,YAAY,QAAQ,WAAW;AAAA,IAClE,IAAI;AAAA,MACH,IAAI,CAAC,KAAK,YAAY,KAAK,EAAE,GAAG;AAAA,QAC/B,MAAM,IAAI,WACT,KACA,2BACA,sCACD;AAAA,MACD;AAAA,MACA,MAAM,SAAS,MAAM,KAAK,YAAY,GAAG;AAAA,MACzC,MAAM,IAAI,OAAO,QAAQ;AAAA,QACxB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACD,CAAC;AAAA,MACD,IAAI,eAAe,GAAG;AAAA,QACrB,MAAM,IAAI,WACT,KACA,mBACA,GAAG,EAAE,mCACN;AAAA,MACD;AAAA,MACA,MAAM,WAAW,EAAE;AAAA,MACnB,IAAI,aAAa,WAAW;AAAA,QAC3B,MAAM,IAAI,WAAW,KAAK,mBAAmB,uBAAuB;AAAA,MACrE;AAAA,MACA,IAAI;AAAA,MACJ,IAAI,EAAE,kBAAkB,sBAAsB;AAAA,QAC7C,OAAO,MAAM,KAAK,WAAW,GAAG,QAAQ;AAAA,MACzC,EAAO,SAAI,EAAE,kBAAkB,iBAAiB;AAAA,QAC/C,OAAO,MAAM,KAAK,cAAc,GAAG,QAAQ;AAAA,MAC5C,EAAO,SAAI,EAAE,kBAAkB,WAAW;AAAA,QACzC,MAAM,IAAI,WAAW,KAAK,mBAAmB,wBAAwB;AAAA,MACtE,EAAO;AAAA,QACN,MAAM,IAAI,WACT,KACA,0BACA,yDACD;AAAA;AAAA,MAED,OAAO,KAAK,MAAM,KAAK,MAAM,OAAO;AAAA,MACnC,OAAO,OAAO;AAAA,MACf,OAAO,KAAK,oBAAoB,OAAO,OAAO;AAAA;AAAA;AAAA,EAIhD,mBAAmB,CAClB,OACA,SACW;AAAA,IACX,IAAI,iBAAiB,YAAY;AAAA,MAChC,MAAM,QAAgC,KAAK,QAAQ;AAAA,MACnD,IAAI,MAAM,WAAW;AAAA,QACpB,MAAM,sBAAsB;AAAA,MAC7B,IAAI,MAAM,WAAW,OAAO,MAAM,WAAW;AAAA,QAC5C,MAAM,iBAAiB;AAAA,MACxB,OAAO,KAAK,MACX,MAAM,QACN,EAAE,OAAO,MAAM,MAAM,mBAAmB,MAAM,QAAQ,GACtD,KACD;AAAA,IACD;AAAA,IACA,KAAK,MAAM,OAAO,MAAM,eAAe;AAAA,MACtC,SAAS,iBAAiB,QAAQ,MAAM,OAAO;AAAA,IAChD,CAAC;AAAA,IACD,OAAO,KAAK,MACX,KACA;AAAA,MACC,OAAO;AAAA,MACP,mBAAmB;AAAA,IACpB,GACA,KAAK,SAAS,eAAe,KAAK,CACnC;AAAA;AAAA,OAIK,WAAW,CAAC,KAAwC;AAAA,IACzD,MAAM,QAAQ,IAAI,QAAQ,IAAI,cAAc,KAAK,IAAI,MAAM,GAAG,EAAE,IAAI,KAAK;AAAA,IACzE,IAAI,SAAS,qCAAqC;AAAA,MACjD,MAAM,IAAI,WACT,KACA,mBACA,oDACD;AAAA,IACD;AAAA,IACA,IAAI,IAAI,QAAQ,IAAI,eAAe,MAAM,MAAM;AAAA,MAE9C,MAAM,IAAI,WACT,KACA,kBACA,0EACD;AAAA,IACD;AAAA,IACA,MAAM,OAAO,MAAM,KAAK,UAAU,GAAG;AAAA,IACrC,IAAI,SAAS,WAAW;AAAA,MACvB,MAAM,IAAI,WAAW,KAAK,mBAAmB,0BAA0B;AAAA,IACxE;AAAA,IACA,MAAM,SAAS,IAAI,gBAAgB,IAAI;AAAA,IACvC,IAAI,OAAO,IAAI,eAAe,KAAK,OAAO,IAAI,kBAAkB,GAAG;AAAA,MAClE,MAAM,IAAI,WACT,KACA,kBACA,0EACD;AAAA,IACD;AAAA,IACA,OAAO;AAAA;AAAA,OAGF,UAAU,CACf,GACA,UACmC;AAAA,IACnC,MAAM,OAAO,EAAE;AAAA,IACf,MAAM,cAAc,EAAE;AAAA,IACtB,MAAM,WAAW,EAAE;AAAA,IACnB,IACC,SAAS,aACT,gBAAgB,aAChB,aAAa,WACZ;AAAA,MACD,MAAM,IAAI,WACT,KACA,mBACA,mDACD;AAAA,IACD;AAAA,IACA,MAAM,MAAM,UAAU,IAAI;AAAA,IAC1B,MAAM,SAAS,KAAK,OAAO,IAAI,GAAG;AAAA,IAClC,MAAM,UAAU,CAAC,QAAgB,IAAI,WAAW,KAAK,iBAAiB,GAAG;AAAA,IACzE,IAAI,WAAW;AAAA,MAAW,MAAM,QAAQ,uBAAuB;AAAA,IAC/D,IAAI,OAAO,MAAM;AAAA,MAEhB,IAAI,OAAO,YAAY,WAAW;AAAA,QACjC,MAAM,KAAK,aACV,OAAO,WACP,OAAO,SACP,gBACD;AAAA,MACD;AAAA,MACA,MAAM,QAAQ,2BAA2B;AAAA,IAC1C;AAAA,IACA,OAAO,OAAO;AAAA,IACd,IAAI,OAAO,aAAa,KAAK,IAAI;AAAA,MAAG,MAAM,QAAQ,sBAAsB;AAAA,IACxE,IAAI,CAAC,kBAAkB,UAAU,OAAO,OAAO,QAAQ,GAAG;AAAA,MACzD,MAAM,QAAQ,uCAAuC;AAAA,IACtD;AAAA,IACA,IAAI,gBAAgB,OAAO,aAAa;AAAA,MACvC,MAAM,QAAQ,uDAAuD;AAAA,IACtE;AAAA,IACA,IAAI,EAAE,gBAAgB,aAAa,EAAE,gBAAgB,OAAO,UAAU;AAAA,MACrE,MAAM,IAAI,WACT,KACA,kBACA,mDACD;AAAA,IACD;AAAA,IACA,IACC,CAAC,SAAS,KAAK,QAAQ,KACvB,CAAC,kBAAkB,MAAK,QAAQ,GAAG,OAAO,aAAa,GACtD;AAAA,MACD,MAAM,QAAQ,iDAAiD;AAAA,IAChE;AAAA,IAGA,IACC,OAAO,YAAY,aACnB,KAAK,MAAM,QAAQ,OAAO,SAAS,GAAG,aAAa,OAAO,SACzD;AAAA,MACD,MAAM,QAAQ,uCAAuC;AAAA,IACtD;AAAA,IAEA,MAAM,MAAM,KAAK,IAAI;AAAA,IACrB,MAAM,UAAU,MAAM,GAAG;AAAA,IACzB,OAAO,UAAU;AAAA,IACjB,MAAM,SAAS,KAAK,MAAM;AAAA,IAC1B,MAAM,SAAS,MAAM,eACpB,KAAK,MAAM,OACX;AAAA,MACC;AAAA,MACA,WAAW,OAAO;AAAA,MAClB,UAAU,OAAO,OAAO;AAAA,MACxB,YAAY,OAAO,OAAO;AAAA,MAC1B,QAAQ,OAAO;AAAA,MACf,gBAAgB;AAAA,SACZ,OAAO,YAAY,YAAY,CAAC,IAAI,EAAE,SAAS,OAAO,QAAQ;AAAA,IACnE,GACA;AAAA,MACC,aAAa,OAAO;AAAA,MACpB,cAAc,OAAO;AAAA,MACrB,aAAa,MAAM,OAAO;AAAA,MAC1B;AAAA,IACD,CACD;AAAA,IACA,IAAI,WAAW,WAAW;AAAA,MAEzB,MAAM,QAAQ,4BAA4B;AAAA,IAC3C;AAAA,IACA,KAAK,MAAM,OAAO,KAAK,uBAAuB;AAAA,MAC7C,SAAS,aAAa,OAAO,SAAS;AAAA,MACtC,QAAQ,OAAO,OAAO;AAAA,IACvB,CAAC;AAAA,IACD,KAAK,MAAM,WAAW,OAAO,WAAW;AAAA,MACvC;AAAA,MACA,QAAQ;AAAA,QACP,IAAI,OAAO,OAAO;AAAA,QAClB,MAAM,OAAO,OAAO;AAAA,QACpB,MAAM,OAAO,OAAO;AAAA,MACrB;AAAA,MACA,WAAW,IAAI,KAAK,GAAG,EAAE,YAAY;AAAA,IACtC,CAAC;AAAA,IACD,OAAO,KAAK,WAAW,QAAQ,OAAO,MAAM;AAAA;AAAA,EAG7C,UAAU,CACT,QACA,QAC0B;AAAA,IAC1B,OAAO;AAAA,MACN,cAAc,OAAO;AAAA,MACrB,YAAY;AAAA,MACZ,YAAY,OAAO;AAAA,MACnB,eAAe,OAAO;AAAA,MACtB,OAAO,OAAO,KAAK,GAAG;AAAA,IACvB;AAAA;AAAA,OAGK,aAAa,CAClB,GACA,UACmC;AAAA,IACnC,MAAM,QAAQ,EAAE;AAAA,IAChB,IAAI,UAAU,WAAW;AAAA,MACxB,MAAM,IAAI,WAAW,KAAK,mBAAmB,2BAA2B;AAAA,IACzE;AAAA,IACA,MAAM,UAAU,CAAC,QAAgB,IAAI,WAAW,KAAK,iBAAiB,GAAG;AAAA,IACzE,MAAM,OAAO,UAAU,KAAK;AAAA,IAC5B,MAAM,SAAS,MAAM,KAAK,MAAM,MAAM,IAAI,IAAI;AAAA,IAC9C,IAAI,WAAW,aAAa,OAAO,SAAS,WAAW;AAAA,MACtD,MAAM,QAAQ,gCAAgC;AAAA,IAC/C;AAAA,IACA,IAAI,CAAC,kBAAkB,UAAU,OAAO,QAAQ,GAAG;AAAA,MAClD,MAAM,QAAQ,gDAAgD;AAAA,IAC/D;AAAA,IACA,MAAM,MAAM,KAAK,IAAI;AAAA,IACrB,IAAI,OAAO,aAAa;AAAA,MAAK,MAAM,QAAQ,+BAA+B;AAAA,IAC1E,IAAI,OAAO,WAAW,WAAW;AAAA,MAChC,MAAM,KAAK,eAAe,MAAM;AAAA,MAChC,MAAM,QACL,gEACD;AAAA,IACD;AAAA,IACA,IACC,EAAE,gBAAgB,aAClB,EAAE,gBAAgB,GAAG,KAAK,aAAa,OAAO,iBAC7C;AAAA,MACD,MAAM,IAAI,WACT,KACA,kBACA,mDACD;AAAA,IACD;AAAA,IACA,MAAM,QAAQ,EAAE;AAAA,IAChB,IAAI,UAAU,WAAW;AAAA,MACxB,MAAM,SAAS,MAAM,MAAM,GAAG,EAAE,OAAO,CAAC,MAAM,MAAM,EAAE;AAAA,MACtD,IAAI,CAAC,OAAO,MAAM,CAAC,MAAM,OAAO,OAAO,SAAS,CAAC,CAAC,GAAG;AAAA,QACpD,MAAM,IAAI,WAAW,KAAK,iBAAiB,yBAAyB;AAAA,MACrE;AAAA,IACD;AAAA,IACA,IAAI,CAAC,KAAK,mBAAmB,KAAK,OAAO,SAAS,GAAG,GAAG;AAAA,MACvD,MAAM,IAAI,WACT,KACA,2BACA,+DACD;AAAA,IACD;AAAA,IAGA,IACC,CAAE,MAAM,KAAK,MAAM,MAAM,SACxB,MACA,KACA,MAAM,uBACP,GACC;AAAA,MACD,MAAM,KAAK,eAAe,MAAM;AAAA,MAChC,MAAM,QACL,gEACD;AAAA,IACD;AAAA,IACA,MAAM,SAAS,MAAM,eACpB,KAAK,MAAM,OACX;AAAA,MACC,SAAS,OAAO;AAAA,MAChB,WAAW,OAAO;AAAA,MAClB,UAAU,OAAO;AAAA,MACjB,YAAY,OAAO;AAAA,MACnB,QAAQ,OAAO;AAAA,MACf,gBAAgB,OAAO;AAAA,SACnB,OAAO,YAAY,YAAY,CAAC,IAAI,EAAE,SAAS,OAAO,QAAQ;AAAA,IACnE,GACA;AAAA,MACC,aAAa,KAAK,MAAM,OAAO;AAAA,MAC/B,cAAc,KAAK,MAAM,OAAO;AAAA,MAEhC,aAAa,OAAO,iBAAiB,KAAK,MAAM,OAAO;AAAA,MACvD;AAAA,IACD,CACD;AAAA,IACA,IAAI,WAAW,WAAW;AAAA,MAEzB,MAAM,QAAQ,4BAA4B;AAAA,IAC3C;AAAA,IACA,KAAK,MAAM,OAAO,MAAM,mBAAmB;AAAA,MAC1C,SAAS,aAAa,OAAO,SAAS;AAAA,MACtC,QAAQ,OAAO,OAAO,QAAQ;AAAA,IAC/B,CAAC;AAAA,IACD,OAAO,KAAK,WAAW,QAAQ,OAAO,MAAM;AAAA;AAAA,OAGvC,cAAc,CAAC,QAAoC;AAAA,IACxD,KAAK,MAAM,OAAO,KAAK,uBAAuB;AAAA,MAC7C,SAAS,aAAa,OAAO,SAAS;AAAA,MACtC,QAAQ,OAAO,OAAO,QAAQ;AAAA,IAC/B,CAAC;AAAA,IACD,MAAM,KAAK,aAAa,OAAO,WAAW,OAAO,SAAS,gBAAgB;AAAA;AAAA,OAGrE,YAAY,CACjB,WACA,SACA,QACgB;AAAA,IAChB,MAAM,MAAM,KAAK,IAAI;AAAA,IACrB,MAAM,IAAI,MAAM,KAAK,MAAM,MAAM,OAChC,EAAE,QAAQ,GACV,EAAE,KAAK,WAAW,MAAM,KAAK,MAAM,OAAO,gBAAgB,CAC3D;AAAA,IACA,IAAI,IAAI;AAAA,MAAG,KAAK,MAAM,aAAa,WAAW,SAAS,MAAM;AAAA;AAAA,OAMxD,OAAM,CAAC,KAAc,IAA+B;AAAA,IACzD,MAAM,UAAU,EAAE,iBAAiB,WAAW;AAAA,IAC9C,IAAI;AAAA,MACH,IAAI,CAAC,KAAK,YAAY,KAAK,EAAE,GAAG;AAAA,QAC/B,MAAM,IAAI,WACT,KACA,2BACA,sCACD;AAAA,MACD;AAAA,MACA,MAAM,SAAS,MAAM,KAAK,YAAY,GAAG;AAAA,MACzC,MAAM,IAAI,OAAO,QAAQ,CAAC,SAAS,aAAa,iBAAiB,CAAC;AAAA,MAClE,IAAI,eAAe,GAAG;AAAA,QACrB,MAAM,IAAI,WACT,KACA,mBACA,GAAG,EAAE,mCACN;AAAA,MACD;AAAA,MACA,MAAM,QAAQ,EAAE;AAAA,MAChB,MAAM,WAAW,EAAE;AAAA,MACnB,IAAI,UAAU,aAAa,aAAa,WAAW;AAAA,QAClD,MAAM,IAAI,WACT,KACA,mBACA,kCACD;AAAA,MACD;AAAA,MACA,MAAM,SAAS,MAAM,KAAK,MAAM,MAAM,IAAI,UAAU,KAAK,CAAC;AAAA,MAE1D,IAAI,WAAW;AAAA,QACd,OAAO,IAAI,SAAS,MAAM;AAAA,UACzB,QAAQ;AAAA,UACR,SAAS,KAAK,KAAK,MAAM,MAAM,QAAQ;AAAA,QACxC,CAAC;AAAA,MACF,IAAI,CAAC,kBAAkB,UAAU,OAAO,QAAQ,GAAG;AAAA,QAClD,MAAM,IAAI,WACT,KACA,kBACA,wCACD;AAAA,MACD;AAAA,MAEA,MAAM,KAAK,aAAa,OAAO,WAAW,OAAO,SAAS,SAAS;AAAA,MACnE,KAAK,MAAM,OAAO,KAAK,iBAAiB;AAAA,QACvC,SAAS,aAAa,OAAO,SAAS;AAAA,QACtC,QAAQ,OAAO,OAAO,QAAQ;AAAA,QAC9B,IAAI;AAAA,MACL,CAAC;AAAA,MACD,OAAO,IAAI,SAAS,MAAM;AAAA,QACzB,QAAQ;AAAA,QACR,SAAS,KAAK,KAAK,MAAM,MAAM,QAAQ;AAAA,MACxC,CAAC;AAAA,MACA,OAAO,OAAO;AAAA,MACf,OAAO,KAAK,oBAAoB,OAAO,OAAO;AAAA;AAAA;AAAA,EAOhD,aAAa,GAAS;AAAA,IACrB,MAAM,MAAM,KAAK,IAAI;AAAA,IACrB,WAAW,KAAK,KAAK,SAAS,OAAO,GAAG;AAAA,MACvC,IAAI,EAAE,YAAY;AAAA,QAAK;AAAA,MACvB,KAAK,aAAa,CAAC;AAAA,IACpB;AAAA;AAAA,EAGD,WAAW,CAAC,QAAQ,OAAa;AAAA,IAChC,MAAM,MAAM,KAAK,IAAI;AAAA,IAErB,YAAY,KAAK,MAAM,KAAK,QAAQ;AAAA,MACnC,IAAI,EAAE,aAAa;AAAA,QAAK,KAAK,OAAO,OAAO,GAAG;AAAA,IAC/C;AAAA,IACA,IAAI,SAAS,KAAK,OAAO,QAAQ,WAAW;AAAA,MAC3C,MAAM,OAAO,KAAK,OAAO,OAAO,YAAY;AAAA,MAC5C,WAAW,OAAO,CAAC,GAAG,KAAK,OAAO,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG;AAAA,QACzD,KAAK,OAAO,OAAO,GAAG;AAAA,MACvB;AAAA,IACD;AAAA;AAAA,EAID,KAAK,GAAS;AAAA,IACb,KAAK,cAAc;AAAA,IACnB,KAAK,YAAY;AAAA,IACjB,MAAM,MAAM,KAAK,IAAI;AAAA,IACrB,KAAK,YAAY,MAAM,GAAG;AAAA,IAC1B,KAAK,eAAe,MAAM,GAAG;AAAA,IAC7B,KAAK,qBAAqB,MAAM,GAAG;AAAA,IACnC,KAAK,mBAAmB,MAAM,GAAG;AAAA,IACjC,KAAK,YAAY,MAAM,GAAG;AAAA,IAC1B,KAAK,mBAAmB,MAAM,GAAG;AAAA;AAEnC;;;AOj3CO,SAAS,QAAQ,CAAC,QAA0C;AAAA,EAClE,OAAO;AAAA,IACN,iBAAiB,OAAO;AAAA,IACxB,cAAc,OAAO;AAAA,IACrB,kBAAkB,OAAO;AAAA,IACzB,eAAe,OAAO;AAAA,IACtB,aAAa,OAAO;AAAA,IACpB,aAAa,OAAO;AAAA,IACpB,uBAAuB,OAAO;AAAA,EAC/B;AAAA;AAGD,SAAS,UAAU,CAAC,UAA0B;AAAA,EAC7C,IAAI;AAAA,IACH,OAAO,IAAI,IAAI,QAAQ,EAAE;AAAA,IACxB,MAAM;AAAA,IACP,OAAO;AAAA;AAAA;AAQT,SAAS,OAAO,CAAC,MAAkC;AAAA,EAClD,OAAO,8BAA8B,KAAK,KAAK,MAAM,GAAG,GAAG,CAAC,IAAI;AAAA;AAAA;AAI1D,MAAM,WAAW;AAAA,EACd,YAAoB,MAAM,GAAG;AAAA,EAC7B;AAAA,EACA;AAAA,EAEA;AAAA,EACA,WAAmB,KAAK,IAAI;AAAA,EAK5B;AAAA,EAET;AAAA,EAEA;AAAA,EAES;AAAA,EAKT;AAAA,EAKA,oBAAoB;AAAA,EACX,UAAiC,IAAI;AAAA,EAErC,gBAAgB,IAAI;AAAA,EAEpB;AAAA,EACA;AAAA,EACT,SAA8C;AAAA,EAE9C,cAAc;AAAA,EACd,iBAAgC,QAAQ,QAAQ;AAAA,EAChD,iBAAiB,KAAK,IAAI;AAAA,EAC1B,eAAe;AAAA,EACf,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EAEA,WAAW,CACV,IACA,IACA,QACA,MACA,MACA,iBACC;AAAA,IACD,KAAK,MAAM;AAAA,IACX,KAAK,KAAK;AAAA,IACV,KAAK,SAAS;AAAA,IACd,KAAK,OAAO;AAAA,IACZ,KAAK,QAAQ;AAAA,IACb,KAAK,kBAAkB;AAAA,IACvB,KAAK,QAAQ,IAAI,aAChB,CAAC,MAAM,cAAc;AAAA,MACpB,KAAK,KAAK;AAAA,QACT,MAAM;AAAA,QACN;AAAA,QACA,WAAW,IAAI,KAAK,SAAS,EAAE,YAAY;AAAA,MAC5C,CAAC;AAAA,OAEF,KAAK,qBAAqB,YACvB,CAAC,IACD,EAAE,OAAO,KAAK,iBAAiB,CACnC;AAAA,IACA,KAAK,cAAc,WAAW,MAAM;AAAA,MACnC,IAAI,KAAK,WAAW,OAAO;AAAA,QAC1B,KAAK,eAAe,eAAe,kBAAkB;AAAA,MACtD;AAAA,OACE,KAAK,OAAO,cAAc;AAAA;AAAA,MAG1B,KAAK,GAAY;AAAA,IACpB,OAAO,KAAK,WAAW;AAAA;AAAA,MAIpB,WAAW,GAAY;AAAA,IAC1B,OAAO,KAAK,KAAK,YAAY,SAAS,KAAK,MAAM,SAAS,KAAK;AAAA;AAAA,MAI5D,MAAM,GAAe;AAAA,IACxB,OAAO,KAAK,KAAK;AAAA;AAAA,EAIlB,IAAI,CAAC,SAAgC;AAAA,IACpC,IAAI,KAAK,WAAW;AAAA,MAAS,OAAO;AAAA,IACpC,IAAI;AAAA,IACJ,IAAI;AAAA,MACH,OAAO,KAAK,IAAI,KAAK,KAAK,UAAU,OAAO,CAAC;AAAA,MAC3C,MAAM;AAAA,MACP,OAAO;AAAA;AAAA,IAER,IAAI,SAAS,GAAG;AAAA,MACf,KAAK,MAAM,OAAO,KAAK,oBAAoB;AAAA,QAC1C,SAAS,KAAK;AAAA,QACd,MAAM,QAAQ;AAAA,MACf,CAAC;AAAA,MACD,OAAO;AAAA,IACR;AAAA,IACA,OAAO;AAAA;AAAA,EAIR,WAAW,CAAC,MAAiC;AAAA,IAC5C,IAAI,KAAK,WAAW;AAAA,MAAS;AAAA,IAC7B,IAAI,OAAO,SAAS,UAAU;AAAA,MAC7B,KAAK,eAAe,eAAe,+BAA+B;AAAA,MAClE;AAAA,IACD;AAAA,IAGA,IAAI,OAAO,WAAW,IAAI,IAAI,KAAK,OAAO,iBAAiB;AAAA,MAC1D,MAAM,KAAK,QAAQ,IAAI;AAAA,MACvB,KAAK,WAAW,aAAa,mCAAmC,EAAE;AAAA,MAClE,MAAM,WAAW,OAAO,YAAY,YAAY,KAAK,QAAQ,IAAI,EAAE;AAAA,MACnE,UAAU,KACT,KACA,eAAe,UACf,+CACA,IACD;AAAA,MACA;AAAA,IACD;AAAA,IACA,MAAM,SAAS,gBAAgB,IAAI;AAAA,IACnC,IAAI,CAAC,OAAO,IAAI;AAAA,MACf,IAAI,KAAK,WAAW,OAAO;AAAA,QAC1B,KAAK,eAAe,eAAe,OAAO,KAAK;AAAA,QAC/C;AAAA,MACD;AAAA,MACA,KAAK,WAAW,eAAe,OAAO,OAAO,OAAO,EAAE;AAAA,MAEtD,MAAM,WACL,OAAO,OAAO,YAAY,YAAY,KAAK,QAAQ,IAAI,OAAO,EAAE;AAAA,MACjE,UAAU,KACT,KACA,eAAe,aACf,sCACA,IACD;AAAA,MACA;AAAA,IACD;AAAA,IACA,IAAI,aAAa,QAAQ;AAAA,MACxB,IAAI,KAAK,WAAW,OAAO;AAAA,QAC1B,KAAK,eAAe,eAAe,gBAAgB;AAAA,MACpD,EAAO,SAAI,OAAO,OAAO,WAAW;AAAA,QACnC,KAAK,WACJ,gBACA,gBAAgB,OAAO,QACvB,OAAO,EACR;AAAA,MACD;AAAA,MACA;AAAA,IACD;AAAA,IAGA,KAAK,QAAQ,OAAO,OAAO,EAAE,MAAM,CAAC,UAAmB;AAAA,MACtD,KAAK,MAAM,OAAO,MAAM,qBAAqB;AAAA,QAC5C,SAAS,KAAK;AAAA,QACd,MAAM,OAAO,QAAQ;AAAA,QACrB,SAAS,iBAAiB,QAAQ,MAAM,OAAO;AAAA,MAChD,CAAC;AAAA,MACD,KAAK,WAAW,eAAe,yCAAyC;AAAA,KACxE;AAAA;AAAA,OAGI,OAAO,CAAC,KAAgC;AAAA,IAC7C,IAAI,KAAK,WAAW,OAAO;AAAA,MAC1B,IAAI,IAAI,SAAS,SAAS;AAAA,QACzB,KAAK,eAAe,eAAe,gBAAgB;AAAA,QACnD;AAAA,MACD;AAAA,MACA,MAAM,KAAK,OACV,IAAI,QACJ,IAAI,SACJ,IAAI,KAAK,MACT,IAAI,cAAc,IACnB;AAAA,MACA;AAAA,IACD;AAAA,IACA,IAAI,KAAK,WAAW;AAAA,MAAS;AAAA,IAC7B,QAAQ,IAAI;AAAA,WACN;AAAA,QACJ,KAAK,WAAW,eAAe,wBAAwB;AAAA,QACvD;AAAA,WACI;AAAA,QACJ,KAAK,eAAe;AAAA,QACpB;AAAA,WACI;AAAA,QACJ,KAAK,IAAI,UAAU,QAAQ,KAAK;AAAA,QAChC;AAAA,WACI;AAAA,QACJ,IAAI,KAAK,KAAK,YAAY;AAAA,UAAQ,KAAK,MAAM,MAAM;AAAA,QAC9C;AAAA,eAAK,cAAc;AAAA,QACxB;AAAA,WACI;AAAA,QACJ,KAAK,MAAM,KAAK;AAAA,QAChB,KAAK,cAAc;AAAA,QACnB;AAAA,WACI;AAAA,QACJ,MAAM,KAAK,gBAAgB,MAC1B,KAAK,MAAM,aAAa,MAAM,IAAI,WAAW,IAAI,KAAK,CACvD;AAAA,QACA;AAAA,WACI;AAAA,QACJ,MAAM,KAAK,gBAAgB,MAAM,KAAK,MAAM,QAAQ,IAAI,CAAC;AAAA,QACzD;AAAA,WACI;AAAA,QACJ,IAAI,CAAE,MAAM,KAAK,MAAM,YAAY,MAAM,IAAI,OAAO,GAAI;AAAA,UACvD,KAAK,WAAW,cAAc,eAAe;AAAA,QAC9C;AAAA,QACA;AAAA,WACI;AAAA,QACJ,MAAM,KAAK,MAAM,UAAU,IAAI;AAAA,QAC/B;AAAA,WACI;AAAA,QACJ,KAAK,MAAM,OAAO,MAAM,aAAa;AAAA,UACpC,SAAS,KAAK;AAAA,UACd,MAAM,IAAI;AAAA,QACX,CAAC;AAAA,QACD;AAAA,WACI;AAAA,WACA;AAAA,WACA;AAAA,WACA,qBAAqB;AAAA,QACzB,MAAM,WAAW,KAAK,QAAQ,IAAI,IAAI,EAAE;AAAA,QACxC,IAAI,aAAa;AAAA,UAAW;AAAA,QAC5B,IAAI,IAAI,SAAS;AAAA,UAAiB,SAAS,WAAW,GAAG;AAAA,QACpD,SAAI,IAAI,SAAS;AAAA,UAAuB,SAAS,QAAQ,GAAG;AAAA,QAC5D,SAAI,IAAI,SAAS;AAAA,UAAuB,SAAS,QAAQ,IAAI,IAAI;AAAA,QACjE;AAAA,mBAAS,MAAM;AAAA,QACpB,IAAI,SAAS,sBAAsB,WAAW;AAAA,UAC7C,KAAK,WAAW,eAAe,SAAS,mBAAmB,IAAI,EAAE;AAAA,QAClE;AAAA,QACA;AAAA,MACD;AAAA;AAAA;AAAA,OAII,MAAM,CACX,QACA,SACA,SACA,YAAY,OACI;AAAA,IAChB,IAAI,CAAC,mBAAmB,MAAM,GAAG;AAAA,MAChC,KAAK,eACJ,eACA,wCACD;AAAA,MACA;AAAA,IACD;AAAA,IACA,MAAM,YAAY,oBAAoB,MAAM;AAAA,IAC5C,IACC,KAAK,oBAAoB,aACzB,KAAK,oBAAoB,WACxB;AAAA,MAID,KAAK,MAAM,OAAO,KAAK,eAAe,EAAE,QAAQ,mBAAmB,CAAC;AAAA,MACpE,KAAK,WACJ,oBACA,wDACD;AAAA,MACA,KAAK,IAAI,UAAU,iBAAiB,kBAAkB;AAAA,MACtD;AAAA,IACD;AAAA,IACA,aAAa,KAAK,WAAW;AAAA,IAC7B,KAAK,SAAS;AAAA,IACd,KAAK,YAAY;AAAA,IACjB,KAAK,UAAU,KAAK,KAAK,QAAQ;AAAA,IACjC,MAAM,WAAW,KAAK,MAAM,aAAa,IAAI;AAAA,IAC7C,IAAI,aAAa,WAAW;AAAA,MAC3B,SAAS,IACR,UAAU,UACV,+BACA,UACD;AAAA,IACD;AAAA,IACA,IAAI,WAAW;AAAA,MAId,IAAI;AAAA,QACH,MAAM,KAAK,MAAM,UAAU,IAAI;AAAA,QAC9B,OAAO,OAAO;AAAA,QACf,KAAK,MAAM,OAAO,MAAM,eAAe;AAAA,UACtC,IAAI;AAAA,UACJ,OAAO,UAAU,KAAK;AAAA,QACvB,CAAC;AAAA,QACD,KAAK,IAAI,UAAU,iBAAiB,6BAA6B;AAAA,QACjE;AAAA;AAAA,IAEF;AAAA,IAEA,IAAI,SAAsB,CAAC;AAAA,IAC3B,IAAI;AAAA,MACH,MAAM,OAAO,MAAM,KAAK,MAAM,MAAM,WACnC,KAAK,WACL,KAAK,IAAI,CACV;AAAA,MACA,SAAS,KAAK,IAAI,CAAC,OAAO;AAAA,QACzB,SAAS,EAAE;AAAA,QACX,QAAQ;AAAA,UACP,IAAI,EAAE;AAAA,UACN,MAAM,EAAE;AAAA,UACR,MAAM,WAAW,EAAE,QAAQ;AAAA,QAC5B;AAAA,QACA,WAAW,IAAI,KAAK,EAAE,SAAS,EAAE,YAAY;AAAA,MAC9C,EAAE;AAAA,MACD,OAAO,OAAO;AAAA,MACf,KAAK,MAAM,OAAO,MAAM,eAAe;AAAA,QACtC,IAAI;AAAA,QACJ,OAAO,UAAU,KAAK;AAAA,MACvB,CAAC;AAAA;AAAA,IAEF,IAAI,KAAK,WAAW;AAAA,MAAS;AAAA,IAE7B,MAAM,SAAS,KAAK;AAAA,IACpB,MAAM,YAAY,KAAK,WAAW,OAAO;AAAA,IACzC,KAAK,SAAS;AAAA,IACd,MAAM,OAAO,KAAK,KAAK;AAAA,MACtB,MAAM;AAAA,MACN,WAAW,KAAK;AAAA,MAChB,SAAS,GAAG,KAAK,MAAM,UAAU,OAAO,KAAK;AAAA,MAC7C,QAAQ,KAAK;AAAA,SACT,KAAK,YAAY,YAAY,CAAC,IAAI,EAAE,SAAS,KAAK,QAAQ;AAAA,MAC9D,SAAS,KAAK,KAAK;AAAA,MACnB,WAAW,IAAI,KAAK,SAAS,EAAE,YAAY;AAAA,MAC3C,QAAQ,SAAS,MAAM;AAAA,MACvB;AAAA,IACD,CAAC;AAAA,IACD,IAAI,CAAC,MAAM;AAAA,MACV,KAAK,IAAI,UAAU,iBAAiB,aAAa;AAAA,MACjD;AAAA,IACD;AAAA,IACA,KAAK,kBAAkB,YAAY,MAAM,KAAK,MAAM,GAAG,OAAO,WAAW;AAAA,IACzE,KAAK,iBAAiB,WACrB,MACC,KAAK,IACJ,UAAU,gBACV,4BACA,SACD,GACD,KAAK,IAAI,GAAG,YAAY,KAAK,IAAI,CAAC,CACnC;AAAA,IACA,KAAK,MAAM,OAAO,KAAK,eAAe;AAAA,MACrC,SAAS,KAAK;AAAA,MACd,SAAS,aAAa,KAAK,SAAS;AAAA,MACpC,QAAQ,KAAK;AAAA,MACb,SAAS,GAAG,QAAQ,QAAQ,QAAQ;AAAA,MACpC,UAAU,aAAa;AAAA,IACxB,CAAC;AAAA,IACD,KAAK,MAAM,MAAM,IAAI;AAAA;AAAA,EAQtB,eAAe,CAAC,KAAyC;AAAA,IACxD,MAAM,OAAO,KAAK,eAAe,KAAK,GAAG;AAAA,IACzC,KAAK,iBAAiB,KAAK,MAAM,MAAM,EAAE;AAAA,IACzC,OAAO;AAAA;AAAA,EAGR,KAAK,GAAS;AAAA,IACb,IAAI,KAAK,WAAW;AAAA,MAAS;AAAA,IAC7B,IAAI,KAAK,gBAAgB,GAAG;AAAA,MAC3B,KAAK,IAAI,UAAU,eAAe,gBAAgB;AAAA,MAClD;AAAA,IACD;AAAA,IAIA,IACC,KAAK,QAAQ,SAAS,KACtB,KAAK,IAAI,IAAI,KAAK,kBAAkB,KAAK,OAAO,eAC/C;AAAA,MACD,KAAK,IAAI,UAAU,aAAa,QAAQ,MAAM;AAAA,MAC9C;AAAA,IACD;AAAA,IACA,KAAK;AAAA,IACL,KAAK,KAAK,EAAE,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE,CAAC;AAAA;AAAA,EAI1C,aAAa,CAAC,SAAyB;AAAA,IACtC,IAAI,IAAI;AAAA,IACR,WAAW,KAAK,KAAK,cAAc,OAAO;AAAA,MAAG,IAAI,MAAM;AAAA,QAAS;AAAA,IAChE,OAAO;AAAA;AAAA,EAIR,OAAO,CAAC,OAA+B;AAAA,IACtC,KAAK,iBAAiB,KAAK,IAAI;AAAA,IAC/B,MAAM,KAAK,IAAI,EAAE,KAAK;AAAA,IACtB,MAAM,SAAS,KAAK;AAAA,IACpB,MAAM,WAAW,IAAI,SAAS;AAAA,MAC7B;AAAA,MACA,OAAO,MAAM;AAAA,MACb,UAAU,MAAM;AAAA,MAChB,kBAAkB,OAAO;AAAA,MACzB,aAAa,OAAO;AAAA,MACpB,cAAc,SAAS,MAAM,EAAE;AAAA,MAC/B,cAAc,MAAM;AAAA,MACpB,QAAQ,CAAC,WAAW;AAAA,QACnB,IAAI,CAAC,KAAK,KAAK,EAAE,MAAM,eAAe,IAAI,OAAO,CAAC,GAAG;AAAA,UACpD,KAAK,MAAM,OAAO,MAAM,uBAAuB;AAAA,YAC9C,SAAS,KAAK;AAAA,UACf,CAAC;AAAA,QACF;AAAA;AAAA,MAED,QAAQ,CAAC,MAAM;AAAA,QACd,KAAK,QAAQ,OAAO,EAAE;AAAA,QACtB,KAAK,cAAc,OAAO,EAAE;AAAA,QAC5B,KAAK,iBAAiB,KAAK,IAAI;AAAA,QAC/B,MAAM,OAAO,CAAC;AAAA;AAAA,SAEX,MAAM,aAAa,YAAY,CAAC,IAAI,EAAE,UAAU,MAAM,SAAS;AAAA,IACpE,CAAC;AAAA,IACD,KAAK,QAAQ,IAAI,IAAI,QAAQ;AAAA,IAC7B,IAAI,MAAM;AAAA,MAAU,KAAK,cAAc,IAAI,IAAI,MAAM,MAAM,OAAO;AAAA,IAClE,MAAM,OAAO,KAAK,KAAK;AAAA,MACtB,MAAM;AAAA,MACN;AAAA,MACA,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS,MAAM;AAAA,MACf,MAAM,MAAM;AAAA,MACZ,OAAO,MAAM;AAAA,IACd,CAAC;AAAA,IACD,IAAI,CAAC,MAAM;AAAA,MACV,SAAS,KACR,KACA,eAAe,YACf,wDACA,KACD;AAAA,IACD;AAAA,IACA,OAAO;AAAA;AAAA,EAIR,GAAG,CAAC,MAAc,QAAgB,KAAuB;AAAA,IACxD,IAAI,KAAK,WAAW;AAAA,MAAS;AAAA,IAC7B,IAAI,QAAQ;AAAA,MAAW,KAAK,KAAK,EAAE,MAAM,OAAO,QAAQ,IAAI,CAAC;AAAA,IAC7D,KAAK,SAAS,MAAM,MAAM;AAAA,IAC1B,IAAI;AAAA,MACH,KAAK,IAAI,MAAM,MAAM,MAAM;AAAA,MAC1B,MAAM;AAAA;AAAA,EAMT,MAAM,CAAC,MAAoB;AAAA,IAC1B,KAAK,SAAS,MAAM,QAAQ;AAAA;AAAA,EAG7B,QAAQ,CAAC,MAAc,QAAsB;AAAA,IAC5C,IAAI,KAAK,WAAW;AAAA,MAAS;AAAA,IAC7B,MAAM,WAAW,KAAK,WAAW,WAAW,KAAK,WAAW;AAAA,IAC5D,KAAK,SAAS;AAAA,IACd,KAAK,MAAM,KAAK;AAAA,IAChB,KAAK,cAAc;AAAA,IACnB,aAAa,KAAK,WAAW;AAAA,IAC7B,cAAc,KAAK,eAAe;AAAA,IAClC,aAAa,KAAK,cAAc;AAAA,IAGhC,KAAK,MAAM,SAAS,IAAI;AAAA,IACxB,WAAW,YAAY,CAAC,GAAG,KAAK,QAAQ,OAAO,CAAC;AAAA,MAAG,SAAS,QAAQ;AAAA,IACpE,IAAI,UAAU;AAAA,MACb,KAAK,MAAM,OAAO,KAAK,cAAc;AAAA,QACpC,SAAS,KAAK;AAAA,QACd;AAAA,QACA;AAAA,QACA,YAAY,KAAK,IAAI,IAAI,KAAK;AAAA,MAC/B,CAAC;AAAA,IACF;AAAA;AAAA,EAGD,UAAU,CAAC,MAAiB,SAAiB,IAAmB;AAAA,IAC/D,KAAK,KACJ,OAAO,YACJ,EAAE,MAAM,SAAS,MAAM,QAAQ,IAC/B,EAAE,MAAM,SAAS,MAAM,SAAS,GAAG,CACvC;AAAA;AAAA,EAGD,cAAc,CAAC,MAAiB,SAAuB;AAAA,IACtD,KAAK,WAAW,MAAM,OAAO;AAAA,IAC7B,KAAK,IAAI,UAAU,iBAAiB,OAAO;AAAA;AAE7C;;;AC7lBA,SAAS,IAAI,CAAC,QAAkC;AAAA,EAC/C,OAAO,KAAK,QAAQ,QAAQ,CAAC,GAAG,OAAO,MAAM,EAAE;AAAA;AAGhD,SAAS,OAAO,CAAC,QAAqB,UAAmC;AAAA,EACxE,OAAO,aAAa,WACjB,OAAO,YAAY,SAAS,UAC5B,OAAO,cAAc,SAAS;AAAA;AAI3B,SAAS,MAAM,CAAC,QAAqB,KAAsB;AAAA,EACjE,OACC,OAAO,YAAY,QAClB,OAAO,SAAS,YAAY,OAAO,WAAW;AAAA;AAK1C,SAAS,eAAe,CAC9B,SACA,KACiB;AAAA,EACjB,MAAM,SAAS,IAAI;AAAA,EACnB,WAAW,KAAK,SAAS;AAAA,IACxB,IAAI,CAAC,OAAO,GAAG,GAAG,KAAK,OAAO,IAAI,EAAE,OAAO;AAAA,MAAG;AAAA,IAC9C,MAAM,UAAwB;AAAA,MAC7B,SAAS,EAAE;AAAA,MACX,UAAU,EAAE;AAAA,MACZ,YAAY,EAAE;AAAA,MACd,QAAQ,CAAC,GAAG,EAAE,MAAM;AAAA,MACpB,WAAW,EAAE;AAAA,IACd;AAAA,IACA,IAAI,EAAE,YAAY;AAAA,MAAW,QAAQ,UAAU,EAAE;AAAA,IACjD,OAAO,IAAI,EAAE,SAAS,OAAO;AAAA,EAC9B;AAAA,EACA,OAAO,CAAC,GAAG,OAAO,OAAO,CAAC,EAAE,KAC3B,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,cAAc,EAAE,OAAO,CACzE;AAAA;AAAA;AAIM,MAAM,iBAAuC;AAAA,EAC1C,WAAW,IAAI;AAAA,EAEf,iBAAiB,IAAI;AAAA,EAErB,oBAAoB,IAAI;AAAA,OAE3B,IAAG,CAAC,QAAuC;AAAA,IAChD,IAAI,KAAK,eAAe,IAAI,OAAO,OAAO;AAAA,MAAG,OAAO;AAAA,IACpD,MAAM,UAAU,KAAK,kBAAkB,IAAI,OAAO,SAAS;AAAA,IAC3D,IAAI,YAAY,aAAa,OAAO,kBAAkB,QAAQ,IAAI;AAAA,MACjE,OAAO;AAAA,IACR;AAAA,IACA,KAAK,SAAS,IAAI,OAAO,MAAM,KAAK,MAAM,CAAC;AAAA,IAC3C,OAAO;AAAA;AAAA,OAGF,IAAG,CAAC,MAAgD;AAAA,IACzD,MAAM,IAAI,KAAK,SAAS,IAAI,IAAI;AAAA,IAChC,OAAO,MAAM,YAAY,YAAY,KAAK,CAAC;AAAA;AAAA,OAGtC,SAAQ,CACb,MACA,KACA,WACmB;AAAA,IACnB,MAAM,IAAI,KAAK,SAAS,IAAI,IAAI;AAAA,IAChC,IAAI,MAAM,aAAa,EAAE,WAAW;AAAA,MAAW,OAAO;AAAA,IACtD,EAAE,SAAS;AAAA,IACX,EAAE,YAAY,KAAK,IAAI,EAAE,WAAW,SAAS;AAAA,IAC7C,OAAO;AAAA;AAAA,OAGF,OAAM,CACX,UACA,SACkB;AAAA,IAClB,IAAI,aAAa,UAAU;AAAA,MAC1B,KAAK,eAAe,IAAI,SAAS,SAAS,QAAQ,SAAS;AAAA,IAC5D,EAAO;AAAA,MACN,MAAM,MAAM,KAAK,kBAAkB,IAAI,SAAS,SAAS;AAAA,MACzD,KAAK,kBAAkB,IAAI,SAAS,WAAW;AAAA,QAC9C,IAAI,KAAK,IAAI,KAAK,MAAM,GAAG,QAAQ,GAAG;AAAA,QACtC,OAAO,KAAK,IAAI,KAAK,SAAS,GAAG,QAAQ,SAAS;AAAA,MACnD,CAAC;AAAA;AAAA,IAEF,IAAI,IAAI;AAAA,IACR,YAAY,MAAM,MAAM,KAAK,UAAU;AAAA,MACtC,IAAI,QAAQ,GAAG,QAAQ,GAAG;AAAA,QACzB,KAAK,SAAS,OAAO,IAAI;AAAA,QACzB;AAAA,MACD;AAAA,IACD;AAAA,IACA,OAAO;AAAA;AAAA,OAGF,WAAU,CAAC,WAAmB,KAAsC;AAAA,IACzE,MAAM,MAAM,CAAC,GAAG,KAAK,SAAS,OAAO,CAAC,EAAE,OACvC,CAAC,MAAM,EAAE,cAAc,SACxB;AAAA,IACA,OAAO,gBAAgB,KAAK,GAAG;AAAA;AAAA,OAG1B,cAAa,CAAC,KAA8B;AAAA,IACjD,YAAY,IAAI,UAAU,KAAK,gBAAgB;AAAA,MAC9C,IAAI,SAAS;AAAA,QAAK,KAAK,eAAe,OAAO,EAAE;AAAA,IAChD;AAAA,IACA,YAAY,IAAI,MAAM,KAAK,mBAAmB;AAAA,MAC7C,IAAI,EAAE,SAAS;AAAA,QAAK,KAAK,kBAAkB,OAAO,EAAE;AAAA,IACrD;AAAA,IACA,IAAI,IAAI;AAAA,IACR,YAAY,MAAM,MAAM,KAAK,UAAU;AAAA,MACtC,IAAI,EAAE,aAAa,KAAK;AAAA,QACvB,KAAK,SAAS,OAAO,IAAI;AAAA,QACzB;AAAA,MACD;AAAA,IACD;AAAA,IACA,OAAO;AAAA;AAAA,OAGF,MAAK,GAAkB;AAAA,IAC5B,KAAK,SAAS,MAAM;AAAA,IACpB,KAAK,eAAe,MAAM;AAAA,IAC1B,KAAK,kBAAkB,MAAM;AAAA;AAE/B;;;ACxIA;AAWA,IAAM,iBAAiB;AAEvB,IAAM,kBAAkB;AAiBxB,SAAS,QAAQ,CAAC,KAAuB;AAAA,EACxC,MAAM,SAAsB;AAAA,IAC3B,MAAM,IAAI;AAAA,IACV,MAAM,IAAI;AAAA,IACV,SAAS,IAAI;AAAA,IACb,WAAW,IAAI;AAAA,IACf,UAAU,IAAI;AAAA,IACd,YAAY,IAAI;AAAA,IAChB,QAAQ,KAAK,MAAM,IAAI,MAAM;AAAA,IAC7B,gBAAgB,IAAI;AAAA,IACpB,UAAU,IAAI;AAAA,IACd,WAAW,IAAI;AAAA,EAChB;AAAA,EACA,IAAI,IAAI,YAAY;AAAA,IAAM,OAAO,SAAS,IAAI;AAAA,EAC9C,IAAI,IAAI,YAAY;AAAA,IAAM,OAAO,UAAU,IAAI;AAAA,EAC/C,OAAO;AAAA;AAAA;AAOD,MAAM,iBAAuC;AAAA,EAC1C;AAAA,EAGT,WAAW,CAAC,MAAc;AAAA,IACzB,KAAK,MAAM,IAAI,SAAS,MAAM,EAAE,QAAQ,MAAM,QAAQ,KAAK,CAAC;AAAA,IAC5D,KAAK,IAAI,IAAI,4BAA4B;AAAA,IACzC,IAAI,SAAS;AAAA,MAAY,KAAK,IAAI,IAAI,2BAA2B;AAAA,IACjE,KAAK,SAAS;AAAA;AAAA,EAGf,QAAQ,GAAS;AAAA,IAChB,MAAM,MAAM,KAAK,IAAI,MAAM,qBAAqB,EAAE,IAAI;AAAA,IAGtD,IAAI,IAAI,gBAAgB;AAAA,MAAgB;AAAA,IACxC,KAAK,IAAI,YAAY,MAAM;AAAA,MAE1B,KAAK,IAAI,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAMJ;AAAA,MACT,KAAK,IAAI,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAaJ;AAAA,MAET,MAAM,UAAU,KAAK,IAAI,MAAM,2BAA2B,EAAE,IAAI;AAAA,MAGhE,IAAI,CAAC,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,SAAS,GAAG;AAAA,QAC/C,KAAK,IAAI,IAAI,4CAA4C;AAAA,MAC1D;AAAA,MACA,KAAK,IAAI,IACR,8DACD;AAAA,MACA,KAAK,IAAI,IACR,kEACD;AAAA,MACA,KAAK,IAAI,IACR,kEACD;AAAA,MAGA,KAAK,IACH,MACA;AAAA,oDAED,EACC,IAAI,EAAE,QAAQ,gBAAgB,CAAC;AAAA,MACjC,KAAK,IAAI,IAAI,yBAAyB,gBAAgB;AAAA,KACtD,EAAE;AAAA;AAAA,OAGE,IAAG,CAAC,GAAkC;AAAA,IAC3C,OAAO,KAAK,IAAI,YAAY,MAAM;AAAA,MACjC,MAAM,UAAU,KAAK,IACnB,MACA;AAAA,mEAED,EACC,IAAI;AAAA,QACJ,UAAU,EAAE;AAAA,QACZ,YAAY,EAAE;AAAA,QACd,SAAS,EAAE;AAAA,MACZ,CAAC;AAAA,MACF,IAAI,YAAY;AAAA,QAAM,OAAO;AAAA,MAC7B,KAAK,QAAQ,CAAC;AAAA,MACd,OAAO;AAAA,KACP,EAAE;AAAA;AAAA,EAGJ,OAAO,CAAC,GAAsB;AAAA,IAC7B,KAAK,IACH,MACA;AAAA;AAAA;AAAA,6EAID,EACC,IAAI;AAAA,MACJ,MAAM,EAAE;AAAA,MACR,MAAM,EAAE;AAAA,MACR,UAAU,EAAE;AAAA,MACZ,YAAY,EAAE;AAAA,MACd,WAAW,EAAE;AAAA,MACb,aAAa,EAAE;AAAA,MACf,QAAQ,KAAK,UAAU,EAAE,MAAM;AAAA,MAC/B,kBAAkB,EAAE;AAAA,MACpB,WAAW,EAAE;AAAA,MACb,YAAY,EAAE;AAAA,MACd,SAAS,EAAE,UAAU;AAAA,MACrB,SAAS,EAAE,WAAW;AAAA,IACvB,CAAC;AAAA;AAAA,OAGG,IAAG,CAAC,MAAgD;AAAA,IACzD,MAAM,MAAM,KAAK,IACf,MAAM,yCAAyC,EAC/C,IAAI,EAAE,KAAK,CAAC;AAAA,IACd,OAAO,QAAQ,OAAO,YAAY,SAAS,GAAG;AAAA;AAAA,OAGzC,SAAQ,CACb,MACA,KACA,WACmB;AAAA,IACnB,MAAM,SAAS,KAAK,IAClB,MACA;AAAA,2CAED,EACC,IAAI,EAAE,MAAM,KAAK,YAAY,UAAU,CAAC;AAAA,IAC1C,OAAO,OAAO,YAAY;AAAA;AAAA,OAGrB,OAAM,CACX,UACA,SACkB;AAAA,IAClB,OAAO,KAAK,IAAI,YAAY,MAAM;AAAA,MACjC,KAAK,IACH,MACA;AAAA;AAAA,uDAGD,EACC,IAAI;AAAA,QACJ,MAAM,aAAa,WAAW,UAAU;AAAA,QACxC,IAAI,aAAa,WAAW,SAAS,UAAU,SAAS;AAAA,QACxD,IAAI,QAAQ;AAAA,QACZ,OAAO,QAAQ;AAAA,MAChB,CAAC;AAAA,MACF,OAAO,KAAK,QAAQ,QAAQ;AAAA,KAC5B,EAAE;AAAA;AAAA,EAGJ,OAAO,CAAC,UAAkC;AAAA,IACzC,MAAM,SACL,aAAa,WACV,KAAK,IACJ,MAAM,yCAAyC,EAC/C,IAAI,EAAE,IAAI,SAAS,QAAQ,CAAC,IAC7B,KAAK,IACJ,MAAM,2CAA2C,EACjD,IAAI,EAAE,IAAI,SAAS,UAAU,CAAC;AAAA,IACnC,OAAO,OAAO;AAAA;AAAA,OAGT,WAAU,CAAC,WAAmB,KAAsC;AAAA,IACzE,MAAM,OAAO,KAAK,IAChB,MACA;AAAA,6CAED,EACC,IAAI,EAAE,WAAW,IAAI,CAAC;AAAA,IACxB,OAAO,gBAAgB,KAAK,IAAI,QAAQ,GAAG,GAAG;AAAA;AAAA,OAGzC,cAAa,CAAC,KAA8B;AAAA,IACjD,KAAK,IACH,MAAM,kDAAkD,EACxD,IAAI,EAAE,IAAI,CAAC;AAAA,IACb,OAAO,KAAK,IACV,MAAM,6CAA6C,EACnD,IAAI,EAAE,IAAI,CAAC,EAAE;AAAA;AAAA,OAGV,MAAK,GAAkB;AAAA,IAC5B,KAAK,IAAI,MAAM;AAAA;AAEjB;;;AC9LO,IAAM,UAAkB;AAE/B,IAAM,aAAwB,EAAE,MAAM,WAAW,QAAQ;AAGzD,IAAM,QAAQ,OAAO,OAAO;AAG5B,IAAM,2BAA2B;AAMjC,IAAM,+BAA+B;AAOrC,IAAM,iBAAiB;AAMvB,IAAM,qBAAqB,IAAI,IAAI;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,CAAC;AAGD,IAAM,iBACL;AAGD,IAAM,gBAAgB;AAGtB,IAAM,oBAAoB,IAAI,IAAI;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,CAAC;AA8BD,IAAM,0BAA0B;AAEhC,IAAM,kBAAkB;AAExB,IAAM,uBAAuB;AAE7B,IAAM,oBAAoB,UAAU,wBAAwB;AAQ5D,SAAS,eAAe,CAAC,QAA4C;AAAA,EACpE,IAAI;AAAA,EACJ,WAAW,QAAQ,OAAO,QAAQ,OAAO,EAAE,EAAE,MAAM,GAAG,GAAG;AAAA,IACxD,IAAI,SAAS;AAAA,MAAI;AAAA,IACjB,MAAM,KAAK,KAAK,QAAQ,GAAG;AAAA,IAC3B,MAAM,UAAU,KAAK,IAAI,OAAO,KAAK,MAAM,GAAG,EAAE;AAAA,IAChD,IAAI;AAAA,IACJ,IAAI;AAAA,MACH,OAAO,mBAAmB,QAAQ,WAAW,KAAK,GAAG,CAAC;AAAA,MACrD,MAAM;AAAA,MACP;AAAA;AAAA,IAED,IAAI,SAAS;AAAA,MAAK;AAAA,IAClB,MAAM,QAAQ,KAAK,IAAI,KAAK,KAAK,MAAM,KAAK,CAAC;AAAA,IAC7C,IAAI,YAAY,OAAO,UAAU,aAAa,CAAC,YAAY,KAAK,GAAG;AAAA,MAClE,OAAO;AAAA,IACR;AAAA,IACA,QAAQ;AAAA,EACT;AAAA,EACA,OAAO;AAAA;AAgCR,SAAS,IAAI,CACZ,QACA,OACA,SACW;AAAA,EACX,MAAM,IAAI,IAAI,QAAQ,OAAO;AAAA,EAC7B,EAAE,IAAI,gBAAgB,kBAAkB;AAAA,EACxC,OAAO,IAAI,SAAS,KAAK,UAAU,KAAK,GAAG,EAAE,QAAQ,SAAS,EAAE,CAAC;AAAA;AAGlE,SAAS,QAAQ,CAChB,QACA,OACA,MACA,SACA,SACA,MACW;AAAA,EACX,OAAO,IAAI,SAAS,aAAa,OAAO,MAAM,SAAS,IAAI,GAAG;AAAA,IAC7D;AAAA,IACA,SAAS,KAAK,SAAS,gBAAgB,mBAAmB;AAAA,EAC3D,CAAC;AAAA;AAGF,SAAS,OAAO,CAAC,MAAkD;AAAA,EAClE,IAAI,EAAE,QAAQ;AAAA,IAAO;AAAA,EACrB,MAAM,KAAK,KAAK;AAAA,EAChB,OAAO,OAAO,OAAO,YAAY,OAAO,OAAO,WAAW,KAAK;AAAA;AAIhE,SAAS,YAAY,CAAC,MAAuC;AAAA,EAC5D,MAAM,IAAI,KAAK;AAAA,EACf,OAAO,OAAO,MAAM,YAAY,0BAA0B,KAAK,CAAC,IAAI,IAAI;AAAA;AAGzE,SAAS,WAAW,CAAC,MAAwC;AAAA,EAC5D,MAAM,SAAS,KAAK;AAAA,EACpB,IAAI,OAAO,WAAW,YAAY,WAAW;AAAA,IAAM;AAAA,EACnD,MAAM,OAAQ,OAAmC;AAAA,EACjD,IAAI,OAAO,SAAS,YAAY,SAAS;AAAA,IAAM;AAAA,EAC/C,OAAQ,KAAiC;AAAA;AAG1C,IAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWnB,SAAS,IAAI,CAAC,MAAwC,MAAwB;AAAA,EAC7E,OAAO,IAAI,SAAS,MAAM;AAAA,IACzB,SAAS;AAAA,MACR,gBAAgB;AAAA,MAChB,2BAA2B;AAAA,MAC3B,0BAA0B;AAAA,MAC1B,iBAAiB;AAAA,IAClB;AAAA,EACD,CAAC;AAAA;AAIK,SAAS,WAAW,CAAC,UAA8B,CAAC,GAAU;AAAA,EACpE,OAAO,WAAW,SAAS,SAAS;AAAA;AAiBrC,SAAS,UAAU,CAClB,SACA,OACQ;AAAA,EACR,QAAQ,OAAO,aAAa,QAAQ,gBAAgB,YAAY;AAAA,EAChE,MAAM,aAAa,OAAO,gBAAgB,WAAW,cAAc;AAAA,EACnE,MAAM,SAAS,cACd,OAAO,gBAAgB,WACpB,KAAK,SAAS,OAAO,YAAY,IACjC,OACJ;AAAA,EACA,MAAM,SAAS,eAAe,aAAa,OAAO,QAAQ;AAAA,EAC1D,MAAM,YAAY,eAAe;AAAA,EACjC,MAAM,QACL,eACC,OAAO,UAAU,WACf,IAAI,iBAAiB,OAAO,UAAU,IACtC,IAAI;AAAA,EAER,MAAM,WAAW,IAAI;AAAA,EACrB,MAAM,cAAc,IAAI;AAAA,EACxB,MAAM,QAAQ,IAAI;AAAA,EAElB,MAAM,UAAU,IAAI;AAAA,EACpB,IAAI,eAAe;AAAA,EAKnB,MAAM,WAAW,IAAI;AAAA,EAIrB,IAAI,oBAAoB;AAAA,EACxB,IAAI,YAAY,OAAO,aAAa;AAAA,EAEpC,MAAM,aACL,OAAO,SAAS,YACb,YACA,IAAI,qBACJ,OAAO,MACP,OAAO,eACP,OAAO,iBACR;AAAA,EAEH,MAAM,cAAsC,OAAO,OAChD;AAAA,IACA,+BAA+B;AAAA,IAC/B,iCACC;AAAA,EACF,IACC,CAAC;AAAA,EAGJ,MAAM,gBAAgB,MAAM;AAAA,IAC3B,MAAM,MAAM,KAAK,IAAI;AAAA,IACrB,OAAO,EAAE,KAAK,WAAW,MAAM,OAAO,gBAAgB;AAAA;AAAA,EAGvD,SAAS,YAAY,CACpB,WACA,SACA,QACO;AAAA,IACP,MAAM,UAAU,SAAS,IAAI,SAAS;AAAA,IACtC,IAAI,SAAS;AAAA,MACZ,QAAQ,KAAK,EAAE,MAAM,iBAAiB,SAAS,OAAO,CAAC;AAAA;AAAA,EAGzD,MAAM,OAAO;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,OACI,OAAO,qBAAqB,YAC7B,CAAC,IACD,EAAE,kBAAkB,MAAM,iBAAiB;AAAA,IAC9C,WAAW,MAAM;AAAA,SACX,YAAW,CAAC,SAAqB,SAAmC;AAAA,MACzE,MAAM,YAAY,QAAQ;AAAA,MAC1B,IAAI,cAAc;AAAA,QAAW,OAAO;AAAA,MACpC,MAAM,SAAS,MAAM,MAAM,WAAW,WAAW,KAAK,IAAI,CAAC;AAAA,MAC3D,IAAI,CAAC,OAAO,KAAK,CAAC,MAAM,EAAE,YAAY,OAAO;AAAA,QAAG,OAAO;AAAA,MACvD,MAAM,MAAM,OAAO,EAAE,QAAQ,GAAG,cAAc,CAAC;AAAA,MAC/C,OAAO,KAAK,iBAAiB;AAAA,QAC5B,SAAS,aAAa,SAAS;AAAA,QAC/B,IAAI;AAAA,MACL,CAAC;AAAA,MACD,aAAa,WAAW,SAAS,SAAS;AAAA,MAC1C,OAAO;AAAA;AAAA,SAEF,UAAS,CAAC,SAAoC;AAAA,MACnD,MAAM,YAAY,QAAQ;AAAA,MAC1B,IAAI,cAAc;AAAA,QAAW;AAAA,MAC7B,MAAM,SAAS,MAAM,MAAM,WAAW,WAAW,KAAK,IAAI,CAAC;AAAA,MAC3D,MAAM,MAAM,OAAO,EAAE,UAAU,GAAG,cAAc,CAAC;AAAA,MACjD,OAAO,KAAK,qBAAqB;AAAA,QAChC,SAAS,aAAa,SAAS;AAAA,QAC/B,QAAQ,OAAO;AAAA,MAChB,CAAC;AAAA,MACD,WAAW,KAAK;AAAA,QAAQ,aAAa,WAAW,EAAE,SAAS,SAAS;AAAA;AAAA,SAO/D,aAAY,CACjB,SACA,WACA,OACgB;AAAA,MAChB,MAAM,YAAY,QAAQ;AAAA,MAC1B,IAAI,cAAc;AAAA,QAAW;AAAA,MAC7B,MAAM,OAAO,UAAU,YAAY,CAAC,IAAI,EAAE,MAAM;AAAA,MAIhD,MAAM,SAAS,CAAC,YAA0B;AAAA,QACzC,IAAI,CAAC,QAAQ,KAAK,OAAO,GAAG;AAAA,UAC3B,OAAO,KAAK,2BAA2B;AAAA,YACtC,SAAS,aAAa,SAAS;AAAA,YAC/B,MAAM,QAAQ;AAAA,UACf,CAAC;AAAA,QACF;AAAA;AAAA,MAED,MAAM,SAAS,CAAC,QAAgB,YAAoB;AAAA,QAKnD,MAAM,YAAY,mBAAmB,IAAI,MAAM;AAAA,QAC/C,QAAQ,oBAAoB;AAAA,QAC5B,IAAI,QAAQ,aAAa,WAAW;AAAA,UACnC,QAAQ,WAAW;AAAA,UACnB,IAAI,WAAW;AAAA,YACd,YAAY,SAAS,gBAAgB,IAAI;AAAA,UAC1C,EAAO;AAAA,YACN,YAAY,SAAS,yCAAyC;AAAA;AAAA,QAEhE;AAAA,QACA,OAAO,KAAK,oBAAoB;AAAA,UAC/B,SAAS,aAAa,SAAS;AAAA,UAC/B;AAAA,QACD,CAAC;AAAA,QACD,OAAO,EAAE,MAAM,SAAS,MAAM,oBAAoB,YAAY,KAAK,CAAC;AAAA;AAAA,MAErE,IAAI,QAAQ,KAAK,YAAY,UAAU,eAAe,WAAW;AAAA,QAChE,OAAO,YAAY,gDAAgD;AAAA,QACnE;AAAA,MACD;AAAA,MACA,IAAI;AAAA,MACJ,IAAI;AAAA,QACH,MAAM,MAAM,WAAW,OACtB,WACA,GAAG,eAAe,eACnB;AAAA,QACC,OAAO,OAAO;AAAA,QACf,OACC,iBAAiB,WAAW,MAAM,SAAS,SAC3C,uCAAuC,iBAAiB,WAAW,MAAM,UAAU,gCACpF;AAAA,QACA;AAAA;AAAA,MAED,IAAI,CAAC,QAAQ;AAAA,QAAO;AAAA,MACpB,MAAM,UAAU,QAAQ,aAAa;AAAA,MACrC,IAAI,WAAW,QAAQ,aAAa,WAAW;AAAA,QAE9C,QAAQ,WAAW;AAAA,QACnB,YAAY,SAAS,0BAA0B;AAAA,MAChD;AAAA,MAEA,IAAI,UAAU;AAAA,MACd,IAAI;AAAA,QACH,MAAM,SAAS,MAAM,MAAM,WAAW,WAAW,KAAK,IAAI,CAAC;AAAA,QAC3D,WAAW,KAAK,OAAO,OAAO,CAAC,MAAM,EAAE,YAAY,GAAG,GAAG;AAAA,UACxD,MAAM,MAAM,OAAO,EAAE,SAAS,EAAE,QAAQ,GAAG,cAAc,CAAC;AAAA,UAC1D,aAAa,WAAW,EAAE,SAAS,SAAS;AAAA,UAC5C;AAAA,QACD;AAAA,QACC,OAAO,OAAO;AAAA,QACf,OAAO,MAAM,eAAe;AAAA,UAC3B,IAAI;AAAA,UACJ,OAAO,UAAU,KAAK;AAAA,QACvB,CAAC;AAAA,QACD,OAAO,qBAAqB,yCAAyC;AAAA,QACrE;AAAA;AAAA,MAED,IAAI,CAAC,QAAQ;AAAA,QAAO;AAAA,MACpB,QAAQ,WAAW;AAAA,MACnB,QAAQ,oBAAoB;AAAA,MAC5B,OAAO,EAAE,MAAM,qBAAqB,KAAK,CAAC;AAAA,MAC1C,OAAO,KAAK,kBAAkB;AAAA,QAC7B,SAAS,aAAa,SAAS;AAAA,QAC/B;AAAA,QACA;AAAA,MACD,CAAC;AAAA,MACD,KAAK,MAAM,OAAO;AAAA;AAAA,SAEb,QAAO,CAAC,SAAoC;AAAA,MACjD,MAAM,YAAY,QAAQ;AAAA,MAC1B,IAAI,cAAc;AAAA,QAAW;AAAA,MAC7B,IAAI,QAAQ,KAAK,YAAY,QAAQ;AAAA,QACpC,QAAQ,KAAK;AAAA,UACZ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,QACV,CAAC;AAAA,QACD;AAAA,MACD;AAAA,MAGA,QAAQ,WAAW;AAAA,MACnB,QAAQ,oBAAoB;AAAA,MAC5B,YAAY,SAAS,6BAA6B;AAAA,MAClD,IAAI;AAAA,QACH,MAAM,SAAS,MAAM,MAAM,WAAW,WAAW,KAAK,IAAI,CAAC;AAAA,QAC3D,MAAM,MAAM,OAAO,EAAE,UAAU,GAAG,cAAc,CAAC;AAAA,QACjD,OAAO,KAAK,uBAAuB;AAAA,UAClC,SAAS,aAAa,SAAS;AAAA,UAC/B,QAAQ,OAAO;AAAA,QAChB,CAAC;AAAA,QACD,WAAW,KAAK;AAAA,UAAQ,aAAa,WAAW,EAAE,SAAS,SAAS;AAAA,QACnE,OAAO,OAAO;AAAA,QAEf,OAAO,MAAM,eAAe,EAAE,IAAI,WAAW,OAAO,UAAU,KAAK,EAAE,CAAC;AAAA;AAAA;AAAA,IAGxE,YAAY,CAAC,SAA6C;AAAA,MACzD,MAAM,KAAK,QAAQ;AAAA,MACnB,IAAI,OAAO;AAAA,QAAW;AAAA,MACtB,MAAM,WAAW,SAAS,IAAI,EAAE;AAAA,MAChC,SAAS,IAAI,IAAI,OAAO;AAAA,MACxB,OAAO,aAAa,UAAU,YAAY;AAAA;AAAA,IAE3C,QAAQ,CAAC,SAA2B;AAAA,MACnC,YAAY,OAAO,OAAO;AAAA,MAC1B,IACC,QAAQ,cAAc,aACtB,SAAS,IAAI,QAAQ,SAAS,MAAM,SACnC;AAAA,QACD,SAAS,OAAO,QAAQ,SAAS;AAAA,MAClC;AAAA,MACA,UAAU,QAAQ,EAAE;AAAA;AAAA,IAErB,KAAK,CAAC,SAA2B;AAAA,MAChC,MAAM,KAAK,QAAQ;AAAA,MACnB,IAAI,OAAO;AAAA,QAAW;AAAA,MACtB,MAAM,UAAU,QAAQ,WAAW,SAAS,IAAI,EAAE,GAAG;AAAA,MACrD,SAAS,OAAO,EAAE;AAAA,MAClB,SAAS,IAAI,IAAI;AAAA,QAChB;AAAA,QACA,uBAAuB,QAAQ,OAAO;AAAA,MACvC,CAAC;AAAA,MAED,IAAI,SAAS,OAAO,OAAO,cAAc,GAAG;AAAA,QAC3C,MAAM,SAAS,SAAS,KAAK,EAAE,KAAK,EAAE;AAAA,QACtC,IAAI,WAAW;AAAA,UAAW,SAAS,OAAO,MAAM;AAAA,MACjD;AAAA,MACA,MAAM,UAAU,QAAQ,IAAI,EAAE;AAAA,MAC9B,IAAI,YAAY;AAAA,QAAW,WAAW,QAAQ,CAAC,GAAG,OAAO;AAAA,UAAG,KAAK,OAAO;AAAA;AAAA,EAE1E;AAAA,EAOA,SAAS,WAAW,CACnB,SACA,SACA,YAAY,OACL;AAAA,IACP,MAAM,YAAY,QAAQ;AAAA,IAC1B,MAAM,UAAkC,YACrC,EAAE,eAAe,cAAc,IAC/B,cAAc,YACb,CAAC,IACD,EAAE,oBAAoB,gBAAgB,WAAW,IAAI,EAAE;AAAA,IAC3D,WAAW,YAAY,CAAC,GAAG,QAAQ,QAAQ,OAAO,CAAC,GAAG;AAAA,MACrD,SAAS,KACR,YAAY,MAAM,KAClB,eAAe,WACf,SACA,MACA,OACD;AAAA,IACD;AAAA;AAAA,EAGD,SAAS,YAAY,CACpB,WACA,SAAqC,MAAM,MAClB;AAAA,IACzB,MAAM,IAAI,SAAS,IAAI,SAAS;AAAA,IAChC,OAAO,GAAG,UAAU,QAAQ,OAAO,CAAC,IAAI,IAAI;AAAA;AAAA,EAQ7C,SAAS,SAAS,CAAC,SAA6B;AAAA,IAC/C,OAAO,CAAC,MACN,YAAY,aAAa,EAAE,KAAK,YAAY,UAC7C,EAAE,aAAa;AAAA;AAAA,EAQjB,SAAS,WAAW,CACnB,WACA,QACA,QACA,QAC8C;AAAA,IAC9C,MAAM,MAAM,aAAa,WAAW,MAAM;AAAA,IAC1C,IAAI,QAAQ;AAAA,MAAW,OAAO,QAAQ,QAAQ,GAAG;AAAA,IACjD,IAAI,WAAW,KAAK,SAAS;AAAA,MAC5B,OAAO,QAAQ,QAAQ,SAAS;AAAA,IACjC;AAAA,IACA,MAAM,MAAM,QAAQ,IAAI,SAAS,KAAK,IAAI;AAAA,IAI1C,MAAM,QACL,SAAS,IAAI,SAAS,GAAG,OAAO,yBAChC,SAAS,IAAI,SAAS,GAAG,yBACzB,OAAO;AAAA,IACR,IAAI,IAAI,QAAQ,SAAS,gBAAgB,OAAO,aAAa;AAAA,MAC5D,OAAO,QAAQ,QAAQ,SAAS;AAAA,IACjC;AAAA,IACA,OAAO,IAAI,QAAQ,CAAC,YAAY;AAAA,MAC/B,IAAI;AAAA,MACJ,IAAI,UAAU;AAAA,MACd,MAAM,OAAO,CAAC,WAA+C;AAAA,QAC5D,IAAI;AAAA,UAAS;AAAA,QACb,UAAU;AAAA,QACV,aAAa,KAAK;AAAA,QAClB,OAAO,oBAAoB,SAAS,OAAO;AAAA,QAC3C,IAAI,OAAO,IAAI;AAAA,QACf;AAAA,QACA,IAAI,IAAI,SAAS,KAAK,QAAQ,IAAI,SAAS,MAAM,KAAK;AAAA,UACrD,QAAQ,OAAO,SAAS;AAAA,QACzB;AAAA,QACA,QAAQ,MAAM;AAAA;AAAA,MAEf,MAAM,OAAO,CAAC,YAAoC;AAAA,QACjD,IAAI,YAAY,aAAa,OAAO,OAAO;AAAA,UAAG,KAAK,OAAO;AAAA;AAAA,MAE3D,MAAM,UAAU,MAAM,KAAK,SAAS;AAAA,MACpC,IAAI,IAAI,IAAI;AAAA,MACZ,QAAQ,IAAI,WAAW,GAAG;AAAA,MAC1B;AAAA,MACA,QAAQ,WAAW,MAAM,KAAK,SAAS,GAAG,MAAM;AAAA,MAChD,OAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAAA,MACxD,IAAI,OAAO;AAAA,QAAS,QAAQ;AAAA,KAC5B;AAAA;AAAA,EAGF,SAAS,SAAS,CAAC,IAAkB;AAAA,IACpC,MAAM,KAAK,MAAM,IAAI,EAAE,KAAK,KAAK;AAAA,IACjC,IAAI,KAAK;AAAA,MAAG,MAAM,OAAO,EAAE;AAAA,IACtB;AAAA,YAAM,IAAI,IAAI,CAAC;AAAA;AAAA,EAGrB,SAAS,QAAQ,CAAC,KAAc,QAAgC;AAAA,IAC/D,IAAI,OAAO,eAAe,aAAa;AAAA,MACtC,MAAM,IAAI,IAAI,QAAQ,IAAI,WAAW,GAAG,KAAK;AAAA,MAC7C,IAAI;AAAA,QAAG,OAAO;AAAA,IACf,EAAO,SAAI,OAAO,eAAe,mBAAmB;AAAA,MACnD,MAAM,SAAS,IAAI,QAAQ,IAAI,iBAAiB,KAAK,IACnD,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,CAAC,MAAM,MAAM,EAAE;AAAA,MACxB,MAAM,OAAO,MAAM,GAAG,EAAE;AAAA,MACxB,IAAI,SAAS;AAAA,QAAW,OAAO;AAAA,IAChC;AAAA,IACA,OAAO,OAAO,UAAU,GAAG,GAAG,WAAW;AAAA;AAAA,EAG1C,MAAM,OAAO,IAAI,oBAChB;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,MAAM;AAAA,IACjB,SAAS,CAAC,cAAc;AAAA,MACvB,MAAM,IAAI,SAAS,IAAI,SAAS;AAAA,MAChC,OAAO,GAAG,UAAU,OAAO,IAAI;AAAA;AAAA,IAEhC,YAAY,CAAC,WAAmB,UAAqB;AAAA,MACpD,MAAM,UAAU,SAAS,IAAI,SAAS;AAAA,MACtC,IAAI,SAAS;AAAA,QAAO,QAAQ,KAAK,EAAE,MAAM,eAAe,MAAM,CAAC;AAAA;AAAA,IAEhE,cAAc,CAAC,WAAW,SAAS,WAClC,aACC,WACA,SACA,MACD;AAAA,EACF,GACA,KACD;AAAA,EACA,IAAI,UAAU,WAAW;AAAA,IACxB,OAAO,KAAK,oBAAoB;AAAA,MAC/B,SAAS;AAAA,IACV,CAAC;AAAA,EACF;AAAA,EAEA,SAAS,SAAS,CACjB,KACA,QACuB;AAAA,IACvB,MAAM,SAAS,IAAI,QAAQ,IAAI,QAAQ;AAAA,IACvC,MAAM,OAAO,QAAQ,QAAQ,MAAM;AAAA,IACnC,IAAI,SAAS,WAAW;AAAA,MACvB,OAAO,KAAK,eAAe,EAAE,QAAQ,SAAS,CAAC;AAAA,MAC/C,OAAO,KAAK,KAAK,EAAE,OAAO,qBAAqB,CAAC;AAAA,IACjD;AAAA,IACA,MAAM,WAAW,IAAI,QAAQ,IAAI,wBAAwB,KAAK,IAC5D,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AAAA,IACrB,IAAI,CAAC,QAAQ,SAAS,WAAW,GAAG;AAAA,MACnC,OAAO,KAAK,KAAK;AAAA,QAChB,OAAO;AAAA,QACP,WAAW,CAAC,WAAW;AAAA,MACxB,CAAC;AAAA,IACF;AAAA,IAIA,MAAM,UAAU,gBAAgB,IAAI,IAAI,IAAI,GAAG,EAAE,MAAM;AAAA,IACvD,IAAI,YAAY,OAAO;AAAA,MACtB,OAAO,KAAK,eAAe,EAAE,QAAQ,cAAc,CAAC;AAAA,MACpD,OAAO,KAAK,KAAK,EAAE,OAAO,cAAc,CAAC;AAAA,IAC1C;AAAA,IACA,MAAM,SAAS,SAAS,KAAK,MAAM;AAAA,IAEnC,MAAM,KAAK,YAAY,MAAM;AAAA,IAC7B,IAAI,YAAY,QAAQ,OAAO,aAAa;AAAA,MAC3C,OAAO,KAAK,eAAe,EAAE,QAAQ,eAAe,CAAC;AAAA,MACrD,OAAO,KAAK,KAAK,EAAE,OAAO,oBAAoB,CAAC;AAAA,IAChD;AAAA,IACA,MAAM,QAAQ,MAAM,IAAI,EAAE,KAAK;AAAA,IAC/B,IAAI,SAAS,OAAO,kBAAkB;AAAA,MACrC,OAAO,KAAK,eAAe;AAAA,QAC1B,QAAQ;AAAA,QACR,IAAI,WAAW,MAAM;AAAA,MACtB,CAAC;AAAA,MACD,OAAO,KAAK,KAAK,EAAE,OAAO,oBAAoB,CAAC;AAAA,IAChD;AAAA,IACA,MAAM,IAAI,IAAI,QAAQ,CAAC;AAAA,IACvB,MAAM,KAAK,OAAO,QAAQ,KAAK;AAAA,MAC9B,MAAM;AAAA,QACL;AAAA,QACA,QAAQ,UAAU;AAAA,QAClB;AAAA,WACI,YAAY,YAAY,CAAC,IAAI,EAAE,QAAQ;AAAA,MAC5C;AAAA,MACA,SAAS,EAAE,0BAA0B,YAAY;AAAA,IAClD,CAAC;AAAA,IACD,IAAI;AAAA,MAAI;AAAA,IACR,UAAU,EAAE;AAAA,IACZ,OAAO,KAAK,KAAK,EAAE,OAAO,6BAA6B,CAAC;AAAA;AAAA,EAGzD,SAAS,eAAe,CAAC,IAAY,WAA4B;AAAA,IAChE,MAAM,WAAW,GAAG,oDAAoD;AAAA,IACxE,MAAM,QAAQ,YAAY,4BAA4B;AAAA,IACtD,OAAO,6BAA6B,2BAA2B;AAAA;AAAA,EAGhE,eAAe,YAAY,CAC1B,KACA,WAC+D;AAAA,IAC/D,MAAM,SAAS,IAAI,QAAQ,IAAI,eAAe;AAAA,IAC9C,IAAI,WAAW;AAAA,MAAM,OAAO;AAAA,IAC5B,MAAM,QAAQ,mCAAmC,KAAK,OAAO,KAAK,CAAC;AAAA,IACnE,MAAM,QAAQ,QAAQ;AAAA,IACtB,IAAI,UAAU;AAAA,MAAW,OAAO;AAAA,IAChC,IAAI;AAAA,IACJ,IAAI;AAAA,MACH,SAAS,MAAM,MAAM,IAAI,UAAU,KAAK,CAAC;AAAA,MACxC,OAAO,OAAO;AAAA,MACf,OAAO,MAAM,eAAe,EAAE,IAAI,OAAO,OAAO,UAAU,KAAK,EAAE,CAAC;AAAA,MAClE,OAAO;AAAA;AAAA,IAER,IACC,WAAW,aACX,OAAO,SAAS,YAChB,OAAO,cAAc,aACrB,OAAO,aAAa,KAAK,IAAI,KAC7B,CAAC,OAAO,OAAO,SAAS,OAAO,GAC9B;AAAA,MACD,OAAO;AAAA,IACR;AAAA,IACA,OAAO;AAAA;AAAA,EAGR,eAAe,QAAQ,CACtB,KACA,UAC2B;AAAA,IAC3B,MAAM,SAAS,OAAO,IAAI,QAAQ,IAAI,gBAAgB,KAAK,GAAG;AAAA,IAC9D,IAAI,SAAS,UAAU;AAAA,MACtB,OAAO,SACN,KACA,WACA,QACA,2BACA,WACD;AAAA,IACD;AAAA,IACA,IAAI;AAAA,IACJ,IAAI;AAAA,MAIH,MAAM,UAAU,IAAI,YAAY;AAAA,MAChC,QAAQ,MAAM,MAAM,EAAE;AAAA,MACtB,IAAI;AAAA,MACJ,MAAM,WAAW,IAAI,QAAmB,CAAC,YAAY;AAAA,QACpD,QAAQ,WAAW,MAAM,QAAQ,SAAS,GAAG,OAAO,aAAa;AAAA,OACjE;AAAA,MACD,IAAI;AAAA,MACJ,IAAI;AAAA,QACH,SAAS,MAAM,QAAQ,KAAK,CAAC,SAAS,QAAQ,CAAC;AAAA,gBAC9C;AAAA,QACD,aAAa,KAAK;AAAA;AAAA,MAEnB,IAAI,WAAW,WAAW;AAAA,QACzB,OAAO,SACN,KACA,WACA,QACA,4CACA,KAAK,aAAa,YAAY,QAAQ,CACvC;AAAA,MACD;AAAA,MACA,QAAQ;AAAA,MACP,MAAM;AAAA,MACP,OAAO,SACN,KACA,WACA,QACA,oCACA,WACD;AAAA;AAAA,IAED,IAAI,MAAM,aAAa,UAAU;AAAA,MAChC,OAAO,SACN,KACA,WACA,QACA,2BACA,WACD;AAAA,IACD;AAAA,IACA,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,MACH,OAAO,IAAI,YAAY,SAAS,EAAE,OAAO,KAAK,CAAC,EAAE,OAAO,KAAK;AAAA,MAC7D,QAAQ,KAAK,MAAM,IAAI;AAAA,MACtB,MAAM;AAAA,MACP,OAAO,SAAS,KAAK,WAAW,QAAQ,gBAAgB,WAAW;AAAA;AAAA,IAEpE,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GAAG;AAAA,MACxE,OAAO,SACN,KACA,WACA,QACA,uDACA,WACD;AAAA,IACD;AAAA,IACA,OAAO,EAAE,OAAyC,KAAK;AAAA;AAAA,EAIxD,SAAS,YAAY,CACpB,KACA,MACA,OACwC;AAAA,IACxC,MAAM,SAAS,IAAI,QAAQ,IAAI,sBAAsB;AAAA,IAIrD,IACC,KAAK,cAAc,gBACnB,EACC,WAAW,wBACX,YAAY,IAAI,MAAM,uBAEtB;AAAA,MACD,MAAM,SAAS,KAAK;AAAA,MACpB,MAAM,YACL,OAAO,SAAS,uBAAuB,WACpC,OAAO,qBACN,UAAU;AAAA,MACf,OAAO,SACN,KACA,OACA,QACA,iCAAiC,OAAO,SAAS,gCAAgC,yBACjF,aACA,EAAE,WAAW,CAAC,oBAAoB,GAAG,UAAU,CAChD;AAAA,IACD;AAAA,IACA,IAAI,WAAW;AAAA,MAAsB,OAAO,EAAE,gBAAgB,OAAO;AAAA,IACrE,IACC,WAAW,4BACX,YAAY,IAAI,MAAM,sBACrB;AAAA,MAED,IAAI,EAAE,sBAAsB,GAAG;AAAA,QAC9B,OAAO,KAAK,gCAAgC;AAAA,UAC3C,SACC;AAAA,QACF,CAAC;AAAA,MACF;AAAA,MACA,OAAO,EAAE,gBAAgB,qBAAqB;AAAA,IAC/C;AAAA,IACA,IAAI,WAAW,MAAM;AAAA,MACpB,OAAO,SACN,KACA,OACA,QACA,wCACA,WACD;AAAA,IACD;AAAA,IACA,OAAO,SACN,KACA,OACA,QACA,iCAAiC,qCAAqC,yBACtE,aACA,EAAE,WAAW,CAAC,oBAAoB,GAAG,WAAW,OAAO,CACxD;AAAA;AAAA,EAGD,eAAe,SAAS,CACvB,KACA,QACA,WACoB;AAAA,IACpB,MAAM,UAAU,KAAK,IAAI;AAAA,IACzB,MAAM,UAAU,CACf,QACA,QACA,QAAyC,CAAC,MAE1C,OAAO,KAAK,eAAe;AAAA,MAC1B,SAAS,aAAa,SAAS;AAAA,MAC/B;AAAA,MACA;AAAA,MACA,YAAY,KAAK,IAAI,IAAI;AAAA,SACtB;AAAA,IACJ,CAAC;AAAA,IAIF,MAAM,OAAO,MAAM,SAClB,KACA,SAAS,IAAI,SAAS,GAAG,OAAO,mBAAmB,OAAO,eAC3D;AAAA,IACA,IAAI,gBAAgB,UAAU;AAAA,MAC7B,QAAQ,KAAK,QAAQ,GAAG;AAAA,MACxB,OAAO;AAAA,IACR;AAAA,IACA,MAAM,QAAQ,QAAQ,KAAK,KAAK;AAAA,IAChC,MAAM,SAAS,aAAa,KAAK,KAAK;AAAA,IAEtC,MAAM,UAAU,aAAa,KAAK,KAAK,OAAO,KAAK;AAAA,IACnD,IAAI,mBAAmB,UAAU;AAAA,MAChC,QAAQ,QAAQ,QAAQ,MAAM;AAAA,MAC9B,OAAO;AAAA,IACR;AAAA,IAEA,MAAM,OAAO,MAAM,aAAa,KAAK,SAAS;AAAA,IAC9C,IAAI,SAAS,eAAe;AAAA,MAE3B,QAAQ,KAAK,QAAQ,EAAE,QAAQ,oBAAoB,CAAC;AAAA,MACpD,OAAO,SACN,KACA,OACA,eAAe,kBACf,+DACA,KAAK,aAAa,eAAe,cAAc,CAChD;AAAA,IACD;AAAA,IACA,IAAI,OAAO,SAAS,UAAU;AAAA,MAC7B,QAAQ,KAAK,MAAM;AAAA,MACnB,OAAO,KACN,KACA;AAAA,QACC,OAAO;AAAA,QACP,mBACC,SAAS,YACN,4BACA;AAAA,MACL,GACA;AAAA,WACI;AAAA,QACH,oBAAoB,gBAAgB,WAAW,SAAS,SAAS;AAAA,MAClE,CACD;AAAA,IACD;AAAA,IAEA,MAAM,UAAkC,CAAC;AAAA,IACzC,YAAY,GAAG,MAAM,IAAI,SAAS;AAAA,MACjC,MAAM,MAAM,EAAE,YAAY;AAAA,MAC1B,IAAI,kBAAkB,IAAI,GAAG,KAAK,IAAI,WAAW,YAAY;AAAA,QAC5D,QAAQ,OAAO;AAAA,IACjB;AAAA,IACA,QAAQ,0BAA0B,QAAQ;AAAA,IAE1C,MAAM,kBAAkB,MAAM;AAAA,MAC7B,IAAI;AAAA,QACH,OAAO,IAAI,IAAI,KAAK,QAAQ,EAAE;AAAA,QAC7B,MAAM;AAAA,QACP,OAAO;AAAA;AAAA,OAEN;AAAA,IACH,MAAM,WAAW,KAAK,MAAM,cAAc;AAAA,IAI1C,MAAM,SACL,KAAK,MAAM,cAAc,qBAGzB,OAAO,WAAW,KAAK,IAAI,IAAI,oBAC5B,IACA,OAAO;AAAA,IACX,MAAM,SAAS,MAAM;AAAA,MACpB,QAAQ,KAAK,QAAQ,EAAE,SAAS,gBAAgB,CAAC;AAAA,MACjD,OAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,IAAI,CAAC;AAAA;AAAA,IAS1C,MAAM,OAAO,CAAC,OACb,OAAO,QAAQ,KAAK,KAAK,OAAO,mBAAmB,CAAC;AAAA,IACrD,MAAM,SAAS,UAAU,KAAK,OAAO;AAAA,IAGrC,MAAM,QAAQ,YAA4C;AAAA,MACzD,MAAM,QAAQ,MAAM,YAAY,WAAW,IAAI,QAAQ,QAAQ,MAAM;AAAA,MAKrE,IAAI,UAAU,aAAa,IAAI,OAAO;AAAA,QAAS,OAAO,OAAO;AAAA,MAC7D,IAAI,UAAU,WAAW;AAAA,QACxB,OAAO,YAAY,KAAK,OAAO,OAAO,WAAW,SAAS,MAAM;AAAA,MACjE;AAAA,MACA,MAAM,UAAU;AAAA,MAEhB,KACE,KAAK,YAAY,aAAa,QAAQ,KAAK,YAAY,WACxD,QAAQ,aAAa,KAAK,SACzB;AAAA,QACD,QAAQ,KAAK,QAAQ,EAAE,QAAQ,oBAAoB,CAAC;AAAA,QACpD,OAAO,KACN,KACA,EAAE,OAAO,iBAAiB,mBAAmB,cAAc,GAC3D;AAAA,aACI;AAAA,UACH,oBAAoB,GAAG,gBAAgB,WAAW,IAAI,yBAAyB;AAAA,QAChF,CACD;AAAA,MACD;AAAA,MAGA,IAAI,OAAO,WAAW,KAAK,IAAI,IAAI,QAAQ,OAAO,iBAAiB;AAAA,QAClE,QAAQ,KAAK,MAAM;AAAA,QACnB,OAAO,SACN,KACA,OACA,QACA,2BACA,WACD;AAAA,MACD;AAAA,MACA,IAAI,QAAQ,QAAQ,QAAQ,QAAQ,OAAO,uBAAuB;AAAA,QACjE,QAAQ,KAAK,MAAM;AAAA,QACnB,OAAO,SACN,KACA,OACA,eAAe,YACf,4CACA,WACD;AAAA,MACD;AAAA,MACA,IACC,YACA,QAAQ,cAAc,KAAK,OAAO,KAAK,8BACtC;AAAA,QACD,QAAQ,KAAK,QAAQ,EAAE,QAAQ,iBAAiB,CAAC;AAAA,QACjD,OAAO,SACN,KACA,OACA,eAAe,YACf,oDACA,WACD;AAAA,MACD;AAAA,MACA,OAAO;AAAA;AAAA,IAGR,IAAI,aAAa,WAAW,MAAM,MAAM,aAAa,SAAS,GAAG;AAAA,MAChE,KAAK,KAAK;AAAA,IACX;AAAA,IACA,IAAI,UAAU;AAAA,IACd,UAAS;AAAA,MACR,MAAM,WAAW,MAAM,MAAM;AAAA,MAC7B,IAAI,oBAAoB,UAAU;AAAA,QACjC,KAAK,IAAI;AAAA,QACT,OAAO;AAAA,MACR;AAAA,MACA,MAAM,UAAU;AAAA,MAChB,KAAK,KAAK;AAAA,MACV,IAAI,QAAoB,MAAM;AAAA,MAC9B,MAAM,WAAW,IAAI,QAAsB,CAAC,YAAY;AAAA,QACvD,QAAQ,MAAM,QAAQ,KAAK;AAAA,OAC3B;AAAA,MACD,MAAM,WACL,CAAC,WAAW,SAAS,KAAK,YAAY,KAAK,MAAM,SAAS;AAAA,MAC3D,MAAM,WAAW,QAAQ,QAAQ;AAAA,QAChC;AAAA,QACA,MAAM,KAAK;AAAA,QACX;AAAA,QACA;AAAA,QACA,OAAO;AAAA,UACN,SAAS,KAAK;AAAA,UACd,UAAU,KAAK;AAAA,UACf,QAAQ,KAAK;AAAA,QACd;AAAA,QACA,cAAc;AAAA,QACd,QAAQ,CAAC,MAAgB;AAAA,UACxB,IAAI,EAAE,YAAY;AAAA,YAAmB;AAAA,UACrC,KAAK,IAAI;AAAA,UACT,QAAQ,EAAE,QAAQ,QAAQ;AAAA,YACzB,SAAS,QAAQ;AAAA,YACjB,QAAQ;AAAA,YACR,SAAS,EAAE;AAAA,eACP,EAAE,YAAY,cAAc,EAAE,QAAQ,gBAAgB,IAAI,CAAC;AAAA,UAChE,CAAC;AAAA;AAAA,QAEF,UAAU,CAAC,YAAY;AAAA,UACtB,IAAI,WAAW,YAAY,CAAC,IAAI,OAAO,SAAS;AAAA,YAC/C,MAAM;AAAA,YACN,OAAO,EAAE,OAAO,KAAK;AAAA,UACtB;AAAA,UACA,MAAM,SAAS,cACd,KAAK,OACL,OACA,QAAQ,SACR,UAAU,oBAAoB,QAC9B,UACD;AAAA,UACA,IAAI,WAAW;AAAA,YAAW,OAAO,EAAE,OAAO,OAAO,MAAM,OAAO;AAAA,UAE9D,OAAO,CAAC,UACL,EAAE,OAAO,MAAM,IACf;AAAA,YACA,OAAO;AAAA,YACP,OAAO;AAAA,cACN,QAAQ;AAAA,cACR,MAAM,eAAe;AAAA,cACrB,SAAS;AAAA,cACT,SAAS,EAAE,eAAe,cAAc;AAAA,YACzC;AAAA,UACD;AAAA;AAAA,MAEJ,CAAC;AAAA,MACD,MAAM,UAAU,MAAM,SAAS,aAAa;AAAA,MAC5C,IAAI,OAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAAA,MAC5D,MAAM,SAAS,MAAM,QAAQ,KAAK,CAAC,SAAS,UAAU,QAAQ,CAAC;AAAA,MAC/D,IAAI,WAAW;AAAA,QAAO,OAAO;AAAA,MAC7B,IAAI,OAAO,oBAAoB,SAAS,OAAO;AAAA,MAC/C,UAAU;AAAA,IACX;AAAA;AAAA,EAOD,SAAS,WAAW,CACnB,OACA,OACA,WACA,SAKA,QACW;AAAA,IAEX,MAAM,OAAO,SAAS,IAAI,SAAS;AAAA,IACnC,IACC,CAAC,WACD,MAAM,UAAU,QAChB,KAAK,aAAa,aAClB,KAAK,mBACJ;AAAA,MAED,QAAQ,KAAK,QAAQ,EAAE,QAAQ,qBAAqB,CAAC;AAAA,MACrD,OAAO,SAAS,KAAK,OAAO,eAAe,WAAW,gBAAgB;AAAA,WAClE;AAAA,QACH,eAAe;AAAA,MAChB,CAAC;AAAA,IACF;AAAA,IACA,MAAM,QAAsB,UACzB,eACA,MAAM,UAAU,QAChB,KAAK,aAAa,aAClB,KAAK,KAAK,YAAY,SACrB,eACA;AAAA,IACJ,MAAM,SAAS,UAAU,eAAe,eAAe;AAAA,IACvD,MAAM,SAAS,cACd,OACA,OACA,MAAM,WAAW,SAAS,IAAI,SAAS,GAAG,SAC1C,OACA,UACD;AAAA,IACA,IAAI,WAAW,WAAW;AAAA,MAEzB,QAAQ,KAAK,QAAQ,EAAE,OAAO,CAAC;AAAA,MAC/B,OAAO,UAAU,eACd,SACA,KACA,OACA,eAAe,YACf,4BACA,KAAK,aAAa,eAAe,cAAc,CAChD,IACC,SACA,KACA,OACA,eAAe,aACf,yBACA,WACD;AAAA,IACH;AAAA,IACA,QAAQ,KAAK,QAAQ,EAAE,OAAO,CAAC;AAAA,IAC/B,OAAO,IAAI,SAAS,QAAQ;AAAA,MAC3B,QAAQ;AAAA,MACR,SAAS,KAAK,aAAa,gBAAgB,mBAAmB;AAAA,IAC/D,CAAC;AAAA;AAAA,EAGF,SAAS,SAAS,CAAC,KAAwB;AAAA,IAC1C,IAAI,CAAC,OAAO;AAAA,MACX,OAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,KAAK,SAAS,EAAE,OAAO,OAAO,EAAE,CAAC;AAAA,IACtE,MAAM,YAAY,IAAI,QAAQ,IAAI,gCAAgC,KAAK;AAAA,IACvE,OAAO,IAAI,SAAS,MAAM;AAAA,MACzB,QAAQ;AAAA,MACR,SAAS;AAAA,WACL;AAAA,QACH,gCAAgC;AAAA,QAChC,gCACC,cAAc,KACX,YACA;AAAA,QACJ,0BAA0B;AAAA,MAC3B;AAAA,IACD,CAAC;AAAA;AAAA,EAGF,MAAM,mBAAmB,MACxB,IAAI,SAAS,MAAM;AAAA,IAClB,QAAQ;AAAA,IACR,SAAS,KAAK,aAAa,OAAO,OAAO;AAAA,EAC1C,CAAC;AAAA,EAEF,MAAM,WAAW,MAChB,IAAI,SAAS,MAAM,EAAE,QAAQ,KAAK,SAAS,EAAE,OAAO,gBAAgB,EAAE,CAAC;AAAA,EAUxE,MAAM,gBAAgB,OAAO,iBAAiB;AAAA,EAC9C,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI,YAAY;AAAA,EAChB,IAAI,aAAa;AAAA,EACjB,eAAe,QAAQ,GAAyB;AAAA,IAC/C,IAAI;AAAA,IACJ,MAAM,WAAW,IAAI,QAAyB,CAAC,YAAY;AAAA,MAC1D,QAAQ,WACP,MAAM,QAAQ,eAAe,GAC7B,uBACD;AAAA,KACA;AAAA,IAGD,MAAM,OAAO,QAAQ,QAAQ,EAC3B,KAAK,MAAM,MAAM,IAAI,iBAAiB,CAAC,EACvC,KAAK,MAAM,IAAa;AAAA,IAC1B,KAAK,MAAM,MAAM,EAAE;AAAA,IACnB,IAAI;AAAA,MACH,MAAM,SAAS,MAAM,QAAQ,KAAK,CAAC,MAAM,QAAQ,CAAC;AAAA,MAClD,IAAI,WAAW,iBAAiB;AAAA,QAC/B,OAAO,KAAK,gBAAgB,EAAE,OAAO,UAAU,CAAC;AAAA,QAChD;AAAA,QACA,aAAa,KAAK,IAAI;AAAA,QACtB,MAAM,UAAU,MAAM;AAAA,UACrB;AAAA;AAAA,QAED,KAAK,KAAK,SAAS,OAAO;AAAA,MAC3B;AAAA,MACA,OAAO;AAAA,MACN,OAAO,OAAO;AAAA,MACf,OAAO,KAAK,gBAAgB,EAAE,OAAO,UAAU,KAAK,EAAE,CAAC;AAAA,MACvD,OAAO;AAAA,cACN;AAAA,MACD,aAAa,KAAK;AAAA;AAAA;AAAA,EAGpB,SAAS,WAAW,GAAyB;AAAA,IAC5C,IAAI,UAAU;AAAA,MAAW,OAAO;AAAA,IAChC,MAAM,MAAM,KAAK,IAAI;AAAA,IACrB,IAAI,WAAW,aAAa,MAAM,OAAO,KAAK,iBAAiB;AAAA,MAC9D,OAAO,QAAQ,QAAQ,OAAO,MAAM;AAAA,IACrC;AAAA,IACA,IAAI,YAAY,KAAK,MAAM,aAAa,eAAe;AAAA,MACtD,OAAO,QAAQ,QAAQ,eAAe;AAAA,IACvC;AAAA,IACA,MAAM,UAAU,SAAS,EAAE,MAAM,MAAmB,mBAAmB;AAAA,IACvE,QAAQ;AAAA,IACH,QAAQ,KAAK,CAAC,WAAW;AAAA,MAC7B,SAAS,EAAE,IAAI,KAAK,IAAI,GAAG,OAAO;AAAA,MAClC,IAAI,UAAU;AAAA,QAAS,QAAQ;AAAA,KAC/B;AAAA,IACD,OAAO;AAAA;AAAA,EAGR,MAAM,UAAU,oBAAoB,MAAM;AAAA,EAC1C,MAAM,OAAO,CAAC,KAAc,QAC3B,YAAY,SAAS,KAAK,GAAG,CAAC;AAAA,EAC/B,MAAM,SAAS,IAAI,MAAM;AAAA,IACxB,MAAM,OAAO;AAAA,IACb,UAAU,OAAO;AAAA,IACjB,aAAa;AAAA,IACb,oBAAoB,UAAU;AAAA,IAC9B,aAAa,OAAO;AAAA,IACpB,QAAQ;AAAA,MACP,YAAY;AAAA,QAGX,KAAK,YAAY;AAAA,UAChB,MAAM,QAAQ,MAAM,YAAY;AAAA,UAChC,IAAI,UAAU,MAAM;AAAA,YAEnB,OAAO,KACN,KACA,EAAE,QAAQ,aAAa,QAAQ,OAAO,SAAS,QAAQ,GACvD,EAAE,iBAAiB,WAAW,CAC/B;AAAA,UACD;AAAA,UACA,OAAO,KACN,KACA;AAAA,YACC,QAAQ;AAAA,YACR,SAAS;AAAA,YACT,UAAU,EAAE,wBAAwB,kBAAkB;AAAA,UACvD,GACA,EAAE,iBAAiB,WAAW,CAC/B;AAAA;AAAA,MAEF;AAAA,MACA,KAAK;AAAA,QACJ,KAAK,MACJ,IAAI,SAAS,YAAY;AAAA,UACxB,SAAS;AAAA,YACR,gBAAgB;AAAA,YAChB,2BACC;AAAA,YACD,0BAA0B;AAAA,YAC1B,iBAAiB;AAAA,UAClB;AAAA,QACD,CAAC;AAAA,MACH;AAAA,MAEA,gBAAgB,EAAE,KAAK,MAAM,KAAK,aAAa,cAAc,EAAE;AAAA,MAC/D,gBAAgB,EAAE,KAAK,MAAM,KAAK,aAAa,eAAe,EAAE;AAAA,MAChE,yBAAyB;AAAA,QACxB,KAAK,MAAM,KAAK,kBAAkB,WAAW;AAAA,MAC9C;AAAA,MACA,QAAQ,CAAC,KAAK,QAAQ,UAAU,KAAK,GAAG;AAAA,MACxC,2CAA2C;AAAA,QAC1C,KAAK,MAAM,KAAK,SAAS;AAAA,QACzB,SAAS,MAAM,KAAK,UAAU,KAAK;AAAA,MACpC;AAAA,MACA,mDAAmD;AAAA,QAClD,KAAK,CAAC,QAAQ,KAAK,kBAAkB,IAAI,OAAO,EAAE;AAAA,QAClD,SAAS,MAAM,KAAK,UAAU,KAAK;AAAA,MACpC;AAAA,MACA,cAAc;AAAA,QACb,KAAK,CAAC,KAAK,QAAQ,KAAK,UAAU,KAAK,KAAK,KAAK,GAAG,CAAC;AAAA,QACrD,MAAM,CAAC,KAAK,QAAQ,KAAK,gBAAgB,KAAK,KAAK,KAAK,GAAG,CAAC;AAAA,MAC7D;AAAA,MACA,uBAAuB;AAAA,QACtB,KAAK,CAAC,KAAK,QAAQ,KAAK,kBAAkB,KAAK,KAAK,KAAK,GAAG,CAAC;AAAA,MAC9D;AAAA,MACA,kBAAkB,EAAE,KAAK,MAAM,KAAK,WAAW,EAAE;AAAA,MACjD,UAAU;AAAA,QACT,MAAM,CAAC,KAAK,QAAQ,KAAK,MAAM,KAAK,KAAK,KAAK,GAAG,CAAC;AAAA,QAClD,SAAS,MAAM,KAAK,UAAU,MAAM;AAAA,QACpC,KAAK;AAAA,MACN;AAAA,MACA,WAAW;AAAA,QACV,MAAM,CAAC,KAAK,QAAQ,KAAK,OAAO,KAAK,KAAK,KAAK,GAAG,CAAC;AAAA,QACnD,SAAS,MAAM,KAAK,UAAU,MAAM;AAAA,QACpC,KAAK;AAAA,MACN;AAAA,MACA,cAAc;AAAA,QACb,MAAM,CAAC,KAAK,QAAQ;AAAA,UACnB,MAAM,KAAK,IAAI,OAAO;AAAA,UACtB,IAAI,CAAC,YAAY,EAAE;AAAA,YAClB,OAAO,IAAI,SAAS,aAAa,EAAE,QAAQ,IAAI,CAAC;AAAA,UACjD,OAAO,UAAU,KAAK,KAAK,EAAE;AAAA;AAAA,QAE9B,SAAS,CAAC,QAAQ,UAAU,GAAG;AAAA,QAC/B,KAAK;AAAA,QACL,QAAQ;AAAA,QACR,KAAK;AAAA,QACL,OAAO;AAAA,MACR;AAAA,IACD;AAAA,IACA,OAAO,MAAM,IAAI,SAAS,aAAa,EAAE,QAAQ,IAAI,CAAC;AAAA,IACtD,WAAW;AAAA,MACV,MAAM,CAAC;AAAA,MACP,kBAAkB,UAAU;AAAA,MAC5B,mBAAmB,OAAO;AAAA,MAC1B,0BAA0B;AAAA,MAC1B,aAAa;AAAA,MACb,WAAW;AAAA,MACX,mBAAmB;AAAA,MACnB,IAAI,CAAC,IAA6B;AAAA,QACjC,MAAM,UAAU,IAAI,WACnB,IACA,GAAG,KAAK,IACR,GAAG,KAAK,QACR,GAAG,KAAK,MACR,MACA,GAAG,KAAK,OACT;AAAA,QACA,GAAG,KAAK,UAAU;AAAA,QAClB,YAAY,IAAI,OAAO;AAAA;AAAA,MAExB,OAAO,CAAC,IAA6B,SAA0B;AAAA,QAC9D,GAAG,KAAK,SAAS,YAChB,OAAO,YAAY,WAAW,UAAU,IAAI,WAAW,OAAO,CAC/D;AAAA;AAAA,MAED,KAAK,CAAC,IAA6B,MAAc;AAAA,QAChD,GAAG,KAAK,SAAS,OAAO,IAAI;AAAA;AAAA,IAE9B;AAAA,EACD,CAAC;AAAA,EAED,IAAI;AAAA,EAEJ,IAAI,UAAU;AAAA,EACd,MAAM,OAAO,OAAO,QAAQ,OAAO;AAAA,EACnC,IAAI,cAAc;AAAA,IAAI,YAAY,oBAAoB;AAAA,EAEtD,MAAM,QAAQ,YAAY,MAAM;AAAA,IAC/B,KAAK,MAAM;AAAA,IACX,MACE,cAAc,KAAK,IAAI,CAAC,EACxB,KAAK,CAAC,MAAM;AAAA,MACZ,IAAI,IAAI;AAAA,QAAG,OAAO,MAAM,eAAe,EAAE,SAAS,EAAE,CAAC;AAAA,KACrD,EACA,MAAM,CAAC,UACP,OAAO,MAAM,eAAe;AAAA,MAC3B,IAAI;AAAA,MACJ,OAAO,UAAU,KAAK;AAAA,IACvB,CAAC,CACF;AAAA,KACC,OAAO,eAAe;AAAA,EAEzB,MAAM,YACL,OAAO,mBAAmB,MACvB,MACA,OAAO,eAAe,SAAS,OAAO,MAAM;AAAA,EAChD,IAAI,OAAO,mBAAmB,KAAK;AAAA,IAClC,OAAO,KAAK,oBAAoB;AAAA,MAC/B,SACC;AAAA,IACF,CAAC;AAAA,EACF,EAAO,SAAI,cAAc,GAAG;AAAA,IAC3B,OAAO,KAAK,oBAAoB;AAAA,MAC/B,SACC;AAAA,IACF,CAAC;AAAA,EACF;AAAA,EACA,OAAO,KAAK,eAAe;AAAA,IAC1B,SAAS;AAAA,IACT,KAAK;AAAA,IACL;AAAA,IACA,OAAO,YAAY,OAAO,QAAQ;AAAA,IAClC,SAAS;AAAA,EACV,CAAC;AAAA,EAED,OAAO;AAAA,IACN,KAAK;AAAA,IACL;AAAA,IACA;AAAA,IACA,YAAY,CAAC,WAAW,GAAG,eAAe,oBAAoB,MAAM;AAAA,QAChE,YAAY,GAAG;AAAA,MAClB,OAAO,YAAY;AAAA;AAAA,IAEpB,IAAI,GAAG;AAAA,MACN,UAAU;AAAA,MACV,cAAc,YAAY;AAAA,QACzB,cAAc,KAAK;AAAA,QACnB,WAAW,OAAO,CAAC,GAAG,QAAQ,OAAO,CAAC,GAAG;AAAA,UACxC,WAAW,QAAQ,CAAC,GAAG,GAAG;AAAA,YAAG,KAAK,SAAS;AAAA,QAC5C;AAAA,QACA,WAAW,WAAW,CAAC,GAAG,WAAW,GAAG;AAAA,UACvC,QAAQ,IACP,UAAU,cACV,uBACA,UACD;AAAA,QACD;AAAA,QACA,MAAM,IAAI,MAAM,EAAE;AAAA,QAClB,MAAM,OAAO,KAAK,IAAI;AAAA,QACtB,IAAI;AAAA,UAAW,MAAM,MAAM,QAAQ;AAAA,QACnC,OAAO,KAAK,cAAc,CAAC,CAAC;AAAA,SAC1B;AAAA,MACH,OAAO;AAAA;AAAA,EAET;AAAA;",
28
+ "debugId": "BA745D07E3DF06AF64756E2164756E21",
28
29
  "names": []
29
30
  }