@thomasfosterau/legation 0.0.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal-JyoQMlfK.js","names":["make","make","layer","Hash.contentHash","Predicate.compareText","Hash.canonicalJson","Subset.make","LiveView.make","LiveView.del","LiveView.put","LiveView.result","Subset.apply","Hash.contentHash","Incremental.deltaFromChanges","Incremental.diff","Incremental.pageOf","Incremental.makeFilter","Incremental.makeMap","Incremental.makeDistinct","Incremental.makeGroupBy","Incremental.makeJoin","Incremental.makeOrderedWindow","make","Subset.hash","Subset.hash","Hash.canonicalJson","make","Collection.relationshipsOf","without","MirrorProtocol.FormMutationBegin","run","Subscriptions.counted","PullMarks.make","MirrorProtocol.mirrorUpdate","MirrorProtocol.relatedUpdate","MirrorProtocol.mutationStatesUpdate","Subset.hash","MirrorProtocol.namedKey","MirrorProtocol.relatedKey","Related.related","Related.query","MirrorProtocol.MUTATION_STATES_KEY","Query.tryPlan","Coverage.ofPlan","MirrorProtocol.decodeMirrorMessage","Coverage.NOT_PULLED","Predicate.eq","Predicate.ne","Predicate.gt","Predicate.gte","Predicate.lt","Predicate.lte","Predicate.isIn","Predicate.notIn","Predicate.isNotNull","Predicate.isNull","Predicate.always","Predicate.not","Predicate.and","Predicate.or","Mutator.make","MemoryBackend.validatedHandlers","MemoryBackend.handler","UnknownMutator.isError","Subset.apply","FilterCorpus.generateCorpus","FilterCorpus.DEFAULT_SEED","FilterCorpus.minimumRows","Subset.make","FilterCorpus.formatDisagreement","Predicate.eq","run","FanoutTopics.coarse","FanoutTopics.topicsForWrite","FanoutTopics.derivableSets","FanoutTopics.topicForSubset","FanoutTopics.collectionOf","InvalidationBus.InvalidationBus","Cvr.layerMemoryStore","InvalidationBus.layerInProcess"],"sources":["../src/SpecExport.ts","../src/Undo.ts","../src/Paced.ts","../src/Introspection.ts","../src/Incremental.ts","../src/Derive.ts","../src/LiveQuery.ts","../src/EngineAtoms.ts","../src/PromiseFacade.ts","../src/MirrorChannel.ts","../src/EngineHost.ts","../src/FilterCorpus.ts","../src/BackendContract.ts","../src/InvalidationSink.ts","../src/PushPoke.ts","../src/FanoutTopics.ts","../src/FanoutBroker.ts","../src/FanoutBus.ts","../src/BusBrokers.ts","../src/HintSource.ts","../src/SyncRoom.ts","../src/HttpCache.ts"],"sourcesContent":["/**\n * SpecExport\n *\n * Emit machine-readable API descriptions of an app's sync surface so bespoke\n * clients can be generated in any language (ADR-0017). The protocol is\n * schema-defined (Protocol.ts) and carrier-agnostic (ADR-0002); this module\n * turns those schemas — *specialized with the app's own collections, mutators\n * and queries* — into an OpenAPI document (the unary push/pull operations) and\n * an AsyncAPI document (push/pull plus the streamed poke channel).\n *\n * The value is specialization. The wire protocol moves `unknown` values and\n * args; a generic spec describes an opaque envelope. Here each message is\n * narrowed to a discriminated union over the app's actual names — a `Mutation`\n * per mutator (its `args` schema), a patch `Put` per collection (its row\n * schema), a named subscription per query — so a generated client gets\n * concrete, per-name types instead of `any`.\n *\n * The pipeline is two steps so new formats are cheap to add: `build` produces a\n * format-neutral {@link SyncSpec} (a shared JSON-Schema component pool plus the\n * names of each message), and the emitters (`toOpenApi`, `toAsyncApi`, or your\n * own) project that into a concrete document.\n *\n * The emitted OpenAPI is the protocol's *logical REST projection*: push and\n * pull as `POST {path}/push` and `POST {path}/pull`. The default RPC carrier\n * (RpcTransport.ts) multiplexes both over a single endpoint with its own\n * envelope; the projection is the codegen-friendly contract, equally servable\n * by a thin REST adapter.\n */\n\nimport * as Arr from \"effect/Array\";\nimport * as JsonSchema from \"effect/JsonSchema\";\nimport * as Schema from \"effect/Schema\";\nimport type * as SchemaAST from \"effect/SchemaAST\";\nimport * as SchemaRepresentation from \"effect/SchemaRepresentation\";\nimport * as Str from \"effect/String\";\nimport type * as Collection from \"./Collection.js\";\nimport type * as Mutator from \"./Mutator.js\";\nimport {\n Mutation,\n NamedSubscription,\n PatchOp,\n Poke,\n PushResponse,\n RejectedMutation,\n} from \"./Protocol.js\";\nimport type * as Query from \"./Query.js\";\nimport { Subset } from \"./Subset.js\";\n\n// ─── Inputs ──────────────────────────────────────────────────────────────────\n\n/** Document metadata shared by every emitted format. */\nexport interface SpecInfo {\n readonly title: string;\n readonly version: string;\n readonly description?: string;\n}\n\n/**\n * The app's sync surface to describe: its collections, mutators and queries.\n * All are optional — a read-only or write-only app still yields a valid spec —\n * and the protocol messages are always present.\n */\nexport interface SyncApi {\n readonly info: SpecInfo;\n readonly collections?: ReadonlyArray<Collection.AnyCollection>;\n readonly mutators?: ReadonlyArray<Mutator.AnyMutator>;\n readonly queries?: ReadonlyArray<Query.AnyQuery>;\n /** Base path the sync RPCs are served on. Defaults to `\"/sync\"`. */\n readonly path?: string;\n}\n\n// ─── Intermediate representation ───────────────────────────────────────────────\n\n/** The component name an app type resolves to in the shared schema pool. */\nexport interface NamedSchema {\n readonly name: string;\n readonly schema: string;\n}\n\n/**\n * A format-neutral description of a sync surface: a shared component pool of\n * JSON Schemas (OpenAPI-style `#/components/schemas/...` refs) plus the\n * component name of each protocol message and app type. Emitters project this\n * into a concrete document; adding a format means adding a `toX(spec)`.\n */\nexport interface SyncSpec {\n readonly info: SpecInfo;\n readonly path: string;\n /** Shared JSON-Schema component pool (draft-2020-12, OpenAPI-style refs). */\n readonly components: JsonSchema.Definitions;\n /** Component name of each protocol message. */\n readonly messages: {\n readonly pushRequest: string;\n readonly pushResponse: string;\n readonly pullRequest: string;\n readonly pullResponse: string;\n readonly poke: string;\n readonly error: string;\n };\n /** App types, each with the component name of its specialized schema. */\n readonly catalog: {\n readonly collections: ReadonlyArray<NamedSchema>;\n readonly mutators: ReadonlyArray<NamedSchema>;\n readonly queries: ReadonlyArray<NamedSchema>;\n };\n}\n\n// ─── Component naming ──────────────────────────────────────────────────────────\n\n/** Coerce an arbitrary name into a `$ref`-safe component identifier fragment. */\nconst sanitize = (name: string): string => {\n const cleaned = name.replace(/[^A-Za-z0-9_]/g, \"_\").replace(/^_+|_+$/g, \"\");\n if (Str.isEmpty(cleaned)) return \"x\";\n return /^[0-9]/.test(cleaned) ? `n${cleaned}` : cleaned;\n};\n\n/** A namer that keeps identifiers unique by suffixing collisions (`_2`, `_3`). */\nconst uniqueNamer = () => {\n const seen = new Set<string>();\n return (prefix: string, name: string): string => {\n const base = `${prefix}${sanitize(name)}`;\n // `base`, then `base_2`, `base_3`, … until one is free.\n const at = (n: number): string => (n < 2 ? base : `${base}_${n}`);\n const free = (n: number): string => (seen.has(at(n)) ? free(n + 1) : at(n));\n const candidate = free(1);\n seen.add(candidate);\n return candidate;\n };\n};\n\n// ─── Specialized schemas ───────────────────────────────────────────────────────\n\nconst id = <S extends Schema.Top>(schema: S, identifier: string): S =>\n schema.annotate({ identifier }) as S;\n\n/** The serializable failure carried on sync operations (RpcTransport's). */\nconst SyncError = Schema.Struct({\n _tag: Schema.tag(\"SyncRpcError\"),\n message: Schema.String,\n});\n\n/**\n * Build the specialized message schemas, each tagged with a stable component\n * identifier. Where the app provides names the generic `unknown` envelope is\n * narrowed to a discriminated union; otherwise the generic schema stands in.\n */\nconst specialize = (api: SyncApi) => {\n const collections = api.collections ?? [];\n const mutators = api.mutators ?? [];\n const queries = api.queries ?? [];\n const name = uniqueNamer();\n\n const collectionNames = collections.map((c) => ({ def: c, schema: name(\"Row_\", c.name) }));\n const mutatorNames = mutators.map((m) => ({ def: m, schema: name(\"MutatorArgs_\", m.name) }));\n const queryNames = queries.map((q) => ({ def: q, schema: name(\"QueryArgs_\", q.name) }));\n\n // Mutation: one variant per mutator, discriminated by `mutator` name.\n const mutation = Arr.isReadonlyArrayEmpty(mutatorNames)\n ? id(Mutation, \"Mutation\")\n : id(\n Schema.Union(\n mutatorNames.map(({ def, schema }) =>\n id(\n Schema.Struct({\n clientId: Schema.String,\n mutationId: Schema.Number,\n mutator: Schema.Literal(def.name),\n args: id(def.args, schema),\n createdAt: Schema.Number,\n }),\n `Mutation_${sanitize(def.name)}`\n )\n )\n ),\n \"Mutation\"\n );\n\n // PatchOp: a `Put` variant per collection (its row schema), plus Del/Clear.\n const patchOp = Arr.isReadonlyArrayEmpty(collectionNames)\n ? id(PatchOp, \"PatchOp\")\n : id(\n Schema.Union([\n ...collectionNames.map(({ def, schema }) =>\n id(\n Schema.Struct({\n _tag: Schema.tag(\"Put\"),\n collection: Schema.Literal(def.name),\n id: Schema.String,\n version: Schema.Union([Schema.String, Schema.Number]),\n value: id(def.schema, schema),\n }),\n `Put_${sanitize(def.name)}`\n )\n ),\n Schema.Struct({\n _tag: Schema.tag(\"Del\"),\n collection: Schema.String,\n id: Schema.String,\n }),\n Schema.Struct({ _tag: Schema.tag(\"Clear\") }),\n ]),\n \"PatchOp\"\n );\n\n // NamedSubscription: one variant per query (its args schema).\n const namedSubscription = Arr.isReadonlyArrayEmpty(queryNames)\n ? id(NamedSubscription, \"NamedSubscription\")\n : id(\n Schema.Union(\n queryNames.map(({ def, schema }) =>\n id(\n Schema.Struct({ name: Schema.Literal(def.name), args: id(def.args, schema) }),\n `NamedSubscription_${sanitize(def.name)}`\n )\n )\n ),\n \"NamedSubscription\"\n );\n\n const pushRequest = id(\n Schema.Struct({ clientGroupId: Schema.String, mutations: Schema.Array(mutation) }),\n \"PushRequest\"\n );\n const pullRequest = id(\n Schema.Struct({\n clientGroupId: Schema.String,\n cookie: Schema.optional(Schema.String),\n subscriptions: Schema.Array(id(Subset, \"Subset\")),\n namedSubscriptions: Schema.optional(Schema.Array(namedSubscription)),\n }),\n \"PullRequest\"\n );\n const pullResponse = id(\n Schema.Struct({\n cookie: Schema.String,\n patch: Schema.Array(patchOp),\n lastMutationIds: Schema.Record(Schema.String, Schema.Number),\n rejected: Schema.optional(Schema.Array(RejectedMutation)),\n }),\n \"PullResponse\"\n );\n\n const roots: [SchemaAST.AST, ...Array<SchemaAST.AST>] = [\n pushRequest.ast,\n id(PushResponse, \"PushResponse\").ast,\n pullRequest.ast,\n pullResponse.ast,\n id(Poke, \"Poke\").ast,\n id(SyncError, \"SyncRpcError\").ast,\n ];\n\n return {\n roots,\n catalog: {\n collections: collectionNames.map(({ def, schema }) => ({ name: def.name, schema })),\n mutators: mutatorNames.map(({ def, schema }) => ({ name: def.name, schema })),\n queries: queryNames.map(({ def, schema }) => ({ name: def.name, schema })),\n },\n };\n};\n\n// ─── Build ─────────────────────────────────────────────────────────────────────\n\n/**\n * Build the format-neutral {@link SyncSpec} from an app's sync surface. The\n * shared component pool is assembled once (so every message reuses the same\n * row/args definitions) in OpenAPI-style draft-2020-12.\n */\nexport const build = (api: SyncApi): SyncSpec => {\n const { roots, catalog } = specialize(api);\n const openApi = JsonSchema.toMultiDocumentOpenApi3_1(\n SchemaRepresentation.toJsonSchemaMultiDocument(SchemaRepresentation.toRepresentations(roots))\n );\n return {\n info: api.info,\n path: api.path ?? \"/sync\",\n components: openApi.definitions,\n messages: {\n pushRequest: \"PushRequest\",\n pushResponse: \"PushResponse\",\n pullRequest: \"PullRequest\",\n pullResponse: \"PullResponse\",\n poke: \"Poke\",\n error: \"SyncRpcError\",\n },\n catalog,\n };\n};\n\n// ─── Emitters ───────────────────────────────────────────────────────────────────\n\n/** A JSON-serializable document (object form), as emitted by the projectors. */\nexport type Document = { readonly [key: string]: unknown };\n\nconst ref = (name: string) => ({ $ref: `#/components/schemas/${name}` });\nconst msgRef = (name: string) => ({ $ref: `#/components/messages/${name}` });\nconst chanRef = (name: string) => ({ $ref: `#/channels/${name}` });\nconst message = (payload: string): Document => ({ name: payload, payload: ref(payload) });\n\nconst withDescription = (info: SpecInfo, extra: string): Document => ({\n title: info.title,\n version: info.version,\n description: info.description === undefined ? extra : `${info.description}\\n\\n${extra}`,\n});\n\n/**\n * Project a {@link SyncSpec} into an OpenAPI 3.1 document: push and pull as the\n * protocol's logical `POST {path}/push` and `POST {path}/pull` operations, with\n * every app type in `components.schemas`. Streamed pokes live in AsyncAPI.\n */\nexport const toOpenApi = (spec: SyncSpec): Document => {\n const operation = (\n operationId: string,\n summary: string,\n request: string,\n response: string\n ): Document => ({\n post: {\n operationId,\n summary,\n requestBody: {\n required: true,\n content: { \"application/json\": { schema: ref(request) } },\n },\n responses: {\n \"200\": {\n description: \"Success.\",\n content: { \"application/json\": { schema: ref(response) } },\n },\n default: {\n description: \"Sync error.\",\n content: { \"application/json\": { schema: ref(spec.messages.error) } },\n },\n },\n },\n });\n\n return {\n openapi: \"3.1.0\",\n info: withDescription(\n spec.info,\n \"Logical REST projection of the sync protocol. The default RPC carrier multiplexes push and pull over a single endpoint; these operations are the codegen-friendly contract.\"\n ),\n paths: {\n [`${spec.path}/push`]: operation(\n \"push\",\n \"Deliver pending mutations (push).\",\n spec.messages.pushRequest,\n spec.messages.pushResponse\n ),\n [`${spec.path}/pull`]: operation(\n \"pull\",\n \"Request a patch to the next cookie (pull).\",\n spec.messages.pullRequest,\n spec.messages.pullResponse\n ),\n },\n components: { schemas: spec.components },\n };\n};\n\n/**\n * Project a {@link SyncSpec} into an AsyncAPI 3.0 document: push and pull as\n * request/reply send operations and the contentless poke hint as a receive\n * channel. Component schemas are shared with the OpenAPI projection.\n */\nexport const toAsyncApi = (spec: SyncSpec): Document => {\n return {\n asyncapi: \"3.0.0\",\n info: withDescription(\n spec.info,\n \"Message-oriented view of the sync protocol: push/pull request-reply and the streamed poke hint.\"\n ),\n channels: {\n push: {\n address: `${spec.path}/push`,\n messages: {\n request: msgRef(spec.messages.pushRequest),\n response: msgRef(spec.messages.pushResponse),\n },\n },\n pull: {\n address: `${spec.path}/pull`,\n messages: {\n request: msgRef(spec.messages.pullRequest),\n response: msgRef(spec.messages.pullResponse),\n },\n },\n pokes: {\n address: `${spec.path}/pokes`,\n messages: { poke: msgRef(spec.messages.poke) },\n },\n },\n operations: {\n push: {\n action: \"send\",\n channel: chanRef(\"push\"),\n reply: { channel: chanRef(\"push\"), messages: [msgRef(spec.messages.pushResponse)] },\n },\n pull: {\n action: \"send\",\n channel: chanRef(\"pull\"),\n reply: { channel: chanRef(\"pull\"), messages: [msgRef(spec.messages.pullResponse)] },\n },\n receivePokes: { action: \"receive\", channel: chanRef(\"pokes\") },\n },\n components: {\n schemas: spec.components,\n messages: {\n [spec.messages.pushRequest]: message(spec.messages.pushRequest),\n [spec.messages.pushResponse]: message(spec.messages.pushResponse),\n [spec.messages.pullRequest]: message(spec.messages.pullRequest),\n [spec.messages.pullResponse]: message(spec.messages.pullResponse),\n [spec.messages.poke]: message(spec.messages.poke),\n },\n },\n };\n};\n\n// ─── Convenience ────────────────────────────────────────────────────────────────\n\n/** Build and project to OpenAPI 3.1 in one step. */\nexport const openApi = (api: SyncApi): Document => toOpenApi(build(api));\n\n/** Build and project to AsyncAPI 3.0 in one step. */\nexport const asyncApi = (api: SyncApi): Document => toAsyncApi(build(api));\n","/**\n * Undo\n *\n * An optional, additive undo/redo module layered over anything that can\n * `mutate(name, args)` — no engine surgery (issue #46). It follows the\n * *paired-intents* design (the `@rocicorp/undo` shape): the caller supplies\n * both directions of a change at run time, and undo/redo replay through the\n * supplied handle's ordinary `mutate` pipeline — a `ClientEngine`, a\n * `Client`, or a test double all satisfy {@link MutateHandle} structurally\n * (issue #223). Because they are just mutations, undo and redo are\n * optimistic, journaled, rebased, and offline-safe like any other write —\n * the module adds only the in-memory history.\n *\n * `ClientEngine.mutate` and `Client.mutate` do not share an error channel\n * (the engine fails with its mutator/store union, the Client with its\n * narrower view error), so both {@link MutateHandle} and {@link UndoManager}\n * are generic in that error type: whatever the supplied handle's `mutate`\n * fails with is what `run`/`undo`/`redo` fail with, unchanged.\n *\n * History is a per-client, in-memory pair of stacks (one manager per handle).\n * It does not survive a reload; the journal (which does) still carries any\n * pending undo/redo mutations to the backend.\n *\n * ## Paired intents\n *\n * Each {@link UndoEntry} names the mutator + args to run now (`execute`) and the\n * mutator + args that reverse it (`undo`). The caller captures whatever the\n * reversal needs at run time — crucially, the *pre-delete value*: read the row\n * from the local view, then `run({ execute: delete, undo: set(capturedValue) })`\n * so an undo re-creates the row exactly.\n *\n * ## Grouping\n *\n * {@link UndoManager.group} coalesces every `run` made while its effect runs\n * into ONE composite step: a single `undo` replays each member's `undo` in\n * reverse order, a single `redo` replays each member's `execute` in order.\n */\n\nimport * as Arr from \"effect/Array\";\nimport * as Effect from \"effect/Effect\";\nimport * as Ref from \"effect/Ref\";\nimport * as Stream from \"effect/Stream\";\nimport * as SubscriptionRef from \"effect/SubscriptionRef\";\n\n/** A mutator invocation: the name and (decoded) args handed to `mutate`. */\nexport interface MutationIntent {\n readonly mutator: string;\n readonly args: unknown;\n}\n\n/**\n * A reversible action as a pair of intents: `execute` applies it, `undo`\n * reverses it. Both replay through `ClientEngine.mutate`, so both are\n * optimistic, journaled, and rebased.\n */\nexport interface UndoEntry {\n readonly execute: MutationIntent;\n readonly undo: MutationIntent;\n}\n\n/** One history step: a single `run`, or a whole {@link UndoManager.group}. */\ntype Step = ReadonlyArray<UndoEntry>;\n\n/** The in-memory history: the undo stack and the redo stack (top = last). */\ninterface History {\n readonly undo: ReadonlyArray<Step>;\n readonly redo: ReadonlyArray<Step>;\n}\n\nconst EMPTY_HISTORY: History = { undo: [], redo: [] };\n\n/**\n * The structural shape {@link make} needs: anything that can run a named\n * mutation. A `ClientEngine` and a `Client` both satisfy this — with\n * different error channels, hence the type parameter (issue #223).\n */\nexport interface MutateHandle<E> {\n readonly mutate: (mutator: string, args: unknown) => Effect.Effect<void, E>;\n}\n\n/**\n * A per-client undo/redo manager over a {@link MutateHandle}. Every operation\n * runs through the handle's `mutate` pipeline, so a failed mutation surfaces\n * as `E` — the handle's own error type; the manager itself only owns the\n * in-memory history and the grouping flag.\n */\nexport interface UndoManager<E> {\n /**\n * Run an entry's `execute` through `mutate`, push it onto the undo stack, and\n * clear the redo stack (a new action invalidates any redo). Inside a\n * {@link group}, the entry is instead accumulated into the group's step.\n */\n readonly run: (entry: UndoEntry) => Effect.Effect<void, E>;\n /**\n * Pop the top undo step, replay its members' `undo` intents (in reverse order\n * for a group), and push it onto the redo stack. A no-op when the undo stack\n * is empty.\n */\n readonly undo: Effect.Effect<void, E>;\n /**\n * Pop the top redo step, replay its members' `execute` intents (in order for a\n * group), and push it back onto the undo stack. A no-op when the redo stack is\n * empty.\n */\n readonly redo: Effect.Effect<void, E>;\n /** Whether an undo is currently possible. */\n readonly canUndo: Effect.Effect<boolean>;\n /** Whether a redo is currently possible. */\n readonly canRedo: Effect.Effect<boolean>;\n /** Observable {@link canUndo} for bindings (emits now, then on every change). */\n readonly canUndoChanges: Stream.Stream<boolean>;\n /** Observable {@link canRedo} for bindings (emits now, then on every change). */\n readonly canRedoChanges: Stream.Stream<boolean>;\n /**\n * Coalesce every `run` made while `effect` runs into a single undo step. The\n * effect's own result, errors, and requirements pass through unchanged.\n * Nested groups fold into the outermost one.\n */\n readonly group: <A, E2, R>(effect: Effect.Effect<A, E2, R>) => Effect.Effect<A, E2, R>;\n}\n\n/**\n * Build an {@link UndoManager} over any {@link MutateHandle} — a\n * `ClientEngine`, a `Client`, or a test double. History is in-memory, so\n * nothing needs a scope; the manager lives as long as the reference is held.\n * The manager's error type is inferred from the handle's `mutate`, so a\n * `ClientEngine` yields the same mutator/store union it always has, and a\n * `Client` yields its narrower view error.\n */\nexport const make = <E>(handle: MutateHandle<E>): Effect.Effect<UndoManager<E>> =>\n Effect.gen(function* () {\n const history = yield* SubscriptionRef.make<History>(EMPTY_HISTORY);\n // The current group's accumulator, or `undefined` when not grouping.\n const groupBuffer = yield* Ref.make<ReadonlyArray<UndoEntry> | undefined>(undefined);\n\n const runIntent = (intent: MutationIntent): Effect.Effect<void, E> =>\n handle.mutate(intent.mutator, intent.args);\n\n // Push a completed step; a new action always clears the redo stack.\n const pushStep = (step: Step): Effect.Effect<void> =>\n SubscriptionRef.update(history, (h) => ({ undo: [...h.undo, step], redo: [] }));\n\n // Record an executed entry: accumulate into the open group, else push it as\n // its own one-member step.\n const record = (entry: UndoEntry): Effect.Effect<void> =>\n Ref.get(groupBuffer).pipe(\n Effect.flatMap((buffer) =>\n buffer === undefined ? pushStep([entry]) : Ref.set(groupBuffer, [...buffer, entry])\n )\n );\n\n const run: UndoManager<E>[\"run\"] = (entry) =>\n runIntent(entry.execute).pipe(Effect.andThen(record(entry)));\n\n // Pop the top of one stack without touching the other; `undefined` when empty.\n const take = (from: \"undo\" | \"redo\"): Effect.Effect<Step | undefined> =>\n SubscriptionRef.modify(history, (h) => {\n const stack = h[from];\n const step = stack.at(-1);\n if (step === undefined) return [undefined, h] as const;\n return [step, { ...h, [from]: stack.slice(0, -1) }] as const;\n });\n\n const pushOnto = (onto: \"undo\" | \"redo\", step: Step): Effect.Effect<void> =>\n SubscriptionRef.update(history, (h) => ({ ...h, [onto]: [...h[onto], step] }));\n\n // Replay a step's members: undo runs the `undo` intents in reverse order,\n // redo runs the `execute` intents in order — the mirror of one another.\n const replay = (step: Step, direction: \"undo\" | \"redo\"): Effect.Effect<void, E> =>\n Effect.gen(function* () {\n const ordered = direction === \"undo\" ? [...step].reverse() : step;\n yield* Effect.forEach(\n ordered,\n (entry) =>\n Effect.gen(function* () {\n yield* runIntent(direction === \"undo\" ? entry.undo : entry.execute);\n }),\n { concurrency: 1, discard: true }\n );\n });\n\n // Pop `from`, replay it, then push it `onto` the opposite stack. Empty → no-op.\n const step = (from: \"undo\" | \"redo\", onto: \"undo\" | \"redo\"): Effect.Effect<void, E> =>\n take(from).pipe(\n Effect.flatMap((popped) =>\n popped === undefined\n ? Effect.void\n : replay(popped, from).pipe(Effect.andThen(pushOnto(onto, popped)))\n )\n );\n\n const canUndo = SubscriptionRef.get(history).pipe(\n Effect.map((h) => Arr.isReadonlyArrayNonEmpty(h.undo))\n );\n const canRedo = SubscriptionRef.get(history).pipe(\n Effect.map((h) => Arr.isReadonlyArrayNonEmpty(h.redo))\n );\n\n const observe = (project: (h: History) => boolean): Stream.Stream<boolean> =>\n SubscriptionRef.changes(history).pipe(Stream.map(project), Stream.changes);\n\n // Flush the open group as one step (nothing to push for an empty group).\n const flushGroup: Effect.Effect<void> = Ref.get(groupBuffer).pipe(\n Effect.flatMap((buffer) =>\n buffer !== undefined && Arr.isReadonlyArrayNonEmpty(buffer) ? pushStep(buffer) : Effect.void\n )\n );\n\n const group: UndoManager<E>[\"group\"] = (effect) =>\n Ref.get(groupBuffer).pipe(\n Effect.flatMap((existing) =>\n // Already grouping → join the outer group; its members keep accumulating.\n existing !== undefined\n ? effect\n : Ref.set(groupBuffer, []).pipe(\n Effect.andThen(effect),\n Effect.tap(() => flushGroup),\n Effect.ensuring(Ref.set(groupBuffer, undefined))\n )\n )\n );\n\n return {\n run,\n undo: step(\"undo\", \"redo\"),\n redo: step(\"redo\", \"undo\"),\n canUndo,\n canRedo,\n canUndoChanges: observe((h) => Arr.isReadonlyArrayNonEmpty(h.undo)),\n canRedoChanges: observe((h) => Arr.isReadonlyArrayNonEmpty(h.redo)),\n group,\n } satisfies UndoManager<E>;\n });\n","/**\n * Paced mutations (#117)\n *\n * Debounce/throttle/coalesce strategies for rapid mutation intents — a text\n * field autosaving per keystroke, a slider, a cart-quantity stepper — layered\n * over {@link ClientEngine} the same way {@link Undo} is: no engine surgery,\n * built entirely from `mutateWithAck` + `dropIfPending` + Effect's own timing\n * primitives (`Effect.sleep`, `Fiber.interrupt`). No pacer dependency, no\n * general-purpose pacer module — just the journal-compaction rule ADR-0008\n * already permits on the unpushed tail.\n *\n * ## Design: journal-then-compact\n *\n * Every call — debounce, throttle, or coalesce — always journals through the\n * ordinary `mutateWithAck` path immediately: full durability, the usual\n * optimistic overlay render, no separate preview mechanism. What pacing adds\n * is a *compaction* step run after journaling: for the mutation's `key` (a\n * caller-supplied string — e.g. a row id — distinguishing independent rapid\n * intents from each other), drop the previous still-pending entry for that\n * key via {@link ClientEngine.dropIfPending}, so a burst collapses to the\n * newest entry rather than piling one row per call into the journal.\n *\n * This was chosen over the alternative sketched in #117 (journal once,\n * replace an unpushed entry's args in place) because it needs no new\n * \"mutate this pushed-adjacent entry in place\" primitive — `dropIfPending`\n * is a narrow, easily-audited addition (drop specific still-pending ids, never\n * touching anything a push may have claimed) that composes with the journal\n * exactly as `acknowledge` already does, and because journal-then-compact\n * gives every strategy the *same* durability profile for the leading and\n * every eagerly-journaled call: nothing is ever held only in memory once it\n * has been accepted as \"the current value\" for a key.\n *\n * The one place memory-only buffering remains is intentional: `debounce` and\n * `throttle` do not journal *every* call. A call arriving while a burst is\n * already active only updates an in-memory `latestArgs` slot and (for\n * `debounce`) restarts the trailing timer; the store is touched at most twice\n * per debounce window (leading + trailing) or once per throttle window,\n * regardless of how many calls landed inside it — which is what keeps overlay\n * replays bounded for a 50-keystroke burst. **Durability tradeoff:** the\n * args sitting in that in-memory slot between flushes are not journaled, so a\n * crash inside a debounce/throttle window loses the freshest edit — the\n * journal still holds the last successfully flushed (leading-edge) args, not\n * nothing, but not the very latest keystroke either. This mirrors TanStack\n * DB's `createPacedMutations` debounce/throttle strategies exactly. `coalesce`\n * has no such window — every call journals immediately — so its tradeoff is\n * the opposite one: momentarily more journal entries (until the next call's\n * compaction catches up), never a lost edit.\n *\n * ## Compaction renumbers (#249)\n *\n * The backends reject a gap in a client's mutation ids (ADR-0008), so dropping\n * a superseded entry is not enough: `dropIfPending` also renumbers the\n * surviving unpushed entries, in order, so the journal stays contiguous and a\n * push can drain it. That means an id this module remembered for a key can\n * move — and not only when *its own* instance compacts: any other paced\n * mutation on the same engine shifts every unpushed entry behind the one it\n * drops. Acting on a stale id could drop an unrelated entry that has since\n * taken that number, so every instance's bookkeeping lives in one registry per\n * engine and each compaction's moves are applied to all of it (see\n * {@link Tracker}).\n *\n * ## Undo pairing\n *\n * A caller combining this with {@link Undo}: wrap the whole burst (every\n * `PacedMutation.call` your input handler makes) in `undo.group(...)`. Because\n * `Undo.group` coalesces every `run` made while its effect executes into one\n * step regardless of how many, a coalesced/debounced/throttled burst becomes\n * a single undo step too, matching what the user actually experiences as one\n * edit.\n */\nimport * as Arr from \"effect/Array\";\nimport * as Effect from \"effect/Effect\";\nimport * as Fiber from \"effect/Fiber\";\nimport * as Semaphore from \"effect/Semaphore\";\nimport type * as Duration from \"effect/Duration\";\nimport type * as Scope from \"effect/Scope\";\nimport type { ClientEngine } from \"./ClientEngine.js\";\nimport type { MutatorError, StoreError } from \"./Errors.js\";\n\n/** A paced mutation bound to one mutator: `call(key, args)` supersedes any of\n * this key's own prior calls per the strategy's rule. */\nexport interface PacedMutation {\n /**\n * Journal `args` for `key`. `key` scopes compaction — calls with different\n * keys (e.g. different row ids) never supersede one another, only\n * consecutive calls sharing a key do.\n */\n readonly call: (key: string, args: unknown) => Effect.Effect<void, MutatorError | StoreError>;\n}\n\n/**\n * One paced instance's memory of the last entry it journaled for each key.\n * `Map<key, mutationId>`; the ids are kept current by {@link compact}.\n */\ntype Tracker = Map<string, number>;\n\n/**\n * Every live {@link Tracker} for one engine. Weakly held, so an instance that\n * is dropped (a `coalesce` has no scope to release it from) does not pin its\n * map for the engine's lifetime.\n */\nconst trackersByEngine = new WeakMap<object, Set<WeakRef<Tracker>>>();\n\n/** Trackers already registered, so each is added once. */\nconst registered = new WeakSet<Tracker>();\n\n/** Register `tracker` so compactions by any instance on `engine` keep it current. */\nconst track = (engine: ClientEngine, tracker: Tracker): void => {\n if (registered.has(tracker)) return;\n registered.add(tracker);\n let all = trackersByEngine.get(engine);\n if (all === undefined) {\n all = new Set();\n trackersByEngine.set(engine, all);\n }\n all.add(new WeakRef(tracker));\n};\n\n/**\n * Drop `previous` (if still compactable) and apply the renumbering it caused\n * to every tracker on the engine, so no instance is left holding an id that\n * now names a different entry.\n */\nconst compact = (engine: ClientEngine, previous: number): Effect.Effect<void, StoreError> =>\n // Uninterruptible: once the engine has renumbered the journal, every tracker\n // must hear about it, or a later call would drop an unrelated entry (#249).\n Effect.uninterruptible(\n Effect.gen(function* () {\n const { renumbered } = yield* engine.dropIfPending([previous]);\n if (Arr.isReadonlyArrayEmpty(renumbered)) return;\n const moves = new Map(renumbered.map(({ from, to }) => [from, to] as const));\n const all = trackersByEngine.get(engine);\n if (all === undefined) return;\n Arr.forEach(all, (ref) => {\n const tracker = ref.deref();\n if (tracker === undefined) {\n all.delete(ref);\n return;\n }\n Arr.forEach(tracker, ([key, id]) => {\n const moved = moves.get(id);\n if (moved !== undefined) tracker.set(key, moved);\n });\n });\n })\n );\n\n/** Per-key buffered state shared by `debounce`/`throttle`'s timer loops. */\ninterface Entry {\n latestArgs: unknown;\n /** Whether `latestArgs` has landed since the last flush for this key. */\n dirty: boolean;\n timer: Fiber.Fiber<void> | undefined;\n}\n\n/**\n * Journal `args` for `mutator`/`key` via `mutateWithAck`, then drop this\n * key's previously-tracked mutation id if it is still pending — the shared\n * compaction step every strategy below is built from. `lastIdByKey` is the\n * caller's own bookkeeping (not the engine's): each Paced instance tracks\n * only the ids *it* journaled, so it only ever asks to drop its own entries.\n */\nconst flush = (\n engine: ClientEngine,\n mutator: string,\n lastIdByKey: Tracker,\n key: string,\n args: unknown\n): Effect.Effect<void, MutatorError | StoreError> =>\n Effect.gen(function* () {\n track(engine, lastIdByKey);\n // Journaling and remembering the id are one uninterruptible step (#249\n // review N1): an interrupt between them would leave an entry no tracker\n // knows, which a later compaction could renumber without anyone noticing.\n const previous = yield* Effect.uninterruptible(\n Effect.gen(function* () {\n const handle = yield* engine.mutateWithAck(mutator, args);\n const before = lastIdByKey.get(key);\n lastIdByKey.set(key, handle.mutationId);\n return before;\n })\n );\n if (previous !== undefined) yield* compact(engine, previous);\n });\n\n/**\n * A background flush (debounce's trailing edge, throttle's periodic tick)\n * that isn't awaited by any caller: failures would otherwise die silently in\n * the forked fiber, so log them instead. The entry this call would have\n * compacted simply stays journaled uncompacted — never lost, just uncoalesced\n * (the same \"short-lived extra entries\" tradeoff `coalesce` always accepts).\n */\nconst flushBackground = (\n engine: ClientEngine,\n mutator: string,\n lastIdByKey: Tracker,\n key: string,\n args: unknown\n): Effect.Effect<void> =>\n flush(engine, mutator, lastIdByKey, key, args).pipe(\n Effect.catch((error) =>\n Effect.logWarning(\"Paced: background flush failed; entry left journaled uncompacted\", {\n mutator,\n key,\n error,\n })\n )\n );\n\n/**\n * Coalesce: consecutive unpushed invocations of `mutator` for the same `key`\n * collapse to the last one. No timing — every call journals and compacts\n * immediately, so nothing is ever buffered only in memory (fully durable),\n * at the cost of a momentary extra journal entry between a call and its\n * compaction.\n */\nexport const coalesce = (engine: ClientEngine, mutator: string): Effect.Effect<PacedMutation> =>\n Effect.gen(function* () {\n const lock = yield* Semaphore.make(1);\n const lastIdByKey = new Map<string, number>();\n const call: PacedMutation[\"call\"] = (key, args) =>\n Semaphore.withPermit(lock, flush(engine, mutator, lastIdByKey, key, args));\n return { call };\n });\n\n/**\n * Debounce: the first call after a quiet period journals immediately (the\n * overlay renders it right away — optimistic rendering never waits for the\n * window); every call inside the window just buffers its args and restarts\n * the trailing timer. When `duration` elapses with no further calls, the\n * latest buffered args flush once, superseding the leading entry. A 50-call\n * burst inside one window therefore produces exactly two journal writes\n * (leading + trailing) no matter how many calls landed in between — see the\n * module doc for the durability tradeoff this implies.\n */\nexport const debounce = (\n engine: ClientEngine,\n mutator: string,\n duration: Duration.Input\n): Effect.Effect<PacedMutation, never, Scope.Scope> =>\n Effect.gen(function* () {\n const scope = yield* Effect.scope;\n const lock = yield* Semaphore.make(1);\n const lastIdByKey = new Map<string, number>();\n const entries = new Map<string, Entry>();\n\n const trailing = (key: string): Effect.Effect<void> =>\n Effect.sleep(duration).pipe(\n Effect.andThen(\n Semaphore.withPermit(\n lock,\n Effect.gen(function* () {\n const entry = entries.get(key);\n if (entry === undefined || !entry.dirty) {\n entries.delete(key);\n return;\n }\n const args = entry.latestArgs;\n entries.delete(key); // idle again: the next call is a fresh leading edge\n yield* flushBackground(engine, mutator, lastIdByKey, key, args);\n })\n )\n )\n );\n\n const call: PacedMutation[\"call\"] = (key, args) =>\n Semaphore.withPermit(\n lock,\n Effect.gen(function* () {\n let entry = entries.get(key);\n if (entry === undefined) {\n // Leading edge: journal now so the overlay reflects it immediately.\n entry = { latestArgs: args, dirty: false, timer: undefined };\n entries.set(key, entry);\n yield* flush(engine, mutator, lastIdByKey, key, args);\n } else {\n if (entry.timer !== undefined) yield* Fiber.interrupt(entry.timer);\n entry.latestArgs = args;\n entry.dirty = true;\n }\n entry.timer = yield* Effect.forkIn(trailing(key), scope);\n })\n );\n\n return { call };\n });\n\n/**\n * Throttle: like {@link debounce}'s leading edge, but the window is never\n * reset by later calls — it flushes at most once per `duration` while calls\n * keep arriving (a continuous drag emits periodic journal writes, not just\n * one at the very end), then goes idle once a window elapses with nothing new\n * buffered.\n */\nexport const throttle = (\n engine: ClientEngine,\n mutator: string,\n duration: Duration.Input\n): Effect.Effect<PacedMutation, never, Scope.Scope> =>\n Effect.gen(function* () {\n const scope = yield* Effect.scope;\n const lock = yield* Semaphore.make(1);\n const lastIdByKey = new Map<string, number>();\n const entries = new Map<string, Entry>();\n\n const tick = (key: string): Effect.Effect<void> =>\n Effect.sleep(duration).pipe(\n Effect.andThen(\n Semaphore.withPermit(\n lock,\n Effect.gen(function* () {\n const entry = entries.get(key);\n if (entry === undefined) return;\n if (!entry.dirty) {\n entries.delete(key); // idle: the next call is a fresh leading edge\n return;\n }\n entry.dirty = false;\n const args = entry.latestArgs;\n yield* flushBackground(engine, mutator, lastIdByKey, key, args);\n entry.timer = yield* Effect.forkIn(tick(key), scope);\n })\n )\n )\n );\n\n const call: PacedMutation[\"call\"] = (key, args) =>\n Semaphore.withPermit(\n lock,\n Effect.gen(function* () {\n const entry = entries.get(key);\n if (entry === undefined) {\n // Leading edge: journal now and start this key's window.\n const created: Entry = { latestArgs: args, dirty: false, timer: undefined };\n entries.set(key, created);\n yield* flush(engine, mutator, lastIdByKey, key, args);\n created.timer = yield* Effect.forkIn(tick(key), scope);\n return;\n }\n // A window is already running for this key: buffer, don't reset it.\n entry.latestArgs = args;\n entry.dirty = true;\n })\n );\n\n return { call };\n });\n","/**\n * Introspection\n *\n * A read-only view of a running {@link ClientEngine} and its\n * {@link ClientStore} (#45): the active subscriptions, the pending-mutation\n * journal, the pull cookie, the materialised collections, and the unified\n * {@link ClientEngine.engineEvents} lifecycle stream. Built entirely over the\n * engine's public read accessors and the store's public reads — it never\n * reaches into private engine state.\n *\n * Every member is a plain `Effect`/`Stream`, so it drives cleanly through\n * `PromiseFacade` for non-Effect surfaces (devtools panels, a demo journal\n * view):\n *\n * ```ts\n * const intro = Introspection.make(engine, store);\n * const pending = await facade.run(intro.journal);\n * const sub = facade.subscribe(intro.events, {\n * onValue: (event) => console.log(event._tag),\n * });\n * ```\n */\n\nimport * as Context from \"effect/Context\";\nimport * as Effect from \"effect/Effect\";\nimport * as Layer from \"effect/Layer\";\nimport * as Stream from \"effect/Stream\";\nimport { ClientEngine, type EngineEvent } from \"./ClientEngine.js\";\nimport { ClientStore } from \"./ClientStore.js\";\nimport type { StoreError } from \"./Errors.js\";\nimport type { Mutation } from \"./Protocol.js\";\nimport type * as Subset from \"./Subset.js\";\n\n/**\n * A read-only introspection surface over an engine + store. `subscriptions`\n * and `events` read the engine; `journal`, `cookie`, and `collections` read\n * the store — all public reads, no private access.\n */\nexport interface EngineIntrospection {\n /** Active subsets: raw subscriptions plus each named subscription resolved. */\n readonly subscriptions: Effect.Effect<ReadonlyArray<Subset.Subset>>;\n /**\n * The journal: pending (unacknowledged) mutations in causal order. It holds\n * pending entries only. A mutation the backend acknowledged but no pull has\n * reported yet is in the engine's unpulled tail (#286), which this view does\n * not show.\n */\n readonly journal: Effect.Effect<ReadonlyArray<Mutation>, StoreError>;\n /** The current pull cookie, or `undefined` before the first pull. */\n readonly cookie: Effect.Effect<string | undefined, StoreError>;\n /** Every collection currently holding confirmed rows. */\n readonly collections: Effect.Effect<ReadonlyArray<string>, StoreError>;\n /** The unified sync-lifecycle event stream (see {@link EngineEvent}). */\n readonly events: Stream.Stream<EngineEvent>;\n}\n\n/** The {@link EngineIntrospection} service devtools read through. */\nexport const EngineIntrospection = Context.Service<EngineIntrospection>(\n \"@thomasfosterau/legation/EngineIntrospection\"\n);\n\n/** Build the introspection view over a given engine and store. */\nexport const make = (engine: ClientEngine, store: ClientStore): EngineIntrospection => ({\n subscriptions: engine.activeSubscriptions,\n journal: store.pendingMutations,\n cookie: store.getCookie,\n collections: store.listCollections,\n events: engine.engineEvents,\n});\n\n/** Build the view from the {@link ClientEngine} + {@link ClientStore} in context. */\nexport const fromServices: Effect.Effect<EngineIntrospection, never, ClientEngine | ClientStore> =\n Effect.gen(function* () {\n const engine = yield* ClientEngine;\n const store = yield* ClientStore;\n return make(engine, store);\n });\n\n/** Layer providing {@link EngineIntrospection} from the engine + store services. */\nexport const layer: Layer.Layer<EngineIntrospection, never, ClientEngine | ClientStore> =\n Layer.effect(EngineIntrospection)(fromServices);\n","/**\n * Incremental\n *\n * The pure delta engines behind #114's derived combinators ({@link Derive}).\n * ADR-0027 (decision 4) blesses the proven per-module seams over extracting a\n * shared #108 operator core, and rules that #114's combinators *are* the\n * operator layer, landing with their consumer — so these are exactly those\n * combinators' engines, not a separately-consumed core. Each mirrors a proven\n * seam's *technique* (not its coupled code): `join` the keyed-bucket-plus-\n * reverse-index of `Related.makeJoinEngine`, `groupBy` the running-fold-plus-\n * `byId` of `Aggregate`, `orderedWindow` the `LiveView`/`OrderedTree`\n * persistent order.\n *\n * The delta currency is keyed `added`/`removed` rows — the `Patch`-op model of\n * ADR-0027 §1, on row identity, not `[value, ±multiplicity]` multiset entries.\n * Each engine is a small, pure, Effect-free function that emits the delta to\n * its result, never a refold of the whole input (a refolding version of this\n * tier was explicitly judged not worth shipping, #114 brief) — and being pure\n * and stream-free is what lets a property test drive it against a naive\n * from-scratch recompute after every prefix of a randomized delta sequence.\n *\n * **The boundary rule (ADR-0027 §3).** These operators are read-layer\n * machinery behind `observe`. They see only rows the client already holds;\n * they never widen what syncs, never serialize, and are never auth-relevant.\n * The serializable `Subset`/`Predicate` tier alone decides what the server\n * ships.\n *\n * The unit is a {@link Row} — the same `(id, value)` shape as `Subset.Row` and\n * `ClientEngine.LocalRow`, so a source's page (`ReadonlyArray<LocalRow>`) is a\n * valid input and an operator's result rows compose as the input of the next\n * operator (queries-from-queries falls out of the shared shape). Output row\n * ids are synthesized where the operation demands it — a join row is keyed by\n * its `(leftId, rightId)` pair, a group row by its group key, a distinct row\n * by its canonical value — always a plain string, always stable.\n */\n\nimport * as Arr from \"effect/Array\";\nimport * as Hash from \"./Hash.js\";\nimport * as LiveView from \"./LiveView.js\";\nimport * as Predicate from \"./Predicate.js\";\nimport type { RowChange } from \"./RowChange.js\";\nimport * as Subset from \"./Subset.js\";\n\n/** A `(id, value)` row — structurally `Subset.Row` / `ClientEngine.LocalRow`. */\nexport interface Row {\n readonly id: string;\n readonly value: unknown;\n}\n\n/**\n * A batch of row changes. An update is carried as a `removed` (old value)\n * paired with an `added` (new value) for the same id — the shape\n * {@link diff} produces from consecutive page snapshots, and the shape every\n * operator's `step` accepts and returns.\n */\nexport interface Delta {\n readonly added: ReadonlyArray<Row>;\n readonly removed: ReadonlyArray<Row>;\n}\n\n/** The empty delta (a no-op step result). */\nexport const emptyDelta: Delta = { added: [], removed: [] };\n\n// ─── Snapshot ↔ delta (the source boundary) ──────────────────────────────────\n//\n// The derived tier consumes `ClientView.observe` page snapshots and recovers\n// row deltas by diffing consecutive pages here — the page-diffing path\n// ADR-0027 §4 describes, the same internal re-diff `Related` does, and the\n// fallback `Derive.maintain` keeps for a plain page source. When the leaf is\n// a `ClientView` (`Derive.observed`), #115's `observeChanges` enter/update/\n// exit/move feed is consumed directly instead: `deltaFromChanges` below reads\n// the delta `LiveView` already computed rather than recomputing it by diffing\n// two page `Map`s.\n\n/** Index a page by id, for diffing against the next snapshot. */\nexport const indexById = (rows: ReadonlyArray<Row>): Map<string, Row> => {\n const map = new Map<string, Row>();\n for (const row of rows) map.set(row.id, row);\n return map;\n};\n\n/**\n * Diff a new page against the previous snapshot (by id, value change detected\n * by content hash): a new id is an `added`, a vanished id a `removed`, a\n * changed value a `removed` (old) + `added` (new). Returns the delta and the\n * new snapshot index to carry forward.\n */\nexport const diff = (\n previous: ReadonlyMap<string, Row>,\n next: ReadonlyArray<Row>\n): { readonly delta: Delta; readonly index: Map<string, Row> } => {\n const added: Array<Row> = [];\n const removed: Array<Row> = [];\n const index = new Map<string, Row>();\n for (const row of next) {\n index.set(row.id, row);\n const prior = previous.get(row.id);\n if (prior === undefined) added.push(row);\n else if (prior !== row && Hash.contentHash(prior.value) !== Hash.contentHash(row.value)) {\n removed.push(prior);\n added.push(row);\n }\n }\n for (const [id, prior] of previous) {\n if (!index.has(id)) removed.push(prior);\n }\n return { delta: { added, removed }, index };\n};\n\n/** Fold a delta into a maintained result map (remove ids, then set adds). */\nexport const applyDelta = (result: Map<string, Row>, delta: Delta): void => {\n for (const row of delta.removed) result.delete(row.id);\n for (const row of delta.added) result.set(row.id, row);\n};\n\n/**\n * Recover a {@link Delta} directly from an `observeChanges` batch (#115),\n * instead of diffing two page snapshots (see {@link diff} above) — the\n * optimization ADR-0027 §4 and this module's header flag as a follow-up:\n * `LiveView` already decided enter/update/exit/move per row, so this just\n * reads that decision instead of recomputing it from two `Map`s. `known`\n * tracks the last row seen per id (across calls, mutated in place) so a\n * `reset` can emit a `removed` for everything it cleared — the same\n * information a page-diff's `previous` snapshot would have given for free.\n * `move` carries no value change, so it contributes nothing to the delta.\n */\nexport const deltaFromChanges = (\n known: Map<string, Row>,\n batch: ReadonlyArray<RowChange<Row>>\n): Delta => {\n const added: Array<Row> = [];\n const removed: Array<Row> = [];\n for (const change of batch) {\n switch (change._tag) {\n case \"reset\":\n for (const row of known.values()) removed.push(row);\n known.clear();\n break;\n case \"enter\":\n added.push(change.row);\n known.set(change.row.id, change.row);\n break;\n case \"update\":\n removed.push(change.previous);\n added.push(change.row);\n known.set(change.row.id, change.row);\n break;\n case \"exit\":\n removed.push(change.previous);\n known.delete(change.id);\n break;\n case \"move\":\n break;\n }\n }\n return { added, removed };\n};\n\n/** Materialize a result map to a page in a deterministic (id-ascending, code-point) order. */\nexport const pageOf = (result: ReadonlyMap<string, Row>): ReadonlyArray<Row> =>\n [...result.values()].toSorted((a, b) => Predicate.compareText(a.id, b.id));\n\n// ─── Operators ───────────────────────────────────────────────────────────────\n\n/** A single-input delta→delta operator maintaining its own internal state. */\nexport interface Operator {\n readonly step: (delta: Delta) => Delta;\n}\n\n/**\n * `filter` — keep rows whose value passes an arbitrary JS predicate. Stateless\n * per row: the predicate is deterministic on the value, and a delta carries the\n * value it concerns, so an added/removed row's membership is decided on the\n * spot (an update that filters a row out is a `removed` with the old value that\n * passed; one that filters it in is an `added` that now passes).\n */\nexport const makeFilter = (predicate: (value: unknown) => boolean): Operator => ({\n step: (delta) => ({\n added: delta.added.filter((row) => predicate(row.value)),\n removed: delta.removed.filter((row) => predicate(row.value)),\n }),\n});\n\n/** {@link makeFilter}'s naive recompute, for the property test. */\nexport const filterFromScratch = (\n rows: ReadonlyArray<Row>,\n predicate: (value: unknown) => boolean\n): Map<string, Row> => indexById(rows.filter((row) => predicate(row.value)));\n\n/**\n * `map`/select — project each value through an arbitrary JS function, keeping\n * the row id (projection preserves identity). Stateless: `f` is deterministic,\n * so an update's `removed` reconstructs the old projection and its `added` the\n * new one.\n */\nexport const makeMap = (f: (value: unknown) => unknown): Operator => ({\n step: (delta) => ({\n added: delta.added.map((row) => ({ id: row.id, value: f(row.value) })),\n removed: delta.removed.map((row) => ({ id: row.id, value: f(row.value) })),\n }),\n});\n\n/** {@link makeMap}'s naive recompute. */\nexport const mapFromScratch = (\n rows: ReadonlyArray<Row>,\n f: (value: unknown) => unknown\n): Map<string, Row> => indexById(rows.map((row) => ({ id: row.id, value: f(row.value) })));\n\n/**\n * `distinct` — collapse duplicate values to one row, keyed and identified by\n * the value's canonical serialization (so value equality, not reference,\n * decides duplication and there is no hash-collision risk). A multiplicity\n * count per distinct value means removing one of several duplicates keeps the\n * distinct row; the row appears when its count goes 0→1 and disappears at 1→0.\n */\nexport const makeDistinct = (): Operator => {\n const counts = new Map<string, { count: number; readonly value: unknown }>();\n return {\n step: (delta) => {\n const added: Array<Row> = [];\n const removed: Array<Row> = [];\n for (const row of delta.removed) {\n const key = Hash.canonicalJson(row.value);\n const entry = counts.get(key);\n if (entry === undefined) continue;\n entry.count -= 1;\n if (entry.count === 0) {\n counts.delete(key);\n removed.push({ id: key, value: entry.value });\n }\n }\n for (const row of delta.added) {\n const key = Hash.canonicalJson(row.value);\n const entry = counts.get(key);\n if (entry === undefined) {\n counts.set(key, { count: 1, value: row.value });\n added.push({ id: key, value: row.value });\n } else {\n entry.count += 1;\n }\n }\n return { added, removed };\n },\n };\n};\n\n/** {@link makeDistinct}'s naive recompute (dedupe by canonical value). */\nexport const distinctFromScratch = (rows: ReadonlyArray<Row>): Map<string, Row> => {\n const result = new Map<string, Row>();\n for (const row of rows) {\n const key = Hash.canonicalJson(row.value);\n if (!result.has(key)) result.set(key, { id: key, value: row.value });\n }\n return result;\n};\n\n/**\n * `groupBy` returning grouped **rows** (not only scalar aggregates): one output\n * row per group, `value` = `{ key, rows }` where `rows` are the group members'\n * values ordered by member id (a deterministic within-group order, so a\n * from-scratch recompute matches). Only the one or two groups a delta touches\n * re-materialize — every other group's row is untouched (the same\n * touch-only-the-affected-bucket discipline as `Aggregate`'s grouped state).\n */\nexport const makeGroupBy = (key: (value: unknown) => string): Operator => {\n const groups = new Map<string, Map<string, unknown>>();\n const groupOf = new Map<string, string>();\n const lastRow = new Map<string, Row>();\n\n const groupRow = (groupKey: string): Row => {\n const rows = [...(groups.get(groupKey)?.entries() ?? [])]\n .toSorted(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n .map(([, value]) => value);\n return { id: groupKey, value: { key: groupKey, rows } };\n };\n\n return {\n step: (delta) => {\n const touched = new Set<string>();\n for (const row of delta.removed) {\n const groupKey = groupOf.get(row.id);\n if (groupKey === undefined) continue;\n const members = groups.get(groupKey);\n members?.delete(row.id);\n groupOf.delete(row.id);\n if (members?.size === 0) groups.delete(groupKey);\n touched.add(groupKey);\n }\n for (const row of delta.added) {\n const groupKey = key(row.value);\n let members = groups.get(groupKey);\n if (members === undefined) {\n members = new Map();\n groups.set(groupKey, members);\n }\n members.set(row.id, row.value);\n groupOf.set(row.id, groupKey);\n touched.add(groupKey);\n }\n const added: Array<Row> = [];\n const removed: Array<Row> = [];\n for (const groupKey of touched) {\n const previous = lastRow.get(groupKey);\n if (previous !== undefined) removed.push(previous);\n if (groups.has(groupKey)) {\n const next = groupRow(groupKey);\n added.push(next);\n lastRow.set(groupKey, next);\n } else {\n lastRow.delete(groupKey);\n }\n }\n return { added, removed };\n },\n };\n};\n\n/** A group row's value shape (what {@link makeGroupBy} emits). */\nexport interface Group {\n readonly key: string;\n readonly rows: ReadonlyArray<unknown>;\n}\n\n/** {@link makeGroupBy}'s naive recompute. */\nexport const groupByFromScratch = (\n rows: ReadonlyArray<Row>,\n key: (value: unknown) => string\n): Map<string, Row> => {\n const groups = new Map<string, Array<[string, unknown]>>();\n for (const row of rows) {\n const groupKey = key(row.value);\n const bucket = groups.get(groupKey) ?? [];\n bucket.push([row.id, row.value]);\n groups.set(groupKey, bucket);\n }\n const result = new Map<string, Row>();\n for (const [groupKey, bucket] of groups) {\n const ordered = bucket\n .toSorted(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n .map(([, value]) => value);\n result.set(groupKey, { id: groupKey, value: { key: groupKey, rows: ordered } });\n }\n return result;\n};\n\n// ─── Join (inner + left) ─────────────────────────────────────────────────────\n\n/** How a joined row's value is assembled; default `{ left, right }`. */\nexport type JoinCombine = (left: unknown, right: unknown | null) => unknown;\n\n/** Options for {@link makeJoin} / {@link joinFromScratch}. */\nexport interface JoinOptions {\n /** Extract the left row's join key (an arbitrary value; `null`/`undefined` never matches). */\n readonly leftKey: (value: unknown) => unknown;\n /** Extract the right row's join key. */\n readonly rightKey: (value: unknown) => unknown;\n /** `inner` drops unmatched left rows; `left` keeps them with a `null` right. */\n readonly kind: \"inner\" | \"left\";\n /** Assemble the joined value; defaults to `{ left, right }`. */\n readonly combine?: JoinCombine;\n}\n\nconst NUL = \"\\u0000\";\nconst defaultCombine: JoinCombine = (left, right) => ({ left, right });\n\n/** A join key's canonical string, or `undefined` for a non-joining `null`/`undefined` key. */\nconst joinKey = (value: unknown): string | undefined =>\n value === null || value === undefined ? undefined : Hash.canonicalJson(value);\n\n/**\n * A two-input join over arbitrary key equality (inner or left). Maintains,\n * per side, an id→row map and a key→ids index; a change re-derives only the\n * left rows whose key the change touches (a right delta re-hydrates only the\n * lefts in the affected buckets; a left delta only itself) — never a full\n * re-group, the same discipline as `Related.makeJoinEngine`. Left-join null\n * rows fall out for free: an unmatched left's contribution is a single\n * `combine(left, null)` row, replaced the moment a matching right arrives.\n */\nexport interface JoinOperator {\n readonly stepLeft: (delta: Delta) => Delta;\n readonly stepRight: (delta: Delta) => Delta;\n}\n\n/** Build a {@link JoinOperator} for the given join keys and kind (inner or left). */\nexport const makeJoin = (options: JoinOptions): JoinOperator => {\n const combine = options.combine ?? defaultCombine;\n const leftById = new Map<string, Row>();\n const rightById = new Map<string, Row>();\n const rightByKey = new Map<string, Map<string, unknown>>();\n const leftByKey = new Map<string, Set<string>>();\n const contribution = new Map<string, Map<string, Row>>();\n\n const contributionOf = (leftId: string): Map<string, Row> => {\n const out = new Map<string, Row>();\n const left = leftById.get(leftId);\n if (left === undefined) return out;\n const key = joinKey(options.leftKey(left.value));\n const rights = key === undefined ? undefined : rightByKey.get(key);\n if (rights !== undefined && rights.size > 0) {\n for (const [rightId, rightValue] of rights) {\n const id = `${leftId}${NUL}${rightId}`;\n out.set(id, { id, value: combine(left.value, rightValue) });\n }\n } else if (options.kind === \"left\") {\n const id = `${leftId}${NUL}`;\n out.set(id, { id, value: combine(left.value, null) });\n }\n return out;\n };\n\n /** Recompute one left row's contribution and emit the diff against its last. */\n const reconcile = (leftId: string, added: Array<Row>, removed: Array<Row>): void => {\n const previous = contribution.get(leftId) ?? new Map<string, Row>();\n const next = contributionOf(leftId);\n for (const [id, row] of previous) {\n if (!next.has(id)) removed.push(row);\n }\n for (const [id, row] of next) {\n const prior = previous.get(id);\n if (prior === undefined) added.push(row);\n else if (Hash.contentHash(prior.value) !== Hash.contentHash(row.value)) {\n removed.push(prior);\n added.push(row);\n }\n }\n if (next.size > 0) contribution.set(leftId, next);\n else contribution.delete(leftId);\n };\n\n const indexLeft = (row: Row): void => {\n leftById.set(row.id, row);\n const key = joinKey(options.leftKey(row.value));\n if (key === undefined) return;\n const set = leftByKey.get(key) ?? new Set<string>();\n set.add(row.id);\n leftByKey.set(key, set);\n };\n\n const unindexLeft = (row: Row): void => {\n leftById.delete(row.id);\n const key = joinKey(options.leftKey(row.value));\n if (key === undefined) return;\n const set = leftByKey.get(key);\n if (set === undefined) return;\n set.delete(row.id);\n if (set.size === 0) leftByKey.delete(key);\n };\n\n const putRight = (row: Row, keys: Set<string>): void => {\n const key = joinKey(options.rightKey(row.value));\n rightById.set(row.id, row);\n if (key === undefined) return;\n const bucket = rightByKey.get(key) ?? new Map<string, unknown>();\n bucket.set(row.id, row.value);\n rightByKey.set(key, bucket);\n keys.add(key);\n };\n\n const removeRight = (row: Row, keys: Set<string>): void => {\n const key = joinKey(options.rightKey(row.value));\n rightById.delete(row.id);\n if (key === undefined) return;\n const bucket = rightByKey.get(key);\n if (bucket === undefined) return;\n bucket.delete(row.id);\n if (bucket.size === 0) rightByKey.delete(key);\n keys.add(key);\n };\n\n return {\n stepLeft: (delta) => {\n const affected = new Set<string>();\n for (const row of delta.removed) {\n unindexLeft(row);\n affected.add(row.id);\n }\n for (const row of delta.added) {\n const prior = leftById.get(row.id);\n if (prior !== undefined) unindexLeft(prior);\n indexLeft(row);\n affected.add(row.id);\n }\n const added: Array<Row> = [];\n const removed: Array<Row> = [];\n for (const leftId of affected) reconcile(leftId, added, removed);\n return { added, removed };\n },\n stepRight: (delta) => {\n const keys = new Set<string>();\n for (const row of delta.removed) removeRight(row, keys);\n for (const row of delta.added) {\n const prior = rightById.get(row.id);\n if (prior !== undefined) removeRight(prior, keys);\n putRight(row, keys);\n }\n const affectedLefts = new Set<string>();\n for (const key of keys) {\n const ids = leftByKey.get(key);\n if (ids !== undefined) for (const id of ids) affectedLefts.add(id);\n }\n const added: Array<Row> = [];\n const removed: Array<Row> = [];\n for (const leftId of affectedLefts) reconcile(leftId, added, removed);\n return { added, removed };\n },\n };\n};\n\n/** {@link makeJoin}'s naive recompute (nested-loop join by key equality). */\nexport const joinFromScratch = (\n left: ReadonlyArray<Row>,\n right: ReadonlyArray<Row>,\n options: JoinOptions\n): Map<string, Row> => {\n const combine = options.combine ?? defaultCombine;\n const rightByKey = new Map<string, Array<Row>>();\n for (const row of right) {\n const key = joinKey(options.rightKey(row.value));\n if (key === undefined) continue;\n const bucket = rightByKey.get(key) ?? [];\n bucket.push(row);\n rightByKey.set(key, bucket);\n }\n const result = new Map<string, Row>();\n for (const leftRow of left) {\n const key = joinKey(options.leftKey(leftRow.value));\n const matches = key === undefined ? undefined : rightByKey.get(key);\n if (matches !== undefined && Arr.isReadonlyArrayNonEmpty(matches)) {\n for (const rightRow of matches) {\n const id = `${leftRow.id}${NUL}${rightRow.id}`;\n result.set(id, { id, value: combine(leftRow.value, rightRow.value) });\n }\n } else if (options.kind === \"left\") {\n const id = `${leftRow.id}${NUL}`;\n result.set(id, { id, value: combine(leftRow.value, null) });\n }\n }\n return result;\n};\n\n// ─── Ordered window (orderBy + limit) ────────────────────────────────────────\n\n/** An ordered-window operator maintaining a `LiveView` over derived rows. */\nexport interface OrderedWindow {\n /** Apply a delta; returns the current window, ordered and limited. */\n readonly step: (delta: Delta) => ReadonlyArray<Row>;\n}\n\n/** The subset an ordered window maintains (an always-true `where` over derived rows). */\nconst windowSubset = (\n orderBy: ReadonlyArray<Subset.OrderBy>,\n limit: number | undefined\n): Subset.Subset =>\n Subset.make({ collection: \"\", orderBy, ...(limit === undefined ? {} : { limit }) });\n\n/**\n * `orderedWindow` — sort derived rows by an `orderBy` and keep the first\n * `limit`. Reuses `LiveView` (the `OrderedTree` + fractional-index machinery of\n * #112): a delta is folded in as O(log n) `put`/`del`s and the window resliced\n * without a re-sort, so a change outside the page costs the same as one inside\n * it. Order is `Subset.comparator` — the one ordering authority (ADR-0026), so\n * \"no orderBy\" still means a stable id-ascending order.\n */\nexport const makeOrderedWindow = (\n orderBy: ReadonlyArray<Subset.OrderBy>,\n limit?: number\n): OrderedWindow => {\n const subset = windowSubset(orderBy, limit);\n let view = LiveView.make(subset, []);\n return {\n step: (delta) => {\n for (const row of delta.removed) view = LiveView.del(view, row.id);\n for (const row of delta.added) view = LiveView.put(view, { id: row.id, value: row.value });\n return LiveView.result(view).map((row) => ({ id: row.id, value: row.value }));\n },\n };\n};\n\n/** {@link makeOrderedWindow}'s naive recompute (`Subset.apply`: sort then window). */\nexport const orderedWindowFromScratch = (\n rows: ReadonlyArray<Row>,\n orderBy: ReadonlyArray<Subset.OrderBy>,\n limit?: number\n): ReadonlyArray<Row> =>\n Subset.apply(rows, windowSubset(orderBy, limit)).map((row) => ({ id: row.id, value: row.value }));\n","/**\n * Derive\n *\n * Client-local **derived live queries**: a set of bare, composable combinators\n * — `filter`, `map`/`select`, `join`, `groupBy`, `distinct`, `orderedWindow` —\n * over already-observed sources, each incrementally maintained from row deltas\n * by the pure {@link Incremental} engines. This is the expressiveness tier the\n * #114 brief describes: the relational shaping (arbitrary joins, DISTINCT,\n * row-level group-by, computed/cross-field predicates) that the serializable\n * `Subset`/`Predicate` wire language deliberately does not carry, done here in\n * memory over what the client has already synced.\n *\n * **The boundary rule — derived combinators never widen what syncs\n * (ADR-0027).** A combinator sees only the rows its source streams already\n * hold; the serializable Query/Subset tier underneath alone decides what the\n * server ships. The failure mode this forbids: filtering locally and believing\n * the result set is complete. Deriving `filter((t) => t.urgent)` over a page\n * synced as \"my open todos\" shows the urgent ones *among the todos already\n * synced* — never any the sync window excluded. If a derived view needs rows\n * the client does not hold, widen the `Query` (what syncs), not the combinator\n * (what is shown).\n *\n * **The seam.** A source is anything satisfying the `ClientView.observe`\n * shape — a `subset -> Stream<page>` observation of an owned engine or a\n * mirror, *or the output of another combinator* (every combinator's output is\n * a page stream of the same `(id, value)` rows, so queries-from-queries falls\n * straight out of the shared shape, the same trick `LiveQuery` and `Related`\n * already play). A combinator recovers deltas by diffing consecutive `observe`\n * pages ({@link Incremental.diff}) — the page-diffing path ADR-0027 §4\n * describes, and the fallback for a plain page source (a raw `Stream`, or\n * another combinator's output).\n *\n * **`observed` prefers `observeChanges` (#115).** When the leaf is built from\n * a full `ClientView` (rather than the narrower `Reader`), `observed` reads\n * its `observeChanges` enter/update/exit/move feed directly instead of\n * `observe`'s pages: `LiveView` already decided each row's delta, so\n * `Incremental.deltaFromChanges` just reads that decision instead of\n * `Incremental.diff` recomputing it from two page `Map`s. The resulting\n * `Source` is tagged (invisibly to its `Stream.Stream<ReadonlyArray<Row>, E>`\n * type) with its native change feed, so every combinator built on top of it —\n * `filter`, `map`, `join`, `groupBy`, `distinct`, `orderedWindow` — consumes\n * that feed too, one level deep. A source built any other way (a raw\n * `Stream`, `view.observe(subset)` called directly, or a combinator's own\n * output) carries no such tag and falls back to page-diffing, unchanged.\n *\n * **Observability.** A derived pipeline is an Effect `Stream` and, via\n * {@link atom}, an Atom on the standard `effect/reactivity` surface —\n * so framework bindings need nothing new: `@thomasfosterau/legation-svelte`'s `query` store\n * and `@thomasfosterau/legation-svelte`'s `useQuery` bind a derived stream exactly as they bind\n * a raw `observe`.\n *\n * **Lifetime.** {@link observed} pairs a refcounted `Subscriptions` acquire\n * with the source observation and releases it when its scope closes, so a\n * pipeline built from `observed` leaves tears the whole chain's subscriptions\n * down together — the same discipline as `Related`.\n */\n\nimport type * as Cause from \"effect/Cause\";\nimport type * as Scope from \"effect/Scope\";\nimport * as Effect from \"effect/Effect\";\nimport * as Stream from \"effect/Stream\";\nimport { Atom, type AsyncResult } from \"effect/reactivity\";\nimport type * as ClientView from \"./ClientView.js\";\nimport * as Hash from \"./Hash.js\";\nimport * as Incremental from \"./Incremental.js\";\nimport type { RowChange } from \"./RowChange.js\";\nimport type * as Subscriptions from \"./Subscriptions.js\";\nimport type * as Subset from \"./Subset.js\";\n\n/** A derived row — the `(id, value)` unit, structurally `ClientEngine.LocalRow`. */\nexport type Row = Incremental.Row;\n\n/** A derived source: a stream of page snapshots (what `ClientView.observe` yields). */\nexport type Source<E> = Stream.Stream<ReadonlyArray<Row>, E>;\n\n// ─── The observeChanges tag (see the module doc's \"observed prefers\n// observeChanges\" section) ────────────────────────────────────────────────\n//\n// `Source<E>` must stay exactly `Stream.Stream<ReadonlyArray<Row>, E>` — it is\n// handed around and constructed directly (a raw `Stream.fromIterable`, or\n// `view.observe(subset)`) by callers who never go through `observed`. A tag\n// smuggled onto the *value* `observed` returns (an ordinary, extensible\n// object, like every Effect `Stream`) lets a combinator opportunistically\n// recover the native change feed without widening that public type: present,\n// it's used; absent (a raw stream, or another combinator's own page output),\n// the page-diff fallback below runs exactly as before.\nconst CHANGES = Symbol.for(\"@thomasfosterau/legation/Derive/changes\");\n\ninterface ChangeTagged<E> {\n readonly [CHANGES]: Stream.Stream<ReadonlyArray<RowChange<Row>>, E>;\n}\n\nconst withChanges = <E>(\n pages: Source<E>,\n changes: Stream.Stream<ReadonlyArray<RowChange<Row>>, E>\n): Source<E> => Object.assign(pages, { [CHANGES]: changes } satisfies ChangeTagged<E>);\n\nconst isChangeTagged = <E>(source: Source<E>): source is Source<E> & ChangeTagged<E> =>\n CHANGES in source;\n\nconst changesOf = <E>(\n source: Source<E>\n): Stream.Stream<ReadonlyArray<RowChange<Row>>, E> | undefined =>\n isChangeTagged(source) ? source[CHANGES] : undefined;\n\n// ─── Dedup ───────────────────────────────────────────────────────────────────\n\nconst sameRow = (a: Row, b: Row): boolean =>\n a === b || (a.id === b.id && Hash.contentHash(a.value) === Hash.contentHash(b.value));\n\n/**\n * Two derived pages are equal when they have the same rows in the same order.\n * Set combinators emit in a stable id order (see {@link Incremental.pageOf}) and\n * `orderedWindow` in its comparator order, so a positional compare never sees a\n * spurious reorder — a genuine no-op step re-emits nothing.\n */\nconst samePage = (a: ReadonlyArray<Row>, b: ReadonlyArray<Row>): boolean =>\n a.length === b.length &&\n a.every((row, i) => {\n const other = b[i];\n return other !== undefined && sameRow(row, other);\n });\n\n// ─── Single-input maintenance ────────────────────────────────────────────────\n\n/**\n * Recover a delta per emission from any `Source`: when it carries the\n * {@link CHANGES} tag (built by `observed` over a `ClientView`), read the\n * delta `LiveView` already computed (`Incremental.deltaFromChanges`);\n * otherwise diff each page against the last snapshot\n * ({@link Incremental.diff}), the pre-#115 fallback for a plain page source.\n * Every combinator funnels through this so the tag needs checking once, not\n * once per combinator.\n */\nconst toDeltaStream = <E>(source: Source<E>): Stream.Stream<Incremental.Delta, E> => {\n const changes = changesOf(source);\n return changes !== undefined\n ? changes.pipe(\n Stream.mapAccum(\n () => new Map<string, Row>(),\n (known, batch) => [known, [Incremental.deltaFromChanges(known, batch)]] as const\n )\n )\n : source.pipe(\n Stream.mapAccum(\n () => new Map<string, Row>(),\n (last, page) => {\n const { delta, index } = Incremental.diff(last, page);\n return [index, [delta]] as const;\n }\n )\n );\n};\n\n/**\n * Drive one delta→delta {@link Incremental.Operator} over a source's deltas\n * ({@link toDeltaStream}): step the operator, fold the output delta into a\n * maintained result, and emit the result as a page (deduped). The operator\n * (and its state) is built lazily per subscription, so one derived value\n * mounted from many components each gets its own maintained state.\n */\nconst maintain = <E>(source: Source<E>, makeOperator: () => Incremental.Operator): Source<E> =>\n toDeltaStream(source).pipe(\n Stream.mapAccum(\n () => ({ operator: makeOperator(), result: new Map<string, Row>() }),\n (state, delta) => {\n Incremental.applyDelta(state.result, state.operator.step(delta));\n return [state, [Incremental.pageOf(state.result)]] as const;\n }\n ),\n Stream.changesWith(samePage)\n );\n\n/**\n * Keep the rows whose value passes an arbitrary JS predicate. The predicate is\n * never serialized and never narrows what syncs — it shapes only what is shown\n * of the already-synced page (the boundary rule above).\n */\nexport const filter = <E>(source: Source<E>, predicate: (value: unknown) => boolean): Source<E> =>\n maintain(source, () => Incremental.makeFilter(predicate));\n\n/** Project each row's value through an arbitrary JS function, keeping its id. */\nexport const map = <E>(source: Source<E>, f: (value: unknown) => unknown): Source<E> =>\n maintain(source, () => Incremental.makeMap(f));\n\n/** {@inheritDoc map} — `select` reads better for a projection; same combinator. */\nexport const select = map;\n\n/** Collapse duplicate values to one row, keyed by the canonical value. */\nexport const distinct = <E>(source: Source<E>): Source<E> =>\n maintain(source, () => Incremental.makeDistinct());\n\n/**\n * Group rows by an arbitrary key function, emitting one row per group whose\n * value is `{ key, rows }` (the group's member values). A having-clause is\n * `filter` after `groupBy`; a scalar rollup is `map` over the group rows.\n */\nexport const groupBy = <E>(source: Source<E>, key: (value: unknown) => string): Source<E> =>\n maintain(source, () => Incremental.makeGroupBy(key));\n\n// ─── Join (two inputs) ───────────────────────────────────────────────────────\n\n/** Options for {@link join} (re-exported from {@link Incremental}). */\nexport type JoinOptions = Incremental.JoinOptions;\n\n/**\n * Join two derived sources on arbitrary key equality (inner or left). Merges\n * the two page streams, feeding each side's delta to the shared join operator,\n * which re-derives only the left rows a change touches. A joined row's value is\n * `{ left, right }` by default (`right` is `null` for an unmatched left row\n * under `kind: \"left\"`); pass `combine` to shape it otherwise.\n */\nexport const join = <E, F>(\n left: Source<E>,\n right: Source<F>,\n options: JoinOptions\n): Source<E | F> => {\n const tagged: Stream.Stream<\n { readonly side: \"left\" | \"right\"; readonly delta: Incremental.Delta },\n E | F\n > = Stream.merge(\n toDeltaStream(left).pipe(Stream.map((delta) => ({ side: \"left\" as const, delta }))),\n toDeltaStream(right).pipe(Stream.map((delta) => ({ side: \"right\" as const, delta })))\n );\n return tagged.pipe(\n Stream.mapAccum(\n () => ({\n operator: Incremental.makeJoin(options),\n result: new Map<string, Row>(),\n }),\n (state, event) => {\n const outDelta =\n event.side === \"left\"\n ? state.operator.stepLeft(event.delta)\n : state.operator.stepRight(event.delta);\n Incremental.applyDelta(state.result, outDelta);\n return [state, [Incremental.pageOf(state.result)]] as const;\n }\n ),\n Stream.changesWith(samePage)\n );\n};\n\n// ─── Ordered window ──────────────────────────────────────────────────────────\n\n/** Options for {@link orderedWindow}: a sort order and an optional row limit. */\nexport interface OrderedWindowOptions {\n readonly orderBy: ReadonlyArray<Subset.OrderBy>;\n readonly limit?: number;\n}\n\n/**\n * Sort derived rows by an `orderBy` and keep the first `limit` — an ORDER\n * BY … LIMIT over the derived result, maintained by `LiveView`'s `OrderedTree`\n * so a change outside the window costs the same as one inside it (ADR-0026's\n * one ordering authority applies, so \"no orderBy\" still means stable id order).\n */\nexport const orderedWindow = <E>(source: Source<E>, options: OrderedWindowOptions): Source<E> =>\n toDeltaStream(source).pipe(\n Stream.mapAccum(\n () => Incremental.makeOrderedWindow(options.orderBy, options.limit),\n (window, delta) => [window, [window.step(delta)]] as const\n ),\n Stream.changesWith(samePage)\n );\n\n// ─── Observability ───────────────────────────────────────────────────────────\n\n/** A derived value's Atom: the current page as an `AsyncResult`, re-emitting on change. */\nexport type DerivedResult<E> = AsyncResult.AsyncResult<\n ReadonlyArray<Row>,\n E | Cause.NoSuchElementError\n>;\n\n/**\n * Expose a derived pipeline as an Atom on the standard reactivity surface — the\n * same shape `LiveQuery.make(...).atom(...)` produces for a raw subset, so a\n * framework binding renders a derived value with no new machinery.\n */\nexport const atom = <E>(source: Source<E>): Atom.Atom<DerivedResult<E>> => Atom.make(source);\n\n// ─── Lifetime ────────────────────────────────────────────────────────────────\n\n/**\n * Fold an `observeChanges` feed into a page stream without ever diffing a\n * page: each batch's delta ({@link Incremental.deltaFromChanges}) is folded\n * straight into a running result map. This is what `observed` returns when\n * the view has `observeChanges` — a real, standalone page stream (so it's\n * correct if consumed directly), separate from the {@link CHANGES} tag that\n * lets a combinator built on top skip this fold entirely and read the same\n * underlying batches itself.\n */\nconst pagesFromChanges = <E>(changes: Stream.Stream<ReadonlyArray<RowChange<Row>>, E>): Source<E> =>\n changes.pipe(\n Stream.mapAccum(\n () => ({ known: new Map<string, Row>(), result: new Map<string, Row>() }),\n (state, batch) => {\n Incremental.applyDelta(state.result, Incremental.deltaFromChanges(state.known, batch));\n return [state, [Incremental.pageOf(state.result)]] as const;\n }\n ),\n Stream.changesWith(samePage)\n );\n\n/**\n * A scoped leaf source: acquire a refcounted subscription for `subset` (so the\n * rows actually sync) and observe it, releasing the subscription when the scope\n * closes. A pipeline built from `observed` leaves holds all its sources'\n * subscriptions for its lifetime and drops them together on teardown — the\n * refcounted-lifetime discipline the #114 brief asks for, `Subscriptions`\n * doing the reference counting so a shared leaf is synced once.\n *\n * When `view` is a full {@link ClientView.ClientView} (not just the narrower\n * {@link ClientView.Reader}), the returned source is built from its\n * `observeChanges` feed and tagged so every combinator composed on top reads\n * that feed directly too (see the module doc). A bare `Reader` has no\n * `observeChanges` to prefer, so this falls back to `observe`'s pages,\n * unchanged.\n */\nexport const observed = (\n subscriptions: Subscriptions.Subscriptions,\n view: ClientView.Reader | ClientView.ClientView,\n subset: Subset.Subset\n): Effect.Effect<Source<ClientView.ClientViewError>, never, Scope.Scope> =>\n Effect.gen(function* () {\n const handle = yield* subscriptions.acquire(subset);\n yield* Effect.addFinalizer(() => handle.release);\n if (!(\"observeChanges\" in view)) return view.observe(subset);\n const changes = view.observeChanges(subset, { includeInitial: true });\n return withChanges(pagesFromChanges(changes), changes);\n });\n","/**\n * LiveQuery\n *\n * Read-side integration with `effect/reactivity` (ADR-0007): turn\n * a live query — a subset observed against the local view — into an Atom\n * whose value re-emits on every local change (patch applied, overlay\n * changed). Atoms are the UI surface; the engine's own change stream is the\n * reactive source, so this is just a binding, not a second cache.\n *\n * The binding is host-agnostic: anything exposing `observe(subset) ->\n * Stream<rows>` qualifies — the in-process `ClientEngine` and the browser\n * `Mirror` both do — so the same `LiveQuery.make(source).atom(subset)`\n * works on the main thread, in a worker, or against a mirror.\n */\n\nimport type * as Cause from \"effect/Cause\";\nimport type * as Stream from \"effect/Stream\";\nimport { Atom, type AsyncResult } from \"effect/reactivity\";\nimport type { LocalRow } from \"./ClientEngine.js\";\nimport * as Subset from \"./Subset.js\";\n\n/** Anything that observes a subset as a stream of materialized rows. */\nexport interface LiveQuerySource<E> {\n readonly observe: (subset: Subset.Subset) => Stream.Stream<ReadonlyArray<LocalRow>, E>;\n}\n\n/**\n * The Atom value for a live query: `AsyncResult` of the current rows. A\n * never-ending source means it stays `Success` (or `Failure`) after the\n * first emission; `NoSuchElementError` only appears if a source completes\n * without emitting.\n */\nexport type LiveQueryResult<E> = AsyncResult.AsyncResult<\n ReadonlyArray<LocalRow>,\n E | Cause.NoSuchElementError\n>;\n\n/** Shared live-query Atoms over a {@link LiveQuerySource}, one per subset identity. */\nexport interface LiveQueries<E> {\n /**\n * The Atom for a subset's live results. Stable per subset identity\n * (`Subset.hash`): the same subset yields the same Atom, so mounting it\n * from many components shares one subscription.\n */\n readonly atom: (subset: Subset.Subset) => Atom.Atom<LiveQueryResult<E>>;\n}\n\n/** Build the Atom factory for a source's live queries. */\nexport const make = <E>(source: LiveQuerySource<E>): LiveQueries<E> => {\n const cache = new Map<string, Atom.Atom<LiveQueryResult<E>>>();\n return {\n atom: (subset) => {\n const key = Subset.hash(subset);\n const existing = cache.get(key);\n if (existing !== undefined) return existing;\n const created = Atom.make(source.observe(subset));\n cache.set(key, created);\n return created;\n },\n };\n};\n","/**\n * EngineAtoms\n *\n * The engine's `effect/reactivity` Atom surface (ADR-0007): live\n * query and named-query atoms whose value re-emits on every local change,\n * plus a mutation atom for optimistic writes. Built over an `Atom.runtime`\n * from the engine layer, so the registry owns the engine's scope.\n *\n * Atoms are the UI surface. Framework packages (e.g. @thomasfosterau/legation-svelte) are\n * thin bindings over these — they mount an atom against an `AtomRegistry`,\n * they do not re-implement reactivity.\n *\n * For binding against a *resolved* observe-source instance (a `ClientEngine`\n * value, or a browser `Mirror`) rather than the engine layer, see\n * `LiveQuery`, which wraps `source.observe(subset)` with the registry's\n * default runtime.\n */\n\nimport type * as Cause from \"effect/Cause\";\nimport type * as Layer from \"effect/Layer\";\nimport * as Effect from \"effect/Effect\";\nimport * as HashMap from \"effect/HashMap\";\nimport * as Stream from \"effect/Stream\";\nimport { Atom } from \"effect/reactivity\";\nimport type { AsyncResult, AtomRegistry, Reactivity } from \"effect/reactivity\";\nimport {\n ClientEngine,\n type LocalRow,\n type MutationOutcome,\n type TypedRow,\n} from \"./ClientEngine.js\";\nimport * as Aggregate from \"./Aggregate.js\";\nimport type { MutatorError, QueryError, StoreError } from \"./Errors.js\";\nimport * as Hash from \"./Hash.js\";\nimport * as MutationState from \"./MutationState.js\";\nimport * as Subset from \"./Subset.js\";\n\ntype Rows = ReadonlyArray<LocalRow>;\n\n/**\n * A live query's Atom value: the current rows as an `AsyncResult`. A\n * never-ending source stays `Success` after the first emission;\n * `NoSuchElementError` only appears if a source completes without emitting.\n */\nexport type LiveQueryResult = AsyncResult.AsyncResult<\n Rows,\n StoreError | MutatorError | Cause.NoSuchElementError\n>;\n\n/**\n * A typed live query's Atom value: the current rows refined to the row type\n * `A`, as an `AsyncResult`. `TypedLiveQueryResult<unknown>` is structurally\n * {@link LiveQueryResult}, so plain-subset callers are unaffected.\n */\nexport type TypedLiveQueryResult<A> = AsyncResult.AsyncResult<\n ReadonlyArray<TypedRow<A>>,\n StoreError | MutatorError | Cause.NoSuchElementError\n>;\n\n/** A named query's Atom value (adds `QueryError` to the failure channel). */\nexport type NamedQueryResult = AsyncResult.AsyncResult<\n Rows,\n StoreError | MutatorError | QueryError | Cause.NoSuchElementError\n>;\n\n/** A live aggregate's Atom value: the current aggregate value as an `AsyncResult`. */\nexport type AggregateResult = AsyncResult.AsyncResult<\n Aggregate.AggregateValue,\n StoreError | MutatorError | Cause.NoSuchElementError\n>;\n\n/** A live grouped-aggregate's Atom value: the per-group record as an `AsyncResult`. */\nexport type GroupedAggregateResult = AsyncResult.AsyncResult<\n Record<string, Aggregate.AggregateValue>,\n StoreError | MutatorError | Cause.NoSuchElementError\n>;\n\n/** What to write to the mutation atom to run a mutator optimistically. */\nexport interface MutationArg {\n readonly mutator: string;\n readonly args: unknown;\n}\n\n/** The mutation-state map's Atom value (#116): an `AsyncResult` of the current map. */\nexport type MutationStatesResult = AsyncResult.AsyncResult<\n MutationState.MutationStateMap,\n Cause.NoSuchElementError\n>;\n\n/** A `mutationsFor` selector's Atom value: the matching states, oldest first. */\nexport type MutationsForResult = AsyncResult.AsyncResult<\n ReadonlyArray<MutationState.MutationState>,\n Cause.NoSuchElementError\n>;\n\n/** The engine's reactive surface, built from its layer. */\nexport interface EngineAtoms {\n /** The runtime backing every engine atom; the registry owns its scope. */\n readonly runtime: Atom.AtomRuntime<ClientEngine, never>;\n /**\n * The Atom for a subset's live results. Stable per subset identity\n * (`Subset.hash`): the same subset yields the same Atom, so mounting it\n * from many components shares one subscription. A {@link Subset.TypedSubset}\n * refines the Atom's rows to its row type.\n */\n readonly liveQuery: {\n <A>(subset: Subset.TypedSubset<A>): Atom.Atom<TypedLiveQueryResult<A>>;\n (subset: Subset.Subset): Atom.Atom<LiveQueryResult>;\n };\n /** The Atom for a named query's live results, stable per (name, args). */\n readonly namedQuery: (name: string, args: unknown) => Atom.Atom<NamedQueryResult>;\n /**\n * The Atom for a subset's live aggregate value. Stable per\n * `(subset hash, aggregate)`, so mounting it from many components shares one\n * subscription. Re-emits only when the aggregate value changes.\n */\n readonly aggregate: (\n subset: Subset.Subset,\n agg: Aggregate.Aggregate\n ) => Atom.Atom<AggregateResult>;\n /** The Atom for a subset's live grouped aggregate, stable per `(subset hash, aggregate, groupBy)`. */\n readonly aggregateGrouped: (\n subset: Subset.Subset,\n agg: Aggregate.Aggregate,\n groupBy: string\n ) => Atom.Atom<GroupedAggregateResult>;\n /** Write a {@link MutationArg} to run a mutator; its result is an `AsyncResult`. */\n readonly mutation: Atom.AtomResultFn<MutationArg, void, MutatorError | StoreError>;\n /**\n * The Atom for the engine's whole keyed mutation-state map (#116) —\n * `ClientEngine.mutationStates` re-emits on every fold; a single shared\n * Atom, so mounting it from many components shares one subscription.\n */\n readonly mutationStates: Atom.Atom<MutationStatesResult>;\n /**\n * A derived selector over {@link mutationStates}, filtered to one mutator\n * and sorted oldest-journaled first — \"N unsent changes\" or \"list failed\n * intents\" for one mutator in one line. Stable per `mutator`.\n */\n readonly mutationsFor: (mutator: string) => Atom.Atom<MutationsForResult>;\n /**\n * Like {@link mutation}, but its result resolves with the mutation's\n * authoritative outcome (applied or permanently rejected) once the backend\n * settles it — the atom stays `Waiting` until then. Backs `useMutationWithAck`.\n */\n readonly mutationWithAck: Atom.AtomResultFn<\n MutationArg,\n MutationOutcome,\n MutatorError | StoreError\n >;\n}\n\n/**\n * Build the engine's reactive surface from its layer. The layer must provide\n * `ClientEngine` with all of its own dependencies already satisfied —\n * `Atom.runtime` supplies only `AtomRegistry`/`Reactivity` and manages the\n * engine's scope for the registry's lifetime.\n */\nexport const fromLayer = (\n engineLayer: Layer.Layer<ClientEngine, never, AtomRegistry.AtomRegistry | Reactivity.Reactivity>\n): EngineAtoms => {\n const runtime = Atom.runtime(engineLayer);\n\n const liveQueries = new Map<string, Atom.Atom<LiveQueryResult>>();\n const liveQuery = (subset: Subset.Subset): Atom.Atom<LiveQueryResult> => {\n const key = Subset.hash(subset);\n const existing = liveQueries.get(key);\n if (existing !== undefined) return existing;\n const atom = runtime.atom(\n Stream.unwrap(Effect.map(ClientEngine, (engine) => engine.observe(subset)))\n );\n liveQueries.set(key, atom);\n return atom;\n };\n\n const namedQueries = new Map<string, Atom.Atom<NamedQueryResult>>();\n const namedQuery = (name: string, args: unknown): Atom.Atom<NamedQueryResult> => {\n const key = `${name}:${Hash.canonicalJson(args)}`;\n const existing = namedQueries.get(key);\n if (existing !== undefined) return existing;\n const atom = runtime.atom(\n Stream.unwrap(Effect.map(ClientEngine, (engine) => engine.observeNamed(name, args)))\n );\n namedQueries.set(key, atom);\n return atom;\n };\n\n const aggregates = new Map<string, Atom.Atom<AggregateResult>>();\n const aggregate = (\n subset: Subset.Subset,\n agg: Aggregate.Aggregate\n ): Atom.Atom<AggregateResult> => {\n const key = `${Subset.hash(subset)}:${Hash.canonicalJson(agg)}`;\n const existing = aggregates.get(key);\n if (existing !== undefined) return existing;\n const atom = runtime.atom(\n Stream.unwrap(Effect.map(ClientEngine, (engine) => engine.observeAggregate(subset, agg)))\n );\n aggregates.set(key, atom);\n return atom;\n };\n\n const groupedAggregates = new Map<string, Atom.Atom<GroupedAggregateResult>>();\n const aggregateGrouped = (\n subset: Subset.Subset,\n agg: Aggregate.Aggregate,\n groupBy: string\n ): Atom.Atom<GroupedAggregateResult> => {\n const key = `${Subset.hash(subset)}:${Hash.canonicalJson(agg)}:${groupBy}`;\n const existing = groupedAggregates.get(key);\n if (existing !== undefined) return existing;\n const atom = runtime.atom(\n Stream.unwrap(\n Effect.map(ClientEngine, (engine) => engine.observeAggregateGrouped(subset, agg, groupBy))\n )\n );\n groupedAggregates.set(key, atom);\n return atom;\n };\n\n const mutation = runtime.fn((arg: MutationArg) =>\n Effect.flatMap(ClientEngine, (engine) => engine.mutate(arg.mutator, arg.args))\n );\n\n const mutationWithAck = runtime.fn((arg: MutationArg) =>\n Effect.flatMap(ClientEngine, (engine) =>\n engine\n .mutateWithAck(arg.mutator, arg.args)\n .pipe(Effect.flatMap((handle) => handle.acknowledged))\n )\n );\n\n // A single shared atom for the whole map; `mutationsFor` derives from it\n // (Atom.mapResult) rather than opening a second engine subscription.\n const mutationStates: Atom.Atom<MutationStatesResult> = runtime.atom(\n Stream.unwrap(Effect.map(ClientEngine, (engine) => engine.mutationStates))\n );\n\n const mutationsForCache = new Map<string, Atom.Atom<MutationsForResult>>();\n const mutationsFor = (mutator: string): Atom.Atom<MutationsForResult> => {\n const existing = mutationsForCache.get(mutator);\n if (existing !== undefined) return existing;\n const atom = Atom.mapResult(mutationStates, (states) =>\n [...HashMap.values(states)]\n .filter((state) => state.mutator === mutator)\n .toSorted((a, b) => a.mutationId - b.mutationId)\n );\n mutationsForCache.set(mutator, atom);\n return atom;\n };\n\n return {\n runtime,\n liveQuery: liveQuery as EngineAtoms[\"liveQuery\"],\n namedQuery,\n aggregate,\n aggregateGrouped,\n mutation,\n mutationWithAck,\n mutationStates,\n mutationsFor,\n };\n};\n","/**\n * PromiseFacade\n *\n * Helpers for driving the Effect-native sync engine from non-Effect code:\n * plain promises and callback subscriptions. This is what framework\n * bindings (React hooks, Vue composables, vanilla JS apps, service worker\n * scripts) build on.\n *\n * A facade wraps a `ManagedRuntime` built from the layer that provides\n * the engine's services. Effects are run with `run`/`runExit`, streams are\n * consumed with `subscribe`, and `dispose` tears everything down.\n *\n * To await a mutation's authoritative backend outcome (#36), run the handle's\n * `acknowledged` effect through `run`:\n * `facade.run(engine.mutateWithAck(m, a).pipe(Effect.flatMap((h) => h.acknowledged)))`.\n */\n\nimport * as Cause from \"effect/Cause\";\nimport * as Effect from \"effect/Effect\";\nimport * as Exit from \"effect/Exit\";\nimport * as Fiber from \"effect/Fiber\";\nimport * as Layer from \"effect/Layer\";\nimport * as ManagedRuntime from \"effect/ManagedRuntime\";\nimport * as Result from \"effect/Result\";\nimport * as Stream from \"effect/Stream\";\n\n/**\n * A callback subscription handle.\n */\nexport interface Subscription {\n /** Stop receiving values and release the underlying fiber. */\n readonly unsubscribe: () => void;\n}\n\n/**\n * A promise/callback facade over an Effect runtime.\n */\nexport interface PromiseFacade<R> {\n /** The underlying managed runtime (for advanced use). */\n readonly runtime: ManagedRuntime.ManagedRuntime<R, never>;\n /** Run an effect, rejecting the promise on any failure. */\n readonly run: <A, E>(effect: Effect.Effect<A, E, R>) => Promise<A>;\n /** Run an effect, resolving with its `Exit` (never rejects on typed failures). */\n readonly runExit: <A, E>(effect: Effect.Effect<A, E, R>) => Promise<Exit.Exit<A, E>>;\n /** Consume a stream with callbacks. */\n readonly subscribe: <A, E>(\n stream: Stream.Stream<A, E, R>,\n listener: {\n readonly onValue: (value: A) => void;\n readonly onError?: ((error: E) => void) | undefined;\n readonly onDone?: (() => void) | undefined;\n }\n ) => Subscription;\n /** Tear down the runtime and every running subscription. */\n readonly dispose: () => Promise<void>;\n}\n\n/**\n * Build a promise/callback facade from a layer providing `R`.\n *\n * ```ts\n * const facade = makePromiseFacade(\n * SyncCache.layer.pipe(Layer.provideMerge(MemoryCacheStore.layer()))\n * );\n * const value = await facade.run(\n * Effect.flatMap(SyncCache.SyncCache.asEffect(), (cache) =>\n * cache.read({ key: [\"users\", \"1\"], loader: fetchUser(\"1\") })\n * )\n * );\n * await facade.dispose();\n * ```\n */\nexport const make = <R, ER>(layer: Layer.Layer<R, ER, never>): PromiseFacade<R> => {\n // The error channel of the layer is surfaced when effects run, so the\n // facade itself treats the runtime as infallible for ergonomic typing.\n const runtime = ManagedRuntime.make(layer) as ManagedRuntime.ManagedRuntime<R, never>;\n\n const run = <A, E>(effect: Effect.Effect<A, E, R>): Promise<A> => runtime.runPromise(effect);\n\n const runExit = <A, E>(effect: Effect.Effect<A, E, R>): Promise<Exit.Exit<A, E>> =>\n runtime.runPromiseExit(effect);\n\n const subscribe = <A, E>(\n stream: Stream.Stream<A, E, R>,\n listener: {\n readonly onValue: (value: A) => void;\n readonly onError?: ((error: E) => void) | undefined;\n readonly onDone?: (() => void) | undefined;\n }\n ): Subscription => {\n const consume = Stream.runForEach(stream, (value) =>\n Effect.sync(() => listener.onValue(value))\n );\n\n const fiber = runtime.runFork(\n consume.pipe(\n Effect.onExit((exit) =>\n Effect.sync(() => {\n if (Exit.isSuccess(exit)) {\n listener.onDone?.();\n } else if (Exit.isFailure(exit) && listener.onError !== undefined) {\n // Surface the first typed failure, if any.\n const failure = Cause.findFail(exit.cause);\n if (Result.isSuccess(failure)) {\n listener.onError(failure.success.error);\n }\n }\n })\n )\n )\n );\n\n return {\n unsubscribe: () => {\n runtime.runFork(Fiber.interrupt(fiber));\n },\n };\n };\n\n return {\n runtime,\n run,\n runExit,\n subscribe,\n dispose: () => runtime.dispose(),\n };\n};\n","/**\n * MirrorChannel\n *\n * The mirror↔engine-host message carrier seam (ADR-0010): one more\n * implementation of \"schema-defined messages over a pluggable carrier\".\n * The BroadcastChannel implementation ships in `@thomasfosterau/legation-browser`\n * (`BroadcastMirrorChannel`); the loopback pair here serves tests and\n * same-process (no-service-worker) hosting on any runtime.\n *\n * `subscribe` is deliberately effectful and eager — the subscription is\n * established once the effect completes — so hosts and mirrors can\n * subscribe first and fork their processing loops afterwards without a\n * subscribe/publish race.\n */\n\nimport type { TransportError } from \"./Errors.js\";\nimport * as Effect from \"effect/Effect\";\nimport * as PubSub from \"effect/PubSub\";\nimport * as Scope from \"effect/Scope\";\n\n/** A live inbound subscription. */\nexport interface MirrorInbox {\n /** The next inbound message; suspends until one arrives. */\n readonly take: Effect.Effect<unknown>;\n}\n\n/** The message channel between an engine host and its mirrors, with BroadcastChannel semantics. */\nexport interface MirrorChannel {\n readonly post: (message: unknown) => Effect.Effect<void, TransportError>;\n /**\n * Subscribe to inbound messages. Messages posted by this side are not\n * received by it (BroadcastChannel semantics).\n */\n readonly subscribe: Effect.Effect<MirrorInbox, never, Scope.Scope>;\n}\n\n/**\n * Two linked in-memory channels: messages posted on one side arrive on the\n * other. For tests and main-thread hosting (the documented degraded mode\n * for environments without service workers).\n */\nexport const makeLoopbackPair: Effect.Effect<\n { readonly host: MirrorChannel; readonly mirror: MirrorChannel },\n never,\n Scope.Scope\n> = Effect.gen(function* () {\n const makeHub = Effect.acquireRelease(PubSub.unbounded<unknown>(), (hub) => PubSub.shutdown(hub));\n const toHost = yield* makeHub;\n const toMirror = yield* makeHub;\n const side = (outbound: typeof toHost, inbound: typeof toMirror): MirrorChannel => ({\n post: (message) => Effect.asVoid(PubSub.publish(outbound, message)),\n subscribe: PubSub.subscribe(inbound).pipe(\n Effect.map((subscription) => ({ take: PubSub.take(subscription) }))\n ),\n });\n return { host: side(toMirror, toHost), mirror: side(toHost, toMirror) };\n});\n","/**\n * EngineHost\n *\n * The host side of the mirror protocol (ADR-0010): serves a running\n * ClientEngine to mirrors over a MirrorChannel — one per client context (a\n * browser tab, an Electron window, an extension, a CLI instance). Mutations\n * forward into\n * the engine's journal (optimism included — the engine's change event\n * re-broadcasts materialized rows to every mirror); subset subscriptions,\n * named-query registrations, and `related` registrations are made with the\n * engine and their live results broadcast on every change.\n *\n * For `related`, the host owns the whole relational read: the reconcile\n * loop that tracks the narrowed foreign subsets AND the join itself run\n * here, and mirrors receive resolved rows — data work stays out of the UI\n * context (ADR-0010's goal), which is why a mirror does not need the\n * collection registry.\n *\n * Registrations are refcounted by mirror: an engine registration and its\n * broadcast fiber start when the first mirror subscribes and stop only when\n * the last mirror unsubscribes or disconnects. `Disconnect` releases\n * everything a departing mirror held — the close-time signal for an orderly\n * exit.\n *\n * A mirror that crashes can't send `Disconnect`, so the host also tracks\n * each mirror's last-seen time (refreshed by subscribes and heartbeats) and a\n * sweep fiber reclaims registrations from mirrors silent past\n * `mirrorTimeout`. This is\n * the disconnect detection a BroadcastChannel can't provide on its own.\n *\n * Engine subscriptions are made through one counted voice\n * (`Subscriptions.counted`): a subset registration and a `related`\n * registration of the same root window — or two `related` registrations\n * pinning one foreign window — release independently, and the engine drops\n * the window only when the last registration lets go.\n *\n * A party with no `Client` at all — a page whose only JavaScript is a\n * `postMessage` — registers by URL (`SubscribeUrl`, ADR-0029 section 2,\n * #159): given `nodes` and `urls`, the host parses the URL, plans the read\n * and registers its root and edge windows under the party's `mirrorId`,\n * exactly as `Subscribe` and `SubscribeRelated` would.\n *\n * The host is the only party in a worker that knows what the mirrors hold,\n * so {@link run} hands back a {@link Host} listing its registrations —\n * every root window and relational registration it made with the engine,\n * with the canonical URL of a `SubscribeUrl` while a party still holds it\n * by URL — as the ledger a façade's coverage check scans\n * (`Coverage.coverageOf`, ADR-0029 section 3). A registration is listed\n * once its engine registration has been made — the root subscribed, or the\n * relational read's root and edge windows registered — and dropped when\n * its last mirror releases it or is swept, so a read judged covered is one\n * whose rows the engine syncs. A relational registration naming an edge\n * the registry does not declare registers nothing: the engine would never\n * sync that edge, so nothing may be credited for it.\n */\n\nimport type { UrlReads } from \"./Client.js\";\nimport * as ClientEngine from \"./ClientEngine.js\";\nimport * as Collection from \"./Collection.js\";\nimport * as Coverage from \"./Coverage.js\";\nimport { QueryError, TransportError } from \"./Errors.js\";\nimport type * as MutationState from \"./MutationState.js\";\nimport type * as Node from \"./Node.js\";\nimport * as PullMarks from \"./PullMarks.js\";\nimport * as Query from \"./Query.js\";\nimport * as Related from \"./Related.js\";\nimport * as Subscriptions from \"./Subscriptions.js\";\nimport * as Subset from \"./Subset.js\";\nimport * as Arr from \"effect/Array\";\nimport * as Clock from \"effect/Clock\";\nimport * as Duration from \"effect/Duration\";\nimport * as Effect from \"effect/Effect\";\nimport * as Exit from \"effect/Exit\";\nimport * as Fiber from \"effect/Fiber\";\nimport * as HashMap from \"effect/HashMap\";\nimport * as Option from \"effect/Option\";\nimport * as Ref from \"effect/Ref\";\nimport * as Schema from \"effect/Schema\";\nimport * as Scope from \"effect/Scope\";\nimport * as Stream from \"effect/Stream\";\nimport type { MirrorChannel } from \"./MirrorChannel.js\";\nimport * as MirrorProtocol from \"./MirrorProtocol.js\";\n\n/** Options for {@link run}: the channel mirrors connect over and the engine they share. */\nexport interface EngineHostOptions {\n readonly channel: MirrorChannel;\n readonly engine: ClientEngine.ClientEngine;\n /**\n * The collection registry `related` registrations resolve against.\n * Defaults to `nodes.collections` when `nodes` is given; without either,\n * `SubscribeRelated` messages are answered with empty results and a\n * logged warning — pass one whenever mirrors use relational reads.\n */\n readonly registry?: Collection.CollectionRegistry;\n /**\n * The node graph and URL-keyed reads `SubscribeUrl` registrations are\n * parsed and planned against (#159). Without both, a `SubscribeUrl` is\n * answered with a logged warning and registers nothing.\n */\n readonly nodes?: Node.NodeRegistry;\n readonly urls?: UrlReads;\n /**\n * Liveness sweep: reclaim registrations from mirrors not heard from within\n * `mirrorTimeout`, checked every `sweepInterval`. Defaults: 30s timeout,\n * 10s sweep — pair with a Mirror heartbeat shorter than the timeout.\n */\n readonly liveness?: {\n readonly mirrorTimeout?: Duration.Input;\n readonly sweepInterval?: Duration.Input;\n };\n}\n\n/** The running host: what a worker can consult about the mirrors it serves. */\nexport interface Host {\n /**\n * The registrations the host holds on mirrors' behalf at this moment, each\n * with its pulled summary (#426): root windows (`Subscribe`), relational\n * registrations with their edge selects (`SubscribeRelated`) and both\n * halves of a `SubscribeUrl`, the latter carrying its canonical URL for as\n * long as some party holds it by that URL. A registration's windows are\n * pulled once a pull started after each was made has applied; a coverage\n * check counts only the windows a read depends on. Named-query and\n * mutation-state registrations cover no read and are not listed. The ledger\n * a coverage check scans: `Coverage.coverageOf(nodes, view.query, host.registrations)`.\n */\n readonly registrations: Effect.Effect<ReadonlyArray<Coverage.Entry>>;\n}\n\n/** What a read's registration covers, and the URL identity a `SubscribeUrl` gave it. */\ninterface Registered {\n readonly registration: Coverage.Registration;\n readonly url?: string;\n}\n\n/** One actively-broadcast registration: which mirrors hold it, its fiber, teardown. */\ninterface Active {\n readonly mirrors: ReadonlySet<string>;\n /** The mirrors holding this registration by URL (`SubscribeUrl`); the URL is reported while any remains. */\n readonly urlMirrors: ReadonlySet<string>;\n readonly fiber: Fiber.Fiber<void, never>;\n /** Engine-side release beyond interrupting the fiber (e.g. unsubscribe). */\n readonly teardown: Effect.Effect<void>;\n /** Re-hydrate a newly-joining mirror from the current result. */\n readonly hydrate: Effect.Effect<void>;\n /** What the registration covers, when it is a read's (not a named query's or the mutation states'). */\n readonly registered?: Registered;\n}\n\n/** Whether a registration's edges are all declared by the registry; the first that is not, otherwise. */\nconst undeclaredEdge = (\n registry: Collection.CollectionRegistry,\n collection: string,\n edges: ReadonlyArray<Related.EdgeSelect>\n): Related.EdgeSelect | undefined => {\n const declared = Collection.relationshipsOf(registry, collection);\n return edges.find((edge) => !declared.has(edge.name));\n};\n\n/** The subscription an entry reports: its registration, with the URL while a party holds it by URL. */\nconst subscriptionOf = (entry: Active): Coverage.Subscription | undefined =>\n entry.registered === undefined\n ? undefined\n : {\n ...entry.registered.registration,\n ...(entry.urlMirrors.size > 0 && entry.registered.url !== undefined\n ? { url: entry.registered.url }\n : {}),\n };\n\n/** A set with one member fewer. */\nconst without = (set: ReadonlySet<string>, member: string): ReadonlySet<string> => {\n const next = new Set(set);\n next.delete(member);\n return next;\n};\n\n/** Liveness settings with their defaults applied. */\nconst livenessOf = (options: EngineHostOptions) => ({\n mirrorTimeout: options.liveness?.mirrorTimeout ?? \"30 seconds\",\n sweepInterval: options.liveness?.sweepInterval ?? \"10 seconds\",\n});\n\n/** The key a mirror's enhanced form submission is held under (#536): its mirror and the begin's requestId. */\nconst formKey = (mirrorId: string, requestId: number) => `${mirrorId}:${requestId}`;\n\n/** A `Mutate` or `Read`: what its replies are addressed by. */\ninterface Request {\n readonly requestId: number;\n readonly mirrorId?: string;\n}\n\n/**\n * A reply's address (#546): the request's `requestId`, and its `mirrorId` when\n * the mirror sent one, so another tab with a request of the same number ignores\n * the reply. A mirror that predates it sends none and gets none back.\n */\nconst replyTo = (request: Request): Request =>\n request.mirrorId === undefined\n ? { requestId: request.requestId }\n : { requestId: request.requestId, mirrorId: request.mirrorId };\n\n/** Decode a {@link MirrorProtocol.FORM_MUTATION_MUTATOR} `Mutate`'s args. */\nconst decodeFormBegin = Schema.decodeUnknownEffect(MirrorProtocol.FormMutationBegin);\n\n/** Read just the mirror a malformed form begin names, to refuse it to that mirror. */\nconst decodeFormSender = Schema.decodeUnknownEffect(Schema.Struct({ mirrorId: Schema.String }));\n\n/**\n * Serve the engine over the channel. The inbound subscription is\n * established before this effect completes; message handling runs on a\n * scoped background fiber.\n */\nexport const run = (options: EngineHostOptions): Effect.Effect<Host, never, Scope.Scope> =>\n Effect.gen(function* () {\n const { channel } = options;\n const engine = Subscriptions.counted(options.engine);\n const inbox = yield* channel.subscribe;\n const active = yield* Ref.make(new Map<string, Active>());\n const lastSeen = yield* Ref.make(new Map<string, number>());\n // Each registration's pull mark (#426): pulled once a pull started after it has applied.\n const marks = PullMarks.make(engine);\n // The pulled summaries last sent to mirrors, so `PulledRegistrations` goes out only when they change.\n const announced = yield* Ref.make<string | undefined>(undefined);\n const announce = Effect.gen(function* () {\n const registrations = yield* marks.registrations;\n const serialised = JSON.stringify(registrations);\n if (serialised === (yield* Ref.get(announced))) return;\n yield* Ref.set(announced, serialised);\n yield* channel.post({ _tag: \"PulledRegistrations\", registrations }).pipe(Effect.ignore);\n });\n\n // Pulls that sync new registrations, at most one fibre at a time (#426). A\n // registration made while one runs sets `again`, and the running fibre pulls\n // once more after it ends, so the pull that makes the registration pulled\n // starts after it. A burst of subscribes therefore costs one extra pull, not\n // one fibre per subscribe.\n const syncState = yield* Ref.make<\"idle\" | \"running\" | \"again\">(\"idle\");\n const syncUntilSettled: Effect.Effect<void, never, Scope.Scope> = engine.pull.pipe(\n Effect.ignore,\n Effect.andThen(\n Ref.modify(syncState, (state) =>\n state === \"again\" ? ([true, \"running\"] as const) : ([false, \"idle\"] as const)\n )\n ),\n Effect.flatMap((again) => (again ? syncUntilSettled : Effect.void))\n );\n const syncRegistrations: Effect.Effect<void, never, Scope.Scope> = Ref.modify(\n syncState,\n (state) => (state === \"idle\" ? ([true, \"running\"] as const) : ([false, \"again\"] as const))\n ).pipe(\n Effect.flatMap((started) => (started ? Effect.forkScoped(syncUntilSettled) : Effect.void)),\n Effect.asVoid\n );\n\n const touch = (mirrorId: string) =>\n Clock.currentTimeMillis.pipe(\n Effect.flatMap((now) => Ref.update(lastSeen, (map) => new Map(map).set(mirrorId, now)))\n );\n const forget = (mirrorId: string) =>\n Ref.update(lastSeen, (map) => {\n const next = new Map(map);\n next.delete(mirrorId);\n return next;\n });\n\n const broadcast = (key: string, rows: ReadonlyArray<ClientEngine.LocalRow>) =>\n channel.post(MirrorProtocol.mirrorUpdate(key, rows));\n const broadcastRelated = (key: string, rows: ReadonlyArray<Related.RelatedRow>) =>\n channel.post(MirrorProtocol.relatedUpdate(key, rows));\n const broadcastMutationStates = (states: MutationState.MutationStateMap) =>\n channel.post(MirrorProtocol.mutationStatesUpdate(states));\n // A one-shot snapshot of the engine's mutation-state map: `mutationStates`\n // is built over `SubscriptionRef.changes`, which replays the current value\n // to a fresh subscriber, so its first emission IS the current snapshot.\n const currentMutationStates: Effect.Effect<MutationState.MutationStateMap> = Stream.runHead(\n engine.mutationStates\n ).pipe(Effect.map(Option.getOrElse(() => HashMap.empty())));\n\n /**\n * Register (or refcount) one broadcastable registration. `start` begins\n * the engine registration and returns the broadcast loop to fork; a mirror\n * joining an already-active key is hydrated from the current result. What\n * a read's registration covers is recorded only once `start` has\n * succeeded — the engine holds the windows — and its URL identity while\n * some mirror holds the key by URL.\n */\n const acquire = (\n mirrorId: string,\n key: string,\n start: Effect.Effect<\n {\n readonly loop: Effect.Effect<void, unknown>;\n readonly teardown: Effect.Effect<void>;\n readonly hydrate: Effect.Effect<void>;\n },\n unknown,\n Scope.Scope\n >,\n registered?: Registered\n ): Effect.Effect<void, unknown, Scope.Scope> =>\n Effect.gen(function* () {\n const byUrl = registered?.url !== undefined;\n const existing = (yield* Ref.get(active)).get(key);\n if (existing !== undefined) {\n // A URL identity learnt later (a `SubscribeUrl` joining a plain\n // `Subscribe` of the same window) is kept on the entry.\n const known = existing.registered?.url === undefined ? registered : existing.registered;\n yield* Ref.update(active, (map) =>\n new Map(map).set(key, {\n ...existing,\n mirrors: new Set(existing.mirrors).add(mirrorId),\n urlMirrors: byUrl ? new Set(existing.urlMirrors).add(mirrorId) : existing.urlMirrors,\n ...(known === undefined ? {} : { registered: known }),\n })\n );\n return yield* existing.hydrate;\n }\n // A failed start (an unknown named query, an undeclared edge) registers\n // nothing and records nothing; the message loop swallows the error and\n // the mirror simply never hydrates.\n const { loop, teardown, hydrate } = yield* start;\n const fiber = yield* Effect.forkScoped(loop.pipe(Effect.ignore));\n yield* Ref.update(active, (map) =>\n new Map(map).set(key, {\n mirrors: new Set([mirrorId]),\n urlMirrors: new Set(byUrl ? [mirrorId] : []),\n fiber,\n teardown,\n hydrate,\n ...(registered === undefined ? {} : { registered }),\n })\n );\n yield* announce;\n });\n\n /** Drop one mirror from one registration; tear it down if it was the last. */\n const release = (mirrorId: string, key: string) =>\n Effect.gen(function* () {\n const entry = (yield* Ref.get(active)).get(key);\n if (entry === undefined || !entry.mirrors.has(mirrorId)) return;\n const mirrors = without(entry.mirrors, mirrorId);\n if (mirrors.size > 0) {\n yield* Ref.update(active, (map) =>\n new Map(map).set(key, {\n ...entry,\n mirrors,\n urlMirrors: without(entry.urlMirrors, mirrorId),\n })\n );\n return;\n }\n yield* Fiber.interrupt(entry.fiber);\n yield* entry.teardown.pipe(Effect.ignore);\n yield* Ref.update(active, (map) => {\n const next = new Map(map);\n next.delete(key);\n return next;\n });\n yield* announce;\n });\n\n const handleSubscribe = (mirrorId: string, subset: Subset.Subset, url?: string) => {\n const key = Subset.hash(subset);\n return acquire(\n mirrorId,\n key,\n Effect.gen(function* () {\n yield* marks.open(key, subset);\n yield* marks\n .wrap(key)\n .subscribe(subset)\n .pipe(Effect.tapError(() => marks.close(key)));\n // Sync the registration promptly, as a named query's is (#426): the rows\n // a covered read needs arrive on a pull that starts after this one. Forked,\n // so the message loop does not wait on the network.\n yield* syncRegistrations;\n return {\n // `observe` emits the current rows first, hydrating the subscriber.\n loop: Stream.runForEach(engine.observe(subset), (rows) => broadcast(key, rows)).pipe(\n Effect.asVoid\n ),\n teardown: marks\n .wrap(key)\n .unsubscribe(subset)\n .pipe(Effect.ignore, Effect.andThen(marks.close(key))),\n hydrate: engine.query(subset).pipe(\n Effect.flatMap((rows) => broadcast(key, rows)),\n Effect.ignore\n ),\n };\n }),\n { registration: { root: subset, edges: [] }, ...(url === undefined ? {} : { url }) }\n );\n };\n\n const handleSubscribeNamed = (mirrorId: string, name: string, args: unknown) => {\n const key = MirrorProtocol.namedKey(name, args);\n return acquire(\n mirrorId,\n key,\n Effect.gen(function* () {\n yield* engine.subscribeQuery(name, args);\n // Sync the registration promptly; a failed pull only delays rows\n // (the engine's own sync loop recovers).\n yield* engine.pull.pipe(Effect.ignore);\n return {\n loop: Stream.runForEach(engine.observeNamed(name, args), (rows) =>\n broadcast(key, rows)\n ).pipe(Effect.asVoid),\n teardown: engine.unsubscribeQuery(name, args).pipe(Effect.ignore),\n hydrate: engine.queryNamed(name, args).pipe(\n Effect.flatMap((rows) => broadcast(key, rows)),\n Effect.ignore\n ),\n };\n })\n );\n };\n\n const handleSubscribeRelated = (\n mirrorId: string,\n collection: string,\n subset: Subset.Subset,\n edges: ReadonlyArray<Related.EdgeSelect>,\n url?: string\n ) => {\n const key = MirrorProtocol.relatedKey(collection, subset, edges);\n const registry = options.registry ?? options.nodes?.collections;\n if (registry === undefined) {\n return Effect.logWarning(\n \"EngineHost: SubscribeRelated received but no collection registry was configured\"\n ).pipe(Effect.andThen(broadcastRelated(key, [])), Effect.ignore);\n }\n return acquire(\n mirrorId,\n key,\n Effect.gen(function* () {\n // `Related` selects the edges it knows and ignores the rest, so an\n // undeclared edge must be refused here: nothing registers, nothing\n // is credited for it.\n const undeclared = undeclaredEdge(registry, collection, edges);\n if (undeclared !== undefined) {\n return yield* Effect.fail(\n new QueryError({\n message: `EngineHost: SubscribeRelated on \"${collection}\" names an edge the registry does not declare: \"${undeclared.name}\"`,\n query: collection,\n })\n );\n }\n // The relational read is established here — its root subscribed,\n // its edge windows registered by the reconcile loop — in a scope of\n // its own under the host's, closed by the teardown; the broadcast\n // loop merely drains its stream.\n const scope = yield* Scope.fork(yield* Effect.scope);\n yield* marks.open(key, subset);\n const stream = yield* Related.related(\n marks.wrap(key),\n registry,\n collection,\n subset,\n edges\n ).pipe(\n Scope.provide(scope),\n Effect.tapError(() => marks.close(key))\n );\n return {\n loop: Stream.runForEach(stream, (rows) => broadcastRelated(key, rows)),\n teardown: Scope.close(scope, Exit.void).pipe(Effect.andThen(marks.close(key))),\n hydrate: Related.query(engine, registry, collection, subset, edges).pipe(\n Effect.flatMap((rows) => broadcastRelated(key, rows)),\n Effect.ignore\n ),\n };\n }).pipe(\n Effect.tapError((error) =>\n Effect.logWarning(`EngineHost: SubscribeRelated rejected: ${String(error)}`)\n )\n ),\n { registration: { root: subset, edges }, ...(url === undefined ? {} : { url }) }\n );\n };\n\n // The mutation-state map (#116): a singleton registration (unlike\n // subsets/named queries, there is exactly one per engine), so it acquires\n // under the fixed `MUTATION_STATES_KEY` — refcounted across mirrors the\n // same way a subset subscription is.\n const handleSubscribeMutationStates = (mirrorId: string) =>\n acquire(\n mirrorId,\n MirrorProtocol.MUTATION_STATES_KEY,\n Effect.succeed({\n // `mutationStates` emits the current map first, hydrating the\n // subscriber, then again on every fold.\n loop: Stream.runForEach(engine.mutationStates, broadcastMutationStates).pipe(\n Effect.asVoid\n ),\n teardown: Effect.void,\n hydrate: currentMutationStates.pipe(\n Effect.flatMap(broadcastMutationStates),\n Effect.ignore\n ),\n })\n );\n\n // A URL-keyed registration (#159) from a party without a Client: parsed\n // and planned here, then registered as the party's Subscribe (root) and\n // SubscribeRelated (edge windows) would be — same refcount per mirrorId,\n // same liveness sweep. A URL the host cannot parse registers nothing.\n const { nodes, urls } = options;\n const registrationOfUrl = (url: string): Effect.Effect<Coverage.Subscription, QueryError> =>\n urls === undefined || nodes === undefined\n ? Effect.fail(\n new QueryError({\n message: \"EngineHost: SubscribeUrl received but no `nodes`/`urls` were configured\",\n query: url,\n })\n )\n : Effect.gen(function* () {\n const read = yield* urls.parse(url);\n const plan = yield* Query.tryPlan(nodes, read);\n // The canonical URL is the registration's identity (ADR-0029\n // section 2); a URL the parser accepted always has one.\n return { ...Coverage.ofPlan(plan), url: yield* urls.canonical(read) };\n });\n\n // The URL names the whole registration: the relational entry when the\n // URL includes edges, the root entry otherwise.\n const handleSubscribeUrl = (mirrorId: string, url: string) =>\n registrationOfUrl(url).pipe(\n Effect.tapError((error) =>\n Effect.logWarning(`EngineHost: SubscribeUrl \"${url}\" rejected: ${error.message}`)\n ),\n Effect.flatMap(({ root, edges, url: canonical }) =>\n Arr.isReadonlyArrayEmpty(edges)\n ? handleSubscribe(mirrorId, root, canonical)\n : handleSubscribe(mirrorId, root).pipe(\n Effect.andThen(\n handleSubscribeRelated(mirrorId, root.collection, root, edges, canonical)\n )\n )\n )\n );\n\n const handleUnsubscribeUrl = (mirrorId: string, url: string) =>\n registrationOfUrl(url).pipe(\n Effect.flatMap(({ root, edges }) =>\n release(mirrorId, Subset.hash(root)).pipe(\n Effect.andThen(\n Arr.isReadonlyArrayEmpty(edges)\n ? Effect.void\n : release(mirrorId, MirrorProtocol.relatedKey(root.collection, root, edges))\n )\n )\n ),\n Effect.ignore\n );\n\n // The server-fallthrough read (ADR-0025): the host owns the transport, so\n // it performs the read and answers point-in-time. Nothing is registered\n // and nothing enters the store — errors travel back as the result.\n const handleRead = (request: Request, subsets: ReadonlyArray<Subset.Subset>) =>\n (engine.readThrough === undefined\n ? Effect.fail(new TransportError({ message: \"Host transport does not support reads\" }))\n : engine.readThrough(subsets)\n ).pipe(\n Effect.flatMap((rows) =>\n channel.post({\n _tag: \"ReadResult\",\n ...replyTo(request),\n rows: rows.map((row) => ({\n collection: row.collection,\n id: row.id,\n value: row.value,\n })),\n })\n ),\n Effect.catch((error) =>\n channel.post({ _tag: \"ReadResult\", ...replyTo(request), rows: [], error: error.message })\n )\n );\n\n // Enhanced form submissions begun by mirrors (#536), keyed by mirror and\n // the begin's requestId. The host holds the engine's in-flight entry, so\n // its overlay and unpulled tail serve every mirror; a mirror that leaves\n // (or is swept) abandons what it still held.\n const forms = yield* Ref.make(HashMap.empty<string, ClientEngine.FormSubmission>());\n const takeForm = (key: string) =>\n Ref.modify(forms, (map) => [HashMap.get(map, key), HashMap.remove(map, key)] as const);\n\n // Begin a mirror's form mutation on the engine (#536). The args arrive\n // encoded, so the engine decodes them against its own Mutation. Every\n // reply names the mirror: replies are broadcast to all of them.\n const beginForm = (requestId: number, begin: MirrorProtocol.FormMutationBegin) =>\n touch(begin.mirrorId).pipe(\n Effect.andThen(engine.beginFormMutationEncoded(begin.form, begin.mutator, begin.args)),\n Effect.flatMap((submission) =>\n Ref.update(forms, HashMap.set(formKey(begin.mirrorId, requestId), submission))\n ),\n Effect.matchEffect({\n onFailure: (error) =>\n channel.post({\n _tag: \"FormMutationFailed\",\n mirrorId: begin.mirrorId,\n requestId,\n message: error.message,\n }),\n onSuccess: () =>\n channel.post({ _tag: \"FormMutationBegun\", mirrorId: begin.mirrorId, requestId }),\n })\n );\n\n // A begin whose args do not decode can still be refused to its mirror\n // when they name one; otherwise there is nobody to answer.\n const handleBeginForm = (message: MirrorProtocol.MirrorMessage & { readonly _tag: \"Mutate\" }) =>\n decodeFormBegin(message.args).pipe(\n Effect.matchEffect({\n onSuccess: (begin) => beginForm(message.requestId, begin),\n onFailure: (error) =>\n decodeFormSender(message.args).pipe(\n Effect.flatMap(({ mirrorId }) =>\n channel.post({\n _tag: \"FormMutationFailed\",\n mirrorId,\n requestId: message.requestId,\n message: error.message,\n })\n ),\n Effect.catch(() =>\n Effect.logWarning(\"EngineHost: dropped a form begin that names no mirror\")\n )\n ),\n })\n );\n\n // End a mirror's form submission and say so, with the store's error when\n // settling it failed; an entry the host no longer holds ends as a no-op.\n const handleEndForm = (\n message: MirrorProtocol.MirrorMessage & { readonly _tag: \"EndFormMutation\" }\n ) =>\n takeForm(formKey(message.mirrorId, message.requestId)).pipe(\n Effect.flatMap(\n Option.match({\n onNone: () => Effect.void,\n onSome: (submission) =>\n message.ruling === undefined ? submission.abandon : submission.settle(message.ruling),\n })\n ),\n Effect.matchEffect({\n onFailure: (error) =>\n channel.post({\n _tag: \"FormMutationEnded\",\n mirrorId: message.mirrorId,\n requestId: message.requestId,\n error: error.message,\n }),\n onSuccess: () =>\n channel.post({\n _tag: \"FormMutationEnded\",\n mirrorId: message.mirrorId,\n requestId: message.requestId,\n }),\n })\n );\n\n const abandonForms = (mirrorId: string) =>\n Ref.modify(forms, (map) => {\n const prefix = `${mirrorId}:`;\n return [\n [...HashMap.values(HashMap.filter(map, (_, key) => key.startsWith(prefix)))],\n HashMap.filter(map, (_, key) => !key.startsWith(prefix)),\n ] as const;\n }).pipe(\n Effect.flatMap((held) =>\n Effect.forEach(held, (submission) => submission.abandon, {\n concurrency: 1,\n discard: true,\n })\n )\n );\n\n const handleDisconnect = (mirrorId: string) =>\n Effect.gen(function* () {\n const keys = [...(yield* Ref.get(active))]\n .filter(([, entry]) => entry.mirrors.has(mirrorId))\n .map(([key]) => key);\n yield* Effect.forEach(\n keys,\n (key) =>\n Effect.gen(function* () {\n yield* release(mirrorId, key);\n }),\n { concurrency: 1, discard: true }\n );\n yield* abandonForms(mirrorId);\n yield* forget(mirrorId);\n });\n\n // The backend's authoritative outcome for a forwarded mutation, posted back\n // to the mirror so `Mirror.mutateWithAck` can resolve. Runs on a scoped\n // fibre because `acknowledged` only settles on a later push/pull.\n const postSettled = (request: Request, outcome: ClientEngine.MutationOutcome) =>\n channel.post({\n _tag: \"MutateSettled\",\n ...replyTo(request),\n outcome: outcome._tag,\n ...(outcome._tag === \"rejected\" ? { reason: outcome.reason } : {}),\n });\n\n // A `Mutate` naming the reserved form mutator is an enhanced form submit's\n // begin (#536), never journaled; any other is an ordinary mutation.\n const handleMutate = (message: MirrorProtocol.MirrorMessage & { readonly _tag: \"Mutate\" }) =>\n message.mutator === MirrorProtocol.FORM_MUTATION_MUTATOR\n ? handleBeginForm(message)\n : handleJournaledMutate(message);\n\n const handleJournaledMutate = (\n message: MirrorProtocol.MirrorMessage & { readonly _tag: \"Mutate\" }\n ) =>\n engine.mutateWithAck(message.mutator, message.args).pipe(\n Effect.flatMap((mutation) =>\n // Ack on journal (unchanged mirror behaviour), then await the backend\n // outcome on a background fibre and forward it.\n channel\n .post({ _tag: \"MutateAck\", ...replyTo(message) })\n .pipe(\n Effect.andThen(\n Effect.forkScoped(\n mutation.acknowledged.pipe(\n Effect.flatMap((outcome) => postSettled(message, outcome))\n )\n )\n )\n )\n ),\n Effect.catch((error) =>\n channel.post({\n _tag: \"MutateError\",\n ...replyTo(message),\n message: error.message,\n })\n )\n );\n\n const handle = (message: MirrorProtocol.MirrorMessage) => {\n switch (message._tag) {\n case \"Mutate\":\n return handleMutate(message);\n case \"EndFormMutation\":\n return touch(message.mirrorId).pipe(Effect.andThen(handleEndForm(message)));\n case \"Subscribe\":\n return touch(message.mirrorId).pipe(\n Effect.andThen(handleSubscribe(message.mirrorId, message.subset))\n );\n case \"Unsubscribe\":\n return touch(message.mirrorId).pipe(\n Effect.andThen(release(message.mirrorId, Subset.hash(message.subset)))\n );\n case \"SubscribeNamed\":\n return touch(message.mirrorId).pipe(\n Effect.andThen(handleSubscribeNamed(message.mirrorId, message.name, message.args))\n );\n case \"UnsubscribeNamed\":\n return touch(message.mirrorId).pipe(\n Effect.andThen(\n release(message.mirrorId, MirrorProtocol.namedKey(message.name, message.args))\n )\n );\n case \"SubscribeRelated\":\n return touch(message.mirrorId).pipe(\n Effect.andThen(\n handleSubscribeRelated(\n message.mirrorId,\n message.collection,\n message.subset,\n message.edges\n )\n )\n );\n case \"UnsubscribeRelated\":\n return touch(message.mirrorId).pipe(\n Effect.andThen(\n release(\n message.mirrorId,\n MirrorProtocol.relatedKey(message.collection, message.subset, message.edges)\n )\n )\n );\n case \"SubscribeUrl\":\n return touch(message.mirrorId).pipe(\n Effect.andThen(handleSubscribeUrl(message.mirrorId, message.url))\n );\n case \"UnsubscribeUrl\":\n return touch(message.mirrorId).pipe(\n Effect.andThen(handleUnsubscribeUrl(message.mirrorId, message.url))\n );\n case \"Read\":\n return handleRead(message, message.subsets);\n case \"SubscribeMutationStates\":\n return touch(message.mirrorId).pipe(\n Effect.andThen(handleSubscribeMutationStates(message.mirrorId))\n );\n case \"UnsubscribeMutationStates\":\n return touch(message.mirrorId).pipe(\n Effect.andThen(release(message.mirrorId, MirrorProtocol.MUTATION_STATES_KEY))\n );\n case \"Disconnect\":\n return handleDisconnect(message.mirrorId);\n case \"Heartbeat\":\n return touch(message.mirrorId);\n }\n };\n\n // Liveness sweep: reclaim registrations from mirrors silent past the timeout.\n const { mirrorTimeout, sweepInterval } = livenessOf(options);\n const sweep = Effect.gen(function* () {\n const now = yield* Clock.currentTimeMillis;\n const cutoff = now - Duration.toMillis(mirrorTimeout);\n const stale = [...(yield* Ref.get(lastSeen))]\n .filter(([, seen]) => seen < cutoff)\n .map(([mirrorId]) => mirrorId);\n yield* Effect.forEach(\n stale,\n (mirrorId) =>\n Effect.gen(function* () {\n yield* handleDisconnect(mirrorId);\n }),\n { concurrency: 1, discard: true }\n );\n });\n yield* Effect.forkScoped(\n Effect.forever(sweep.pipe(Effect.andThen(Effect.sleep(sweepInterval))))\n );\n\n // A pull that applies may make a registration pulled: tell the mirrors. The\n // stream is opened here, before anything is forked: `engineEvents` subscribes\n // when it is first pulled, so a `PullCompleted` published before a forked\n // reader ran would be missed (#426).\n const pullEvents = yield* Stream.toPull(engine.engineEvents);\n yield* Effect.forkScoped(\n Effect.forever(\n pullEvents.pipe(\n Effect.flatMap((events) =>\n Effect.forEach(\n events,\n (event) => (event._tag === \"PullCompleted\" ? announce : Effect.void),\n { discard: true }\n )\n )\n )\n ).pipe(Effect.ignore)\n );\n\n yield* Effect.forkScoped(\n Effect.forever(\n inbox.take.pipe(\n Effect.flatMap(MirrorProtocol.decodeMirrorMessage),\n Effect.flatMap((message) =>\n message === undefined ? Effect.void : handle(message).pipe(Effect.ignore)\n )\n )\n )\n );\n\n // The pulled set first (empty at boot), then readiness LAST: mirrors that\n // raced this host's boot (or survived a previous host) answer by re-posting\n // their registrations.\n yield* announce;\n yield* channel.post({ _tag: \"HostReady\" }).pipe(Effect.ignore);\n\n return {\n registrations: Effect.all({ entries: Ref.get(active), pulled: marks.registrations }).pipe(\n Effect.map(({ entries, pulled }) => {\n const summaries = new Map(pulled.map((entry) => [entry.key, entry.pulled]));\n return [...entries].flatMap(([key, entry]) => {\n const subscription = subscriptionOf(entry);\n return subscription === undefined\n ? []\n : [{ ...subscription, pulled: summaries.get(key) ?? Coverage.NOT_PULLED }];\n });\n })\n ),\n };\n });\n","/**\n * FilterCorpus\n *\n * Seeded generators for the differential filter harness (issue #153,\n * ADR-0028). Three evaluators of one predicate AST exist — `Predicate.evaluate`\n * in JS, `Sql.compileWhere` on SQLite, and `Sql.compileWhere` on Postgres —\n * and Postgres is normative: every other evaluator must agree with it\n * exactly. This module produces the corpus they are compared over: random\n * rows over a fixed fixture schema (text, integer, double, boolean, ISO\n * instant) including NULL, absent fields, empty strings, boundary numerics,\n * and non-ASCII text up to astral characters; random depth-bounded\n * predicates covering every operator in the core; random `orderBy` terms;\n * and a minimiser that shrinks a disagreeing predicate/row pair to its\n * smallest reproducing form.\n *\n * The generators are Effects over Effect's `Random` service, and\n * `generateCorpus` runs them under `Random.withSeed(seed)` — Effect's own\n * seedable generator — so a seed reproduces a corpus exactly and a failure\n * reports the seed. This is the repo's shared corpus module; the property\n * tests elsewhere still carry their own hand-rolled mulberry32 copies (no\n * `fast-check` in the dependency set), and `Random.withSeed` is the idiom\n * to reach for instead of another copy.\n *\n * Rule (d) of ADR-0028 — no cross-type comparison — is enforced here by\n * construction: a leaf's literal always has its column's kind. Rule (e)\n * fixes the literal kinds (`Predicate.LiteralKind`): `text`, `integer` (int4\n * range), `double` precision, `boolean`, and `instant` as `Date#toISOString`\n * text compared as text.\n *\n * `Exists` is never generated; it is relational and has no single-row\n * meaning.\n */\n\nimport * as Arr from \"effect/Array\";\nimport * as Effect from \"effect/Effect\";\nimport * as Option from \"effect/Option\";\nimport * as Random from \"effect/Random\";\nimport * as Predicate from \"./Predicate.js\";\nimport type * as Subset from \"./Subset.js\";\n\n// ─── Draws over the Random service ───────────────────────────────────────────\n\n/** A uniform integer in `[0, max)`. */\nconst int = (max: number): Effect.Effect<number> =>\n Random.nextIntBetween(0, max, { halfOpen: true });\n/** A uniform pick from a non-empty list (an empty one is a generator bug). */\nconst pick = <A>(xs: ReadonlyArray<A>): Effect.Effect<A> => Random.choice(xs).pipe(Effect.orDie);\n/** `true` with probability `p`. */\nconst chance = (p: number): Effect.Effect<boolean> => Effect.map(Random.next, (roll) => roll < p);\n\n/** The default corpus seed; `LEGATION_CORPUS_SEED` overrides it. */\nexport const DEFAULT_SEED = 20260902;\n\n/**\n * Resolve the corpus seed from an optional environment override (the value\n * of `LEGATION_CORPUS_SEED`). Callers pass the variable in so this module\n * stays free of `process` (it ships in the engine core, which also runs in\n * browsers).\n */\nexport const resolveSeed = (override: string | undefined): number => {\n if (override === undefined || override.trim() === \"\") return DEFAULT_SEED;\n const seed = Number(override);\n if (!Number.isInteger(seed)) {\n throw new Error(`LEGATION_CORPUS_SEED must be an integer, got ${JSON.stringify(override)}`);\n }\n return seed;\n};\n\n// ─── Fixture schema ──────────────────────────────────────────────────────────\n\n/** One column of the fixture schema: a row field with a declared literal kind (`Predicate.LiteralKind`). */\nexport interface Column {\n readonly name: string;\n readonly kind: Predicate.LiteralKind;\n}\n\n/**\n * The harness's fixture table `corpus`: every non-id column is nullable.\n * Postgres declares `COLLATE \"C\"` on `id` and `s` and stores `t` as\n * `timestamptz`; SQLite uses `BINARY` text throughout.\n */\nexport const corpusColumns: ReadonlyArray<Column> = [\n { name: \"s\", kind: \"text\" },\n { name: \"i\", kind: \"integer\" },\n { name: \"d\", kind: \"double\" },\n { name: \"b\", kind: \"boolean\" },\n { name: \"t\", kind: \"instant\" },\n];\n\n/** Generator knobs shared by rows and predicates. */\nexport interface CorpusOptions {\n /**\n * Generate NULL and absent (JS-only: the key is missing) field values.\n * Default `true`. `false` keeps every field present and non-null (the\n * regression floor every evaluator agreed on before ADR-0028's rules\n * (a)/(b) were implemented) and also drops the `isnull` operator, which is\n * a constant predicate over such rows: a corpus only covers `isnull` with\n * `nulls` on.\n */\n readonly nulls?: boolean;\n /**\n * Generate astral (non-BMP) text and text mixing BMP and astral\n * characters. Default `true`. This is where UTF-16 code-unit order (JS)\n * diverges from code-point order (Postgres `COLLATE \"C\"`, SQLite\n * `BINARY`) — ADR-0028 rule (c).\n */\n readonly astral?: boolean;\n /**\n * Apply the ordered operators (`gt gte lt lte`) to the boolean column too.\n * Default `true`. Postgres orders booleans `false < true` (ADR-0028\n * section 3), and so does `Predicate.compareLiterals`; `false` is the\n * regression floor from before that rule was implemented.\n */\n readonly booleanOrder?: boolean;\n}\n\ninterface ResolvedOptions {\n readonly nulls: boolean;\n readonly astral: boolean;\n readonly booleanOrder: boolean;\n}\n\nconst resolveOptions = (options: CorpusOptions | undefined): ResolvedOptions => ({\n nulls: options?.nulls ?? true,\n astral: options?.astral ?? true,\n booleanOrder: options?.booleanOrder ?? true,\n});\n\n// ─── Literal pools ───────────────────────────────────────────────────────────\n//\n// Rows draw from `rows`; predicate literals draw from `rows ∪ foreign`, so\n// every operator is exercised both against values that occur and values\n// that do not.\n\ninterface Pool {\n readonly rows: ReadonlyArray<Predicate.Literal>;\n readonly foreign: ReadonlyArray<Predicate.Literal>;\n}\n\nconst ASCII_STRINGS: ReadonlyArray<string> = [\n \"\",\n \"a\",\n \"b\",\n \"abc\",\n \"abd\",\n \"A\",\n \"Z\",\n \"z\",\n \" \",\n \"a b\",\n \"0\",\n \"10\",\n \"9\",\n];\n\n/** BMP non-ASCII: Latin-1, a private-use character, and the U+FFFF noncharacter. */\nconst BMP_STRINGS: ReadonlyArray<string> = [\"é\", \"ß\", \"éa\", \"\", \"￿\", \"ア\"];\n\n/** Astral characters, alone and mixed with BMP text. */\nconst ASTRAL_STRINGS: ReadonlyArray<string> = [\n \"😀\",\n \"𝔘\",\n \"\\u{10FFFF}\",\n \"a😀\",\n \"😀a\",\n \"￿😀\",\n \"é😀\",\n \"😀😀\",\n];\n\nconst FOREIGN_STRINGS: ReadonlyArray<string> = [\"nope\", \"zz\", \"è\"];\n\nconst INTEGERS: ReadonlyArray<number> = [\n 0, -0, 1, -1, 2, 3, 7, 10, 42, 100, -7, 2147483647, -2147483648, 2147483646,\n];\nconst FOREIGN_INTEGERS: ReadonlyArray<number> = [5, -100, 12345];\n\nconst DOUBLES: ReadonlyArray<number> = [\n 0,\n -0,\n 0.5,\n -0.5,\n 1e-7,\n 1.5,\n // The boundary of exact integers in a double: 2^53 - 1, 2^53, and the next\n // representable double above it (2^53 + 1 is not one; it rounds to 2^53 in\n // JS and Postgres alike). These live in the double column only because\n // int4 cannot hold them.\n 2 ** 53 - 1,\n 2 ** 53,\n 2 ** 53 + 2,\n 1e300,\n -1e-300,\n 3.25,\n 100.125,\n -2.5,\n];\nconst FOREIGN_DOUBLES: ReadonlyArray<number> = [2.75, 1e-6];\n\nconst INSTANTS: ReadonlyArray<string> = [\n \"1970-01-01T00:00:00.000Z\",\n \"1999-12-31T23:59:59.999Z\",\n \"2000-01-01T00:00:00.001Z\",\n \"2020-02-29T12:34:56.789Z\",\n \"2024-01-01T00:00:00.000Z\",\n \"2038-01-19T03:14:07.000Z\",\n];\nconst FOREIGN_INSTANTS: ReadonlyArray<string> = [\"2001-09-09T01:46:40.000Z\"];\n\nconst poolFor = (kind: Predicate.LiteralKind, options: ResolvedOptions): Pool => {\n switch (kind) {\n case \"text\":\n return {\n rows: [...ASCII_STRINGS, ...BMP_STRINGS, ...(options.astral ? ASTRAL_STRINGS : [])],\n foreign: FOREIGN_STRINGS,\n };\n case \"integer\":\n return { rows: INTEGERS, foreign: FOREIGN_INTEGERS };\n case \"double\":\n return { rows: DOUBLES, foreign: FOREIGN_DOUBLES };\n case \"boolean\":\n return { rows: [true, false], foreign: [] };\n case \"instant\":\n return { rows: INSTANTS, foreign: FOREIGN_INSTANTS };\n }\n};\n\n// ─── Rows ────────────────────────────────────────────────────────────────────\n\n/**\n * A generated row in its JS object form: an absent field is a missing key,\n * distinct from an explicit `null`. The SQL legs insert both as SQL NULL\n * (ADR-0028 rule (b)).\n */\nexport interface CorpusRow {\n readonly id: string;\n readonly value: Readonly<Record<string, Predicate.Literal>>;\n}\n\nconst NULL_RATE = 0.12;\nconst ABSENT_RATE = 0.08;\n\n/** The shape of one row set: its columns, their pools, and the pinned prefix. */\ninterface RowPlan {\n readonly columns: ReadonlyArray<Column>;\n readonly pools: ReadonlyArray<ReadonlyArray<Predicate.Literal>>;\n readonly nulls: boolean;\n /** Rows 0..pinned-1 are the all-NULL and all-absent rows (with `nulls`). */\n readonly pinned: number;\n /** Rows pinned..pinned+sweep-1 walk every pool value into every column. */\n readonly sweep: number;\n}\n\nconst planRows = (columns: ReadonlyArray<Column>, options: ResolvedOptions): RowPlan => {\n const pools = columns.map((column) => poolFor(column.kind, options).rows);\n return {\n columns,\n pools,\n nulls: options.nulls,\n pinned: options.nulls ? 2 : 0,\n sweep: Math.max(0, ...pools.map((pool) => pool.length)),\n };\n};\n\n/** A random field value: NULL, absent (`undefined`), or a pool value. */\nconst randomField = (\n pool: ReadonlyArray<Predicate.Literal>,\n nulls: boolean\n): Effect.Effect<Predicate.Literal | undefined> =>\n Effect.gen(function* () {\n if (nulls) {\n const roll = yield* Random.next;\n if (roll < NULL_RATE) return null;\n if (roll < NULL_RATE + ABSENT_RATE) return undefined;\n }\n return yield* pick(pool);\n });\n\nconst generateRow = (plan: RowPlan, index: number): Effect.Effect<CorpusRow> =>\n Effect.gen(function* () {\n const value: Record<string, Predicate.Literal> = {};\n yield* Effect.forEach(\n plan.columns.entries(),\n ([c, column]) =>\n Effect.gen(function* () {\n const pool = plan.pools[c] ?? [];\n let field: Predicate.Literal | undefined;\n if (index < plan.pinned) field = index === 0 ? null : undefined;\n else if (index < plan.pinned + plan.sweep)\n field = pool[(index - plan.pinned) % pool.length];\n else field = yield* randomField(pool, plan.nulls);\n if (field !== undefined) value[column.name] = field;\n }),\n { concurrency: 1, discard: true }\n );\n return { id: `r${String(index).padStart(3, \"0\")}`, value };\n });\n\n/**\n * The fewest rows {@link generateRows} accepts for `columns` under\n * `options`: the pinned NULL/absent rows plus the sweep that puts every pool\n * value into every column. Fewer would silently drop guaranteed edge values.\n */\nexport const minimumRows = (\n columns: ReadonlyArray<Column> = corpusColumns,\n options?: CorpusOptions\n): number => {\n const plan = planRows(columns, resolveOptions(options));\n return plan.pinned + plan.sweep;\n};\n\n/**\n * Generate `count` rows over `columns`. Coverage of the edge values is\n * guaranteed, not left to chance: with `nulls` on, row 0 is all-NULL and row\n * 1 all-absent; then one row per pool position sweeps every pool value into\n * every column (int4 bounds, `-0`, `2^53±1`, the empty string, U+FFFF, the\n * astral characters, …); the remaining rows are random with NULL/absent\n * rolls. `count` below {@link minimumRows} is an error rather than a\n * truncated sweep. Ids are zero-padded ASCII (`r000`, `r001`, …) so their\n * order is the same in JS, SQLite `BINARY`, and Postgres `COLLATE \"C\"`,\n * keeping the id tie-break comparable across legs.\n */\nexport const generateRows = (\n count: number,\n columns: ReadonlyArray<Column> = corpusColumns,\n options?: CorpusOptions\n): Effect.Effect<ReadonlyArray<CorpusRow>> => {\n const plan = planRows(columns, resolveOptions(options));\n const minimum = plan.pinned + plan.sweep;\n if (count < minimum) {\n throw new Error(\n `generateRows needs at least ${minimum} rows for these columns (the pinned rows plus the pool sweep), got ${count}`\n );\n }\n return Effect.forEach(\n Array.from({ length: count }, (_, index) => index),\n (index) => generateRow(plan, index)\n );\n};\n\n// ─── Operators ───────────────────────────────────────────────────────────────\n//\n// The operator core of ADR-0028: `eq ne lt lte gt gte in nin isnull` plus\n// `and or not`. `nin` is the `NotIn` node and `isnull` the `IsNull` node,\n// negated half the time so `IS NOT NULL` is exercised as its own node and\n// not only as `Not(IsNull)`.\n\n/** Every operator name the generator can emit; coverage is counted by these. */\nexport type OperatorName =\n | \"eq\"\n | \"ne\"\n | \"gt\"\n | \"gte\"\n | \"lt\"\n | \"lte\"\n | \"in\"\n | \"nin\"\n | \"isnull\"\n | \"and\"\n | \"or\"\n | \"not\"\n | \"true\";\n\n/** Per-operator emission counts for one generated corpus. */\nexport type Coverage = Record<OperatorName, number>;\n\n/** A fresh all-zero coverage table. */\nexport const emptyCoverage = (): Coverage => ({\n eq: 0,\n ne: 0,\n gt: 0,\n gte: 0,\n lt: 0,\n lte: 0,\n in: 0,\n nin: 0,\n isnull: 0,\n and: 0,\n or: 0,\n not: 0,\n true: 0,\n});\n\ninterface LeafOperator {\n readonly name: OperatorName;\n /** An ordered comparison: applied to a boolean column only with `booleanOrder`. */\n readonly ordered: boolean;\n /** Build the leaf from a literal draw and a list draw; each runs only if used. */\n readonly build: (\n field: string,\n literal: Effect.Effect<Predicate.Literal>,\n list: Effect.Effect<ReadonlyArray<Predicate.Literal>>\n ) => Effect.Effect<Predicate.Predicate>;\n}\n\nconst comparison =\n (make: (field: string, value: Predicate.Literal) => Predicate.Predicate): LeafOperator[\"build\"] =>\n (field, literal) =>\n Effect.map(literal, (value) => make(field, value));\n\n/** The leaf operator table: one constructor per core operator. */\nexport const leafOperators: ReadonlyArray<LeafOperator> = [\n { name: \"eq\", ordered: false, build: comparison(Predicate.eq) },\n { name: \"ne\", ordered: false, build: comparison(Predicate.ne) },\n { name: \"gt\", ordered: true, build: comparison(Predicate.gt) },\n { name: \"gte\", ordered: true, build: comparison(Predicate.gte) },\n { name: \"lt\", ordered: true, build: comparison(Predicate.lt) },\n { name: \"lte\", ordered: true, build: comparison(Predicate.lte) },\n {\n name: \"in\",\n ordered: false,\n build: (field, _literal, list) => Effect.map(list, (values) => Predicate.isIn(field, values)),\n },\n {\n name: \"nin\",\n ordered: false,\n build: (field, _literal, list) => Effect.map(list, (values) => Predicate.notIn(field, values)),\n },\n {\n name: \"isnull\",\n ordered: false,\n build: (field) =>\n Effect.map(chance(0.5), (negated) =>\n negated ? Predicate.isNotNull(field) : Predicate.isNull(field)\n ),\n },\n];\n\n// ─── Predicates ──────────────────────────────────────────────────────────────\n\nconst EMPTY_IN_RATE = 0.1;\nconst LEAF_RATE = 0.55;\nconst TRUE_RATE = 0.03;\nconst FOREIGN_RATE = 0.3;\n\n/** A literal of the pool's kind: usually one that occurs, sometimes one that does not. */\nconst literalFor = (pool: Pool): Effect.Effect<Predicate.Literal> =>\n Effect.gen(function* () {\n const foreign = Arr.isReadonlyArrayNonEmpty(pool.foreign) && (yield* chance(FOREIGN_RATE));\n return yield* pick(foreign ? pool.foreign : pool.rows);\n });\n\n/** An `In` list: occasionally empty, otherwise 1–4 literals. */\nconst listFor = (pool: Pool): Effect.Effect<ReadonlyArray<Predicate.Literal>> =>\n Effect.gen(function* () {\n if (yield* chance(EMPTY_IN_RATE)) return [];\n const length = 1 + (yield* int(4));\n return yield* literalFor(pool).pipe(Effect.replicateEffect(length));\n });\n\nconst generateLeaf = (\n columns: ReadonlyArray<Column>,\n options: ResolvedOptions,\n coverage: Coverage\n): Effect.Effect<Predicate.Predicate> =>\n Effect.gen(function* () {\n if (yield* chance(TRUE_RATE)) {\n coverage.true++;\n return Predicate.always;\n }\n const column = yield* pick(columns);\n const pool = poolFor(column.kind, options);\n // Ordered operators reach the boolean column only with `booleanOrder`;\n // `isnull` is only worth emitting when NULL/absent rows exist.\n const candidates = leafOperators.filter(\n (op) =>\n (!op.ordered || column.kind !== \"boolean\" || options.booleanOrder) &&\n (op.name !== \"isnull\" || options.nulls)\n );\n const operator = yield* pick(candidates);\n coverage[operator.name]++;\n return yield* operator.build(column.name, literalFor(pool), listFor(pool));\n });\n\n/**\n * Generate one depth-bounded predicate tree: leaves from the operator table\n * on a random column with a literal of that column's kind; `And`/`Or` with\n * 2–3 children and `Not` with one, down to `depth`. Emitted operators are\n * tallied into `coverage`.\n */\nexport const generatePredicate = (\n columns: ReadonlyArray<Column>,\n options: CorpusOptions | undefined,\n coverage: Coverage,\n depth = 2\n): Effect.Effect<Predicate.Predicate> => {\n const resolved = resolveOptions(options);\n const go = (remaining: number): Effect.Effect<Predicate.Predicate> =>\n Effect.gen(function* () {\n if (remaining === 0 || (yield* chance(LEAF_RATE))) {\n return yield* generateLeaf(columns, resolved, coverage);\n }\n const branch = yield* int(3);\n if (branch === 2) {\n coverage.not++;\n return Predicate.not(yield* go(remaining - 1));\n }\n const width = 2 + (yield* int(2));\n const children = yield* go(remaining - 1).pipe(Effect.replicateEffect(width));\n if (branch === 0) {\n coverage.and++;\n return Predicate.and(...children);\n }\n coverage.or++;\n return Predicate.or(...children);\n });\n return go(depth);\n};\n\n// ─── Order terms ─────────────────────────────────────────────────────────────\n\n/** Generate 1–2 `orderBy` terms over distinct columns with random directions. */\nexport const generateOrderBy = (\n columns: ReadonlyArray<Column> = corpusColumns\n): Effect.Effect<ReadonlyArray<Subset.OrderBy>> =>\n Effect.gen(function* () {\n const count = Math.min(columns.length, 1 + (yield* int(2)));\n const shuffled = yield* Random.shuffle(columns);\n return yield* Effect.forEach(shuffled.slice(0, count), (column) =>\n Effect.map(Random.nextBoolean, (asc): Subset.OrderBy => ({\n field: column.name,\n direction: asc ? \"asc\" : \"desc\",\n }))\n );\n });\n\n// ─── Corpus ──────────────────────────────────────────────────────────────────\n\n/** Options for {@link generateCorpus}. */\nexport interface GenerateOptions extends CorpusOptions {\n readonly seed: number;\n readonly columns?: ReadonlyArray<Column>;\n /** Rows in the fixture set (default 64: the pinned sweep plus random rows). */\n readonly rows?: number;\n /** Predicates to generate (default 200). */\n readonly predicates?: number;\n /** `orderBy` term lists to generate (default 60). */\n readonly orderBys?: number;\n /** Predicate tree depth bound (default 2). */\n readonly depth?: number;\n}\n\n/** A generated corpus: one row set, many predicates and order terms, and coverage. */\nexport interface Corpus {\n readonly seed: number;\n readonly columns: ReadonlyArray<Column>;\n readonly rows: ReadonlyArray<CorpusRow>;\n readonly predicates: ReadonlyArray<Predicate.Predicate>;\n readonly orderBys: ReadonlyArray<ReadonlyArray<Subset.OrderBy>>;\n readonly coverage: Coverage;\n}\n\n/**\n * Generate a whole corpus deterministically from a seed. The generators run\n * under `Random.withSeed(options.seed)`; the seeding is suspended so every\n * run of the returned effect starts the sequence afresh and yields the same\n * corpus.\n */\nexport const generateCorpus = (options: GenerateOptions): Effect.Effect<Corpus> =>\n Effect.suspend(() => {\n const columns = options.columns ?? corpusColumns;\n const coverage = emptyCoverage();\n return Effect.gen(function* () {\n const rows = yield* generateRows(options.rows ?? 64, columns, options);\n const predicates = yield* generatePredicate(\n columns,\n options,\n coverage,\n options.depth ?? 2\n ).pipe(Effect.replicateEffect(options.predicates ?? 200));\n const orderBys = yield* generateOrderBy(columns).pipe(\n Effect.replicateEffect(options.orderBys ?? 60)\n );\n return { seed: options.seed, columns, rows, predicates, orderBys, coverage };\n }).pipe(Random.withSeed(options.seed));\n });\n\n// ─── Minimiser ───────────────────────────────────────────────────────────────\n\n/** A predicate over a row set — the unit the harness compares and shrinks. */\nexport interface Case {\n readonly predicate: Predicate.Predicate;\n readonly rows: ReadonlyArray<CorpusRow>;\n}\n\nconst replaceAt = <A>(xs: ReadonlyArray<A>, index: number, x: A): Array<A> =>\n xs.map((y, i) => (i === index ? x : y));\nconst without = <A>(xs: ReadonlyArray<A>, index: number): Array<A> =>\n xs.filter((_, i) => i !== index);\n\n/**\n * One-step shrinks of a predicate, larger jumps first: replace a junction by\n * one child, drop one child, unwrap `Not`, drop one `In` value, then the\n * same recursively inside each child.\n */\nexport const shrinkPredicate = (\n predicate: Predicate.Predicate\n): ReadonlyArray<Predicate.Predicate> => {\n switch (predicate._tag) {\n case \"And\":\n case \"Or\": {\n const rebuild = predicate._tag === \"And\" ? Predicate.and : Predicate.or;\n const children = predicate.predicates;\n const out: Array<Predicate.Predicate> = [];\n if (children.length > 1) {\n out.push(...children);\n out.push(...children.map((_, i) => rebuild(...without(children, i))));\n }\n children.forEach((child, i) => {\n Arr.forEach(shrinkPredicate(child), (shrunk) => {\n out.push(rebuild(...replaceAt(children, i, shrunk)));\n });\n });\n return out;\n }\n case \"Not\":\n return [predicate.predicate, ...shrinkPredicate(predicate.predicate).map(Predicate.not)];\n case \"In\":\n case \"NotIn\": {\n const rebuild = predicate._tag === \"In\" ? Predicate.isIn : Predicate.notIn;\n return predicate.values.length > 1\n ? predicate.values.map((_, i) => rebuild(predicate.field, without(predicate.values, i)))\n : [];\n }\n default:\n return [];\n }\n};\n\nconst MAX_SHRINK_STEPS = 1000;\n\n/**\n * Greedily shrink a disagreeing case while `disagrees` keeps holding:\n * predicate shrinks first, then row removals, restarting from the smallest\n * accepted candidate until no candidate still disagrees. `disagrees` runs the\n * subjects, so it is an Effect (the SQL legs are asynchronous).\n */\nexport const minimise = <E, R>(\n failing: Case,\n disagrees: (candidate: Case) => Effect.Effect<boolean, E, R>\n): Effect.Effect<Case, E, R> => {\n // One round: the first shrunk candidate that still disagrees replaces\n // `current`; every candidate tried counts against the step budget.\n const round = (current: Case, steps: number): Effect.Effect<Case, E, R> => {\n if (steps >= MAX_SHRINK_STEPS) return Effect.succeed(current);\n const candidates: Array<Case> = [\n ...shrinkPredicate(current.predicate).map((predicate) => ({\n predicate,\n rows: current.rows,\n })),\n ...current.rows.map((_, i) => ({\n predicate: current.predicate,\n rows: without(current.rows, i),\n })),\n ];\n let tried = 0;\n return Effect.findFirst(candidates, (candidate) => {\n tried++;\n return disagrees(candidate);\n }).pipe(\n Effect.flatMap((accepted) =>\n Option.isSome(accepted) ? round(accepted.value, steps + tried) : Effect.succeed(current)\n )\n );\n };\n return round(failing, 0);\n};\n\n// ─── Reporting ───────────────────────────────────────────────────────────────\n\n/** A disagreement between subjects, ready to print. */\nexport interface Disagreement {\n readonly seed: number;\n readonly subject: string;\n readonly predicate?: Predicate.Predicate;\n readonly orderBy?: ReadonlyArray<Subset.OrderBy>;\n /** The (minimal) rows; any `(id, value)` row prints, not only corpus rows. */\n readonly rows: ReadonlyArray<Subset.Row>;\n /** Per-subject result (ids), keyed by subject name. */\n readonly results: Readonly<Record<string, ReadonlyArray<string>>>;\n /**\n * How to reproduce at this seed. Defaults to the harness's environment\n * override; a caller with a fixed seed (`BackendContract`) says so instead.\n */\n readonly reproduce?: string;\n}\n\n/**\n * `JSON.stringify` that keeps `-0` visible (as the string `\"-0\"`): plain\n * JSON prints it as `0`, and a minimal case built on `-0` would not\n * reproduce from its own report.\n */\nconst print = (value: unknown): string =>\n JSON.stringify(value, (_key, field: unknown) => (Object.is(field, -0) ? \"-0\" : field));\n\n/**\n * Render a disagreement: the seed, the (minimal) predicate or order terms,\n * the (minimal) rows — absent keys stay absent, `null` prints as `null`,\n * `-0` prints as `\"-0\"` — and every subject's ids.\n */\nexport const formatDisagreement = (disagreement: Disagreement): string => {\n const reproduce = disagreement.reproduce ?? \"set LEGATION_CORPUS_SEED to reproduce\";\n const lines = [`${disagreement.subject} (seed ${disagreement.seed}; ${reproduce})`];\n if (disagreement.predicate !== undefined) {\n lines.push(`predicate: ${print(disagreement.predicate)}`);\n }\n if (disagreement.orderBy !== undefined) {\n lines.push(`orderBy: ${print(disagreement.orderBy)}`);\n }\n lines.push(\"rows:\");\n Arr.forEach(disagreement.rows, (row) => {\n lines.push(` ${row.id} ${print(row.value)}`);\n });\n Arr.forEach(Object.entries(disagreement.results), ([name, ids]) => {\n lines.push(`${name}: ${JSON.stringify(ids)}`);\n });\n return lines.join(\"\\n\");\n};\n","/**\n * BackendContract\n *\n * The executable specification of the Backend contract (ADR-0009).\n * `verifyBackendContract` drives an implementation through the guarantees\n * documented in Backend.ts — in-order application, idempotent skip, gap\n * rejection, bump-atomic-with-effects (for both a transient failure and a\n * permanent rejection), version-bumping writes, reference subset-evaluation\n * semantics (Subset.apply), and client-group isolation — failing with a\n * ContractViolation naming the broken rule.\n *\n * The backend under test must register the contract mutators (the\n * definitions below; `memoryHandlers` is the ready-made registration for\n * MemoryBackend-style backends). Verification writes rows into the\n * configured contract collections, so run it against disposable instances.\n *\n * Visibility before the bump (guarantee 1) is not a rule here. The rules make\n * one call at a time, so the harness never observes a backend mid-mutation:\n * that needs a handler parked after its write, which only the backend's own\n * handler can express, and its concurrency differs per backend. Each backend\n * therefore discharges it itself: `MemoryBackend` by its stage (covered by\n * `memory-backend-atomicity.test.ts`, \"keeps a handler's writes and its bump\n * invisible until the mutation commits\"). `SqlBackend` by its transaction\n * (`sql-backend-visibility.test.ts`: a second connection reads nothing of a\n * parked handler's write or bump). `JsonApiBackend` by the server's\n * all-or-nothing batch (`jsonapi-atomic-contract.test.ts`, \"JsonApiBackend\n * visibility before the bump\"). A new backend must add its own mid-flight test\n * before it can claim guarantee 1.\n *\n * Serialisability across client groups (guarantee 1, #353) is a rule: rule 11\n * parks a handler after its read, lets another group commit a write to the same\n * row, then resumes the handler and checks that no write was lost. Its handler\n * parks through {@link park}, the one seam a backend's own counter handler needs\n * to expose the read-then-write window. The gate is named by a string in the\n * mutator's args, so the mutation stays serialisable like any other.\n *\n * A backend that caches the rows a listing returns must keep that cache in line\n * with its own writes: rule 12 lists a collection, applies an update and a delete\n * to listed rows through the backend, and checks that `getRows` returns the\n * post-write value and omits the deleted row, without a re-list (#444). It uses\n * the existing `putRow` and `delRow` mutators and the `evaluate` collection.\n *\n * **Types and runtime (#177, ADR-0009's amendment).** A backend whose\n * `applyMutations` is built with `Backend.transaction` gets the ledger's\n * ordering rules by construction: in-order application, idempotent skip and gap\n * rejection (rules 1–3), and the bump travelling with each outcome, a rejection\n * committing no effects (rules 4, 9 and 10). The store keeps one obligation:\n * its `commit` (or `atomically`) must really be atomic and isolated. Types cannot\n * see that, so this suite still runs every rule against every backend, built\n * through the combinator or by hand. Evaluation (rules 6 and 14), row versions,\n * `getRows`, isolation and the rejection list (rules 5, 7, 8, 12 and 13) are\n * behaviour, and stay runtime only.\n *\n * A backend that provides the optional `evaluateMany` (#505) must agree with\n * its own `evaluate`: rule 14 asks for rule 6's subsets, the generated corpus\n * included, in one call and checks each list against `evaluate` for that\n * subset. A backend without it passes that rule vacuously.\n */\n\nimport * as Arr from \"effect/Array\";\nimport * as DateTime from \"effect/DateTime\";\nimport * as Deferred from \"effect/Deferred\";\nimport * as Effect from \"effect/Effect\";\nimport * as Exit from \"effect/Exit\";\nimport * as Fiber from \"effect/Fiber\";\nimport * as Option from \"effect/Option\";\nimport * as Schema from \"effect/Schema\";\nimport type { Backend, SubsetEntry, SyncContext } from \"./Backend.js\";\nimport { BackendError, MutationRejected } from \"./Errors.js\";\nimport * as FilterCorpus from \"./FilterCorpus.js\";\nimport * as MemoryBackend from \"./MemoryBackend.js\";\nimport * as Mutator from \"./Mutator.js\";\nimport * as Predicate from \"./Predicate.js\";\nimport type { Mutation } from \"./Protocol.js\";\nimport * as Subset from \"./Subset.js\";\nimport * as UnknownMutator from \"./UnknownMutator.js\";\n\n/** A backend broke one of the contract's guarantees. */\nexport class ContractViolation extends Schema.TaggedError<\n ContractViolation,\n { readonly brand: unique symbol }\n>()(\"ContractViolation\", {\n rule: Schema.String,\n message: Schema.String,\n}) {}\n\n// ─── Park gates (rule 11) ────────────────────────────────────────────────────\n\n/** A park gate the harness holds: `entered` once the handler is parked, `release` lets it resume. */\ninterface ParkGate {\n readonly entered: Deferred.Deferred<void>;\n readonly release: Deferred.Deferred<void>;\n}\n\n/** The gates the harness has registered, by name. Args carry the name, never the gate. */\nconst parkGates = new Map<string, ParkGate>();\n\n/**\n * The park a `contract/count-up` handler takes between its read and its write.\n * When the harness has registered `gate`, it signals that the handler is parked\n * and waits until the harness releases it; for any other name it does nothing.\n * Only the contract's `countUp` handler calls it, so no production handler should.\n */\nexport const park = (gate: string): Effect.Effect<void> => {\n const registered = parkGates.get(gate);\n return registered === undefined\n ? Effect.void\n : Deferred.succeed(registered.entered, undefined).pipe(\n Effect.andThen(Deferred.await(registered.release))\n );\n};\n\n// ─── Contract mutators ───────────────────────────────────────────────────────\n\n/** Write one row. */\nexport const putRow = Mutator.make(\n \"contract/put\",\n Schema.Struct({ collection: Schema.String, id: Schema.String, value: Schema.Unknown })\n);\n\n/** Delete one row. */\nexport const delRow = Mutator.make(\n \"contract/del\",\n Schema.Struct({ collection: Schema.String, id: Schema.String })\n);\n\n/**\n * Fails transiently — probes that a `BackendError` aborts the batch and the\n * mutation-id bump is atomic with effects (no bump on abort).\n */\nexport const failAlways = Mutator.make(\"contract/fail\", Schema.Struct({}));\n\n/** The reason `rejectAlways` gives for its permanent rejection. */\nconst rejectReason = \"contract/reject always rejects\";\n\n/**\n * Writes a row and then rejects permanently — probes that a `MutationRejected`\n * bumps the id *without* leaving effects (the staged write must roll back).\n */\nexport const rejectAlways = Mutator.make(\n \"contract/reject\",\n Schema.Struct({ collection: Schema.String, id: Schema.String })\n);\n\n/**\n * Writes a row and then fails transiently — probes that a `BackendError` leaves\n * no trace of that write (the row keeps its value and version) and no bump\n * (the client's retry applies the mutation again). `failAlways` writes nothing\n * first, so it does not probe this. A backend that cannot discard a handler's\n * writes on its own failure fails this rule by design: D1 commits each\n * statement separately (#342), so it is not run through this contract. A\n * registered handler that never writes passes this rule vacuously, and the\n * contract cannot detect that: it sees only the failure.\n */\nexport const writeThenFail = Mutator.make(\n \"contract/write-then-fail\",\n Schema.Struct({ collection: Schema.String, id: Schema.String })\n);\n\n/**\n * Reads a counter row, parks after the read (see {@link park}), then writes the\n * counter plus one. Two client groups running it on one row must both count\n * (rule 11). `gate` names a park gate the harness registered, or matches none.\n *\n * A third-party backend registers its handler for this mutator under\n * `BackendContract.countUp.name` (`contract/count-up`), passes `gate` unchanged\n * to `park` between its read and its write, and writes the counter plus one. A\n * handler that omits `park` fails rule 11 with \"finished without reaching park()\".\n */\nexport const countUp = Mutator.make(\n \"contract/count-up\",\n Schema.Struct({ collection: Schema.String, id: Schema.String, gate: Schema.String })\n);\n\n/** Ready-made authoritative handlers for MemoryBackend-style registration. */\nexport const memoryHandlers: Record<string, MemoryBackend.BackendHandler> =\n MemoryBackend.validatedHandlers([\n MemoryBackend.handler(putRow, (args, writer) =>\n writer.put(args.collection, args.id, args.value)\n ),\n MemoryBackend.handler(delRow, (args, writer) => writer.del(args.collection, args.id)),\n MemoryBackend.handler(failAlways, () =>\n Effect.fail(new BackendError({ message: \"contract/fail always fails\" }))\n ),\n MemoryBackend.handler(rejectAlways, (args, writer) =>\n writer\n .put(args.collection, args.id, { poison: true })\n .pipe(Effect.andThen(Effect.fail(new MutationRejected({ reason: rejectReason }))))\n ),\n MemoryBackend.handler(writeThenFail, (args, writer) =>\n writer\n .put(args.collection, args.id, { n: 99 })\n .pipe(\n Effect.andThen(\n Effect.fail(\n new BackendError({ message: \"contract/write-then-fail fails after writing\" })\n )\n )\n )\n ),\n MemoryBackend.handler(countUp, (args, writer) =>\n Effect.gen(function* () {\n const current = (yield* writer.get(args.collection, args.id)) as\n | { readonly n?: number }\n | undefined;\n yield* park(args.gate);\n yield* writer.put(args.collection, args.id, { n: (current?.n ?? 0) + 1 });\n })\n ),\n ]);\n\n// ─── Verification harness ────────────────────────────────────────────────────\n\n/**\n * Waits, while rule 11 holds a parked call, for the peer call the harness started. `peerSettled`\n * reads true once the peer's call has finished. The returned effect must complete once the peer has\n * settled, or once the backend observes the peer blocked on a lock the parked call holds (the peer\n * can then finish only after the parked call is released). It decides on that observed state, never\n * on elapsed time.\n */\nexport type PeerSettle = (peerSettled: Effect.Effect<boolean>) => Effect.Effect<void>;\n\n/** Options for {@link verifyBackendContract}. */\nexport interface VerifyOptions {\n /** Base name for the collections written during verification. */\n readonly collection?: string;\n readonly clientGroupId?: string;\n /**\n * How rule 11 waits for the peer while the parked call is held. Absent, the\n * harness gives the peer a bounded number of scheduler turns, which suits a backend\n * whose peer runs at once or waits on a lock. A backend whose peer does real I/O\n * (PostgreSQL) cannot reach the overlap that way, so it observes the peer instead\n * (#416).\n */\n readonly awaitPeer?: PeerSettle | undefined;\n /**\n * The contract client's ledger a restarted run expects: the id the backend reported for it before the\n * restart. Absent, the run is a fresh group and expects 0. The contract fails first when the backend\n * reports another id, naming a forgotten or differing ledger, then numbers its mutations from it (#483).\n */\n readonly restoredLedger?: number | undefined;\n /**\n * The ledger rule 11's peer group expects on a restarted run, as `restoredLedger` is for the\n * contract client. Absent, the peer group is fresh and expects 0 (#483).\n */\n readonly restoredPeerLedger?: number | undefined;\n}\n\ninterface EvalRow {\n readonly rank: number;\n /**\n * A string discriminator rather than a boolean: SQL backends store what\n * their columns can hold, and e.g. SQLite has no boolean type — the\n * contract exercises predicate evaluation, not a value-encoding\n * convention (ADR-0014 keeps values opaque).\n */\n readonly tag: \"keep\" | \"drop\";\n}\n\n/**\n * What every rule shares: the backend under test, the fixed sync context and\n * client id, the two contract collections, the mutation constructors, and\n * the helpers that turn a backend call into a `ContractViolation`.\n */\ninterface Harness {\n readonly backend: Backend;\n readonly context: SyncContext;\n readonly clientId: string;\n /**\n * The contract client's last acknowledged id when the contract begins: 0 on a\n * fresh group, the restored id on a backend restarted over its ledger (#477, #483).\n * Every rule numbers its mutations from here, so expectations are relative to it.\n */\n readonly start: number;\n /** Rule 11's peer group's last acknowledged id when the contract begins (#483). */\n readonly peerStart: number;\n /** The collection the write rules target. */\n readonly rows: string;\n /** The collection rule 6 evaluates subsets over. */\n readonly evalRows: string;\n readonly check: (\n rule: string,\n condition: boolean,\n message: string\n ) => Effect.Effect<void, ContractViolation>;\n /** Run backend calls that the contract requires to succeed. */\n readonly expectOk: <A>(\n rule: string,\n effect: Effect.Effect<A, BackendError>\n ) => Effect.Effect<A, ContractViolation>;\n /** Run backend calls that the contract requires to fail. */\n readonly expectFail: (\n rule: string,\n effect: Effect.Effect<unknown, BackendError>,\n what: string\n ) => Effect.Effect<void, ContractViolation>;\n /**\n * Run a call that must fail because the named contract mutator ran and\n * failed. An unregistered mutator fails the same way, so that failure is\n * reported as a missing registration rather than a pass.\n */\n readonly expectRegisteredFailure: (\n rule: string,\n effect: Effect.Effect<unknown, BackendError>,\n mutator: string,\n exportName: string\n ) => Effect.Effect<void, ContractViolation>;\n /** The contract client's last mutation id in the verification group. */\n readonly lastIdOf: (rule: string) => Effect.Effect<number, ContractViolation>;\n readonly mutation: (mutationId: number, mutator: string, args: unknown) => Mutation;\n readonly put: (mutationId: number, collection: string, id: string, value: unknown) => Mutation;\n readonly reject: (mutationId: number, collection: string, id: string) => Mutation;\n /** The backend's own peer wait for rule 11, when it supplies one. */\n readonly awaitPeer: PeerSettle | undefined;\n}\n\n/**\n * True when a failed call shows `mutator` is not registered. The\n * `UnknownMutator` tag identifies it; the exact message `UnknownMutator.make`\n * writes is a fallback for a third-party backend that does not use it yet, so a\n * registered handler whose own error merely mentions \"Unknown mutator\" still counts.\n */\nconst isUnregisteredFailure = (error: BackendError, mutator: string): boolean =>\n UnknownMutator.isError(error) || error.message === `Unknown mutator: ${mutator}`;\n\n/** The client id every contract mutation is sent under. */\nconst CONTRACT_CLIENT = \"contract-client\";\n\n/**\n * The rule that checks, before any other rule runs, that the backend reports the\n * ledger the run expects (#483).\n */\nconst restoredLedgerRule = \"reports the ledger the run expects\";\n\n/**\n * The message for a backend whose ledger for `clientId` in the named group is not the one the run\n * expects. A fresh group must report 0. A restored group that reports 0 has forgotten its ledger.\n */\nconst ledgerMismatch = (\n group: string,\n clientId: string,\n expected: number,\n reported: number\n): string => {\n const ledger = `lastMutationIds[\"${clientId}\"]`;\n if (expected === 0) {\n return `A fresh ${group} must report ${ledger} = 0, got ${reported}`;\n }\n if (reported === 0) {\n return `Expected the restored ${group} ${ledger} = ${expected}, got 0: the backend forgot its ledger on restart`;\n }\n return `Expected the restored ${group} ${ledger} = ${expected}, got ${reported}: the restored ledger differs`;\n};\n\nconst makeHarness = (\n backend: Backend,\n options: VerifyOptions | undefined,\n start: number,\n peerStart: number\n): Harness => {\n const rows = options?.collection ?? \"__contract\";\n const context: SyncContext = { clientGroupId: options?.clientGroupId ?? \"__contract-group\" };\n const clientId = CONTRACT_CLIENT;\n\n const violation = (rule: string, message: string) => new ContractViolation({ rule, message });\n const check: Harness[\"check\"] = (rule, condition, message) =>\n condition ? Effect.void : Effect.fail(violation(rule, message));\n const expectOk: Harness[\"expectOk\"] = (rule, effect) =>\n effect.pipe(\n Effect.mapError((error) => violation(rule, `Backend failed unexpectedly: ${error.message}`))\n );\n const expectFail: Harness[\"expectFail\"] = (rule, effect, what) =>\n Effect.exit(effect).pipe(\n Effect.flatMap((exit) => check(rule, exit._tag === \"Failure\", `Expected failure: ${what}`))\n );\n const expectRegisteredFailure: Harness[\"expectRegisteredFailure\"] = (\n rule,\n effect,\n mutator,\n exportName\n ) =>\n Effect.exit(effect).pipe(\n Effect.flatMap((exit) => {\n const failure = Exit.findErrorOption(exit);\n if (Option.isNone(failure)) {\n return check(rule, false, `Expected failure: the ${mutator} mutator`);\n }\n return check(\n rule,\n !isUnregisteredFailure(failure.value, mutator),\n `${mutator} is not registered: register BackendContract.${exportName}`\n );\n })\n );\n const mutation: Harness[\"mutation\"] = (mutationId, mutator, args) => ({\n clientId,\n mutationId,\n mutator,\n args,\n createdAt: DateTime.toEpochMillis(DateTime.nowUnsafe()),\n });\n\n return {\n backend,\n context,\n clientId,\n start,\n peerStart,\n rows,\n evalRows: `${rows}_eval`,\n check,\n expectOk,\n expectFail,\n expectRegisteredFailure,\n lastIdOf: (rule) =>\n expectOk(rule, backend.lastMutationIds(context)).pipe(\n Effect.map((ids) => ids[clientId] ?? 0)\n ),\n mutation,\n put: (mutationId, collection, id, value) =>\n mutation(mutationId, putRow.name, { collection, id, value }),\n reject: (mutationId, collection, id) =>\n mutation(mutationId, rejectAlways.name, { collection, id }),\n awaitPeer: options?.awaitPeer,\n };\n};\n\n/** One numbered rule of the contract, run against the shared harness. */\ntype Rule = (h: Harness) => Effect.Effect<void, ContractViolation>;\n\n// ─── Rules ───────────────────────────────────────────────────────────────────\n\n/** 1. In-order application bumps lastMutationIds and applies effects. */\nconst rule1InOrderApplication: Rule = ({\n backend,\n context,\n clientId,\n rows,\n start,\n check,\n expectOk,\n put,\n}) =>\n Effect.gen(function* () {\n const rule = \"applies mutations in order and bumps lastMutationIds\";\n const result = yield* expectOk(\n rule,\n backend.applyMutations(context, [\n put(start + 1, rows, \"a\", { n: 1 }),\n put(start + 2, rows, \"b\", { n: 2 }),\n ])\n );\n yield* check(\n rule,\n result.lastMutationIds[clientId] === start + 2,\n `Expected lastMutationIds[\"${clientId}\"] = ${start + 2}, got ${result.lastMutationIds[clientId]}`\n );\n const fetched = yield* expectOk(rule, backend.getRows(context, rows, [\"a\", \"b\"]));\n yield* check(rule, fetched.length === 2, `Expected 2 rows back, got ${fetched.length}`);\n yield* check(\n rule,\n fetched.every((row) => row.version !== undefined && row.version !== null),\n \"Every row must carry a row version\"\n );\n });\n\n/** 2. Idempotent skip: an already-applied mutation id has no effect. */\nconst rule2IdempotentSkip: Rule = ({\n backend,\n context,\n clientId,\n rows,\n start,\n check,\n expectOk,\n put,\n}) =>\n Effect.gen(function* () {\n const rule = \"skips already-applied mutation ids (idempotency)\";\n const result = yield* expectOk(\n rule,\n backend.applyMutations(context, [put(start + 2, rows, \"b\", { n: 99 })])\n );\n yield* check(\n rule,\n result.lastMutationIds[clientId] === start + 2,\n `Replaying mutation ${start + 2} must keep lastMutationId at ${start + 2}, got ${result.lastMutationIds[clientId]}`\n );\n const [b] = yield* expectOk(rule, backend.getRows(context, rows, [\"b\"]));\n // Field-level check, not exact value equality: how a backend encodes a\n // row (extra columns, an id echoed into the value) is its own business\n // (ADR-0014 keeps values opaque); the contract only demands the replay\n // did not re-execute.\n yield* check(\n rule,\n (b?.value as { n?: number } | undefined)?.n === 2,\n `Replaying mutation 2 must not re-execute its effects (row \"b\" became ${JSON.stringify(b?.value)})`\n );\n });\n\n/** 3. Gap rejection: a mutation id beyond last+1 is an error. */\nconst rule3GapRejection: Rule = ({\n backend,\n context,\n rows,\n start,\n check,\n expectOk,\n expectFail,\n lastIdOf,\n put,\n}) =>\n Effect.gen(function* () {\n const rule = \"rejects mutation-id gaps\";\n yield* expectFail(\n rule,\n backend.applyMutations(context, [put(start + 4, rows, \"c\", { n: 4 })]),\n `mutation id ${start + 4} after lastMutationId ${start + 2}`\n );\n yield* check(\n rule,\n (yield* lastIdOf(rule)) === start + 2,\n \"A rejected gap must not bump lastMutationId\"\n );\n const fetched = yield* expectOk(rule, backend.getRows(context, rows, [\"c\"]));\n yield* check(rule, Arr.isReadonlyArrayEmpty(fetched), \"A rejected gap must not apply effects\");\n });\n\n/** 4. Atomicity: a failed mutator bumps nothing. */\nconst rule4AtomicBump: Rule = ({\n backend,\n context,\n start,\n check,\n expectRegisteredFailure,\n lastIdOf,\n mutation,\n}) =>\n Effect.gen(function* () {\n const rule = \"keeps the lastMutationId bump atomic with mutator effects\";\n yield* expectRegisteredFailure(\n rule,\n backend.applyMutations(context, [mutation(start + 3, failAlways.name, {})]),\n failAlways.name,\n \"failAlways\"\n );\n yield* check(\n rule,\n (yield* lastIdOf(rule)) === start + 2,\n \"A failed mutator must not bump lastMutationId\"\n );\n });\n\n/** 5. Authoritative writes change row versions. */\nconst rule5VersionBump: Rule = ({ backend, context, rows, start, check, expectOk, put }) =>\n Effect.gen(function* () {\n const rule = \"changes the row version on every authoritative write\";\n const [before] = yield* expectOk(rule, backend.getRows(context, rows, [\"a\"]));\n yield* expectOk(rule, backend.applyMutations(context, [put(start + 3, rows, \"a\", { n: 3 })]));\n const [after] = yield* expectOk(rule, backend.getRows(context, rows, [\"a\"]));\n yield* check(\n rule,\n before !== undefined && after !== undefined && before.version !== after.version,\n `Rewriting row \"a\" must change its version (was ${before?.version}, now ${after?.version})`\n );\n });\n\n/**\n * `evaluate` must return exactly the ids `Subset.apply` returns over\n * `reference`, order included. Returns the expected ids so a caller can\n * page on from them; `describe` renders the violation from both id lists.\n */\nconst expectEvaluation = (\n { backend, context, check, expectOk }: Harness,\n rule: string,\n reference: ReadonlyArray<Subset.Row>,\n subset: Subset.Subset,\n describe: (expected: ReadonlyArray<string>, evaluated: ReadonlyArray<string>) => string\n) =>\n Effect.gen(function* () {\n const expected = Subset.apply(reference, subset).map((row) => row.id);\n const evaluated = (yield* expectOk(rule, backend.evaluate(context, subset))).map(\n (entry) => entry.id\n );\n yield* check(\n rule,\n JSON.stringify(evaluated) === JSON.stringify(expected),\n describe(expected, evaluated)\n );\n return expected;\n });\n\n/** The five hand-picked rows rule 6 starts from, in insertion order. */\nconst evalSeed: ReadonlyArray<readonly [string, EvalRow]> = [\n [\"e1\", { rank: 10, tag: \"keep\" }],\n [\"e2\", { rank: 40, tag: \"keep\" }],\n [\"e3\", { rank: 20, tag: \"drop\" }],\n [\"e4\", { rank: 30, tag: \"keep\" }],\n [\"e5\", { rank: 50, tag: \"keep\" }],\n];\n\n/**\n * The generated corpus rules 6 and 14 share (issue #153): two columns, NULL\n * and astral values on, from the fixed seed, so every run sees the same rows,\n * predicates and order terms.\n */\nconst contractCorpus = Effect.suspend(() => {\n const columns: ReadonlyArray<FilterCorpus.Column> = [\n { name: \"rank\", kind: \"integer\" },\n { name: \"tag\", kind: \"text\" },\n ];\n const options: FilterCorpus.CorpusOptions = { nulls: true, astral: true };\n return FilterCorpus.generateCorpus({\n seed: FilterCorpus.DEFAULT_SEED,\n columns,\n // The guaranteed pool sweep plus a handful of random rows.\n rows: FilterCorpus.minimumRows(columns, options) + 10,\n predicates: 40,\n orderBys: 40,\n ...options,\n });\n});\n\n/** The corpus's subsets over the evaluation collection: one per predicate, some with a limit. */\nconst corpusSubsets = (\n h: Harness,\n corpus: Effect.Success<typeof contractCorpus>\n): ReadonlyArray<Subset.Subset> =>\n corpus.predicates.map((where, index) =>\n Subset.make({\n collection: h.evalRows,\n where,\n orderBy: corpus.orderBys[index % corpus.orderBys.length],\n ...(index % 3 === 0 ? { limit: 1 + (index % 7) } : {}),\n })\n );\n\n/**\n * The generated half of rule 6: a small corpus (issue #153) over the same two\n * columns, so every backend inherits the check for every operator in the\n * core: `evaluate` must return exactly what `Subset.apply` returns over the\n * same rows, order included, for random predicates, order terms, and\n * limits. NULL/absent values and astral text are on: ADR-0028 makes\n * Postgres normative for both and the JS evaluator is exact there (#155),\n * so a backend whose storage treats NULL two-valued, orders NULL first\n * ascending, or compares text by UTF-16 code unit fails here by design.\n * String order is code-point order (ADR-0028 rule (c)): the `tag` pool\n * mixes case and accents, so a backend whose text column carries a locale\n * collation fails too — the contract requires `COLLATE \"C\"` (Postgres) or\n * `BINARY` (SQLite).\n */\nconst generatedCorpus = (\n h: Harness,\n rule: string,\n reference: ReadonlyArray<Subset.Row>,\n nextMutationId: number\n) =>\n Effect.gen(function* () {\n const corpus = yield* contractCorpus;\n const corpusRows = corpus.rows.map((row) => ({ id: `c-${row.id}`, value: row.value }));\n yield* h.expectOk(\n rule,\n h.backend.applyMutations(\n h.context,\n corpusRows.map((row, index) => h.put(nextMutationId + index, h.evalRows, row.id, row.value))\n )\n );\n const all = [...reference, ...corpusRows];\n yield* Effect.forEach(\n corpusSubsets(h, corpus),\n (subset, index) =>\n expectEvaluation(h, rule, all, subset, (expected, evaluated) =>\n FilterCorpus.formatDisagreement({\n seed: corpus.seed,\n subject: `generated subset ${index}${subset.limit !== undefined ? ` (limit ${subset.limit})` : \"\"}`,\n predicate: subset.where,\n orderBy: subset.orderBy,\n rows: all,\n results: { \"Subset.apply\": expected, \"backend.evaluate\": evaluated },\n reproduce: \"the contract corpus uses FilterCorpus.DEFAULT_SEED, not the environment\",\n })\n ),\n { concurrency: 1, discard: true }\n );\n });\n\n/** 6. Evaluate matches the reference subset semantics (Subset.apply). */\nconst rule6ReferenceSemantics: Rule = (h) =>\n Effect.gen(function* () {\n const rule = \"evaluates subsets with the reference semantics (Subset.apply)\";\n yield* h.expectOk(\n rule,\n h.backend.applyMutations(\n h.context,\n evalSeed.map(([id, value], index) => h.put(h.start + 4 + index, h.evalRows, id, value))\n )\n );\n const reference = evalSeed.map(([id, value]) => ({ id, value }));\n\n const limited = Subset.make({\n collection: h.evalRows,\n where: Predicate.eq(\"tag\", \"keep\"),\n orderBy: [{ field: \"rank\", direction: \"desc\" }],\n limit: 2,\n });\n const expectedLimited = yield* expectEvaluation(\n h,\n rule,\n reference,\n limited,\n (expected, evaluated) =>\n `where+orderBy+limit: expected ${JSON.stringify(expected)}, got ${JSON.stringify(evaluated)}`\n );\n\n const paged = Subset.make({\n collection: h.evalRows,\n where: Predicate.eq(\"tag\", \"keep\"),\n orderBy: [{ field: \"rank\", direction: \"desc\" }],\n limit: 2,\n cursor: expectedLimited[expectedLimited.length - 1],\n });\n yield* expectEvaluation(\n h,\n rule,\n reference,\n paged,\n (expected, evaluated) =>\n `cursor page: expected ${JSON.stringify(expected)}, got ${JSON.stringify(evaluated)}`\n );\n\n yield* generatedCorpus(h, rule, reference, h.start + 4 + evalSeed.length);\n });\n\n/** 7. getRows omits missing ids. */\nconst rule7OmitsMissingIds: Rule = ({ backend, context, rows, check, expectOk }) =>\n Effect.gen(function* () {\n const rule = \"omits missing ids from getRows\";\n const fetched = yield* expectOk(rule, backend.getRows(context, rows, [\"a\", \"does-not-exist\"]));\n yield* check(\n rule,\n fetched.length === 1 && fetched[0]?.id === \"a\",\n `Expected exactly row \"a\", got ${JSON.stringify(fetched.map((row) => row.id))}`\n );\n });\n\n/** 8. Client groups are isolated. */\nconst rule8ClientGroupIsolation: Rule = ({ backend, context, clientId, check, expectOk }) =>\n Effect.gen(function* () {\n const rule = \"isolates lastMutationIds between client groups\";\n const other: SyncContext = { clientGroupId: `${context.clientGroupId}-other` };\n const ids = yield* expectOk(rule, backend.lastMutationIds(other));\n yield* check(\n rule,\n (ids[clientId] ?? 0) === 0,\n `A fresh client group must not see another group's mutation ids (got ${ids[clientId]})`\n );\n });\n\n/**\n * 9. Permanent rejection: the poison mutation is acknowledged (its id\n * bumped) with no effects, and the mutation queued behind it applies.\n */\nconst rule9PermanentRejection: Rule = (h) =>\n Effect.gen(function* () {\n const { backend, context, clientId, rows, check, expectOk } = h;\n const rule = \"acknowledges a permanent rejection without effects and applies those behind it\";\n const startId = yield* h.lastIdOf(rule);\n const result = yield* expectOk(\n rule,\n backend.applyMutations(context, [\n h.reject(startId + 1, rows, \"poison\"),\n h.put(startId + 2, rows, \"behind\", { n: 1 }),\n ])\n );\n yield* check(\n rule,\n result.lastMutationIds[clientId] === startId + 2,\n `A rejection must still bump lastMutationId (expected ${startId + 2}, got ${result.lastMutationIds[clientId]})`\n );\n yield* check(\n rule,\n (result.rejected ?? []).some(\n (entry) => entry.clientId === clientId && entry.mutationId === startId + 1\n ),\n \"The rejected mutation must appear in the result's `rejected` list\"\n );\n const poison = yield* expectOk(rule, backend.getRows(context, rows, [\"poison\"]));\n yield* check(\n rule,\n Arr.isReadonlyArrayEmpty(poison),\n \"A rejected mutation must leave no effects (its staged write must roll back)\"\n );\n const behind = yield* expectOk(rule, backend.getRows(context, rows, [\"behind\"]));\n yield* check(\n rule,\n behind.length === 1,\n \"A mutation queued behind a rejected one must still apply in the same push\"\n );\n });\n\n/**\n * 10. Transient failure after a write: the failed mutator's write is discarded\n * (the row keeps its value and version, and a new row is not created) and\n * the id is not bumped, so the client's retry applies the mutation again.\n */\nconst rule10WriteThenFail: Rule = (h) =>\n Effect.gen(function* () {\n const { backend, context, rows, check, expectOk } = h;\n const rule = \"discards a transiently failed mutation's writes and does not bump\";\n const startId = yield* h.lastIdOf(rule);\n const [before] = yield* expectOk(rule, backend.getRows(context, rows, [\"a\"]));\n yield* check(rule, before !== undefined, 'Row \"a\" must exist before the probe');\n\n const attempt = (id: string) =>\n backend.applyMutations(context, [\n h.mutation(startId + 1, writeThenFail.name, { collection: rows, id }),\n ]);\n\n // An unregistered mutator is also a BackendError, which would let an\n // unregistered backend pass this rule vacuously: expectRegisteredFailure\n // reports that case as a missing registration.\n yield* h.expectRegisteredFailure(rule, attempt(\"a\"), writeThenFail.name, \"writeThenFail\");\n\n const [after] = yield* expectOk(rule, backend.getRows(context, rows, [\"a\"]));\n yield* check(\n rule,\n after?.version === before?.version &&\n JSON.stringify(after?.value) === JSON.stringify(before?.value),\n `A failed write must leave row \"a\" unchanged (was ${JSON.stringify(before?.value)} at version ${before?.version}, now ${JSON.stringify(after?.value)} at version ${after?.version})`\n );\n\n yield* Effect.exit(attempt(\"ghost\"));\n const ghost = yield* expectOk(rule, backend.getRows(context, rows, [\"ghost\"]));\n yield* check(rule, Arr.isReadonlyArrayEmpty(ghost), \"A failed write must not create a row\");\n\n yield* check(\n rule,\n (yield* h.lastIdOf(rule)) === startId,\n \"A failed write must not bump lastMutationId\"\n );\n });\n\n/** How many times a transient `BackendError` is retried, as the client's own retry would. */\nconst TRANSIENT_RETRIES = 3;\n\n/**\n * Scheduler turns the rule gives the peer to commit while the parked handler\n * waits, when the backend supplies no `awaitPeer`. A backend that runs the peer\n * at once commits it within a few turns. One that serialises it behind the parked\n * call (SQLite's writer lock, a server lock) keeps it waiting, and the rule then\n * releases the handler anyway. Counted in turns, not time, so the rule never reads\n * the wall clock. On PostgreSQL the peer's statements are real I/O, so this turn\n * count does not reach the overlap: that backend observes the peer through\n * `awaitPeer` instead (#416).\n */\nconst PEER_TURNS = 1000;\n\n/** The rule's own gate names are unique per run, so two verifications in one process cannot collide. */\nlet gateRuns = 0;\n\n/** The gate name for a mutation that parks at nothing: no registered gate has this name. */\nconst NO_GATE = \"\";\n\nconst retryTransient = <A>(effect: Effect.Effect<A, BackendError>) =>\n effect.pipe(\n Effect.retry({ times: TRANSIENT_RETRIES, while: (error) => error._tag === \"BackendError\" })\n );\n\n/** Runs the scheduler until `peerSettled` reads true, or `PEER_TURNS` turns have passed. */\nconst settleByTurns = (peerSettled: Effect.Effect<boolean>): Effect.Effect<void> => {\n // Each turn checks first, then yields, until settled or out of turns.\n const turn = (left: number): Effect.Effect<void> =>\n left <= 0\n ? Effect.void\n : Effect.flatMap(peerSettled, (settled) =>\n settled ? Effect.void : Effect.andThen(Effect.yieldNow, turn(left - 1))\n );\n return turn(PEER_TURNS);\n};\n\n/**\n * 11. Serialisable across client groups (guarantee 1, #353). Group X reads a\n * counter and parks after the read. Group Y increments the same counter and\n * commits while X is parked. Then X resumes and increments. Both increments\n * must land, so the counter reads 2. A backend whose handler read is not\n * validated at commit writes X's stale count over Y's and reads 1. A backend\n * that serialises the two (a lock, or serialisable isolation) either orders\n * them or refuses one with a transient `BackendError`, which the harness\n * retries. Y waits behind X on a backend that serialises by lock, so the rule\n * releases X once the peer has settled, or blocked on X's lock, and does not\n * deadlock. That wait is the backend's `awaitPeer`, or `PEER_TURNS` turns when\n * it supplies none. A PostgreSQL run needs `awaitPeer` to reach the overlap at\n * all (#416). D1 does not meet guarantee 1 (#342): it has no transaction to\n * isolate the read from another group's commit, so it is not run through this\n * contract, and this rule does not claim it.\n */\nconst rule11CrossGroupLostUpdate: Rule = (h) =>\n Effect.gen(function* () {\n const rule =\n \"keeps a read-modify-write across client groups from losing an update (guarantee 1)\";\n const startId = yield* h.lastIdOf(rule);\n const row = \"race\";\n yield* h.expectOk(\n rule,\n h.backend.applyMutations(h.context, [h.put(startId + 1, h.rows, row, { n: 0 })])\n );\n\n // The peer group has its own ledger. A restarted run expects the one it left (#477, #483), and\n // the check runs before the gate is registered, so a failure leaves no parked handler behind.\n const peer: SyncContext = { clientGroupId: `${h.context.clientGroupId}-peer` };\n const peerLedger = (yield* h.expectOk(rule, h.backend.lastMutationIds(peer)))[h.clientId] ?? 0;\n yield* h.check(\n rule,\n peerLedger === h.peerStart,\n ledgerMismatch(\"peer group\", h.clientId, h.peerStart, peerLedger)\n );\n\n gateRuns += 1;\n const gate = `${h.context.clientGroupId}/race-${gateRuns}`;\n const parked: ParkGate = {\n entered: yield* Deferred.make<void>(),\n release: yield* Deferred.make<void>(),\n };\n parkGates.set(gate, parked);\n const increment = (mutationId: number, gateName: string) =>\n h.mutation(mutationId, countUp.name, { collection: h.rows, id: row, gate: gateName });\n\n const run = Effect.gen(function* () {\n const first = yield* Effect.forkChild(\n retryTransient(h.backend.applyMutations(h.context, [increment(startId + 2, gate)]))\n );\n // Either X has parked after its read, or X finished without parking.\n const firstEarly = yield* Effect.raceFirst(\n Deferred.await(parked.entered).pipe(Effect.as(undefined)),\n Effect.exit(Fiber.join(first))\n );\n if (firstEarly !== undefined) {\n const failure = Exit.findErrorOption(firstEarly);\n if (Option.isSome(failure) && isUnregisteredFailure(failure.value, countUp.name)) {\n return yield* h.check(\n rule,\n false,\n `${countUp.name} is not registered: register BackendContract.countUp`\n );\n }\n return yield* h.check(\n rule,\n false,\n Option.isSome(failure)\n ? `Backend failed unexpectedly: ${failure.value.message}`\n : `${countUp.name} finished without reaching park(): its handler must call BackendContract.park between its read and its write`\n );\n }\n\n const peerDone = yield* Deferred.make<void>();\n const second = yield* Effect.forkChild(\n retryTransient(h.backend.applyMutations(peer, [increment(h.peerStart + 1, NO_GATE)])).pipe(\n Effect.ensuring(Deferred.succeed(peerDone, undefined))\n )\n );\n const peerSettled = Deferred.isDone(peerDone);\n yield* (h.awaitPeer ?? settleByTurns)(peerSettled);\n yield* Deferred.succeed(parked.release, undefined);\n const firstExit = yield* Effect.exit(Fiber.join(first));\n const peerExit = yield* Effect.exit(Fiber.join(second));\n const failed = Arr.findFirst(\n [\n [\"first\", firstExit],\n [\"peer\", peerExit],\n ] as const,\n ([label, exit]) => Option.map(Exit.findErrorOption(exit), (error) => ({ label, error }))\n );\n if (Option.isSome(failed)) {\n return yield* h.check(\n rule,\n false,\n `The ${failed.value.label} increment failed: ${failed.value.error.message}`\n );\n }\n\n const [stored] = yield* h.expectOk(rule, h.backend.getRows(h.context, h.rows, [row]));\n const count = (stored?.value as { readonly n?: number } | undefined)?.n;\n yield* h.check(\n rule,\n count === 2,\n `Two increments of \"${row}\" from two client groups must leave it at 2, got ${count}: a committed write was lost to the other group's concurrent commit`\n );\n });\n\n yield* run.pipe(\n Effect.ensuring(\n Effect.sync(() => parkGates.delete(gate)).pipe(\n Effect.andThen(Deferred.succeed(parked.release, undefined))\n )\n )\n );\n });\n\n/**\n * 12. Own writes reach getRows (#444). A listing (`evaluate`) may cache a row, and a\n * later write of that row through the same backend must show in `getRows` with no\n * re-list: an update reads back the post-write value, and a delete makes `getRows`\n * omit the row. A backend that caches listed rows and does not bring its cache into\n * line with its own writes passes rules 1 to 11 and fails here.\n */\nconst rule12OwnWritesReachGetRows: Rule = (h) =>\n Effect.gen(function* () {\n const { backend, context, check, expectOk, put } = h;\n const rule = \"getRows reflects this backend's own writes to rows a listing has cached\";\n const collection = h.evalRows;\n const kept = \"cached-kept\";\n const gone = \"cached-gone\";\n const startId = yield* h.lastIdOf(rule);\n yield* expectOk(\n rule,\n backend.applyMutations(context, [\n put(startId + 1, collection, kept, { n: 1 }),\n put(startId + 2, collection, gone, { n: 1 }),\n ])\n );\n const listed = (yield* expectOk(\n rule,\n backend.evaluate(context, Subset.make({ collection }))\n )).map((entry) => entry.id);\n yield* check(\n rule,\n listed.includes(kept) && listed.includes(gone),\n `The listing must return both seeded rows so the backend can cache them, got ${JSON.stringify(listed)}`\n );\n\n yield* expectOk(\n rule,\n backend.applyMutations(context, [put(startId + 3, collection, kept, { n: 2 })])\n );\n const [updated] = yield* expectOk(rule, backend.getRows(context, collection, [kept]));\n yield* check(\n rule,\n (updated?.value as { readonly n?: number } | undefined)?.n === 2,\n `An update must show in getRows without a re-list: row \"${kept}\" reads ${JSON.stringify(updated?.value)}`\n );\n\n yield* expectOk(\n rule,\n backend.applyMutations(context, [\n h.mutation(startId + 4, delRow.name, { collection, id: gone }),\n ])\n );\n const removed = yield* expectOk(rule, backend.getRows(context, collection, [gone]));\n yield* check(\n rule,\n Arr.isReadonlyArrayEmpty(removed),\n `A delete must make getRows omit the row without a re-list: row \"${gone}\" still reads ${JSON.stringify(removed[0]?.value)}`\n );\n });\n\n/**\n * 13. Rejection memory: a permanent rejection is listed by `rejections`, with\n * the reason `applyMutations` reported for it, so a pull whose watermark\n * covers it can report it (#365). A client whose push response was lost\n * learns the outcome from that list.\n */\nconst rule13ListsRejections: Rule = (h) =>\n Effect.gen(function* () {\n const { backend, context, clientId, rows, check, expectOk } = h;\n const rule =\n \"lists a permanent rejection, with the reason applyMutations reported, in rejections\";\n const startId = yield* h.lastIdOf(rule);\n const result = yield* expectOk(\n rule,\n backend.applyMutations(context, [h.reject(startId + 1, rows, \"listed\")])\n );\n const reported = (result.rejected ?? []).find(\n (entry) => entry.clientId === clientId && entry.mutationId === startId + 1\n );\n yield* check(\n rule,\n reported !== undefined,\n \"The rejected mutation must appear in the result's `rejected` list\"\n );\n const listed = yield* expectOk(rule, backend.rejections(context));\n yield* check(\n rule,\n listed.some(\n (entry) =>\n entry.clientId === clientId &&\n entry.mutationId === startId + 1 &&\n entry.reason === reported?.reason\n ),\n `A permanent rejection must be listed by rejections with the reason applyMutations reported (${JSON.stringify(reported?.reason)}), got ${JSON.stringify(listed)}`\n );\n });\n\n/**\n * 14. `evaluateMany`, when the backend provides it (#505), equals per-subset\n * `evaluate`: for rule 6's subsets over its rows (the hand-picked windows\n * and the generated corpus) plus whole-collection subsets of both contract\n * collections, asked in one call, each list holds the same entries, ids\n * and versions, in the same order, as `evaluate` gives that subset. Asking\n * for no subsets gives no lists. A backend without `evaluateMany` passes\n * vacuously: a pull falls back to `evaluate`.\n */\n/** Whether two entry lists hold the same ids and versions in the same order. */\nconst sameEntries = (\n left: ReadonlyArray<SubsetEntry>,\n right: ReadonlyArray<SubsetEntry>\n): boolean =>\n left.length === right.length &&\n left.every(\n (entry, index) => entry.id === right[index]?.id && entry.version === right[index]?.version\n );\n\n/** An entry list for a violation message: `id@version`, comma-separated. */\nconst describeEntries = (entries: ReadonlyArray<SubsetEntry>): string =>\n entries.map((entry) => `${entry.id}@${entry.version}`).join(\", \");\n\nconst rule14EvaluateManyEquivalence: Rule = (h) =>\n Effect.gen(function* () {\n const many = h.backend.evaluateMany;\n if (many === undefined) return;\n const rule = \"evaluateMany equals per-subset evaluate\";\n const corpus = yield* contractCorpus;\n const keep = Predicate.eq(\"tag\", \"keep\");\n const byRank = [{ field: \"rank\", direction: \"desc\" as const }];\n const subsets: ReadonlyArray<Subset.Subset> = [\n Subset.make({ collection: h.evalRows }),\n Subset.make({ collection: h.rows }),\n Subset.make({ collection: h.evalRows, where: keep, orderBy: byRank, limit: 2 }),\n Subset.make({ collection: h.evalRows, where: keep, orderBy: byRank, limit: 2, cursor: \"e5\" }),\n ...corpusSubsets(h, corpus),\n ];\n const batched = yield* h.expectOk(rule, many(h.context, subsets));\n yield* h.check(\n rule,\n batched.length === subsets.length,\n `Expected ${subsets.length} entry lists, one per subset, got ${batched.length}`\n );\n yield* Effect.forEach(\n subsets,\n (subset, index) =>\n Effect.gen(function* () {\n const single = yield* h.expectOk(rule, h.backend.evaluate(h.context, subset));\n const together = batched[index] ?? [];\n yield* h.check(\n rule,\n sameEntries(together, single),\n `Subset ${index} over \"${subset.collection}\": evaluate gave [${describeEntries(single)}], evaluateMany gave [${describeEntries(together)}]`\n );\n }),\n { concurrency: 1, discard: true }\n );\n const none = yield* h.expectOk(rule, many(h.context, []));\n yield* h.check(\n rule,\n Arr.isReadonlyArrayEmpty(none),\n `Asked for no subsets, evaluateMany gave ${none.length} lists`\n );\n });\n\n/** The contract, in the order the rules build on one another's state. */\nconst rules: ReadonlyArray<Rule> = [\n rule1InOrderApplication,\n rule2IdempotentSkip,\n rule3GapRejection,\n rule4AtomicBump,\n rule5VersionBump,\n rule6ReferenceSemantics,\n rule7OmitsMissingIds,\n rule8ClientGroupIsolation,\n rule9PermanentRejection,\n rule10WriteThenFail,\n rule11CrossGroupLostUpdate,\n rule12OwnWritesReachGetRows,\n rule13ListsRejections,\n rule14EvaluateManyEquivalence,\n];\n\n// ─── Verification ────────────────────────────────────────────────────────────\n\n/**\n * Verify a backend against the contract. The backend must have the contract\n * mutators registered and the contract collections empty. On a fresh client group\n * the contract expects the backend to report a ledger of 0 for its client. A run\n * over a restarted backend passes the ledger it expects as `restoredLedger`: the\n * contract first checks the backend reports exactly that, failing a backend that\n * forgot its ledger, and then numbers its mutations from it (#483).\n */\nexport const verifyBackendContract = (\n backend: Backend,\n options?: VerifyOptions\n): Effect.Effect<void, ContractViolation> => {\n const context: SyncContext = { clientGroupId: options?.clientGroupId ?? \"__contract-group\" };\n const expected = options?.restoredLedger ?? 0;\n return backend.lastMutationIds(context).pipe(\n Effect.mapError(\n (error) =>\n new ContractViolation({\n rule: restoredLedgerRule,\n message: `Backend failed unexpectedly: ${error.message}`,\n })\n ),\n Effect.flatMap((ids) => {\n const reported = ids[CONTRACT_CLIENT] ?? 0;\n if (reported !== expected) {\n return Effect.fail(\n new ContractViolation({\n rule: restoredLedgerRule,\n message: ledgerMismatch(\"contract group\", CONTRACT_CLIENT, expected, reported),\n })\n );\n }\n const harness = makeHarness(backend, options, expected, options?.restoredPeerLedger ?? 0);\n return Effect.forEach(rules, (rule) => rule(harness), { discard: true });\n })\n );\n};\n","/**\n * InvalidationSink\n *\n * Turn committed writes into evictions of server-side caches (#206). A\n * {@link InvalidationSink} is told what each hint batch on the\n * {@link InvalidationBus} touched, the collections and the row ids, and evicts\n * whatever it caches for them: a KV read-through cache, the edge HTTP cache's\n * tags. {@link run} subscribes a sink to the bus, so eviction stops being an\n * obligation of each mutation's call site.\n *\n * Eviction is best-effort, like the bus itself (ADR-0009): a sink logs a\n * failure and never surfaces it, and it runs on its own fibre, so it can\n * neither fail nor delay the write that published the hint. A cache's TTL is\n * the backstop for an eviction that is lost.\n *\n * The tag spelling is `HttpCache`'s convention (`collection:{name}`,\n * `collection:{name}:{id}`), shared with the browser's Cache API invalidation.\n * Runtime sinks live in their runtime's package: Cloudflare KV and\n * `cache.purge` in `@thomasfosterau/legation-alchemy-cloudflare` (`EdgeInvalidation`).\n */\n\nimport * as Arr from \"effect/Array\";\nimport * as Effect from \"effect/Effect\";\nimport type * as Scope from \"effect/Scope\";\nimport type { ChangeHint } from \"./Backend.js\";\nimport type { Touched } from \"./HttpCache.js\";\nimport { InvalidationBus } from \"./InvalidationBus.js\";\n\n/**\n * A server-side cache that evicts what a change touched (#206). `invalidate`\n * never fails: an implementation logs its own failures, since a lost eviction\n * only leaves an entry until its TTL.\n */\nexport interface InvalidationSink {\n readonly invalidate: (touched: Touched) => Effect.Effect<void>;\n}\n\n/** What a hint batch touched: its collections, and every row id it names (puts and deletes). */\nexport const touchedBy = (hints: ReadonlyArray<ChangeHint>): Touched => ({\n collections: Arr.dedupe(hints.map((hint) => hint.collection)),\n rows: hints.flatMap((hint) => hint.ids.map((id) => ({ collection: hint.collection, id }))),\n});\n\n/** Whether a change touched nothing. */\nconst isEmpty = (touched: Touched): boolean =>\n Arr.isReadonlyArrayEmpty(touched.collections) && Arr.isReadonlyArrayEmpty(touched.rows);\n\n/**\n * One sink over several, run concurrently: a KV cache and the edge cache\n * evicted from the same hint. A defect in one is logged and does not stop the\n * others.\n */\nexport const all = (sinks: ReadonlyArray<InvalidationSink>): InvalidationSink => ({\n invalidate: (touched) =>\n Effect.forEach(sinks, (sink) => guarded(sink, touched), {\n concurrency: \"unbounded\",\n discard: true,\n }),\n});\n\n/** Run one sink's eviction, logging rather than propagating a defect it did not catch. */\nconst guarded = (sink: InvalidationSink, touched: Touched): Effect.Effect<void> =>\n sink\n .invalidate(touched)\n .pipe(\n Effect.catchCause((cause) =>\n Effect.logWarning(\n \"InvalidationSink: an eviction failed; the cache TTL is the backstop\",\n cause\n )\n )\n );\n\n/**\n * Subscribe `sink` to the bus for the scope's lifetime: each hint batch's\n * touched collections and rows are passed to it, on a fibre of its own. Run it\n * where the bus is, in the process that commits the writes. A sink that has to\n * reach a cache in another process forwards there (Cloudflare:\n * `EdgeInvalidation.forward` over a service binding).\n */\nexport const run = (\n sink: InvalidationSink\n): Effect.Effect<void, never, InvalidationBus | Scope.Scope> =>\n Effect.gen(function* () {\n const bus = yield* InvalidationBus;\n const subscription = yield* bus.subscribe;\n yield* Effect.forkScoped(\n Effect.forever(\n subscription.take.pipe(\n Effect.flatMap((hints) => {\n const touched = touchedBy(hints);\n return isEmpty(touched) ? Effect.void : guarded(sink, touched);\n })\n )\n )\n );\n });\n","/**\n * PushPoke\n *\n * Web Push as a poke carrier (#214): the one mechanism that wakes a service\n * worker that is not running, so a client with no open tab converges before\n * the user returns. Under poke-then-pull it is a safe fit. A poke carries no\n * data, so a lost push costs a delay and a duplicate costs one pull that finds\n * nothing: pull is the correctness path (ADR-0008).\n *\n * ## The payload is contentless\n *\n * Every push this module sends is {@link payload}: a fixed marker and nothing\n * else. No topic, no collection name, no row id. A push payload crosses a\n * third-party push service, and a collection name would tell it what a user\n * subscribes to. The pull the poke prompts is the authenticated channel; that\n * is where the data travels.\n *\n * ## The app owns the subscriptions and the credentials\n *\n * {@link sink} takes the app's endpoint registry (which subscriptions a change\n * should wake, {@link SinkOptions.targetsFor}) and the app's sender\n * ({@link SinkOptions.send}, which signs with the app's VAPID keys). The\n * library holds no credential and stores no subscription.\n *\n * ## The budget is the app's stated choice\n *\n * Browsers penalise a push that shows no notification, and push services\n * rate-limit each subscription: an app that wakes a device for every write can\n * lose its push permission. So {@link SinkOptions.coalesce} and\n * {@link SinkOptions.budget} are required, with no default: the silent-push\n * posture is a decision the app writes down, not a guess the library makes.\n * Within the coalescing window a target gets at most one push, plus one more at\n * the window's end if anything else changed meanwhile; past its budget a\n * target gets none until the budget period moves on. A skipped push is logged\n * at debug level: the next pull, or the next page boot, converges anyway.\n *\n * The worker side, which turns a recognised push into a Background Sync\n * registration or a pull, is `PushPoke` in `@thomasfosterau/legation-browser`.\n */\n\nimport * as Arr from \"effect/Array\";\nimport * as Duration from \"effect/Duration\";\nimport * as Effect from \"effect/Effect\";\nimport * as HashMap from \"effect/HashMap\";\nimport * as Option from \"effect/Option\";\nimport * as Ref from \"effect/Ref\";\nimport type * as Scope from \"effect/Scope\";\nimport * as Clock from \"effect/Clock\";\nimport type { Touched } from \"./HttpCache.js\";\nimport type { InvalidationSink } from \"./InvalidationSink.js\";\n\n/**\n * The payload of every push-poke: a fixed marker, so the worker can tell the\n * library's push from the app's own, and nothing about what changed.\n */\nexport const payload = '{\"legation\":\"poke\"}';\n\n/** Whether a push's text is the library's poke ({@link payload}). */\nexport const isPoke = (text: string): boolean => text === payload;\n\n/** How many push-pokes a target may receive per period. */\nexport interface Budget {\n readonly pushes: number;\n readonly per: Duration.Input;\n}\n\n/** Options for {@link sink}. `Target` is the app's own push subscription record. */\nexport interface SinkOptions<Target> {\n /**\n * The push subscriptions a change should wake: the app's endpoint registry,\n * scoped as the app scopes its users' data (a write to a user's rows wakes\n * that user's devices). Failing reads as no targets, logged.\n */\n readonly targetsFor: (touched: Touched) => Effect.Effect<ReadonlyArray<Target>, unknown>;\n /** A stable key per target, for coalescing and the budget: its endpoint URL, say. */\n readonly keyOf: (target: Target) => string;\n /**\n * Send `payload` to `target` through its push service, signed with the\n * app's VAPID keys. A failure is logged, never retried here: the next change\n * pokes again, and pull converges regardless.\n */\n readonly send: (target: Target, payload: string) => Effect.Effect<void, unknown>;\n /** **Required.** At most one push per target per window, plus one trailing push. */\n readonly coalesce: Duration.Input;\n /** **Required.** The most pushes a target receives per period; past it, none. */\n readonly budget: Budget;\n}\n\ninterface TargetState {\n /** When the last push to the target went out. */\n readonly lastSent: number;\n /** Whether a trailing push is scheduled for the end of the window. */\n readonly trailing: boolean;\n /** When each push inside the current budget period went out. */\n readonly sent: ReadonlyArray<number>;\n}\n\nconst emptyState: TargetState = { lastSent: Number.NEGATIVE_INFINITY, trailing: false, sent: [] };\n\n/** What to do with one target's push now. */\ntype Decision = \"send\" | \"trail\" | \"skip\" | \"over-budget\";\n\n/**\n * An `InvalidationSink` that pokes the devices a change should wake, over Web\n * Push, within the app's coalescing window and budget. Run it with\n * `InvalidationSink.run` where the bus is. Its trailing pushes run on fibres\n * of the scope it is built in.\n */\nexport const sink = <Target>(\n options: SinkOptions<Target>\n): Effect.Effect<InvalidationSink, never, Scope.Scope> =>\n Effect.gen(function* () {\n const window = Duration.toMillis(Duration.fromInputUnsafe(options.coalesce));\n const period = Duration.toMillis(Duration.fromInputUnsafe(options.budget.per));\n const limit = Math.max(0, options.budget.pushes);\n const states = yield* Ref.make(HashMap.empty<string, TargetState>());\n const scope = yield* Effect.scope;\n\n const stateOf = (all: HashMap.HashMap<string, TargetState>, key: string): TargetState =>\n Option.getOrElse(HashMap.get(all, key), () => emptyState);\n\n // Record a push to `key` at `now`, if the budget allows it.\n const claim = (key: string, now: number) =>\n Ref.modify(states, (all): readonly [boolean, HashMap.HashMap<string, TargetState>] => {\n const state = stateOf(all, key);\n const sent = state.sent.filter((at) => now - at < period);\n if (sent.length >= limit) return [false, all];\n return [\n true,\n HashMap.set(all, key, { lastSent: now, trailing: false, sent: [...sent, now] }),\n ];\n });\n\n const push = (target: Target, key: string, now: number): Effect.Effect<void> =>\n Effect.flatMap(claim(key, now), (allowed) =>\n allowed\n ? options\n .send(target, payload)\n .pipe(\n Effect.catchCause((cause) =>\n Effect.logWarning(\"PushPoke: a push failed; the next pull converges\", cause)\n )\n )\n : Effect.logDebug(\"PushPoke: a target is over its push budget; skipped\")\n );\n\n // Decide one target's push: send now, schedule the trailing push, or skip.\n const decide = (key: string, now: number) =>\n Ref.modify(states, (all): readonly [Decision, HashMap.HashMap<string, TargetState>] => {\n const state = stateOf(all, key);\n if (now - state.lastSent >= window) return [\"send\", all];\n if (state.trailing) return [\"skip\", all];\n return [\"trail\", HashMap.set(all, key, { ...state, trailing: true })];\n });\n\n const poke = (target: Target): Effect.Effect<void> =>\n Effect.gen(function* () {\n const key = options.keyOf(target);\n const now = yield* Clock.currentTimeMillis;\n const decision = yield* decide(key, now);\n if (decision === \"send\") return yield* push(target, key, now);\n if (decision !== \"trail\") return;\n const state = stateOf(yield* Ref.get(states), key);\n const wait = Math.max(0, state.lastSent + window - now);\n yield* Effect.forkIn(\n Effect.sleep(Duration.millis(wait)).pipe(\n Effect.andThen(Clock.currentTimeMillis),\n Effect.flatMap((at) => push(target, key, at))\n ),\n scope\n );\n });\n\n return {\n invalidate: (touched) =>\n options.targetsFor(touched).pipe(\n Effect.catchCause((cause) =>\n Effect.logWarning(\"PushPoke: the endpoint registry failed; no push sent\", cause).pipe(\n Effect.as(Arr.empty<Target>())\n )\n ),\n Effect.flatMap((targets) =>\n Effect.forEach(\n Arr.dedupeWith(targets, (a, b) => options.keyOf(a) === options.keyOf(b)),\n poke,\n {\n concurrency: \"unbounded\",\n discard: true,\n }\n )\n )\n ),\n };\n });\n","/**\n * FanoutTopics\n *\n * The pure topic algebra of ADR-0023: fan-out is publish/subscribe over\n * **derived topics**, and the fan-out layer never evaluates a predicate.\n * For a node type `C` the topic space is the coarse topic `C` plus fine\n * topics `C/field=value`, allowed only for fields in the node's\n * **derivable set** (its `one`-edge keys + declared `hintKeys`) — declared\n * on the Node, so registration and write-derivation cannot disagree.\n *\n * Soundness by construction: a window registers the finest topic its\n * predicate legally allows (an equality conjunct on a derivable field),\n * and a write emits every derivable-set topic for its **old and new**\n * values — so any write that can affect a fine-registered window emits\n * that window's topic. Over-poking is harmless (pull is the correctness\n * path); under-poking is impossible.\n */\n\nimport * as Arr from \"effect/Array\";\nimport * as P from \"effect/Predicate\";\nimport type * as Node from \"./Node.js\";\nimport type * as Predicate from \"./Predicate.js\";\nimport type * as Subset from \"./Subset.js\";\n\n/** A fan-out topic: `collection` (coarse) or `collection/field=value` (fine). */\nexport type Topic = string;\n\n/** The coarse topic of a collection: every write to it publishes here. */\nexport const coarse = (collection: string): Topic => collection;\n\n/** A fine topic: a graph location (`reviews/productId=p-1` IS that edge). */\nexport const fine = (collection: string, field: string, value: string | number | boolean): Topic =>\n `${collection}/${field}=${String(value)}`;\n\n/** The collection a topic belongs to (both coarse and fine). */\nexport const collectionOf = (topic: Topic): string => {\n const slash = topic.indexOf(\"/\");\n return slash === -1 ? topic : topic.slice(0, slash);\n};\n\n/** The derivable set of every node in a registry, keyed by collection. */\nexport const derivableSets = (\n nodes: Node.NodeRegistry\n): ReadonlyMap<string, ReadonlySet<string>> => {\n const map = new Map<string, ReadonlySet<string>>();\n Arr.forEach(nodes.nodes, ([type, node]) => {\n const fields = new Set<string>(node.hintKeys);\n Arr.forEach(Object.values(node.edges), (edge) => {\n if (edge.kind === \"one\") fields.add(edge.via);\n });\n map.set(type, fields);\n });\n return map;\n};\n\nconst isLiteral = (value: unknown): value is string | number | boolean =>\n P.isString(value) || P.isNumber(value) || P.isBoolean(value);\n\n/** The equality conjuncts of a predicate (a bare Compare or an And of them). */\nconst eqConjuncts = (\n predicate: Predicate.Predicate\n): ReadonlyArray<{ readonly field: string; readonly value: string | number | boolean }> => {\n if (predicate._tag === \"Compare\" && predicate.op === \"eq\" && isLiteral(predicate.value)) {\n return [{ field: predicate.field, value: predicate.value }];\n }\n if (predicate._tag === \"And\") return predicate.predicates.flatMap(eqConjuncts);\n return [];\n};\n\n/**\n * The finest topic a window's predicate legally allows: an equality\n * conjunct on a derivable field → that fine topic (every row in the\n * window carries the value, so every affecting write derives it);\n * anything else → the coarse topic.\n */\nexport const topicForSubset = (\n subset: Subset.Subset,\n derivable: ReadonlySet<string> | undefined\n): Topic => {\n const conjunct =\n derivable === undefined\n ? undefined\n : eqConjuncts(subset.where).find((candidate) => derivable.has(candidate.field));\n return conjunct === undefined\n ? coarse(subset.collection)\n : fine(subset.collection, conjunct.field, conjunct.value);\n};\n\n/**\n * The topics one written row derives: the coarse topic plus a fine topic\n * per derivable field of its **old and new** values — an update that moves\n * a row between parents pokes both edge windows; a delete derives from the\n * old row; a value-less write degrades to coarse alone.\n */\nexport const topicsForWrite = (\n collection: string,\n derivable: ReadonlySet<string> | undefined,\n values: { readonly oldValue?: unknown; readonly newValue?: unknown }\n): ReadonlySet<Topic> => {\n const topics = new Set<Topic>([coarse(collection)]);\n if (derivable === undefined) return topics;\n Arr.forEach([values.oldValue, values.newValue], (value) => {\n if (!P.isObjectOrArray(value)) return;\n Arr.forEach(derivable, (field) => {\n const fieldValue = (value as Record<string, unknown>)[field];\n if (isLiteral(fieldValue)) topics.add(fine(collection, field, fieldValue));\n });\n });\n return topics;\n};\n","/**\n * FanoutBroker\n *\n * ADR-0023's shard seam: topic pub/sub with **leased** registrations.\n * Rooms register the topic set their windows compile to and renew on a\n * heartbeat; shards drop expired entries, so crashed rooms age out with no\n * distributed cleanup. `publish` routes a write's derived topics to every\n * room whose live lease intersects them — the fan-out layer never\n * evaluates a predicate.\n *\n * The in-process implementation is the single-process reference (and the\n * semantics a Durable Object or Redis shard must match). A poke here is a\n * batch of matched topics; a dropped poke only delays the next interval\n * pull, never prevents convergence.\n */\n\nimport * as Arr from \"effect/Array\";\nimport * as Clock from \"effect/Clock\";\nimport * as Context from \"effect/Context\";\nimport * as Duration from \"effect/Duration\";\nimport * as Effect from \"effect/Effect\";\nimport * as PubSub from \"effect/PubSub\";\nimport * as Ref from \"effect/Ref\";\nimport * as Scope from \"effect/Scope\";\nimport type { Topic } from \"./FanoutTopics.js\";\n\n/** A live subscription to a room's topic pokes. */\nexport interface TopicPokes {\n /** The next batch of matched topics; suspends until one arrives. */\n readonly take: Effect.Effect<ReadonlyArray<Topic>>;\n}\n\n/**\n * Topic pub/sub with leased registrations: rooms lease the topics their windows compile to, and\n * `publish` pokes every room whose live lease intersects a write's topics.\n */\nexport interface FanoutBroker {\n /**\n * Lease (or replace) a room's topic registrations. The lease expires\n * after `ttl` unless re-registered — registration is idempotent, so the\n * heartbeat IS re-registration.\n */\n readonly register: (\n roomId: string,\n topics: ReadonlySet<Topic>,\n ttl: Duration.Input\n ) => Effect.Effect<void>;\n /** Route derived topics to every room whose live lease intersects them. */\n readonly publish: (topics: Iterable<Topic>) => Effect.Effect<void>;\n /** A room's poke feed. Established once the effect completes. */\n readonly pokes: (roomId: string) => Effect.Effect<TopicPokes, never, Scope.Scope>;\n}\n\n/**\n * The {@link FanoutBroker} service tag, for apps that provide a broker by layer;\n * `FanoutBus.make` takes it as an option.\n */\nexport const FanoutBroker = Context.Service<FanoutBroker>(\"@thomasfosterau/legation/FanoutBroker\");\n\ninterface Lease {\n readonly topics: ReadonlySet<Topic>;\n readonly expiresAt: number;\n}\n\nconst POKE_CAPACITY = 256;\n\n/** The in-process broker: leases in a Ref, one dropping hub per room. */\nexport const makeInProcess: Effect.Effect<FanoutBroker, never, Scope.Scope> = Effect.gen(\n function* () {\n const leases = yield* Ref.make(new Map<string, Lease>());\n const hubs = yield* Ref.make(new Map<string, PubSub.PubSub<ReadonlyArray<Topic>>>());\n const scope = yield* Effect.scope;\n\n const hubFor = (roomId: string) =>\n Effect.gen(function* () {\n const existing = (yield* Ref.get(hubs)).get(roomId);\n if (existing !== undefined) return existing;\n const hub = yield* PubSub.dropping<ReadonlyArray<Topic>>({ capacity: POKE_CAPACITY });\n yield* Scope.addFinalizer(scope, PubSub.shutdown(hub));\n yield* Ref.update(hubs, (map) => new Map(map).set(roomId, hub));\n return hub;\n });\n\n return {\n register: (roomId, topics, ttl) =>\n Effect.gen(function* () {\n const now = yield* Clock.currentTimeMillis;\n yield* Ref.update(leases, (map) =>\n new Map(map).set(roomId, { topics, expiresAt: now + Duration.toMillis(ttl) })\n );\n }),\n publish: (topics) =>\n Effect.gen(function* () {\n const wanted = new Set(topics);\n const now = yield* Clock.currentTimeMillis;\n // Lazy lease sweep: expired rooms drop out as publishes pass by.\n const live = new Map<string, Lease>();\n Arr.forEach(yield* Ref.get(leases), ([roomId, lease]) => {\n if (lease.expiresAt > now) live.set(roomId, lease);\n });\n yield* Ref.set(leases, live);\n const hubMap = yield* Ref.get(hubs);\n yield* Effect.forEach(\n live,\n ([roomId, lease]) =>\n Effect.gen(function* () {\n const matched = [...wanted].filter((topic) => lease.topics.has(topic));\n if (Arr.isReadonlyArrayEmpty(matched)) return;\n const hub = hubMap.get(roomId);\n if (hub !== undefined) yield* PubSub.publish(hub, matched);\n }),\n { concurrency: 1, discard: true }\n );\n }),\n pokes: (roomId) =>\n Effect.gen(function* () {\n const hub = yield* hubFor(roomId);\n const subscription = yield* PubSub.subscribe(hub);\n return { take: PubSub.take(subscription) };\n }),\n };\n }\n);\n","/**\n * FanoutBus\n *\n * An {@link InvalidationBus} over a {@link FanoutBroker} — the piece that\n * makes ADR-0023's topic routing a drop-in: `Server.make({ bus })` accepts\n * it unchanged, and the room deployment gets topic-precise cross-room\n * fan-out instead of a flat channel.\n *\n * Publishing derives each hint's topics (coarse always; fine per derivable\n * field of the old and new values) and hands them to the broker. The\n * subscription side surfaces the broker's topic pokes as collection-level\n * hints — within a room the group count is small (typically one user), so\n * the sync server's existing matcher finishes the job.\n *\n * Registration: the room's current windows compile to topics\n * ({@link FanoutTopics.topicForSubset}) and are leased on a heartbeat —\n * registration is idempotent, so the heartbeat IS renewal, and a crashed\n * room simply ages out shard-side.\n */\n\nimport * as Arr from \"effect/Array\";\nimport * as Duration from \"effect/Duration\";\nimport * as Effect from \"effect/Effect\";\nimport * as Scope from \"effect/Scope\";\nimport type { ChangeHint } from \"./Backend.js\";\nimport type { FanoutBroker } from \"./FanoutBroker.js\";\nimport * as FanoutTopics from \"./FanoutTopics.js\";\nimport type { InvalidationBus } from \"./InvalidationBus.js\";\nimport type * as Node from \"./Node.js\";\nimport type * as Subset from \"./Subset.js\";\n\n/**\n * Options for {@link make}: this room's id at the broker, the broker, and the node graph topics\n * are derived from.\n */\nexport interface MakeOptions {\n /** This room's identity at the broker (typically the user id). */\n readonly roomId: string;\n readonly broker: FanoutBroker;\n /** The node graph — the derivable sets both derivation sides agree on. */\n readonly nodes: Node.NodeRegistry;\n /**\n * The room's current windows (e.g. the authorized subsets of its client\n * groups, from the sync server's introspection). Re-evaluated on every\n * heartbeat, so new subscriptions register within one beat.\n */\n readonly subsets: Effect.Effect<ReadonlyArray<Subset.Subset>>;\n /** Lease heartbeat. Default 10 seconds. */\n readonly heartbeat?: Duration.Input;\n /** Lease time-to-live. Default 3× the heartbeat. */\n readonly ttl?: Duration.Input;\n /**\n * Bound on each broker call the bus makes (a publish, a lease registration). A call that\n * exceeds it is logged and dropped, since a lost poke only delays the next pull (ADR-0009).\n * `publish` makes two such calls in turn (the broker publish, then a lease registration), each\n * with its own bound, so a hung broker can hold one `publish` for up to two bounds. `publish`\n * runs inside the sync server's uninterruptible commit-and-publish region, so these bounds are\n * what keep a hung broker from holding that region open indefinitely. With Durable Objects one\n * broker publish is many shard calls under its single bound, so a multi-topic publish can be cut\n * short and its unsent pokes dropped. That is acceptable per ADR-0009: a lost poke only delays\n * the next pull, which `syncLoop.pullInterval` bounds when it is configured. Default 5 seconds.\n */\n readonly timeout?: Duration.Input | undefined;\n}\n\n/** The topics one hint derives (coarse + fine over old and new values). */\nconst topicsForHint = (\n hint: ChangeHint,\n derivable: ReadonlySet<string> | undefined\n): ReadonlySet<FanoutTopics.Topic> => {\n const values = new Map(hint.values?.map(({ id, value }) => [id, value]) ?? []);\n const olds = new Map(hint.oldValues?.map(({ id, value }) => [id, value]) ?? []);\n const topics = new Set<FanoutTopics.Topic>([FanoutTopics.coarse(hint.collection)]);\n const ids = Arr.isReadonlyArrayNonEmpty(hint.ids) ? hint.ids : [...values.keys()];\n Arr.forEach(ids, (id) => {\n Arr.forEach(\n FanoutTopics.topicsForWrite(hint.collection, derivable, {\n oldValue: olds.get(id),\n newValue: values.get(id),\n }),\n (topic) => {\n topics.add(topic);\n }\n );\n });\n return topics;\n};\n\n/** Build the bus; the lease heartbeat runs until the scope closes. */\nexport const make = (options: MakeOptions): Effect.Effect<InvalidationBus, never, Scope.Scope> =>\n Effect.gen(function* () {\n const derivable = FanoutTopics.derivableSets(options.nodes);\n const heartbeat = options.heartbeat ?? \"10 seconds\";\n const ttl = options.ttl ?? Duration.millis(Duration.toMillis(heartbeat) * 3);\n const timeout = options.timeout ?? \"5 seconds\";\n // Every broker call is bounded, so a hung broker drops its call instead of\n // stalling the publish that awaits it (ADR-0009: correctness never depends on the bus).\n const bounded = (what: string, call: Effect.Effect<void>): Effect.Effect<void> =>\n call.pipe(\n Effect.timeoutOrElse({\n duration: timeout,\n orElse: () =>\n Effect.logWarning(\n `FanoutBus: ${what} timed out; dropped (the next heartbeat or pull recovers it)`\n ),\n })\n );\n\n const registerNow = bounded(\n \"lease registration\",\n options.subsets.pipe(\n Effect.flatMap((subsets) =>\n options.broker.register(\n options.roomId,\n new Set(\n subsets.map((subset) =>\n FanoutTopics.topicForSubset(subset, derivable.get(subset.collection))\n )\n ),\n ttl\n )\n )\n )\n );\n yield* registerNow;\n yield* Effect.forkScoped(\n Effect.forever(Effect.sleep(heartbeat).pipe(Effect.andThen(registerNow)))\n );\n\n return {\n publish: (hints) => {\n const topics = new Set<FanoutTopics.Topic>();\n Arr.forEach(hints, (hint) => {\n Arr.forEach(topicsForHint(hint, derivable.get(hint.collection)), (topic) => {\n topics.add(topic);\n });\n });\n // Freshen the lease alongside the write — a busy room never expires.\n return bounded(\"publish\", options.broker.publish(topics)).pipe(Effect.andThen(registerNow));\n },\n subscribe: Effect.gen(function* () {\n const pokes = yield* options.broker.pokes(options.roomId);\n return {\n take: pokes.take.pipe(\n Effect.map((topics) => {\n const collections = new Set(topics.map(FanoutTopics.collectionOf));\n return [...collections].map((collection) => ({ collection, ids: [] }));\n })\n ),\n };\n }),\n };\n });\n","/**\n * BusBrokers\n *\n * Concrete {@link BusBroker} implementations for the distributed\n * invalidation bus (ADR-0009). A broker is one string pub/sub channel;\n * `InvalidationBus.makeSerialized` runs the whole bus over it. These add no\n * dependency footprint (Redis ships inside `effect`; the WebSocket broker is\n * structural), so they live in core per ADR-0006.\n *\n * - `makeRedisBroker`: over Redis **Streams** (`XADD` / `XREAD BLOCK`) using\n * `effect/persistence` Redis. Streams give durable, replayable\n * fan-out; point every instance's subscriber at the same stream key.\n * - `makeWebSocketBroker`: over any `WebSocketLike` whose far end broadcasts\n * every frame to all peers — the shape of a Cloudflare Durable Object\n * relay (each Worker isolate holds a socket to the DO; the DO rebroadcasts).\n */\n\nimport * as Arr from \"effect/Array\";\nimport * as Duration from \"effect/Duration\";\nimport * as Effect from \"effect/Effect\";\nimport * as Option from \"effect/Option\";\nimport * as P from \"effect/Predicate\";\nimport * as Queue from \"effect/Queue\";\nimport * as Schema from \"effect/Schema\";\nimport * as Scope from \"effect/Scope\";\nimport { Redis } from \"effect/persistence\";\nimport type { BusBroker } from \"./InvalidationBus.js\";\n\n// ─── Redis Streams broker ────────────────────────────────────────────────────\n\n/** Options for {@link makeRedisBroker}. */\nexport interface RedisBrokerOptions {\n /** Stream key all instances share. Defaults to `\"legation:hints\"`. */\n readonly stream?: string;\n /**\n * XREAD BLOCK timeout before re-issuing. Defaults to 5 seconds. A reader XREAD with no reply\n * within this plus a fixed 2-second margin is a failed step. `0` disables that hang detection:\n * the reader parks until an entry arrives, so a dead connection parks it silently, as before.\n */\n readonly block?: Duration.Input;\n /**\n * Where a new subscriber starts reading. `\"$\"` (default) delivers only\n * messages published after it connects — pub/sub semantics; `\"0\"` replays\n * the whole stream (harmless for a bus, but unbounded without trimming).\n */\n readonly from?: \"$\" | \"0\";\n /**\n * Bound on one XADD. A publish that exceeds it is logged and dropped: the bus publishes inside\n * the sync server's uninterruptible commit-and-publish region, so a hung Redis must not hold\n * that region open. Defaults to 5 seconds.\n */\n readonly timeout?: Duration.Input;\n}\n\n/** One stream entry: `[id, [field0, value0, ...]]`. */\ntype StreamEntry = readonly [string, ReadonlyArray<string>];\n/** One stream's slice in an XREAD reply: `[streamKey, entries]`. */\ntype StreamReply = readonly [string, ReadonlyArray<StreamEntry>];\n/** A full XREAD reply, or null on BLOCK timeout. */\ntype XReadReply = ReadonlyArray<StreamReply> | null;\n/** An XREVRANGE reply: the entries in range, newest first. */\ntype XRevRangeReply = ReadonlyArray<StreamEntry>;\n\nconst PAYLOAD_FIELD = \"p\";\n\n/** Pull the payload value out of an entry's flattened field/value pairs. */\nconst payloadOf = (fields: ReadonlyArray<string>): string | undefined => {\n const at = Arr.findFirstIndex(\n fields,\n (field, i) => i % 2 === 0 && i + 1 < fields.length && String(field) === PAYLOAD_FIELD\n );\n return Option.match(at, { onNone: () => undefined, onSome: (i) => String(fields[i + 1]) });\n};\n\n/**\n * The ID an XREAD continues from after the given XREVRANGE reply: the newest\n * entry's ID, or `0-0` for an empty stream (so the next XREAD delivers every entry).\n */\nconst cursorAfter = (reply: XRevRangeReply): string => {\n const [newest] = reply;\n return newest === undefined ? \"0-0\" : newest[0];\n};\n\n/**\n * How long `subscribe` waits for its one start-position lookup. Past it, the\n * subscription is returned anyway and the reader resolves the position itself.\n */\nconst START_LOOKUP_BOUND = Duration.millis(500);\n\n/** The reader's start-position lookup did not answer within {@link START_LOOKUP_BOUND}. */\nclass StartLookupTimeout extends Schema.TaggedError<\n StartLookupTimeout,\n { readonly brand: unique symbol }\n>()(\"StartLookupTimeout\", {}) {}\n\n/**\n * The margin added to the XREAD BLOCK time to bound one reader XREAD. Redis ends a healthy idle\n * block at BLOCK, so a reply still missing at BLOCK plus this margin is a dead read (a half-open\n * connection, say), not a quiet stream.\n */\nconst XREAD_MARGIN_MS = 2_000;\n\n/** A reader XREAD got no reply within its bound (see {@link XREAD_MARGIN_MS}). */\nclass XReadTimeout extends Schema.TaggedError<XReadTimeout, { readonly brand: unique symbol }>()(\n \"XReadTimeout\",\n {}\n) {}\n\n/** The reader's first back-off after a failed step; it doubles on each consecutive failure. */\nconst RETRY_BASE_MS = 200;\n\n/** The cap on the reader's back-off. */\nconst RETRY_CAP_MS = 5_000;\n\n/** Back-off before the next attempt, after `failures` consecutive failed steps (`failures >= 1`). */\nconst backoffMs = (failures: number): number =>\n Math.min(RETRY_CAP_MS, RETRY_BASE_MS * 2 ** (failures - 1));\n\n/**\n * A BusBroker over Redis Streams. Captures the `Redis` service; each\n * `subscribe` forks a scoped reader looping `XREAD BLOCK`.\n *\n * `subscribe` makes one attempt at the start position (`XREVRANGE`, or `0-0`\n * for an empty stream), waiting at most 500 ms, and returns either way. If the\n * attempt answers in time, a hint published once `subscribe` returns is never\n * missed. If it fails or times out, the forked reader resolves the start\n * position on its first step and retries with back-off (200 ms, doubling,\n * capped at 5 s) until Redis answers. While Redis is unreachable, a publish that\n * races the start can be missed: it lands after `subscribe` returns but before\n * the reader resolves its start position. Delivery is best-effort (ADR-0009).\n * Each reader XREAD is bounded at its `block` time plus the margin described on\n * `block`. A call with no reply by then is a failed step: it is logged, backed off\n * and retried from the last ID seen, as a failed start lookup is, so no entry is\n * skipped. A reply of null (a normal BLOCK timeout) is a success.\n *\n * The `Redis` service's `send` must meet two properties that this bound relies on.\n * It must be interruptible: the bound interrupts a read that never replies. And\n * after an aborted `send`, it must keep replies in order on its connection, so a\n * late reply to an abandoned XREAD is never read as the answer to the next command.\n *\n * Known limit: after a `DEL` and recreate of the stream, or a Redis clock\n * stepping backwards, new IDs can fall at or below the sticky cursor and be\n * skipped until the subscriber resubscribes.\n */\nexport const makeRedisBroker = (\n options?: RedisBrokerOptions\n): Effect.Effect<BusBroker, never, Redis.Redis> =>\n Effect.gen(function* () {\n const redis = yield* Redis.Redis;\n const stream = options?.stream ?? \"legation:hints\";\n const blockMillis = Math.trunc(Duration.toMillis(options?.block ?? \"5 seconds\"));\n const blockMs = String(blockMillis);\n const from = options?.from ?? \"$\";\n const timeout = options?.timeout ?? \"5 seconds\";\n\n // Bounds one reader XREAD (see XREAD_MARGIN_MS). BLOCK 0 parks until an entry\n // arrives, so no bound can tell a dead read from a quiet stream and none applies.\n const boundRead = <A>(\n read: Effect.Effect<A, Redis.RedisError>\n ): Effect.Effect<A, Redis.RedisError | XReadTimeout> =>\n blockMillis > 0\n ? read.pipe(\n Effect.timeoutOrElse({\n duration: Duration.millis(blockMillis + XREAD_MARGIN_MS),\n orElse: () => Effect.fail(new XReadTimeout()),\n })\n )\n : read;\n\n // The start position of a subscription, read before the first XREAD. XREAD's\n // \"$\" re-resolves on each call, so a BLOCK timeout followed by a publish would\n // move the cursor past that entry and the subscriber would never read it; the\n // ID read here does not move. A failure is raised to the caller: `subscribe`\n // treats it as \"not yet\", and the reader asks again. The reader bounds this\n // lookup itself (START_LOOKUP_BOUND), so a hung Redis is a failed step too.\n const lastId = redis\n .send<XRevRangeReply>(\"XREVRANGE\", stream, \"+\", \"-\", \"COUNT\", \"1\")\n .pipe(Effect.map(cursorAfter));\n\n return {\n // Best-effort: a failed or timed-out publish only delays the next pull\n // (ADR-0009), and BusBroker.publish has no error channel.\n publish: (payload) =>\n redis.send(\"XADD\", stream, \"*\", PAYLOAD_FIELD, payload).pipe(\n Effect.timeoutOrElse({\n duration: timeout,\n orElse: () => Effect.logWarning(\"Redis broker: XADD timed out; publish dropped\"),\n }),\n Effect.ignore\n ),\n subscribe: Effect.gen(function* () {\n const queue = yield* Queue.unbounded<string>();\n // The ID the next XREAD continues from. `from: \"0\"` needs no lookup. Any\n // other start gets one bounded attempt here, so a publish made right after\n // `subscribe` returns is not missed while Redis answers in time. If the\n // attempt fails or times out, the reader's first step resolves it.\n const cursor: { id: string | undefined } = { id: from === \"0\" ? \"0\" : undefined };\n if (cursor.id === undefined) {\n const first = yield* lastId.pipe(\n Effect.timeoutOption(START_LOOKUP_BOUND),\n Effect.orElseSucceed(() => Option.none<string>())\n );\n if (Option.isSome(first)) cursor.id = first.value;\n }\n // Per-subscription outage state: consecutive failed steps. The first failure\n // of an outage logs a warning, each further retry logs at debug, and the\n // first successful Redis reply after an outage logs at info.\n const outage = { failures: 0 };\n const answered = Effect.suspend(() => {\n const failures = outage.failures;\n if (failures === 0) return Effect.void;\n outage.failures = 0;\n return Effect.logInfo(`Redis broker: reader recovered after ${failures} failed step(s)`);\n });\n const failed = (error: unknown) =>\n Effect.suspend(() => {\n outage.failures += 1;\n const delay = backoffMs(outage.failures);\n const log =\n outage.failures === 1\n ? Effect.logWarning(\n \"Redis broker: reader step failed; retrying with back-off\",\n error\n )\n : Effect.logDebug(\n `Redis broker: reader step failed again; retrying in ${delay} millis`,\n error\n );\n return log.pipe(Effect.andThen(Effect.sleep(Duration.millis(delay))));\n });\n const readOnce = Effect.gen(function* () {\n if (cursor.id === undefined) {\n cursor.id = yield* lastId.pipe(\n Effect.timeoutOrElse({\n duration: START_LOOKUP_BOUND,\n orElse: () => Effect.fail(new StartLookupTimeout()),\n }),\n Effect.tap(() => answered)\n );\n }\n const reply = yield* boundRead(\n redis.send<XReadReply>(\"XREAD\", \"BLOCK\", blockMs, \"STREAMS\", stream, cursor.id)\n ).pipe(Effect.tap(() => answered));\n if (reply === null) return;\n yield* Effect.forEach(\n reply,\n ([, entries]) =>\n Effect.gen(function* () {\n yield* Effect.forEach(\n entries,\n ([id, fields]) =>\n Effect.gen(function* () {\n cursor.id = id;\n const payload = payloadOf(fields);\n if (payload !== undefined) yield* Queue.offer(queue, payload);\n }),\n { concurrency: 1, discard: true }\n );\n }),\n { concurrency: 1, discard: true }\n );\n }).pipe(\n // A transient Redis error, a read with no reply (XReadTimeout), or an\n // unresolved start position must not kill the subscription: log it, back\n // off, and run the step again from the last ID seen.\n Effect.catch(failed)\n );\n yield* Effect.forkScoped(Effect.forever(readOnce));\n return { take: Queue.take(queue) };\n }),\n };\n });\n\n// ─── WebSocket / Durable Object broker ───────────────────────────────────────\n\n/** The minimal WebSocket surface this broker uses (browser/DO/ws-compatible). */\nexport interface WebSocketLike {\n readonly send: (data: string) => void;\n readonly addEventListener: (\n type: \"message\",\n listener: (event: { readonly data: unknown }) => void\n ) => void;\n readonly removeEventListener: (\n type: \"message\",\n listener: (event: { readonly data: unknown }) => void\n ) => void;\n}\n\n/**\n * A BusBroker over a `WebSocketLike` whose far end rebroadcasts every frame\n * to all connected peers — the Durable Object relay pattern. `publish` sends\n * a frame; `subscribe` collects inbound string frames.\n */\nexport const makeWebSocketBroker = (socket: WebSocketLike): BusBroker => ({\n publish: (payload) => Effect.sync(() => socket.send(payload)),\n subscribe: Effect.gen(function* () {\n const queue = yield* Queue.unbounded<string>();\n yield* Effect.acquireRelease(\n Effect.sync(() => {\n const listener = (event: { readonly data: unknown }) => {\n if (P.isString(event.data)) Queue.offerUnsafe(queue, event.data);\n };\n socket.addEventListener(\"message\", listener);\n return listener;\n }),\n (listener) => Effect.sync(() => socket.removeEventListener(\"message\", listener))\n );\n return { take: Queue.take(queue) };\n }),\n});\n\n// ─── BroadcastChannel broker ─────────────────────────────────────────────────\n\n/** The minimal `BroadcastChannel` surface this broker uses. */\nexport interface BroadcastChannelLike {\n readonly postMessage: (data: string) => void;\n readonly addEventListener: (\n type: \"message\",\n listener: (event: { readonly data: unknown }) => void\n ) => void;\n readonly removeEventListener: (\n type: \"message\",\n listener: (event: { readonly data: unknown }) => void\n ) => void;\n}\n\n/**\n * A BusBroker over a `BroadcastChannel` — cross-context fan-out on one machine\n * (browser tabs, Node worker threads). A `BroadcastChannel` delivers to every\n * *other* channel of the same name but not the sender, so `publish` also offers\n * to this broker's own subscribers, honoring the contract's self-delivery (each\n * instance fans the hint out to its local sessions). Point every context's\n * broker at the same channel name.\n */\nexport const makeBroadcastChannelBroker = (\n channel: BroadcastChannelLike\n): Effect.Effect<BusBroker, never, Scope.Scope> =>\n Effect.gen(function* () {\n const queues = new Set<Queue.Queue<string>>();\n yield* Effect.acquireRelease(\n Effect.sync(() => {\n const listener = (event: { readonly data: unknown }) => {\n const data = event.data;\n if (!P.isString(data)) return;\n Arr.forEach(queues, (queue) => {\n Queue.offerUnsafe(queue, data);\n });\n };\n channel.addEventListener(\"message\", listener);\n return listener;\n }),\n (listener) => Effect.sync(() => channel.removeEventListener(\"message\", listener))\n );\n return {\n publish: (payload) =>\n Effect.sync(() => {\n Arr.forEach(queues, (queue) => {\n Queue.offerUnsafe(queue, payload);\n }); // self\n channel.postMessage(payload); // other contexts\n }),\n subscribe: Effect.gen(function* () {\n const queue = yield* Queue.unbounded<string>();\n yield* Effect.acquireRelease(\n Effect.sync(() => queues.add(queue)),\n () => Effect.sync(() => queues.delete(queue))\n );\n return { take: Queue.take(queue) };\n }),\n };\n });\n","/**\n * HintSource\n *\n * A HintSource produces ChangeHints for writes that bypass mutators (CDC —\n * cron jobs, admin tools, another service, psql), publishing them to the\n * InvalidationBus so out-of-band changes poke subscribed clients. Fork its\n * `run` into a scope alongside the SyncServer.\n *\n * Correctness is preserved regardless: a HintSource only pokes, and poke is\n * never a correctness dependency (ADR-0009) — a missed or redundant hint only\n * changes when the next pull happens. A source that publishes value-less hints\n * (no `values`) is matched at the collection level by the #42 fan-out matcher,\n * which is sound: over-matching a poke costs an empty pull, under-matching would\n * delay convergence, so a hint that names only a collection pokes every group\n * subscribed to it.\n */\n\nimport * as Effect from \"effect/Effect\";\nimport * as Scope from \"effect/Scope\";\nimport * as Stream from \"effect/Stream\";\nimport type { ChangeHint } from \"./Backend.js\";\nimport * as InvalidationBus from \"./InvalidationBus.js\";\n\n/**\n * A producer of change hints for writes that bypass mutations; fork its `run` beside the server.\n */\nexport interface HintSource {\n /** Run until the scope closes; publishes to the in-context InvalidationBus. */\n readonly run: Effect.Effect<void, never, InvalidationBus.InvalidationBus | Scope.Scope>;\n}\n\n/**\n * Build a HintSource from a stream of hint batches (used by the LISTEN/NOTIFY\n * recipe and tests): each emitted batch is published to the in-context bus, and\n * the consuming fibre is tied to the scope so it stops when the scope closes.\n */\nexport const fromStream = (hints: Stream.Stream<ReadonlyArray<ChangeHint>>): HintSource => ({\n run: Effect.flatMap(InvalidationBus.InvalidationBus, (bus) =>\n Effect.asVoid(Effect.forkScoped(Stream.runForEach(hints, bus.publish)))\n ),\n});\n\n/**\n * Fork a HintSource for the caller's scope, resolving the bus from context: the\n * source's worker runs on a scoped fibre alongside the SyncServer and is\n * interrupted when the scope closes.\n */\nexport const run = (\n source: HintSource\n): Effect.Effect<void, never, InvalidationBus.InvalidationBus | Scope.Scope> => source.run;\n","/**\n * SyncRoom\n *\n * The packaged server composition (ADR-0009): SyncServer orchestration +\n * in-memory CVR store + in-process invalidation bus, ready to bind to any\n * carrier. The same composition runs in-process on Node or inside a\n * Cloudflare Durable Object (where the DO's single-threaded scope IS the\n * room); distributed deployments swap the bus and CVR store layers.\n */\n\nimport * as Layer from \"effect/Layer\";\nimport type { Backend } from \"./Backend.js\";\nimport type { AuthPolicy } from \"./Authorization.js\";\nimport * as Cvr from \"./Cvr.js\";\nimport * as InvalidationBus from \"./InvalidationBus.js\";\nimport * as SyncServer from \"./SyncServer.js\";\nimport type { ServerHandler } from \"./Transport.js\";\n\n/**\n * A self-contained room: provide a Backend and an AuthPolicy, get a\n * ServerHandler. CVRs and the bus are in-memory/in-process.\n */\nexport const layer: Layer.Layer<ServerHandler, never, Backend | AuthPolicy> = SyncServer.layer.pipe(\n Layer.provide(Cvr.layerMemoryStore),\n Layer.provide(InvalidationBus.layerInProcess)\n);\n","/**\n * HttpCache\n *\n * The separate service-worker HTTP caching module (distinct from collection\n * sync; see CONTEXT.md). Core defines the runtime-agnostic service: a\n * Request/Response cache with freshness windows, stale-while-revalidate,\n * and tag-based invalidation. The browser package implements the store over\n * the Cache API (fixing the former text-only body limitation) and closes the\n * loop on collection- and row-driven invalidation: `HttpCacheInvalidation`\n * maps an engine's collection and row changes (the `collection:{name}` /\n * `collection:{name}:{id}` tag convention, #207) onto `invalidateTags`, so a\n * synced change evicts the responses tagged for what it touched.\n * Implementations for edge runtimes can back the store with their own\n * primitives.\n *\n * Phase 3 module: interfaces are final-shape; the fetch-event handler and\n * Cache API store land with the browser host.\n */\n\nimport * as Arr from \"effect/Array\";\nimport * as Context from \"effect/Context\";\nimport type * as Effect from \"effect/Effect\";\nimport type * as Duration from \"effect/Duration\";\nimport type { StoreError } from \"./Errors.js\";\n\n/** Cache metadata kept alongside a stored Response. */\nexport interface CachedResponseMeta {\n readonly url: string;\n readonly storedAt: number;\n readonly staleAt: number;\n readonly expiresAt: number | undefined;\n readonly tags: ReadonlyArray<string>;\n}\n\n/** A pluggable store of Request/Response pairs (Cache API in browsers). */\nexport interface ResponseCacheStore {\n readonly match: (\n request: Request\n ) => Effect.Effect<\n { readonly response: Response; readonly meta: CachedResponseMeta } | undefined,\n StoreError\n >;\n readonly put: (\n request: Request,\n response: Response,\n meta: CachedResponseMeta\n ) => Effect.Effect<void, StoreError>;\n readonly delete: (request: Request) => Effect.Effect<void, StoreError>;\n /** Remove every entry carrying any of the tags. */\n readonly invalidateTags: (tags: ReadonlyArray<string>) => Effect.Effect<void, StoreError>;\n}\n\n/**\n * The {@link ResponseCacheStore} service tag, for apps that provide a store by layer;\n * the fetch handlers take it as an option.\n */\nexport const ResponseCacheStore = Context.Service<ResponseCacheStore>(\n \"@thomasfosterau/legation/ResponseCacheStore\"\n);\n\n/** Per-route caching policy. */\nexport interface HttpCachePolicy {\n readonly staleTime: Duration.Input;\n readonly timeToLive?: Duration.Input | undefined;\n readonly tags?: ReadonlyArray<string> | undefined;\n}\n\n// ─── The tag convention (#207, #206) ─────────────────────────────────────────\n//\n// One spelling for every cache that evicts by what a write touched: the\n// browser's Cache API (`HttpCacheInvalidation` in `@thomasfosterau/legation-browser`)\n// and the edge (`EdgeInvalidation` in `@thomasfosterau/legation-alchemy-cloudflare`).\n\n/** The coarse tag of a collection: `collection:{name}`. Every response enumerating (part of) it carries it. */\nexport const tagFor = (collection: string): string => `collection:${collection}`;\n\n/** The fine tag of one row: `collection:{name}:{id}`. A response carries one per row it contains. */\nexport const fineTagFor = (collection: string, id: string): string => `${tagFor(collection)}:${id}`;\n\n/** The collections and individual rows a change touched. */\nexport interface Touched {\n readonly collections: ReadonlyArray<string>;\n readonly rows: ReadonlyArray<{ readonly collection: string; readonly id: string }>;\n}\n\n/** Options for {@link evictionTags}: the tag spelling, defaulting to {@link tagFor} and {@link fineTagFor}. */\nexport interface EvictionTagOptions {\n readonly tagFor?: (collection: string) => string;\n readonly fineTagFor?: (collection: string, id: string) => string;\n}\n\n/**\n * The tags to evict for a change, each once: the coarse tag of every touched\n * collection **and** the fine tag of every touched row. The coarse eviction is\n * not redundant with the fine one: a cached aggregate (a list, a feed, a\n * sitemap) can be staled by a row it does not yet contain, such as a newly\n * published one, and only the coarse tag reaches it.\n */\nexport const evictionTags = (\n touched: Touched,\n options: EvictionTagOptions = {}\n): ReadonlyArray<string> => {\n const coarse = options.tagFor ?? tagFor;\n const fine = options.fineTagFor ?? fineTagFor;\n return Arr.dedupe([\n ...touched.collections.map((collection) => coarse(collection)),\n ...touched.rows.map((row) => fine(row.collection, row.id)),\n ]);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8GA,MAAM,YAAY,SAAyB;CACzC,MAAM,UAAU,KAAK,QAAQ,kBAAkB,GAAG,CAAC,CAAC,QAAQ,YAAY,EAAE;CAC1E,IAAI,IAAI,QAAQ,OAAO,GAAG,OAAO;CACjC,OAAO,SAAS,KAAK,OAAO,IAAI,IAAI,YAAY;AAClD;;AAGA,MAAM,oBAAoB;CACxB,MAAM,uBAAO,IAAI,IAAY;CAC7B,QAAQ,QAAgB,SAAyB;EAC/C,MAAM,OAAO,GAAG,SAAS,SAAS,IAAI;EAEtC,MAAM,MAAM,MAAuB,IAAI,IAAI,OAAO,GAAG,KAAK,GAAG;EAC7D,MAAM,QAAQ,MAAuB,KAAK,IAAI,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,GAAG,CAAC;EACzE,MAAM,YAAY,KAAK,CAAC;EACxB,KAAK,IAAI,SAAS;EAClB,OAAO;CACT;AACF;AAIA,MAAM,MAA4B,QAAW,eAC3C,OAAO,SAAS,EAAE,WAAW,CAAC;;AAGhC,MAAM,YAAY,OAAO,OAAO;CAC9B,MAAM,OAAO,IAAI,cAAc;CAC/B,SAAS,OAAO;AAClB,CAAC;;;;;;AAOD,MAAM,cAAc,QAAiB;CACnC,MAAM,cAAc,IAAI,eAAe,CAAC;CACxC,MAAM,WAAW,IAAI,YAAY,CAAC;CAClC,MAAM,UAAU,IAAI,WAAW,CAAC;CAChC,MAAM,OAAO,YAAY;CAEzB,MAAM,kBAAkB,YAAY,KAAK,OAAO;EAAE,KAAK;EAAG,QAAQ,KAAK,QAAQ,EAAE,IAAI;CAAE,EAAE;CACzF,MAAM,eAAe,SAAS,KAAK,OAAO;EAAE,KAAK;EAAG,QAAQ,KAAK,gBAAgB,EAAE,IAAI;CAAE,EAAE;CAC3F,MAAM,aAAa,QAAQ,KAAK,OAAO;EAAE,KAAK;EAAG,QAAQ,KAAK,cAAc,EAAE,IAAI;CAAE,EAAE;CAGtF,MAAM,WAAW,IAAI,qBAAqB,YAAY,IAClD,GAAG,UAAU,UAAU,IACvB,GACE,OAAO,MACL,aAAa,KAAK,EAAE,KAAK,aACvB,GACE,OAAO,OAAO;EACZ,UAAU,OAAO;EACjB,YAAY,OAAO;EACnB,SAAS,OAAO,QAAQ,IAAI,IAAI;EAChC,MAAM,GAAG,IAAI,MAAM,MAAM;EACzB,WAAW,OAAO;CACpB,CAAC,GACD,YAAY,SAAS,IAAI,IAAI,GAC/B,CACF,CACF,GACA,UACF;CAGJ,MAAM,UAAU,IAAI,qBAAqB,eAAe,IACpD,GAAG,SAAS,SAAS,IACrB,GACE,OAAO,MAAM;EACX,GAAG,gBAAgB,KAAK,EAAE,KAAK,aAC7B,GACE,OAAO,OAAO;GACZ,MAAM,OAAO,IAAI,KAAK;GACtB,YAAY,OAAO,QAAQ,IAAI,IAAI;GACnC,IAAI,OAAO;GACX,SAAS,OAAO,MAAM,CAAC,OAAO,QAAQ,OAAO,MAAM,CAAC;GACpD,OAAO,GAAG,IAAI,QAAQ,MAAM;EAC9B,CAAC,GACD,OAAO,SAAS,IAAI,IAAI,GAC1B,CACF;EACA,OAAO,OAAO;GACZ,MAAM,OAAO,IAAI,KAAK;GACtB,YAAY,OAAO;GACnB,IAAI,OAAO;EACb,CAAC;EACD,OAAO,OAAO,EAAE,MAAM,OAAO,IAAI,OAAO,EAAE,CAAC;CAC7C,CAAC,GACD,SACF;CAGJ,MAAM,oBAAoB,IAAI,qBAAqB,UAAU,IACzD,GAAG,mBAAmB,mBAAmB,IACzC,GACE,OAAO,MACL,WAAW,KAAK,EAAE,KAAK,aACrB,GACE,OAAO,OAAO;EAAE,MAAM,OAAO,QAAQ,IAAI,IAAI;EAAG,MAAM,GAAG,IAAI,MAAM,MAAM;CAAE,CAAC,GAC5E,qBAAqB,SAAS,IAAI,IAAI,GACxC,CACF,CACF,GACA,mBACF;CAEJ,MAAM,cAAc,GAClB,OAAO,OAAO;EAAE,eAAe,OAAO;EAAQ,WAAW,OAAO,MAAM,QAAQ;CAAE,CAAC,GACjF,aACF;CACA,MAAM,cAAc,GAClB,OAAO,OAAO;EACZ,eAAe,OAAO;EACtB,QAAQ,OAAO,SAAS,OAAO,MAAM;EACrC,eAAe,OAAO,MAAM,GAAG,QAAQ,QAAQ,CAAC;EAChD,oBAAoB,OAAO,SAAS,OAAO,MAAM,iBAAiB,CAAC;CACrE,CAAC,GACD,aACF;CACA,MAAM,eAAe,GACnB,OAAO,OAAO;EACZ,QAAQ,OAAO;EACf,OAAO,OAAO,MAAM,OAAO;EAC3B,iBAAiB,OAAO,OAAO,OAAO,QAAQ,OAAO,MAAM;EAC3D,UAAU,OAAO,SAAS,OAAO,MAAM,gBAAgB,CAAC;CAC1D,CAAC,GACD,cACF;CAWA,OAAO;EACL,OAAA;GATA,YAAY;GACZ,GAAG,cAAc,cAAc,CAAC,CAAC;GACjC,YAAY;GACZ,aAAa;GACb,GAAG,MAAM,MAAM,CAAC,CAAC;GACjB,GAAG,WAAW,cAAc,CAAC,CAAC;EAI1B;EACJ,SAAS;GACP,aAAa,gBAAgB,KAAK,EAAE,KAAK,cAAc;IAAE,MAAM,IAAI;IAAM;GAAO,EAAE;GAClF,UAAU,aAAa,KAAK,EAAE,KAAK,cAAc;IAAE,MAAM,IAAI;IAAM;GAAO,EAAE;GAC5E,SAAS,WAAW,KAAK,EAAE,KAAK,cAAc;IAAE,MAAM,IAAI;IAAM;GAAO,EAAE;EAC3E;CACF;AACF;;;;;;AASA,MAAa,SAAS,QAA2B;CAC/C,MAAM,EAAE,OAAO,YAAY,WAAW,GAAG;CACzC,MAAM,UAAU,WAAW,0BACzB,qBAAqB,0BAA0B,qBAAqB,kBAAkB,KAAK,CAAC,CAC9F;CACA,OAAO;EACL,MAAM,IAAI;EACV,MAAM,IAAI,QAAQ;EAClB,YAAY,QAAQ;EACpB,UAAU;GACR,aAAa;GACb,cAAc;GACd,aAAa;GACb,cAAc;GACd,MAAM;GACN,OAAO;EACT;EACA;CACF;AACF;AAOA,MAAM,OAAO,UAAkB,EAAE,MAAM,wBAAwB,OAAO;AACtE,MAAM,UAAU,UAAkB,EAAE,MAAM,yBAAyB,OAAO;AAC1E,MAAM,WAAW,UAAkB,EAAE,MAAM,cAAc,OAAO;AAChE,MAAM,WAAW,aAA+B;CAAE,MAAM;CAAS,SAAS,IAAI,OAAO;AAAE;AAEvF,MAAM,mBAAmB,MAAgB,WAA6B;CACpE,OAAO,KAAK;CACZ,SAAS,KAAK;CACd,aAAa,KAAK,gBAAgB,KAAA,IAAY,QAAQ,GAAG,KAAK,YAAY,MAAM;AAClF;;;;;;AAOA,MAAa,aAAa,SAA6B;CACrD,MAAM,aACJ,aACA,SACA,SACA,cACc,EACd,MAAM;EACJ;EACA;EACA,aAAa;GACX,UAAU;GACV,SAAS,EAAE,oBAAoB,EAAE,QAAQ,IAAI,OAAO,EAAE,EAAE;EAC1D;EACA,WAAW;GACT,OAAO;IACL,aAAa;IACb,SAAS,EAAE,oBAAoB,EAAE,QAAQ,IAAI,QAAQ,EAAE,EAAE;GAC3D;GACA,SAAS;IACP,aAAa;IACb,SAAS,EAAE,oBAAoB,EAAE,QAAQ,IAAI,KAAK,SAAS,KAAK,EAAE,EAAE;GACtE;EACF;CACF,EACF;CAEA,OAAO;EACL,SAAS;EACT,MAAM,gBACJ,KAAK,MACL,6KACF;EACA,OAAO;IACJ,GAAG,KAAK,KAAK,SAAS,UACrB,QACA,qCACA,KAAK,SAAS,aACd,KAAK,SAAS,YAChB;IACC,GAAG,KAAK,KAAK,SAAS,UACrB,QACA,8CACA,KAAK,SAAS,aACd,KAAK,SAAS,YAChB;EACF;EACA,YAAY,EAAE,SAAS,KAAK,WAAW;CACzC;AACF;;;;;;AAOA,MAAa,cAAc,SAA6B;CACtD,OAAO;EACL,UAAU;EACV,MAAM,gBACJ,KAAK,MACL,iGACF;EACA,UAAU;GACR,MAAM;IACJ,SAAS,GAAG,KAAK,KAAK;IACtB,UAAU;KACR,SAAS,OAAO,KAAK,SAAS,WAAW;KACzC,UAAU,OAAO,KAAK,SAAS,YAAY;IAC7C;GACF;GACA,MAAM;IACJ,SAAS,GAAG,KAAK,KAAK;IACtB,UAAU;KACR,SAAS,OAAO,KAAK,SAAS,WAAW;KACzC,UAAU,OAAO,KAAK,SAAS,YAAY;IAC7C;GACF;GACA,OAAO;IACL,SAAS,GAAG,KAAK,KAAK;IACtB,UAAU,EAAE,MAAM,OAAO,KAAK,SAAS,IAAI,EAAE;GAC/C;EACF;EACA,YAAY;GACV,MAAM;IACJ,QAAQ;IACR,SAAS,QAAQ,MAAM;IACvB,OAAO;KAAE,SAAS,QAAQ,MAAM;KAAG,UAAU,CAAC,OAAO,KAAK,SAAS,YAAY,CAAC;IAAE;GACpF;GACA,MAAM;IACJ,QAAQ;IACR,SAAS,QAAQ,MAAM;IACvB,OAAO;KAAE,SAAS,QAAQ,MAAM;KAAG,UAAU,CAAC,OAAO,KAAK,SAAS,YAAY,CAAC;IAAE;GACpF;GACA,cAAc;IAAE,QAAQ;IAAW,SAAS,QAAQ,OAAO;GAAE;EAC/D;EACA,YAAY;GACV,SAAS,KAAK;GACd,UAAU;KACP,KAAK,SAAS,cAAc,QAAQ,KAAK,SAAS,WAAW;KAC7D,KAAK,SAAS,eAAe,QAAQ,KAAK,SAAS,YAAY;KAC/D,KAAK,SAAS,cAAc,QAAQ,KAAK,SAAS,WAAW;KAC7D,KAAK,SAAS,eAAe,QAAQ,KAAK,SAAS,YAAY;KAC/D,KAAK,SAAS,OAAO,QAAQ,KAAK,SAAS,IAAI;GAClD;EACF;CACF;AACF;;AAKA,MAAa,WAAW,QAA2B,UAAU,MAAM,GAAG,CAAC;;AAGvE,MAAa,YAAY,QAA2B,WAAW,MAAM,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACpWzE,MAAM,gBAAyB;CAAE,MAAM,CAAC;CAAG,MAAM,CAAC;AAAE;;;;;;;;;AA4DpD,MAAaA,UAAW,WACtB,OAAO,IAAI,aAAa;CACtB,MAAM,UAAU,OAAO,gBAAgB,KAAc,aAAa;CAElE,MAAM,cAAc,OAAO,IAAI,KAA2C,KAAA,CAAS;CAEnF,MAAM,aAAa,WACjB,OAAO,OAAO,OAAO,SAAS,OAAO,IAAI;CAG3C,MAAM,YAAY,SAChB,gBAAgB,OAAO,UAAU,OAAO;EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,IAAI;EAAG,MAAM,CAAC;CAAE,EAAE;CAIhF,MAAM,UAAU,UACd,IAAI,IAAI,WAAW,CAAC,CAAC,KACnB,OAAO,SAAS,WACd,WAAW,KAAA,IAAY,SAAS,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,aAAa,CAAC,GAAG,QAAQ,KAAK,CAAC,CACpF,CACF;CAEF,MAAM,OAA8B,UAClC,UAAU,MAAM,OAAO,CAAC,CAAC,KAAK,OAAO,QAAQ,OAAO,KAAK,CAAC,CAAC;CAG7D,MAAM,QAAQ,SACZ,gBAAgB,OAAO,UAAU,MAAM;EACrC,MAAM,QAAQ,EAAE;EAChB,MAAM,OAAO,MAAM,GAAG,EAAE;EACxB,IAAI,SAAS,KAAA,GAAW,OAAO,CAAC,KAAA,GAAW,CAAC;EAC5C,OAAO,CAAC,MAAM;GAAE,GAAG;IAAI,OAAO,MAAM,MAAM,GAAG,EAAE;EAAE,CAAC;CACpD,CAAC;CAEH,MAAM,YAAY,MAAuB,SACvC,gBAAgB,OAAO,UAAU,OAAO;EAAE,GAAG;GAAI,OAAO,CAAC,GAAG,EAAE,OAAO,IAAI;CAAE,EAAE;CAI/E,MAAM,UAAU,MAAY,cAC1B,OAAO,IAAI,aAAa;EACtB,MAAM,UAAU,cAAc,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC,QAAQ,IAAI;EAC7D,OAAO,OAAO,QACZ,UACC,UACC,OAAO,IAAI,aAAa;GACtB,OAAO,UAAU,cAAc,SAAS,MAAM,OAAO,MAAM,OAAO;EACpE,CAAC,GACH;GAAE,aAAa;GAAG,SAAS;EAAK,CAClC;CACF,CAAC;CAGH,MAAM,QAAQ,MAAuB,SACnC,KAAK,IAAI,CAAC,CAAC,KACT,OAAO,SAAS,WACd,WAAW,KAAA,IACP,OAAO,OACP,OAAO,QAAQ,IAAI,CAAC,CAAC,KAAK,OAAO,QAAQ,SAAS,MAAM,MAAM,CAAC,CAAC,CACtE,CACF;CAEF,MAAM,UAAU,gBAAgB,IAAI,OAAO,CAAC,CAAC,KAC3C,OAAO,KAAK,MAAM,IAAI,wBAAwB,EAAE,IAAI,CAAC,CACvD;CACA,MAAM,UAAU,gBAAgB,IAAI,OAAO,CAAC,CAAC,KAC3C,OAAO,KAAK,MAAM,IAAI,wBAAwB,EAAE,IAAI,CAAC,CACvD;CAEA,MAAM,WAAW,YACf,gBAAgB,QAAQ,OAAO,CAAC,CAAC,KAAK,OAAO,IAAI,OAAO,GAAG,OAAO,OAAO;CAG3E,MAAM,aAAkC,IAAI,IAAI,WAAW,CAAC,CAAC,KAC3D,OAAO,SAAS,WACd,WAAW,KAAA,KAAa,IAAI,wBAAwB,MAAM,IAAI,SAAS,MAAM,IAAI,OAAO,IAC1F,CACF;CAEA,MAAM,SAAkC,WACtC,IAAI,IAAI,WAAW,CAAC,CAAC,KACnB,OAAO,SAAS,aAEd,aAAa,KAAA,IACT,SACA,IAAI,IAAI,aAAa,CAAC,CAAC,CAAC,CAAC,KACvB,OAAO,QAAQ,MAAM,GACrB,OAAO,UAAU,UAAU,GAC3B,OAAO,SAAS,IAAI,IAAI,aAAa,KAAA,CAAS,CAAC,CACjD,CACN,CACF;CAEF,OAAO;EACL;EACA,MAAM,KAAK,QAAQ,MAAM;EACzB,MAAM,KAAK,QAAQ,MAAM;EACzB;EACA;EACA,gBAAgB,SAAS,MAAM,IAAI,wBAAwB,EAAE,IAAI,CAAC;EAClE,gBAAgB,SAAS,MAAM,IAAI,wBAAwB,EAAE,IAAI,CAAC;EAClE;CACF;AACF,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACnIH,MAAM,mCAAmB,IAAI,QAAuC;;AAGpE,MAAM,6BAAa,IAAI,QAAiB;;AAGxC,MAAM,SAAS,QAAsB,YAA2B;CAC9D,IAAI,WAAW,IAAI,OAAO,GAAG;CAC7B,WAAW,IAAI,OAAO;CACtB,IAAI,MAAM,iBAAiB,IAAI,MAAM;CACrC,IAAI,QAAQ,KAAA,GAAW;EACrB,sBAAM,IAAI,IAAI;EACd,iBAAiB,IAAI,QAAQ,GAAG;CAClC;CACA,IAAI,IAAI,IAAI,QAAQ,OAAO,CAAC;AAC9B;;;;;;AAOA,MAAM,WAAW,QAAsB,aAGrC,OAAO,gBACL,OAAO,IAAI,aAAa;CACtB,MAAM,EAAE,eAAe,OAAO,OAAO,cAAc,CAAC,QAAQ,CAAC;CAC7D,IAAI,IAAI,qBAAqB,UAAU,GAAG;CAC1C,MAAM,QAAQ,IAAI,IAAI,WAAW,KAAK,EAAE,MAAM,SAAS,CAAC,MAAM,EAAE,CAAU,CAAC;CAC3E,MAAM,MAAM,iBAAiB,IAAI,MAAM;CACvC,IAAI,QAAQ,KAAA,GAAW;CACvB,IAAI,QAAQ,MAAM,QAAQ;EACxB,MAAM,UAAU,IAAI,MAAM;EAC1B,IAAI,YAAY,KAAA,GAAW;GACzB,IAAI,OAAO,GAAG;GACd;EACF;EACA,IAAI,QAAQ,UAAU,CAAC,KAAK,QAAQ;GAClC,MAAM,QAAQ,MAAM,IAAI,EAAE;GAC1B,IAAI,UAAU,KAAA,GAAW,QAAQ,IAAI,KAAK,KAAK;EACjD,CAAC;CACH,CAAC;AACH,CAAC,CACH;;;;;;;;AAiBF,MAAM,SACJ,QACA,SACA,aACA,KACA,SAEA,OAAO,IAAI,aAAa;CACtB,MAAM,QAAQ,WAAW;CAIzB,MAAM,WAAW,OAAO,OAAO,gBAC7B,OAAO,IAAI,aAAa;EACtB,MAAM,SAAS,OAAO,OAAO,cAAc,SAAS,IAAI;EACxD,MAAM,SAAS,YAAY,IAAI,GAAG;EAClC,YAAY,IAAI,KAAK,OAAO,UAAU;EACtC,OAAO;CACT,CAAC,CACH;CACA,IAAI,aAAa,KAAA,GAAW,OAAO,QAAQ,QAAQ,QAAQ;AAC7D,CAAC;;;;;;;;AASH,MAAM,mBACJ,QACA,SACA,aACA,KACA,SAEA,MAAM,QAAQ,SAAS,aAAa,KAAK,IAAI,CAAC,CAAC,KAC7C,OAAO,OAAO,UACZ,OAAO,WAAW,oEAAoE;CACpF;CACA;CACA;AACF,CAAC,CACH,CACF;;;;;;;;AASF,MAAa,YAAY,QAAsB,YAC7C,OAAO,IAAI,aAAa;CACtB,MAAM,OAAO,OAAO,UAAU,KAAK,CAAC;CACpC,MAAM,8BAAc,IAAI,IAAoB;CAC5C,MAAM,QAA+B,KAAK,SACxC,UAAU,WAAW,MAAM,MAAM,QAAQ,SAAS,aAAa,KAAK,IAAI,CAAC;CAC3E,OAAO,EAAE,KAAK;AAChB,CAAC;;;;;;;;;;;AAYH,MAAa,YACX,QACA,SACA,aAEA,OAAO,IAAI,aAAa;CACtB,MAAM,QAAQ,OAAO,OAAO;CAC5B,MAAM,OAAO,OAAO,UAAU,KAAK,CAAC;CACpC,MAAM,8BAAc,IAAI,IAAoB;CAC5C,MAAM,0BAAU,IAAI,IAAmB;CAEvC,MAAM,YAAY,QAChB,OAAO,MAAM,QAAQ,CAAC,CAAC,KACrB,OAAO,QACL,UAAU,WACR,MACA,OAAO,IAAI,aAAa;EACtB,MAAM,QAAQ,QAAQ,IAAI,GAAG;EAC7B,IAAI,UAAU,KAAA,KAAa,CAAC,MAAM,OAAO;GACvC,QAAQ,OAAO,GAAG;GAClB;EACF;EACA,MAAM,OAAO,MAAM;EACnB,QAAQ,OAAO,GAAG;EAClB,OAAO,gBAAgB,QAAQ,SAAS,aAAa,KAAK,IAAI;CAChE,CAAC,CACH,CACF,CACF;CAEF,MAAM,QAA+B,KAAK,SACxC,UAAU,WACR,MACA,OAAO,IAAI,aAAa;EACtB,IAAI,QAAQ,QAAQ,IAAI,GAAG;EAC3B,IAAI,UAAU,KAAA,GAAW;GAEvB,QAAQ;IAAE,YAAY;IAAM,OAAO;IAAO,OAAO,KAAA;GAAU;GAC3D,QAAQ,IAAI,KAAK,KAAK;GACtB,OAAO,MAAM,QAAQ,SAAS,aAAa,KAAK,IAAI;EACtD,OAAO;GACL,IAAI,MAAM,UAAU,KAAA,GAAW,OAAO,MAAM,UAAU,MAAM,KAAK;GACjE,MAAM,aAAa;GACnB,MAAM,QAAQ;EAChB;EACA,MAAM,QAAQ,OAAO,OAAO,OAAO,SAAS,GAAG,GAAG,KAAK;CACzD,CAAC,CACH;CAEF,OAAO,EAAE,KAAK;AAChB,CAAC;;;;;;;;AASH,MAAa,YACX,QACA,SACA,aAEA,OAAO,IAAI,aAAa;CACtB,MAAM,QAAQ,OAAO,OAAO;CAC5B,MAAM,OAAO,OAAO,UAAU,KAAK,CAAC;CACpC,MAAM,8BAAc,IAAI,IAAoB;CAC5C,MAAM,0BAAU,IAAI,IAAmB;CAEvC,MAAM,QAAQ,QACZ,OAAO,MAAM,QAAQ,CAAC,CAAC,KACrB,OAAO,QACL,UAAU,WACR,MACA,OAAO,IAAI,aAAa;EACtB,MAAM,QAAQ,QAAQ,IAAI,GAAG;EAC7B,IAAI,UAAU,KAAA,GAAW;EACzB,IAAI,CAAC,MAAM,OAAO;GAChB,QAAQ,OAAO,GAAG;GAClB;EACF;EACA,MAAM,QAAQ;EACd,MAAM,OAAO,MAAM;EACnB,OAAO,gBAAgB,QAAQ,SAAS,aAAa,KAAK,IAAI;EAC9D,MAAM,QAAQ,OAAO,OAAO,OAAO,KAAK,GAAG,GAAG,KAAK;CACrD,CAAC,CACH,CACF,CACF;CAEF,MAAM,QAA+B,KAAK,SACxC,UAAU,WACR,MACA,OAAO,IAAI,aAAa;EACtB,MAAM,QAAQ,QAAQ,IAAI,GAAG;EAC7B,IAAI,UAAU,KAAA,GAAW;GAEvB,MAAM,UAAiB;IAAE,YAAY;IAAM,OAAO;IAAO,OAAO,KAAA;GAAU;GAC1E,QAAQ,IAAI,KAAK,OAAO;GACxB,OAAO,MAAM,QAAQ,SAAS,aAAa,KAAK,IAAI;GACpD,QAAQ,QAAQ,OAAO,OAAO,OAAO,KAAK,GAAG,GAAG,KAAK;GACrD;EACF;EAEA,MAAM,aAAa;EACnB,MAAM,QAAQ;CAChB,CAAC,CACH;CAEF,OAAO,EAAE,KAAK;AAChB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACjSH,MAAa,sBAAsB,QAAQ,QACzC,8CACF;;AAGA,MAAaC,UAAQ,QAAsB,WAA6C;CACtF,eAAe,OAAO;CACtB,SAAS,MAAM;CACf,QAAQ,MAAM;CACd,aAAa,MAAM;CACnB,QAAQ,OAAO;AACjB;;AAGA,MAAa,eACX,OAAO,IAAI,aAAa;CACtB,MAAM,SAAS,OAAO;CACtB,MAAM,QAAQ,OAAO;CACrB,OAAOA,OAAK,QAAQ,KAAK;AAC3B,CAAC;;AAGH,MAAaC,UACX,MAAM,OAAO,mBAAmB,CAAC,CAAC,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACnBhD,MAAa,aAAoB;CAAE,OAAO,CAAC;CAAG,SAAS,CAAC;AAAE;;AAc1D,MAAa,aAAa,SAA+C;CACvE,MAAM,sBAAM,IAAI,IAAiB;CACjC,KAAK,MAAM,OAAO,MAAM,IAAI,IAAI,IAAI,IAAI,GAAG;CAC3C,OAAO;AACT;;;;;;;AAQA,MAAa,QACX,UACA,SACgE;CAChE,MAAM,QAAoB,CAAC;CAC3B,MAAM,UAAsB,CAAC;CAC7B,MAAM,wBAAQ,IAAI,IAAiB;CACnC,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,IAAI,IAAI,IAAI,GAAG;EACrB,MAAM,QAAQ,SAAS,IAAI,IAAI,EAAE;EACjC,IAAI,UAAU,KAAA,GAAW,MAAM,KAAK,GAAG;OAClC,IAAI,UAAU,OAAOC,YAAiB,MAAM,KAAK,MAAMA,YAAiB,IAAI,KAAK,GAAG;GACvF,QAAQ,KAAK,KAAK;GAClB,MAAM,KAAK,GAAG;EAChB;CACF;CACA,KAAK,MAAM,CAAC,IAAI,UAAU,UACxB,IAAI,CAAC,MAAM,IAAI,EAAE,GAAG,QAAQ,KAAK,KAAK;CAExC,OAAO;EAAE,OAAO;GAAE;GAAO;EAAQ;EAAG;CAAM;AAC5C;;AAGA,MAAa,cAAc,QAA0B,UAAuB;CAC1E,KAAK,MAAM,OAAO,MAAM,SAAS,OAAO,OAAO,IAAI,EAAE;CACrD,KAAK,MAAM,OAAO,MAAM,OAAO,OAAO,IAAI,IAAI,IAAI,GAAG;AACvD;;;;;;;;;;;;AAaA,MAAa,oBACX,OACA,UACU;CACV,MAAM,QAAoB,CAAC;CAC3B,MAAM,UAAsB,CAAC;CAC7B,KAAK,MAAM,UAAU,OACnB,QAAQ,OAAO,MAAf;EACE,KAAK;GACH,KAAK,MAAM,OAAO,MAAM,OAAO,GAAG,QAAQ,KAAK,GAAG;GAClD,MAAM,MAAM;GACZ;EACF,KAAK;GACH,MAAM,KAAK,OAAO,GAAG;GACrB,MAAM,IAAI,OAAO,IAAI,IAAI,OAAO,GAAG;GACnC;EACF,KAAK;GACH,QAAQ,KAAK,OAAO,QAAQ;GAC5B,MAAM,KAAK,OAAO,GAAG;GACrB,MAAM,IAAI,OAAO,IAAI,IAAI,OAAO,GAAG;GACnC;EACF,KAAK;GACH,QAAQ,KAAK,OAAO,QAAQ;GAC5B,MAAM,OAAO,OAAO,EAAE;CAI1B;CAEF,OAAO;EAAE;EAAO;CAAQ;AAC1B;;AAGA,MAAa,UAAU,WACrB,CAAC,GAAG,OAAO,OAAO,CAAC,CAAC,CAAC,UAAU,GAAG,MAAMC,YAAsB,EAAE,IAAI,EAAE,EAAE,CAAC;;;;;;;;AAgB3E,MAAa,cAAc,eAAsD,EAC/E,OAAO,WAAW;CAChB,OAAO,MAAM,MAAM,QAAQ,QAAQ,UAAU,IAAI,KAAK,CAAC;CACvD,SAAS,MAAM,QAAQ,QAAQ,QAAQ,UAAU,IAAI,KAAK,CAAC;AAC7D,GACF;;AAGA,MAAa,qBACX,MACA,cACqB,UAAU,KAAK,QAAQ,QAAQ,UAAU,IAAI,KAAK,CAAC,CAAC;;;;;;;AAQ3E,MAAa,WAAW,OAA8C,EACpE,OAAO,WAAW;CAChB,OAAO,MAAM,MAAM,KAAK,SAAS;EAAE,IAAI,IAAI;EAAI,OAAO,EAAE,IAAI,KAAK;CAAE,EAAE;CACrE,SAAS,MAAM,QAAQ,KAAK,SAAS;EAAE,IAAI,IAAI;EAAI,OAAO,EAAE,IAAI,KAAK;CAAE,EAAE;AAC3E,GACF;;AAGA,MAAa,kBACX,MACA,MACqB,UAAU,KAAK,KAAK,SAAS;CAAE,IAAI,IAAI;CAAI,OAAO,EAAE,IAAI,KAAK;AAAE,EAAE,CAAC;;;;;;;;AASzF,MAAa,qBAA+B;CAC1C,MAAM,yBAAS,IAAI,IAAwD;CAC3E,OAAO,EACL,OAAO,UAAU;EACf,MAAM,QAAoB,CAAC;EAC3B,MAAM,UAAsB,CAAC;EAC7B,KAAK,MAAM,OAAO,MAAM,SAAS;GAC/B,MAAM,MAAMC,cAAmB,IAAI,KAAK;GACxC,MAAM,QAAQ,OAAO,IAAI,GAAG;GAC5B,IAAI,UAAU,KAAA,GAAW;GACzB,MAAM,SAAS;GACf,IAAI,MAAM,UAAU,GAAG;IACrB,OAAO,OAAO,GAAG;IACjB,QAAQ,KAAK;KAAE,IAAI;KAAK,OAAO,MAAM;IAAM,CAAC;GAC9C;EACF;EACA,KAAK,MAAM,OAAO,MAAM,OAAO;GAC7B,MAAM,MAAMA,cAAmB,IAAI,KAAK;GACxC,MAAM,QAAQ,OAAO,IAAI,GAAG;GAC5B,IAAI,UAAU,KAAA,GAAW;IACvB,OAAO,IAAI,KAAK;KAAE,OAAO;KAAG,OAAO,IAAI;IAAM,CAAC;IAC9C,MAAM,KAAK;KAAE,IAAI;KAAK,OAAO,IAAI;IAAM,CAAC;GAC1C,OACE,MAAM,SAAS;EAEnB;EACA,OAAO;GAAE;GAAO;EAAQ;CAC1B,EACF;AACF;;AAGA,MAAa,uBAAuB,SAA+C;CACjF,MAAM,yBAAS,IAAI,IAAiB;CACpC,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,MAAMA,cAAmB,IAAI,KAAK;EACxC,IAAI,CAAC,OAAO,IAAI,GAAG,GAAG,OAAO,IAAI,KAAK;GAAE,IAAI;GAAK,OAAO,IAAI;EAAM,CAAC;CACrE;CACA,OAAO;AACT;;;;;;;;;AAUA,MAAa,eAAe,QAA8C;CACxE,MAAM,yBAAS,IAAI,IAAkC;CACrD,MAAM,0BAAU,IAAI,IAAoB;CACxC,MAAM,0BAAU,IAAI,IAAiB;CAErC,MAAM,YAAY,aAA0B;EAI1C,OAAO;GAAE,IAAI;GAAU,OAAO;IAAE,KAAK;IAAU,MAHlC,CAAC,GAAI,OAAO,IAAI,QAAQ,CAAC,EAAE,QAAQ,KAAK,CAAC,CAAE,CAAC,CACtD,UAAU,CAAC,IAAI,CAAC,OAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAE,CAAC,CACpD,KAAK,GAAG,WAAW,KAC4B;GAAE;EAAE;CACxD;CAEA,OAAO,EACL,OAAO,UAAU;EACf,MAAM,0BAAU,IAAI,IAAY;EAChC,KAAK,MAAM,OAAO,MAAM,SAAS;GAC/B,MAAM,WAAW,QAAQ,IAAI,IAAI,EAAE;GACnC,IAAI,aAAa,KAAA,GAAW;GAC5B,MAAM,UAAU,OAAO,IAAI,QAAQ;GACnC,SAAS,OAAO,IAAI,EAAE;GACtB,QAAQ,OAAO,IAAI,EAAE;GACrB,IAAI,SAAS,SAAS,GAAG,OAAO,OAAO,QAAQ;GAC/C,QAAQ,IAAI,QAAQ;EACtB;EACA,KAAK,MAAM,OAAO,MAAM,OAAO;GAC7B,MAAM,WAAW,IAAI,IAAI,KAAK;GAC9B,IAAI,UAAU,OAAO,IAAI,QAAQ;GACjC,IAAI,YAAY,KAAA,GAAW;IACzB,0BAAU,IAAI,IAAI;IAClB,OAAO,IAAI,UAAU,OAAO;GAC9B;GACA,QAAQ,IAAI,IAAI,IAAI,IAAI,KAAK;GAC7B,QAAQ,IAAI,IAAI,IAAI,QAAQ;GAC5B,QAAQ,IAAI,QAAQ;EACtB;EACA,MAAM,QAAoB,CAAC;EAC3B,MAAM,UAAsB,CAAC;EAC7B,KAAK,MAAM,YAAY,SAAS;GAC9B,MAAM,WAAW,QAAQ,IAAI,QAAQ;GACrC,IAAI,aAAa,KAAA,GAAW,QAAQ,KAAK,QAAQ;GACjD,IAAI,OAAO,IAAI,QAAQ,GAAG;IACxB,MAAM,OAAO,SAAS,QAAQ;IAC9B,MAAM,KAAK,IAAI;IACf,QAAQ,IAAI,UAAU,IAAI;GAC5B,OACE,QAAQ,OAAO,QAAQ;EAE3B;EACA,OAAO;GAAE;GAAO;EAAQ;CAC1B,EACF;AACF;;AASA,MAAa,sBACX,MACA,QACqB;CACrB,MAAM,yBAAS,IAAI,IAAsC;CACzD,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,WAAW,IAAI,IAAI,KAAK;EAC9B,MAAM,SAAS,OAAO,IAAI,QAAQ,KAAK,CAAC;EACxC,OAAO,KAAK,CAAC,IAAI,IAAI,IAAI,KAAK,CAAC;EAC/B,OAAO,IAAI,UAAU,MAAM;CAC7B;CACA,MAAM,yBAAS,IAAI,IAAiB;CACpC,KAAK,MAAM,CAAC,UAAU,WAAW,QAAQ;EACvC,MAAM,UAAU,OACb,UAAU,CAAC,IAAI,CAAC,OAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAE,CAAC,CACpD,KAAK,GAAG,WAAW,KAAK;EAC3B,OAAO,IAAI,UAAU;GAAE,IAAI;GAAU,OAAO;IAAE,KAAK;IAAU,MAAM;GAAQ;EAAE,CAAC;CAChF;CACA,OAAO;AACT;AAmBA,MAAM,MAAM;AACZ,MAAM,kBAA+B,MAAM,WAAW;CAAE;CAAM;AAAM;;AAGpE,MAAM,WAAW,UACf,UAAU,QAAQ,UAAU,KAAA,IAAY,KAAA,IAAYA,cAAmB,KAAK;;AAiB9E,MAAa,YAAY,YAAuC;CAC9D,MAAM,UAAU,QAAQ,WAAW;CACnC,MAAM,2BAAW,IAAI,IAAiB;CACtC,MAAM,4BAAY,IAAI,IAAiB;CACvC,MAAM,6BAAa,IAAI,IAAkC;CACzD,MAAM,4BAAY,IAAI,IAAyB;CAC/C,MAAM,+BAAe,IAAI,IAA8B;CAEvD,MAAM,kBAAkB,WAAqC;EAC3D,MAAM,sBAAM,IAAI,IAAiB;EACjC,MAAM,OAAO,SAAS,IAAI,MAAM;EAChC,IAAI,SAAS,KAAA,GAAW,OAAO;EAC/B,MAAM,MAAM,QAAQ,QAAQ,QAAQ,KAAK,KAAK,CAAC;EAC/C,MAAM,SAAS,QAAQ,KAAA,IAAY,KAAA,IAAY,WAAW,IAAI,GAAG;EACjE,IAAI,WAAW,KAAA,KAAa,OAAO,OAAO,GACxC,KAAK,MAAM,CAAC,SAAS,eAAe,QAAQ;GAC1C,MAAM,KAAK,GAAG,SAAS,MAAM;GAC7B,IAAI,IAAI,IAAI;IAAE;IAAI,OAAO,QAAQ,KAAK,OAAO,UAAU;GAAE,CAAC;EAC5D;OACK,IAAI,QAAQ,SAAS,QAAQ;GAClC,MAAM,KAAK,GAAG,SAAS;GACvB,IAAI,IAAI,IAAI;IAAE;IAAI,OAAO,QAAQ,KAAK,OAAO,IAAI;GAAE,CAAC;EACtD;EACA,OAAO;CACT;;CAGA,MAAM,aAAa,QAAgB,OAAmB,YAA8B;EAClF,MAAM,WAAW,aAAa,IAAI,MAAM,qBAAK,IAAI,IAAiB;EAClE,MAAM,OAAO,eAAe,MAAM;EAClC,KAAK,MAAM,CAAC,IAAI,QAAQ,UACtB,IAAI,CAAC,KAAK,IAAI,EAAE,GAAG,QAAQ,KAAK,GAAG;EAErC,KAAK,MAAM,CAAC,IAAI,QAAQ,MAAM;GAC5B,MAAM,QAAQ,SAAS,IAAI,EAAE;GAC7B,IAAI,UAAU,KAAA,GAAW,MAAM,KAAK,GAAG;QAClC,IAAIF,YAAiB,MAAM,KAAK,MAAMA,YAAiB,IAAI,KAAK,GAAG;IACtE,QAAQ,KAAK,KAAK;IAClB,MAAM,KAAK,GAAG;GAChB;EACF;EACA,IAAI,KAAK,OAAO,GAAG,aAAa,IAAI,QAAQ,IAAI;OAC3C,aAAa,OAAO,MAAM;CACjC;CAEA,MAAM,aAAa,QAAmB;EACpC,SAAS,IAAI,IAAI,IAAI,GAAG;EACxB,MAAM,MAAM,QAAQ,QAAQ,QAAQ,IAAI,KAAK,CAAC;EAC9C,IAAI,QAAQ,KAAA,GAAW;EACvB,MAAM,MAAM,UAAU,IAAI,GAAG,qBAAK,IAAI,IAAY;EAClD,IAAI,IAAI,IAAI,EAAE;EACd,UAAU,IAAI,KAAK,GAAG;CACxB;CAEA,MAAM,eAAe,QAAmB;EACtC,SAAS,OAAO,IAAI,EAAE;EACtB,MAAM,MAAM,QAAQ,QAAQ,QAAQ,IAAI,KAAK,CAAC;EAC9C,IAAI,QAAQ,KAAA,GAAW;EACvB,MAAM,MAAM,UAAU,IAAI,GAAG;EAC7B,IAAI,QAAQ,KAAA,GAAW;EACvB,IAAI,OAAO,IAAI,EAAE;EACjB,IAAI,IAAI,SAAS,GAAG,UAAU,OAAO,GAAG;CAC1C;CAEA,MAAM,YAAY,KAAU,SAA4B;EACtD,MAAM,MAAM,QAAQ,QAAQ,SAAS,IAAI,KAAK,CAAC;EAC/C,UAAU,IAAI,IAAI,IAAI,GAAG;EACzB,IAAI,QAAQ,KAAA,GAAW;EACvB,MAAM,SAAS,WAAW,IAAI,GAAG,qBAAK,IAAI,IAAqB;EAC/D,OAAO,IAAI,IAAI,IAAI,IAAI,KAAK;EAC5B,WAAW,IAAI,KAAK,MAAM;EAC1B,KAAK,IAAI,GAAG;CACd;CAEA,MAAM,eAAe,KAAU,SAA4B;EACzD,MAAM,MAAM,QAAQ,QAAQ,SAAS,IAAI,KAAK,CAAC;EAC/C,UAAU,OAAO,IAAI,EAAE;EACvB,IAAI,QAAQ,KAAA,GAAW;EACvB,MAAM,SAAS,WAAW,IAAI,GAAG;EACjC,IAAI,WAAW,KAAA,GAAW;EAC1B,OAAO,OAAO,IAAI,EAAE;EACpB,IAAI,OAAO,SAAS,GAAG,WAAW,OAAO,GAAG;EAC5C,KAAK,IAAI,GAAG;CACd;CAEA,OAAO;EACL,WAAW,UAAU;GACnB,MAAM,2BAAW,IAAI,IAAY;GACjC,KAAK,MAAM,OAAO,MAAM,SAAS;IAC/B,YAAY,GAAG;IACf,SAAS,IAAI,IAAI,EAAE;GACrB;GACA,KAAK,MAAM,OAAO,MAAM,OAAO;IAC7B,MAAM,QAAQ,SAAS,IAAI,IAAI,EAAE;IACjC,IAAI,UAAU,KAAA,GAAW,YAAY,KAAK;IAC1C,UAAU,GAAG;IACb,SAAS,IAAI,IAAI,EAAE;GACrB;GACA,MAAM,QAAoB,CAAC;GAC3B,MAAM,UAAsB,CAAC;GAC7B,KAAK,MAAM,UAAU,UAAU,UAAU,QAAQ,OAAO,OAAO;GAC/D,OAAO;IAAE;IAAO;GAAQ;EAC1B;EACA,YAAY,UAAU;GACpB,MAAM,uBAAO,IAAI,IAAY;GAC7B,KAAK,MAAM,OAAO,MAAM,SAAS,YAAY,KAAK,IAAI;GACtD,KAAK,MAAM,OAAO,MAAM,OAAO;IAC7B,MAAM,QAAQ,UAAU,IAAI,IAAI,EAAE;IAClC,IAAI,UAAU,KAAA,GAAW,YAAY,OAAO,IAAI;IAChD,SAAS,KAAK,IAAI;GACpB;GACA,MAAM,gCAAgB,IAAI,IAAY;GACtC,KAAK,MAAM,OAAO,MAAM;IACtB,MAAM,MAAM,UAAU,IAAI,GAAG;IAC7B,IAAI,QAAQ,KAAA,GAAW,KAAK,MAAM,MAAM,KAAK,cAAc,IAAI,EAAE;GACnE;GACA,MAAM,QAAoB,CAAC;GAC3B,MAAM,UAAsB,CAAC;GAC7B,KAAK,MAAM,UAAU,eAAe,UAAU,QAAQ,OAAO,OAAO;GACpE,OAAO;IAAE;IAAO;GAAQ;EAC1B;CACF;AACF;;AAGA,MAAa,mBACX,MACA,OACA,YACqB;CACrB,MAAM,UAAU,QAAQ,WAAW;CACnC,MAAM,6BAAa,IAAI,IAAwB;CAC/C,KAAK,MAAM,OAAO,OAAO;EACvB,MAAM,MAAM,QAAQ,QAAQ,SAAS,IAAI,KAAK,CAAC;EAC/C,IAAI,QAAQ,KAAA,GAAW;EACvB,MAAM,SAAS,WAAW,IAAI,GAAG,KAAK,CAAC;EACvC,OAAO,KAAK,GAAG;EACf,WAAW,IAAI,KAAK,MAAM;CAC5B;CACA,MAAM,yBAAS,IAAI,IAAiB;CACpC,KAAK,MAAM,WAAW,MAAM;EAC1B,MAAM,MAAM,QAAQ,QAAQ,QAAQ,QAAQ,KAAK,CAAC;EAClD,MAAM,UAAU,QAAQ,KAAA,IAAY,KAAA,IAAY,WAAW,IAAI,GAAG;EAClE,IAAI,YAAY,KAAA,KAAa,IAAI,wBAAwB,OAAO,GAC9D,KAAK,MAAM,YAAY,SAAS;GAC9B,MAAM,KAAK,GAAG,QAAQ,KAAK,MAAM,SAAS;GAC1C,OAAO,IAAI,IAAI;IAAE;IAAI,OAAO,QAAQ,QAAQ,OAAO,SAAS,KAAK;GAAE,CAAC;EACtE;OACK,IAAI,QAAQ,SAAS,QAAQ;GAClC,MAAM,KAAK,GAAG,QAAQ,KAAK;GAC3B,OAAO,IAAI,IAAI;IAAE;IAAI,OAAO,QAAQ,QAAQ,OAAO,IAAI;GAAE,CAAC;EAC5D;CACF;CACA,OAAO;AACT;;AAWA,MAAM,gBACJ,SACA,UAEAG,OAAY;CAAE,YAAY;CAAI;CAAS,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;AAAG,CAAC;;;;;;;;;AAUpF,MAAa,qBACX,SACA,UACkB;CAClB,MAAM,SAAS,aAAa,SAAS,KAAK;CAC1C,IAAI,OAAOC,OAAc,QAAQ,CAAC,CAAC;CACnC,OAAO,EACL,OAAO,UAAU;EACf,KAAK,MAAM,OAAO,MAAM,SAAS,OAAOC,IAAa,MAAM,IAAI,EAAE;EACjE,KAAK,MAAM,OAAO,MAAM,OAAO,OAAOC,IAAa,MAAM;GAAE,IAAI,IAAI;GAAI,OAAO,IAAI;EAAM,CAAC;EACzF,OAAOC,OAAgB,IAAI,CAAC,CAAC,KAAK,SAAS;GAAE,IAAI,IAAI;GAAI,OAAO,IAAI;EAAM,EAAE;CAC9E,EACF;AACF;;AAGA,MAAa,4BACX,MACA,SACA,UAEAC,MAAa,MAAM,aAAa,SAAS,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS;CAAE,IAAI,IAAI;CAAI,OAAO,IAAI;AAAM,EAAE;;;;;;;;;;;;;AClflG,MAAM,UAAU,OAAO,IAAI,yCAAyC;AAMpE,MAAM,eACJ,OACA,YACc,OAAO,OAAO,OAAO,GAAG,UAAU,QAAQ,CAA2B;AAErF,MAAM,kBAAqB,WACzB,WAAW;AAEb,MAAM,aACJ,WAEA,eAAe,MAAM,IAAI,OAAO,WAAW,KAAA;AAI7C,MAAM,WAAW,GAAQ,MACvB,MAAM,KAAM,EAAE,OAAO,EAAE,MAAMC,YAAiB,EAAE,KAAK,MAAMA,YAAiB,EAAE,KAAK;;;;;;;AAQrF,MAAM,YAAY,GAAuB,MACvC,EAAE,WAAW,EAAE,UACf,EAAE,OAAO,KAAK,MAAM;CAClB,MAAM,QAAQ,EAAE;CAChB,OAAO,UAAU,KAAA,KAAa,QAAQ,KAAK,KAAK;AAClD,CAAC;;;;;;;;;;AAaH,MAAM,iBAAoB,WAA2D;CACnF,MAAM,UAAU,UAAU,MAAM;CAChC,OAAO,YAAY,KAAA,IACf,QAAQ,KACN,OAAO,+BACC,IAAI,IAAiB,IAC1B,OAAO,UAAU,CAAC,OAAO,CAACC,iBAA6B,OAAO,KAAK,CAAC,CAAC,CACxE,CACF,IACA,OAAO,KACL,OAAO,+BACC,IAAI,IAAiB,IAC1B,MAAM,SAAS;EACd,MAAM,EAAE,OAAO,UAAUC,KAAiB,MAAM,IAAI;EACpD,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;CACxB,CACF,CACF;AACN;;;;;;;;AASA,MAAM,YAAe,QAAmB,iBACtC,cAAc,MAAM,CAAC,CAAC,KACpB,OAAO,gBACE;CAAE,UAAU,aAAa;CAAG,wBAAQ,IAAI,IAAiB;AAAE,KACjE,OAAO,UAAU;CAChB,WAAuB,MAAM,QAAQ,MAAM,SAAS,KAAK,KAAK,CAAC;CAC/D,OAAO,CAAC,OAAO,CAACC,OAAmB,MAAM,MAAM,CAAC,CAAC;AACnD,CACF,GACA,OAAO,YAAY,QAAQ,CAC7B;;;;;;AAOF,MAAa,UAAa,QAAmB,cAC3C,SAAS,cAAcC,WAAuB,SAAS,CAAC;;AAG1D,MAAa,OAAU,QAAmB,MACxC,SAAS,cAAcC,QAAoB,CAAC,CAAC;;AAG/C,MAAa,SAAS;;AAGtB,MAAa,YAAe,WAC1B,SAAS,cAAcC,aAAyB,CAAC;;;;;;AAOnD,MAAa,WAAc,QAAmB,QAC5C,SAAS,cAAcC,YAAwB,GAAG,CAAC;;;;;;;;AAcrD,MAAa,QACX,MACA,OACA,YACkB;CAQlB,OAJI,OAAO,MACT,cAAc,IAAI,CAAC,CAAC,KAAK,OAAO,KAAK,WAAW;EAAE,MAAM;EAAiB;CAAM,EAAE,CAAC,GAClF,cAAc,KAAK,CAAC,CAAC,KAAK,OAAO,KAAK,WAAW;EAAE,MAAM;EAAkB;CAAM,EAAE,CAAC,CAE1E,CAAC,CAAC,KACZ,OAAO,gBACE;EACL,UAAUC,SAAqB,OAAO;EACtC,wBAAQ,IAAI,IAAiB;CAC/B,KACC,OAAO,UAAU;EAChB,MAAM,WACJ,MAAM,SAAS,SACX,MAAM,SAAS,SAAS,MAAM,KAAK,IACnC,MAAM,SAAS,UAAU,MAAM,KAAK;EAC1C,WAAuB,MAAM,QAAQ,QAAQ;EAC7C,OAAO,CAAC,OAAO,CAACL,OAAmB,MAAM,MAAM,CAAC,CAAC;CACnD,CACF,GACA,OAAO,YAAY,QAAQ,CAC7B;AACF;;;;;;;AAgBA,MAAa,iBAAoB,QAAmB,YAClD,cAAc,MAAM,CAAC,CAAC,KACpB,OAAO,eACCM,kBAA8B,QAAQ,SAAS,QAAQ,KAAK,IACjE,QAAQ,UAAU,CAAC,QAAQ,CAAC,OAAO,KAAK,KAAK,CAAC,CAAC,CAClD,GACA,OAAO,YAAY,QAAQ,CAC7B;;;;;;AAeF,MAAa,QAAW,WAAmD,KAAK,KAAK,MAAM;;;;;;;;;;AAa3F,MAAM,oBAAuB,YAC3B,QAAQ,KACN,OAAO,gBACE;CAAE,uBAAO,IAAI,IAAiB;CAAG,wBAAQ,IAAI,IAAiB;AAAE,KACtE,OAAO,UAAU;CAChB,WAAuB,MAAM,QAAQR,iBAA6B,MAAM,OAAO,KAAK,CAAC;CACrF,OAAO,CAAC,OAAO,CAACE,OAAmB,MAAM,MAAM,CAAC,CAAC;AACnD,CACF,GACA,OAAO,YAAY,QAAQ,CAC7B;;;;;;;;;;;;;;;;AAiBF,MAAa,YACX,eACA,MACA,WAEA,OAAO,IAAI,aAAa;CACtB,MAAM,SAAS,OAAO,cAAc,QAAQ,MAAM;CAClD,OAAO,OAAO,mBAAmB,OAAO,OAAO;CAC/C,IAAI,EAAE,oBAAoB,OAAO,OAAO,KAAK,QAAQ,MAAM;CAC3D,MAAM,UAAU,KAAK,eAAe,QAAQ,EAAE,gBAAgB,KAAK,CAAC;CACpE,OAAO,YAAY,iBAAiB,OAAO,GAAG,OAAO;AACvD,CAAC;;;;AC1RH,MAAaO,UAAW,WAA+C;CACrE,MAAM,wBAAQ,IAAI,IAA2C;CAC7D,OAAO,EACL,OAAO,WAAW;EAChB,MAAM,MAAMC,KAAY,MAAM;EAC9B,MAAM,WAAW,MAAM,IAAI,GAAG;EAC9B,IAAI,aAAa,KAAA,GAAW,OAAO;EACnC,MAAM,UAAU,KAAK,KAAK,OAAO,QAAQ,MAAM,CAAC;EAChD,MAAM,IAAI,KAAK,OAAO;EACtB,OAAO;CACT,EACF;AACF;;;;;;;;;ACkGA,MAAa,aACX,gBACgB;CAChB,MAAM,UAAU,KAAK,QAAQ,WAAW;CAExC,MAAM,8BAAc,IAAI,IAAwC;CAChE,MAAM,aAAa,WAAsD;EACvE,MAAM,MAAMC,KAAY,MAAM;EAC9B,MAAM,WAAW,YAAY,IAAI,GAAG;EACpC,IAAI,aAAa,KAAA,GAAW,OAAO;EACnC,MAAM,OAAO,QAAQ,KACnB,OAAO,OAAO,OAAO,IAAI,eAAe,WAAW,OAAO,QAAQ,MAAM,CAAC,CAAC,CAC5E;EACA,YAAY,IAAI,KAAK,IAAI;EACzB,OAAO;CACT;CAEA,MAAM,+BAAe,IAAI,IAAyC;CAClE,MAAM,cAAc,MAAc,SAA+C;EAC/E,MAAM,MAAM,GAAG,KAAK,GAAGC,cAAmB,IAAI;EAC9C,MAAM,WAAW,aAAa,IAAI,GAAG;EACrC,IAAI,aAAa,KAAA,GAAW,OAAO;EACnC,MAAM,OAAO,QAAQ,KACnB,OAAO,OAAO,OAAO,IAAI,eAAe,WAAW,OAAO,aAAa,MAAM,IAAI,CAAC,CAAC,CACrF;EACA,aAAa,IAAI,KAAK,IAAI;EAC1B,OAAO;CACT;CAEA,MAAM,6BAAa,IAAI,IAAwC;CAC/D,MAAM,aACJ,QACA,QAC+B;EAC/B,MAAM,MAAM,GAAGD,KAAY,MAAM,EAAE,GAAGC,cAAmB,GAAG;EAC5D,MAAM,WAAW,WAAW,IAAI,GAAG;EACnC,IAAI,aAAa,KAAA,GAAW,OAAO;EACnC,MAAM,OAAO,QAAQ,KACnB,OAAO,OAAO,OAAO,IAAI,eAAe,WAAW,OAAO,iBAAiB,QAAQ,GAAG,CAAC,CAAC,CAC1F;EACA,WAAW,IAAI,KAAK,IAAI;EACxB,OAAO;CACT;CAEA,MAAM,oCAAoB,IAAI,IAA+C;CAC7E,MAAM,oBACJ,QACA,KACA,YACsC;EACtC,MAAM,MAAM,GAAGD,KAAY,MAAM,EAAE,GAAGC,cAAmB,GAAG,EAAE,GAAG;EACjE,MAAM,WAAW,kBAAkB,IAAI,GAAG;EAC1C,IAAI,aAAa,KAAA,GAAW,OAAO;EACnC,MAAM,OAAO,QAAQ,KACnB,OAAO,OACL,OAAO,IAAI,eAAe,WAAW,OAAO,wBAAwB,QAAQ,KAAK,OAAO,CAAC,CAC3F,CACF;EACA,kBAAkB,IAAI,KAAK,IAAI;EAC/B,OAAO;CACT;CAEA,MAAM,WAAW,QAAQ,IAAI,QAC3B,OAAO,QAAQ,eAAe,WAAW,OAAO,OAAO,IAAI,SAAS,IAAI,IAAI,CAAC,CAC/E;CAEA,MAAM,kBAAkB,QAAQ,IAAI,QAClC,OAAO,QAAQ,eAAe,WAC5B,OACG,cAAc,IAAI,SAAS,IAAI,IAAI,CAAC,CACpC,KAAK,OAAO,SAAS,WAAW,OAAO,YAAY,CAAC,CACzD,CACF;CAIA,MAAM,iBAAkD,QAAQ,KAC9D,OAAO,OAAO,OAAO,IAAI,eAAe,WAAW,OAAO,cAAc,CAAC,CAC3E;CAEA,MAAM,oCAAoB,IAAI,IAA2C;CACzE,MAAM,gBAAgB,YAAmD;EACvE,MAAM,WAAW,kBAAkB,IAAI,OAAO;EAC9C,IAAI,aAAa,KAAA,GAAW,OAAO;EACnC,MAAM,OAAO,KAAK,UAAU,iBAAiB,WAC3C,CAAC,GAAG,QAAQ,OAAO,MAAM,CAAC,CAAC,CACxB,QAAQ,UAAU,MAAM,YAAY,OAAO,CAAC,CAC5C,UAAU,GAAG,MAAM,EAAE,aAAa,EAAE,UAAU,CACnD;EACA,kBAAkB,IAAI,SAAS,IAAI;EACnC,OAAO;CACT;CAEA,OAAO;EACL;EACW;EACX;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC9LA,MAAaC,UAAe,UAAuD;CAGjF,MAAM,UAAU,eAAe,KAAK,KAAK;CAEzC,MAAM,OAAa,WAA+C,QAAQ,WAAW,MAAM;CAE3F,MAAM,WAAiB,WACrB,QAAQ,eAAe,MAAM;CAE/B,MAAM,aACJ,QACA,aAKiB;EACjB,MAAM,UAAU,OAAO,WAAW,SAAS,UACzC,OAAO,WAAW,SAAS,QAAQ,KAAK,CAAC,CAC3C;EAEA,MAAM,QAAQ,QAAQ,QACpB,QAAQ,KACN,OAAO,QAAQ,SACb,OAAO,WAAW;GAChB,IAAI,KAAK,UAAU,IAAI,GACrB,SAAS,SAAS;QACb,IAAI,KAAK,UAAU,IAAI,KAAK,SAAS,YAAY,KAAA,GAAW;IAEjE,MAAM,UAAU,MAAM,SAAS,KAAK,KAAK;IACzC,IAAI,OAAO,UAAU,OAAO,GAC1B,SAAS,QAAQ,QAAQ,QAAQ,KAAK;GAE1C;EACF,CAAC,CACH,CACF,CACF;EAEA,OAAO,EACL,mBAAmB;GACjB,QAAQ,QAAQ,MAAM,UAAU,KAAK,CAAC;EACxC,EACF;CACF;CAEA,OAAO;EACL;EACA;EACA;EACA;EACA,eAAe,QAAQ,QAAQ;CACjC;AACF;;;;;;;;ACrFA,MAAa,mBAIT,OAAO,IAAI,aAAa;CAC1B,MAAM,UAAU,OAAO,eAAe,OAAO,UAAmB,IAAI,QAAQ,OAAO,SAAS,GAAG,CAAC;CAChG,MAAM,SAAS,OAAO;CACtB,MAAM,WAAW,OAAO;CACxB,MAAM,QAAQ,UAAyB,aAA6C;EAClF,OAAO,YAAY,OAAO,OAAO,OAAO,QAAQ,UAAU,OAAO,CAAC;EAClE,WAAW,OAAO,UAAU,OAAO,CAAC,CAAC,KACnC,OAAO,KAAK,kBAAkB,EAAE,MAAM,OAAO,KAAK,YAAY,EAAE,EAAE,CACpE;CACF;CACA,OAAO;EAAE,MAAM,KAAK,UAAU,MAAM;EAAG,QAAQ,KAAK,QAAQ,QAAQ;CAAE;AACxE,CAAC;;;;AC6FD,MAAM,kBACJ,UACA,YACA,UACmC;CACnC,MAAM,WAAWC,gBAA2B,UAAU,UAAU;CAChE,OAAO,MAAM,MAAM,SAAS,CAAC,SAAS,IAAI,KAAK,IAAI,CAAC;AACtD;;AAGA,MAAM,kBAAkB,UACtB,MAAM,eAAe,KAAA,IACjB,KAAA,IACA;CACE,GAAG,MAAM,WAAW;CACpB,GAAI,MAAM,WAAW,OAAO,KAAK,MAAM,WAAW,QAAQ,KAAA,IACtD,EAAE,KAAK,MAAM,WAAW,IAAI,IAC5B,CAAC;AACP;;AAGN,MAAMC,aAAW,KAA0B,WAAwC;CACjF,MAAM,OAAO,IAAI,IAAI,GAAG;CACxB,KAAK,OAAO,MAAM;CAClB,OAAO;AACT;;AAGA,MAAM,cAAc,aAAgC;CAClD,eAAe,QAAQ,UAAU,iBAAiB;CAClD,eAAe,QAAQ,UAAU,iBAAiB;AACpD;;AAGA,MAAM,WAAW,UAAkB,cAAsB,GAAG,SAAS,GAAG;;;;;;AAaxE,MAAM,WAAW,YACf,QAAQ,aAAa,KAAA,IACjB,EAAE,WAAW,QAAQ,UAAU,IAC/B;CAAE,WAAW,QAAQ;CAAW,UAAU,QAAQ;AAAS;;AAGjE,MAAM,kBAAkB,OAAO,oBAAoBC,iBAAgC;;AAGnF,MAAM,mBAAmB,OAAO,oBAAoB,OAAO,OAAO,EAAE,UAAU,OAAO,OAAO,CAAC,CAAC;;;;;;AAO9F,MAAaC,SAAO,YAClB,OAAO,IAAI,aAAa;CACtB,MAAM,EAAE,YAAY;CACpB,MAAM,SAASC,QAAsB,QAAQ,MAAM;CACnD,MAAM,QAAQ,OAAO,QAAQ;CAC7B,MAAM,SAAS,OAAO,IAAI,qBAAK,IAAI,IAAoB,CAAC;CACxD,MAAM,WAAW,OAAO,IAAI,qBAAK,IAAI,IAAoB,CAAC;CAE1D,MAAM,QAAQC,OAAe,MAAM;CAEnC,MAAM,YAAY,OAAO,IAAI,KAAyB,KAAA,CAAS;CAC/D,MAAM,WAAW,OAAO,IAAI,aAAa;EACvC,MAAM,gBAAgB,OAAO,MAAM;EACnC,MAAM,aAAa,KAAK,UAAU,aAAa;EAC/C,IAAI,gBAAgB,OAAO,IAAI,IAAI,SAAS,IAAI;EAChD,OAAO,IAAI,IAAI,WAAW,UAAU;EACpC,OAAO,QAAQ,KAAK;GAAE,MAAM;GAAuB;EAAc,CAAC,CAAC,CAAC,KAAK,OAAO,MAAM;CACxF,CAAC;CAOD,MAAM,YAAY,OAAO,IAAI,KAAmC,MAAM;CACtE,MAAM,mBAA4D,OAAO,KAAK,KAC5E,OAAO,QACP,OAAO,QACL,IAAI,OAAO,YAAY,UACrB,UAAU,UAAW,CAAC,MAAM,SAAS,IAAe,CAAC,OAAO,MAAM,CACpE,CACF,GACA,OAAO,SAAS,UAAW,QAAQ,mBAAmB,OAAO,IAAK,CACpE;CACA,MAAM,oBAA6D,IAAI,OACrE,YACC,UAAW,UAAU,SAAU,CAAC,MAAM,SAAS,IAAe,CAAC,OAAO,OAAO,CAChF,CAAC,CAAC,KACA,OAAO,SAAS,YAAa,UAAU,OAAO,WAAW,gBAAgB,IAAI,OAAO,IAAK,GACzF,OAAO,MACT;CAEA,MAAM,SAAS,aACb,MAAM,kBAAkB,KACtB,OAAO,SAAS,QAAQ,IAAI,OAAO,WAAW,QAAQ,IAAI,IAAI,GAAG,CAAC,CAAC,IAAI,UAAU,GAAG,CAAC,CAAC,CACxF;CACF,MAAM,UAAU,aACd,IAAI,OAAO,WAAW,QAAQ;EAC5B,MAAM,OAAO,IAAI,IAAI,GAAG;EACxB,KAAK,OAAO,QAAQ;EACpB,OAAO;CACT,CAAC;CAEH,MAAM,aAAa,KAAa,SAC9B,QAAQ,KAAKC,aAA4B,KAAK,IAAI,CAAC;CACrD,MAAM,oBAAoB,KAAa,SACrC,QAAQ,KAAKC,cAA6B,KAAK,IAAI,CAAC;CACtD,MAAM,2BAA2B,WAC/B,QAAQ,KAAKC,qBAAoC,MAAM,CAAC;CAI1D,MAAM,wBAAuE,OAAO,QAClF,OAAO,cACT,CAAC,CAAC,KAAK,OAAO,IAAI,OAAO,gBAAgB,QAAQ,MAAM,CAAC,CAAC,CAAC;;;;;;;;;CAU1D,MAAM,WACJ,UACA,KACA,OASA,eAEA,OAAO,IAAI,aAAa;EACtB,MAAM,QAAQ,YAAY,QAAQ,KAAA;EAClC,MAAM,YAAY,OAAO,IAAI,IAAI,MAAM,EAAA,CAAG,IAAI,GAAG;EACjD,IAAI,aAAa,KAAA,GAAW;GAG1B,MAAM,QAAQ,SAAS,YAAY,QAAQ,KAAA,IAAY,aAAa,SAAS;GAC7E,OAAO,IAAI,OAAO,SAAS,QACzB,IAAI,IAAI,GAAG,CAAC,CAAC,IAAI,KAAK;IACpB,GAAG;IACH,SAAS,IAAI,IAAI,SAAS,OAAO,CAAC,CAAC,IAAI,QAAQ;IAC/C,YAAY,QAAQ,IAAI,IAAI,SAAS,UAAU,CAAC,CAAC,IAAI,QAAQ,IAAI,SAAS;IAC1E,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,YAAY,MAAM;GACrD,CAAC,CACH;GACA,OAAO,OAAO,SAAS;EACzB;EAIA,MAAM,EAAE,MAAM,UAAU,YAAY,OAAO;EAC3C,MAAM,QAAQ,OAAO,OAAO,WAAW,KAAK,KAAK,OAAO,MAAM,CAAC;EAC/D,OAAO,IAAI,OAAO,SAAS,QACzB,IAAI,IAAI,GAAG,CAAC,CAAC,IAAI,KAAK;GACpB,yBAAS,IAAI,IAAI,CAAC,QAAQ,CAAC;GAC3B,YAAY,IAAI,IAAI,QAAQ,CAAC,QAAQ,IAAI,CAAC,CAAC;GAC3C;GACA;GACA;GACA,GAAI,eAAe,KAAA,IAAY,CAAC,IAAI,EAAE,WAAW;EACnD,CAAC,CACH;EACA,OAAO;CACT,CAAC;;CAGH,MAAM,WAAW,UAAkB,QACjC,OAAO,IAAI,aAAa;EACtB,MAAM,SAAS,OAAO,IAAI,IAAI,MAAM,EAAA,CAAG,IAAI,GAAG;EAC9C,IAAI,UAAU,KAAA,KAAa,CAAC,MAAM,QAAQ,IAAI,QAAQ,GAAG;EACzD,MAAM,UAAUP,UAAQ,MAAM,SAAS,QAAQ;EAC/C,IAAI,QAAQ,OAAO,GAAG;GACpB,OAAO,IAAI,OAAO,SAAS,QACzB,IAAI,IAAI,GAAG,CAAC,CAAC,IAAI,KAAK;IACpB,GAAG;IACH;IACA,YAAYA,UAAQ,MAAM,YAAY,QAAQ;GAChD,CAAC,CACH;GACA;EACF;EACA,OAAO,MAAM,UAAU,MAAM,KAAK;EAClC,OAAO,MAAM,SAAS,KAAK,OAAO,MAAM;EACxC,OAAO,IAAI,OAAO,SAAS,QAAQ;GACjC,MAAM,OAAO,IAAI,IAAI,GAAG;GACxB,KAAK,OAAO,GAAG;GACf,OAAO;EACT,CAAC;EACD,OAAO;CACT,CAAC;CAEH,MAAM,mBAAmB,UAAkB,QAAuB,QAAiB;EACjF,MAAM,MAAMQ,KAAY,MAAM;EAC9B,OAAO,QACL,UACA,KACA,OAAO,IAAI,aAAa;GACtB,OAAO,MAAM,KAAK,KAAK,MAAM;GAC7B,OAAO,MACJ,KAAK,GAAG,CAAC,CACT,UAAU,MAAM,CAAC,CACjB,KAAK,OAAO,eAAe,MAAM,MAAM,GAAG,CAAC,CAAC;GAI/C,OAAO;GACP,OAAO;IAEL,MAAM,OAAO,WAAW,OAAO,QAAQ,MAAM,IAAI,SAAS,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,KAC9E,OAAO,MACT;IACA,UAAU,MACP,KAAK,GAAG,CAAC,CACT,YAAY,MAAM,CAAC,CACnB,KAAK,OAAO,QAAQ,OAAO,QAAQ,MAAM,MAAM,GAAG,CAAC,CAAC;IACvD,SAAS,OAAO,MAAM,MAAM,CAAC,CAAC,KAC5B,OAAO,SAAS,SAAS,UAAU,KAAK,IAAI,CAAC,GAC7C,OAAO,MACT;GACF;EACF,CAAC,GACD;GAAE,cAAc;IAAE,MAAM;IAAQ,OAAO,CAAC;GAAE;GAAG,GAAI,QAAQ,KAAA,IAAY,CAAC,IAAI,EAAE,IAAI;EAAG,CACrF;CACF;CAEA,MAAM,wBAAwB,UAAkB,MAAc,SAAkB;EAC9E,MAAM,MAAMC,SAAwB,MAAM,IAAI;EAC9C,OAAO,QACL,UACA,KACA,OAAO,IAAI,aAAa;GACtB,OAAO,OAAO,eAAe,MAAM,IAAI;GAGvC,OAAO,OAAO,KAAK,KAAK,OAAO,MAAM;GACrC,OAAO;IACL,MAAM,OAAO,WAAW,OAAO,aAAa,MAAM,IAAI,IAAI,SACxD,UAAU,KAAK,IAAI,CACrB,CAAC,CAAC,KAAK,OAAO,MAAM;IACpB,UAAU,OAAO,iBAAiB,MAAM,IAAI,CAAC,CAAC,KAAK,OAAO,MAAM;IAChE,SAAS,OAAO,WAAW,MAAM,IAAI,CAAC,CAAC,KACrC,OAAO,SAAS,SAAS,UAAU,KAAK,IAAI,CAAC,GAC7C,OAAO,MACT;GACF;EACF,CAAC,CACH;CACF;CAEA,MAAM,0BACJ,UACA,YACA,QACA,OACA,QACG;EACH,MAAM,MAAMC,WAA0B,YAAY,QAAQ,KAAK;EAC/D,MAAM,WAAW,QAAQ,YAAY,QAAQ,OAAO;EACpD,IAAI,aAAa,KAAA,GACf,OAAO,OAAO,WACZ,iFACF,CAAC,CAAC,KAAK,OAAO,QAAQ,iBAAiB,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,MAAM;EAEjE,OAAO,QACL,UACA,KACA,OAAO,IAAI,aAAa;GAItB,MAAM,aAAa,eAAe,UAAU,YAAY,KAAK;GAC7D,IAAI,eAAe,KAAA,GACjB,OAAO,OAAO,OAAO,KACnB,IAAI,WAAW;IACb,SAAS,oCAAoC,WAAW,kDAAkD,WAAW,KAAK;IAC1H,OAAO;GACT,CAAC,CACH;GAMF,MAAM,QAAQ,OAAO,MAAM,KAAK,OAAO,OAAO,KAAK;GACnD,OAAO,MAAM,KAAK,KAAK,MAAM;GAC7B,MAAM,SAAS,OAAOC,QACpB,MAAM,KAAK,GAAG,GACd,UACA,YACA,QACA,KACF,CAAC,CAAC,KACA,MAAM,QAAQ,KAAK,GACnB,OAAO,eAAe,MAAM,MAAM,GAAG,CAAC,CACxC;GACA,OAAO;IACL,MAAM,OAAO,WAAW,SAAS,SAAS,iBAAiB,KAAK,IAAI,CAAC;IACrE,UAAU,MAAM,MAAM,OAAO,KAAK,IAAI,CAAC,CAAC,KAAK,OAAO,QAAQ,MAAM,MAAM,GAAG,CAAC,CAAC;IAC7E,SAASC,MAAc,QAAQ,UAAU,YAAY,QAAQ,KAAK,CAAC,CAAC,KAClE,OAAO,SAAS,SAAS,iBAAiB,KAAK,IAAI,CAAC,GACpD,OAAO,MACT;GACF;EACF,CAAC,CAAC,CAAC,KACD,OAAO,UAAU,UACf,OAAO,WAAW,0CAA0C,OAAO,KAAK,GAAG,CAC7E,CACF,GACA;GAAE,cAAc;IAAE,MAAM;IAAQ;GAAM;GAAG,GAAI,QAAQ,KAAA,IAAY,CAAC,IAAI,EAAE,IAAI;EAAG,CACjF;CACF;CAMA,MAAM,iCAAiC,aACrC,QACE,UACAC,qBACA,OAAO,QAAQ;EAGb,MAAM,OAAO,WAAW,OAAO,gBAAgB,uBAAuB,CAAC,CAAC,KACtE,OAAO,MACT;EACA,UAAU,OAAO;EACjB,SAAS,sBAAsB,KAC7B,OAAO,QAAQ,uBAAuB,GACtC,OAAO,MACT;CACF,CAAC,CACH;CAMF,MAAM,EAAE,OAAO,SAAS;CACxB,MAAM,qBAAqB,QACzB,SAAS,KAAA,KAAa,UAAU,KAAA,IAC5B,OAAO,KACL,IAAI,WAAW;EACb,SAAS;EACT,OAAO;CACT,CAAC,CACH,IACA,OAAO,IAAI,aAAa;EACtB,MAAM,OAAO,OAAO,KAAK,MAAM,GAAG;EAClC,MAAM,OAAO,OAAOC,QAAc,OAAO,IAAI;EAG7C,OAAO;GAAE,GAAGC,OAAgB,IAAI;GAAG,KAAK,OAAO,KAAK,UAAU,IAAI;EAAE;CACtE,CAAC;CAIP,MAAM,sBAAsB,UAAkB,QAC5C,kBAAkB,GAAG,CAAC,CAAC,KACrB,OAAO,UAAU,UACf,OAAO,WAAW,6BAA6B,IAAI,cAAc,MAAM,SAAS,CAClF,GACA,OAAO,SAAS,EAAE,MAAM,OAAO,KAAK,gBAClC,IAAI,qBAAqB,KAAK,IAC1B,gBAAgB,UAAU,MAAM,SAAS,IACzC,gBAAgB,UAAU,IAAI,CAAC,CAAC,KAC9B,OAAO,QACL,uBAAuB,UAAU,KAAK,YAAY,MAAM,OAAO,SAAS,CAC1E,CACF,CACN,CACF;CAEF,MAAM,wBAAwB,UAAkB,QAC9C,kBAAkB,GAAG,CAAC,CAAC,KACrB,OAAO,SAAS,EAAE,MAAM,YACtB,QAAQ,UAAUP,KAAY,IAAI,CAAC,CAAC,CAAC,KACnC,OAAO,QACL,IAAI,qBAAqB,KAAK,IAC1B,OAAO,OACP,QAAQ,UAAUE,WAA0B,KAAK,YAAY,MAAM,KAAK,CAAC,CAC/E,CACF,CACF,GACA,OAAO,MACT;CAKF,MAAM,cAAc,SAAkB,aACnC,OAAO,gBAAgB,KAAA,IACpB,OAAO,KAAK,IAAI,eAAe,EAAE,SAAS,wCAAwC,CAAC,CAAC,IACpF,OAAO,YAAY,OAAO,EAAA,CAC5B,KACA,OAAO,SAAS,SACd,QAAQ,KAAK;EACX,MAAM;EACN,GAAG,QAAQ,OAAO;EAClB,MAAM,KAAK,KAAK,SAAS;GACvB,YAAY,IAAI;GAChB,IAAI,IAAI;GACR,OAAO,IAAI;EACb,EAAE;CACJ,CAAC,CACH,GACA,OAAO,OAAO,UACZ,QAAQ,KAAK;EAAE,MAAM;EAAc,GAAG,QAAQ,OAAO;EAAG,MAAM,CAAC;EAAG,OAAO,MAAM;CAAQ,CAAC,CAC1F,CACF;CAMF,MAAM,QAAQ,OAAO,IAAI,KAAK,QAAQ,MAA2C,CAAC;CAClF,MAAM,YAAY,QAChB,IAAI,OAAO,QAAQ,QAAQ,CAAC,QAAQ,IAAI,KAAK,GAAG,GAAG,QAAQ,OAAO,KAAK,GAAG,CAAC,CAAU;CAKvF,MAAM,aAAa,WAAmB,UACpC,MAAM,MAAM,QAAQ,CAAC,CAAC,KACpB,OAAO,QAAQ,OAAO,yBAAyB,MAAM,MAAM,MAAM,SAAS,MAAM,IAAI,CAAC,GACrF,OAAO,SAAS,eACd,IAAI,OAAO,OAAO,QAAQ,IAAI,QAAQ,MAAM,UAAU,SAAS,GAAG,UAAU,CAAC,CAC/E,GACA,OAAO,YAAY;EACjB,YAAY,UACV,QAAQ,KAAK;GACX,MAAM;GACN,UAAU,MAAM;GAChB;GACA,SAAS,MAAM;EACjB,CAAC;EACH,iBACE,QAAQ,KAAK;GAAE,MAAM;GAAqB,UAAU,MAAM;GAAU;EAAU,CAAC;CACnF,CAAC,CACH;CAIF,MAAM,mBAAmB,YACvB,gBAAgB,QAAQ,IAAI,CAAC,CAAC,KAC5B,OAAO,YAAY;EACjB,YAAY,UAAU,UAAU,QAAQ,WAAW,KAAK;EACxD,YAAY,UACV,iBAAiB,QAAQ,IAAI,CAAC,CAAC,KAC7B,OAAO,SAAS,EAAE,eAChB,QAAQ,KAAK;GACX,MAAM;GACN;GACA,WAAW,QAAQ;GACnB,SAAS,MAAM;EACjB,CAAC,CACH,GACA,OAAO,YACL,OAAO,WAAW,uDAAuD,CAC3E,CACF;CACJ,CAAC,CACH;CAIF,MAAM,iBACJ,YAEA,SAAS,QAAQ,QAAQ,UAAU,QAAQ,SAAS,CAAC,CAAC,CAAC,KACrD,OAAO,QACL,OAAO,MAAM;EACX,cAAc,OAAO;EACrB,SAAS,eACP,QAAQ,WAAW,KAAA,IAAY,WAAW,UAAU,WAAW,OAAO,QAAQ,MAAM;CACxF,CAAC,CACH,GACA,OAAO,YAAY;EACjB,YAAY,UACV,QAAQ,KAAK;GACX,MAAM;GACN,UAAU,QAAQ;GAClB,WAAW,QAAQ;GACnB,OAAO,MAAM;EACf,CAAC;EACH,iBACE,QAAQ,KAAK;GACX,MAAM;GACN,UAAU,QAAQ;GAClB,WAAW,QAAQ;EACrB,CAAC;CACL,CAAC,CACH;CAEF,MAAM,gBAAgB,aACpB,IAAI,OAAO,QAAQ,QAAQ;EACzB,MAAM,SAAS,GAAG,SAAS;EAC3B,OAAO,CACL,CAAC,GAAG,QAAQ,OAAO,QAAQ,OAAO,MAAM,GAAG,QAAQ,IAAI,WAAW,MAAM,CAAC,CAAC,CAAC,GAC3E,QAAQ,OAAO,MAAM,GAAG,QAAQ,CAAC,IAAI,WAAW,MAAM,CAAC,CACzD;CACF,CAAC,CAAC,CAAC,KACD,OAAO,SAAS,SACd,OAAO,QAAQ,OAAO,eAAe,WAAW,SAAS;EACvD,aAAa;EACb,SAAS;CACX,CAAC,CACH,CACF;CAEF,MAAM,oBAAoB,aACxB,OAAO,IAAI,aAAa;EACtB,MAAM,OAAO,CAAC,GAAI,OAAO,IAAI,IAAI,MAAM,CAAE,CAAC,CACvC,QAAQ,GAAG,WAAW,MAAM,QAAQ,IAAI,QAAQ,CAAC,CAAC,CAClD,KAAK,CAAC,SAAS,GAAG;EACrB,OAAO,OAAO,QACZ,OACC,QACC,OAAO,IAAI,aAAa;GACtB,OAAO,QAAQ,UAAU,GAAG;EAC9B,CAAC,GACH;GAAE,aAAa;GAAG,SAAS;EAAK,CAClC;EACA,OAAO,aAAa,QAAQ;EAC5B,OAAO,OAAO,QAAQ;CACxB,CAAC;CAKH,MAAM,eAAe,SAAkB,YACrC,QAAQ,KAAK;EACX,MAAM;EACN,GAAG,QAAQ,OAAO;EAClB,SAAS,QAAQ;EACjB,GAAI,QAAQ,SAAS,aAAa,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;CAClE,CAAC;CAIH,MAAM,gBAAgB,YACpB,QAAQ,YAAY,+CAChB,gBAAgB,OAAO,IACvB,sBAAsB,OAAO;CAEnC,MAAM,yBACJ,YAEA,OAAO,cAAc,QAAQ,SAAS,QAAQ,IAAI,CAAC,CAAC,KAClD,OAAO,SAAS,aAGd,QACG,KAAK;EAAE,MAAM;EAAa,GAAG,QAAQ,OAAO;CAAE,CAAC,CAAC,CAChD,KACC,OAAO,QACL,OAAO,WACL,SAAS,aAAa,KACpB,OAAO,SAAS,YAAY,YAAY,SAAS,OAAO,CAAC,CAC3D,CACF,CACF,CACF,CACJ,GACA,OAAO,OAAO,UACZ,QAAQ,KAAK;EACX,MAAM;EACN,GAAG,QAAQ,OAAO;EAClB,SAAS,MAAM;CACjB,CAAC,CACH,CACF;CAEF,MAAM,UAAU,YAA0C;EACxD,QAAQ,QAAQ,MAAhB;GACE,KAAK,UACH,OAAO,aAAa,OAAO;GAC7B,KAAK,mBACH,OAAO,MAAM,QAAQ,QAAQ,CAAC,CAAC,KAAK,OAAO,QAAQ,cAAc,OAAO,CAAC,CAAC;GAC5E,KAAK,aACH,OAAO,MAAM,QAAQ,QAAQ,CAAC,CAAC,KAC7B,OAAO,QAAQ,gBAAgB,QAAQ,UAAU,QAAQ,MAAM,CAAC,CAClE;GACF,KAAK,eACH,OAAO,MAAM,QAAQ,QAAQ,CAAC,CAAC,KAC7B,OAAO,QAAQ,QAAQ,QAAQ,UAAUF,KAAY,QAAQ,MAAM,CAAC,CAAC,CACvE;GACF,KAAK,kBACH,OAAO,MAAM,QAAQ,QAAQ,CAAC,CAAC,KAC7B,OAAO,QAAQ,qBAAqB,QAAQ,UAAU,QAAQ,MAAM,QAAQ,IAAI,CAAC,CACnF;GACF,KAAK,oBACH,OAAO,MAAM,QAAQ,QAAQ,CAAC,CAAC,KAC7B,OAAO,QACL,QAAQ,QAAQ,UAAUC,SAAwB,QAAQ,MAAM,QAAQ,IAAI,CAAC,CAC/E,CACF;GACF,KAAK,oBACH,OAAO,MAAM,QAAQ,QAAQ,CAAC,CAAC,KAC7B,OAAO,QACL,uBACE,QAAQ,UACR,QAAQ,YACR,QAAQ,QACR,QAAQ,KACV,CACF,CACF;GACF,KAAK,sBACH,OAAO,MAAM,QAAQ,QAAQ,CAAC,CAAC,KAC7B,OAAO,QACL,QACE,QAAQ,UACRC,WAA0B,QAAQ,YAAY,QAAQ,QAAQ,QAAQ,KAAK,CAC7E,CACF,CACF;GACF,KAAK,gBACH,OAAO,MAAM,QAAQ,QAAQ,CAAC,CAAC,KAC7B,OAAO,QAAQ,mBAAmB,QAAQ,UAAU,QAAQ,GAAG,CAAC,CAClE;GACF,KAAK,kBACH,OAAO,MAAM,QAAQ,QAAQ,CAAC,CAAC,KAC7B,OAAO,QAAQ,qBAAqB,QAAQ,UAAU,QAAQ,GAAG,CAAC,CACpE;GACF,KAAK,QACH,OAAO,WAAW,SAAS,QAAQ,OAAO;GAC5C,KAAK,2BACH,OAAO,MAAM,QAAQ,QAAQ,CAAC,CAAC,KAC7B,OAAO,QAAQ,8BAA8B,QAAQ,QAAQ,CAAC,CAChE;GACF,KAAK,6BACH,OAAO,MAAM,QAAQ,QAAQ,CAAC,CAAC,KAC7B,OAAO,QAAQ,QAAQ,QAAQ,UAAUG,mBAAkC,CAAC,CAC9E;GACF,KAAK,cACH,OAAO,iBAAiB,QAAQ,QAAQ;GAC1C,KAAK,aACH,OAAO,MAAM,QAAQ,QAAQ;EACjC;CACF;CAGA,MAAM,EAAE,eAAe,kBAAkB,WAAW,OAAO;CAC3D,MAAM,QAAQ,OAAO,IAAI,aAAa;EAEpC,MAAM,UAAS,OADI,MAAM,qBACJ,SAAS,SAAS,aAAa;EACpD,MAAM,QAAQ,CAAC,GAAI,OAAO,IAAI,IAAI,QAAQ,CAAE,CAAC,CAC1C,QAAQ,GAAG,UAAU,OAAO,MAAM,CAAC,CACnC,KAAK,CAAC,cAAc,QAAQ;EAC/B,OAAO,OAAO,QACZ,QACC,aACC,OAAO,IAAI,aAAa;GACtB,OAAO,iBAAiB,QAAQ;EAClC,CAAC,GACH;GAAE,aAAa;GAAG,SAAS;EAAK,CAClC;CACF,CAAC;CACD,OAAO,OAAO,WACZ,OAAO,QAAQ,MAAM,KAAK,OAAO,QAAQ,OAAO,MAAM,aAAa,CAAC,CAAC,CAAC,CACxE;CAMA,MAAM,aAAa,OAAO,OAAO,OAAO,OAAO,YAAY;CAC3D,OAAO,OAAO,WACZ,OAAO,QACL,WAAW,KACT,OAAO,SAAS,WACd,OAAO,QACL,SACC,UAAW,MAAM,SAAS,kBAAkB,WAAW,OAAO,MAC/D,EAAE,SAAS,KAAK,CAClB,CACF,CACF,CACF,CAAC,CAAC,KAAK,OAAO,MAAM,CACtB;CAEA,OAAO,OAAO,WACZ,OAAO,QACL,MAAM,KAAK,KACT,OAAO,QAAQG,mBAAkC,GACjD,OAAO,SAAS,YACd,YAAY,KAAA,IAAY,OAAO,OAAO,OAAO,OAAO,CAAC,CAAC,KAAK,OAAO,MAAM,CAC1E,CACF,CACF,CACF;CAKA,OAAO;CACP,OAAO,QAAQ,KAAK,EAAE,MAAM,YAAY,CAAC,CAAC,CAAC,KAAK,OAAO,MAAM;CAE7D,OAAO,EACL,eAAe,OAAO,IAAI;EAAE,SAAS,IAAI,IAAI,MAAM;EAAG,QAAQ,MAAM;CAAc,CAAC,CAAC,CAAC,KACnF,OAAO,KAAK,EAAE,SAAS,aAAa;EAClC,MAAM,YAAY,IAAI,IAAI,OAAO,KAAK,UAAU,CAAC,MAAM,KAAK,MAAM,MAAM,CAAC,CAAC;EAC1E,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,SAAS,CAAC,KAAK,WAAW;GAC5C,MAAM,eAAe,eAAe,KAAK;GACzC,OAAO,iBAAiB,KAAA,IACpB,CAAC,IACD,CAAC;IAAE,GAAG;IAAc,QAAQ,UAAU,IAAI,GAAG,KAAKC;GAAoB,CAAC;EAC7E,CAAC;CACH,CAAC,CACH,EACF;AACF,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACv0BH,MAAM,OAAO,QACX,OAAO,eAAe,GAAG,KAAK,EAAE,UAAU,KAAK,CAAC;;AAElD,MAAM,QAAW,OAA2C,OAAO,OAAO,EAAE,CAAC,CAAC,KAAK,OAAO,KAAK;;AAE/F,MAAM,UAAU,MAAsC,OAAO,IAAI,OAAO,OAAO,SAAS,OAAO,CAAC;;AAGhG,MAAa,eAAe;;;;;;;AAQ5B,MAAa,eAAe,aAAyC;CACnE,IAAI,aAAa,KAAA,KAAa,SAAS,KAAK,MAAM,IAAI,OAAO;CAC7D,MAAM,OAAO,OAAO,QAAQ;CAC5B,IAAI,CAAC,OAAO,UAAU,IAAI,GACxB,MAAM,IAAI,MAAM,gDAAgD,KAAK,UAAU,QAAQ,GAAG;CAE5F,OAAO;AACT;;;;;;AAeA,MAAa,gBAAuC;CAClD;EAAE,MAAM;EAAK,MAAM;CAAO;CAC1B;EAAE,MAAM;EAAK,MAAM;CAAU;CAC7B;EAAE,MAAM;EAAK,MAAM;CAAS;CAC5B;EAAE,MAAM;EAAK,MAAM;CAAU;CAC7B;EAAE,MAAM;EAAK,MAAM;CAAU;AAC/B;AAmCA,MAAM,kBAAkB,aAAyD;CAC/E,OAAO,SAAS,SAAS;CACzB,QAAQ,SAAS,UAAU;CAC3B,cAAc,SAAS,gBAAgB;AACzC;AAaA,MAAM,gBAAuC;CAC3C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;AAGA,MAAM,cAAqC;CAAC;CAAK;CAAK;CAAM;CAAI;CAAK;AAAG;;AAGxE,MAAM,iBAAwC;CAC5C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,MAAM,kBAAyC;CAAC;CAAQ;CAAM;AAAG;AAEjE,MAAM,WAAkC;CACtC;CAAG;CAAI;CAAG;CAAI;CAAG;CAAG;CAAG;CAAI;CAAI;CAAK;CAAI;CAAY;CAAa;AACnE;AACA,MAAM,mBAA0C;CAAC;CAAG;CAAM;AAAK;AAE/D,MAAM,UAAiC;CACrC;CACA;CACA;CACA;CACA;CACA;CAKA,KAAK,KAAK;CACV,KAAK;CACL,KAAK,KAAK;CACV;CACA;CACA;CACA;CACA;AACF;AACA,MAAM,kBAAyC,CAAC,MAAM,IAAI;AAE1D,MAAM,WAAkC;CACtC;CACA;CACA;CACA;CACA;CACA;AACF;AACA,MAAM,mBAA0C,CAAC,0BAA0B;AAE3E,MAAM,WAAW,MAA6B,YAAmC;CAC/E,QAAQ,MAAR;EACE,KAAK,QACH,OAAO;GACL,MAAM;IAAC,GAAG;IAAe,GAAG;IAAa,GAAI,QAAQ,SAAS,iBAAiB,CAAC;GAAE;GAClF,SAAS;EACX;EACF,KAAK,WACH,OAAO;GAAE,MAAM;GAAU,SAAS;EAAiB;EACrD,KAAK,UACH,OAAO;GAAE,MAAM;GAAS,SAAS;EAAgB;EACnD,KAAK,WACH,OAAO;GAAE,MAAM,CAAC,MAAM,KAAK;GAAG,SAAS,CAAC;EAAE;EAC5C,KAAK,WACH,OAAO;GAAE,MAAM;GAAU,SAAS;EAAiB;CACvD;AACF;AAcA,MAAM,YAAY;AAclB,MAAM,YAAY,SAAgC,YAAsC;CACtF,MAAM,QAAQ,QAAQ,KAAK,WAAW,QAAQ,OAAO,MAAM,OAAO,CAAC,CAAC,IAAI;CACxE,OAAO;EACL;EACA;EACA,OAAO,QAAQ;EACf,QAAQ,QAAQ,QAAQ,IAAI;EAC5B,OAAO,KAAK,IAAI,GAAG,GAAG,MAAM,KAAK,SAAS,KAAK,MAAM,CAAC;CACxD;AACF;;AAGA,MAAM,eACJ,MACA,UAEA,OAAO,IAAI,aAAa;CACtB,IAAI,OAAO;EACT,MAAM,OAAO,OAAO,OAAO;EAC3B,IAAI,OAAO,WAAW,OAAO;EAC7B,IAAI,OAAO,IAAyB,OAAO,KAAA;CAC7C;CACA,OAAO,OAAO,KAAK,IAAI;AACzB,CAAC;AAEH,MAAM,eAAe,MAAe,UAClC,OAAO,IAAI,aAAa;CACtB,MAAM,QAA2C,CAAC;CAClD,OAAO,OAAO,QACZ,KAAK,QAAQ,QAAQ,IACpB,CAAC,GAAG,YACH,OAAO,IAAI,aAAa;EACtB,MAAM,OAAO,KAAK,MAAM,MAAM,CAAC;EAC/B,IAAI;EACJ,IAAI,QAAQ,KAAK,QAAQ,QAAQ,UAAU,IAAI,OAAO,KAAA;OACjD,IAAI,QAAQ,KAAK,SAAS,KAAK,OAClC,QAAQ,MAAM,QAAQ,KAAK,UAAU,KAAK;OACvC,QAAQ,OAAO,YAAY,MAAM,KAAK,KAAK;EAChD,IAAI,UAAU,KAAA,GAAW,MAAM,OAAO,QAAQ;CAChD,CAAC,GACH;EAAE,aAAa;EAAG,SAAS;CAAK,CAClC;CACA,OAAO;EAAE,IAAI,IAAI,OAAO,KAAK,CAAC,CAAC,SAAS,GAAG,GAAG;EAAK;CAAM;AAC3D,CAAC;;;;;;AAOH,MAAa,eACX,UAAiC,eACjC,YACW;CACX,MAAM,OAAO,SAAS,SAAS,eAAe,OAAO,CAAC;CACtD,OAAO,KAAK,SAAS,KAAK;AAC5B;;;;;;;;;;;;AAaA,MAAa,gBACX,OACA,UAAiC,eACjC,YAC4C;CAC5C,MAAM,OAAO,SAAS,SAAS,eAAe,OAAO,CAAC;CACtD,MAAM,UAAU,KAAK,SAAS,KAAK;CACnC,IAAI,QAAQ,SACV,MAAM,IAAI,MACR,+BAA+B,QAAQ,qEAAqE,OAC9G;CAEF,OAAO,OAAO,QACZ,MAAM,KAAK,EAAE,QAAQ,MAAM,IAAI,GAAG,UAAU,KAAK,IAChD,UAAU,YAAY,MAAM,KAAK,CACpC;AACF;;AA6BA,MAAa,uBAAiC;CAC5C,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,KAAK;CACL,IAAI;CACJ,KAAK;CACL,IAAI;CACJ,KAAK;CACL,QAAQ;CACR,KAAK;CACL,IAAI;CACJ,KAAK;CACL,MAAM;AACR;AAcA,MAAM,cACH,UACA,OAAO,YACN,OAAO,IAAI,UAAU,UAAU,KAAK,OAAO,KAAK,CAAC;;AAGrD,MAAa,gBAA6C;CACxD;EAAE,MAAM;EAAM,SAAS;EAAO,OAAO,WAAWC,EAAY;CAAE;CAC9D;EAAE,MAAM;EAAM,SAAS;EAAO,OAAO,WAAWC,EAAY;CAAE;CAC9D;EAAE,MAAM;EAAM,SAAS;EAAM,OAAO,WAAWC,EAAY;CAAE;CAC7D;EAAE,MAAM;EAAO,SAAS;EAAM,OAAO,WAAWC,GAAa;CAAE;CAC/D;EAAE,MAAM;EAAM,SAAS;EAAM,OAAO,WAAWC,EAAY;CAAE;CAC7D;EAAE,MAAM;EAAO,SAAS;EAAM,OAAO,WAAWC,GAAa;CAAE;CAC/D;EACE,MAAM;EACN,SAAS;EACT,QAAQ,OAAO,UAAU,SAAS,OAAO,IAAI,OAAO,WAAWC,KAAe,OAAO,MAAM,CAAC;CAC9F;CACA;EACE,MAAM;EACN,SAAS;EACT,QAAQ,OAAO,UAAU,SAAS,OAAO,IAAI,OAAO,WAAWC,MAAgB,OAAO,MAAM,CAAC;CAC/F;CACA;EACE,MAAM;EACN,SAAS;EACT,QAAQ,UACN,OAAO,IAAI,OAAO,EAAG,IAAI,YACvB,UAAUC,UAAoB,KAAK,IAAIC,OAAiB,KAAK,CAC/D;CACJ;AACF;AAIA,MAAM,gBAAgB;AACtB,MAAM,YAAY;AAClB,MAAM,YAAY;AAClB,MAAM,eAAe;;AAGrB,MAAM,cAAc,SAClB,OAAO,IAAI,aAAa;CACtB,MAAM,UAAU,IAAI,wBAAwB,KAAK,OAAO,MAAM,OAAO,OAAO,YAAY;CACxF,OAAO,OAAO,KAAK,UAAU,KAAK,UAAU,KAAK,IAAI;AACvD,CAAC;;AAGH,MAAM,WAAW,SACf,OAAO,IAAI,aAAa;CACtB,IAAI,OAAO,OAAO,aAAa,GAAG,OAAO,CAAC;CAC1C,MAAM,SAAS,KAAK,OAAO,IAAI,CAAC;CAChC,OAAO,OAAO,WAAW,IAAI,CAAC,CAAC,KAAK,OAAO,gBAAgB,MAAM,CAAC;AACpE,CAAC;AAEH,MAAM,gBACJ,SACA,SACA,aAEA,OAAO,IAAI,aAAa;CACtB,IAAI,OAAO,OAAO,SAAS,GAAG;EAC5B,SAAS;EACT,OAAOC;CACT;CACA,MAAM,SAAS,OAAO,KAAK,OAAO;CAClC,MAAM,OAAO,QAAQ,OAAO,MAAM,OAAO;CAGzC,MAAM,aAAa,cAAc,QAC9B,QACE,CAAC,GAAG,WAAW,OAAO,SAAS,aAAa,QAAQ,kBACpD,GAAG,SAAS,YAAY,QAAQ,MACrC;CACA,MAAM,WAAW,OAAO,KAAK,UAAU;CACvC,SAAS,SAAS,KAAK;CACvB,OAAO,OAAO,SAAS,MAAM,OAAO,MAAM,WAAW,IAAI,GAAG,QAAQ,IAAI,CAAC;AAC3E,CAAC;;;;;;;AAQH,MAAa,qBACX,SACA,SACA,UACA,QAAQ,MAC+B;CACvC,MAAM,WAAW,eAAe,OAAO;CACvC,MAAM,MAAM,cACV,OAAO,IAAI,aAAa;EACtB,IAAI,cAAc,MAAM,OAAO,OAAO,SAAS,IAC7C,OAAO,OAAO,aAAa,SAAS,UAAU,QAAQ;EAExD,MAAM,SAAS,OAAO,IAAI,CAAC;EAC3B,IAAI,WAAW,GAAG;GAChB,SAAS;GACT,OAAOC,IAAc,OAAO,GAAG,YAAY,CAAC,CAAC;EAC/C;EACA,MAAM,QAAQ,KAAK,OAAO,IAAI,CAAC;EAC/B,MAAM,WAAW,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,KAAK,OAAO,gBAAgB,KAAK,CAAC;EAC5E,IAAI,WAAW,GAAG;GAChB,SAAS;GACT,OAAOC,IAAc,GAAG,QAAQ;EAClC;EACA,SAAS;EACT,OAAOC,GAAa,GAAG,QAAQ;CACjC,CAAC;CACH,OAAO,GAAG,KAAK;AACjB;;AAKA,MAAa,mBACX,UAAiC,kBAEjC,OAAO,IAAI,aAAa;CACtB,MAAM,QAAQ,KAAK,IAAI,QAAQ,QAAQ,KAAK,OAAO,IAAI,CAAC,EAAE;CAC1D,MAAM,WAAW,OAAO,OAAO,QAAQ,OAAO;CAC9C,OAAO,OAAO,OAAO,QAAQ,SAAS,MAAM,GAAG,KAAK,IAAI,WACtD,OAAO,IAAI,OAAO,cAAc,SAAyB;EACvD,OAAO,OAAO;EACd,WAAW,MAAM,QAAQ;CAC3B,EAAE,CACJ;AACF,CAAC;;;;;;;AAkCH,MAAa,kBAAkB,YAC7B,OAAO,cAAc;CACnB,MAAM,UAAU,QAAQ,WAAW;CACnC,MAAM,WAAW,cAAc;CAC/B,OAAO,OAAO,IAAI,aAAa;EAC7B,MAAM,OAAO,OAAO,aAAa,QAAQ,QAAQ,IAAI,SAAS,OAAO;EACrE,MAAM,aAAa,OAAO,kBACxB,SACA,SACA,UACA,QAAQ,SAAS,CACnB,CAAC,CAAC,KAAK,OAAO,gBAAgB,QAAQ,cAAc,GAAG,CAAC;EACxD,MAAM,WAAW,OAAO,gBAAgB,OAAO,CAAC,CAAC,KAC/C,OAAO,gBAAgB,QAAQ,YAAY,EAAE,CAC/C;EACA,OAAO;GAAE,MAAM,QAAQ;GAAM;GAAS;GAAM;GAAY;GAAU;EAAS;CAC7E,CAAC,CAAC,CAAC,KAAK,OAAO,SAAS,QAAQ,IAAI,CAAC;AACvC,CAAC;AAUH,MAAM,aAAgB,IAAsB,OAAe,MACzD,GAAG,KAAK,GAAG,MAAO,MAAM,QAAQ,IAAI,CAAE;AACxC,MAAM,WAAc,IAAsB,UACxC,GAAG,QAAQ,GAAG,MAAM,MAAM,KAAK;;;;;;AAOjC,MAAa,mBACX,cACuC;CACvC,QAAQ,UAAU,MAAlB;EACE,KAAK;EACL,KAAK,MAAM;GACT,MAAM,UAAU,UAAU,SAAS,QAAQD,MAAgBC;GAC3D,MAAM,WAAW,UAAU;GAC3B,MAAM,MAAkC,CAAC;GACzC,IAAI,SAAS,SAAS,GAAG;IACvB,IAAI,KAAK,GAAG,QAAQ;IACpB,IAAI,KAAK,GAAG,SAAS,KAAK,GAAG,MAAM,QAAQ,GAAG,QAAQ,UAAU,CAAC,CAAC,CAAC,CAAC;GACtE;GACA,SAAS,SAAS,OAAO,MAAM;IAC7B,IAAI,QAAQ,gBAAgB,KAAK,IAAI,WAAW;KAC9C,IAAI,KAAK,QAAQ,GAAG,UAAU,UAAU,GAAG,MAAM,CAAC,CAAC;IACrD,CAAC;GACH,CAAC;GACD,OAAO;EACT;EACA,KAAK,OACH,OAAO,CAAC,UAAU,WAAW,GAAG,gBAAgB,UAAU,SAAS,CAAC,CAAC,IAAIF,GAAa,CAAC;EACzF,KAAK;EACL,KAAK,SAAS;GACZ,MAAM,UAAU,UAAU,SAAS,OAAOL,OAAiBC;GAC3D,OAAO,UAAU,OAAO,SAAS,IAC7B,UAAU,OAAO,KAAK,GAAG,MAAM,QAAQ,UAAU,OAAO,QAAQ,UAAU,QAAQ,CAAC,CAAC,CAAC,IACrF,CAAC;EACP;EACA,SACE,OAAO,CAAC;CACZ;AACF;AAEA,MAAM,mBAAmB;;;;;;;AAQzB,MAAa,YACX,SACA,cAC8B;CAG9B,MAAM,SAAS,SAAe,UAA6C;EACzE,IAAI,SAAS,kBAAkB,OAAO,OAAO,QAAQ,OAAO;EAC5D,MAAM,aAA0B,CAC9B,GAAG,gBAAgB,QAAQ,SAAS,CAAC,CAAC,KAAK,eAAe;GACxD;GACA,MAAM,QAAQ;EAChB,EAAE,GACF,GAAG,QAAQ,KAAK,KAAK,GAAG,OAAO;GAC7B,WAAW,QAAQ;GACnB,MAAM,QAAQ,QAAQ,MAAM,CAAC;EAC/B,EAAE,CACJ;EACA,IAAI,QAAQ;EACZ,OAAO,OAAO,UAAU,aAAa,cAAc;GACjD;GACA,OAAO,UAAU,SAAS;EAC5B,CAAC,CAAC,CAAC,KACD,OAAO,SAAS,aACd,OAAO,OAAO,QAAQ,IAAI,MAAM,SAAS,OAAO,QAAQ,KAAK,IAAI,OAAO,QAAQ,OAAO,CACzF,CACF;CACF;CACA,OAAO,MAAM,SAAS,CAAC;AACzB;;;;;;AA0BA,MAAM,SAAS,UACb,KAAK,UAAU,QAAQ,MAAM,UAAoB,OAAO,GAAG,OAAO,EAAE,IAAI,OAAO,KAAM;;;;;;AAOvF,MAAa,sBAAsB,iBAAuC;CACxE,MAAM,YAAY,aAAa,aAAa;CAC5C,MAAM,QAAQ,CAAC,GAAG,aAAa,QAAQ,SAAS,aAAa,KAAK,IAAI,UAAU,EAAE;CAClF,IAAI,aAAa,cAAc,KAAA,GAC7B,MAAM,KAAK,cAAc,MAAM,aAAa,SAAS,GAAG;CAE1D,IAAI,aAAa,YAAY,KAAA,GAC3B,MAAM,KAAK,YAAY,MAAM,aAAa,OAAO,GAAG;CAEtD,MAAM,KAAK,OAAO;CAClB,IAAI,QAAQ,aAAa,OAAO,QAAQ;EACtC,MAAM,KAAK,KAAK,IAAI,GAAG,GAAG,MAAM,IAAI,KAAK,GAAG;CAC9C,CAAC;CACD,IAAI,QAAQ,OAAO,QAAQ,aAAa,OAAO,IAAI,CAAC,MAAM,SAAS;EACjE,MAAM,KAAK,GAAG,KAAK,IAAI,KAAK,UAAU,GAAG,GAAG;CAC9C,CAAC;CACD,OAAO,MAAM,KAAK,IAAI;AACxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC/nBA,IAAa,oBAAb,cAAuC,OAAO,YAG5C,CAAC,CAAC,qBAAqB;CACvB,MAAM,OAAO;CACb,SAAS,OAAO;AAClB,CAAC,CAAC,CAAC,CAAC;;AAWJ,MAAM,4BAAY,IAAI,IAAsB;;;;;;;AAQ5C,MAAa,QAAQ,SAAsC;CACzD,MAAM,aAAa,UAAU,IAAI,IAAI;CACrC,OAAO,eAAe,KAAA,IAClB,OAAO,OACP,SAAS,QAAQ,WAAW,SAAS,KAAA,CAAS,CAAC,CAAC,KAC9C,OAAO,QAAQ,SAAS,MAAM,WAAW,OAAO,CAAC,CACnD;AACN;;AAKA,MAAa,SAASO,OACpB,gBACA,OAAO,OAAO;CAAE,YAAY,OAAO;CAAQ,IAAI,OAAO;CAAQ,OAAO,OAAO;AAAQ,CAAC,CACvF;;AAGA,MAAa,SAASA,OACpB,gBACA,OAAO,OAAO;CAAE,YAAY,OAAO;CAAQ,IAAI,OAAO;AAAO,CAAC,CAChE;;;;;AAMA,MAAa,aAAaA,OAAa,iBAAiB,OAAO,OAAO,CAAC,CAAC,CAAC;;AAGzE,MAAM,eAAe;;;;;AAMrB,MAAa,eAAeA,OAC1B,mBACA,OAAO,OAAO;CAAE,YAAY,OAAO;CAAQ,IAAI,OAAO;AAAO,CAAC,CAChE;;;;;;;;;;;AAYA,MAAa,gBAAgBA,OAC3B,4BACA,OAAO,OAAO;CAAE,YAAY,OAAO;CAAQ,IAAI,OAAO;AAAO,CAAC,CAChE;;;;;;;;;;;AAYA,MAAa,UAAUA,OACrB,qBACA,OAAO,OAAO;CAAE,YAAY,OAAO;CAAQ,IAAI,OAAO;CAAQ,MAAM,OAAO;AAAO,CAAC,CACrF;;AAGA,MAAa,iBACXC,kBAAgC;CAC9BC,QAAsB,SAAS,MAAM,WACnC,OAAO,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,KAAK,CACjD;CACAA,QAAsB,SAAS,MAAM,WAAW,OAAO,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;CACpFA,QAAsB,kBACpB,OAAO,KAAK,IAAI,aAAa,EAAE,SAAS,6BAA6B,CAAC,CAAC,CACzE;CACAA,QAAsB,eAAe,MAAM,WACzC,OACG,IAAI,KAAK,YAAY,KAAK,IAAI,EAAE,QAAQ,KAAK,CAAC,CAAC,CAC/C,KAAK,OAAO,QAAQ,OAAO,KAAK,IAAI,iBAAiB,EAAE,QAAQ,aAAa,CAAC,CAAC,CAAC,CAAC,CACrF;CACAA,QAAsB,gBAAgB,MAAM,WAC1C,OACG,IAAI,KAAK,YAAY,KAAK,IAAI,EAAE,GAAG,GAAG,CAAC,CAAC,CACxC,KACC,OAAO,QACL,OAAO,KACL,IAAI,aAAa,EAAE,SAAS,+CAA+C,CAAC,CAC9E,CACF,CACF,CACJ;CACAA,QAAsB,UAAU,MAAM,WACpC,OAAO,IAAI,aAAa;EACtB,MAAM,UAAW,OAAO,OAAO,IAAI,KAAK,YAAY,KAAK,EAAE;EAG3D,OAAO,KAAK,KAAK,IAAI;EACrB,OAAO,OAAO,IAAI,KAAK,YAAY,KAAK,IAAI,EAAE,IAAI,SAAS,KAAK,KAAK,EAAE,CAAC;CAC1E,CAAC,CACH;AACF,CAAC;;;;;;;AAiHH,MAAM,yBAAyB,OAAqB,YAClDC,QAAuB,KAAK,KAAK,MAAM,YAAY,oBAAoB;;AAGzE,MAAM,kBAAkB;;;;;AAMxB,MAAM,qBAAqB;;;;;AAM3B,MAAM,kBACJ,OACA,UACA,UACA,aACW;CACX,MAAM,SAAS,oBAAoB,SAAS;CAC5C,IAAI,aAAa,GACf,OAAO,WAAW,MAAM,eAAe,OAAO,YAAY;CAE5D,IAAI,aAAa,GACf,OAAO,yBAAyB,MAAM,GAAG,OAAO,KAAK,SAAS;CAEhE,OAAO,yBAAyB,MAAM,GAAG,OAAO,KAAK,SAAS,QAAQ,SAAS;AACjF;AAEA,MAAM,eACJ,SACA,SACA,OACA,cACY;CACZ,MAAM,OAAO,SAAS,cAAc;CACpC,MAAM,UAAuB,EAAE,eAAe,SAAS,iBAAiB,mBAAmB;CAC3F,MAAM,WAAW;CAEjB,MAAM,aAAa,MAAc,YAAoB,IAAI,kBAAkB;EAAE;EAAM;CAAQ,CAAC;CAC5F,MAAM,SAA2B,MAAM,WAAW,YAChD,YAAY,OAAO,OAAO,OAAO,KAAK,UAAU,MAAM,OAAO,CAAC;CAChE,MAAM,YAAiC,MAAM,WAC3C,OAAO,KACL,OAAO,UAAU,UAAU,UAAU,MAAM,gCAAgC,MAAM,SAAS,CAAC,CAC7F;CACF,MAAM,cAAqC,MAAM,QAAQ,SACvD,OAAO,KAAK,MAAM,CAAC,CAAC,KAClB,OAAO,SAAS,SAAS,MAAM,MAAM,KAAK,SAAS,WAAW,qBAAqB,MAAM,CAAC,CAC5F;CACF,MAAM,2BACJ,MACA,QACA,SACA,eAEA,OAAO,KAAK,MAAM,CAAC,CAAC,KAClB,OAAO,SAAS,SAAS;EACvB,MAAM,UAAU,KAAK,gBAAgB,IAAI;EACzC,IAAI,OAAO,OAAO,OAAO,GACvB,OAAO,MAAM,MAAM,OAAO,yBAAyB,QAAQ,SAAS;EAEtE,OAAO,MACL,MACA,CAAC,sBAAsB,QAAQ,OAAO,OAAO,GAC7C,GAAG,QAAQ,+CAA+C,YAC5D;CACF,CAAC,CACH;CACF,MAAM,YAAiC,YAAY,SAAS,UAAU;EACpE;EACA;EACA;EACA;EACA,WAAW,SAAS,cAAc,SAAS,UAAU,CAAC;CACxD;CAEA,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA,UAAU,GAAG,KAAK;EAClB;EACA;EACA;EACA;EACA,WAAW,SACT,SAAS,MAAM,QAAQ,gBAAgB,OAAO,CAAC,CAAC,CAAC,KAC/C,OAAO,KAAK,QAAQ,IAAI,aAAa,CAAC,CACxC;EACF;EACA,MAAM,YAAY,YAAY,IAAI,UAChC,SAAS,YAAY,OAAO,MAAM;GAAE;GAAY;GAAI;EAAM,CAAC;EAC7D,SAAS,YAAY,YAAY,OAC/B,SAAS,YAAY,aAAa,MAAM;GAAE;GAAY;EAAG,CAAC;EAC5D,WAAW,SAAS;CACtB;AACF;;AAQA,MAAM,2BAAiC,EACrC,SACA,SACA,UACA,MACA,OACA,OACA,UACA,UAEA,OAAO,IAAI,aAAa;CACtB,MAAM,OAAO;CACb,MAAM,SAAS,OAAO,SACpB,MACA,QAAQ,eAAe,SAAS,CAC9B,IAAI,QAAQ,GAAG,MAAM,KAAK,EAAE,GAAG,EAAE,CAAC,GAClC,IAAI,QAAQ,GAAG,MAAM,KAAK,EAAE,GAAG,EAAE,CAAC,CACpC,CAAC,CACH;CACA,OAAO,MACL,MACA,OAAO,gBAAgB,cAAc,QAAQ,GAC7C,6BAA6B,SAAS,OAAO,QAAQ,EAAE,QAAQ,OAAO,gBAAgB,WACxF;CACA,MAAM,UAAU,OAAO,SAAS,MAAM,QAAQ,QAAQ,SAAS,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;CAChF,OAAO,MAAM,MAAM,QAAQ,WAAW,GAAG,6BAA6B,QAAQ,QAAQ;CACtF,OAAO,MACL,MACA,QAAQ,OAAO,QAAQ,IAAI,YAAY,KAAA,KAAa,IAAI,YAAY,IAAI,GACxE,oCACF;AACF,CAAC;;AAGH,MAAM,uBAA6B,EACjC,SACA,SACA,UACA,MACA,OACA,OACA,UACA,UAEA,OAAO,IAAI,aAAa;CACtB,MAAM,OAAO;CACb,MAAM,SAAS,OAAO,SACpB,MACA,QAAQ,eAAe,SAAS,CAAC,IAAI,QAAQ,GAAG,MAAM,KAAK,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CACxE;CACA,OAAO,MACL,MACA,OAAO,gBAAgB,cAAc,QAAQ,GAC7C,sBAAsB,QAAQ,EAAE,+BAA+B,QAAQ,EAAE,QAAQ,OAAO,gBAAgB,WAC1G;CACA,MAAM,CAAC,KAAK,OAAO,SAAS,MAAM,QAAQ,QAAQ,SAAS,MAAM,CAAC,GAAG,CAAC,CAAC;CAKvE,OAAO,MACL,OACC,GAAG,MAAA,EAAsC,MAAM,GAChD,wEAAwE,KAAK,UAAU,GAAG,KAAK,EAAE,EACnG;AACF,CAAC;;AAGH,MAAM,qBAA2B,EAC/B,SACA,SACA,MACA,OACA,OACA,UACA,YACA,UACA,UAEA,OAAO,IAAI,aAAa;CACtB,MAAM,OAAO;CACb,OAAO,WACL,MACA,QAAQ,eAAe,SAAS,CAAC,IAAI,QAAQ,GAAG,MAAM,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,GACrE,eAAe,QAAQ,EAAE,wBAAwB,QAAQ,GAC3D;CACA,OAAO,MACL,OACC,OAAO,SAAS,IAAI,OAAO,QAAQ,GACpC,6CACF;CACA,MAAM,UAAU,OAAO,SAAS,MAAM,QAAQ,QAAQ,SAAS,MAAM,CAAC,GAAG,CAAC,CAAC;CAC3E,OAAO,MAAM,MAAM,IAAI,qBAAqB,OAAO,GAAG,uCAAuC;AAC/F,CAAC;;AAGH,MAAM,mBAAyB,EAC7B,SACA,SACA,OACA,OACA,yBACA,UACA,eAEA,OAAO,IAAI,aAAa;CACtB,MAAM,OAAO;CACb,OAAO,wBACL,MACA,QAAQ,eAAe,SAAS,CAAC,SAAS,QAAQ,GAAG,WAAW,MAAM,CAAC,CAAC,CAAC,CAAC,GAC1E,WAAW,MACX,YACF;CACA,OAAO,MACL,OACC,OAAO,SAAS,IAAI,OAAO,QAAQ,GACpC,+CACF;AACF,CAAC;;AAGH,MAAM,oBAA0B,EAAE,SAAS,SAAS,MAAM,OAAO,OAAO,UAAU,UAChF,OAAO,IAAI,aAAa;CACtB,MAAM,OAAO;CACb,MAAM,CAAC,UAAU,OAAO,SAAS,MAAM,QAAQ,QAAQ,SAAS,MAAM,CAAC,GAAG,CAAC,CAAC;CAC5E,OAAO,SAAS,MAAM,QAAQ,eAAe,SAAS,CAAC,IAAI,QAAQ,GAAG,MAAM,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;CAC5F,MAAM,CAAC,SAAS,OAAO,SAAS,MAAM,QAAQ,QAAQ,SAAS,MAAM,CAAC,GAAG,CAAC,CAAC;CAC3E,OAAO,MACL,MACA,WAAW,KAAA,KAAa,UAAU,KAAA,KAAa,OAAO,YAAY,MAAM,SACxE,kDAAkD,QAAQ,QAAQ,QAAQ,OAAO,QAAQ,EAC3F;AACF,CAAC;;;;;;AAOH,MAAM,oBACJ,EAAE,SAAS,SAAS,OAAO,YAC3B,MACA,WACA,QACA,aAEA,OAAO,IAAI,aAAa;CACtB,MAAM,WAAWC,MAAa,WAAW,MAAM,CAAC,CAAC,KAAK,QAAQ,IAAI,EAAE;CACpE,MAAM,aAAa,OAAO,SAAS,MAAM,QAAQ,SAAS,SAAS,MAAM,CAAC,EAAA,CAAG,KAC1E,UAAU,MAAM,EACnB;CACA,OAAO,MACL,MACA,KAAK,UAAU,SAAS,MAAM,KAAK,UAAU,QAAQ,GACrD,SAAS,UAAU,SAAS,CAC9B;CACA,OAAO;AACT,CAAC;;AAGH,MAAM,WAAsD;CAC1D,CAAC,MAAM;EAAE,MAAM;EAAI,KAAK;CAAO,CAAC;CAChC,CAAC,MAAM;EAAE,MAAM;EAAI,KAAK;CAAO,CAAC;CAChC,CAAC,MAAM;EAAE,MAAM;EAAI,KAAK;CAAO,CAAC;CAChC,CAAC,MAAM;EAAE,MAAM;EAAI,KAAK;CAAO,CAAC;CAChC,CAAC,MAAM;EAAE,MAAM;EAAI,KAAK;CAAO,CAAC;AAClC;;;;;;AAOA,MAAM,iBAAiB,OAAO,cAAc;CAC1C,MAAM,UAA8C,CAClD;EAAE,MAAM;EAAQ,MAAM;CAAU,GAChC;EAAE,MAAM;EAAO,MAAM;CAAO,CAC9B;CACA,MAAM,UAAsC;EAAE,OAAO;EAAM,QAAQ;CAAK;CACxE,OAAOC,eAA4B;EACjC,MAAMC;EACN;EAEA,MAAMC,YAAyB,SAAS,OAAO,IAAI;EACnD,YAAY;EACZ,UAAU;EACV,GAAG;CACL,CAAC;AACH,CAAC;;AAGD,MAAM,iBACJ,GACA,WAEA,OAAO,WAAW,KAAK,OAAO,UAC5BC,OAAY;CACV,YAAY,EAAE;CACd;CACA,SAAS,OAAO,SAAS,QAAQ,OAAO,SAAS;CACjD,GAAI,QAAQ,MAAM,IAAI,EAAE,OAAO,IAAK,QAAQ,EAAG,IAAI,CAAC;AACtD,CAAC,CACH;;;;;;;;;;;;;;;AAgBF,MAAM,mBACJ,GACA,MACA,WACA,mBAEA,OAAO,IAAI,aAAa;CACtB,MAAM,SAAS,OAAO;CACtB,MAAM,aAAa,OAAO,KAAK,KAAK,SAAS;EAAE,IAAI,KAAK,IAAI;EAAM,OAAO,IAAI;CAAM,EAAE;CACrF,OAAO,EAAE,SACP,MACA,EAAE,QAAQ,eACR,EAAE,SACF,WAAW,KAAK,KAAK,UAAU,EAAE,IAAI,iBAAiB,OAAO,EAAE,UAAU,IAAI,IAAI,IAAI,KAAK,CAAC,CAC7F,CACF;CACA,MAAM,MAAM,CAAC,GAAG,WAAW,GAAG,UAAU;CACxC,OAAO,OAAO,QACZ,cAAc,GAAG,MAAM,IACtB,QAAQ,UACP,iBAAiB,GAAG,MAAM,KAAK,SAAS,UAAU,cAChDC,mBAAgC;EAC9B,MAAM,OAAO;EACb,SAAS,oBAAoB,QAAQ,OAAO,UAAU,KAAA,IAAY,WAAW,OAAO,MAAM,KAAK;EAC/F,WAAW,OAAO;EAClB,SAAS,OAAO;EAChB,MAAM;EACN,SAAS;GAAE,gBAAgB;GAAU,oBAAoB;EAAU;EACnE,WAAW;CACb,CAAC,CACH,GACF;EAAE,aAAa;EAAG,SAAS;CAAK,CAClC;AACF,CAAC;;AAGH,MAAM,2BAAiC,MACrC,OAAO,IAAI,aAAa;CACtB,MAAM,OAAO;CACb,OAAO,EAAE,SACP,MACA,EAAE,QAAQ,eACR,EAAE,SACF,SAAS,KAAK,CAAC,IAAI,QAAQ,UAAU,EAAE,IAAI,EAAE,QAAQ,IAAI,OAAO,EAAE,UAAU,IAAI,KAAK,CAAC,CACxF,CACF;CACA,MAAM,YAAY,SAAS,KAAK,CAAC,IAAI,YAAY;EAAE;EAAI;CAAM,EAAE;CAE/D,MAAM,UAAUD,OAAY;EAC1B,YAAY,EAAE;EACd,OAAOE,GAAa,OAAO,MAAM;EACjC,SAAS,CAAC;GAAE,OAAO;GAAQ,WAAW;EAAO,CAAC;EAC9C,OAAO;CACT,CAAC;CACD,MAAM,kBAAkB,OAAO,iBAC7B,GACA,MACA,WACA,UACC,UAAU,cACT,iCAAiC,KAAK,UAAU,QAAQ,EAAE,QAAQ,KAAK,UAAU,SAAS,GAC9F;CAEA,MAAM,QAAQF,OAAY;EACxB,YAAY,EAAE;EACd,OAAOE,GAAa,OAAO,MAAM;EACjC,SAAS,CAAC;GAAE,OAAO;GAAQ,WAAW;EAAO,CAAC;EAC9C,OAAO;EACP,QAAQ,gBAAgB,gBAAgB,SAAS;CACnD,CAAC;CACD,OAAO,iBACL,GACA,MACA,WACA,QACC,UAAU,cACT,yBAAyB,KAAK,UAAU,QAAQ,EAAE,QAAQ,KAAK,UAAU,SAAS,GACtF;CAEA,OAAO,gBAAgB,GAAG,MAAM,WAAW,EAAE,QAAQ,IAAI,SAAS,MAAM;AAC1E,CAAC;;AAGH,MAAM,wBAA8B,EAAE,SAAS,SAAS,MAAM,OAAO,eACnE,OAAO,IAAI,aAAa;CACtB,MAAM,OAAO;CACb,MAAM,UAAU,OAAO,SAAS,MAAM,QAAQ,QAAQ,SAAS,MAAM,CAAC,KAAK,gBAAgB,CAAC,CAAC;CAC7F,OAAO,MACL,MACA,QAAQ,WAAW,KAAK,QAAQ,EAAE,EAAE,OAAO,KAC3C,iCAAiC,KAAK,UAAU,QAAQ,KAAK,QAAQ,IAAI,EAAE,CAAC,GAC9E;AACF,CAAC;;AAGH,MAAM,6BAAmC,EAAE,SAAS,SAAS,UAAU,OAAO,eAC5E,OAAO,IAAI,aAAa;CACtB,MAAM,OAAO;CACb,MAAM,QAAqB,EAAE,eAAe,GAAG,QAAQ,cAAc,QAAQ;CAC7E,MAAM,MAAM,OAAO,SAAS,MAAM,QAAQ,gBAAgB,KAAK,CAAC;CAChE,OAAO,MACL,OACC,IAAI,aAAa,OAAO,GACzB,uEAAuE,IAAI,UAAU,EACvF;AACF,CAAC;;;;;AAMH,MAAM,2BAAiC,MACrC,OAAO,IAAI,aAAa;CACtB,MAAM,EAAE,SAAS,SAAS,UAAU,MAAM,OAAO,aAAa;CAC9D,MAAM,OAAO;CACb,MAAM,UAAU,OAAO,EAAE,SAAS,IAAI;CACtC,MAAM,SAAS,OAAO,SACpB,MACA,QAAQ,eAAe,SAAS,CAC9B,EAAE,OAAO,UAAU,GAAG,MAAM,QAAQ,GACpC,EAAE,IAAI,UAAU,GAAG,MAAM,UAAU,EAAE,GAAG,EAAE,CAAC,CAC7C,CAAC,CACH;CACA,OAAO,MACL,MACA,OAAO,gBAAgB,cAAc,UAAU,GAC/C,wDAAwD,UAAU,EAAE,QAAQ,OAAO,gBAAgB,UAAU,EAC/G;CACA,OAAO,MACL,OACC,OAAO,YAAY,CAAC,EAAA,CAAG,MACrB,UAAU,MAAM,aAAa,YAAY,MAAM,eAAe,UAAU,CAC3E,GACA,mEACF;CACA,MAAM,SAAS,OAAO,SAAS,MAAM,QAAQ,QAAQ,SAAS,MAAM,CAAC,QAAQ,CAAC,CAAC;CAC/E,OAAO,MACL,MACA,IAAI,qBAAqB,MAAM,GAC/B,6EACF;CAEA,OAAO,MACL,OACA,OAHoB,SAAS,MAAM,QAAQ,QAAQ,SAAS,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAA,CAGtE,WAAW,GAClB,2EACF;AACF,CAAC;;;;;;AAOH,MAAM,uBAA6B,MACjC,OAAO,IAAI,aAAa;CACtB,MAAM,EAAE,SAAS,SAAS,MAAM,OAAO,aAAa;CACpD,MAAM,OAAO;CACb,MAAM,UAAU,OAAO,EAAE,SAAS,IAAI;CACtC,MAAM,CAAC,UAAU,OAAO,SAAS,MAAM,QAAQ,QAAQ,SAAS,MAAM,CAAC,GAAG,CAAC,CAAC;CAC5E,OAAO,MAAM,MAAM,WAAW,KAAA,GAAW,uCAAqC;CAE9E,MAAM,WAAW,OACf,QAAQ,eAAe,SAAS,CAC9B,EAAE,SAAS,UAAU,GAAG,cAAc,MAAM;EAAE,YAAY;EAAM;CAAG,CAAC,CACtE,CAAC;CAKH,OAAO,EAAE,wBAAwB,MAAM,QAAQ,GAAG,GAAG,cAAc,MAAM,eAAe;CAExF,MAAM,CAAC,SAAS,OAAO,SAAS,MAAM,QAAQ,QAAQ,SAAS,MAAM,CAAC,GAAG,CAAC,CAAC;CAC3E,OAAO,MACL,MACA,OAAO,YAAY,QAAQ,WACzB,KAAK,UAAU,OAAO,KAAK,MAAM,KAAK,UAAU,QAAQ,KAAK,GAC/D,oDAAoD,KAAK,UAAU,QAAQ,KAAK,EAAE,cAAc,QAAQ,QAAQ,QAAQ,KAAK,UAAU,OAAO,KAAK,EAAE,cAAc,OAAO,QAAQ,EACpL;CAEA,OAAO,OAAO,KAAK,QAAQ,OAAO,CAAC;CACnC,MAAM,QAAQ,OAAO,SAAS,MAAM,QAAQ,QAAQ,SAAS,MAAM,CAAC,OAAO,CAAC,CAAC;CAC7E,OAAO,MAAM,MAAM,IAAI,qBAAqB,KAAK,GAAG,sCAAsC;CAE1F,OAAO,MACL,OACC,OAAO,EAAE,SAAS,IAAI,OAAO,SAC9B,6CACF;AACF,CAAC;;AAGH,MAAM,oBAAoB;;;;;;;;;;;AAY1B,MAAM,aAAa;;AAGnB,IAAI,WAAW;;AAGf,MAAM,UAAU;AAEhB,MAAM,kBAAqB,WACzB,OAAO,KACL,OAAO,MAAM;CAAE,OAAO;CAAmB,QAAQ,UAAU,MAAM,SAAS;AAAe,CAAC,CAC5F;;AAGF,MAAM,iBAAiB,gBAA6D;CAElF,MAAM,QAAQ,SACZ,QAAQ,IACJ,OAAO,OACP,OAAO,QAAQ,cAAc,YAC3B,UAAU,OAAO,OAAO,OAAO,QAAQ,OAAO,UAAU,KAAK,OAAO,CAAC,CAAC,CACxE;CACN,OAAO,KAAK,UAAU;AACxB;;;;;;;;;;;;;;;;;AAkBA,MAAM,8BAAoC,MACxC,OAAO,IAAI,aAAa;CACtB,MAAM,OACJ;CACF,MAAM,UAAU,OAAO,EAAE,SAAS,IAAI;CACtC,MAAM,MAAM;CACZ,OAAO,EAAE,SACP,MACA,EAAE,QAAQ,eAAe,EAAE,SAAS,CAAC,EAAE,IAAI,UAAU,GAAG,EAAE,MAAM,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CACjF;CAIA,MAAM,OAAoB,EAAE,eAAe,GAAG,EAAE,QAAQ,cAAc,OAAO;CAC7E,MAAM,cAAc,OAAO,EAAE,SAAS,MAAM,EAAE,QAAQ,gBAAgB,IAAI,CAAC,EAAA,CAAG,EAAE,aAAa;CAC7F,OAAO,EAAE,MACP,MACA,eAAe,EAAE,WACjB,eAAe,cAAc,EAAE,UAAU,EAAE,WAAW,UAAU,CAClE;CAEA,YAAY;CACZ,MAAM,OAAO,GAAG,EAAE,QAAQ,cAAc,QAAQ;CAChD,MAAM,SAAmB;EACvB,SAAS,OAAO,SAAS,KAAW;EACpC,SAAS,OAAO,SAAS,KAAW;CACtC;CACA,UAAU,IAAI,MAAM,MAAM;CAC1B,MAAM,aAAa,YAAoB,aACrC,EAAE,SAAS,YAAY,QAAQ,MAAM;EAAE,YAAY,EAAE;EAAM,IAAI;EAAK,MAAM;CAAS,CAAC;CAgEtF,OA9DY,OAAO,IAAI,aAAa;EAClC,MAAM,QAAQ,OAAO,OAAO,UAC1B,eAAe,EAAE,QAAQ,eAAe,EAAE,SAAS,CAAC,UAAU,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CACpF;EAEA,MAAM,aAAa,OAAO,OAAO,UAC/B,SAAS,MAAM,OAAO,OAAO,CAAC,CAAC,KAAK,OAAO,GAAG,KAAA,CAAS,CAAC,GACxD,OAAO,KAAK,MAAM,KAAK,KAAK,CAAC,CAC/B;EACA,IAAI,eAAe,KAAA,GAAW;GAC5B,MAAM,UAAU,KAAK,gBAAgB,UAAU;GAC/C,IAAI,OAAO,OAAO,OAAO,KAAK,sBAAsB,QAAQ,OAAO,QAAQ,IAAI,GAC7E,OAAO,OAAO,EAAE,MACd,MACA,OACA,GAAG,QAAQ,KAAK,qDAClB;GAEF,OAAO,OAAO,EAAE,MACd,MACA,OACA,OAAO,OAAO,OAAO,IACjB,gCAAgC,QAAQ,MAAM,YAC9C,GAAG,QAAQ,KAAK,6GACtB;EACF;EAEA,MAAM,WAAW,OAAO,SAAS,KAAW;EAC5C,MAAM,SAAS,OAAO,OAAO,UAC3B,eAAe,EAAE,QAAQ,eAAe,MAAM,CAAC,UAAU,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,KACpF,OAAO,SAAS,SAAS,QAAQ,UAAU,KAAA,CAAS,CAAC,CACvD,CACF;EACA,MAAM,cAAc,SAAS,OAAO,QAAQ;EAC5C,QAAQ,EAAE,aAAa,cAAA,CAAe,WAAW;EACjD,OAAO,SAAS,QAAQ,OAAO,SAAS,KAAA,CAAS;EACjD,MAAM,YAAY,OAAO,OAAO,KAAK,MAAM,KAAK,KAAK,CAAC;EACtD,MAAM,WAAW,OAAO,OAAO,KAAK,MAAM,KAAK,MAAM,CAAC;EACtD,MAAM,SAAS,IAAI,UACjB,CACE,CAAC,SAAS,SAAS,GACnB,CAAC,QAAQ,QAAQ,CACnB,IACC,CAAC,OAAO,UAAU,OAAO,IAAI,KAAK,gBAAgB,IAAI,IAAI,WAAW;GAAE;GAAO;EAAM,EAAE,CACzF;EACA,IAAI,OAAO,OAAO,MAAM,GACtB,OAAO,OAAO,EAAE,MACd,MACA,OACA,OAAO,OAAO,MAAM,MAAM,qBAAqB,OAAO,MAAM,MAAM,SACpE;EAGF,MAAM,CAAC,UAAU,OAAO,EAAE,SAAS,MAAM,EAAE,QAAQ,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;EACpF,MAAM,SAAS,QAAQ,MAAA,EAA+C;EACtE,OAAO,EAAE,MACP,MACA,UAAU,GACV,sBAAsB,IAAI,mDAAmD,MAAM,oEACrF;CACF,CAES,CAAC,CAAC,KACT,OAAO,SACL,OAAO,WAAW,UAAU,OAAO,IAAI,CAAC,CAAC,CAAC,KACxC,OAAO,QAAQ,SAAS,QAAQ,OAAO,SAAS,KAAA,CAAS,CAAC,CAC5D,CACF,CACF;AACF,CAAC;;;;;;;;AASH,MAAM,+BAAqC,MACzC,OAAO,IAAI,aAAa;CACtB,MAAM,EAAE,SAAS,SAAS,OAAO,UAAU,QAAQ;CACnD,MAAM,OAAO;CACb,MAAM,aAAa,EAAE;CACrB,MAAM,OAAO;CACb,MAAM,OAAO;CACb,MAAM,UAAU,OAAO,EAAE,SAAS,IAAI;CACtC,OAAO,SACL,MACA,QAAQ,eAAe,SAAS,CAC9B,IAAI,UAAU,GAAG,YAAY,MAAM,EAAE,GAAG,EAAE,CAAC,GAC3C,IAAI,UAAU,GAAG,YAAY,MAAM,EAAE,GAAG,EAAE,CAAC,CAC7C,CAAC,CACH;CACA,MAAM,UAAU,OAAO,SACrB,MACA,QAAQ,SAAS,SAASF,OAAY,EAAE,WAAW,CAAC,CAAC,CACvD,EAAA,CAAG,KAAK,UAAU,MAAM,EAAE;CAC1B,OAAO,MACL,MACA,OAAO,SAAS,IAAI,KAAK,OAAO,SAAS,IAAI,GAC7C,+EAA+E,KAAK,UAAU,MAAM,GACtG;CAEA,OAAO,SACL,MACA,QAAQ,eAAe,SAAS,CAAC,IAAI,UAAU,GAAG,YAAY,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAChF;CACA,MAAM,CAAC,WAAW,OAAO,SAAS,MAAM,QAAQ,QAAQ,SAAS,YAAY,CAAC,IAAI,CAAC,CAAC;CACpF,OAAO,MACL,OACC,SAAS,MAAA,EAA+C,MAAM,GAC/D,0DAA0D,KAAK,UAAU,KAAK,UAAU,SAAS,KAAK,GACxG;CAEA,OAAO,SACL,MACA,QAAQ,eAAe,SAAS,CAC9B,EAAE,SAAS,UAAU,GAAG,OAAO,MAAM;EAAE;EAAY,IAAI;CAAK,CAAC,CAC/D,CAAC,CACH;CACA,MAAM,UAAU,OAAO,SAAS,MAAM,QAAQ,QAAQ,SAAS,YAAY,CAAC,IAAI,CAAC,CAAC;CAClF,OAAO,MACL,MACA,IAAI,qBAAqB,OAAO,GAChC,mEAAmE,KAAK,gBAAgB,KAAK,UAAU,QAAQ,EAAE,EAAE,KAAK,GAC1H;AACF,CAAC;;;;;;;AAQH,MAAM,yBAA+B,MACnC,OAAO,IAAI,aAAa;CACtB,MAAM,EAAE,SAAS,SAAS,UAAU,MAAM,OAAO,aAAa;CAC9D,MAAM,OACJ;CACF,MAAM,UAAU,OAAO,EAAE,SAAS,IAAI;CAKtC,MAAM,aAAY,OAJI,SACpB,MACA,QAAQ,eAAe,SAAS,CAAC,EAAE,OAAO,UAAU,GAAG,MAAM,QAAQ,CAAC,CAAC,CACzE,EAAA,CACyB,YAAY,CAAC,EAAA,CAAG,MACtC,UAAU,MAAM,aAAa,YAAY,MAAM,eAAe,UAAU,CAC3E;CACA,OAAO,MACL,MACA,aAAa,KAAA,GACb,mEACF;CACA,MAAM,SAAS,OAAO,SAAS,MAAM,QAAQ,WAAW,OAAO,CAAC;CAChE,OAAO,MACL,MACA,OAAO,MACJ,UACC,MAAM,aAAa,YACnB,MAAM,eAAe,UAAU,KAC/B,MAAM,WAAW,UAAU,MAC/B,GACA,+FAA+F,KAAK,UAAU,UAAU,MAAM,EAAE,SAAS,KAAK,UAAU,MAAM,GAChK;AACF,CAAC;;;;;;;;;;;AAYH,MAAM,eACJ,MACA,UAEA,KAAK,WAAW,MAAM,UACtB,KAAK,OACF,OAAO,UAAU,MAAM,OAAO,MAAM,MAAM,EAAE,MAAM,MAAM,YAAY,MAAM,MAAM,EAAE,OACrF;;AAGF,MAAM,mBAAmB,YACvB,QAAQ,KAAK,UAAU,GAAG,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,CAAC,KAAK,IAAI;AAElE,MAAM,iCAAuC,MAC3C,OAAO,IAAI,aAAa;CACtB,MAAM,OAAO,EAAE,QAAQ;CACvB,IAAI,SAAS,KAAA,GAAW;CACxB,MAAM,OAAO;CACb,MAAM,SAAS,OAAO;CACtB,MAAM,OAAOE,GAAa,OAAO,MAAM;CACvC,MAAM,SAAS,CAAC;EAAE,OAAO;EAAQ,WAAW;CAAgB,CAAC;CAC7D,MAAM,UAAwC;EAC5CF,OAAY,EAAE,YAAY,EAAE,SAAS,CAAC;EACtCA,OAAY,EAAE,YAAY,EAAE,KAAK,CAAC;EAClCA,OAAY;GAAE,YAAY,EAAE;GAAU,OAAO;GAAM,SAAS;GAAQ,OAAO;EAAE,CAAC;EAC9EA,OAAY;GAAE,YAAY,EAAE;GAAU,OAAO;GAAM,SAAS;GAAQ,OAAO;GAAG,QAAQ;EAAK,CAAC;EAC5F,GAAG,cAAc,GAAG,MAAM;CAC5B;CACA,MAAM,UAAU,OAAO,EAAE,SAAS,MAAM,KAAK,EAAE,SAAS,OAAO,CAAC;CAChE,OAAO,EAAE,MACP,MACA,QAAQ,WAAW,QAAQ,QAC3B,YAAY,QAAQ,OAAO,oCAAoC,QAAQ,QACzE;CACA,OAAO,OAAO,QACZ,UACC,QAAQ,UACP,OAAO,IAAI,aAAa;EACtB,MAAM,SAAS,OAAO,EAAE,SAAS,MAAM,EAAE,QAAQ,SAAS,EAAE,SAAS,MAAM,CAAC;EAC5E,MAAM,WAAW,QAAQ,UAAU,CAAC;EACpC,OAAO,EAAE,MACP,MACA,YAAY,UAAU,MAAM,GAC5B,UAAU,MAAM,SAAS,OAAO,WAAW,oBAAoB,gBAAgB,MAAM,EAAE,wBAAwB,gBAAgB,QAAQ,EAAE,EAC3I;CACF,CAAC,GACH;EAAE,aAAa;EAAG,SAAS;CAAK,CAClC;CACA,MAAM,OAAO,OAAO,EAAE,SAAS,MAAM,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;CACxD,OAAO,EAAE,MACP,MACA,IAAI,qBAAqB,IAAI,GAC7B,2CAA2C,KAAK,OAAO,OACzD;AACF,CAAC;;AAGH,MAAM,QAA6B;CACjC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;;;;;;;;AAYA,MAAa,yBACX,SACA,YAC2C;CAC3C,MAAM,UAAuB,EAAE,eAAe,SAAS,iBAAiB,mBAAmB;CAC3F,MAAM,WAAW,SAAS,kBAAkB;CAC5C,OAAO,QAAQ,gBAAgB,OAAO,CAAC,CAAC,KACtC,OAAO,UACJ,UACC,IAAI,kBAAkB;EACpB,MAAM;EACN,SAAS,gCAAgC,MAAM;CACjD,CAAC,CACL,GACA,OAAO,SAAS,QAAQ;EACtB,MAAM,WAAW,IAAI,oBAAoB;EACzC,IAAI,aAAa,UACf,OAAO,OAAO,KACZ,IAAI,kBAAkB;GACpB,MAAM;GACN,SAAS,eAAe,kBAAkB,iBAAiB,UAAU,QAAQ;EAC/E,CAAC,CACH;EAEF,MAAM,UAAU,YAAY,SAAS,SAAS,UAAU,SAAS,sBAAsB,CAAC;EACxF,OAAO,OAAO,QAAQ,QAAQ,SAAS,KAAK,OAAO,GAAG,EAAE,SAAS,KAAK,CAAC;CACzE,CAAC,CACH;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACxpCA,MAAa,aAAa,WAA+C;CACvE,aAAa,IAAI,OAAO,MAAM,KAAK,SAAS,KAAK,UAAU,CAAC;CAC5D,MAAM,MAAM,SAAS,SAAS,KAAK,IAAI,KAAK,QAAQ;EAAE,YAAY,KAAK;EAAY;CAAG,EAAE,CAAC;AAC3F;;AAGA,MAAM,WAAW,YACf,IAAI,qBAAqB,QAAQ,WAAW,KAAK,IAAI,qBAAqB,QAAQ,IAAI;;;;;;AAOxF,MAAa,OAAO,WAA8D,EAChF,aAAa,YACX,OAAO,QAAQ,QAAQ,SAAS,QAAQ,MAAM,OAAO,GAAG;CACtD,aAAa;CACb,SAAS;AACX,CAAC,EACL;;AAGA,MAAM,WAAW,MAAwB,YACvC,KACG,WAAW,OAAO,CAAC,CACnB,KACC,OAAO,YAAY,UACjB,OAAO,WACL,uEACA,KACF,CACF,CACF;;;;;;;;AASJ,MAAaG,SACX,SAEA,OAAO,IAAI,aAAa;CAEtB,MAAM,eAAe,QAAO,OADT,gBAAA,CACa;CAChC,OAAO,OAAO,WACZ,OAAO,QACL,aAAa,KAAK,KAChB,OAAO,SAAS,UAAU;EACxB,MAAM,UAAU,UAAU,KAAK;EAC/B,OAAO,QAAQ,OAAO,IAAI,OAAO,OAAO,QAAQ,MAAM,OAAO;CAC/D,CAAC,CACH,CACF,CACF;AACF,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACzCH,MAAa,UAAU;;AAGvB,MAAa,UAAU,SAA0B,SAAS;AAuC1D,MAAM,aAA0B;CAAE,UAAU,OAAO;CAAmB,UAAU;CAAO,MAAM,CAAC;AAAE;;;;;;;AAWhG,MAAa,QACX,YAEA,OAAO,IAAI,aAAa;CACtB,MAAM,SAAS,SAAS,SAAS,SAAS,gBAAgB,QAAQ,QAAQ,CAAC;CAC3E,MAAM,SAAS,SAAS,SAAS,SAAS,gBAAgB,QAAQ,OAAO,GAAG,CAAC;CAC7E,MAAM,QAAQ,KAAK,IAAI,GAAG,QAAQ,OAAO,MAAM;CAC/C,MAAM,SAAS,OAAO,IAAI,KAAK,QAAQ,MAA2B,CAAC;CACnE,MAAM,QAAQ,OAAO,OAAO;CAE5B,MAAM,WAAW,KAA2C,QAC1D,OAAO,UAAU,QAAQ,IAAI,KAAK,GAAG,SAAS,UAAU;CAG1D,MAAM,SAAS,KAAa,QAC1B,IAAI,OAAO,SAAS,QAAkE;EAEpF,MAAM,OADQ,QAAQ,KAAK,GACV,CAAC,CAAC,KAAK,QAAQ,OAAO,MAAM,KAAK,MAAM;EACxD,IAAI,KAAK,UAAU,OAAO,OAAO,CAAC,OAAO,GAAG;EAC5C,OAAO,CACL,MACA,QAAQ,IAAI,KAAK,KAAK;GAAE,UAAU;GAAK,UAAU;GAAO,MAAM,CAAC,GAAG,MAAM,GAAG;EAAE,CAAC,CAChF;CACF,CAAC;CAEH,MAAM,QAAQ,QAAgB,KAAa,QACzC,OAAO,QAAQ,MAAM,KAAK,GAAG,IAAI,YAC/B,UACI,QACG,KAAK,QAAQ,OAAO,CAAC,CACrB,KACC,OAAO,YAAY,UACjB,OAAO,WAAW,oDAAoD,KAAK,CAC7E,CACF,IACF,OAAO,SAAS,qDAAqD,CAC3E;CAGF,MAAM,UAAU,KAAa,QAC3B,IAAI,OAAO,SAAS,QAAmE;EACrF,MAAM,QAAQ,QAAQ,KAAK,GAAG;EAC9B,IAAI,MAAM,MAAM,YAAY,QAAQ,OAAO,CAAC,QAAQ,GAAG;EACvD,IAAI,MAAM,UAAU,OAAO,CAAC,QAAQ,GAAG;EACvC,OAAO,CAAC,SAAS,QAAQ,IAAI,KAAK,KAAK;GAAE,GAAG;GAAO,UAAU;EAAK,CAAC,CAAC;CACtE,CAAC;CAEH,MAAM,QAAQ,WACZ,OAAO,IAAI,aAAa;EACtB,MAAM,MAAM,QAAQ,MAAM,MAAM;EAChC,MAAM,MAAM,OAAO,MAAM;EACzB,MAAM,WAAW,OAAO,OAAO,KAAK,GAAG;EACvC,IAAI,aAAa,QAAQ,OAAO,OAAO,KAAK,QAAQ,KAAK,GAAG;EAC5D,IAAI,aAAa,SAAS;EAC1B,MAAM,QAAQ,QAAQ,OAAO,IAAI,IAAI,MAAM,GAAG,GAAG;EACjD,MAAM,OAAO,KAAK,IAAI,GAAG,MAAM,WAAW,SAAS,GAAG;EACtD,OAAO,OAAO,OACZ,OAAO,MAAM,SAAS,OAAO,IAAI,CAAC,CAAC,CAAC,KAClC,OAAO,QAAQ,MAAM,iBAAiB,GACtC,OAAO,SAAS,OAAO,KAAK,QAAQ,KAAK,EAAE,CAAC,CAC9C,GACA,KACF;CACF,CAAC;CAEH,OAAO,EACL,aAAa,YACX,QAAQ,WAAW,OAAO,CAAC,CAAC,KAC1B,OAAO,YAAY,UACjB,OAAO,WAAW,wDAAwD,KAAK,CAAC,CAAC,KAC/E,OAAO,GAAG,IAAI,MAAc,CAAC,CAC/B,CACF,GACA,OAAO,SAAS,YACd,OAAO,QACL,IAAI,WAAW,UAAU,GAAG,MAAM,QAAQ,MAAM,CAAC,MAAM,QAAQ,MAAM,CAAC,CAAC,GACvE,MACA;EACE,aAAa;EACb,SAAS;CACX,CACF,CACF,CACF,EACJ;AACF,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACrKH,MAAa,UAAU,eAA8B;;AAGrD,MAAa,QAAQ,YAAoB,OAAe,UACtD,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,KAAK;;AAGxC,MAAa,gBAAgB,UAAyB;CACpD,MAAM,QAAQ,MAAM,QAAQ,GAAG;CAC/B,OAAO,UAAU,KAAK,QAAQ,MAAM,MAAM,GAAG,KAAK;AACpD;;AAGA,MAAa,iBACX,UAC6C;CAC7C,MAAM,sBAAM,IAAI,IAAiC;CACjD,IAAI,QAAQ,MAAM,QAAQ,CAAC,MAAM,UAAU;EACzC,MAAM,SAAS,IAAI,IAAY,KAAK,QAAQ;EAC5C,IAAI,QAAQ,OAAO,OAAO,KAAK,KAAK,IAAI,SAAS;GAC/C,IAAI,KAAK,SAAS,OAAO,OAAO,IAAI,KAAK,GAAG;EAC9C,CAAC;EACD,IAAI,IAAI,MAAM,MAAM;CACtB,CAAC;CACD,OAAO;AACT;AAEA,MAAM,aAAa,UACjB,EAAE,SAAS,KAAK,KAAK,EAAE,SAAS,KAAK,KAAK,EAAE,UAAU,KAAK;;AAG7D,MAAM,eACJ,cACyF;CACzF,IAAI,UAAU,SAAS,aAAa,UAAU,OAAO,QAAQ,UAAU,UAAU,KAAK,GACpF,OAAO,CAAC;EAAE,OAAO,UAAU;EAAO,OAAO,UAAU;CAAM,CAAC;CAE5D,IAAI,UAAU,SAAS,OAAO,OAAO,UAAU,WAAW,QAAQ,WAAW;CAC7E,OAAO,CAAC;AACV;;;;;;;AAQA,MAAa,kBACX,QACA,cACU;CACV,MAAM,WACJ,cAAc,KAAA,IACV,KAAA,IACA,YAAY,OAAO,KAAK,CAAC,CAAC,MAAM,cAAc,UAAU,IAAI,UAAU,KAAK,CAAC;CAClF,OAAO,aAAa,KAAA,IAChB,OAAO,OAAO,UAAU,IACxB,KAAK,OAAO,YAAY,SAAS,OAAO,SAAS,KAAK;AAC5D;;;;;;;AAQA,MAAa,kBACX,YACA,WACA,WACuB;CACvB,MAAM,yBAAS,IAAI,IAAW,CAAC,OAAO,UAAU,CAAC,CAAC;CAClD,IAAI,cAAc,KAAA,GAAW,OAAO;CACpC,IAAI,QAAQ,CAAC,OAAO,UAAU,OAAO,QAAQ,IAAI,UAAU;EACzD,IAAI,CAAC,EAAE,gBAAgB,KAAK,GAAG;EAC/B,IAAI,QAAQ,YAAY,UAAU;GAChC,MAAM,aAAc,MAAkC;GACtD,IAAI,UAAU,UAAU,GAAG,OAAO,IAAI,KAAK,YAAY,OAAO,UAAU,CAAC;EAC3E,CAAC;CACH,CAAC;CACD,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;ACpDA,MAAa,eAAe,QAAQ,QAAsB,uCAAuC;AAOjG,MAAM,gBAAgB;;AAGtB,MAAa,gBAAiE,OAAO,IACnF,aAAa;CACX,MAAM,SAAS,OAAO,IAAI,qBAAK,IAAI,IAAmB,CAAC;CACvD,MAAM,OAAO,OAAO,IAAI,qBAAK,IAAI,IAAiD,CAAC;CACnF,MAAM,QAAQ,OAAO,OAAO;CAE5B,MAAM,UAAU,WACd,OAAO,IAAI,aAAa;EACtB,MAAM,YAAY,OAAO,IAAI,IAAI,IAAI,EAAA,CAAG,IAAI,MAAM;EAClD,IAAI,aAAa,KAAA,GAAW,OAAO;EACnC,MAAM,MAAM,OAAO,OAAO,SAA+B,EAAE,UAAU,cAAc,CAAC;EACpF,OAAO,MAAM,aAAa,OAAO,OAAO,SAAS,GAAG,CAAC;EACrD,OAAO,IAAI,OAAO,OAAO,QAAQ,IAAI,IAAI,GAAG,CAAC,CAAC,IAAI,QAAQ,GAAG,CAAC;EAC9D,OAAO;CACT,CAAC;CAEH,OAAO;EACL,WAAW,QAAQ,QAAQ,QACzB,OAAO,IAAI,aAAa;GACtB,MAAM,MAAM,OAAO,MAAM;GACzB,OAAO,IAAI,OAAO,SAAS,QACzB,IAAI,IAAI,GAAG,CAAC,CAAC,IAAI,QAAQ;IAAE;IAAQ,WAAW,MAAM,SAAS,SAAS,GAAG;GAAE,CAAC,CAC9E;EACF,CAAC;EACH,UAAU,WACR,OAAO,IAAI,aAAa;GACtB,MAAM,SAAS,IAAI,IAAI,MAAM;GAC7B,MAAM,MAAM,OAAO,MAAM;GAEzB,MAAM,uBAAO,IAAI,IAAmB;GACpC,IAAI,QAAQ,OAAO,IAAI,IAAI,MAAM,IAAI,CAAC,QAAQ,WAAW;IACvD,IAAI,MAAM,YAAY,KAAK,KAAK,IAAI,QAAQ,KAAK;GACnD,CAAC;GACD,OAAO,IAAI,IAAI,QAAQ,IAAI;GAC3B,MAAM,SAAS,OAAO,IAAI,IAAI,IAAI;GAClC,OAAO,OAAO,QACZ,OACC,CAAC,QAAQ,WACR,OAAO,IAAI,aAAa;IACtB,MAAM,UAAU,CAAC,GAAG,MAAM,CAAC,CAAC,QAAQ,UAAU,MAAM,OAAO,IAAI,KAAK,CAAC;IACrE,IAAI,IAAI,qBAAqB,OAAO,GAAG;IACvC,MAAM,MAAM,OAAO,IAAI,MAAM;IAC7B,IAAI,QAAQ,KAAA,GAAW,OAAO,OAAO,QAAQ,KAAK,OAAO;GAC3D,CAAC,GACH;IAAE,aAAa;IAAG,SAAS;GAAK,CAClC;EACF,CAAC;EACH,QAAQ,WACN,OAAO,IAAI,aAAa;GACtB,MAAM,MAAM,OAAO,OAAO,MAAM;GAChC,MAAM,eAAe,OAAO,OAAO,UAAU,GAAG;GAChD,OAAO,EAAE,MAAM,OAAO,KAAK,YAAY,EAAE;EAC3C,CAAC;CACL;AACF,CACF;;;;;;;;;;;;;;;;;;;;;;;ACxDA,MAAM,iBACJ,MACA,cACoC;CACpC,MAAM,SAAS,IAAI,IAAI,KAAK,QAAQ,KAAK,EAAE,IAAI,YAAY,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;CAC7E,MAAM,OAAO,IAAI,IAAI,KAAK,WAAW,KAAK,EAAE,IAAI,YAAY,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;CAC9E,MAAM,yBAAS,IAAI,IAAwB,CAACC,OAAoB,KAAK,UAAU,CAAC,CAAC;CACjF,MAAM,MAAM,IAAI,wBAAwB,KAAK,GAAG,IAAI,KAAK,MAAM,CAAC,GAAG,OAAO,KAAK,CAAC;CAChF,IAAI,QAAQ,MAAM,OAAO;EACvB,IAAI,QACFC,eAA4B,KAAK,YAAY,WAAW;GACtD,UAAU,KAAK,IAAI,EAAE;GACrB,UAAU,OAAO,IAAI,EAAE;EACzB,CAAC,IACA,UAAU;GACT,OAAO,IAAI,KAAK;EAClB,CACF;CACF,CAAC;CACD,OAAO;AACT;;AAGA,MAAa,QAAQ,YACnB,OAAO,IAAI,aAAa;CACtB,MAAM,YAAYC,cAA2B,QAAQ,KAAK;CAC1D,MAAM,YAAY,QAAQ,aAAa;CACvC,MAAM,MAAM,QAAQ,OAAO,SAAS,OAAO,SAAS,SAAS,SAAS,IAAI,CAAC;CAC3E,MAAM,UAAU,QAAQ,WAAW;CAGnC,MAAM,WAAW,MAAc,SAC7B,KAAK,KACH,OAAO,cAAc;EACnB,UAAU;EACV,cACE,OAAO,WACL,cAAc,KAAK,6DACrB;CACJ,CAAC,CACH;CAEF,MAAM,cAAc,QAClB,sBACA,QAAQ,QAAQ,KACd,OAAO,SAAS,YACd,QAAQ,OAAO,SACb,QAAQ,QACR,IAAI,IACF,QAAQ,KAAK,WACXC,eAA4B,QAAQ,UAAU,IAAI,OAAO,UAAU,CAAC,CACtE,CACF,GACA,GACF,CACF,CACF,CACF;CACA,OAAO;CACP,OAAO,OAAO,WACZ,OAAO,QAAQ,OAAO,MAAM,SAAS,CAAC,CAAC,KAAK,OAAO,QAAQ,WAAW,CAAC,CAAC,CAC1E;CAEA,OAAO;EACL,UAAU,UAAU;GAClB,MAAM,yBAAS,IAAI,IAAwB;GAC3C,IAAI,QAAQ,QAAQ,SAAS;IAC3B,IAAI,QAAQ,cAAc,MAAM,UAAU,IAAI,KAAK,UAAU,CAAC,IAAI,UAAU;KAC1E,OAAO,IAAI,KAAK;IAClB,CAAC;GACH,CAAC;GAED,OAAO,QAAQ,WAAW,QAAQ,OAAO,QAAQ,MAAM,CAAC,CAAC,CAAC,KAAK,OAAO,QAAQ,WAAW,CAAC;EAC5F;EACA,WAAW,OAAO,IAAI,aAAa;GAEjC,OAAO,EACL,OAAM,OAFa,QAAQ,OAAO,MAAM,QAAQ,MAAM,EAAA,CAE1C,KAAK,KACf,OAAO,KAAK,WAAW;IAErB,OAAO,CAAC,GAAG,IADa,IAAI,OAAO,IAAIC,YAAyB,CAC3C,CAAC,CAAC,CAAC,KAAK,gBAAgB;KAAE;KAAY,KAAK,CAAC;IAAE,EAAE;GACvE,CAAC,CACH,EACF;EACF,CAAC;CACH;AACF,CAAC;;;;;;;;;;;;;;;;;;;;;;;ACzFH,MAAM,gBAAgB;;AAGtB,MAAM,aAAa,WAAsD;CACvE,MAAM,KAAK,IAAI,eACb,SACC,OAAO,MAAM,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,UAAU,OAAO,KAAK,MAAM,aAC1E;CACA,OAAO,OAAO,MAAM,IAAI;EAAE,cAAc,KAAA;EAAW,SAAS,MAAM,OAAO,OAAO,IAAI,EAAE;CAAE,CAAC;AAC3F;;;;;AAMA,MAAM,eAAe,UAAkC;CACrD,MAAM,CAAC,UAAU;CACjB,OAAO,WAAW,KAAA,IAAY,QAAQ,OAAO;AAC/C;;;;;AAMA,MAAM,qBAAqB,SAAS,OAAO,GAAG;;AAG9C,IAAM,qBAAN,cAAiC,OAAO,YAGtC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC;;;;;;AAO/B,MAAM,kBAAkB;;AAGxB,IAAM,eAAN,cAA2B,OAAO,YAA6D,CAAC,CAC9F,gBACA,CAAC,CACH,CAAC,CAAC,CAAC;;AAGH,MAAM,gBAAgB;;AAGtB,MAAM,eAAe;;AAGrB,MAAM,aAAa,aACjB,KAAK,IAAI,cAAc,gBAAgB,MAAM,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4B5D,MAAa,mBACX,YAEA,OAAO,IAAI,aAAa;CACtB,MAAM,QAAQ,OAAO,MAAM;CAC3B,MAAM,SAAS,SAAS,UAAU;CAClC,MAAM,cAAc,KAAK,MAAM,SAAS,SAAS,SAAS,SAAS,WAAW,CAAC;CAC/E,MAAM,UAAU,OAAO,WAAW;CAClC,MAAM,OAAO,SAAS,QAAQ;CAC9B,MAAM,UAAU,SAAS,WAAW;CAIpC,MAAM,aACJ,SAEA,cAAc,IACV,KAAK,KACH,OAAO,cAAc;EACnB,UAAU,SAAS,OAAO,cAAc,eAAe;EACvD,cAAc,OAAO,KAAK,IAAI,aAAa,CAAC;CAC9C,CAAC,CACH,IACA;CAQN,MAAM,SAAS,MACZ,KAAqB,aAAa,QAAQ,KAAK,KAAK,SAAS,GAAG,CAAC,CACjE,KAAK,OAAO,IAAI,WAAW,CAAC;CAE/B,OAAO;EAGL,UAAU,YACR,MAAM,KAAK,QAAQ,QAAQ,KAAK,eAAe,OAAO,CAAC,CAAC,KACtD,OAAO,cAAc;GACnB,UAAU;GACV,cAAc,OAAO,WAAW,+CAA+C;EACjF,CAAC,GACD,OAAO,MACT;EACF,WAAW,OAAO,IAAI,aAAa;GACjC,MAAM,QAAQ,OAAO,MAAM,UAAkB;GAK7C,MAAM,SAAqC,EAAE,IAAI,SAAS,MAAM,MAAM,KAAA,EAAU;GAChF,IAAI,OAAO,OAAO,KAAA,GAAW;IAC3B,MAAM,QAAQ,OAAO,OAAO,KAC1B,OAAO,cAAc,kBAAkB,GACvC,OAAO,oBAAoB,OAAO,KAAa,CAAC,CAClD;IACA,IAAI,OAAO,OAAO,KAAK,GAAG,OAAO,KAAK,MAAM;GAC9C;GAIA,MAAM,SAAS,EAAE,UAAU,EAAE;GAC7B,MAAM,WAAW,OAAO,cAAc;IACpC,MAAM,WAAW,OAAO;IACxB,IAAI,aAAa,GAAG,OAAO,OAAO;IAClC,OAAO,WAAW;IAClB,OAAO,OAAO,QAAQ,wCAAwC,SAAS,gBAAgB;GACzF,CAAC;GACD,MAAM,UAAU,UACd,OAAO,cAAc;IACnB,OAAO,YAAY;IACnB,MAAM,QAAQ,UAAU,OAAO,QAAQ;IAWvC,QATE,OAAO,aAAa,IAChB,OAAO,WACL,4DACA,KACF,IACA,OAAO,SACL,uDAAuD,MAAM,UAC7D,KACF,EAAA,CACK,KAAK,OAAO,QAAQ,OAAO,MAAM,SAAS,OAAO,KAAK,CAAC,CAAC,CAAC;GACtE,CAAC;GACH,MAAM,WAAW,OAAO,IAAI,aAAa;IACvC,IAAI,OAAO,OAAO,KAAA,GAChB,OAAO,KAAK,OAAO,OAAO,KACxB,OAAO,cAAc;KACnB,UAAU;KACV,cAAc,OAAO,KAAK,IAAI,mBAAmB,CAAC;IACpD,CAAC,GACD,OAAO,UAAU,QAAQ,CAC3B;IAEF,MAAM,QAAQ,OAAO,UACnB,MAAM,KAAiB,SAAS,SAAS,SAAS,WAAW,QAAQ,OAAO,EAAE,CAChF,CAAC,CAAC,KAAK,OAAO,UAAU,QAAQ,CAAC;IACjC,IAAI,UAAU,MAAM;IACpB,OAAO,OAAO,QACZ,QACC,GAAG,aACF,OAAO,IAAI,aAAa;KACtB,OAAO,OAAO,QACZ,UACC,CAAC,IAAI,YACJ,OAAO,IAAI,aAAa;MACtB,OAAO,KAAK;MACZ,MAAM,UAAU,UAAU,MAAM;MAChC,IAAI,YAAY,KAAA,GAAW,OAAO,MAAM,MAAM,OAAO,OAAO;KAC9D,CAAC,GACH;MAAE,aAAa;MAAG,SAAS;KAAK,CAClC;IACF,CAAC,GACH;KAAE,aAAa;KAAG,SAAS;IAAK,CAClC;GACF,CAAC,CAAC,CAAC,KAID,OAAO,MAAM,MAAM,CACrB;GACA,OAAO,OAAO,WAAW,OAAO,QAAQ,QAAQ,CAAC;GACjD,OAAO,EAAE,MAAM,MAAM,KAAK,KAAK,EAAE;EACnC,CAAC;CACH;AACF,CAAC;;;;;;AAsBH,MAAa,uBAAuB,YAAsC;CACxE,UAAU,YAAY,OAAO,WAAW,OAAO,KAAK,OAAO,CAAC;CAC5D,WAAW,OAAO,IAAI,aAAa;EACjC,MAAM,QAAQ,OAAO,MAAM,UAAkB;EAC7C,OAAO,OAAO,eACZ,OAAO,WAAW;GAChB,MAAM,YAAY,UAAsC;IACtD,IAAI,EAAE,SAAS,MAAM,IAAI,GAAG,MAAM,YAAY,OAAO,MAAM,IAAI;GACjE;GACA,OAAO,iBAAiB,WAAW,QAAQ;GAC3C,OAAO;EACT,CAAC,IACA,aAAa,OAAO,WAAW,OAAO,oBAAoB,WAAW,QAAQ,CAAC,CACjF;EACA,OAAO,EAAE,MAAM,MAAM,KAAK,KAAK,EAAE;CACnC,CAAC;AACH;;;;;;;;;AAyBA,MAAa,8BACX,YAEA,OAAO,IAAI,aAAa;CACtB,MAAM,yBAAS,IAAI,IAAyB;CAC5C,OAAO,OAAO,eACZ,OAAO,WAAW;EAChB,MAAM,YAAY,UAAsC;GACtD,MAAM,OAAO,MAAM;GACnB,IAAI,CAAC,EAAE,SAAS,IAAI,GAAG;GACvB,IAAI,QAAQ,SAAS,UAAU;IAC7B,MAAM,YAAY,OAAO,IAAI;GAC/B,CAAC;EACH;EACA,QAAQ,iBAAiB,WAAW,QAAQ;EAC5C,OAAO;CACT,CAAC,IACA,aAAa,OAAO,WAAW,QAAQ,oBAAoB,WAAW,QAAQ,CAAC,CAClF;CACA,OAAO;EACL,UAAU,YACR,OAAO,WAAW;GAChB,IAAI,QAAQ,SAAS,UAAU;IAC7B,MAAM,YAAY,OAAO,OAAO;GAClC,CAAC;GACD,QAAQ,YAAY,OAAO;EAC7B,CAAC;EACH,WAAW,OAAO,IAAI,aAAa;GACjC,MAAM,QAAQ,OAAO,MAAM,UAAkB;GAC7C,OAAO,OAAO,eACZ,OAAO,WAAW,OAAO,IAAI,KAAK,CAAC,SAC7B,OAAO,WAAW,OAAO,OAAO,KAAK,CAAC,CAC9C;GACA,OAAO,EAAE,MAAM,MAAM,KAAK,KAAK,EAAE;EACnC,CAAC;CACH;AACF,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;AC9UH,MAAa,cAAc,WAAiE,EAC1F,KAAK,OAAO,QAAQC,kBAAkC,QACpD,OAAO,OAAO,OAAO,WAAW,OAAO,WAAW,OAAO,IAAI,OAAO,CAAC,CAAC,CACxE,EACF;;;;;;AAOA,MAAa,OACX,WAC8E,OAAO;;;;;;;;;;;;;;;;AC3BvF,MAAa,QAAA,QAAkF,KAC7F,MAAM,QAAQC,gBAAoB,GAClC,MAAM,QAAQC,cAA8B,CAC9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC+BA,MAAa,qBAAqB,QAAQ,QACxC,6CACF;;AAgBA,MAAa,UAAU,eAA+B,cAAc;;AAGpE,MAAa,cAAc,YAAoB,OAAuB,GAAG,OAAO,UAAU,EAAE,GAAG;;;;;;;;AAqB/F,MAAa,gBACX,SACA,UAA8B,CAAC,MACL;CAC1B,MAAM,SAAS,QAAQ,UAAU;CACjC,MAAM,OAAO,QAAQ,cAAc;CACnC,OAAO,IAAI,OAAO,CAChB,GAAG,QAAQ,YAAY,KAAK,eAAe,OAAO,UAAU,CAAC,GAC7D,GAAG,QAAQ,KAAK,KAAK,QAAQ,KAAK,IAAI,YAAY,IAAI,EAAE,CAAC,CAC3D,CAAC;AACH"}