{"version":3,"sources":["../../src/receiver/index.ts","../../src/receiver/extract.ts","../../src/receiver/verify.ts","../../src/receiver/check.ts","../../src/receiver/start.ts","../../src/receiver/finalize.ts","../../src/receiver/hono/index.ts"],"sourcesContent":["/**\n * @packageDocumentation\n * @module act-http/receiver\n *\n * Server-side helpers for the inbound HTTP role — the receiver that\n * sits on the other end of an `@rotorsoft/act-http/webhook` POST.\n *\n * The subpath hosts two primitives today:\n *\n * - {@link extractIdempotencyKey} — case-insensitive\n *   `Idempotency-Key` parser; pair with `IdempotencyStore.claim`\n *   from `@rotorsoft/act-ops/idempotency` for dedup.\n * - {@link verifyWebhook} — HMAC-SHA256 signature + timestamp\n *   verifier; pair with `webhook({ secret })` from\n *   `@rotorsoft/act-http/webhook` for authenticated, replay-resistant\n *   delivery.\n *\n * The framework-agnostic middleware that wires these into request\n * handlers, plus per-framework adapters (tRPC / Express / Fastify /\n * Hono), lands in #744 (ACT-1116).\n *\n * Sibling subpaths in the same package:\n *\n * - `@rotorsoft/act-http/webhook` — the sender side: outbound POSTs,\n *   automatic `Idempotency-Key`, status-classified retries, optional\n *   HMAC signing.\n * - `@rotorsoft/act-http/sse` — incremental state broadcast over\n *   Server-Sent Events.\n *\n * The receiver subpath ships from the same package as `/webhook` so\n * a service that both sends and receives webhooks installs one\n * dependency. The dedup contract that links them lives in\n * `@rotorsoft/act-ops/idempotency`.\n */\n\nexport {\n  type CheckFailureReason,\n  type CheckResult,\n  type CheckWebhookOptions,\n  checkWebhook,\n} from \"./check.js\";\nexport { extractIdempotencyKey } from \"./extract.js\";\nexport { receiver } from \"./start.js\";\nexport {\n  type VerifyOptions,\n  type VerifyResult,\n  verifyWebhook,\n} from \"./verify.js\";\n","/**\n * Pull the `Idempotency-Key` header from a Node-style headers bag,\n * case-insensitive. Returns `undefined` when any of the following\n * carries no usable key:\n *\n * - the header is missing\n * - its value is an array (ambiguous — can't pick one without a\n *   policy the receiver hasn't declared)\n * - its value is the empty string (carries no idempotency\n *   information; structurally equivalent to \"no header at all\")\n *\n * Pair with `IdempotencyStore.claim` from\n * `@rotorsoft/act-ops/idempotency`: extract the key from the inbound\n * request, claim it on the store, return a `deduped` marker when the\n * claim fails. The framework-agnostic middleware that wires these\n * together lands in #744.\n *\n * Validation beyond \"is there a usable key?\" (length bounds, format\n * checks, normalization) is intentionally out of scope. Receivers\n * picking a policy can layer it on top — or, when #744 ships, opt\n * into the middleware's opinionated defaults.\n */\nexport function extractIdempotencyKey(\n  headers: Record<string, string | string[] | undefined>\n): string | undefined {\n  for (const [name, value] of Object.entries(headers)) {\n    if (name.toLowerCase() !== \"idempotency-key\") continue;\n    if (Array.isArray(value)) return undefined;\n    if (value === \"\") return undefined;\n    return value;\n  }\n  return undefined;\n}\n","import { createHmac, timingSafeEqual } from \"node:crypto\";\n\n/**\n * Outcome of {@link verifyWebhook}. Either the request signature\n * checks out, or one of five distinct failure reasons applies. Each\n * reason maps to an operator-meaningful telemetry bucket — separated\n * deliberately so dashboards can distinguish \"client lost its secret\"\n * from \"client clock is wrong\" from \"this is a replay attack.\"\n */\nexport type VerifyResult =\n  | { ok: true }\n  | {\n      ok: false;\n      reason:\n        | \"missing-signature\"\n        | \"missing-timestamp\"\n        | \"stale\"\n        | \"future\"\n        | \"bad-signature\";\n    };\n\n/** Options for {@link verifyWebhook}. */\nexport type VerifyOptions = {\n  /**\n   * Maximum acceptable timestamp drift in either direction, in\n   * seconds. Default: 300 (±5 minutes) — matches Stripe / GitHub /\n   * Slack conventions. Tightening narrows the replay window;\n   * loosening accommodates clients with worse clock sync.\n   */\n  maxAgeSeconds?: number;\n  /**\n   * Current Unix-seconds time. Exposed for tests; production\n   * callers should leave it undefined so wall-clock is used.\n   */\n  now?: number;\n};\n\n/**\n * Verify an inbound webhook's signature and timestamp against the\n * shared secret. Pair with the sender side: configure\n * `webhook({ secret })` from `@rotorsoft/act-http/webhook`.\n *\n * Returns `{ ok: true }` on success or `{ ok: false; reason }` on\n * failure. The reasons are:\n *\n * - `missing-signature` — no `X-Webhook-Signature` header, value\n *   was an array, or value was empty.\n * - `missing-timestamp` — no `X-Webhook-Timestamp` header, value\n *   was empty, or value isn't a parseable integer.\n * - `stale` — timestamp older than `maxAgeSeconds` from `now`.\n * - `future` — timestamp more than `maxAgeSeconds` ahead of `now`.\n * - `bad-signature` — signature header didn't start with `sha256=`,\n *   wasn't 64 hex chars, or the recomputed HMAC didn't match\n *   (constant-time compare).\n *\n * The signed payload is `${timestamp}.${body}`, so `body` must be\n * the **raw request body bytes**. Any pre-parse normalization\n * (whitespace trimming, JSON re-stringification) would change the\n * hash and reject every otherwise-valid request. Framework adapters\n * in #744 will provide the raw body alongside the parsed one.\n *\n * Uses Node's `crypto.timingSafeEqual` for the final comparison to\n * avoid signature-equality timing attacks.\n */\nexport function verifyWebhook(\n  headers: Record<string, string | string[] | undefined>,\n  body: string,\n  secret: string,\n  options?: VerifyOptions\n): VerifyResult {\n  const maxAgeSeconds = options?.maxAgeSeconds ?? 300;\n  const now = options?.now ?? Math.floor(Date.now() / 1000);\n\n  const signature = pick_header(headers, \"x-webhook-signature\");\n  if (!signature) return { ok: false, reason: \"missing-signature\" };\n\n  const timestamp_str = pick_header(headers, \"x-webhook-timestamp\");\n  if (!timestamp_str) return { ok: false, reason: \"missing-timestamp\" };\n  const timestamp = Number.parseInt(timestamp_str, 10);\n  if (Number.isNaN(timestamp) || String(timestamp) !== timestamp_str) {\n    return { ok: false, reason: \"missing-timestamp\" };\n  }\n\n  const delta = now - timestamp;\n  if (delta > maxAgeSeconds) return { ok: false, reason: \"stale\" };\n  if (delta < -maxAgeSeconds) return { ok: false, reason: \"future\" };\n\n  if (!signature.startsWith(\"sha256=\")) {\n    return { ok: false, reason: \"bad-signature\" };\n  }\n  const provided_hex = signature.slice(\"sha256=\".length);\n  if (!/^[0-9a-fA-F]{64}$/.test(provided_hex)) {\n    return { ok: false, reason: \"bad-signature\" };\n  }\n\n  const expected_hex = createHmac(\"sha256\", secret)\n    .update(`${timestamp_str}.${body}`)\n    .digest(\"hex\");\n\n  const a = Buffer.from(provided_hex, \"hex\");\n  const b = Buffer.from(expected_hex, \"hex\");\n  if (!timingSafeEqual(a, b)) {\n    return { ok: false, reason: \"bad-signature\" };\n  }\n\n  return { ok: true };\n}\n\nfunction pick_header(\n  headers: Record<string, string | string[] | undefined>,\n  lower_name: string\n): string | undefined {\n  for (const [name, value] of Object.entries(headers)) {\n    if (name.toLowerCase() !== lower_name) continue;\n    if (Array.isArray(value) || value === undefined || value === \"\") {\n      return undefined;\n    }\n    return value;\n  }\n  return undefined;\n}\n","import type { IdempotencyStore } from \"@rotorsoft/act-ops/idempotency\";\nimport { extractIdempotencyKey } from \"./extract.js\";\nimport { type VerifyOptions, verifyWebhook } from \"./verify.js\";\n\n/**\n * Failure reasons returned by {@link checkWebhook}. The shape splits\n * client/configuration errors (`missing-key`, `empty-body` — HTTP 400)\n * from the five verification failures (authentication errors, HTTP 401)\n * so each maps to its own telemetry bucket. `empty-body` is the\n * misconfigured-raw-parser signal: `secret` is set but the resolved\n * body is empty, so hashing it would compute an HMAC over `${ts}.` and\n * reject every otherwise-valid signed request with a misleading\n * bad-signature — a distinct config error is far easier to diagnose.\n */\nexport type CheckFailureReason =\n  | \"missing-key\"\n  | \"empty-body\"\n  | \"missing-signature\"\n  | \"missing-timestamp\"\n  | \"stale\"\n  | \"future\"\n  | \"bad-signature\";\n\n/**\n * Outcome of {@link checkWebhook}. Either the request passed every\n * configured check and carries a usable idempotency key, or it\n * failed one of them and the framework adapter should reply with the\n * corresponding HTTP status.\n */\nexport type CheckResult =\n  | { ok: false; status: 400 | 401; reason: CheckFailureReason }\n  | { ok: true; key: string; deduped: boolean };\n\n/** Options for {@link checkWebhook}. */\nexport type CheckWebhookOptions = {\n  /** Idempotency store the framework-agnostic core claims the key on. */\n  store: IdempotencyStore;\n  /**\n   * Optional HMAC-SHA256 secret. When set, the request's\n   * `X-Webhook-Signature` and `X-Webhook-Timestamp` headers are\n   * verified before the dedup claim. When omitted, signature\n   * verification is skipped (unsigned receivers).\n   */\n  secret?: string;\n  /**\n   * Verification options forwarded to {@link verifyWebhook}. Only\n   * meaningful when `secret` is set. Defaults to a ±300-second\n   * timestamp window.\n   */\n  verify?: VerifyOptions;\n};\n\n/**\n * Framework-agnostic receiver check: verify the signature (when a\n * secret is configured), extract the `Idempotency-Key`, and claim\n * it on the store. Returns the request's fate as a discriminated\n * union the per-framework adapter translates into the framework's\n * idiomatic 4xx response or context injection.\n *\n * **Order of checks** (matters):\n *\n * 1. Verify signature + timestamp window (when `secret` is set).\n *    Rejecting bad signatures *before* extracting and claiming the\n *    key keeps attacker-supplied keys out of the dedup store —\n *    otherwise a flood of spoofed POSTs would pollute the LRU.\n * 2. Extract the `Idempotency-Key`. Missing → reject with 400.\n * 3. Claim the key on the store. If already seen, return\n *    `{ ok: true; deduped: true }` so the framework adapter can\n *    short-circuit the handler without re-running side effects.\n *\n * The dedup store may be sync (`InMemoryIdempotencyStore`) or async\n * (durable adapters like a future `PostgresIdempotencyStore`); the\n * core awaits unconditionally so both shapes compose cleanly.\n */\nexport async function checkWebhook(\n  headers: Record<string, string | string[] | undefined>,\n  body: string,\n  options: CheckWebhookOptions\n): Promise<CheckResult> {\n  if (options.secret !== undefined) {\n    // Raw body not captured (default JSON parser ate the bytes) but a\n    // secret is configured — hashing the empty string is a guaranteed\n    // bad-signature. Surface a distinct configuration error instead of a\n    // misleading 401 so the operator mounts the raw-body parser.\n    if (body === \"\") {\n      return { ok: false, status: 400, reason: \"empty-body\" };\n    }\n    const verification = verifyWebhook(\n      headers,\n      body,\n      options.secret,\n      options.verify\n    );\n    if (!verification.ok) {\n      return { ok: false, status: 401, reason: verification.reason };\n    }\n  }\n\n  const key = extractIdempotencyKey(headers);\n  if (!key) return { ok: false, status: 400, reason: \"missing-key\" };\n\n  const claimed = await options.store.claim(key);\n  return { ok: true, key, deduped: !claimed };\n}\n","import type {\n  Receiver,\n  ReceiverBuilder,\n  ReceiverContext,\n  ReceiverOptions,\n  Validator,\n} from \"@rotorsoft/act-ops/receiver\";\nimport { Hono } from \"hono\";\nimport { webhookMiddleware } from \"./hono/index.js\";\n\n/**\n * Recommended factory for \"I want to receive webhooks.\" Returns a\n * {@link ReceiverBuilder} the operator configures fluently:\n *\n * ```ts\n * import { receiver } from \"@rotorsoft/act-http/receiver\";\n * import { InMemoryIdempotencyStore } from \"@rotorsoft/act-ops/idempotency\";\n * import { z } from \"zod\";\n *\n * const r = receiver({\n *   port: 4001,\n *   store: new InMemoryIdempotencyStore(),\n *   secret: process.env.WEBHOOK_SECRET,\n * })\n *   .on(\"OrderConfirmed\", z.object({\n *     orderId: z.string(),\n *     total: z.number(),\n *   }), async (event, ctx) => {\n *     // event.orderId and event.total are typed\n *     // ctx.key is the deduplicated Idempotency-Key\n *     await process_order(event.orderId, event.total);\n *   })\n *   .build();\n *\n * await r.listen();\n * ```\n *\n * Matches Act's builder pattern: `receiver(...)` is the factory,\n * `.on()` registers handlers fluently, `.build()` finalizes and\n * produces an immutable {@link Receiver} — at which point the type\n * loses `.on()` and gains the runtime methods (`listen` / `close` /\n * `fetch`). The lifecycle phases are split at the type level.\n *\n * Internally uses Hono for routing — the universal-runtime choice\n * that gives one code path coverage across Node, AWS Lambda,\n * Cloudflare Workers, Vercel Edge, Bun, and Deno. For operators\n * with an existing tRPC / Express / Fastify / Hono app who need to\n * compose the receiver with their own middleware stack, the\n * lower-level `webhookMiddleware` from\n * `@rotorsoft/act-http/receiver/<framework>` is the escape hatch.\n *\n * `@hono/node-server` is imported lazily inside `.listen()` so\n * Lambda / edge consumers (who never call `.listen()`) don't need\n * it installed.\n */\nexport function receiver(options: ReceiverOptions): ReceiverBuilder {\n  const app = new Hono<{\n    Variables: { idempotency: { key: string; deduped: boolean } };\n  }>();\n\n  const middleware = webhookMiddleware({\n    store: options.store,\n    secret: options.secret,\n  });\n\n  let built = false;\n\n  const builder: ReceiverBuilder = {\n    on<T>(\n      name: string,\n      schema: Validator<T>,\n      handler: (event: T, ctx: ReceiverContext) => Promise<void>\n    ): ReceiverBuilder {\n      if (built) {\n        throw new Error(\n          `Cannot register handler \"${name}\" after .build() — handlers are frozen once the receiver is built.`\n        );\n      }\n\n      app.post(`/${name}`, middleware, async (c) => {\n        let validated: T;\n        try {\n          const body = await c.req.json();\n          validated = schema.parse(body);\n        } catch (err) {\n          return c.json(\n            {\n              error: \"validation-failed\",\n              detail: (err as Error).message,\n            },\n            422\n          );\n        }\n\n        const idem = c.get(\"idempotency\");\n        if (!idem.deduped) {\n          try {\n            await handler(validated, { key: idem.key });\n          } catch (err) {\n            // Transient failure: release the tentative claim so the\n            // sender's retry re-processes instead of being deduped\n            // into a silent success and permanently lost. Finalize through\n            // the context's `settled`-guarded finalizer, NOT the raw store —\n            // the `webhookMiddleware` this route mounts auto-finalizes after\n            // `next()` too, and hitting the raw store here double-fires (a\n            // stale second `release` can delete a concurrent retry's live\n            // claim, breaking exactly-once). The guard collapses both into\n            // one store call (#1293).\n            await idem.release();\n            return c.json(\n              {\n                error: \"handler-failed\",\n                detail: (err as Error).message,\n              },\n              500\n            );\n          }\n          // Success: promote the tentative claim to a durable record so every\n          // later retry of this key dedups — again via the guarded finalizer,\n          // not the raw store (#1293).\n          await idem.commit();\n        }\n\n        return c.body(null, 204);\n      });\n\n      return builder;\n    },\n\n    build(): Receiver {\n      built = true;\n\n      // `any`: server lifecycle handle from @hono/node-server\n      let server: any | undefined;\n\n      return {\n        async listen(): Promise<void> {\n          const { serve } = await import(\"@hono/node-server\");\n          const launched = serve({ fetch: app.fetch, port: options.port });\n          server = launched;\n          await new Promise<void>((resolve) => {\n            launched.once(\"listening\", () => resolve());\n          });\n        },\n\n        async close(): Promise<void> {\n          if (!server) return;\n          const s = server;\n          server = undefined;\n          await new Promise<void>((resolve) => s.close(() => resolve()));\n        },\n\n        async fetch(request: Request): Promise<Response> {\n          return app.fetch(request);\n        },\n      };\n    },\n  };\n\n  return builder;\n}\n","import type { IdempotencyStore } from \"@rotorsoft/act-ops/idempotency\";\n\n/**\n * The two-phase finalizers a receiver adapter binds to a single\n * inbound delivery. The claim `checkWebhook` makes is *tentative*;\n * exactly one of these promotes or drops it once the business handler\n * resolves its outcome.\n */\nexport type Finalizers = {\n  /**\n   * Promote the tentative claim to a durable record so every later\n   * retry of this key dedups. Call on handler success.\n   */\n  commit: () => void | Promise<void>;\n  /**\n   * Drop the tentative claim so the sender's retry re-processes.\n   * Call on transient handler failure.\n   */\n  release: () => void | Promise<void>;\n};\n\n/**\n * Build the {@link Finalizers} for one delivery.\n *\n * Guarantees:\n *\n * - **Deduped deliveries are inert.** When `deduped` is `true` the key\n *   was already committed by an earlier delivery; both finalizers are\n *   no-ops so a duplicate can never release someone else's committed\n *   claim.\n * - **Finalize-once.** After the first `commit` or `release` fires,\n *   further calls are no-ops — an adapter that both auto-finalizes and\n *   lets the operator call `commit()`/`release()` can't double-fire.\n */\nexport function make_finalizers(\n  store: IdempotencyStore,\n  key: string,\n  deduped: boolean\n): Finalizers {\n  let settled = deduped;\n  return {\n    async commit() {\n      if (settled) return;\n      settled = true;\n      await store.commit(key);\n    },\n    async release() {\n      if (settled) return;\n      settled = true;\n      await store.release(key);\n    },\n  };\n}\n","/**\n * @packageDocumentation\n * @module act-http/receiver/hono\n *\n * Hono adapter for the receiver-side webhook check.\n *\n * Usage:\n *\n * ```ts\n * import { Hono } from \"hono\";\n * import { webhookMiddleware } from \"@rotorsoft/act-http/receiver/hono\";\n * import { InMemoryIdempotencyStore } from \"@rotorsoft/act-ops/idempotency\";\n *\n * const app = new Hono();\n * const dedup = new InMemoryIdempotencyStore();\n *\n * app.post(\n *   \"/webhooks/orders\",\n *   webhookMiddleware({ store: dedup, secret: process.env.WEBHOOK_SECRET }),\n *   async (c) => {\n *     const idem = c.get(\"idempotency\") as { key: string; deduped: boolean };\n *     if (idem.deduped) return c.json({ status: \"dedup-skipped\", key: idem.key });\n *     // ... process the inbound event ...\n *     return c.json({ status: \"processed\", key: idem.key });\n *   }\n * );\n * ```\n *\n * On failure: returns `c.json({ error: <reason> }, status)` directly\n * (Hono short-circuits when middleware returns a Response). On\n * success: stashes `c.set(\"idempotency\", { key, deduped })` and\n * continues with `await next()`.\n *\n * **Two-phase dedup**: the claim `checkWebhook` makes is *tentative*.\n * Because Hono middleware wraps the downstream chain, this adapter\n * finalizes the claim automatically after `await next()`: a downstream\n * 2xx/3xx **commits** the key (later retries dedup); any **4xx or 5xx**\n * (or a thrown handler) **releases** it, so the sender's corrected retry\n * re-processes instead of being silently dropped (#1364). Fail-safe is\n * toward reprocessing: releasing a deterministic 4xx costs bounded\n * re-delivery, while committing it would lose a delivery the handler\n * never accepted (the shipped `receiver()` returns 422 on a schema\n * mismatch, where the handler never runs). Operators who need explicit\n * control can still call `c.get(\"idempotency\").commit()` / `.release()`.\n *\n * **Raw body**: Hono exposes `await c.req.text()` natively, which\n * the middleware reads when `secret` is configured. No extra setup\n * needed.\n */\nimport type { MiddlewareHandler } from \"hono\";\nimport { type CheckWebhookOptions, checkWebhook } from \"../check.js\";\nimport { make_finalizers } from \"../finalize.js\";\n\n/**\n * Variables this middleware contributes to the Hono context. The\n * generic on the returned {@link MiddlewareHandler} threads it\n * through so route handlers downstream of `app.post(..., webhookMiddleware(...), handler)`\n * see `c.get(\"idempotency\")` typed without a manual cast.\n *\n * `commit` / `release` finalize the tentative claim — call one after\n * the handler resolves its outcome. This adapter also finalizes\n * automatically based on the response status, so explicit calls are\n * only needed when the auto-detection doesn't fit.\n */\nexport type WebhookVariables = {\n  idempotency: {\n    key: string;\n    deduped: boolean;\n    commit: () => void | Promise<void>;\n    release: () => void | Promise<void>;\n  };\n};\n\n/**\n * Build a Hono middleware that verifies the request signature (when\n * `secret` is set), enforces `Idempotency-Key`, and claims the key\n * on the configured store. See the module-level docs for usage.\n */\nexport function webhookMiddleware(\n  options: CheckWebhookOptions\n): MiddlewareHandler<{ Variables: WebhookVariables }> {\n  return async function check(c, next) {\n    const headers = headers_bag(c.req.raw.headers);\n    const rawBody = await c.req.text();\n    const result = await checkWebhook(headers, rawBody, options);\n    if (!result.ok) {\n      return c.json({ error: result.reason }, result.status);\n    }\n    const { commit, release } = make_finalizers(\n      options.store,\n      result.key,\n      result.deduped\n    );\n    c.set(\"idempotency\", {\n      key: result.key,\n      deduped: result.deduped,\n      commit,\n      release,\n    });\n    try {\n      await next();\n    } catch (err) {\n      await release();\n      throw err;\n    }\n    // Commit only a genuine success (2xx/3xx); release on any 4xx/5xx so a\n    // failed delivery's corrected same-key retry re-processes instead of being\n    // deduped into a silent success (#1364).\n    if (c.res.status >= 400) await release();\n    else await commit();\n  };\n}\n\nfunction headers_bag(\n  headers: Headers\n): Record<string, string | string[] | undefined> {\n  const out: Record<string, string | string[] | undefined> = {};\n  headers.forEach((value, key) => {\n    out[key] = value;\n  });\n  return out;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACsBO,SAAS,sBACd,SACoB;AACpB,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG;AACnD,QAAI,KAAK,YAAY,MAAM,kBAAmB;AAC9C,QAAI,MAAM,QAAQ,KAAK,EAAG,QAAO;AACjC,QAAI,UAAU,GAAI,QAAO;AACzB,WAAO;AAAA,EACT;AACA,SAAO;AACT;;;AChCA,yBAA4C;AAgErC,SAAS,cACd,SACA,MACA,QACA,SACc;AACd,QAAM,gBAAgB,SAAS,iBAAiB;AAChD,QAAM,MAAM,SAAS,OAAO,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAExD,QAAM,YAAY,YAAY,SAAS,qBAAqB;AAC5D,MAAI,CAAC,UAAW,QAAO,EAAE,IAAI,OAAO,QAAQ,oBAAoB;AAEhE,QAAM,gBAAgB,YAAY,SAAS,qBAAqB;AAChE,MAAI,CAAC,cAAe,QAAO,EAAE,IAAI,OAAO,QAAQ,oBAAoB;AACpE,QAAM,YAAY,OAAO,SAAS,eAAe,EAAE;AACnD,MAAI,OAAO,MAAM,SAAS,KAAK,OAAO,SAAS,MAAM,eAAe;AAClE,WAAO,EAAE,IAAI,OAAO,QAAQ,oBAAoB;AAAA,EAClD;AAEA,QAAM,QAAQ,MAAM;AACpB,MAAI,QAAQ,cAAe,QAAO,EAAE,IAAI,OAAO,QAAQ,QAAQ;AAC/D,MAAI,QAAQ,CAAC,cAAe,QAAO,EAAE,IAAI,OAAO,QAAQ,SAAS;AAEjE,MAAI,CAAC,UAAU,WAAW,SAAS,GAAG;AACpC,WAAO,EAAE,IAAI,OAAO,QAAQ,gBAAgB;AAAA,EAC9C;AACA,QAAM,eAAe,UAAU,MAAM,UAAU,MAAM;AACrD,MAAI,CAAC,oBAAoB,KAAK,YAAY,GAAG;AAC3C,WAAO,EAAE,IAAI,OAAO,QAAQ,gBAAgB;AAAA,EAC9C;AAEA,QAAM,mBAAe,+BAAW,UAAU,MAAM,EAC7C,OAAO,GAAG,aAAa,IAAI,IAAI,EAAE,EACjC,OAAO,KAAK;AAEf,QAAM,IAAI,OAAO,KAAK,cAAc,KAAK;AACzC,QAAM,IAAI,OAAO,KAAK,cAAc,KAAK;AACzC,MAAI,KAAC,oCAAgB,GAAG,CAAC,GAAG;AAC1B,WAAO,EAAE,IAAI,OAAO,QAAQ,gBAAgB;AAAA,EAC9C;AAEA,SAAO,EAAE,IAAI,KAAK;AACpB;AAEA,SAAS,YACP,SACA,YACoB;AACpB,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG;AACnD,QAAI,KAAK,YAAY,MAAM,WAAY;AACvC,QAAI,MAAM,QAAQ,KAAK,KAAK,UAAU,UAAa,UAAU,IAAI;AAC/D,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;;;AC9CA,eAAsB,aACpB,SACA,MACA,SACsB;AACtB,MAAI,QAAQ,WAAW,QAAW;AAKhC,QAAI,SAAS,IAAI;AACf,aAAO,EAAE,IAAI,OAAO,QAAQ,KAAK,QAAQ,aAAa;AAAA,IACxD;AACA,UAAM,eAAe;AAAA,MACnB;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AACA,QAAI,CAAC,aAAa,IAAI;AACpB,aAAO,EAAE,IAAI,OAAO,QAAQ,KAAK,QAAQ,aAAa,OAAO;AAAA,IAC/D;AAAA,EACF;AAEA,QAAM,MAAM,sBAAsB,OAAO;AACzC,MAAI,CAAC,IAAK,QAAO,EAAE,IAAI,OAAO,QAAQ,KAAK,QAAQ,cAAc;AAEjE,QAAM,UAAU,MAAM,QAAQ,MAAM,MAAM,GAAG;AAC7C,SAAO,EAAE,IAAI,MAAM,KAAK,SAAS,CAAC,QAAQ;AAC5C;;;AChGA,kBAAqB;;;AC2Bd,SAAS,gBACd,OACA,KACA,SACY;AACZ,MAAI,UAAU;AACd,SAAO;AAAA,IACL,MAAM,SAAS;AACb,UAAI,QAAS;AACb,gBAAU;AACV,YAAM,MAAM,OAAO,GAAG;AAAA,IACxB;AAAA,IACA,MAAM,UAAU;AACd,UAAI,QAAS;AACb,gBAAU;AACV,YAAM,MAAM,QAAQ,GAAG;AAAA,IACzB;AAAA,EACF;AACF;;;AC0BO,SAAS,kBACd,SACoD;AACpD,SAAO,eAAe,MAAM,GAAG,MAAM;AACnC,UAAM,UAAU,YAAY,EAAE,IAAI,IAAI,OAAO;AAC7C,UAAM,UAAU,MAAM,EAAE,IAAI,KAAK;AACjC,UAAM,SAAS,MAAM,aAAa,SAAS,SAAS,OAAO;AAC3D,QAAI,CAAC,OAAO,IAAI;AACd,aAAO,EAAE,KAAK,EAAE,OAAO,OAAO,OAAO,GAAG,OAAO,MAAM;AAAA,IACvD;AACA,UAAM,EAAE,QAAQ,QAAQ,IAAI;AAAA,MAC1B,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AACA,MAAE,IAAI,eAAe;AAAA,MACnB,KAAK,OAAO;AAAA,MACZ,SAAS,OAAO;AAAA,MAChB;AAAA,MACA;AAAA,IACF,CAAC;AACD,QAAI;AACF,YAAM,KAAK;AAAA,IACb,SAAS,KAAK;AACZ,YAAM,QAAQ;AACd,YAAM;AAAA,IACR;AAIA,QAAI,EAAE,IAAI,UAAU,IAAK,OAAM,QAAQ;AAAA,QAClC,OAAM,OAAO;AAAA,EACpB;AACF;AAEA,SAAS,YACP,SAC+C;AAC/C,QAAM,MAAqD,CAAC;AAC5D,UAAQ,QAAQ,CAAC,OAAO,QAAQ;AAC9B,QAAI,GAAG,IAAI;AAAA,EACb,CAAC;AACD,SAAO;AACT;;;AFlEO,SAAS,SAAS,SAA2C;AAClE,QAAM,MAAM,IAAI,iBAEb;AAEH,QAAM,aAAa,kBAAkB;AAAA,IACnC,OAAO,QAAQ;AAAA,IACf,QAAQ,QAAQ;AAAA,EAClB,CAAC;AAED,MAAI,QAAQ;AAEZ,QAAM,UAA2B;AAAA,IAC/B,GACE,MACA,QACA,SACiB;AACjB,UAAI,OAAO;AACT,cAAM,IAAI;AAAA,UACR,4BAA4B,IAAI;AAAA,QAClC;AAAA,MACF;AAEA,UAAI,KAAK,IAAI,IAAI,IAAI,YAAY,OAAO,MAAM;AAC5C,YAAI;AACJ,YAAI;AACF,gBAAM,OAAO,MAAM,EAAE,IAAI,KAAK;AAC9B,sBAAY,OAAO,MAAM,IAAI;AAAA,QAC/B,SAAS,KAAK;AACZ,iBAAO,EAAE;AAAA,YACP;AAAA,cACE,OAAO;AAAA,cACP,QAAS,IAAc;AAAA,YACzB;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAEA,cAAM,OAAO,EAAE,IAAI,aAAa;AAChC,YAAI,CAAC,KAAK,SAAS;AACjB,cAAI;AACF,kBAAM,QAAQ,WAAW,EAAE,KAAK,KAAK,IAAI,CAAC;AAAA,UAC5C,SAAS,KAAK;AAUZ,kBAAM,KAAK,QAAQ;AACnB,mBAAO,EAAE;AAAA,cACP;AAAA,gBACE,OAAO;AAAA,gBACP,QAAS,IAAc;AAAA,cACzB;AAAA,cACA;AAAA,YACF;AAAA,UACF;AAIA,gBAAM,KAAK,OAAO;AAAA,QACpB;AAEA,eAAO,EAAE,KAAK,MAAM,GAAG;AAAA,MACzB,CAAC;AAED,aAAO;AAAA,IACT;AAAA,IAEA,QAAkB;AAChB,cAAQ;AAGR,UAAI;AAEJ,aAAO;AAAA,QACL,MAAM,SAAwB;AAC5B,gBAAM,EAAE,MAAM,IAAI,MAAM,OAAO,mBAAmB;AAClD,gBAAM,WAAW,MAAM,EAAE,OAAO,IAAI,OAAO,MAAM,QAAQ,KAAK,CAAC;AAC/D,mBAAS;AACT,gBAAM,IAAI,QAAc,CAAC,YAAY;AACnC,qBAAS,KAAK,aAAa,MAAM,QAAQ,CAAC;AAAA,UAC5C,CAAC;AAAA,QACH;AAAA,QAEA,MAAM,QAAuB;AAC3B,cAAI,CAAC,OAAQ;AACb,gBAAM,IAAI;AACV,mBAAS;AACT,gBAAM,IAAI,QAAc,CAAC,YAAY,EAAE,MAAM,MAAM,QAAQ,CAAC,CAAC;AAAA,QAC/D;AAAA,QAEA,MAAM,MAAM,SAAqC;AAC/C,iBAAO,IAAI,MAAM,OAAO;AAAA,QAC1B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}