@nymbalhq/contract-tests 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-ABEL44IM.js → chunk-KK53D2KL.js} +1 -2
- package/dist/{chunk-ABEL44IM.js.map → chunk-KK53D2KL.js.map} +1 -1
- package/dist/index.d.ts +24 -8
- package/dist/index.js +766 -357
- package/dist/index.js.map +1 -1
- package/dist/kinds.d.ts +1 -1
- package/dist/kinds.js +1 -1
- package/package.json +2 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ai.ts","../src/common.ts","../src/analytics.ts","../src/document-store.ts","../src/document-store-model.ts","../src/document-store-replace.ts","../src/email.ts","../src/event-bus.ts","../src/event-bus-delivery.ts","../src/media-storage.ts","../src/payments.ts","../src/reviews.ts","../src/search.ts","../src/search-oracle.ts","../src/shipping.ts","../src/tax.ts","../src/adapter-context.ts","../src/security.ts","../src/projection.ts","../src/index.ts"],"sourcesContent":["import { describe, expect, it } from 'vitest'\nimport type { AiAdapter } from '@nymbalhq/types'\nimport { CASE_MS, healthAndDowntime, type Build, type ContractOptions } from './common.js'\n\nexport function runAiContract(\n name: string,\n build: Build<AiAdapter>,\n options: ContractOptions<AiAdapter> = {},\n): void {\n describe(`AiAdapter contract: ${name}`, () => {\n it(\n 'embed returns embedding vectors with correct dimensions',\n async () => {\n const adapter = await build()\n const embeddings = await adapter.embed(['hello world', 'test text'])\n expect(Array.isArray(embeddings)).toBe(true)\n expect(embeddings).toHaveLength(2)\n expect(Array.isArray(embeddings[0])).toBe(true)\n expect((embeddings[0] ?? []).length).toBeGreaterThan(0)\n },\n CASE_MS,\n )\n\n it(\n 'complete returns a non-empty string',\n async () => {\n const adapter = await build()\n const result = await adapter.complete('Write one word: hello', { maxTokens: 10 })\n expect(typeof result).toBe('string')\n expect(result.length).toBeGreaterThan(0)\n },\n CASE_MS,\n )\n\n healthAndDowntime(build, options.unreachable, 'complete()', (adapter) =>\n adapter.complete('Write one word: hello', { maxTokens: 10 }),\n )\n })\n}\n","import { describe, expect, it } from 'vitest'\nimport type { HealthReport } from '@nymbalhq/types'\n\n/** How long a health check, or a call on an unreachable dependency, may take to settle. */\nexport const BOUND_MS = 6000\n\n/** A case's own timeout: the bound, plus room for `build` and the case's own calls. */\nexport const CASE_MS = 30_000\n\n/** Makes the adapter under test: a fresh, initialized one each time it is called. */\nexport type Build<A> = () => A | Promise<A>\n\n/** The options every suite takes. */\nexport interface ContractOptions<A = unknown> {\n /**\n * An adapter whose dependency cannot be reached. Given, the suite adds the downtime cases: `healthCheck()` reports\n * `down`, and one representative operation rejects, each within 6 s. For a client that connects when it is built,\n * build it while the dependency is up and then take the dependency away (close a proxy in front of it).\n */\n unreachable?: Build<A>\n}\n\ninterface Checkable {\n healthCheck?: () => Promise<HealthReport>\n}\n\ntype Settled<T> =\n | { state: 'resolved'; value: T; ms: number }\n | { state: 'rejected'; error: unknown; ms: number }\n | { state: 'hung'; ms: number }\n\n/** How `call` settled within `ms`: a synchronous throw is a rejection, and a call still pending is `hung`. */\nexport async function settle<T>(call: () => T | Promise<T>, ms = BOUND_MS): Promise<Settled<T>> {\n const started = Date.now()\n let timer: ReturnType<typeof setTimeout> | undefined\n const hung = new Promise<{ state: 'hung' }>((resolve) => {\n timer = setTimeout(() => resolve({ state: 'hung' }), ms)\n })\n try {\n const outcome = await Promise.race([\n Promise.resolve()\n .then(call)\n .then(\n (value) => ({ state: 'resolved' as const, value }),\n (error: unknown) => ({ state: 'rejected' as const, error }),\n ),\n hung,\n ])\n return { ...outcome, ms: Date.now() - started }\n } finally {\n clearTimeout(timer)\n }\n}\n\n/** Closes what has a `close()`, without letting a close that hangs (a client on a dead host) hold the case. */\nexport async function release(target: unknown): Promise<void> {\n const close = (target as { close?: unknown } | null)?.close\n if (typeof close !== 'function') return\n let timer: ReturnType<typeof setTimeout> | undefined\n await Promise.race([\n Promise.resolve()\n .then(() => (close as () => unknown).call(target))\n .catch(() => undefined),\n new Promise<void>((resolve) => {\n timer = setTimeout(resolve, 5000)\n }),\n ])\n clearTimeout(timer)\n}\n\nfunction healthOf(target: Checkable): Promise<Settled<HealthReport>> {\n expect(\n typeof target.healthCheck,\n 'healthCheck() is missing: certification needs it, though the type keeps it optional',\n ).toBe('function')\n return settle(() => target.healthCheck!())\n}\n\n/** `healthCheck()` resolves `healthy` or `degraded` within the bound. */\nexport async function expectHealthy(target: Checkable): Promise<void> {\n const health = await healthOf(target)\n expect(health.state, `healthCheck() did not resolve within ${BOUND_MS} ms`).toBe('resolved')\n const status = health.state === 'resolved' ? health.value?.status : undefined\n expect(['healthy', 'degraded'], `healthCheck() reported ${String(status)}`).toContain(status)\n}\n\n/** `healthCheck()` resolves `down` within the bound. */\nexport async function expectDown(target: Checkable): Promise<void> {\n const health = await healthOf(target)\n expect(health.state, `healthCheck() did not resolve within ${BOUND_MS} ms`).toBe('resolved')\n expect(health.state === 'resolved' ? health.value?.status : undefined).toBe('down')\n}\n\n/** `call` rejects within the bound: it neither succeeds on a dead dependency nor hangs on one. */\nexport async function expectRejects(call: () => Promise<unknown>): Promise<void> {\n const outcome = await settle(call)\n expect(\n outcome.state,\n outcome.state === 'hung' ? `still pending after ${BOUND_MS} ms` : 'it succeeded',\n ).toBe('rejected')\n}\n\n/** Builds the adapter, runs `body` on it, and closes it when it has a `close()`. */\nexport async function using<A, T>(build: Build<A>, body: (adapter: A) => Promise<T>): Promise<T> {\n const adapter = await build()\n try {\n return await body(adapter)\n } finally {\n await release(adapter)\n }\n}\n\n/**\n * The health case every suite has, and, when `unreachable` is given, the downtime cases: health `down`, and\n * `operation` (named by `label`) rejecting, each within the bound.\n */\nexport function healthAndDowntime<A extends object>(\n build: Build<A>,\n unreachable: Build<A> | undefined,\n label: string,\n operation: (adapter: A) => Promise<unknown>,\n): void {\n it(\n 'health: healthCheck() resolves healthy or degraded within 6 s',\n () => using(build, (adapter) => expectHealthy(adapter as Checkable)),\n CASE_MS,\n )\n if (unreachable === undefined) return\n describe('unreachable dependency', () => {\n it(\n 'down: healthCheck() reports down within 6 s',\n () => using(unreachable, (adapter) => expectDown(adapter as Checkable)),\n CASE_MS,\n )\n it(\n `down: ${label} rejects within 6 s instead of hanging`,\n () => using(unreachable, (adapter) => expectRejects(() => operation(adapter))),\n CASE_MS,\n )\n })\n}\n","import { describe, expect, it } from 'vitest'\nimport type { AnalyticsAdapter } from '@nymbalhq/types'\nimport { CASE_MS, healthAndDowntime, type Build, type ContractOptions } from './common.js'\n\nexport function runAnalyticsContract(\n name: string,\n build: Build<AnalyticsAdapter>,\n options: ContractOptions<AnalyticsAdapter> = {},\n): void {\n describe(`AnalyticsAdapter contract: ${name}`, () => {\n it(\n 'track resolves without throwing',\n async () => {\n const adapter = await build()\n await expect(\n adapter.track('product_viewed', { productId: 'prod-1', source: 'test' }),\n ).resolves.not.toThrow()\n },\n CASE_MS,\n )\n\n it(\n 'identify resolves without throwing',\n async () => {\n const adapter = await build()\n await expect(\n adapter.identify('user-1', { email: 'test@example.com', plan: 'free' }),\n ).resolves.not.toThrow()\n },\n CASE_MS,\n )\n\n healthAndDowntime(build, options.unreachable, 'track()', (adapter) =>\n adapter.track('product_viewed', { productId: 'prod-1', source: 'contract-down' }),\n )\n })\n}\n","import { describe, expect, it } from 'vitest'\nimport type { DocumentStoreAdapter, QueryParams } from '@nymbalhq/types'\nimport { CASE_MS, healthAndDowntime, type Build, type ContractOptions } from './common.js'\nimport { documentStoreModelCases } from './document-store-model.js'\nimport { documentStoreReplaceCases } from './document-store-replace.js'\n\nexport interface DocumentStoreContractOptions extends ContractOptions<DocumentStoreAdapter> {\n /** A clock the store reads: the TTL cases advance it instead of waiting a one-second TTL out. */\n clock?: { advance(ms: number): void | Promise<void> }\n /** Two stores on one backend under different prefixes, for the prefix isolation cases. */\n isolation?: () => Promise<[DocumentStoreAdapter, DocumentStoreAdapter]>\n}\n\ntype Make = Build<DocumentStoreAdapter>\n\ninterface Doc {\n id: string\n part: string\n v?: unknown\n nested?: { v?: unknown }\n}\n\nconst SLOW = 30_000\n\nasync function using(make: Make, body: (store: DocumentStoreAdapter) => Promise<void>) {\n const store = await make()\n try {\n await body(store)\n } finally {\n await store.close()\n }\n}\n\nasync function rejection(promise: Promise<unknown>): Promise<unknown> {\n return promise.then(\n () => null,\n (error: unknown) => error ?? new Error('rejected with nothing'),\n )\n}\n\nasync function putAll(store: DocumentStoreAdapter, collection: string, docs: Doc[]) {\n for (const doc of docs) await store.put(collection, doc.id, doc)\n}\n\nconst ids = (docs: Doc[]): string[] => docs.map((d) => d.id)\n\nasync function walk(\n store: DocumentStoreAdapter,\n collection: string,\n params: QueryParams,\n between?: (page: number) => Promise<void>,\n): Promise<Doc[][]> {\n const pages: Doc[][] = []\n let cursor: string | undefined\n do {\n const page = await store.query<Doc>(collection, {\n ...params,\n ...(cursor !== undefined && { cursor }),\n })\n pages.push(page.items)\n cursor = page.nextCursor ?? undefined\n if (between !== undefined) await between(pages.length)\n } while (cursor !== undefined && pages.length < 100)\n return pages\n}\n\n/**\n * The document store contract every implementation runs: the reference order and filter of\n * `compareDocumentValues` and `matchesSortKey`, cursors that survive a delete, TTL, conditional puts, batches,\n * isolation between collections (and, given `isolation`, between prefixes), the same as a property against the\n * reference model, an atomic `replaceCollection`, and health (and, given `unreachable`, downtime). `make` returns an\n * empty store each time.\n */\nexport function runDocumentStoreContract(\n name: string,\n make: Make,\n opts: DocumentStoreContractOptions = {},\n): void {\n describe(`DocumentStoreAdapter contract: ${name}`, () => {\n it(\n 'get is null for a missing key; put then get round-trips; a second put overwrites',\n async () => {\n await using(make, async (store) => {\n expect(await store.get('col', 'missing')).toBeNull()\n await store.put('col', 'k1', { name: 'test', value: 42, nested: { list: [1, 'two'] } })\n expect(await store.get('col', 'k1')).toEqual({\n name: 'test',\n value: 42,\n nested: { list: [1, 'two'] },\n })\n await store.put('col', 'k1', { v: 2 })\n expect(await store.get('col', 'k1')).toEqual({ v: 2 })\n })\n },\n CASE_MS,\n )\n\n it(\n 'delete removes the document, and deleting a missing key does not throw',\n async () => {\n await using(make, async (store) => {\n await store.put('col', 'k1', { v: 1 })\n await store.delete('col', 'k1')\n expect(await store.get('col', 'k1')).toBeNull()\n await expect(store.delete('col', 'nope')).resolves.toBeUndefined()\n })\n },\n CASE_MS,\n )\n\n it(\n \"query narrows by partition, and '*' returns the whole collection\",\n async () => {\n await using(make, async (store) => {\n await putAll(store, 'col', [\n { id: 'a', part: 'p' },\n { id: 'b', part: 'q' },\n { id: 'c', part: 'p' },\n ])\n const p = await store.query<Doc>('col', { partitionKey: { field: 'part', value: 'p' } })\n expect(ids(p.items).sort()).toEqual(['a', 'c'])\n const all = await store.query<Doc>('col', { partitionKey: { field: 'part', value: '*' } })\n expect(ids(all.items).sort()).toEqual(['a', 'b', 'c'])\n expect(all.nextCursor).toBeNull()\n })\n },\n CASE_MS,\n )\n\n it(\n \"sortKey eq is strict (1 is not '1', 'a' is not 'A'); gt, lt and between follow compareDocumentValues\",\n async () => {\n await using(make, async (store) => {\n await putAll(store, 'col', [\n { id: 'n1', part: 'p', v: 1 },\n { id: 's1', part: 'p', v: '1' },\n { id: 'n5', part: 'p', v: 5 },\n { id: 'sa', part: 'p', v: 'a' },\n { id: 'sA', part: 'p', v: 'A' },\n { id: 'nul', part: 'p', v: null },\n ])\n const where = async (sortKey: NonNullable<QueryParams['sortKey']>) =>\n ids(\n (\n await store.query<Doc>('col', {\n partitionKey: { field: 'part', value: 'p' },\n sortKey,\n })\n ).items,\n ).sort()\n expect(await where({ field: 'v', operator: 'eq', value: 1 })).toEqual(['n1'])\n expect(await where({ field: 'v', operator: 'eq', value: 'a' })).toEqual(['sa'])\n // Numbers rank before strings, strings before null; 'A' and 'a' tie at base sensitivity.\n expect(await where({ field: 'v', operator: 'lt', value: '0' })).toEqual(['n1', 'n5'])\n expect(await where({ field: 'v', operator: 'gt', value: 5 })).toEqual(\n ['nul', 's1', 'sA', 'sa'].sort(),\n )\n expect(await where({ field: 'v', operator: 'between', value: [2, 'a'] })).toEqual(\n ['n5', 's1', 'sA', 'sa'].sort(),\n )\n })\n },\n CASE_MS,\n )\n\n it(\n 'orderBy orders by value with the collator, nulls and missing last, ties by key, on a dotted path too',\n async () => {\n await using(make, async (store) => {\n await putAll(store, 'col', [\n { id: 'k4', part: 'p', nested: { v: 'b' } },\n { id: 'k1', part: 'p', nested: { v: 'B' } },\n { id: 'k2', part: 'p', nested: { v: 'a' } },\n { id: 'k3', part: 'p', nested: {} },\n { id: 'k5', part: 'p', nested: { v: 10 } },\n { id: 'k6', part: 'p', nested: { v: 9 } },\n { id: 'k0', part: 'p', nested: { v: null } },\n ])\n const asc = await store.query<Doc>('col', {\n partitionKey: { field: 'part', value: 'p' },\n orderBy: { field: 'nested.v', direction: 'asc', nulls: 'last' },\n })\n expect(ids(asc.items)).toEqual(['k6', 'k5', 'k2', 'k1', 'k4', 'k0', 'k3'])\n const desc = await store.query<Doc>('col', {\n partitionKey: { field: 'part', value: 'p' },\n orderBy: { field: 'nested.v', direction: 'desc', nulls: 'last' },\n })\n expect(ids(desc.items)).toEqual(['k1', 'k4', 'k2', 'k5', 'k6', 'k0', 'k3'])\n })\n },\n CASE_MS,\n )\n\n it(\n 'a limit and cursor walk returns every match exactly once, also when a document is deleted mid-walk',\n async () => {\n await using(make, async (store) => {\n const docs = Array.from({ length: 9 }, (_, i) => ({ id: `k${i}`, part: 'p', v: i % 3 }))\n await putAll(store, 'col', docs)\n for (const orderBy of [undefined, { field: 'v', direction: 'asc' as const }]) {\n const params: QueryParams = {\n partitionKey: { field: 'part', value: 'p' },\n limit: 2,\n ...(orderBy !== undefined && { orderBy }),\n }\n const whole = (await walk(store, 'col', params)).flat()\n expect(ids(whole).sort()).toEqual(ids(docs).sort())\n\n // The first cursor's anchor is deleted after the first page: the walk neither restarts nor repeats.\n const anchor = whole[1]!\n const walked = (\n await walk(store, 'col', params, async (page) => {\n if (page === 1) await store.delete('col', anchor.id)\n })\n ).flat()\n expect(new Set(ids(walked)).size).toBe(walked.length)\n expect(ids(walked).sort()).toEqual(ids(docs).sort())\n await store.put('col', anchor.id, anchor)\n }\n })\n },\n SLOW,\n )\n\n it(\n 'a cursor issued under one orderBy is refused under another, and continues under its own',\n async () => {\n await using(make, async (store) => {\n await putAll(\n store,\n 'col',\n Array.from({ length: 5 }, (_, i) => ({ id: `k${i}`, part: 'p', v: i })),\n )\n const base: QueryParams = {\n partitionKey: { field: 'part', value: 'p' },\n orderBy: { field: 'v', direction: 'asc' },\n limit: 2,\n }\n const first = await store.query<Doc>('col', base)\n expect(first.nextCursor).not.toBeNull()\n const cursor = first.nextCursor!\n const other = await rejection(\n store.query('col', { ...base, orderBy: { field: 'v', direction: 'desc' }, cursor }),\n )\n expect(other).toBeInstanceOf(Error)\n const next = await store.query<Doc>('col', { ...base, cursor })\n expect(ids(next.items)).toEqual(['k2', 'k3'])\n })\n },\n CASE_MS,\n )\n\n it(\n 'a document put with a ttl (seconds) is gone from get, query and batchGet once it expires',\n async () => {\n await using(make, async (store) => {\n await store.put('col', 'short', { id: 'short', part: 'p' }, { ttl: 1 })\n await store.put('col', 'kept', { id: 'kept', part: 'p' })\n expect(await store.get('col', 'short')).toEqual({ id: 'short', part: 'p' })\n if (opts.clock !== undefined) {\n await opts.clock.advance(1_001)\n } else {\n const deadline = Date.now() + 4_000\n while ((await store.get('col', 'short')) !== null && Date.now() < deadline) {\n await new Promise((r) => setTimeout(r, 50))\n }\n }\n expect(await store.get('col', 'short')).toBeNull()\n const all = await store.query<Doc>('col', { partitionKey: { field: 'part', value: '*' } })\n expect(ids(all.items)).toEqual(['kept'])\n expect([...(await store.batchGet('col', ['short', 'kept'])).keys()]).toEqual(['kept'])\n })\n },\n SLOW,\n )\n\n it(\n 'a conditional put applies when the field is strictly equal, and otherwise fails condition-failed',\n async () => {\n await using(make, async (store) => {\n await store.put('col', 'c', { version: 1, label: 'v1' })\n await store.put(\n 'col',\n 'c',\n { version: 2, label: 'v2' },\n { conditionKey: 'version', conditionValue: 1 },\n )\n expect(await store.get('col', 'c')).toEqual({ version: 2, label: 'v2' })\n for (const conditionValue of [1, '2']) {\n const failed = await rejection(\n store.put('col', 'c', { version: 3 }, { conditionKey: 'version', conditionValue }),\n )\n expect((failed as { code?: unknown } | null)?.code).toBe('adapter.condition-failed')\n }\n const absent = await rejection(\n store.put(\n 'col',\n 'none',\n { version: 1 },\n { conditionKey: 'version', conditionValue: 1 },\n ),\n )\n expect((absent as { code?: unknown } | null)?.code).toBe('adapter.condition-failed')\n expect(await store.get('col', 'c')).toEqual({ version: 2, label: 'v2' })\n expect(await store.get('col', 'none')).toBeNull()\n })\n },\n CASE_MS,\n )\n\n it(\n 'batchPut stores every item; batchGet returns exactly the stored keys',\n async () => {\n await using(make, async (store) => {\n await store.batchPut(\n 'col',\n new Map([\n ['x', { n: 10 }],\n ['y', { n: 20 }],\n ]),\n )\n const got = await store.batchGet<{ n: number }>('col', ['x', 'y', 'missing'])\n expect([...got.keys()].sort()).toEqual(['x', 'y'])\n expect(got.get('x')).toEqual({ n: 10 })\n expect(await store.get('col', 'y')).toEqual({ n: 20 })\n expect((await store.batchGet('col', [])).size).toBe(0)\n })\n },\n CASE_MS,\n )\n\n it(\n 'collections are isolated for get, query and delete',\n async () => {\n await using(make, async (store) => {\n await store.put('colA', 'key', { id: 'key', part: 'p', from: 'A' })\n await store.put('colB', 'key', { id: 'key', part: 'p', from: 'B' })\n expect(await store.get('colA', 'key')).toEqual({ id: 'key', part: 'p', from: 'A' })\n const inB = await store.query('colB', { partitionKey: { field: 'part', value: '*' } })\n expect(inB.items).toEqual([{ id: 'key', part: 'p', from: 'B' }])\n await store.delete('colA', 'key')\n expect(await store.get('colB', 'key')).toEqual({ id: 'key', part: 'p', from: 'B' })\n })\n },\n CASE_MS,\n )\n\n const isolation = opts.isolation\n if (isolation !== undefined) {\n it(\n 'two stores under different prefixes never see each other’s documents',\n async () => {\n const [one, two] = await isolation()\n try {\n await one.put('col', 'shared', { id: 'shared', part: 'p', owner: 'one' })\n await one.put('col', 'one-only', { id: 'one-only', part: 'p', owner: 'one' })\n await two.put('col', 'shared', { id: 'shared', part: 'p', owner: 'two' })\n expect(await one.get('col', 'shared')).toEqual({\n id: 'shared',\n part: 'p',\n owner: 'one',\n })\n expect(await two.get('col', 'one-only')).toBeNull()\n const inTwo = await two.query('col', { partitionKey: { field: 'part', value: '*' } })\n expect(inTwo.items).toEqual([{ id: 'shared', part: 'p', owner: 'two' }])\n await one.delete('col', 'shared')\n expect(await two.get('col', 'shared')).toEqual({\n id: 'shared',\n part: 'p',\n owner: 'two',\n })\n } finally {\n await one.close()\n await two.close()\n }\n },\n CASE_MS,\n )\n }\n\n documentStoreModelCases(make, opts)\n\n documentStoreReplaceCases(make, opts)\n\n healthAndDowntime(make, opts.unreachable, 'get()', (store) => store.get('contract-down', 'k'))\n })\n}\n","import fc from 'fast-check'\nimport { describe, expect, it } from 'vitest'\nimport {\n compareDocumentValues,\n matchesSortKey,\n type DocumentStoreAdapter,\n type QueryParams,\n} from '@nymbalhq/types'\nimport { CASE_MS, type Build } from './common.js'\n\n// The document store contract as a property against the reference model: each store's page sequence, over the\n// generator domain below, equals the reference (filter with matchesSortKey, order with compareDocumentValues, nulls\n// last, ties by key, slice by `limit`). Kills: a store that filters `eq` as text (1 against '1'), orders strings by\n// bytes instead of the collator, places nulls or missing fields first, ignores a dotted path, restarts or repeats a\n// cursor walk (also across a delete), accepts a cursor under another order, ignores or misreads a TTL, skips a put\n// condition, or leaks across a collection or a prefix.\n\n/** What the model cases read of the suite's options. */\nexport interface ModelOptions {\n clock?: { advance(ms: number): void | Promise<void> }\n isolation?: () => Promise<[DocumentStoreAdapter, DocumentStoreAdapter]>\n}\n\nconst COLLECTION = 'contract-docs'\nconst DECOY = 'contract-decoy'\nconst SLOW = 60_000\n\ntype Value = string | number | null\n\n/** A stored document. `v` and `nested.v` are absent when the generator chose \"missing\". */\ninterface Doc {\n id: string\n part: string\n v?: Value\n nested: { v?: Value }\n label: string\n}\n\ninterface Generated {\n key: string\n part: 'p' | 'q'\n v: Value | undefined\n n: Value | undefined\n}\n\n/** The domain: case, accent and equal-base strings, ints next to numeric strings, and null. */\nconst valueArb: fc.Arbitrary<Value> = fc.oneof(\n fc.constantFrom('a', 'A', 'á', 'b', 'B', 'é', 'e', 'ab', 'Ab', '1', '10', '2'),\n fc.integer({ min: -2, max: 10 }),\n fc.constant(null),\n)\n/** A field holding a domain value, or missing (undefined). */\nconst fieldArb = fc.option(valueArb, { nil: undefined, freq: 4 })\n\nconst docsArb = (minLength: number) =>\n fc.uniqueArray(\n fc.record({\n // Random keys, so key order is unrelated to value order.\n key: fc.stringMatching(/^[a-z0-9]{1,6}$/),\n part: fc.constantFrom<'p' | 'q'>('p', 'q'),\n v: fieldArb,\n n: fieldArb,\n }),\n { minLength, maxLength: 14, selector: (d) => d.key },\n )\n\ntype SortKey = NonNullable<QueryParams['sortKey']>\ntype Direction = 'asc' | 'desc'\n\nconst sortKeyArb: fc.Arbitrary<SortKey | undefined> = fc.option(\n fc.oneof(\n fc.record({\n field: fc.constant('v'),\n operator: fc.constantFrom<'eq' | 'gt' | 'lt'>('eq', 'gt', 'lt'),\n value: valueArb as fc.Arbitrary<unknown>,\n }),\n fc.record({\n field: fc.constant('v'),\n operator: fc.constant<'between'>('between'),\n value: fc.tuple(valueArb, valueArb) as fc.Arbitrary<unknown>,\n }),\n ),\n { nil: undefined },\n)\nconst orderByArb = fc.record({\n field: fc.constantFrom('v', 'nested.v'),\n direction: fc.constantFrom<Direction>('asc', 'desc'),\n})\n\nfunction stored(g: Generated): Doc {\n return {\n id: g.key,\n part: g.part,\n ...(g.v !== undefined && { v: g.v }),\n nested: g.n !== undefined ? { v: g.n } : {},\n label: 'Ünïcödé ✓',\n }\n}\n\nfunction valueAt(doc: Doc, path: string): unknown {\n let value: unknown = doc\n for (const part of path.split('.')) {\n if (value === null || typeof value !== 'object') return undefined\n value = (value as Record<string, unknown>)[part]\n }\n return value\n}\n\nconst nullish = (v: unknown): boolean => v === null || v === undefined\n\ninterface Query {\n partition: 'p' | '*'\n sortKey: SortKey | undefined\n orderBy: { field: string; direction: Direction } | undefined\n}\n\n/** The reference: filter by partition and matchesSortKey, then order (when asked) by compareDocumentValues. */\nfunction reference(docs: Doc[], q: Query): string[] {\n const hits = docs.filter(\n (d) =>\n (q.partition === '*' || d.part === q.partition) &&\n (q.sortKey === undefined || matchesSortKey(d.v, q.sortKey)),\n )\n const { orderBy } = q\n if (orderBy === undefined) return hits.map((d) => d.id).sort()\n return hits\n .sort((a, b) => {\n const x = valueAt(a, orderBy.field)\n const y = valueAt(b, orderBy.field)\n // nulls: 'last' in both directions; a missing field is a null.\n if (nullish(x) !== nullish(y)) return nullish(x) ? 1 : -1\n let c = nullish(x) ? 0 : compareDocumentValues(x, y)\n if (orderBy.direction === 'desc') c = -c\n if (c !== 0) return c\n return a.id < b.id ? -1 : a.id > b.id ? 1 : 0\n })\n .map((d) => d.id)\n}\n\nfunction params(q: Query, limit: number, cursor?: string): QueryParams {\n return {\n partitionKey: { field: 'part', value: q.partition },\n ...(q.sortKey !== undefined && { sortKey: q.sortKey }),\n ...(q.orderBy !== undefined && { orderBy: { ...q.orderBy, nulls: 'last' as const } }),\n limit,\n ...(cursor !== undefined && { cursor }),\n }\n}\n\n/** Every page of a cursor walk. `between` runs after each page; the walk stops after `docs + 2` pages. */\nasync function walk(\n store: DocumentStoreAdapter,\n q: Query,\n limit: number,\n maxPages: number,\n between?: (page: number) => Promise<void>,\n): Promise<{ pages: Doc[][]; ended: boolean }> {\n const pages: Doc[][] = []\n let cursor: string | undefined\n do {\n const page = await store.query<Doc>(COLLECTION, params(q, limit, cursor))\n pages.push(page.items)\n cursor = page.nextCursor ?? undefined\n if (between !== undefined) await between(pages.length)\n } while (cursor !== undefined && pages.length <= maxPages)\n return { pages, ended: cursor === undefined }\n}\n\nconst idsOf = (docs: Doc[]): string[] => docs.map((d) => d.id)\n\nfunction chunk<T>(items: T[], size: number): T[][] {\n const out: T[][] = []\n for (let i = 0; i < items.length; i += size) out.push(items.slice(i, i + size))\n return out\n}\n\n/** A final empty page (a cursor issued on an exact multiple of `limit`) adds nothing to the sequence. */\nfunction withoutTrailingEmpty<T>(pages: T[][]): T[][] {\n return pages.length > 0 && pages[pages.length - 1]!.length === 0 ? pages.slice(0, -1) : pages\n}\n\nasync function storeWith(\n make: Build<DocumentStoreAdapter>,\n generated: Generated[],\n): Promise<{ store: DocumentStoreAdapter; docs: Doc[] }> {\n const store = await make()\n const docs = generated.map(stored)\n for (const doc of docs) await store.put<Doc>(COLLECTION, doc.id, doc)\n // Same keys, same partition, another collection: no query on COLLECTION may return them.\n for (const doc of docs.slice(0, 3)) {\n await store.put<Doc>(DECOY, doc.id, { ...doc, label: 'decoy' })\n }\n return { store, docs }\n}\n\nasync function closing<T>(store: DocumentStoreAdapter, body: () => Promise<T>): Promise<T> {\n try {\n return await body()\n } finally {\n await store.close()\n }\n}\n\nasync function rejection(promise: Promise<unknown>): Promise<unknown> {\n return promise.then(\n () => null,\n (error: unknown) => error ?? new Error('rejected with nothing'),\n )\n}\n\nconst TTL_SECONDS = 1\n\n/** The reference-model cases, registered inside the suite's describe. */\nexport function documentStoreModelCases(make: Build<DocumentStoreAdapter>, opts: ModelOptions): void {\n describe('agrees with the reference model', () => {\n it(\n 'every query’s page sequence equals the reference: filter by partition and sortKey, order with nulls last and ties by key, slice by limit',\n async () => {\n await fc.assert(\n fc.asyncProperty(\n docsArb(0),\n fc.constantFrom<'p' | '*'>('p', '*'),\n sortKeyArb,\n orderByArb,\n fc.integer({ min: 1, max: 5 }),\n async (generated, partition, sortKey, orderBy, limit) => {\n const { store, docs } = await storeWith(make, generated)\n await closing(store, async () => {\n const q: Query = { partition, sortKey, orderBy }\n const expected = reference(docs, q)\n const { pages, ended } = await walk(store, q, limit, docs.length + 2)\n\n expect(ended, 'the cursor walk never ended').toBe(true)\n for (const page of pages) expect(page.length).toBeLessThanOrEqual(limit)\n expect(withoutTrailingEmpty(pages.map(idsOf))).toEqual(chunk(expected, limit))\n const byId = new Map(docs.map((d) => [d.id, d]))\n for (const item of pages.flat()) expect(item).toEqual(byId.get(item.id))\n })\n },\n ),\n { numRuns: 50 },\n )\n },\n SLOW,\n )\n\n it(\n 'without orderBy, a cursor walk returns exactly the reference’s matches, each once',\n async () => {\n await fc.assert(\n fc.asyncProperty(\n docsArb(0),\n fc.constantFrom<'p' | '*'>('p', '*'),\n sortKeyArb,\n fc.integer({ min: 1, max: 5 }),\n async (generated, partition, sortKey, limit) => {\n const { store, docs } = await storeWith(make, generated)\n await closing(store, async () => {\n const q: Query = { partition, sortKey, orderBy: undefined }\n const { pages, ended } = await walk(store, q, limit, docs.length + 2)\n const walked = idsOf(pages.flat())\n\n expect(ended, 'the cursor walk never ended').toBe(true)\n expect(walked.length, `duplicates in ${walked.join(',')}`).toBe(\n new Set(walked).size,\n )\n expect([...walked].sort()).toEqual(reference(docs, q))\n })\n },\n ),\n { numRuns: 40 },\n )\n },\n SLOW,\n )\n\n it(\n 'a cursor walk across a mid-walk delete returns every remaining match exactly once, in the reference order',\n async () => {\n await fc.assert(\n fc.asyncProperty(\n docsArb(3),\n fc.option(orderByArb, { nil: undefined }),\n fc.integer({ min: 1, max: 3 }),\n fc.nat(),\n async (generated, orderBy, limit, pick) => {\n const { store, docs } = await storeWith(make, generated)\n await closing(store, async () => {\n const q: Query = { partition: '*', sortKey: undefined, orderBy }\n const expected = reference(docs, q)\n fc.pre(expected.length > limit)\n // Any match: one already returned, the last one returned (the cursor's anchor), or one still ahead.\n const deleted = expected[pick % expected.length]!\n const { pages, ended } = await walk(store, q, limit, docs.length + 2, async (n) => {\n if (n === 1) await store.delete(COLLECTION, deleted)\n })\n const walked = idsOf(pages.flat())\n\n expect(ended, 'the cursor walk never ended').toBe(true)\n expect(walked.length, `duplicates in ${walked.join(',')}`).toBe(\n new Set(walked).size,\n )\n expect(walked.filter((id) => !expected.includes(id))).toEqual([])\n expect(expected.filter((id) => id !== deleted && !walked.includes(id))).toEqual([])\n if (orderBy !== undefined) {\n expect(walked).toEqual(expected.filter((id) => walked.includes(id)))\n }\n })\n },\n ),\n { numRuns: 50 },\n )\n },\n SLOW,\n )\n\n it(\n 'a cursor issued under one orderBy is refused under another, and continues the walk under its own',\n async () => {\n const generated: Generated[] = ['k1', 'k2', 'k3', 'k4', 'k5'].map((key, i) => ({\n key,\n part: 'p',\n v: 5 - i,\n n: i,\n }))\n const { store, docs } = await storeWith(make, generated)\n await closing(store, async () => {\n const asc: Query = {\n partition: 'p',\n sortKey: undefined,\n orderBy: { field: 'v', direction: 'asc' },\n }\n const first = await store.query<Doc>(COLLECTION, params(asc, 2))\n expect(first.nextCursor).not.toBeNull()\n const cursor = first.nextCursor!\n\n const otherDirection = { ...asc, orderBy: { field: 'v', direction: 'desc' as const } }\n const otherField = { ...asc, orderBy: { field: 'nested.v', direction: 'asc' as const } }\n expect(\n await rejection(store.query(COLLECTION, params(otherDirection, 2, cursor))),\n ).toBeInstanceOf(Error)\n expect(\n await rejection(store.query(COLLECTION, params(otherField, 2, cursor))),\n ).toBeInstanceOf(Error)\n const next = await store.query<Doc>(COLLECTION, params(asc, 2, cursor))\n expect(idsOf(next.items)).toEqual(reference(docs, asc).slice(2, 4))\n })\n },\n SLOW,\n )\n\n it(\n 'a document put with a TTL is returned until it expires, then by no get, query or batchGet; one put without stays',\n async () => {\n const store = await make()\n await closing(store, async () => {\n const short: Doc = { id: 'short', part: 'p', nested: {}, label: 'ttl' }\n const long: Doc = { id: 'long', part: 'p', nested: {}, label: 'no ttl' }\n const putAt = Date.now()\n await store.put<Doc>(COLLECTION, short.id, short, { ttl: TTL_SECONDS })\n await store.put<Doc>(COLLECTION, long.id, long)\n expect(await store.get<Doc>(COLLECTION, short.id)).toEqual(short)\n\n if (opts.clock !== undefined) {\n await opts.clock.advance(TTL_SECONDS * 1000 - 1)\n expect(await store.get<Doc>(COLLECTION, short.id)).toEqual(short)\n await opts.clock.advance(2)\n } else {\n // Polled, not slept: the TTL is the store's to keep, and its expiry is read back as soon as it shows.\n const deadline = putAt + TTL_SECONDS * 1000 + 3000\n while ((await store.get(COLLECTION, short.id)) !== null && Date.now() < deadline) {\n await new Promise((r) => setTimeout(r, 25))\n }\n expect(Date.now() - putAt, 'expired before its TTL').toBeGreaterThanOrEqual(\n TTL_SECONDS * 1000 - 100,\n )\n }\n\n expect(await store.get(COLLECTION, short.id)).toBeNull()\n const all = await store.query<Doc>(COLLECTION, {\n partitionKey: { field: 'part', value: '*' },\n limit: 100,\n })\n expect(idsOf(all.items)).toEqual([long.id])\n const batch = await store.batchGet<Doc>(COLLECTION, [short.id, long.id])\n expect([...batch.keys()]).toEqual([long.id])\n })\n },\n SLOW,\n )\n\n it('a conditional put applies when the field matches, and otherwise fails condition-failed and changes nothing', async () => {\n const store = await make()\n await closing(store, async () => {\n const v1: Doc & { version: number } = {\n id: 'c',\n part: 'p',\n nested: {},\n label: 'v1',\n version: 1,\n }\n const v2 = { ...v1, label: 'v2', version: 2 }\n await store.put(COLLECTION, 'c', v1)\n\n await store.put(COLLECTION, 'c', v2, { conditionKey: 'version', conditionValue: 1 })\n expect(await store.get(COLLECTION, 'c')).toEqual(v2)\n\n const stale = await rejection(\n store.put(\n COLLECTION,\n 'c',\n { ...v1, label: 'v3', version: 3 },\n { conditionKey: 'version', conditionValue: 1 },\n ),\n )\n expect((stale as { code?: unknown } | null)?.code).toBe('adapter.condition-failed')\n expect(await store.get(COLLECTION, 'c')).toEqual(v2)\n\n const absent = await rejection(\n store.put(COLLECTION, 'none', v1, { conditionKey: 'version', conditionValue: 1 }),\n )\n expect((absent as { code?: unknown } | null)?.code).toBe('adapter.condition-failed')\n expect(await store.get(COLLECTION, 'none')).toBeNull()\n })\n }, CASE_MS)\n\n it(\n 'batchPut stores every item and batchGet returns exactly the stored keys, equal to what was put',\n async () => {\n await fc.assert(\n fc.asyncProperty(docsArb(1), async (generated) => {\n const store = await make()\n await closing(store, async () => {\n const docs = generated.map(stored)\n await store.batchPut(COLLECTION, new Map(docs.map((d) => [d.id, d])))\n const asked = [...docs.map((d) => d.id), 'contract-absent']\n const got = await store.batchGet<Doc>(COLLECTION, asked)\n\n expect(got.size).toBe(docs.length)\n for (const doc of docs) {\n expect(got.get(doc.id)).toEqual(doc)\n expect(await store.get<Doc>(COLLECTION, doc.id)).toEqual(doc)\n }\n })\n }),\n { numRuns: 15 },\n )\n },\n SLOW,\n )\n\n it('collections are isolated for get, query and delete', async () => {\n const store = await make()\n await closing(store, async () => {\n const a: Doc = { id: 'same', part: 'p', nested: {}, label: 'A' }\n const b: Doc = { ...a, label: 'B' }\n const onlyA: Doc = { ...a, id: 'only-a' }\n await store.put('contract-col-a', a.id, a)\n await store.put('contract-col-a', onlyA.id, onlyA)\n await store.put('contract-col-b', b.id, b)\n\n expect(await store.get('contract-col-a', 'same')).toEqual(a)\n expect(await store.get('contract-col-b', 'same')).toEqual(b)\n const inB = await store.query<Doc>('contract-col-b', {\n partitionKey: { field: 'part', value: '*' },\n limit: 100,\n })\n expect(idsOf(inB.items)).toEqual([b.id])\n await store.delete('contract-col-a', 'same')\n expect(await store.get('contract-col-b', 'same')).toEqual(b)\n expect(await store.get('contract-col-a', 'only-a')).toEqual(onlyA)\n })\n }, CASE_MS)\n\n if (opts.isolation !== undefined) {\n const isolation = opts.isolation\n it('two instances with different prefixes never see each other’s documents', async () => {\n const [one, two] = await isolation()\n try {\n const mine: Doc = { id: 'shared-key', part: 'p', nested: {}, label: 'one' }\n const theirs: Doc = { ...mine, label: 'two' }\n await one.put(COLLECTION, mine.id, mine)\n await one.put(COLLECTION, 'one-only', { ...mine, id: 'one-only' })\n await two.put(COLLECTION, theirs.id, theirs)\n\n expect(await one.get(COLLECTION, mine.id)).toEqual(mine)\n expect(await two.get(COLLECTION, theirs.id)).toEqual(theirs)\n expect(await two.get(COLLECTION, 'one-only')).toBeNull()\n const inTwo = await two.query<Doc>(COLLECTION, {\n partitionKey: { field: 'part', value: '*' },\n limit: 100,\n })\n expect(idsOf(inTwo.items)).toEqual([theirs.id])\n const batch = await two.batchGet<Doc>(COLLECTION, [mine.id, 'one-only'])\n expect([...batch.values()]).toEqual([theirs])\n\n await one.delete(COLLECTION, mine.id)\n expect(await two.get(COLLECTION, theirs.id)).toEqual(theirs)\n } finally {\n await one.close()\n await two.close()\n }\n }, CASE_MS)\n }\n })\n}\n","import fc from 'fast-check'\nimport { expect, it } from 'vitest'\nimport type { DocumentStoreAdapter } from '@nymbalhq/types'\nimport { CASE_MS, using, type Build } from './common.js'\n\n// The replaceCollection cases of the document store contract: a rebuilt read model is swapped in with it, so readers\n// must never see it half-built. Kills: a replace that merges (stale keys of the old set survive), one that deletes and\n// writes in steps a reader can see between (a partial set), and one that empties the collection before a source that\n// then throws (a failed rebuild leaves nothing).\n\ninterface Doc {\n id: string\n part: string\n v: number\n}\n\nconst SLOW = 60_000\nconst KEYS = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] as const\n\nconst macrotask = () => new Promise<void>((resolve) => setImmediate(resolve))\n\nasync function* entriesOf(docs: Doc[], pause = false): AsyncGenerator<[string, Doc]> {\n for (const doc of docs) {\n if (pause) await macrotask()\n yield [doc.id, doc]\n }\n}\n\n/** The whole collection, in key order, as `id:v` strings: what a reader saw. */\nasync function snapshot(store: DocumentStoreAdapter, collection: string): Promise<string[]> {\n const all = await store.query<Doc>(collection, { partitionKey: { field: 'part', value: '*' } })\n return all.items.map((d) => `${d.id}:${d.v}`)\n}\n\nconst shape = (docs: Doc[]) =>\n [...docs].sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)).map((d) => `${d.id}:${d.v}`)\n\nasync function putAll(store: DocumentStoreAdapter, collection: string, docs: Doc[]) {\n for (const doc of docs) await store.put(collection, doc.id, doc)\n}\n\nconst docsFrom = (keys: readonly string[], v: number): Doc[] =>\n keys.map((id) => ({ id, part: 'p', v }))\n\nexport function documentStoreReplaceCases(\n make: Build<DocumentStoreAdapter>,\n opts: { clock?: { advance(ms: number): void | Promise<void> } },\n): void {\n it(\n 'replaceCollection leaves exactly the new set, whatever the old and new sets: no stale key of the old set survives, and another collection is untouched (property)',\n async () => {\n await using(make, async (store) => {\n let run = 0\n await fc.assert(\n fc.asyncProperty(\n fc.uniqueArray(fc.constantFrom(...KEYS)),\n fc.uniqueArray(fc.constantFrom(...KEYS)),\n async (oldKeys, newKeys) => {\n run += 1\n const collection = `contract-replace-${run}`\n const decoy = `contract-replace-decoy-${run}`\n await putAll(store, collection, docsFrom(oldKeys, 1))\n await putAll(store, decoy, docsFrom(oldKeys, 3))\n\n const next = docsFrom(newKeys, 2)\n await store.replaceCollection(collection, entriesOf(next))\n\n expect(await snapshot(store, collection)).toEqual(shape(next))\n for (const key of oldKeys.filter((k) => !newKeys.includes(k))) {\n expect(await store.get(collection, key), `stale key ${key}`).toBeNull()\n }\n expect(await snapshot(store, decoy)).toEqual(shape(docsFrom(oldKeys, 3)))\n },\n ),\n { numRuns: 25 },\n )\n })\n },\n SLOW,\n )\n\n it(\n 'replaceCollection is atomic to a concurrent reader: polling while the replace runs sees only the full old set or the full new set, never a partial set',\n async () => {\n await using(make, async (store) => {\n const old = docsFrom(['a', 'b', 'c', 'd', 'e', 'f'], 1)\n const next = docsFrom(['d', 'e', 'f', 'g', 'h', 'i'], 2)\n await putAll(store, 'contract-replace-reader', old)\n const allowed = new Set([JSON.stringify(shape(old)), JSON.stringify(shape(next))])\n\n let done = false\n const seen: string[][] = []\n const reader = (async () => {\n while (!done) {\n seen.push(await snapshot(store, 'contract-replace-reader'))\n await macrotask()\n }\n })()\n await store\n .replaceCollection('contract-replace-reader', entriesOf(next, true))\n .finally(() => {\n done = true\n })\n await reader\n\n expect(seen.length, 'the reader read while the replace ran').toBeGreaterThan(0)\n for (const observed of seen) {\n expect(\n allowed.has(JSON.stringify(observed)),\n `a partial set: ${observed.join(' ')}`,\n ).toBe(true)\n }\n expect(await snapshot(store, 'contract-replace-reader')).toEqual(shape(next))\n })\n },\n CASE_MS,\n )\n\n it(\n 'replaceCollection whose source throws part-way rejects with the source’s error and leaves the old set intact',\n async () => {\n await using(make, async (store) => {\n const old = docsFrom(['a', 'b', 'c'], 1)\n await putAll(store, 'contract-replace-failing', old)\n async function* failing(): AsyncGenerator<[string, Doc]> {\n yield ['a', { id: 'a', part: 'p', v: 2 }]\n yield ['z', { id: 'z', part: 'p', v: 2 }]\n throw new Error('contract: the source failed')\n }\n\n const failed = await store.replaceCollection('contract-replace-failing', failing()).then(\n () => null,\n (error: unknown) => error,\n )\n\n expect(String(failed)).toContain('contract: the source failed')\n expect(await snapshot(store, 'contract-replace-failing')).toEqual(shape(old))\n })\n },\n CASE_MS,\n )\n\n it(\n 'replaceCollection with an empty source empties the collection',\n async () => {\n await using(make, async (store) => {\n await putAll(store, 'contract-replace-empty', docsFrom(['a', 'b'], 1))\n await store.replaceCollection('contract-replace-empty', entriesOf([]))\n expect(await snapshot(store, 'contract-replace-empty')).toEqual([])\n expect(await store.get('contract-replace-empty', 'a')).toBeNull()\n })\n },\n CASE_MS,\n )\n\n const clock = opts.clock\n if (clock !== undefined) {\n it(\n 'replaceCollection writes documents without a TTL: a key whose old document had one is still there after that TTL passes',\n async () => {\n await using(make, async (store) => {\n await store.put('contract-replace-ttl', 'a', { id: 'a', part: 'p', v: 1 }, { ttl: 60 })\n await store.replaceCollection('contract-replace-ttl', entriesOf(docsFrom(['a', 'b'], 2)))\n await clock.advance(61_000)\n expect(await snapshot(store, 'contract-replace-ttl')).toEqual(['a:2', 'b:2'])\n })\n },\n CASE_MS,\n )\n }\n}\n","import { describe, expect, it } from 'vitest'\nimport type { EmailAdapter } from '@nymbalhq/types'\nimport { CASE_MS, healthAndDowntime, type Build, type ContractOptions } from './common.js'\n\nconst MAIL = {\n template: 'order-confirmation',\n to: 'test@example.com',\n vars: { orderNumber: 'ORD-001' },\n}\n\nexport function runEmailContract(\n name: string,\n build: Build<EmailAdapter>,\n options: ContractOptions<EmailAdapter> = {},\n): void {\n describe(`EmailAdapter contract: ${name}`, () => {\n it(\n 'sendTransactional resolves with accepted or messageId',\n async () => {\n const adapter = await build()\n const result = await adapter.sendTransactional(MAIL)\n expect(typeof result.accepted).toBe('boolean')\n },\n CASE_MS,\n )\n\n it(\n 'syncCustomerToList resolves without throwing',\n async () => {\n const adapter = await build()\n await expect(\n adapter.syncCustomerToList({\n customerId: 'cust-1',\n orderCount: 0,\n totalSpentMinor: 0,\n segment: 'new',\n createdAt: new Date().toISOString(),\n }),\n ).resolves.not.toThrow()\n },\n CASE_MS,\n )\n\n it(\n 'removeCustomerFromList resolves without throwing',\n async () => {\n const adapter = await build()\n await expect(adapter.removeCustomerFromList('cust-1')).resolves.not.toThrow()\n },\n CASE_MS,\n )\n\n healthAndDowntime(build, options.unreachable, 'sendTransactional()', (adapter) =>\n adapter.sendTransactional(MAIL),\n )\n })\n}\n","import { randomUUID } from 'node:crypto'\nimport { describe, expect, it } from 'vitest'\nimport type { EventBusAdapter, NymbalEvent } from '@nymbalhq/types'\nimport { CASE_MS, healthAndDowntime, type Build, type ContractOptions } from './common.js'\nimport { eventBusDeliveryCases } from './event-bus-delivery.js'\n\nexport interface EventBusContractOptions extends ContractOptions<EventBusAdapter> {\n /** Another instance on the same streams as the bus `make` returned last: only a shared bus passes it. */\n second?: () => Promise<EventBusAdapter>\n /** The bus's own knobs, set small by the caller: the claim and timeout cases assert the windows they bound. */\n timing?: { claimIdleMs: number; ackTimeoutMs: number }\n}\n\ntype Make = Build<EventBusAdapter>\n\nconst SLOW = 30_000\n\nfunction makeEvent(type: string, payload: Record<string, unknown> = {}): NymbalEvent {\n return {\n id: `evt-${randomUUID()}`,\n type,\n timestamp: new Date().toISOString(),\n source: 'contract-tests',\n correlationId: `corr-${randomUUID()}`,\n payload,\n metadata: { storeId: 'test', environment: 'development', version: '0.0.0' },\n }\n}\n\nconst delay = (ms: number): Promise<void> => new Promise((r) => setTimeout(r, ms))\n\nasync function using(buses: EventBusAdapter[], body: () => Promise<void>): Promise<void> {\n try {\n await body()\n } finally {\n for (const bus of buses) await bus.close()\n }\n}\n\n/**\n * The event bus contract every implementation runs. `publish` resolves only after every matching subscription's\n * handler has finished (what a read straight after a command relies on); a throwing handler is logged and does not\n * reject it; `replay` reaches `derived` subscriptions only; each subscription takes its events in order. With `second`,\n * a named subscription is handled once across instances and an unnamed one on every instance. Then the delivery\n * contract's cases, and health (and, given `unreachable`, downtime).\n */\nexport function runEventBusContract(\n name: string,\n make: Make,\n opts: EventBusContractOptions = {},\n): void {\n describe(`EventBusAdapter contract: ${name}`, () => {\n it('publish resolves after the matching handler has finished, and never calls a non-matching one', async () => {\n const bus = await make()\n await using([bus], async () => {\n const received: unknown[] = []\n const other: unknown[] = []\n await bus.subscribe('test.event.v1', async (e) => {\n await delay(50)\n received.push(e.payload)\n })\n await bus.subscribe('test.other.v1', async (e) => void other.push(e))\n await bus.publish(makeEvent('test.event.v1', { x: 1 }))\n expect(received).toEqual([{ x: 1 }])\n expect(other).toEqual([])\n })\n }, CASE_MS)\n\n it('a handler that throws leaves publish resolved and every other handler called', async () => {\n const bus = await make()\n await using([bus], async () => {\n const results: string[] = []\n await bus.subscribe('error.test.v1', async () => {\n throw new Error('boom')\n })\n await bus.subscribe('error.test.v1', async () => void results.push('ok'))\n await expect(bus.publish(makeEvent('error.test.v1'))).resolves.toBeUndefined()\n expect(results).toEqual(['ok'])\n })\n }, CASE_MS)\n\n it('replay reaches derived subscriptions only', async () => {\n const bus = await make()\n await using([bus], async () => {\n const derived: string[] = []\n const sideEffect: string[] = []\n await bus.subscribe('replay.test.v1', async (e) => void derived.push(e.id), {\n name: 'contract-projection',\n derived: true,\n })\n await bus.subscribe('replay.test.v1', async (e) => void sideEffect.push(e.id), {\n name: 'contract-side-effect',\n })\n const events = [makeEvent('replay.test.v1'), makeEvent('replay.test.v1')]\n await bus.replay(events)\n expect(derived).toEqual(events.map((e) => e.id))\n expect(sideEffect).toEqual([])\n })\n }, CASE_MS)\n\n it('publishBatch reaches each subscription in batch order, through wildcards and pattern arrays', async () => {\n const bus = await make()\n await using([bus], async () => {\n const wildcard: string[] = []\n const listed: string[] = []\n await bus.subscribe('batch.*', async (e) => void wildcard.push(e.id))\n await bus.subscribe(['batch.a.v1', 'batch.c.v1'], async (e) => void listed.push(e.id), {\n name: 'contract-listed',\n })\n const events = ['batch.a.v1', 'batch.b.v1', 'batch.c.v1', 'batch.a.v1'].map((t, seq) =>\n makeEvent(t, { seq }),\n )\n await bus.publishBatch(events)\n expect(wildcard).toEqual(events.map((e) => e.id))\n expect(listed).toEqual(events.filter((e) => e.type !== 'batch.b.v1').map((e) => e.id))\n })\n }, CASE_MS)\n\n it('an unsubscribed handler receives nothing more', async () => {\n const bus = await make()\n await using([bus], async () => {\n const received: string[] = []\n const sub = await bus.subscribe('unsub.event.v1', async (e) => void received.push(e.id))\n const before = makeEvent('unsub.event.v1')\n await bus.publish(before)\n await bus.unsubscribe(sub)\n await bus.publish(makeEvent('unsub.event.v1'))\n expect(received).toEqual([before.id])\n })\n }, CASE_MS)\n\n it('on one instance, a named and an unnamed subscription each handle every event once', async () => {\n const bus = await make()\n await using([bus], async () => {\n const named: string[] = []\n const unnamed: string[] = []\n await bus.subscribe('both.event.v1', async (e) => void named.push(e.id), {\n name: 'contract-named',\n })\n await bus.subscribe('both.event.v1', async (e) => void unnamed.push(e.id))\n const events = [makeEvent('both.event.v1'), makeEvent('both.event.v1')]\n for (const e of events) await bus.publish(e)\n expect(named).toEqual(events.map((e) => e.id))\n expect(unnamed).toEqual(named)\n })\n }, CASE_MS)\n\n eventBusDeliveryCases(make, opts)\n\n healthAndDowntime(make, opts.unreachable, 'publish()', (bus) =>\n bus.publish(makeEvent('contract.down.v1')),\n )\n\n const second = opts.second\n if (second === undefined) return\n\n it(\n 'across two instances, a named subscription handles each event once in total, and an unnamed one on each',\n async () => {\n const a = await make()\n const b = await second()\n await using([a, b], async () => {\n const named: string[] = []\n const onA: string[] = []\n const onB: string[] = []\n await a.subscribe('shared.*', async (e) => void named.push(e.id), {\n name: 'contract-shared',\n })\n await b.subscribe('shared.*', async (e) => void named.push(e.id), {\n name: 'contract-shared',\n })\n await a.subscribe('shared.*', async (e) => void onA.push(e.id))\n await b.subscribe('shared.*', async (e) => void onB.push(e.id))\n const events = Array.from({ length: 6 }, (_, seq) => makeEvent('shared.x', { seq }))\n for (const [i, e] of events.entries()) await (i % 2 === 0 ? a : b).publish(e)\n // Each instance's own unnamed subscription is waited on by its own publishes: a fence on each.\n const fenceA = makeEvent('shared.fence')\n const fenceB = makeEvent('shared.fence')\n await a.publish(fenceA)\n await b.publish(fenceB)\n\n const ids = events.map((e) => e.id)\n expect(named.filter((id) => ids.includes(id)).sort()).toEqual([...ids].sort())\n expect(onA.filter((id) => ids.includes(id))).toEqual(ids)\n expect(onB.filter((id) => ids.includes(id))).toEqual(ids)\n })\n },\n SLOW,\n )\n })\n}\n","import { randomUUID } from 'node:crypto'\nimport fc from 'fast-check'\nimport { describe, expect, it } from 'vitest'\nimport type { EventBusAdapter, NymbalEvent } from '@nymbalhq/types'\nimport type { Build } from './common.js'\n\n// The event bus delivery contract. With `second` (another instance on the same streams as the bus `make` returned\n// last) and `timing` (the bus's own knobs, set small) it adds the cases only a shared bus has. Kills: a publish that\n// resolves before its handlers ran (a read straight after a command misses its projection), a throwing handler that\n// rejects publish or starves another, replay reaching side effects, batch order lost, two instances double-handling a\n// named event, an instance missing an unnamed (admin tab) event, and a dead instance or consumer stalling every\n// publish (every checkout) until the timeout.\n\n/** What the delivery cases read of the suite's options. */\nexport interface DeliveryOptions {\n second?: () => Promise<EventBusAdapter>\n timing?: { claimIdleMs: number; ackTimeoutMs: number }\n}\n\nconst SLOW = 60_000\n\nfunction event(type: string, payload: Record<string, unknown> = {}): NymbalEvent {\n return {\n id: `evt-${randomUUID()}`,\n type,\n timestamp: new Date().toISOString(),\n source: 'contract-contract',\n correlationId: `corr-${randomUUID()}`,\n payload,\n metadata: { storeId: 'contract', environment: 'development', version: '0.0.0' },\n }\n}\n\nconst delay = (ms: number): Promise<void> => new Promise((r) => setTimeout(r, ms))\n\n/** Polls `check` (no fixed sleep); throws naming `label` after `ms`. */\nasync function until(check: () => boolean, label: string, ms: number): Promise<void> {\n const deadline = Date.now() + ms\n while (!check()) {\n if (Date.now() > deadline) throw new Error(`timed out after ${ms} ms waiting for ${label}`)\n await delay(10)\n }\n}\n\nfunction gate(): { wait: Promise<void>; open(): void } {\n let open!: () => void\n const wait = new Promise<void>((r) => {\n open = r\n })\n return { wait, open }\n}\n\nasync function closingAll(buses: EventBusAdapter[], body: () => Promise<void>): Promise<void> {\n try {\n await body()\n } finally {\n for (const bus of buses) await bus.close()\n }\n}\n\nconst TYPES = ['order.created.v1', 'order.paid.v1', 'cart.updated.v1'] as const\n\n/** The delivery cases, registered inside the suite's describe. */\nexport function eventBusDeliveryCases(make: Build<EventBusAdapter>, opts: DeliveryOptions): void {\n describe('keeps the delivery contract', () => {\n it(\n 'publish resolves only after every matching handler has finished: a 200 ms handler, named and unnamed, is done first',\n async () => {\n const bus = await make()\n await closingAll([bus], async () => {\n const finished: string[] = []\n await bus.subscribe('contract.slow.v1', async () => {\n await delay(200)\n finished.push('unnamed')\n })\n await bus.subscribe(\n 'contract.slow.v1',\n async () => {\n await delay(200)\n finished.push('named')\n },\n { name: 'contract-slow' },\n )\n\n const startedAt = Date.now()\n await bus.publish(event('contract.slow.v1'))\n const elapsed = Date.now() - startedAt\n\n expect([...finished].sort()).toEqual(['named', 'unnamed'])\n expect(elapsed).toBeGreaterThanOrEqual(190)\n })\n },\n SLOW,\n )\n\n it(\n 'a throwing handler leaves publish resolved and every other matching handler called, event after event',\n async () => {\n const bus = await make()\n await closingAll([bus], async () => {\n const received: string[] = []\n await bus.subscribe(\n 'contract.boom.v1',\n async () => {\n throw new Error('contract handler failure')\n },\n { name: 'contract-throws' },\n )\n await bus.subscribe('contract.boom.v1', async (e) => {\n received.push(e.id)\n })\n const events = [event('contract.boom.v1'), event('contract.boom.v1'), event('contract.boom.v1')]\n\n for (const e of events) await expect(bus.publish(e)).resolves.toBeUndefined()\n\n expect(received).toEqual(events.map((e) => e.id))\n })\n },\n SLOW,\n )\n\n it(\n 'replay reaches derived subscriptions only, in order; a later publish still reaches every subscription',\n async () => {\n const bus = await make()\n await closingAll([bus], async () => {\n const derived: string[] = []\n const sideNamed: string[] = []\n const sideUnnamed: string[] = []\n await bus.subscribe('contract.replay.v1', async (e) => void derived.push(e.id), {\n name: 'contract-projection',\n derived: true,\n })\n await bus.subscribe('contract.replay.v1', async (e) => void sideNamed.push(e.id), {\n name: 'contract-side-effect',\n })\n await bus.subscribe('contract.replay.v1', async (e) => void sideUnnamed.push(e.id))\n const replayed = [event('contract.replay.v1'), event('contract.replay.v1')]\n\n await bus.replay(replayed)\n\n expect(derived).toEqual(replayed.map((e) => e.id))\n expect(sideNamed).toEqual([])\n expect(sideUnnamed).toEqual([])\n\n const live = event('contract.replay.v1')\n await bus.publish(live)\n expect(derived).toEqual([...replayed, live].map((e) => e.id))\n expect(sideNamed).toEqual([live.id])\n expect(sideUnnamed).toEqual([live.id])\n })\n },\n SLOW,\n )\n\n it(\n 'publishBatch reaches each subscription with exactly its matching events, in batch order (wildcards and pattern arrays)',\n async () => {\n await fc.assert(\n fc.asyncProperty(\n fc.array(fc.constantFrom(...TYPES), { minLength: 1, maxLength: 12 }),\n async (types) => {\n const bus = await make()\n await closingAll([bus], async () => {\n const fence = event('contract.fence.v1')\n const subs = [\n { patterns: ['order.*', fence.type], name: undefined },\n { patterns: ['cart.updated.v1', 'order.paid.v1', fence.type], name: 'contract-arr' },\n { patterns: ['order.created.v1', fence.type], name: 'contract-one' },\n ]\n const seen = subs.map(() => [] as string[])\n for (const [i, sub] of subs.entries()) {\n await bus.subscribe(\n sub.patterns,\n async (e) => void seen[i]!.push(e.id),\n sub.name === undefined ? undefined : { name: sub.name },\n )\n }\n const events = types.map((type, seq) => event(type, { seq }))\n\n await bus.publishBatch(events)\n // Each subscription takes its events in order, so once the fence is handled the batch was too.\n await bus.publish(fence)\n\n const matches = (patterns: string[], type: string): boolean =>\n patterns.some((p) =>\n p.endsWith('*') ? type.startsWith(p.slice(0, -1)) : p === type,\n )\n for (const [i, sub] of subs.entries()) {\n const expected = events.filter((e) => matches(sub.patterns, e.type))\n expect(seen[i], sub.patterns.join('|')).toEqual([\n ...expected.map((e) => e.id),\n fence.id,\n ])\n }\n })\n },\n ),\n { numRuns: 15 },\n )\n },\n SLOW,\n )\n\n it(\n 'an unsubscribed handler, by bus.unsubscribe or by its own unsubscribe(), receives nothing more',\n async () => {\n const bus = await make()\n await closingAll([bus], async () => {\n const gone: string[] = []\n const goneToo: string[] = []\n const kept: string[] = []\n const a = await bus.subscribe('contract.unsub.v1', async (e) => void gone.push(e.id), {\n name: 'contract-unsub',\n })\n const b = await bus.subscribe('contract.unsub.v1', async (e) => void goneToo.push(e.id))\n await bus.subscribe('contract.unsub.v1', async (e) => void kept.push(e.id))\n const before = event('contract.unsub.v1')\n await bus.publish(before)\n\n await bus.unsubscribe(a)\n await b.unsubscribe()\n const after = [event('contract.unsub.v1'), event('contract.unsub.v1')]\n for (const e of after) await bus.publish(e)\n\n expect(kept).toEqual([before, ...after].map((e) => e.id))\n expect(gone).toEqual([before.id])\n expect(goneToo).toEqual([before.id])\n })\n },\n SLOW,\n )\n\n it(\n 'on one instance, a named and an unnamed subscription each handle every event once',\n async () => {\n const bus = await make()\n await closingAll([bus], async () => {\n const named: string[] = []\n const unnamed: string[] = []\n await bus.subscribe('contract.both.v1', async (e) => void named.push(e.id), {\n name: 'contract-named',\n })\n await bus.subscribe('contract.both.v1', async (e) => void unnamed.push(e.id))\n const events = Array.from({ length: 6 }, () => event('contract.both.v1'))\n\n for (const e of events) await bus.publish(e)\n\n expect(named).toEqual(events.map((e) => e.id))\n expect(unnamed).toEqual(named)\n })\n },\n SLOW,\n )\n\n const second = opts.second\n if (second === undefined) return\n\n describe('two instances on the same streams', () => {\n const N = 12\n\n it(\n 'one named subscription on both instances handles each of N events exactly once in total',\n async () => {\n const a = await make()\n const b = await second()\n await closingAll([a, b], async () => {\n const byA: string[] = []\n const byB: string[] = []\n await a.subscribe('contract.named.*', async (e) => void byA.push(e.id), {\n name: 'contract-shared',\n })\n await b.subscribe('contract.named.*', async (e) => void byB.push(e.id), {\n name: 'contract-shared',\n })\n const events = Array.from({ length: N }, (_, seq) => event('contract.named.x', { seq }))\n\n for (const [i, e] of events.entries()) await (i % 2 === 0 ? a : b).publish(e)\n // A per-instance group would hand every event to both; these fences make its copies show before the count.\n await b.publish(event('contract.named.fence'))\n await a.publish(event('contract.named.fence'))\n\n const ids = new Set(events.map((e) => e.id))\n const handled = [...byA, ...byB].filter((id) => ids.has(id))\n expect(handled.length).toBe(events.length)\n expect([...handled].sort()).toEqual(events.map((e) => e.id).sort())\n })\n },\n SLOW,\n )\n\n it(\n 'an unnamed subscription on each instance receives all N events, in order, on both',\n async () => {\n const a = await make()\n const b = await second()\n await closingAll([a, b], async () => {\n const onA: string[] = []\n const onB: string[] = []\n await a.subscribe('contract.fanout.*', async (e) => void onA.push(e.id))\n await b.subscribe('contract.fanout.*', async (e) => void onB.push(e.id))\n const events = Array.from({ length: N }, (_, seq) => event('contract.fanout.x', { seq }))\n\n for (const e of events) await a.publish(e)\n const fenceB = event('contract.fanout.fence')\n await b.publish(fenceB)\n\n const ids = events.map((e) => e.id)\n expect(onA.slice(0, N)).toEqual(ids)\n expect(onB.slice(0, N)).toEqual(ids)\n expect(onB[N]).toBe(fenceB.id)\n })\n },\n SLOW,\n )\n\n it(\n 'replay on one instance reaches its own derived handlers and nothing on the other instance',\n async () => {\n const a = await make()\n const b = await second()\n await closingAll([a, b], async () => {\n const derivedA: string[] = []\n const derivedB: string[] = []\n const sideB: string[] = []\n await a.subscribe('contract.rebuild.*', async (e) => void derivedA.push(e.id), {\n name: 'contract-projection',\n derived: true,\n })\n await b.subscribe('contract.rebuild.*', async (e) => void derivedB.push(e.id), {\n name: 'contract-projection',\n derived: true,\n })\n await b.subscribe('contract.rebuild.*', async (e) => void sideB.push(e.id), {\n name: 'contract-side-effect',\n })\n const replayed = [event('contract.rebuild.x'), event('contract.rebuild.x')]\n\n await a.replay(replayed)\n // b reads its groups in stream order: a replay that went through the stream would reach b before this.\n const fence = event('contract.rebuild.fence')\n await b.publish(fence)\n\n expect(derivedA.slice(0, replayed.length)).toEqual(replayed.map((e) => e.id))\n const ids = new Set(replayed.map((e) => e.id))\n expect(derivedB.filter((id) => ids.has(id))).toEqual([])\n expect(sideB).toEqual([fence.id])\n })\n },\n SLOW,\n )\n\n const timing = opts.timing\n if (timing === undefined) return\n const { claimIdleMs, ackTimeoutMs } = timing\n\n it(\n 'groups left by a stopped instance (never unsubscribed) do not delay publish on the other instance',\n async () => {\n const a = await make()\n const b = await second()\n await closingAll([a], async () => {\n await b.subscribe('contract.left.*', async () => undefined, { name: 'contract-left-behind' })\n await b.subscribe('contract.left.*', async () => undefined)\n await b.close()\n const handled: string[] = []\n await a.subscribe('contract.left.*', async (e) => void handled.push(e.id), {\n name: 'contract-live',\n })\n const e = event('contract.left.x')\n\n const startedAt = Date.now()\n await a.publish(e)\n const elapsed = Date.now() - startedAt\n\n expect(handled).toEqual([e.id])\n expect(elapsed).toBeLessThan(ackTimeoutMs / 2)\n })\n },\n SLOW,\n )\n\n it(\n 'an entry pending on a stopped consumer of a named group is handled by the live one after claimIdleMs and before ackTimeoutMs',\n async () => {\n const a = await make()\n const b = await second()\n const held = gate()\n let closingB: Promise<void> | undefined\n try {\n let receivedByB: number | undefined\n await b.subscribe(\n 'contract.claim.*',\n async () => {\n receivedByB = Date.now()\n await held.wait\n },\n { name: 'contract-claimed' },\n )\n const stranded = event('contract.claim.x')\n // a holds no subscription to the group yet, so this publish waits on nothing and b's consumer takes it.\n await a.publish(stranded)\n await until(() => receivedByB !== undefined, 'b to receive the entry', ackTimeoutMs)\n closingB = b.close()\n\n const byA: Array<{ id: string; at: number }> = []\n await a.subscribe(\n 'contract.claim.*',\n async (e) => void byA.push({ id: e.id, at: Date.now() }),\n {\n name: 'contract-claimed',\n },\n )\n const next = event('contract.claim.x')\n const startedAt = Date.now()\n await a.publish(next)\n const publishMs = Date.now() - startedAt\n await until(\n () => byA.some((h) => h.id === stranded.id),\n 'a to take over the stranded entry',\n ackTimeoutMs * 2,\n )\n\n const claimed = byA.find((h) => h.id === stranded.id)!\n const idle = claimed.at - receivedByB!\n expect(idle, 'taken over before claimIdleMs').toBeGreaterThanOrEqual(claimIdleMs - 50)\n expect(idle, 'taken over only after ackTimeoutMs').toBeLessThan(ackTimeoutMs)\n expect(byA.filter((h) => h.id === stranded.id).length).toBe(1)\n expect(publishMs, 'a publish on the group waited out the timeout').toBeLessThan(\n ackTimeoutMs,\n )\n } finally {\n held.open()\n await closingB\n await a.close()\n }\n },\n SLOW,\n )\n\n it(\n 'an unnamed subscription unsubscribed while publish waits on it lets publish resolve well before ackTimeoutMs',\n async () => {\n const a = await make()\n const held = gate()\n try {\n let entered = false\n const sub = await a.subscribe('contract.wait.*', async () => {\n entered = true\n await held.wait\n })\n const publishing = a.publish(event('contract.wait.x')).then(\n () => Date.now(),\n (error: unknown) => error,\n )\n await until(() => entered, 'the handler to start', ackTimeoutMs)\n\n const unsubscribedAt = Date.now()\n const unsubscribing = a.unsubscribe(sub)\n const outcome = await publishing\n\n expect(typeof outcome, `publish rejected: ${String(outcome)}`).toBe('number')\n expect((outcome as number) - unsubscribedAt).toBeLessThan(ackTimeoutMs / 2)\n held.open()\n await unsubscribing\n } finally {\n held.open()\n await a.close()\n }\n },\n SLOW,\n )\n })\n })\n}\n","import { describe, expect, it } from 'vitest'\nimport type { MediaStorage } from '@nymbalhq/types'\nimport { CASE_MS, healthAndDowntime, type Build, type ContractOptions } from './common.js'\n\nexport interface MediaStorageContractOptions extends ContractOptions<MediaStorage> {\n /** Reads back the bytes a URL `put` returned serves: the storage's public URL, or the file a local URL names. */\n fetchUrl: (url: string) => Promise<Uint8Array>\n}\n\n/**\n * The media storage contract every implementation runs: `put` resolves with a URL, and the bytes read back from that\n * URL (through `fetchUrl`, which knows where the storage serves from) are the bytes that were put; then health (and,\n * given `unreachable`, downtime).\n */\nexport function runMediaStorageContract(\n name: string,\n make: Build<MediaStorage>,\n options: MediaStorageContractOptions,\n): void {\n const { fetchUrl } = options\n describe(`MediaStorage contract: ${name}`, () => {\n it('reports put among its capabilities', async () => {\n const storage = await make()\n expect(storage.capabilities()).toContain('put')\n }, CASE_MS)\n\n it('put then a read of the returned url gives back the same bytes, for nested keys too', async () => {\n const storage = await make()\n const bodies = new Map<string, Uint8Array>([\n ['image.png', Uint8Array.from([137, 80, 78, 71, 0, 255, 1])],\n ['products/42/large.jpg', new TextEncoder().encode('jpeg bytes ✓')],\n ['empty.txt', new Uint8Array(0)],\n ])\n const urls = new Set<string>()\n for (const [key, body] of bodies) {\n const { url } = await storage.put(key, body, 'application/octet-stream')\n urls.add(url)\n expect([...(await fetchUrl(url))]).toEqual([...body])\n }\n expect(urls.size).toBe(bodies.size)\n }, CASE_MS)\n\n it('a second put under a key replaces what the url serves', async () => {\n const storage = await make()\n await storage.put('replaced.bin', Uint8Array.from([1, 2, 3]), 'application/octet-stream')\n const { url } = await storage.put(\n 'replaced.bin',\n Uint8Array.from([9]),\n 'application/octet-stream',\n )\n expect([...(await fetchUrl(url))]).toEqual([9])\n }, CASE_MS)\n\n healthAndDowntime(make, options.unreachable, 'put()', (storage) =>\n storage.put('contract-down.bin', Uint8Array.from([1]), 'application/octet-stream'),\n )\n })\n}\n","import { randomUUID } from 'node:crypto'\nimport { describe, expect, it } from 'vitest'\nimport type { PaymentsAdapter } from '@nymbalhq/types'\nimport { CASE_MS, healthAndDowntime, type Build, type ContractOptions } from './common.js'\n\nexport interface PaymentsContractOptions extends ContractOptions<PaymentsAdapter> {\n /** One webhook as the provider would deliver it, signed. Given, the suite parses it twice and compares. */\n signedWebhook?: () => { rawBody: string | Buffer; signature: string }\n}\n\n/** The intent amount of the refund idempotency case: odd, so its two halves differ. */\nconst TOTAL = 1999\n\n/** The code a call rejected with, or null when it resolved. */\nasync function rejectionCode(call: Promise<unknown>): Promise<unknown> {\n return call.then(\n () => null,\n (err: unknown) => (err as { code?: unknown } | null)?.code ?? err,\n )\n}\n\nexport function runPaymentsContract(\n name: string,\n build: Build<PaymentsAdapter>,\n options: PaymentsContractOptions = {},\n): void {\n describe(`PaymentsAdapter contract: ${name}`, () => {\n it(\n 'createPaymentIntent returns a clientSecret and id',\n async () => {\n const adapter = await build()\n const intent = await adapter.createPaymentIntent({\n amountMinor: 1000,\n currency: 'GBP',\n orderRef: `contract-${randomUUID()}`,\n })\n expect(intent.id).toBeTruthy()\n expect(intent.clientSecret).toBeTruthy()\n expect(intent.amountMinor).toBe(1000)\n expect(intent.currency).toBe('GBP')\n },\n CASE_MS,\n )\n\n it(\n 'getPaymentStatus returns a valid status',\n async () => {\n const adapter = await build()\n const intent = await adapter.createPaymentIntent({ amountMinor: 500, currency: 'GBP' })\n const status = await adapter.getPaymentStatus(intent.id)\n expect([\n 'requires_payment_method',\n 'requires_confirmation',\n 'requires_action',\n 'processing',\n 'requires_capture',\n 'succeeded',\n 'cancelled',\n 'failed',\n ]).toContain(status)\n },\n CASE_MS,\n )\n\n // Seen through the payments surface alone: after T/2 twice under one key, the remainder still fits and one more\n // minor unit does not, which holds only when the retry refunded nothing. Kills: a retry that refunds again.\n it(\n 'idempotency: a refund repeated with the same idempotencyKey returns the same refund and refunds once',\n async () => {\n const adapter = await build()\n const intent = await adapter.createPaymentIntent({\n amountMinor: TOTAL,\n currency: 'GBP',\n orderRef: `contract-${randomUUID()}`,\n })\n if (intent.status !== 'succeeded') await adapter.capturePayment(intent.id)\n const half = Math.floor(TOTAL / 2)\n const key = `contract-refund-${randomUUID()}`\n\n const first = await adapter.refund(intent.id, half, 'requested_by_customer', {\n idempotencyKey: key,\n })\n const again = await adapter.refund(intent.id, half, 'requested_by_customer', {\n idempotencyKey: key,\n })\n expect(again.refundId, 'the retry under the same key made another refund').toBe(\n first.refundId,\n )\n expect(again.amountMinor).toBe(first.amountMinor)\n\n const rest = await adapter.refund(intent.id, TOTAL - half, 'requested_by_customer', {\n idempotencyKey: `${key}-rest`,\n })\n expect(rest.amountMinor + first.amountMinor).toBe(TOTAL)\n const over = await rejectionCode(\n adapter.refund(intent.id, 1, 'requested_by_customer', { idempotencyKey: `${key}-over` }),\n )\n expect(over, 'a minor unit past the amount was refunded').toBe('payment.refund_rejected')\n },\n CASE_MS,\n )\n\n const signedWebhook = options.signedWebhook\n if (signedWebhook !== undefined) {\n it(\n 'idempotency: parsing one signed webhook event twice gives equal results',\n async () => {\n const adapter = await build()\n const { rawBody, signature } = signedWebhook()\n const first = await adapter.parseWebhook(rawBody, signature)\n const second = await adapter.parseWebhook(rawBody, signature)\n expect(second).toEqual(first)\n },\n CASE_MS,\n )\n }\n\n healthAndDowntime(build, options.unreachable, 'createPaymentIntent()', (adapter) =>\n adapter.createPaymentIntent({ amountMinor: 100, currency: 'GBP' }),\n )\n })\n}\n","import { randomUUID } from 'node:crypto'\nimport fc from 'fast-check'\nimport { describe, expect, it } from 'vitest'\nimport type { Review, ReviewsAdapter, ReviewsResult } from '@nymbalhq/types'\nimport { CASE_MS, healthAndDowntime, type Build, type ContractOptions } from './common.js'\n\n// Every case seeds under a product of its own, and reads what it seeded with the moderation status the adapter\n// reported on submitReview: one that files reviews for moderation reads them as pending, one that auto-approves as\n// approved.\n\nasync function seed(adapter: ReviewsAdapter, count: number): Promise<Review[]> {\n const productId = `contract-reviews-${randomUUID()}`\n const seeded: Review[] = []\n for (let i = 0; i < count; i++) {\n const { review } = await adapter.submitReview({\n productId,\n customerId: null,\n orderId: null,\n rating: (i % 5) + 1,\n title: `review ${i}`,\n body: `body ${i}`,\n })\n seeded.push(review)\n }\n return seeded\n}\n\n/** Every page from page 1, stopping after `maxPages`: a cursor that never ends shows as a walk that long. */\nasync function walk(\n adapter: ReviewsAdapter,\n first: Review,\n limit: number,\n maxPages: number,\n): Promise<ReviewsResult[]> {\n const pages: ReviewsResult[] = []\n let cursor: string | undefined\n do {\n const page = await adapter.getProductReviews(first.productId, {\n limit,\n status: first.moderationStatus,\n ...(cursor !== undefined && { cursor }),\n })\n pages.push(page)\n cursor = page.nextCursor ?? undefined\n } while (cursor !== undefined && pages.length < maxPages)\n return pages\n}\n\nexport function runReviewsContract(\n name: string,\n build: Build<ReviewsAdapter>,\n options: ContractOptions<ReviewsAdapter> = {},\n): void {\n describe(`ReviewsAdapter contract: ${name}`, () => {\n it(\n 'submitReview returns the created review',\n async () => {\n const adapter = await build()\n const productId = `contract-reviews-${randomUUID()}`\n const { review } = await adapter.submitReview({\n productId,\n customerId: null,\n orderId: null,\n rating: 5,\n title: 'Great!',\n body: 'Really liked it.',\n })\n expect(review.productId).toBe(productId)\n expect(review.rating).toBe(5)\n expect(review.id).toBeTruthy()\n },\n CASE_MS,\n )\n\n it(\n 'getProductReviews returns the submitted review, read under the status submitReview reported',\n async () => {\n const adapter = await build()\n const [review] = await seed(adapter, 1)\n const { items } = await adapter.getProductReviews(review!.productId, {\n status: review!.moderationStatus,\n })\n expect(items.map((r) => r.id)).toEqual([review!.id])\n expect(items[0]!.productId).toBe(review!.productId)\n },\n CASE_MS,\n )\n\n it(\n 'getAggregateRating is consistent: its histogram sums to its count, and an approved review is counted',\n async () => {\n const adapter = await build()\n const [review] = await seed(adapter, 1)\n const agg = await adapter.getAggregateRating(review!.productId)\n expect(agg.productId).toBe(review!.productId)\n expect(Object.values(agg.histogram).reduce((a, b) => a + b, 0)).toBe(agg.count)\n if (agg.count === 0) expect(agg.average).toBe(0)\n else {\n expect(agg.average).toBeGreaterThanOrEqual(1)\n expect(agg.average).toBeLessThanOrEqual(5)\n }\n if (review!.moderationStatus === 'approved') expect(agg.count).toBeGreaterThanOrEqual(1)\n },\n CASE_MS,\n )\n\n // Kills: an adapter that ignores the cursor (page 1 again), returns no next cursor after the first page, or\n // repeats or skips a review between pages.\n it(\n 'pagination: over seeds larger than a page, the cursor walk from page 1 yields each review once, the walk is the seed, no page exceeds limit and nextCursor is null exactly on the last page',\n async () => {\n const adapter = await build()\n await fc.assert(\n fc.asyncProperty(\n fc.integer({ min: 1, max: 5 }),\n fc.integer({ min: 1, max: 8 }),\n async (limit, extra) => {\n const seeded = await seed(adapter, limit + extra)\n const status = seeded[0]!.moderationStatus\n const expected = seeded.filter((r) => r.moderationStatus === status).map((r) => r.id)\n const pages = await walk(\n adapter,\n seeded[0]!,\n limit,\n Math.ceil(expected.length / limit) + 2,\n )\n const walked = pages.flatMap((p) => p.items.map((r) => r.id))\n\n expect(new Set(walked).size, 'a review came back on two pages').toBe(walked.length)\n expect([...walked].sort()).toEqual([...expected].sort())\n for (const page of pages) expect(page.items.length).toBeLessThanOrEqual(limit)\n expect(pages.map((p) => p.nextCursor === null)).toEqual(\n pages.map((_, i) => i === pages.length - 1),\n )\n },\n ),\n { numRuns: 15 },\n )\n },\n 120_000,\n )\n\n healthAndDowntime(build, options.unreachable, 'getProductReviews()', (adapter) =>\n adapter.getProductReviews(`contract-reviews-${randomUUID()}`, { limit: 1 }),\n )\n })\n}\n","import { randomUUID } from 'node:crypto'\nimport fc from 'fast-check'\nimport { describe, expect, it } from 'vitest'\nimport type { SearchAdapter, SearchResult } from '@nymbalhq/types'\nimport { CASE_MS, healthAndDowntime, type Build, type ContractOptions } from './common.js'\nimport {\n matchesQuery,\n searchTerms,\n tierOf,\n toSearchDocument,\n type ContractProduct,\n} from './search-oracle.js'\n\n// The search contract. The cases are index-agnostic: the index may be shared across cases and runs and no runner\n// truncates it. Every generated product carries a run token term in its name and every query puts the token first, so\n// the AND of the query's terms scopes it to the run, the oracle is over the run's products, and the run removes them\n// when it ends.\n\nexport interface SearchContractOptions extends ContractOptions<SearchAdapter> {\n /** The adapter ranks by tiers (every term in the name, then every term in name, SKU or variant name), then score,\n * then id. Native does; a vendor's need not, so the ranking case runs only when the runner says so. */\n ranking?: boolean\n /** The adapter reports `facet` and counts `facet('categoryIds', {query, filters})` within the query's matches. */\n facets?: boolean\n /** This adapter's cursor for an offset, valid or not (it encodes; only search validates), so the malformed-cursor\n * case can build a negative and a non-integer cursor. Without it only the undecodable and the stale cursor run. */\n cursorAt?: (offset: number) => string\n /** fast-check runs per property (default 25). */\n numRuns?: number\n}\n\n// --- Generators ---------------------------------------------------------------------------------------------------\n\n/** One length, a leading letter no generated word uses: no token is a prefix of another or of a generated word. */\nfunction runToken(): string {\n return `t${randomUUID().replace(/-/g, '').slice(0, 15)}`\n}\n\n/** Words over a small alphabet, so they share prefixes and collide often. */\nconst word = fc.string({\n unit: fc.constantFrom('a', 'b', 'c', 'd', '1', '2'),\n minLength: 1,\n maxLength: 3,\n})\nconst words = (max: number) => fc.array(word, { maxLength: max }).map((ws) => ws.join(' '))\n\ninterface GenProduct {\n name: string\n description: string\n // priceMinor's digits overlap the words' digits: a search over every field would match on a price.\n variants: Array<{ sku: string; name: string; priceMinor: number }>\n categories: number[]\n}\n\nconst CATEGORIES = 3\n\nconst genProduct: fc.Arbitrary<GenProduct> = fc.record({\n name: words(3),\n description: words(6),\n variants: fc.array(\n fc.record({ sku: word, name: words(2), priceMinor: fc.integer({ min: 1, max: 2222 }) }),\n { maxLength: 3 },\n ),\n categories: fc.subarray([0, 1, 2]),\n})\n\n/** The run's category ids: one term each, `c0…`, `c1…`; a search over every field would match `c1` on one. */\nfunction runCategories(token: string): string[] {\n return Array.from({ length: CATEGORIES }, (_, k) => `c${k}${token.slice(1)}`)\n}\n\nfunction materialise(token: string, gen: GenProduct, i: number, cats: string[]): ContractProduct {\n return {\n id: `${token}-${i}`,\n name: gen.name === '' ? token : `${token} ${gen.name}`,\n description: gen.description,\n variants: gen.variants,\n categoryIds: gen.categories.map((k) => cats[k]!),\n }\n}\n\n// --- Walking -------------------------------------------------------------------------------------------------------\n\nasync function walk(\n adapter: SearchAdapter,\n query: string,\n limit: number,\n expectedMatches: number,\n filters?: Record<string, unknown>,\n): Promise<SearchResult[]> {\n // Room for every page an exact walk needs, and two more: a walk past it is one whose cursor does not advance.\n const maxPages = Math.ceil(expectedMatches / limit) + 2\n const pages: SearchResult[] = []\n const seen = new Set<string>()\n let cursor: string | undefined\n for (;;) {\n const page = await adapter.search(query, {\n limit,\n ...(cursor !== undefined && { cursor }),\n ...(filters !== undefined && { filters }),\n })\n pages.push(page)\n // Fails at the first repeat rather than after the whole walk: a cursor read as page 1 then costs two pages, not\n // every page, on each of the runs fast-check shrinks through.\n const again = page.items.map((item) => item.id).filter((id) => seen.has(id))\n expect(again, `the walk for \"${query}\": an id came back on page ${pages.length}`).toEqual([])\n for (const item of page.items) seen.add(item.id)\n if (page.nextCursor === null) return pages\n expect(\n pages.length,\n `the walk for \"${query}\" did not end within ${maxPages} pages`,\n ).toBeLessThan(maxPages)\n cursor = page.nextCursor\n }\n}\n\nconst idsOf = (pages: SearchResult[]) => pages.flatMap((p) => p.items.map((item) => item.id))\n\n/** One walk against the oracle's match set: each match once, an exact total, no page past limit, a last page. */\nfunction expectExactWalk(\n pages: SearchResult[],\n expected: string[],\n limit: number,\n label: string,\n): void {\n const ids = idsOf(pages)\n expect(new Set(ids).size, `${label}: an id came back on two pages`).toBe(ids.length)\n expect([...ids].sort(), `${label}: the walk's union is not the oracle's match set`).toEqual(\n [...expected].sort(),\n )\n for (const [i, page] of pages.entries()) {\n expect(page.total, `${label}: total on page ${i + 1}`).toBe(expected.length)\n expect(page.items.length, `${label}: page ${i + 1} exceeds limit`).toBeLessThanOrEqual(limit)\n expect(\n page.nextCursor === null,\n `${label}: nextCursor is null on page ${i + 1} of ${pages.length}`,\n ).toBe(i === pages.length - 1)\n // With an exact total the page that completes the walk is the last: only a walk with no match has an empty page.\n if (expected.length > 0)\n expect(page.items.length, `${label}: page ${i + 1} is empty`).toBeGreaterThan(0)\n }\n}\n\nconst SLOW = 180_000\n\nexport function runSearchContract(\n name: string,\n build: Build<SearchAdapter>,\n options: SearchContractOptions = {},\n): void {\n const numRuns = options.numRuns ?? 25\n\n describe(`SearchAdapter contract: ${name}`, () => {\n it(\n 'index returns count of indexed documents',\n async () => {\n const adapter = await build()\n const result = await adapter.index([\n { id: 'doc-1', type: 'product', fields: { name: 'Widget' } },\n { id: 'doc-2', type: 'product', fields: { name: 'Gadget' } },\n ])\n expect(result.indexed).toBe(2)\n },\n CASE_MS,\n )\n\n it(\n 'search returns indexed documents',\n async () => {\n const adapter = await build()\n await adapter.index([\n { id: 'search-doc-1', type: 'product', fields: { name: 'Searchable Item' } },\n ])\n const result = await adapter.search('Searchable')\n expect(result.items.length).toBeGreaterThanOrEqual(1)\n expect(result.total).toBeGreaterThanOrEqual(1)\n },\n CASE_MS,\n )\n\n it(\n 'remove deletes documents from index',\n async () => {\n const adapter = await build()\n const tag = `remove-${randomUUID()}`\n await adapter.index([{ id: tag, type: 'product', fields: { name: 'To Remove' } }])\n await adapter.remove([tag])\n const result = await adapter.search('To Remove')\n expect(result.items.find((i) => i.id === tag)).toBeUndefined()\n },\n CASE_MS,\n )\n\n it(\n 'facet returns values for a field',\n async () => {\n const adapter = await build()\n await adapter.index([\n { id: 'facet-doc-1', type: 'product', fields: { category: 'shirts' } },\n { id: 'facet-doc-2', type: 'product', fields: { category: 'trousers' } },\n { id: 'facet-doc-3', type: 'product', fields: { category: 'shirts' } },\n ])\n const facet = await adapter.facet('category')\n expect(typeof facet.field).toBe('string')\n expect(typeof facet.label).toBe('string')\n expect(Array.isArray(facet.values)).toBe(true)\n if (facet.values.length > 0) {\n expect(typeof facet.values[0]!.value).toBe('string')\n }\n },\n CASE_MS,\n )\n\n healthAndDowntime(build, options.unreachable, 'search()', (adapter) =>\n adapter.search('contract', { limit: 1 }),\n )\n\n describe('pages, ranking, facets and hostile input', () => {\n // Kills: a cursor that is ignored (page 1 again, or no next page), a total that counts the page or a capped\n // prefix, a filter that is skipped or only applied with a query, a removed doc that lingers, a re-index that\n // appends instead of replacing, and a tokeniser other than the oracle's (a price or category id searched,\n // punctuation kept, a prefix not matched).\n it(\n 'over generated catalogues and page sizes, the cursor walk yields each oracle match exactly once, total is exact on every page, nextCursor is null exactly on the last page and no page exceeds limit, with and without a category filter, after removals and re-indexes',\n async () => {\n const adapter = await build()\n await fc.assert(\n fc.asyncProperty(\n // The page size first: fast-check shrinks the arguments in order, so a failing walk shrinks its limit\n // before its catalogue, and the catalogue's products are shrunk once there are few of them.\n fc.integer({ min: 1, max: 40 }),\n fc.array(fc.record({ first: genProduct, second: fc.option(genProduct) }), {\n maxLength: 300,\n size: 'large',\n }),\n fc.array(word, { maxLength: 2 }),\n fc.integer({ min: 0, max: CATEGORIES - 1 }),\n fc.func(fc.boolean()),\n async (limit, catalogue, queryWords, filterCategory, removeIt) => {\n const token = runToken()\n const cats = runCategories(token)\n const first = catalogue.map((c, i) => materialise(token, c.first, i, cats))\n try {\n const indexed = await adapter.index(first.map(toSearchDocument))\n expect(indexed.indexed).toBe(first.length)\n // Re-indexes: the second version replaces the first.\n const current = catalogue.map((c, i) =>\n c.second === null ? first[i]! : materialise(token, c.second, i, cats),\n )\n const rewritten = current.filter((_, i) => catalogue[i]!.second !== null)\n if (rewritten.length > 0) await adapter.index(rewritten.map(toSearchDocument))\n // Removals.\n const removed = current.filter((p) => removeIt(p.id))\n if (removed.length > 0) await adapter.remove(removed.map((p) => p.id))\n const gone = new Set(removed.map((p) => p.id))\n const live = current.filter((p) => !gone.has(p.id))\n\n const query = [token, ...queryWords].join(' ')\n const matches = live.filter((p) => matchesQuery(p, query))\n const all = await walk(adapter, query, limit, matches.length)\n expectExactWalk(\n all,\n matches.map((p) => p.id),\n limit,\n `\"${query}\" limit ${limit}`,\n )\n\n const category = cats[filterCategory]!\n const inCategory = matches.filter((p) => p.categoryIds.includes(category))\n const filtered = await walk(adapter, query, limit, inCategory.length, {\n categoryIds: category,\n })\n expectExactWalk(\n filtered,\n inCategory.map((p) => p.id),\n limit,\n `\"${query}\" in ${category} limit ${limit}`,\n )\n\n // No removed id on any page of either walk.\n const shown = [...idsOf(all), ...idsOf(filtered)]\n expect(\n shown.filter((id) => gone.has(id)),\n 'a removed id came back',\n ).toEqual([])\n } finally {\n await adapter.remove(first.map((p) => p.id))\n }\n },\n ),\n { numRuns },\n )\n },\n SLOW,\n )\n\n if (options.ranking) {\n // Kills: an order by engine score alone (ts_rank_cd lets a description repeating the term outrank a name\n // hit), by insertion order, or one that differs between two walks of the same query.\n it(\n 'for any query, every all-terms-in-name match ranks above every other match and every name/SKU/variant-name match above every description-only match, however often the description repeats the term, and the same query walks in the same order twice',\n async () => {\n const adapter = await build()\n const placed = fc.record({\n base: genProduct,\n inName: fc.boolean(),\n inSku: fc.boolean(),\n inVariant: fc.boolean(),\n descriptionRepeats: fc.integer({ min: 0, max: 10 }),\n })\n await fc.assert(\n fc.asyncProperty(\n fc.array(placed, { minLength: 1, maxLength: 60 }),\n word,\n fc.option(word),\n fc.integer({ min: 1, max: 30 }),\n fc.integer({ min: 1, max: 30 }),\n async (catalogue, term, second, limitA, limitB) => {\n const token = runToken()\n const cats = runCategories(token)\n const products = catalogue.map((c, i): ContractProduct => {\n const p = materialise(token, c.base, i, cats)\n const variants =\n p.variants.length > 0\n ? [...p.variants]\n : [{ sku: 'zz', name: '', priceMinor: 1 }]\n if (c.inSku) variants[0] = { ...variants[0]!, sku: `${term}9` }\n if (c.inVariant)\n variants[0] = { ...variants[0]!, name: `${variants[0]!.name} ${term}` }\n return {\n ...p,\n name: c.inName ? `${p.name} ${term}` : p.name,\n description: `${p.description}${` ${term}`.repeat(c.descriptionRepeats)}`,\n variants,\n }\n })\n try {\n await adapter.index(products.map(toSearchDocument))\n const query = [token, term, ...(second === null ? [] : [second])].join(' ')\n const byId = new Map(products.map((p) => [p.id, p]))\n const matches = products.filter((p) => matchesQuery(p, query))\n\n const order = idsOf(await walk(adapter, query, limitA, matches.length))\n expect([...order].sort(), 'the walk is not the match set').toEqual(\n matches.map((p) => p.id).sort(),\n )\n const tiers = order.map((id) => tierOf(byId.get(id)!, query))\n for (let i = 1; i < tiers.length; i++) {\n expect(\n tiers[i - 1],\n `\"${query}\": ${order[i - 1]} (tier ${tiers[i - 1]}) ranked above ${order[i]} (tier ${tiers[i]})`,\n ).toBeGreaterThanOrEqual(tiers[i]!)\n }\n\n const again = idsOf(await walk(adapter, query, limitB, matches.length))\n expect(again, `\"${query}\" walked at limit ${limitA}, then ${limitB}`).toEqual(\n order,\n )\n } finally {\n await adapter.remove(products.map((p) => p.id))\n }\n },\n ),\n { numRuns },\n )\n },\n SLOW,\n )\n }\n\n if (options.facets) {\n // Kills: a facet that ignores the query or the filters, counts a capped prefix, or lists a category with\n // no match.\n it(\n \"facet('categoryIds', {query, filters}) counts, per category id, exactly the oracle's matches in that category under the filters, lists no category without one, and orders by count descending, then value\",\n async () => {\n const adapter = await build()\n expect(adapter.capabilities()).toContain('facet')\n await fc.assert(\n fc.asyncProperty(\n fc.array(genProduct, { maxLength: 150, size: 'medium' }),\n fc.array(word, { maxLength: 2 }),\n fc.option(fc.integer({ min: 0, max: CATEGORIES - 1 })),\n async (catalogue, queryWords, filterCategory) => {\n const token = runToken()\n const cats = runCategories(token)\n const products = catalogue.map((g, i) => materialise(token, g, i, cats))\n try {\n await adapter.index(products.map(toSearchDocument))\n const query = [token, ...queryWords].join(' ')\n const filter = filterCategory === null ? undefined : cats[filterCategory]!\n const matches = products.filter(\n (p) =>\n matchesQuery(p, query) &&\n (filter === undefined || p.categoryIds.includes(filter)),\n )\n const expected = new Map<string, number>()\n for (const p of matches)\n for (const c of p.categoryIds) expected.set(c, (expected.get(c) ?? 0) + 1)\n\n const facet = await adapter.facet('categoryIds', {\n query,\n ...(filter !== undefined && { filters: { categoryIds: filter } }),\n })\n const label = `facet for \"${query}\"${filter === undefined ? '' : ` in ${filter}`}`\n expect(\n Object.fromEntries(facet.values.map((v) => [v.value, v.count])),\n label,\n ).toEqual(Object.fromEntries(expected))\n const ordered = [...expected.entries()]\n .sort((a, b) => b[1] - a[1] || (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0))\n .map(([value]) => value)\n expect(\n facet.values.map((v) => v.value),\n `${label}: order`,\n ).toEqual(ordered)\n } finally {\n await adapter.remove(products.map((p) => p.id))\n }\n },\n ),\n { numRuns },\n )\n },\n SLOW,\n )\n }\n\n // Kills: raw input reaching FTS MATCH or to_tsquery (a syntax error, or an operator that changes the match),\n // a tokeniser on either side other than the oracle's (case, punctuation, non-ASCII), an empty query that returns\n // everything, and a malformed cursor read as page 1 or a stale one that errors.\n describe('hostile input', () => {\n const operator = fc.constantFrom(\n '\"',\n '*',\n 'NEAR',\n 'NEAR(',\n ':',\n '&',\n '|',\n '!',\n '(',\n ')',\n '-',\n '^',\n 'AND',\n 'OR',\n 'NOT',\n \"'\",\n '\\\\',\n '{',\n '}',\n '<->',\n ':*',\n '+',\n '%',\n '_',\n ';',\n '\\u0000',\n )\n const fragment = fc.oneof(\n fc.string({ unit: 'binary', maxLength: 6 }),\n operator,\n word,\n word.map((w) => w.toUpperCase()),\n )\n // Fragments glued together, so an operator sits against a word as it would in a typed query.\n const hostile = fc.array(fragment, { maxLength: 6 }).map((fs) => fs.join(''))\n const longTerm = 'a'.repeat(2047)\n const plain: GenProduct = { name: 'a b', description: 'c', variants: [], categories: [0] }\n\n it(\n \"any string after the run token, full unicode and FTS operators included, never throws and returns exactly the oracle's matches for the query's normalised terms\",\n async () => {\n const adapter = await build()\n await fc.assert(\n fc.asyncProperty(\n fc.array(genProduct, { maxLength: 40 }),\n hostile,\n async (catalogue, raw) => {\n const token = runToken()\n const cats = runCategories(token)\n const products = catalogue.map((g, i) => materialise(token, g, i, cats))\n try {\n await adapter.index(products.map(toSearchDocument))\n const query = `${token} ${raw}`\n const expected = products.filter((p) => matchesQuery(p, query)).map((p) => p.id)\n const result = await adapter.search(query, { limit: 100 })\n expect(result.items.map((d) => d.id).sort(), JSON.stringify(query)).toEqual(\n expected.sort(),\n )\n expect(result.total, JSON.stringify(query)).toBe(expected.length)\n } finally {\n await adapter.remove(products.map((p) => p.id))\n }\n },\n ),\n {\n numRuns: numRuns * 2,\n // A term one byte past Postgres's longest lexeme (2046 bytes; terms are ASCII, so bytes are\n // characters): in the query, in a description, and in both.\n examples: [\n [[plain], longTerm],\n [[{ ...plain, description: `c ${longTerm}` }], ''],\n [[{ ...plain, description: longTerm }], longTerm],\n ],\n },\n )\n },\n SLOW,\n )\n\n it(\n 'input with no terms returns no items, total 0 and no next page, over an index that holds products',\n async () => {\n const adapter = await build()\n const token = runToken()\n const products: ContractProduct[] = Array.from({ length: 5 }, (_, i) => ({\n id: `${token}-${i}`,\n name: `${token} a b`,\n description: 'c d',\n variants: [{ sku: 'a1', name: 'b', priceMinor: 100 }],\n categoryIds: [],\n }))\n await adapter.index(products.map(toSearchDocument))\n try {\n const termless = fc\n .array(\n fc.oneof(\n operator,\n fc.string({ unit: 'binary', maxLength: 4 }),\n fc.constantFrom(' ', '\\t', '\\n'),\n ),\n { maxLength: 6 },\n )\n .map((fs) => fs.join(''))\n .filter((s) => searchTerms(s).length === 0)\n await fc.assert(\n fc.asyncProperty(termless, async (raw) => {\n const result = await adapter.search(raw, { limit: 20 })\n expect(result.items.length, JSON.stringify(raw)).toBe(0)\n expect(result.total, JSON.stringify(raw)).toBe(0)\n expect(result.nextCursor, JSON.stringify(raw)).toBeNull()\n }),\n {\n numRuns: numRuns * 2,\n examples: [[''], [' '], [' '], ['*'], ['\"'], ['-'], ['é']],\n },\n )\n } finally {\n await adapter.remove(products.map((p) => p.id))\n }\n },\n SLOW,\n )\n\n it(\n 'a malformed cursor (undecodable, negative, non-integer) rejects, and a cursor at or past total, as after a removal between two pages, is an empty page with nextCursor null',\n async () => {\n const adapter = await build()\n const token = runToken()\n const products: ContractProduct[] = Array.from({ length: 6 }, (_, i) => ({\n id: `${token}-${i}`,\n name: `${token} cursor ${i}`,\n description: '',\n variants: [],\n categoryIds: [],\n }))\n await adapter.index(products.map(toSearchDocument))\n try {\n // A page-2 cursor taken while all six match, used after four are removed: its offset is past total.\n const first = await adapter.search(token, { limit: 4 })\n expect(first.total).toBe(products.length)\n expect(first.nextCursor, 'six matches at limit 4 have a second page').not.toBeNull()\n\n for (const cursor of ['not a cursor', '%%%', '!!']) {\n await expect(\n adapter.search(token, { limit: 2, cursor }),\n `cursor ${cursor}`,\n ).rejects.toThrow()\n }\n if (options.cursorAt !== undefined) {\n for (const offset of [-1, -20, 1.5, 0.25]) {\n await expect(\n adapter.search(token, { limit: 2, cursor: options.cursorAt(offset) }),\n `cursor at offset ${offset}`,\n ).rejects.toThrow()\n }\n }\n\n const kept = products.slice(0, 2)\n await adapter.remove(products.slice(2).map((p) => p.id))\n const stale = await adapter.search(token, { limit: 4, cursor: first.nextCursor! })\n expect(stale.items.length).toBe(0)\n expect(stale.nextCursor).toBeNull()\n expect(stale.total).toBe(kept.length)\n\n if (options.cursorAt !== undefined) {\n for (const offset of [kept.length, kept.length + 7]) {\n const past = await adapter.search(token, {\n limit: 4,\n cursor: options.cursorAt(offset),\n })\n expect(past.items.length, `offset ${offset}`).toBe(0)\n expect(past.nextCursor, `offset ${offset}`).toBeNull()\n expect(past.total, `offset ${offset}`).toBe(kept.length)\n }\n }\n } finally {\n await adapter.remove(products.map((p) => p.id))\n }\n },\n SLOW,\n )\n })\n })\n })\n}\n","import type { SearchDocument } from '@nymbalhq/types'\n\n// The search suite's oracle: one tokeniser, for query, index and expectation. A term is a maximal run of ASCII letters\n// and digits after lowercasing; everything else separates terms. A product matches a query iff the query has a term\n// and every query term is a prefix of one of the product's terms in name, SKU, variant name or description. Nothing\n// else it carries (slug, status, prices, category ids) is searched.\n\n/** The terms of a text, as search sees them. */\nexport function searchTerms(text: string): string[] {\n return text.toLowerCase().match(/[a-z0-9]+/g) ?? []\n}\n\n/** A product as the search handler indexes it, before it is a SearchDocument. */\nexport interface ContractProduct {\n id: string\n name: string\n description: string\n variants: Array<{ sku: string; name: string; priceMinor: number }>\n categoryIds: string[]\n}\n\n/** The document the search handler indexes for the product. */\nexport function toSearchDocument(p: ContractProduct): SearchDocument {\n return {\n id: p.id,\n type: 'product',\n fields: {\n slug: p.id,\n name: p.name,\n description: p.description,\n status: 'active',\n categoryIds: p.categoryIds,\n variants: p.variants.map((v) => ({ sku: v.sku, name: v.name, priceMinor: v.priceMinor })),\n },\n }\n}\n\nfunction prefixed(queryTerms: string[], docTerms: string[]): boolean {\n return queryTerms.every((q) => docTerms.some((d) => d.startsWith(q)))\n}\n\nfunction strongTerms(p: ContractProduct): string[] {\n return [\n ...searchTerms(p.name),\n ...p.variants.flatMap((v) => [...searchTerms(v.sku), ...searchTerms(v.name)]),\n ]\n}\n\n/** Does the product match the query. */\nexport function matchesQuery(p: ContractProduct, query: string): boolean {\n const q = searchTerms(query)\n return q.length > 0 && prefixed(q, [...strongTerms(p), ...searchTerms(p.description)])\n}\n\n/** 2: every term matches in the name; 1: every term matches in name, SKU or variant name; 0: otherwise. */\nexport function tierOf(p: ContractProduct, query: string): number {\n const q = searchTerms(query)\n if (prefixed(q, searchTerms(p.name))) return 2\n if (prefixed(q, strongTerms(p))) return 1\n return 0\n}\n","import { describe, expect, it } from 'vitest'\nimport type { ShippingAdapter } from '@nymbalhq/types'\nimport { CASE_MS, healthAndDowntime, type Build, type ContractOptions } from './common.js'\n\nconst REQUEST = {\n fromPostalCode: 'SW1A 1AA',\n toPostalCode: 'EC1A 1BB',\n toCountry: 'GB',\n weightGrams: 500,\n currency: 'GBP',\n}\n\nexport function runShippingContract(\n name: string,\n build: Build<ShippingAdapter>,\n options: ContractOptions<ShippingAdapter> = {},\n): void {\n describe(`ShippingAdapter contract: ${name}`, () => {\n it(\n 'rate returns an array of shipping options',\n async () => {\n const adapter = await build()\n const rates = await adapter.rate(REQUEST)\n expect(Array.isArray(rates)).toBe(true)\n if (rates.length > 0) {\n const rate = rates[0]!\n expect(typeof rate.amountMinor).toBe('number')\n expect(typeof rate.carrier).toBe('string')\n expect(typeof rate.estimatedDays).toBe('number')\n }\n },\n CASE_MS,\n )\n\n healthAndDowntime(build, options.unreachable, 'rate()', (adapter) => adapter.rate(REQUEST))\n })\n}\n","import { describe, expect, it } from 'vitest'\nimport type { TaxAdapter } from '@nymbalhq/types'\nimport { CASE_MS, healthAndDowntime, type Build, type ContractOptions } from './common.js'\n\nconst REQUEST = {\n currency: 'GBP',\n shippingCountry: 'GB',\n shippingRegion: 'England',\n lines: [{ amountMinor: 1000, qty: 2 }],\n}\n\nexport function runTaxContract(\n name: string,\n build: Build<TaxAdapter>,\n options: ContractOptions<TaxAdapter> = {},\n): void {\n describe(`TaxAdapter contract: ${name}`, () => {\n it(\n 'calculate returns totalTaxMinor >= 0',\n async () => {\n const adapter = await build()\n const result = await adapter.calculate(REQUEST)\n expect(typeof result.totalTaxMinor).toBe('number')\n expect(result.totalTaxMinor).toBeGreaterThanOrEqual(0)\n expect(result.ratePerLine).toHaveLength(1)\n expect(typeof result.ratePerLine[0]!.taxMinor).toBe('number')\n },\n CASE_MS,\n )\n\n it(\n 'calculate with zero amount returns zero tax',\n async () => {\n const adapter = await build()\n const result = await adapter.calculate({\n ...REQUEST,\n lines: [{ amountMinor: 0, qty: 1 }],\n })\n expect(result.totalTaxMinor).toBe(0)\n },\n CASE_MS,\n )\n\n healthAndDowntime(build, options.unreachable, 'calculate()', (adapter) =>\n adapter.calculate(REQUEST),\n )\n })\n}\n","import type { AdapterContext, Logger, Slot } from '@nymbalhq/types'\n\nconst silent: Logger = {\n trace: () => undefined,\n debug: () => undefined,\n info: () => undefined,\n warn: () => undefined,\n error: () => undefined,\n child: () => silent,\n}\n\n/**\n * The AdapterContext the kernel hands a package's `createAdapter`, with a silent logger: `config` is a commerce slot's\n * `config` record or a primitive's connection block.\n */\nexport function adapterContext(\n slot: Slot,\n config: Record<string, unknown>,\n env: NodeJS.ProcessEnv = {},\n): AdapterContext {\n return { slot, config, logger: silent, env }\n}\n","import { describe, expect, it } from 'vitest'\nimport type { SecurityAdapter, SecurityConfigLike } from '@nymbalhq/types'\nimport { CASE_MS, healthAndDowntime, type Build, type ContractOptions } from './common.js'\n\nconst testConfig: SecurityConfigLike = {\n rateLimit: {\n api: { requests: 100, window: '1m', action: 'block' },\n },\n csrf: false,\n headers: {\n hsts: true,\n contentSecurityPolicy: \"default-src 'self'\",\n referrerPolicy: 'strict-origin-when-cross-origin',\n xFrameOptions: 'DENY',\n },\n}\n\nexport function runSecurityContract(\n name: string,\n build: Build<SecurityAdapter>,\n options: ContractOptions<SecurityAdapter> = {},\n): void {\n describe(`SecurityAdapter contract: ${name}`, () => {\n it(\n 'validate accepts a valid config',\n async () => {\n const adapter = await build()\n const result = await adapter.validate(testConfig)\n expect(typeof result.valid).toBe('boolean')\n expect(Array.isArray(result.errors)).toBe(true)\n },\n CASE_MS,\n )\n\n it(\n 'validate of empty config reports errors',\n async () => {\n const adapter = await build()\n const result = await adapter.validate({} as SecurityConfigLike)\n if (!result.valid) {\n expect(result.errors.length).toBeGreaterThan(0)\n }\n },\n CASE_MS,\n )\n\n healthAndDowntime(build, options.unreachable, 'validate()', async (adapter) =>\n adapter.validate(testConfig),\n )\n })\n}\n","import { describe, it, expect } from 'vitest'\nimport type { NymbalEvent } from '@nymbalhq/types'\n\nexport interface ProjectionContractOptions {\n /**\n * Build a fresh projection handler context. Returns:\n * - `handle(event)` — processes the event through the idempotency-guarded handler\n * - `applicationCount()` — returns how many times the underlying handler actually ran\n */\n build: () => Promise<{\n handle: (event: NymbalEvent) => Promise<void>\n applicationCount: () => Promise<number>\n }>\n}\n\nfunction makeEvent(id: string): NymbalEvent {\n return {\n id,\n type: 'test.event.v1',\n timestamp: new Date().toISOString(),\n source: 'test',\n correlationId: 'corr-1',\n payload: { id },\n metadata: { storeId: 'test', environment: 'development', version: '0.0.0' },\n }\n}\n\nexport function runProjectionContract(opts: ProjectionContractOptions): void {\n describe('Projection idempotency contract', () => {\n it('processing the same event twice applies the mutation only once', async () => {\n const ctx = await opts.build()\n const event = makeEvent('dedup-evt-001')\n await ctx.handle(event)\n await ctx.handle(event)\n expect(await ctx.applicationCount()).toBe(1)\n })\n\n it('distinct events each apply their mutation', async () => {\n const ctx = await opts.build()\n await ctx.handle(makeEvent('distinct-evt-001'))\n await ctx.handle(makeEvent('distinct-evt-002'))\n expect(await ctx.applicationCount()).toBe(2)\n })\n\n it('after reprocessing a batch the count equals unique event count', async () => {\n const ctx = await opts.build()\n const events = [makeEvent('batch-001'), makeEvent('batch-002'), makeEvent('batch-003')]\n for (const e of events) await ctx.handle(e)\n for (const e of events) await ctx.handle(e)\n expect(await ctx.applicationCount()).toBe(3)\n })\n })\n}\n","import type { Slot } from '@nymbalhq/types'\nimport { runAiContract } from './ai.js'\nimport { runAnalyticsContract } from './analytics.js'\nimport type { Build } from './common.js'\nimport { runDocumentStoreContract } from './document-store.js'\nimport { runEmailContract } from './email.js'\nimport { runEventBusContract } from './event-bus.js'\nimport type { CONTRACT_KINDS } from './kinds.js'\nimport { runMediaStorageContract, type MediaStorageContractOptions } from './media-storage.js'\nimport { runPaymentsContract } from './payments.js'\nimport { runReviewsContract } from './reviews.js'\nimport { runSearchContract } from './search.js'\nimport { runShippingContract } from './shipping.js'\nimport { runTaxContract } from './tax.js'\n\nexport { adapterContext } from './adapter-context.js'\nexport { BOUND_MS, type Build, type ContractOptions } from './common.js'\nexport { CONTRACT_KINDS } from './kinds.js'\nexport { runDocumentStoreContract, type DocumentStoreContractOptions } from './document-store.js'\nexport { runEventBusContract, type EventBusContractOptions } from './event-bus.js'\nexport { runMediaStorageContract, type MediaStorageContractOptions } from './media-storage.js'\nexport { runPaymentsContract, type PaymentsContractOptions } from './payments.js'\nexport { runEmailContract } from './email.js'\nexport { runReviewsContract } from './reviews.js'\nexport { runSearchContract, type SearchContractOptions } from './search.js'\nexport { matchesQuery, searchTerms, toSearchDocument, type ContractProduct } from './search-oracle.js'\nexport { runAnalyticsContract } from './analytics.js'\nexport { runShippingContract } from './shipping.js'\nexport { runTaxContract } from './tax.js'\nexport { runAiContract } from './ai.js'\nexport { runSecurityContract } from './security.js'\nexport { runProjectionContract } from './projection.js'\nexport type { ProjectionContractOptions } from './projection.js'\n\n/** What a suite certifies: a commerce slot or an infrastructure primitive. */\nexport type ContractKind = Slot\n\n/** A kind's suite, as `nymbal test:contracts` calls it: `build` makes a fresh adapter for each case. */\nexport type ContractSuite = (\n name: string,\n build: Build<unknown>,\n options?: Record<string, unknown>,\n) => void\n\n/** A URL's bytes over HTTP: how a media storage's public URL is read back when the caller names no `fetchUrl`. */\nasync function fetchOverHttp(url: string): Promise<Uint8Array> {\n const response = await fetch(url)\n if (!response.ok) throw new Error(`GET ${url} answered ${response.status}`)\n return new Uint8Array(await response.arrayBuffer())\n}\n\nconst suites = {\n payments: runPaymentsContract as ContractSuite,\n email: runEmailContract as ContractSuite,\n reviews: runReviewsContract as ContractSuite,\n search: runSearchContract as ContractSuite,\n analytics: runAnalyticsContract as ContractSuite,\n shipping: runShippingContract as ContractSuite,\n tax: runTaxContract as ContractSuite,\n ai: runAiContract as ContractSuite,\n documentStore: runDocumentStoreContract as ContractSuite,\n eventBus: runEventBusContract as ContractSuite,\n media: (name, build, options = {}) =>\n runMediaStorageContract(name, build as Parameters<typeof runMediaStorageContract>[1], {\n fetchUrl: fetchOverHttp,\n ...options,\n } as MediaStorageContractOptions),\n} satisfies Record<(typeof CONTRACT_KINDS)[number], ContractSuite>\n\n/** Each kind's suite, one for every kind in CONTRACT_KINDS. Each is typed here, at the CLI's boundary. */\nexport const contractSuites: Partial<Record<ContractKind, ContractSuite>> = suites\n"],"mappings":";;;;;AAAA,SAAS,YAAAA,WAAU,UAAAC,SAAQ,MAAAC,WAAU;;;ACArC,SAAS,UAAU,QAAQ,UAAU;AAI9B,IAAM,WAAW;AAGjB,IAAM,UAAU;AAyBvB,eAAsB,OAAU,MAA4B,KAAK,UAA+B;AAC9F,QAAM,UAAU,KAAK,IAAI;AACzB,MAAI;AACJ,QAAM,OAAO,IAAI,QAA2B,CAAC,YAAY;AACvD,YAAQ,WAAW,MAAM,QAAQ,EAAE,OAAO,OAAO,CAAC,GAAG,EAAE;AAAA,EACzD,CAAC;AACD,MAAI;AACF,UAAM,UAAU,MAAM,QAAQ,KAAK;AAAA,MACjC,QAAQ,QAAQ,EACb,KAAK,IAAI,EACT;AAAA,QACC,CAAC,WAAW,EAAE,OAAO,YAAqB,MAAM;AAAA,QAChD,CAAC,WAAoB,EAAE,OAAO,YAAqB,MAAM;AAAA,MAC3D;AAAA,MACF;AAAA,IACF,CAAC;AACD,WAAO,EAAE,GAAG,SAAS,IAAI,KAAK,IAAI,IAAI,QAAQ;AAAA,EAChD,UAAE;AACA,iBAAa,KAAK;AAAA,EACpB;AACF;AAGA,eAAsB,QAAQ,QAAgC;AAC5D,QAAM,QAAS,QAAuC;AACtD,MAAI,OAAO,UAAU,WAAY;AACjC,MAAI;AACJ,QAAM,QAAQ,KAAK;AAAA,IACjB,QAAQ,QAAQ,EACb,KAAK,MAAO,MAAwB,KAAK,MAAM,CAAC,EAChD,MAAM,MAAM,MAAS;AAAA,IACxB,IAAI,QAAc,CAAC,YAAY;AAC7B,cAAQ,WAAW,SAAS,GAAI;AAAA,IAClC,CAAC;AAAA,EACH,CAAC;AACD,eAAa,KAAK;AACpB;AAEA,SAAS,SAAS,QAAmD;AACnE;AAAA,IACE,OAAO,OAAO;AAAA,IACd;AAAA,EACF,EAAE,KAAK,UAAU;AACjB,SAAO,OAAO,MAAM,OAAO,YAAa,CAAC;AAC3C;AAGA,eAAsB,cAAc,QAAkC;AACpE,QAAM,SAAS,MAAM,SAAS,MAAM;AACpC,SAAO,OAAO,OAAO,wCAAwC,QAAQ,KAAK,EAAE,KAAK,UAAU;AAC3F,QAAM,SAAS,OAAO,UAAU,aAAa,OAAO,OAAO,SAAS;AACpE,SAAO,CAAC,WAAW,UAAU,GAAG,0BAA0B,OAAO,MAAM,CAAC,EAAE,EAAE,UAAU,MAAM;AAC9F;AAGA,eAAsB,WAAW,QAAkC;AACjE,QAAM,SAAS,MAAM,SAAS,MAAM;AACpC,SAAO,OAAO,OAAO,wCAAwC,QAAQ,KAAK,EAAE,KAAK,UAAU;AAC3F,SAAO,OAAO,UAAU,aAAa,OAAO,OAAO,SAAS,MAAS,EAAE,KAAK,MAAM;AACpF;AAGA,eAAsB,cAAc,MAA6C;AAC/E,QAAM,UAAU,MAAM,OAAO,IAAI;AACjC;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ,UAAU,SAAS,uBAAuB,QAAQ,QAAQ;AAAA,EACpE,EAAE,KAAK,UAAU;AACnB;AAGA,eAAsB,MAAY,OAAiB,MAA8C;AAC/F,QAAM,UAAU,MAAM,MAAM;AAC5B,MAAI;AACF,WAAO,MAAM,KAAK,OAAO;AAAA,EAC3B,UAAE;AACA,UAAM,QAAQ,OAAO;AAAA,EACvB;AACF;AAMO,SAAS,kBACd,OACA,aACA,OACA,WACM;AACN;AAAA,IACE;AAAA,IACA,MAAM,MAAM,OAAO,CAAC,YAAY,cAAc,OAAoB,CAAC;AAAA,IACnE;AAAA,EACF;AACA,MAAI,gBAAgB,OAAW;AAC/B,WAAS,0BAA0B,MAAM;AACvC;AAAA,MACE;AAAA,MACA,MAAM,MAAM,aAAa,CAAC,YAAY,WAAW,OAAoB,CAAC;AAAA,MACtE;AAAA,IACF;AACA;AAAA,MACE,SAAS,KAAK;AAAA,MACd,MAAM,MAAM,aAAa,CAAC,YAAY,cAAc,MAAM,UAAU,OAAO,CAAC,CAAC;AAAA,MAC7E;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;ADxIO,SAAS,cACd,MACA,OACA,UAAsC,CAAC,GACjC;AACN,EAAAC,UAAS,uBAAuB,IAAI,IAAI,MAAM;AAC5C,IAAAC;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,UAAU,MAAM,MAAM;AAC5B,cAAM,aAAa,MAAM,QAAQ,MAAM,CAAC,eAAe,WAAW,CAAC;AACnE,QAAAC,QAAO,MAAM,QAAQ,UAAU,CAAC,EAAE,KAAK,IAAI;AAC3C,QAAAA,QAAO,UAAU,EAAE,aAAa,CAAC;AACjC,QAAAA,QAAO,MAAM,QAAQ,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI;AAC9C,QAAAA,SAAQ,WAAW,CAAC,KAAK,CAAC,GAAG,MAAM,EAAE,gBAAgB,CAAC;AAAA,MACxD;AAAA,MACA;AAAA,IACF;AAEA,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,UAAU,MAAM,MAAM;AAC5B,cAAM,SAAS,MAAM,QAAQ,SAAS,yBAAyB,EAAE,WAAW,GAAG,CAAC;AAChF,QAAAC,QAAO,OAAO,MAAM,EAAE,KAAK,QAAQ;AACnC,QAAAA,QAAO,OAAO,MAAM,EAAE,gBAAgB,CAAC;AAAA,MACzC;AAAA,MACA;AAAA,IACF;AAEA;AAAA,MAAkB;AAAA,MAAO,QAAQ;AAAA,MAAa;AAAA,MAAc,CAAC,YAC3D,QAAQ,SAAS,yBAAyB,EAAE,WAAW,GAAG,CAAC;AAAA,IAC7D;AAAA,EACF,CAAC;AACH;;;AEtCA,SAAS,YAAAC,WAAU,UAAAC,SAAQ,MAAAC,WAAU;AAI9B,SAAS,qBACd,MACA,OACA,UAA6C,CAAC,GACxC;AACN,EAAAC,UAAS,8BAA8B,IAAI,IAAI,MAAM;AACnD,IAAAC;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,UAAU,MAAM,MAAM;AAC5B,cAAMC;AAAA,UACJ,QAAQ,MAAM,kBAAkB,EAAE,WAAW,UAAU,QAAQ,OAAO,CAAC;AAAA,QACzE,EAAE,SAAS,IAAI,QAAQ;AAAA,MACzB;AAAA,MACA;AAAA,IACF;AAEA,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,UAAU,MAAM,MAAM;AAC5B,cAAMC;AAAA,UACJ,QAAQ,SAAS,UAAU,EAAE,OAAO,oBAAoB,MAAM,OAAO,CAAC;AAAA,QACxE,EAAE,SAAS,IAAI,QAAQ;AAAA,MACzB;AAAA,MACA;AAAA,IACF;AAEA;AAAA,MAAkB;AAAA,MAAO,QAAQ;AAAA,MAAa;AAAA,MAAW,CAAC,YACxD,QAAQ,MAAM,kBAAkB,EAAE,WAAW,UAAU,QAAQ,gBAAgB,CAAC;AAAA,IAClF;AAAA,EACF,CAAC;AACH;;;ACpCA,SAAS,YAAAC,WAAU,UAAAC,SAAQ,MAAAC,WAAU;;;ACArC,OAAO,QAAQ;AACf,SAAS,YAAAC,WAAU,UAAAC,SAAQ,MAAAC,WAAU;AACrC;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AAgBP,IAAM,aAAa;AACnB,IAAM,QAAQ;AACd,IAAM,OAAO;AAqBb,IAAM,WAAgC,GAAG;AAAA,EACvC,GAAG,aAAa,KAAK,KAAK,QAAK,KAAK,KAAK,QAAK,KAAK,MAAM,MAAM,KAAK,MAAM,GAAG;AAAA,EAC7E,GAAG,QAAQ,EAAE,KAAK,IAAI,KAAK,GAAG,CAAC;AAAA,EAC/B,GAAG,SAAS,IAAI;AAClB;AAEA,IAAM,WAAW,GAAG,OAAO,UAAU,EAAE,KAAK,QAAW,MAAM,EAAE,CAAC;AAEhE,IAAM,UAAU,CAAC,cACf,GAAG;AAAA,EACD,GAAG,OAAO;AAAA;AAAA,IAER,KAAK,GAAG,eAAe,iBAAiB;AAAA,IACxC,MAAM,GAAG,aAAwB,KAAK,GAAG;AAAA,IACzC,GAAG;AAAA,IACH,GAAG;AAAA,EACL,CAAC;AAAA,EACD,EAAE,WAAW,WAAW,IAAI,UAAU,CAAC,MAAM,EAAE,IAAI;AACrD;AAKF,IAAM,aAAgD,GAAG;AAAA,EACvD,GAAG;AAAA,IACD,GAAG,OAAO;AAAA,MACR,OAAO,GAAG,SAAS,GAAG;AAAA,MACtB,UAAU,GAAG,aAAiC,MAAM,MAAM,IAAI;AAAA,MAC9D,OAAO;AAAA,IACT,CAAC;AAAA,IACD,GAAG,OAAO;AAAA,MACR,OAAO,GAAG,SAAS,GAAG;AAAA,MACtB,UAAU,GAAG,SAAoB,SAAS;AAAA,MAC1C,OAAO,GAAG,MAAM,UAAU,QAAQ;AAAA,IACpC,CAAC;AAAA,EACH;AAAA,EACA,EAAE,KAAK,OAAU;AACnB;AACA,IAAM,aAAa,GAAG,OAAO;AAAA,EAC3B,OAAO,GAAG,aAAa,KAAK,UAAU;AAAA,EACtC,WAAW,GAAG,aAAwB,OAAO,MAAM;AACrD,CAAC;AAED,SAAS,OAAO,GAAmB;AACjC,SAAO;AAAA,IACL,IAAI,EAAE;AAAA,IACN,MAAM,EAAE;AAAA,IACR,GAAI,EAAE,MAAM,UAAa,EAAE,GAAG,EAAE,EAAE;AAAA,IAClC,QAAQ,EAAE,MAAM,SAAY,EAAE,GAAG,EAAE,EAAE,IAAI,CAAC;AAAA,IAC1C,OAAO;AAAA,EACT;AACF;AAEA,SAAS,QAAQ,KAAU,MAAuB;AAChD,MAAI,QAAiB;AACrB,aAAW,QAAQ,KAAK,MAAM,GAAG,GAAG;AAClC,QAAI,UAAU,QAAQ,OAAO,UAAU,SAAU,QAAO;AACxD,YAAS,MAAkC,IAAI;AAAA,EACjD;AACA,SAAO;AACT;AAEA,IAAM,UAAU,CAAC,MAAwB,MAAM,QAAQ,MAAM;AAS7D,SAAS,UAAU,MAAa,GAAoB;AAClD,QAAM,OAAO,KAAK;AAAA,IAChB,CAAC,OACE,EAAE,cAAc,OAAO,EAAE,SAAS,EAAE,eACpC,EAAE,YAAY,UAAa,eAAe,EAAE,GAAG,EAAE,OAAO;AAAA,EAC7D;AACA,QAAM,EAAE,QAAQ,IAAI;AACpB,MAAI,YAAY,OAAW,QAAO,KAAK,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,KAAK;AAC7D,SAAO,KACJ,KAAK,CAAC,GAAG,MAAM;AACd,UAAM,IAAI,QAAQ,GAAG,QAAQ,KAAK;AAClC,UAAM,IAAI,QAAQ,GAAG,QAAQ,KAAK;AAElC,QAAI,QAAQ,CAAC,MAAM,QAAQ,CAAC,EAAG,QAAO,QAAQ,CAAC,IAAI,IAAI;AACvD,QAAI,IAAI,QAAQ,CAAC,IAAI,IAAI,sBAAsB,GAAG,CAAC;AACnD,QAAI,QAAQ,cAAc,OAAQ,KAAI,CAAC;AACvC,QAAI,MAAM,EAAG,QAAO;AACpB,WAAO,EAAE,KAAK,EAAE,KAAK,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI;AAAA,EAC9C,CAAC,EACA,IAAI,CAAC,MAAM,EAAE,EAAE;AACpB;AAEA,SAAS,OAAO,GAAU,OAAe,QAA8B;AACrE,SAAO;AAAA,IACL,cAAc,EAAE,OAAO,QAAQ,OAAO,EAAE,UAAU;AAAA,IAClD,GAAI,EAAE,YAAY,UAAa,EAAE,SAAS,EAAE,QAAQ;AAAA,IACpD,GAAI,EAAE,YAAY,UAAa,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,OAAO,OAAgB,EAAE;AAAA,IACnF;AAAA,IACA,GAAI,WAAW,UAAa,EAAE,OAAO;AAAA,EACvC;AACF;AAGA,eAAe,KACb,OACA,GACA,OACA,UACA,SAC6C;AAC7C,QAAM,QAAiB,CAAC;AACxB,MAAI;AACJ,KAAG;AACD,UAAM,OAAO,MAAM,MAAM,MAAW,YAAY,OAAO,GAAG,OAAO,MAAM,CAAC;AACxE,UAAM,KAAK,KAAK,KAAK;AACrB,aAAS,KAAK,cAAc;AAC5B,QAAI,YAAY,OAAW,OAAM,QAAQ,MAAM,MAAM;AAAA,EACvD,SAAS,WAAW,UAAa,MAAM,UAAU;AACjD,SAAO,EAAE,OAAO,OAAO,WAAW,OAAU;AAC9C;AAEA,IAAM,QAAQ,CAAC,SAA0B,KAAK,IAAI,CAAC,MAAM,EAAE,EAAE;AAE7D,SAAS,MAAS,OAAY,MAAqB;AACjD,QAAM,MAAa,CAAC;AACpB,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,KAAM,KAAI,KAAK,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC;AAC9E,SAAO;AACT;AAGA,SAAS,qBAAwB,OAAqB;AACpD,SAAO,MAAM,SAAS,KAAK,MAAM,MAAM,SAAS,CAAC,EAAG,WAAW,IAAI,MAAM,MAAM,GAAG,EAAE,IAAI;AAC1F;AAEA,eAAe,UACb,MACA,WACuD;AACvD,QAAM,QAAQ,MAAM,KAAK;AACzB,QAAM,OAAO,UAAU,IAAI,MAAM;AACjC,aAAW,OAAO,KAAM,OAAM,MAAM,IAAS,YAAY,IAAI,IAAI,GAAG;AAEpE,aAAW,OAAO,KAAK,MAAM,GAAG,CAAC,GAAG;AAClC,UAAM,MAAM,IAAS,OAAO,IAAI,IAAI,EAAE,GAAG,KAAK,OAAO,QAAQ,CAAC;AAAA,EAChE;AACA,SAAO,EAAE,OAAO,KAAK;AACvB;AAEA,eAAe,QAAW,OAA6B,MAAoC;AACzF,MAAI;AACF,WAAO,MAAM,KAAK;AAAA,EACpB,UAAE;AACA,UAAM,MAAM,MAAM;AAAA,EACpB;AACF;AAEA,eAAe,UAAU,SAA6C;AACpE,SAAO,QAAQ;AAAA,IACb,MAAM;AAAA,IACN,CAAC,UAAmB,SAAS,IAAI,MAAM,uBAAuB;AAAA,EAChE;AACF;AAEA,IAAM,cAAc;AAGb,SAAS,wBAAwB,MAAmC,MAA0B;AACnG,EAAAC,UAAS,mCAAmC,MAAM;AAChD,IAAAC;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,GAAG;AAAA,UACP,GAAG;AAAA,YACD,QAAQ,CAAC;AAAA,YACT,GAAG,aAAwB,KAAK,GAAG;AAAA,YACnC;AAAA,YACA;AAAA,YACA,GAAG,QAAQ,EAAE,KAAK,GAAG,KAAK,EAAE,CAAC;AAAA,YAC7B,OAAO,WAAW,WAAW,SAAS,SAAS,UAAU;AACvD,oBAAM,EAAE,OAAO,KAAK,IAAI,MAAM,UAAU,MAAM,SAAS;AACvD,oBAAM,QAAQ,OAAO,YAAY;AAC/B,sBAAM,IAAW,EAAE,WAAW,SAAS,QAAQ;AAC/C,sBAAM,WAAW,UAAU,MAAM,CAAC;AAClC,sBAAM,EAAE,OAAO,MAAM,IAAI,MAAM,KAAK,OAAO,GAAG,OAAO,KAAK,SAAS,CAAC;AAEpE,gBAAAC,QAAO,OAAO,6BAA6B,EAAE,KAAK,IAAI;AACtD,2BAAW,QAAQ,MAAO,CAAAA,QAAO,KAAK,MAAM,EAAE,oBAAoB,KAAK;AACvE,gBAAAA,QAAO,qBAAqB,MAAM,IAAI,KAAK,CAAC,CAAC,EAAE,QAAQ,MAAM,UAAU,KAAK,CAAC;AAC7E,sBAAM,OAAO,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAC/C,2BAAW,QAAQ,MAAM,KAAK,EAAG,CAAAA,QAAO,IAAI,EAAE,QAAQ,KAAK,IAAI,KAAK,EAAE,CAAC;AAAA,cACzE,CAAC;AAAA,YACH;AAAA,UACF;AAAA,UACA,EAAE,SAAS,GAAG;AAAA,QAChB;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAEA,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,GAAG;AAAA,UACP,GAAG;AAAA,YACD,QAAQ,CAAC;AAAA,YACT,GAAG,aAAwB,KAAK,GAAG;AAAA,YACnC;AAAA,YACA,GAAG,QAAQ,EAAE,KAAK,GAAG,KAAK,EAAE,CAAC;AAAA,YAC7B,OAAO,WAAW,WAAW,SAAS,UAAU;AAC9C,oBAAM,EAAE,OAAO,KAAK,IAAI,MAAM,UAAU,MAAM,SAAS;AACvD,oBAAM,QAAQ,OAAO,YAAY;AAC/B,sBAAM,IAAW,EAAE,WAAW,SAAS,SAAS,OAAU;AAC1D,sBAAM,EAAE,OAAO,MAAM,IAAI,MAAM,KAAK,OAAO,GAAG,OAAO,KAAK,SAAS,CAAC;AACpE,sBAAM,SAAS,MAAM,MAAM,KAAK,CAAC;AAEjC,gBAAAC,QAAO,OAAO,6BAA6B,EAAE,KAAK,IAAI;AACtD,gBAAAA,QAAO,OAAO,QAAQ,iBAAiB,OAAO,KAAK,GAAG,CAAC,EAAE,EAAE;AAAA,kBACzD,IAAI,IAAI,MAAM,EAAE;AAAA,gBAClB;AACA,gBAAAA,QAAO,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,EAAE,QAAQ,UAAU,MAAM,CAAC,CAAC;AAAA,cACvD,CAAC;AAAA,YACH;AAAA,UACF;AAAA,UACA,EAAE,SAAS,GAAG;AAAA,QAChB;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAEA,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,GAAG;AAAA,UACP,GAAG;AAAA,YACD,QAAQ,CAAC;AAAA,YACT,GAAG,OAAO,YAAY,EAAE,KAAK,OAAU,CAAC;AAAA,YACxC,GAAG,QAAQ,EAAE,KAAK,GAAG,KAAK,EAAE,CAAC;AAAA,YAC7B,GAAG,IAAI;AAAA,YACP,OAAO,WAAW,SAAS,OAAO,SAAS;AACzC,oBAAM,EAAE,OAAO,KAAK,IAAI,MAAM,UAAU,MAAM,SAAS;AACvD,oBAAM,QAAQ,OAAO,YAAY;AAC/B,sBAAM,IAAW,EAAE,WAAW,KAAK,SAAS,QAAW,QAAQ;AAC/D,sBAAM,WAAW,UAAU,MAAM,CAAC;AAClC,mBAAG,IAAI,SAAS,SAAS,KAAK;AAE9B,sBAAM,UAAU,SAAS,OAAO,SAAS,MAAM;AAC/C,sBAAM,EAAE,OAAO,MAAM,IAAI,MAAM,KAAK,OAAO,GAAG,OAAO,KAAK,SAAS,GAAG,OAAO,MAAM;AACjF,sBAAI,MAAM,EAAG,OAAM,MAAM,OAAO,YAAY,OAAO;AAAA,gBACrD,CAAC;AACD,sBAAM,SAAS,MAAM,MAAM,KAAK,CAAC;AAEjC,gBAAAC,QAAO,OAAO,6BAA6B,EAAE,KAAK,IAAI;AACtD,gBAAAA,QAAO,OAAO,QAAQ,iBAAiB,OAAO,KAAK,GAAG,CAAC,EAAE,EAAE;AAAA,kBACzD,IAAI,IAAI,MAAM,EAAE;AAAA,gBAClB;AACA,gBAAAA,QAAO,OAAO,OAAO,CAAC,OAAO,CAAC,SAAS,SAAS,EAAE,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;AAChE,gBAAAA,QAAO,SAAS,OAAO,CAAC,OAAO,OAAO,WAAW,CAAC,OAAO,SAAS,EAAE,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;AAClF,oBAAI,YAAY,QAAW;AACzB,kBAAAA,QAAO,MAAM,EAAE,QAAQ,SAAS,OAAO,CAAC,OAAO,OAAO,SAAS,EAAE,CAAC,CAAC;AAAA,gBACrE;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF;AAAA,UACA,EAAE,SAAS,GAAG;AAAA,QAChB;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAEA,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,YAAyB,CAAC,MAAM,MAAM,MAAM,MAAM,IAAI,EAAE,IAAI,CAAC,KAAK,OAAO;AAAA,UAC7E;AAAA,UACA,MAAM;AAAA,UACN,GAAG,IAAI;AAAA,UACP,GAAG;AAAA,QACL,EAAE;AACF,cAAM,EAAE,OAAO,KAAK,IAAI,MAAM,UAAU,MAAM,SAAS;AACvD,cAAM,QAAQ,OAAO,YAAY;AAC/B,gBAAM,MAAa;AAAA,YACjB,WAAW;AAAA,YACX,SAAS;AAAA,YACT,SAAS,EAAE,OAAO,KAAK,WAAW,MAAM;AAAA,UAC1C;AACA,gBAAM,QAAQ,MAAM,MAAM,MAAW,YAAY,OAAO,KAAK,CAAC,CAAC;AAC/D,UAAAC,QAAO,MAAM,UAAU,EAAE,IAAI,SAAS;AACtC,gBAAM,SAAS,MAAM;AAErB,gBAAM,iBAAiB,EAAE,GAAG,KAAK,SAAS,EAAE,OAAO,KAAK,WAAW,OAAgB,EAAE;AACrF,gBAAM,aAAa,EAAE,GAAG,KAAK,SAAS,EAAE,OAAO,YAAY,WAAW,MAAe,EAAE;AACvF,UAAAA;AAAA,YACE,MAAM,UAAU,MAAM,MAAM,YAAY,OAAO,gBAAgB,GAAG,MAAM,CAAC,CAAC;AAAA,UAC5E,EAAE,eAAe,KAAK;AACtB,UAAAA;AAAA,YACE,MAAM,UAAU,MAAM,MAAM,YAAY,OAAO,YAAY,GAAG,MAAM,CAAC,CAAC;AAAA,UACxE,EAAE,eAAe,KAAK;AACtB,gBAAM,OAAO,MAAM,MAAM,MAAW,YAAY,OAAO,KAAK,GAAG,MAAM,CAAC;AACtE,UAAAA,QAAO,MAAM,KAAK,KAAK,CAAC,EAAE,QAAQ,UAAU,MAAM,GAAG,EAAE,MAAM,GAAG,CAAC,CAAC;AAAA,QACpE,CAAC;AAAA,MACH;AAAA,MACA;AAAA,IACF;AAEA,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,QAAQ,MAAM,KAAK;AACzB,cAAM,QAAQ,OAAO,YAAY;AAC/B,gBAAM,QAAa,EAAE,IAAI,SAAS,MAAM,KAAK,QAAQ,CAAC,GAAG,OAAO,MAAM;AACtE,gBAAM,OAAY,EAAE,IAAI,QAAQ,MAAM,KAAK,QAAQ,CAAC,GAAG,OAAO,SAAS;AACvE,gBAAM,QAAQ,KAAK,IAAI;AACvB,gBAAM,MAAM,IAAS,YAAY,MAAM,IAAI,OAAO,EAAE,KAAK,YAAY,CAAC;AACtE,gBAAM,MAAM,IAAS,YAAY,KAAK,IAAI,IAAI;AAC9C,UAAAC,QAAO,MAAM,MAAM,IAAS,YAAY,MAAM,EAAE,CAAC,EAAE,QAAQ,KAAK;AAEhE,cAAI,KAAK,UAAU,QAAW;AAC5B,kBAAM,KAAK,MAAM,QAAQ,cAAc,MAAO,CAAC;AAC/C,YAAAA,QAAO,MAAM,MAAM,IAAS,YAAY,MAAM,EAAE,CAAC,EAAE,QAAQ,KAAK;AAChE,kBAAM,KAAK,MAAM,QAAQ,CAAC;AAAA,UAC5B,OAAO;AAEL,kBAAM,WAAW,QAAQ,cAAc,MAAO;AAC9C,mBAAQ,MAAM,MAAM,IAAI,YAAY,MAAM,EAAE,MAAO,QAAQ,KAAK,IAAI,IAAI,UAAU;AAChF,oBAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAAA,YAC5C;AACA,YAAAA,QAAO,KAAK,IAAI,IAAI,OAAO,wBAAwB,EAAE;AAAA,cACnD,cAAc,MAAO;AAAA,YACvB;AAAA,UACF;AAEA,UAAAA,QAAO,MAAM,MAAM,IAAI,YAAY,MAAM,EAAE,CAAC,EAAE,SAAS;AACvD,gBAAM,MAAM,MAAM,MAAM,MAAW,YAAY;AAAA,YAC7C,cAAc,EAAE,OAAO,QAAQ,OAAO,IAAI;AAAA,YAC1C,OAAO;AAAA,UACT,CAAC;AACD,UAAAA,QAAO,MAAM,IAAI,KAAK,CAAC,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC;AAC1C,gBAAM,QAAQ,MAAM,MAAM,SAAc,YAAY,CAAC,MAAM,IAAI,KAAK,EAAE,CAAC;AACvE,UAAAA,QAAO,CAAC,GAAG,MAAM,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC;AAAA,QAC7C,CAAC;AAAA,MACH;AAAA,MACA;AAAA,IACF;AAEA,IAAAD,IAAG,8GAA8G,YAAY;AAC3H,YAAM,QAAQ,MAAM,KAAK;AACzB,YAAM,QAAQ,OAAO,YAAY;AAC/B,cAAM,KAAgC;AAAA,UACpC,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,QAAQ,CAAC;AAAA,UACT,OAAO;AAAA,UACP,SAAS;AAAA,QACX;AACA,cAAM,KAAK,EAAE,GAAG,IAAI,OAAO,MAAM,SAAS,EAAE;AAC5C,cAAM,MAAM,IAAI,YAAY,KAAK,EAAE;AAEnC,cAAM,MAAM,IAAI,YAAY,KAAK,IAAI,EAAE,cAAc,WAAW,gBAAgB,EAAE,CAAC;AACnF,QAAAC,QAAO,MAAM,MAAM,IAAI,YAAY,GAAG,CAAC,EAAE,QAAQ,EAAE;AAEnD,cAAM,QAAQ,MAAM;AAAA,UAClB,MAAM;AAAA,YACJ;AAAA,YACA;AAAA,YACA,EAAE,GAAG,IAAI,OAAO,MAAM,SAAS,EAAE;AAAA,YACjC,EAAE,cAAc,WAAW,gBAAgB,EAAE;AAAA,UAC/C;AAAA,QACF;AACA,QAAAA,QAAQ,OAAqC,IAAI,EAAE,KAAK,0BAA0B;AAClF,QAAAA,QAAO,MAAM,MAAM,IAAI,YAAY,GAAG,CAAC,EAAE,QAAQ,EAAE;AAEnD,cAAM,SAAS,MAAM;AAAA,UACnB,MAAM,IAAI,YAAY,QAAQ,IAAI,EAAE,cAAc,WAAW,gBAAgB,EAAE,CAAC;AAAA,QAClF;AACA,QAAAA,QAAQ,QAAsC,IAAI,EAAE,KAAK,0BAA0B;AACnF,QAAAA,QAAO,MAAM,MAAM,IAAI,YAAY,MAAM,CAAC,EAAE,SAAS;AAAA,MACvD,CAAC;AAAA,IACH,GAAG,OAAO;AAEV,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,GAAG;AAAA,UACP,GAAG,cAAc,QAAQ,CAAC,GAAG,OAAO,cAAc;AAChD,kBAAM,QAAQ,MAAM,KAAK;AACzB,kBAAM,QAAQ,OAAO,YAAY;AAC/B,oBAAM,OAAO,UAAU,IAAI,MAAM;AACjC,oBAAM,MAAM,SAAS,YAAY,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;AACpE,oBAAM,QAAQ,CAAC,GAAG,KAAK,IAAI,CAAC,MAAM,EAAE,EAAE,GAAG,iBAAiB;AAC1D,oBAAM,MAAM,MAAM,MAAM,SAAc,YAAY,KAAK;AAEvD,cAAAC,QAAO,IAAI,IAAI,EAAE,KAAK,KAAK,MAAM;AACjC,yBAAW,OAAO,MAAM;AACtB,gBAAAA,QAAO,IAAI,IAAI,IAAI,EAAE,CAAC,EAAE,QAAQ,GAAG;AACnC,gBAAAA,QAAO,MAAM,MAAM,IAAS,YAAY,IAAI,EAAE,CAAC,EAAE,QAAQ,GAAG;AAAA,cAC9D;AAAA,YACF,CAAC;AAAA,UACH,CAAC;AAAA,UACD,EAAE,SAAS,GAAG;AAAA,QAChB;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAEA,IAAAD,IAAG,sDAAsD,YAAY;AACnE,YAAM,QAAQ,MAAM,KAAK;AACzB,YAAM,QAAQ,OAAO,YAAY;AAC/B,cAAM,IAAS,EAAE,IAAI,QAAQ,MAAM,KAAK,QAAQ,CAAC,GAAG,OAAO,IAAI;AAC/D,cAAM,IAAS,EAAE,GAAG,GAAG,OAAO,IAAI;AAClC,cAAM,QAAa,EAAE,GAAG,GAAG,IAAI,SAAS;AACxC,cAAM,MAAM,IAAI,kBAAkB,EAAE,IAAI,CAAC;AACzC,cAAM,MAAM,IAAI,kBAAkB,MAAM,IAAI,KAAK;AACjD,cAAM,MAAM,IAAI,kBAAkB,EAAE,IAAI,CAAC;AAEzC,QAAAC,QAAO,MAAM,MAAM,IAAI,kBAAkB,MAAM,CAAC,EAAE,QAAQ,CAAC;AAC3D,QAAAA,QAAO,MAAM,MAAM,IAAI,kBAAkB,MAAM,CAAC,EAAE,QAAQ,CAAC;AAC3D,cAAM,MAAM,MAAM,MAAM,MAAW,kBAAkB;AAAA,UACnD,cAAc,EAAE,OAAO,QAAQ,OAAO,IAAI;AAAA,UAC1C,OAAO;AAAA,QACT,CAAC;AACD,QAAAA,QAAO,MAAM,IAAI,KAAK,CAAC,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC;AACvC,cAAM,MAAM,OAAO,kBAAkB,MAAM;AAC3C,QAAAA,QAAO,MAAM,MAAM,IAAI,kBAAkB,MAAM,CAAC,EAAE,QAAQ,CAAC;AAC3D,QAAAA,QAAO,MAAM,MAAM,IAAI,kBAAkB,QAAQ,CAAC,EAAE,QAAQ,KAAK;AAAA,MACnE,CAAC;AAAA,IACH,GAAG,OAAO;AAEV,QAAI,KAAK,cAAc,QAAW;AAChC,YAAM,YAAY,KAAK;AACvB,MAAAD,IAAG,+EAA0E,YAAY;AACvF,cAAM,CAAC,KAAK,GAAG,IAAI,MAAM,UAAU;AACnC,YAAI;AACF,gBAAM,OAAY,EAAE,IAAI,cAAc,MAAM,KAAK,QAAQ,CAAC,GAAG,OAAO,MAAM;AAC1E,gBAAM,SAAc,EAAE,GAAG,MAAM,OAAO,MAAM;AAC5C,gBAAM,IAAI,IAAI,YAAY,KAAK,IAAI,IAAI;AACvC,gBAAM,IAAI,IAAI,YAAY,YAAY,EAAE,GAAG,MAAM,IAAI,WAAW,CAAC;AACjE,gBAAM,IAAI,IAAI,YAAY,OAAO,IAAI,MAAM;AAE3C,UAAAC,QAAO,MAAM,IAAI,IAAI,YAAY,KAAK,EAAE,CAAC,EAAE,QAAQ,IAAI;AACvD,UAAAA,QAAO,MAAM,IAAI,IAAI,YAAY,OAAO,EAAE,CAAC,EAAE,QAAQ,MAAM;AAC3D,UAAAA,QAAO,MAAM,IAAI,IAAI,YAAY,UAAU,CAAC,EAAE,SAAS;AACvD,gBAAM,QAAQ,MAAM,IAAI,MAAW,YAAY;AAAA,YAC7C,cAAc,EAAE,OAAO,QAAQ,OAAO,IAAI;AAAA,YAC1C,OAAO;AAAA,UACT,CAAC;AACD,UAAAA,QAAO,MAAM,MAAM,KAAK,CAAC,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC;AAC9C,gBAAM,QAAQ,MAAM,IAAI,SAAc,YAAY,CAAC,KAAK,IAAI,UAAU,CAAC;AACvE,UAAAA,QAAO,CAAC,GAAG,MAAM,OAAO,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC;AAE5C,gBAAM,IAAI,OAAO,YAAY,KAAK,EAAE;AACpC,UAAAA,QAAO,MAAM,IAAI,IAAI,YAAY,OAAO,EAAE,CAAC,EAAE,QAAQ,MAAM;AAAA,QAC7D,UAAE;AACA,gBAAM,IAAI,MAAM;AAChB,gBAAM,IAAI,MAAM;AAAA,QAClB;AAAA,MACF,GAAG,OAAO;AAAA,IACZ;AAAA,EACF,CAAC;AACH;;;ACzfA,OAAOC,SAAQ;AACf,SAAS,UAAAC,SAAQ,MAAAC,WAAU;AAe3B,IAAMC,QAAO;AACb,IAAM,OAAO,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAEpD,IAAM,YAAY,MAAM,IAAI,QAAc,CAAC,YAAY,aAAa,OAAO,CAAC;AAE5E,gBAAgB,UAAU,MAAa,QAAQ,OAAsC;AACnF,aAAW,OAAO,MAAM;AACtB,QAAI,MAAO,OAAM,UAAU;AAC3B,UAAM,CAAC,IAAI,IAAI,GAAG;AAAA,EACpB;AACF;AAGA,eAAe,SAAS,OAA6B,YAAuC;AAC1F,QAAM,MAAM,MAAM,MAAM,MAAW,YAAY,EAAE,cAAc,EAAE,OAAO,QAAQ,OAAO,IAAI,EAAE,CAAC;AAC9F,SAAO,IAAI,MAAM,IAAI,CAAC,MAAM,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE;AAC9C;AAEA,IAAM,QAAQ,CAAC,SACb,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,MAAO,EAAE,KAAK,EAAE,KAAK,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,CAAE,EAAE,IAAI,CAAC,MAAM,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE;AAEhG,eAAe,OAAO,OAA6B,YAAoB,MAAa;AAClF,aAAW,OAAO,KAAM,OAAM,MAAM,IAAI,YAAY,IAAI,IAAI,GAAG;AACjE;AAEA,IAAM,WAAW,CAAC,MAAyB,MACzC,KAAK,IAAI,CAAC,QAAQ,EAAE,IAAI,MAAM,KAAK,EAAE,EAAE;AAElC,SAAS,0BACd,MACA,MACM;AACN,EAAAC;AAAA,IACE;AAAA,IACA,YAAY;AACV,YAAM,MAAM,MAAM,OAAO,UAAU;AACjC,YAAI,MAAM;AACV,cAAMC,IAAG;AAAA,UACPA,IAAG;AAAA,YACDA,IAAG,YAAYA,IAAG,aAAa,GAAG,IAAI,CAAC;AAAA,YACvCA,IAAG,YAAYA,IAAG,aAAa,GAAG,IAAI,CAAC;AAAA,YACvC,OAAO,SAAS,YAAY;AAC1B,qBAAO;AACP,oBAAM,aAAa,oBAAoB,GAAG;AAC1C,oBAAM,QAAQ,0BAA0B,GAAG;AAC3C,oBAAM,OAAO,OAAO,YAAY,SAAS,SAAS,CAAC,CAAC;AACpD,oBAAM,OAAO,OAAO,OAAO,SAAS,SAAS,CAAC,CAAC;AAE/C,oBAAM,OAAO,SAAS,SAAS,CAAC;AAChC,oBAAM,MAAM,kBAAkB,YAAY,UAAU,IAAI,CAAC;AAEzD,cAAAC,QAAO,MAAM,SAAS,OAAO,UAAU,CAAC,EAAE,QAAQ,MAAM,IAAI,CAAC;AAC7D,yBAAW,OAAO,QAAQ,OAAO,CAAC,MAAM,CAAC,QAAQ,SAAS,CAAC,CAAC,GAAG;AAC7D,gBAAAA,QAAO,MAAM,MAAM,IAAI,YAAY,GAAG,GAAG,aAAa,GAAG,EAAE,EAAE,SAAS;AAAA,cACxE;AACA,cAAAA,QAAO,MAAM,SAAS,OAAO,KAAK,CAAC,EAAE,QAAQ,MAAM,SAAS,SAAS,CAAC,CAAC,CAAC;AAAA,YAC1E;AAAA,UACF;AAAA,UACA,EAAE,SAAS,GAAG;AAAA,QAChB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACAH;AAAA,EACF;AAEA,EAAAC;AAAA,IACE;AAAA,IACA,YAAY;AACV,YAAM,MAAM,MAAM,OAAO,UAAU;AACjC,cAAM,MAAM,SAAS,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG,GAAG,CAAC;AACtD,cAAM,OAAO,SAAS,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG,GAAG,CAAC;AACvD,cAAM,OAAO,OAAO,2BAA2B,GAAG;AAClD,cAAM,UAAU,oBAAI,IAAI,CAAC,KAAK,UAAU,MAAM,GAAG,CAAC,GAAG,KAAK,UAAU,MAAM,IAAI,CAAC,CAAC,CAAC;AAEjF,YAAI,OAAO;AACX,cAAM,OAAmB,CAAC;AAC1B,cAAM,UAAU,YAAY;AAC1B,iBAAO,CAAC,MAAM;AACZ,iBAAK,KAAK,MAAM,SAAS,OAAO,yBAAyB,CAAC;AAC1D,kBAAM,UAAU;AAAA,UAClB;AAAA,QACF,GAAG;AACH,cAAM,MACH,kBAAkB,2BAA2B,UAAU,MAAM,IAAI,CAAC,EAClE,QAAQ,MAAM;AACb,iBAAO;AAAA,QACT,CAAC;AACH,cAAM;AAEN,QAAAE,QAAO,KAAK,QAAQ,uCAAuC,EAAE,gBAAgB,CAAC;AAC9E,mBAAW,YAAY,MAAM;AAC3B,UAAAA;AAAA,YACE,QAAQ,IAAI,KAAK,UAAU,QAAQ,CAAC;AAAA,YACpC,kBAAkB,SAAS,KAAK,GAAG,CAAC;AAAA,UACtC,EAAE,KAAK,IAAI;AAAA,QACb;AACA,QAAAA,QAAO,MAAM,SAAS,OAAO,yBAAyB,CAAC,EAAE,QAAQ,MAAM,IAAI,CAAC;AAAA,MAC9E,CAAC;AAAA,IACH;AAAA,IACA;AAAA,EACF;AAEA,EAAAF;AAAA,IACE;AAAA,IACA,YAAY;AACV,YAAM,MAAM,MAAM,OAAO,UAAU;AACjC,cAAM,MAAM,SAAS,CAAC,KAAK,KAAK,GAAG,GAAG,CAAC;AACvC,cAAM,OAAO,OAAO,4BAA4B,GAAG;AACnD,wBAAgB,UAAyC;AACvD,gBAAM,CAAC,KAAK,EAAE,IAAI,KAAK,MAAM,KAAK,GAAG,EAAE,CAAC;AACxC,gBAAM,CAAC,KAAK,EAAE,IAAI,KAAK,MAAM,KAAK,GAAG,EAAE,CAAC;AACxC,gBAAM,IAAI,MAAM,6BAA6B;AAAA,QAC/C;AAEA,cAAM,SAAS,MAAM,MAAM,kBAAkB,4BAA4B,QAAQ,CAAC,EAAE;AAAA,UAClF,MAAM;AAAA,UACN,CAAC,UAAmB;AAAA,QACtB;AAEA,QAAAE,QAAO,OAAO,MAAM,CAAC,EAAE,UAAU,6BAA6B;AAC9D,QAAAA,QAAO,MAAM,SAAS,OAAO,0BAA0B,CAAC,EAAE,QAAQ,MAAM,GAAG,CAAC;AAAA,MAC9E,CAAC;AAAA,IACH;AAAA,IACA;AAAA,EACF;AAEA,EAAAF;AAAA,IACE;AAAA,IACA,YAAY;AACV,YAAM,MAAM,MAAM,OAAO,UAAU;AACjC,cAAM,OAAO,OAAO,0BAA0B,SAAS,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC;AACrE,cAAM,MAAM,kBAAkB,0BAA0B,UAAU,CAAC,CAAC,CAAC;AACrE,QAAAE,QAAO,MAAM,SAAS,OAAO,wBAAwB,CAAC,EAAE,QAAQ,CAAC,CAAC;AAClE,QAAAA,QAAO,MAAM,MAAM,IAAI,0BAA0B,GAAG,CAAC,EAAE,SAAS;AAAA,MAClE,CAAC;AAAA,IACH;AAAA,IACA;AAAA,EACF;AAEA,QAAM,QAAQ,KAAK;AACnB,MAAI,UAAU,QAAW;AACvB,IAAAF;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,MAAM,MAAM,OAAO,UAAU;AACjC,gBAAM,MAAM,IAAI,wBAAwB,KAAK,EAAE,IAAI,KAAK,MAAM,KAAK,GAAG,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;AACtF,gBAAM,MAAM,kBAAkB,wBAAwB,UAAU,SAAS,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC;AACxF,gBAAM,MAAM,QAAQ,IAAM;AAC1B,UAAAE,QAAO,MAAM,SAAS,OAAO,sBAAsB,CAAC,EAAE,QAAQ,CAAC,OAAO,KAAK,CAAC;AAAA,QAC9E,CAAC;AAAA,MACH;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;;;AFpJA,IAAMC,QAAO;AAEb,eAAeC,OAAM,MAAY,MAAsD;AACrF,QAAM,QAAQ,MAAM,KAAK;AACzB,MAAI;AACF,UAAM,KAAK,KAAK;AAAA,EAClB,UAAE;AACA,UAAM,MAAM,MAAM;AAAA,EACpB;AACF;AAEA,eAAeC,WAAU,SAA6C;AACpE,SAAO,QAAQ;AAAA,IACb,MAAM;AAAA,IACN,CAAC,UAAmB,SAAS,IAAI,MAAM,uBAAuB;AAAA,EAChE;AACF;AAEA,eAAeC,QAAO,OAA6B,YAAoB,MAAa;AAClF,aAAW,OAAO,KAAM,OAAM,MAAM,IAAI,YAAY,IAAI,IAAI,GAAG;AACjE;AAEA,IAAM,MAAM,CAAC,SAA0B,KAAK,IAAI,CAAC,MAAM,EAAE,EAAE;AAE3D,eAAeC,MACb,OACA,YACAC,SACA,SACkB;AAClB,QAAM,QAAiB,CAAC;AACxB,MAAI;AACJ,KAAG;AACD,UAAM,OAAO,MAAM,MAAM,MAAW,YAAY;AAAA,MAC9C,GAAGA;AAAA,MACH,GAAI,WAAW,UAAa,EAAE,OAAO;AAAA,IACvC,CAAC;AACD,UAAM,KAAK,KAAK,KAAK;AACrB,aAAS,KAAK,cAAc;AAC5B,QAAI,YAAY,OAAW,OAAM,QAAQ,MAAM,MAAM;AAAA,EACvD,SAAS,WAAW,UAAa,MAAM,SAAS;AAChD,SAAO;AACT;AASO,SAAS,yBACd,MACA,MACA,OAAqC,CAAC,GAChC;AACN,EAAAC,UAAS,kCAAkC,IAAI,IAAI,MAAM;AACvD,IAAAC;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAMN,OAAM,MAAM,OAAO,UAAU;AACjC,UAAAO,QAAO,MAAM,MAAM,IAAI,OAAO,SAAS,CAAC,EAAE,SAAS;AACnD,gBAAM,MAAM,IAAI,OAAO,MAAM,EAAE,MAAM,QAAQ,OAAO,IAAI,QAAQ,EAAE,MAAM,CAAC,GAAG,KAAK,EAAE,EAAE,CAAC;AACtF,UAAAA,QAAO,MAAM,MAAM,IAAI,OAAO,IAAI,CAAC,EAAE,QAAQ;AAAA,YAC3C,MAAM;AAAA,YACN,OAAO;AAAA,YACP,QAAQ,EAAE,MAAM,CAAC,GAAG,KAAK,EAAE;AAAA,UAC7B,CAAC;AACD,gBAAM,MAAM,IAAI,OAAO,MAAM,EAAE,GAAG,EAAE,CAAC;AACrC,UAAAA,QAAO,MAAM,MAAM,IAAI,OAAO,IAAI,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;AAAA,QACvD,CAAC;AAAA,MACH;AAAA,MACA;AAAA,IACF;AAEA,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAMN,OAAM,MAAM,OAAO,UAAU;AACjC,gBAAM,MAAM,IAAI,OAAO,MAAM,EAAE,GAAG,EAAE,CAAC;AACrC,gBAAM,MAAM,OAAO,OAAO,IAAI;AAC9B,UAAAO,QAAO,MAAM,MAAM,IAAI,OAAO,IAAI,CAAC,EAAE,SAAS;AAC9C,gBAAMA,QAAO,MAAM,OAAO,OAAO,MAAM,CAAC,EAAE,SAAS,cAAc;AAAA,QACnE,CAAC;AAAA,MACH;AAAA,MACA;AAAA,IACF;AAEA,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAMN,OAAM,MAAM,OAAO,UAAU;AACjC,gBAAME,QAAO,OAAO,OAAO;AAAA,YACzB,EAAE,IAAI,KAAK,MAAM,IAAI;AAAA,YACrB,EAAE,IAAI,KAAK,MAAM,IAAI;AAAA,YACrB,EAAE,IAAI,KAAK,MAAM,IAAI;AAAA,UACvB,CAAC;AACD,gBAAM,IAAI,MAAM,MAAM,MAAW,OAAO,EAAE,cAAc,EAAE,OAAO,QAAQ,OAAO,IAAI,EAAE,CAAC;AACvF,UAAAK,QAAO,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,QAAQ,CAAC,KAAK,GAAG,CAAC;AAC9C,gBAAM,MAAM,MAAM,MAAM,MAAW,OAAO,EAAE,cAAc,EAAE,OAAO,QAAQ,OAAO,IAAI,EAAE,CAAC;AACzF,UAAAA,QAAO,IAAI,IAAI,KAAK,EAAE,KAAK,CAAC,EAAE,QAAQ,CAAC,KAAK,KAAK,GAAG,CAAC;AACrD,UAAAA,QAAO,IAAI,UAAU,EAAE,SAAS;AAAA,QAClC,CAAC;AAAA,MACH;AAAA,MACA;AAAA,IACF;AAEA,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAMN,OAAM,MAAM,OAAO,UAAU;AACjC,gBAAME,QAAO,OAAO,OAAO;AAAA,YACzB,EAAE,IAAI,MAAM,MAAM,KAAK,GAAG,EAAE;AAAA,YAC5B,EAAE,IAAI,MAAM,MAAM,KAAK,GAAG,IAAI;AAAA,YAC9B,EAAE,IAAI,MAAM,MAAM,KAAK,GAAG,EAAE;AAAA,YAC5B,EAAE,IAAI,MAAM,MAAM,KAAK,GAAG,IAAI;AAAA,YAC9B,EAAE,IAAI,MAAM,MAAM,KAAK,GAAG,IAAI;AAAA,YAC9B,EAAE,IAAI,OAAO,MAAM,KAAK,GAAG,KAAK;AAAA,UAClC,CAAC;AACD,gBAAM,QAAQ,OAAO,YACnB;AAAA,aAEI,MAAM,MAAM,MAAW,OAAO;AAAA,cAC5B,cAAc,EAAE,OAAO,QAAQ,OAAO,IAAI;AAAA,cAC1C;AAAA,YACF,CAAC,GACD;AAAA,UACJ,EAAE,KAAK;AACT,UAAAK,QAAO,MAAM,MAAM,EAAE,OAAO,KAAK,UAAU,MAAM,OAAO,EAAE,CAAC,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC;AAC5E,UAAAA,QAAO,MAAM,MAAM,EAAE,OAAO,KAAK,UAAU,MAAM,OAAO,IAAI,CAAC,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC;AAE9E,UAAAA,QAAO,MAAM,MAAM,EAAE,OAAO,KAAK,UAAU,MAAM,OAAO,IAAI,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,IAAI,CAAC;AACpF,UAAAA,QAAO,MAAM,MAAM,EAAE,OAAO,KAAK,UAAU,MAAM,OAAO,EAAE,CAAC,CAAC,EAAE;AAAA,YAC5D,CAAC,OAAO,MAAM,MAAM,IAAI,EAAE,KAAK;AAAA,UACjC;AACA,UAAAA,QAAO,MAAM,MAAM,EAAE,OAAO,KAAK,UAAU,WAAW,OAAO,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,EAAE;AAAA,YACxE,CAAC,MAAM,MAAM,MAAM,IAAI,EAAE,KAAK;AAAA,UAChC;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MACA;AAAA,IACF;AAEA,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAMN,OAAM,MAAM,OAAO,UAAU;AACjC,gBAAME,QAAO,OAAO,OAAO;AAAA,YACzB,EAAE,IAAI,MAAM,MAAM,KAAK,QAAQ,EAAE,GAAG,IAAI,EAAE;AAAA,YAC1C,EAAE,IAAI,MAAM,MAAM,KAAK,QAAQ,EAAE,GAAG,IAAI,EAAE;AAAA,YAC1C,EAAE,IAAI,MAAM,MAAM,KAAK,QAAQ,EAAE,GAAG,IAAI,EAAE;AAAA,YAC1C,EAAE,IAAI,MAAM,MAAM,KAAK,QAAQ,CAAC,EAAE;AAAA,YAClC,EAAE,IAAI,MAAM,MAAM,KAAK,QAAQ,EAAE,GAAG,GAAG,EAAE;AAAA,YACzC,EAAE,IAAI,MAAM,MAAM,KAAK,QAAQ,EAAE,GAAG,EAAE,EAAE;AAAA,YACxC,EAAE,IAAI,MAAM,MAAM,KAAK,QAAQ,EAAE,GAAG,KAAK,EAAE;AAAA,UAC7C,CAAC;AACD,gBAAM,MAAM,MAAM,MAAM,MAAW,OAAO;AAAA,YACxC,cAAc,EAAE,OAAO,QAAQ,OAAO,IAAI;AAAA,YAC1C,SAAS,EAAE,OAAO,YAAY,WAAW,OAAO,OAAO,OAAO;AAAA,UAChE,CAAC;AACD,UAAAK,QAAO,IAAI,IAAI,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,IAAI,CAAC;AACzE,gBAAM,OAAO,MAAM,MAAM,MAAW,OAAO;AAAA,YACzC,cAAc,EAAE,OAAO,QAAQ,OAAO,IAAI;AAAA,YAC1C,SAAS,EAAE,OAAO,YAAY,WAAW,QAAQ,OAAO,OAAO;AAAA,UACjE,CAAC;AACD,UAAAA,QAAO,IAAI,KAAK,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,IAAI,CAAC;AAAA,QAC5E,CAAC;AAAA,MACH;AAAA,MACA;AAAA,IACF;AAEA,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAMN,OAAM,MAAM,OAAO,UAAU;AACjC,gBAAM,OAAO,MAAM,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,GAAG,OAAO,EAAE,IAAI,IAAI,CAAC,IAAI,MAAM,KAAK,GAAG,IAAI,EAAE,EAAE;AACvF,gBAAME,QAAO,OAAO,OAAO,IAAI;AAC/B,qBAAW,WAAW,CAAC,QAAW,EAAE,OAAO,KAAK,WAAW,MAAe,CAAC,GAAG;AAC5E,kBAAME,UAAsB;AAAA,cAC1B,cAAc,EAAE,OAAO,QAAQ,OAAO,IAAI;AAAA,cAC1C,OAAO;AAAA,cACP,GAAI,YAAY,UAAa,EAAE,QAAQ;AAAA,YACzC;AACA,kBAAM,SAAS,MAAMD,MAAK,OAAO,OAAOC,OAAM,GAAG,KAAK;AACtD,YAAAG,QAAO,IAAI,KAAK,EAAE,KAAK,CAAC,EAAE,QAAQ,IAAI,IAAI,EAAE,KAAK,CAAC;AAGlD,kBAAM,SAAS,MAAM,CAAC;AACtB,kBAAM,UACJ,MAAMJ,MAAK,OAAO,OAAOC,SAAQ,OAAO,SAAS;AAC/C,kBAAI,SAAS,EAAG,OAAM,MAAM,OAAO,OAAO,OAAO,EAAE;AAAA,YACrD,CAAC,GACD,KAAK;AACP,YAAAG,QAAO,IAAI,IAAI,IAAI,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,OAAO,MAAM;AACpD,YAAAA,QAAO,IAAI,MAAM,EAAE,KAAK,CAAC,EAAE,QAAQ,IAAI,IAAI,EAAE,KAAK,CAAC;AACnD,kBAAM,MAAM,IAAI,OAAO,OAAO,IAAI,MAAM;AAAA,UAC1C;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MACAR;AAAA,IACF;AAEA,IAAAO;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAMN,OAAM,MAAM,OAAO,UAAU;AACjC,gBAAME;AAAA,YACJ;AAAA,YACA;AAAA,YACA,MAAM,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,GAAG,OAAO,EAAE,IAAI,IAAI,CAAC,IAAI,MAAM,KAAK,GAAG,EAAE,EAAE;AAAA,UACxE;AACA,gBAAM,OAAoB;AAAA,YACxB,cAAc,EAAE,OAAO,QAAQ,OAAO,IAAI;AAAA,YAC1C,SAAS,EAAE,OAAO,KAAK,WAAW,MAAM;AAAA,YACxC,OAAO;AAAA,UACT;AACA,gBAAM,QAAQ,MAAM,MAAM,MAAW,OAAO,IAAI;AAChD,UAAAK,QAAO,MAAM,UAAU,EAAE,IAAI,SAAS;AACtC,gBAAM,SAAS,MAAM;AACrB,gBAAM,QAAQ,MAAMN;AAAA,YAClB,MAAM,MAAM,OAAO,EAAE,GAAG,MAAM,SAAS,EAAE,OAAO,KAAK,WAAW,OAAO,GAAG,OAAO,CAAC;AAAA,UACpF;AACA,UAAAM,QAAO,KAAK,EAAE,eAAe,KAAK;AAClC,gBAAM,OAAO,MAAM,MAAM,MAAW,OAAO,EAAE,GAAG,MAAM,OAAO,CAAC;AAC9D,UAAAA,QAAO,IAAI,KAAK,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,IAAI,CAAC;AAAA,QAC9C,CAAC;AAAA,MACH;AAAA,MACA;AAAA,IACF;AAEA,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAMN,OAAM,MAAM,OAAO,UAAU;AACjC,gBAAM,MAAM,IAAI,OAAO,SAAS,EAAE,IAAI,SAAS,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,CAAC;AACtE,gBAAM,MAAM,IAAI,OAAO,QAAQ,EAAE,IAAI,QAAQ,MAAM,IAAI,CAAC;AACxD,UAAAO,QAAO,MAAM,MAAM,IAAI,OAAO,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,SAAS,MAAM,IAAI,CAAC;AAC1E,cAAI,KAAK,UAAU,QAAW;AAC5B,kBAAM,KAAK,MAAM,QAAQ,IAAK;AAAA,UAChC,OAAO;AACL,kBAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,mBAAQ,MAAM,MAAM,IAAI,OAAO,OAAO,MAAO,QAAQ,KAAK,IAAI,IAAI,UAAU;AAC1E,oBAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAAA,YAC5C;AAAA,UACF;AACA,UAAAA,QAAO,MAAM,MAAM,IAAI,OAAO,OAAO,CAAC,EAAE,SAAS;AACjD,gBAAM,MAAM,MAAM,MAAM,MAAW,OAAO,EAAE,cAAc,EAAE,OAAO,QAAQ,OAAO,IAAI,EAAE,CAAC;AACzF,UAAAA,QAAO,IAAI,IAAI,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC;AACvC,UAAAA,QAAO,CAAC,IAAI,MAAM,MAAM,SAAS,OAAO,CAAC,SAAS,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC;AAAA,QACvF,CAAC;AAAA,MACH;AAAA,MACAR;AAAA,IACF;AAEA,IAAAO;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAMN,OAAM,MAAM,OAAO,UAAU;AACjC,gBAAM,MAAM,IAAI,OAAO,KAAK,EAAE,SAAS,GAAG,OAAO,KAAK,CAAC;AACvD,gBAAM,MAAM;AAAA,YACV;AAAA,YACA;AAAA,YACA,EAAE,SAAS,GAAG,OAAO,KAAK;AAAA,YAC1B,EAAE,cAAc,WAAW,gBAAgB,EAAE;AAAA,UAC/C;AACA,UAAAO,QAAO,MAAM,MAAM,IAAI,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAE,SAAS,GAAG,OAAO,KAAK,CAAC;AACvE,qBAAW,kBAAkB,CAAC,GAAG,GAAG,GAAG;AACrC,kBAAM,SAAS,MAAMN;AAAA,cACnB,MAAM,IAAI,OAAO,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,cAAc,WAAW,eAAe,CAAC;AAAA,YACnF;AACA,YAAAM,QAAQ,QAAsC,IAAI,EAAE,KAAK,0BAA0B;AAAA,UACrF;AACA,gBAAM,SAAS,MAAMN;AAAA,YACnB,MAAM;AAAA,cACJ;AAAA,cACA;AAAA,cACA,EAAE,SAAS,EAAE;AAAA,cACb,EAAE,cAAc,WAAW,gBAAgB,EAAE;AAAA,YAC/C;AAAA,UACF;AACA,UAAAM,QAAQ,QAAsC,IAAI,EAAE,KAAK,0BAA0B;AACnF,UAAAA,QAAO,MAAM,MAAM,IAAI,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAE,SAAS,GAAG,OAAO,KAAK,CAAC;AACvE,UAAAA,QAAO,MAAM,MAAM,IAAI,OAAO,MAAM,CAAC,EAAE,SAAS;AAAA,QAClD,CAAC;AAAA,MACH;AAAA,MACA;AAAA,IACF;AAEA,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAMN,OAAM,MAAM,OAAO,UAAU;AACjC,gBAAM,MAAM;AAAA,YACV;AAAA,YACA,oBAAI,IAAI;AAAA,cACN,CAAC,KAAK,EAAE,GAAG,GAAG,CAAC;AAAA,cACf,CAAC,KAAK,EAAE,GAAG,GAAG,CAAC;AAAA,YACjB,CAAC;AAAA,UACH;AACA,gBAAM,MAAM,MAAM,MAAM,SAAwB,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC;AAC5E,UAAAO,QAAO,CAAC,GAAG,IAAI,KAAK,CAAC,EAAE,KAAK,CAAC,EAAE,QAAQ,CAAC,KAAK,GAAG,CAAC;AACjD,UAAAA,QAAO,IAAI,IAAI,GAAG,CAAC,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC;AACtC,UAAAA,QAAO,MAAM,MAAM,IAAI,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC;AACrD,UAAAA,SAAQ,MAAM,MAAM,SAAS,OAAO,CAAC,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC;AAAA,QACvD,CAAC;AAAA,MACH;AAAA,MACA;AAAA,IACF;AAEA,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAMN,OAAM,MAAM,OAAO,UAAU;AACjC,gBAAM,MAAM,IAAI,QAAQ,OAAO,EAAE,IAAI,OAAO,MAAM,KAAK,MAAM,IAAI,CAAC;AAClE,gBAAM,MAAM,IAAI,QAAQ,OAAO,EAAE,IAAI,OAAO,MAAM,KAAK,MAAM,IAAI,CAAC;AAClE,UAAAO,QAAO,MAAM,MAAM,IAAI,QAAQ,KAAK,CAAC,EAAE,QAAQ,EAAE,IAAI,OAAO,MAAM,KAAK,MAAM,IAAI,CAAC;AAClF,gBAAM,MAAM,MAAM,MAAM,MAAM,QAAQ,EAAE,cAAc,EAAE,OAAO,QAAQ,OAAO,IAAI,EAAE,CAAC;AACrF,UAAAA,QAAO,IAAI,KAAK,EAAE,QAAQ,CAAC,EAAE,IAAI,OAAO,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC;AAC/D,gBAAM,MAAM,OAAO,QAAQ,KAAK;AAChC,UAAAA,QAAO,MAAM,MAAM,IAAI,QAAQ,KAAK,CAAC,EAAE,QAAQ,EAAE,IAAI,OAAO,MAAM,KAAK,MAAM,IAAI,CAAC;AAAA,QACpF,CAAC;AAAA,MACH;AAAA,MACA;AAAA,IACF;AAEA,UAAM,YAAY,KAAK;AACvB,QAAI,cAAc,QAAW;AAC3B,MAAAD;AAAA,QACE;AAAA,QACA,YAAY;AACV,gBAAM,CAAC,KAAK,GAAG,IAAI,MAAM,UAAU;AACnC,cAAI;AACF,kBAAM,IAAI,IAAI,OAAO,UAAU,EAAE,IAAI,UAAU,MAAM,KAAK,OAAO,MAAM,CAAC;AACxE,kBAAM,IAAI,IAAI,OAAO,YAAY,EAAE,IAAI,YAAY,MAAM,KAAK,OAAO,MAAM,CAAC;AAC5E,kBAAM,IAAI,IAAI,OAAO,UAAU,EAAE,IAAI,UAAU,MAAM,KAAK,OAAO,MAAM,CAAC;AACxE,YAAAC,QAAO,MAAM,IAAI,IAAI,OAAO,QAAQ,CAAC,EAAE,QAAQ;AAAA,cAC7C,IAAI;AAAA,cACJ,MAAM;AAAA,cACN,OAAO;AAAA,YACT,CAAC;AACD,YAAAA,QAAO,MAAM,IAAI,IAAI,OAAO,UAAU,CAAC,EAAE,SAAS;AAClD,kBAAM,QAAQ,MAAM,IAAI,MAAM,OAAO,EAAE,cAAc,EAAE,OAAO,QAAQ,OAAO,IAAI,EAAE,CAAC;AACpF,YAAAA,QAAO,MAAM,KAAK,EAAE,QAAQ,CAAC,EAAE,IAAI,UAAU,MAAM,KAAK,OAAO,MAAM,CAAC,CAAC;AACvE,kBAAM,IAAI,OAAO,OAAO,QAAQ;AAChC,YAAAA,QAAO,MAAM,IAAI,IAAI,OAAO,QAAQ,CAAC,EAAE,QAAQ;AAAA,cAC7C,IAAI;AAAA,cACJ,MAAM;AAAA,cACN,OAAO;AAAA,YACT,CAAC;AAAA,UACH,UAAE;AACA,kBAAM,IAAI,MAAM;AAChB,kBAAM,IAAI,MAAM;AAAA,UAClB;AAAA,QACF;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,4BAAwB,MAAM,IAAI;AAElC,8BAA0B,MAAM,IAAI;AAEpC,sBAAkB,MAAM,KAAK,aAAa,SAAS,CAAC,UAAU,MAAM,IAAI,iBAAiB,GAAG,CAAC;AAAA,EAC/F,CAAC;AACH;;;AGlYA,SAAS,YAAAC,WAAU,UAAAC,SAAQ,MAAAC,WAAU;AAIrC,IAAM,OAAO;AAAA,EACX,UAAU;AAAA,EACV,IAAI;AAAA,EACJ,MAAM,EAAE,aAAa,UAAU;AACjC;AAEO,SAAS,iBACd,MACA,OACA,UAAyC,CAAC,GACpC;AACN,EAAAC,UAAS,0BAA0B,IAAI,IAAI,MAAM;AAC/C,IAAAC;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,UAAU,MAAM,MAAM;AAC5B,cAAM,SAAS,MAAM,QAAQ,kBAAkB,IAAI;AACnD,QAAAC,QAAO,OAAO,OAAO,QAAQ,EAAE,KAAK,SAAS;AAAA,MAC/C;AAAA,MACA;AAAA,IACF;AAEA,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,UAAU,MAAM,MAAM;AAC5B,cAAMC;AAAA,UACJ,QAAQ,mBAAmB;AAAA,YACzB,YAAY;AAAA,YACZ,YAAY;AAAA,YACZ,iBAAiB;AAAA,YACjB,SAAS;AAAA,YACT,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,UACpC,CAAC;AAAA,QACH,EAAE,SAAS,IAAI,QAAQ;AAAA,MACzB;AAAA,MACA;AAAA,IACF;AAEA,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,UAAU,MAAM,MAAM;AAC5B,cAAMC,QAAO,QAAQ,uBAAuB,QAAQ,CAAC,EAAE,SAAS,IAAI,QAAQ;AAAA,MAC9E;AAAA,MACA;AAAA,IACF;AAEA;AAAA,MAAkB;AAAA,MAAO,QAAQ;AAAA,MAAa;AAAA,MAAuB,CAAC,YACpE,QAAQ,kBAAkB,IAAI;AAAA,IAChC;AAAA,EACF,CAAC;AACH;;;ACxDA,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,YAAAC,WAAU,UAAAC,SAAQ,MAAAC,WAAU;;;ACDrC,SAAS,kBAAkB;AAC3B,OAAOC,SAAQ;AACf,SAAS,YAAAC,WAAU,UAAAC,SAAQ,MAAAC,WAAU;AAiBrC,IAAMC,QAAO;AAEb,SAAS,MAAM,MAAc,UAAmC,CAAC,GAAgB;AAC/E,SAAO;AAAA,IACL,IAAI,OAAO,WAAW,CAAC;AAAA,IACvB;AAAA,IACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC,QAAQ;AAAA,IACR,eAAe,QAAQ,WAAW,CAAC;AAAA,IACnC;AAAA,IACA,UAAU,EAAE,SAAS,YAAY,aAAa,eAAe,SAAS,QAAQ;AAAA,EAChF;AACF;AAEA,IAAM,QAAQ,CAAC,OAA8B,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAGjF,eAAe,MAAM,OAAsB,OAAe,IAA2B;AACnF,QAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,SAAO,CAAC,MAAM,GAAG;AACf,QAAI,KAAK,IAAI,IAAI,SAAU,OAAM,IAAI,MAAM,mBAAmB,EAAE,mBAAmB,KAAK,EAAE;AAC1F,UAAM,MAAM,EAAE;AAAA,EAChB;AACF;AAEA,SAAS,OAA8C;AACrD,MAAI;AACJ,QAAM,OAAO,IAAI,QAAc,CAAC,MAAM;AACpC,WAAO;AAAA,EACT,CAAC;AACD,SAAO,EAAE,MAAM,KAAK;AACtB;AAEA,eAAe,WAAW,OAA0B,MAA0C;AAC5F,MAAI;AACF,UAAM,KAAK;AAAA,EACb,UAAE;AACA,eAAW,OAAO,MAAO,OAAM,IAAI,MAAM;AAAA,EAC3C;AACF;AAEA,IAAM,QAAQ,CAAC,oBAAoB,iBAAiB,iBAAiB;AAG9D,SAAS,sBAAsB,MAA8B,MAA6B;AAC/F,EAAAH,UAAS,+BAA+B,MAAM;AAC5C,IAAAE;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,MAAM,MAAM,KAAK;AACvB,cAAM,WAAW,CAAC,GAAG,GAAG,YAAY;AAClC,gBAAM,WAAqB,CAAC;AAC5B,gBAAM,IAAI,UAAU,oBAAoB,YAAY;AAClD,kBAAM,MAAM,GAAG;AACf,qBAAS,KAAK,SAAS;AAAA,UACzB,CAAC;AACD,gBAAM,IAAI;AAAA,YACR;AAAA,YACA,YAAY;AACV,oBAAM,MAAM,GAAG;AACf,uBAAS,KAAK,OAAO;AAAA,YACvB;AAAA,YACA,EAAE,MAAM,gBAAgB;AAAA,UAC1B;AAEA,gBAAM,YAAY,KAAK,IAAI;AAC3B,gBAAM,IAAI,QAAQ,MAAM,kBAAkB,CAAC;AAC3C,gBAAM,UAAU,KAAK,IAAI,IAAI;AAE7B,UAAAD,QAAO,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,EAAE,QAAQ,CAAC,SAAS,SAAS,CAAC;AACzD,UAAAA,QAAO,OAAO,EAAE,uBAAuB,GAAG;AAAA,QAC5C,CAAC;AAAA,MACH;AAAA,MACAE;AAAA,IACF;AAEA,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,MAAM,MAAM,KAAK;AACvB,cAAM,WAAW,CAAC,GAAG,GAAG,YAAY;AAClC,gBAAM,WAAqB,CAAC;AAC5B,gBAAM,IAAI;AAAA,YACR;AAAA,YACA,YAAY;AACV,oBAAM,IAAI,MAAM,0BAA0B;AAAA,YAC5C;AAAA,YACA,EAAE,MAAM,kBAAkB;AAAA,UAC5B;AACA,gBAAM,IAAI,UAAU,oBAAoB,OAAO,MAAM;AACnD,qBAAS,KAAK,EAAE,EAAE;AAAA,UACpB,CAAC;AACD,gBAAM,SAAS,CAAC,MAAM,kBAAkB,GAAG,MAAM,kBAAkB,GAAG,MAAM,kBAAkB,CAAC;AAE/F,qBAAW,KAAK,OAAQ,OAAMD,QAAO,IAAI,QAAQ,CAAC,CAAC,EAAE,SAAS,cAAc;AAE5E,UAAAA,QAAO,QAAQ,EAAE,QAAQ,OAAO,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAAA,QAClD,CAAC;AAAA,MACH;AAAA,MACAE;AAAA,IACF;AAEA,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,MAAM,MAAM,KAAK;AACvB,cAAM,WAAW,CAAC,GAAG,GAAG,YAAY;AAClC,gBAAM,UAAoB,CAAC;AAC3B,gBAAM,YAAsB,CAAC;AAC7B,gBAAM,cAAwB,CAAC;AAC/B,gBAAM,IAAI,UAAU,sBAAsB,OAAO,MAAM,KAAK,QAAQ,KAAK,EAAE,EAAE,GAAG;AAAA,YAC9E,MAAM;AAAA,YACN,SAAS;AAAA,UACX,CAAC;AACD,gBAAM,IAAI,UAAU,sBAAsB,OAAO,MAAM,KAAK,UAAU,KAAK,EAAE,EAAE,GAAG;AAAA,YAChF,MAAM;AAAA,UACR,CAAC;AACD,gBAAM,IAAI,UAAU,sBAAsB,OAAO,MAAM,KAAK,YAAY,KAAK,EAAE,EAAE,CAAC;AAClF,gBAAM,WAAW,CAAC,MAAM,oBAAoB,GAAG,MAAM,oBAAoB,CAAC;AAE1E,gBAAM,IAAI,OAAO,QAAQ;AAEzB,UAAAD,QAAO,OAAO,EAAE,QAAQ,SAAS,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AACjD,UAAAA,QAAO,SAAS,EAAE,QAAQ,CAAC,CAAC;AAC5B,UAAAA,QAAO,WAAW,EAAE,QAAQ,CAAC,CAAC;AAE9B,gBAAM,OAAO,MAAM,oBAAoB;AACvC,gBAAM,IAAI,QAAQ,IAAI;AACtB,UAAAA,QAAO,OAAO,EAAE,QAAQ,CAAC,GAAG,UAAU,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAC5D,UAAAA,QAAO,SAAS,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC;AACnC,UAAAA,QAAO,WAAW,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC;AAAA,QACvC,CAAC;AAAA,MACH;AAAA,MACAE;AAAA,IACF;AAEA,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAMH,IAAG;AAAA,UACPA,IAAG;AAAA,YACDA,IAAG,MAAMA,IAAG,aAAa,GAAG,KAAK,GAAG,EAAE,WAAW,GAAG,WAAW,GAAG,CAAC;AAAA,YACnE,OAAO,UAAU;AACf,oBAAM,MAAM,MAAM,KAAK;AACvB,oBAAM,WAAW,CAAC,GAAG,GAAG,YAAY;AAClC,sBAAM,QAAQ,MAAM,mBAAmB;AACvC,sBAAM,OAAO;AAAA,kBACX,EAAE,UAAU,CAAC,WAAW,MAAM,IAAI,GAAG,MAAM,OAAU;AAAA,kBACrD,EAAE,UAAU,CAAC,mBAAmB,iBAAiB,MAAM,IAAI,GAAG,MAAM,eAAe;AAAA,kBACnF,EAAE,UAAU,CAAC,oBAAoB,MAAM,IAAI,GAAG,MAAM,eAAe;AAAA,gBACrE;AACA,sBAAM,OAAO,KAAK,IAAI,MAAM,CAAC,CAAa;AAC1C,2BAAW,CAAC,GAAG,GAAG,KAAK,KAAK,QAAQ,GAAG;AACrC,wBAAM,IAAI;AAAA,oBACR,IAAI;AAAA,oBACJ,OAAO,MAAM,KAAK,KAAK,CAAC,EAAG,KAAK,EAAE,EAAE;AAAA,oBACpC,IAAI,SAAS,SAAY,SAAY,EAAE,MAAM,IAAI,KAAK;AAAA,kBACxD;AAAA,gBACF;AACA,sBAAM,SAAS,MAAM,IAAI,CAAC,MAAM,QAAQ,MAAM,MAAM,EAAE,IAAI,CAAC,CAAC;AAE5D,sBAAM,IAAI,aAAa,MAAM;AAE7B,sBAAM,IAAI,QAAQ,KAAK;AAEvB,sBAAM,UAAU,CAAC,UAAoB,SACnC,SAAS;AAAA,kBAAK,CAAC,MACb,EAAE,SAAS,GAAG,IAAI,KAAK,WAAW,EAAE,MAAM,GAAG,EAAE,CAAC,IAAI,MAAM;AAAA,gBAC5D;AACF,2BAAW,CAAC,GAAG,GAAG,KAAK,KAAK,QAAQ,GAAG;AACrC,wBAAM,WAAW,OAAO,OAAO,CAAC,MAAM,QAAQ,IAAI,UAAU,EAAE,IAAI,CAAC;AACnE,kBAAAE,QAAO,KAAK,CAAC,GAAG,IAAI,SAAS,KAAK,GAAG,CAAC,EAAE,QAAQ;AAAA,oBAC9C,GAAG,SAAS,IAAI,CAAC,MAAM,EAAE,EAAE;AAAA,oBAC3B,MAAM;AAAA,kBACR,CAAC;AAAA,gBACH;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF;AAAA,UACA,EAAE,SAAS,GAAG;AAAA,QAChB;AAAA,MACF;AAAA,MACAE;AAAA,IACF;AAEA,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,MAAM,MAAM,KAAK;AACvB,cAAM,WAAW,CAAC,GAAG,GAAG,YAAY;AAClC,gBAAM,OAAiB,CAAC;AACxB,gBAAM,UAAoB,CAAC;AAC3B,gBAAM,OAAiB,CAAC;AACxB,gBAAM,IAAI,MAAM,IAAI,UAAU,qBAAqB,OAAO,MAAM,KAAK,KAAK,KAAK,EAAE,EAAE,GAAG;AAAA,YACpF,MAAM;AAAA,UACR,CAAC;AACD,gBAAM,IAAI,MAAM,IAAI,UAAU,qBAAqB,OAAO,MAAM,KAAK,QAAQ,KAAK,EAAE,EAAE,CAAC;AACvF,gBAAM,IAAI,UAAU,qBAAqB,OAAO,MAAM,KAAK,KAAK,KAAK,EAAE,EAAE,CAAC;AAC1E,gBAAM,SAAS,MAAM,mBAAmB;AACxC,gBAAM,IAAI,QAAQ,MAAM;AAExB,gBAAM,IAAI,YAAY,CAAC;AACvB,gBAAM,EAAE,YAAY;AACpB,gBAAM,QAAQ,CAAC,MAAM,mBAAmB,GAAG,MAAM,mBAAmB,CAAC;AACrE,qBAAW,KAAK,MAAO,OAAM,IAAI,QAAQ,CAAC;AAE1C,UAAAD,QAAO,IAAI,EAAE,QAAQ,CAAC,QAAQ,GAAG,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AACxD,UAAAA,QAAO,IAAI,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC;AAChC,UAAAA,QAAO,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC;AAAA,QACrC,CAAC;AAAA,MACH;AAAA,MACAE;AAAA,IACF;AAEA,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,MAAM,MAAM,KAAK;AACvB,cAAM,WAAW,CAAC,GAAG,GAAG,YAAY;AAClC,gBAAM,QAAkB,CAAC;AACzB,gBAAM,UAAoB,CAAC;AAC3B,gBAAM,IAAI,UAAU,oBAAoB,OAAO,MAAM,KAAK,MAAM,KAAK,EAAE,EAAE,GAAG;AAAA,YAC1E,MAAM;AAAA,UACR,CAAC;AACD,gBAAM,IAAI,UAAU,oBAAoB,OAAO,MAAM,KAAK,QAAQ,KAAK,EAAE,EAAE,CAAC;AAC5E,gBAAM,SAAS,MAAM,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,kBAAkB,CAAC;AAExE,qBAAW,KAAK,OAAQ,OAAM,IAAI,QAAQ,CAAC;AAE3C,UAAAD,QAAO,KAAK,EAAE,QAAQ,OAAO,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAC7C,UAAAA,QAAO,OAAO,EAAE,QAAQ,KAAK;AAAA,QAC/B,CAAC;AAAA,MACH;AAAA,MACAE;AAAA,IACF;AAEA,UAAM,SAAS,KAAK;AACpB,QAAI,WAAW,OAAW;AAE1B,IAAAH,UAAS,qCAAqC,MAAM;AAClD,YAAM,IAAI;AAEV,MAAAE;AAAA,QACE;AAAA,QACA,YAAY;AACV,gBAAM,IAAI,MAAM,KAAK;AACrB,gBAAM,IAAI,MAAM,OAAO;AACvB,gBAAM,WAAW,CAAC,GAAG,CAAC,GAAG,YAAY;AACnC,kBAAM,MAAgB,CAAC;AACvB,kBAAM,MAAgB,CAAC;AACvB,kBAAM,EAAE,UAAU,oBAAoB,OAAO,MAAM,KAAK,IAAI,KAAK,EAAE,EAAE,GAAG;AAAA,cACtE,MAAM;AAAA,YACR,CAAC;AACD,kBAAM,EAAE,UAAU,oBAAoB,OAAO,MAAM,KAAK,IAAI,KAAK,EAAE,EAAE,GAAG;AAAA,cACtE,MAAM;AAAA,YACR,CAAC;AACD,kBAAM,SAAS,MAAM,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,GAAG,QAAQ,MAAM,oBAAoB,EAAE,IAAI,CAAC,CAAC;AAEvF,uBAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,EAAG,QAAO,IAAI,MAAM,IAAI,IAAI,GAAG,QAAQ,CAAC;AAE5E,kBAAM,EAAE,QAAQ,MAAM,sBAAsB,CAAC;AAC7C,kBAAM,EAAE,QAAQ,MAAM,sBAAsB,CAAC;AAE7C,kBAAME,OAAM,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAC3C,kBAAM,UAAU,CAAC,GAAG,KAAK,GAAG,GAAG,EAAE,OAAO,CAAC,OAAOA,KAAI,IAAI,EAAE,CAAC;AAC3D,YAAAH,QAAO,QAAQ,MAAM,EAAE,KAAK,OAAO,MAAM;AACzC,YAAAA,QAAO,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC,EAAE,QAAQ,OAAO,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,KAAK,CAAC;AAAA,UACpE,CAAC;AAAA,QACH;AAAA,QACAE;AAAA,MACF;AAEA,MAAAD;AAAA,QACE;AAAA,QACA,YAAY;AACV,gBAAM,IAAI,MAAM,KAAK;AACrB,gBAAM,IAAI,MAAM,OAAO;AACvB,gBAAM,WAAW,CAAC,GAAG,CAAC,GAAG,YAAY;AACnC,kBAAM,MAAgB,CAAC;AACvB,kBAAM,MAAgB,CAAC;AACvB,kBAAM,EAAE,UAAU,qBAAqB,OAAO,MAAM,KAAK,IAAI,KAAK,EAAE,EAAE,CAAC;AACvE,kBAAM,EAAE,UAAU,qBAAqB,OAAO,MAAM,KAAK,IAAI,KAAK,EAAE,EAAE,CAAC;AACvE,kBAAM,SAAS,MAAM,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,GAAG,QAAQ,MAAM,qBAAqB,EAAE,IAAI,CAAC,CAAC;AAExF,uBAAW,KAAK,OAAQ,OAAM,EAAE,QAAQ,CAAC;AACzC,kBAAM,SAAS,MAAM,uBAAuB;AAC5C,kBAAM,EAAE,QAAQ,MAAM;AAEtB,kBAAME,OAAM,OAAO,IAAI,CAAC,MAAM,EAAE,EAAE;AAClC,YAAAH,QAAO,IAAI,MAAM,GAAG,CAAC,CAAC,EAAE,QAAQG,IAAG;AACnC,YAAAH,QAAO,IAAI,MAAM,GAAG,CAAC,CAAC,EAAE,QAAQG,IAAG;AACnC,YAAAH,QAAO,IAAI,CAAC,CAAC,EAAE,KAAK,OAAO,EAAE;AAAA,UAC/B,CAAC;AAAA,QACH;AAAA,QACAE;AAAA,MACF;AAEA,MAAAD;AAAA,QACE;AAAA,QACA,YAAY;AACV,gBAAM,IAAI,MAAM,KAAK;AACrB,gBAAM,IAAI,MAAM,OAAO;AACvB,gBAAM,WAAW,CAAC,GAAG,CAAC,GAAG,YAAY;AACnC,kBAAM,WAAqB,CAAC;AAC5B,kBAAM,WAAqB,CAAC;AAC5B,kBAAM,QAAkB,CAAC;AACzB,kBAAM,EAAE,UAAU,sBAAsB,OAAO,MAAM,KAAK,SAAS,KAAK,EAAE,EAAE,GAAG;AAAA,cAC7E,MAAM;AAAA,cACN,SAAS;AAAA,YACX,CAAC;AACD,kBAAM,EAAE,UAAU,sBAAsB,OAAO,MAAM,KAAK,SAAS,KAAK,EAAE,EAAE,GAAG;AAAA,cAC7E,MAAM;AAAA,cACN,SAAS;AAAA,YACX,CAAC;AACD,kBAAM,EAAE,UAAU,sBAAsB,OAAO,MAAM,KAAK,MAAM,KAAK,EAAE,EAAE,GAAG;AAAA,cAC1E,MAAM;AAAA,YACR,CAAC;AACD,kBAAM,WAAW,CAAC,MAAM,oBAAoB,GAAG,MAAM,oBAAoB,CAAC;AAE1E,kBAAM,EAAE,OAAO,QAAQ;AAEvB,kBAAM,QAAQ,MAAM,wBAAwB;AAC5C,kBAAM,EAAE,QAAQ,KAAK;AAErB,YAAAD,QAAO,SAAS,MAAM,GAAG,SAAS,MAAM,CAAC,EAAE,QAAQ,SAAS,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAC5E,kBAAMG,OAAM,IAAI,IAAI,SAAS,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAC7C,YAAAH,QAAO,SAAS,OAAO,CAAC,OAAOG,KAAI,IAAI,EAAE,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;AACvD,YAAAH,QAAO,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;AAAA,UAClC,CAAC;AAAA,QACH;AAAA,QACAE;AAAA,MACF;AAEA,YAAM,SAAS,KAAK;AACpB,UAAI,WAAW,OAAW;AAC1B,YAAM,EAAE,aAAa,aAAa,IAAI;AAEtC,MAAAD;AAAA,QACE;AAAA,QACA,YAAY;AACV,gBAAM,IAAI,MAAM,KAAK;AACrB,gBAAM,IAAI,MAAM,OAAO;AACvB,gBAAM,WAAW,CAAC,CAAC,GAAG,YAAY;AAChC,kBAAM,EAAE,UAAU,mBAAmB,YAAY,QAAW,EAAE,MAAM,uBAAuB,CAAC;AAC5F,kBAAM,EAAE,UAAU,mBAAmB,YAAY,MAAS;AAC1D,kBAAM,EAAE,MAAM;AACd,kBAAM,UAAoB,CAAC;AAC3B,kBAAM,EAAE,UAAU,mBAAmB,OAAOG,OAAM,KAAK,QAAQ,KAAKA,GAAE,EAAE,GAAG;AAAA,cACzE,MAAM;AAAA,YACR,CAAC;AACD,kBAAM,IAAI,MAAM,iBAAiB;AAEjC,kBAAM,YAAY,KAAK,IAAI;AAC3B,kBAAM,EAAE,QAAQ,CAAC;AACjB,kBAAM,UAAU,KAAK,IAAI,IAAI;AAE7B,YAAAJ,QAAO,OAAO,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC;AAC9B,YAAAA,QAAO,OAAO,EAAE,aAAa,eAAe,CAAC;AAAA,UAC/C,CAAC;AAAA,QACH;AAAA,QACAE;AAAA,MACF;AAEA,MAAAD;AAAA,QACE;AAAA,QACA,YAAY;AACV,gBAAM,IAAI,MAAM,KAAK;AACrB,gBAAM,IAAI,MAAM,OAAO;AACvB,gBAAM,OAAO,KAAK;AAClB,cAAI;AACJ,cAAI;AACF,gBAAI;AACJ,kBAAM,EAAE;AAAA,cACN;AAAA,cACA,YAAY;AACV,8BAAc,KAAK,IAAI;AACvB,sBAAM,KAAK;AAAA,cACb;AAAA,cACA,EAAE,MAAM,mBAAmB;AAAA,YAC7B;AACA,kBAAM,WAAW,MAAM,kBAAkB;AAEzC,kBAAM,EAAE,QAAQ,QAAQ;AACxB,kBAAM,MAAM,MAAM,gBAAgB,QAAW,0BAA0B,YAAY;AACnF,uBAAW,EAAE,MAAM;AAEnB,kBAAM,MAAyC,CAAC;AAChD,kBAAM,EAAE;AAAA,cACN;AAAA,cACA,OAAO,MAAM,KAAK,IAAI,KAAK,EAAE,IAAI,EAAE,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;AAAA,cACvD;AAAA,gBACE,MAAM;AAAA,cACR;AAAA,YACF;AACA,kBAAM,OAAO,MAAM,kBAAkB;AACrC,kBAAM,YAAY,KAAK,IAAI;AAC3B,kBAAM,EAAE,QAAQ,IAAI;AACpB,kBAAM,YAAY,KAAK,IAAI,IAAI;AAC/B,kBAAM;AAAA,cACJ,MAAM,IAAI,KAAK,CAAC,MAAM,EAAE,OAAO,SAAS,EAAE;AAAA,cAC1C;AAAA,cACA,eAAe;AAAA,YACjB;AAEA,kBAAM,UAAU,IAAI,KAAK,CAAC,MAAM,EAAE,OAAO,SAAS,EAAE;AACpD,kBAAM,OAAO,QAAQ,KAAK;AAC1B,YAAAD,QAAO,MAAM,+BAA+B,EAAE,uBAAuB,cAAc,EAAE;AACrF,YAAAA,QAAO,MAAM,oCAAoC,EAAE,aAAa,YAAY;AAC5E,YAAAA,QAAO,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO,SAAS,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC;AAC7D,YAAAA,QAAO,WAAW,+CAA+C,EAAE;AAAA,cACjE;AAAA,YACF;AAAA,UACF,UAAE;AACA,iBAAK,KAAK;AACV,kBAAM;AACN,kBAAM,EAAE,MAAM;AAAA,UAChB;AAAA,QACF;AAAA,QACAE;AAAA,MACF;AAEA,MAAAD;AAAA,QACE;AAAA,QACA,YAAY;AACV,gBAAM,IAAI,MAAM,KAAK;AACrB,gBAAM,OAAO,KAAK;AAClB,cAAI;AACF,gBAAI,UAAU;AACd,kBAAM,MAAM,MAAM,EAAE,UAAU,mBAAmB,YAAY;AAC3D,wBAAU;AACV,oBAAM,KAAK;AAAA,YACb,CAAC;AACD,kBAAM,aAAa,EAAE,QAAQ,MAAM,iBAAiB,CAAC,EAAE;AAAA,cACrD,MAAM,KAAK,IAAI;AAAA,cACf,CAAC,UAAmB;AAAA,YACtB;AACA,kBAAM,MAAM,MAAM,SAAS,wBAAwB,YAAY;AAE/D,kBAAM,iBAAiB,KAAK,IAAI;AAChC,kBAAM,gBAAgB,EAAE,YAAY,GAAG;AACvC,kBAAM,UAAU,MAAM;AAEtB,YAAAD,QAAO,OAAO,SAAS,qBAAqB,OAAO,OAAO,CAAC,EAAE,EAAE,KAAK,QAAQ;AAC5E,YAAAA,QAAQ,UAAqB,cAAc,EAAE,aAAa,eAAe,CAAC;AAC1E,iBAAK,KAAK;AACV,kBAAM;AAAA,UACR,UAAE;AACA,iBAAK,KAAK;AACV,kBAAM,EAAE,MAAM;AAAA,UAChB;AAAA,QACF;AAAA,QACAE;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH;;;AD3cA,IAAMG,QAAO;AAEb,SAAS,UAAU,MAAc,UAAmC,CAAC,GAAgB;AACnF,SAAO;AAAA,IACL,IAAI,OAAOC,YAAW,CAAC;AAAA,IACvB;AAAA,IACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC,QAAQ;AAAA,IACR,eAAe,QAAQA,YAAW,CAAC;AAAA,IACnC;AAAA,IACA,UAAU,EAAE,SAAS,QAAQ,aAAa,eAAe,SAAS,QAAQ;AAAA,EAC5E;AACF;AAEA,IAAMC,SAAQ,CAAC,OAA8B,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAEjF,eAAeC,OAAM,OAA0B,MAA0C;AACvF,MAAI;AACF,UAAM,KAAK;AAAA,EACb,UAAE;AACA,eAAW,OAAO,MAAO,OAAM,IAAI,MAAM;AAAA,EAC3C;AACF;AASO,SAAS,oBACd,MACA,MACA,OAAgC,CAAC,GAC3B;AACN,EAAAC,UAAS,6BAA6B,IAAI,IAAI,MAAM;AAClD,IAAAC,IAAG,gGAAgG,YAAY;AAC7G,YAAM,MAAM,MAAM,KAAK;AACvB,YAAMF,OAAM,CAAC,GAAG,GAAG,YAAY;AAC7B,cAAM,WAAsB,CAAC;AAC7B,cAAM,QAAmB,CAAC;AAC1B,cAAM,IAAI,UAAU,iBAAiB,OAAO,MAAM;AAChD,gBAAMD,OAAM,EAAE;AACd,mBAAS,KAAK,EAAE,OAAO;AAAA,QACzB,CAAC;AACD,cAAM,IAAI,UAAU,iBAAiB,OAAO,MAAM,KAAK,MAAM,KAAK,CAAC,CAAC;AACpE,cAAM,IAAI,QAAQ,UAAU,iBAAiB,EAAE,GAAG,EAAE,CAAC,CAAC;AACtD,QAAAI,QAAO,QAAQ,EAAE,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;AACnC,QAAAA,QAAO,KAAK,EAAE,QAAQ,CAAC,CAAC;AAAA,MAC1B,CAAC;AAAA,IACH,GAAG,OAAO;AAEV,IAAAD,IAAG,gFAAgF,YAAY;AAC7F,YAAM,MAAM,MAAM,KAAK;AACvB,YAAMF,OAAM,CAAC,GAAG,GAAG,YAAY;AAC7B,cAAM,UAAoB,CAAC;AAC3B,cAAM,IAAI,UAAU,iBAAiB,YAAY;AAC/C,gBAAM,IAAI,MAAM,MAAM;AAAA,QACxB,CAAC;AACD,cAAM,IAAI,UAAU,iBAAiB,YAAY,KAAK,QAAQ,KAAK,IAAI,CAAC;AACxE,cAAMG,QAAO,IAAI,QAAQ,UAAU,eAAe,CAAC,CAAC,EAAE,SAAS,cAAc;AAC7E,QAAAA,QAAO,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC;AAAA,MAChC,CAAC;AAAA,IACH,GAAG,OAAO;AAEV,IAAAD,IAAG,6CAA6C,YAAY;AAC1D,YAAM,MAAM,MAAM,KAAK;AACvB,YAAMF,OAAM,CAAC,GAAG,GAAG,YAAY;AAC7B,cAAM,UAAoB,CAAC;AAC3B,cAAM,aAAuB,CAAC;AAC9B,cAAM,IAAI,UAAU,kBAAkB,OAAO,MAAM,KAAK,QAAQ,KAAK,EAAE,EAAE,GAAG;AAAA,UAC1E,MAAM;AAAA,UACN,SAAS;AAAA,QACX,CAAC;AACD,cAAM,IAAI,UAAU,kBAAkB,OAAO,MAAM,KAAK,WAAW,KAAK,EAAE,EAAE,GAAG;AAAA,UAC7E,MAAM;AAAA,QACR,CAAC;AACD,cAAM,SAAS,CAAC,UAAU,gBAAgB,GAAG,UAAU,gBAAgB,CAAC;AACxE,cAAM,IAAI,OAAO,MAAM;AACvB,QAAAG,QAAO,OAAO,EAAE,QAAQ,OAAO,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAC/C,QAAAA,QAAO,UAAU,EAAE,QAAQ,CAAC,CAAC;AAAA,MAC/B,CAAC;AAAA,IACH,GAAG,OAAO;AAEV,IAAAD,IAAG,+FAA+F,YAAY;AAC5G,YAAM,MAAM,MAAM,KAAK;AACvB,YAAMF,OAAM,CAAC,GAAG,GAAG,YAAY;AAC7B,cAAM,WAAqB,CAAC;AAC5B,cAAM,SAAmB,CAAC;AAC1B,cAAM,IAAI,UAAU,WAAW,OAAO,MAAM,KAAK,SAAS,KAAK,EAAE,EAAE,CAAC;AACpE,cAAM,IAAI,UAAU,CAAC,cAAc,YAAY,GAAG,OAAO,MAAM,KAAK,OAAO,KAAK,EAAE,EAAE,GAAG;AAAA,UACrF,MAAM;AAAA,QACR,CAAC;AACD,cAAM,SAAS,CAAC,cAAc,cAAc,cAAc,YAAY,EAAE;AAAA,UAAI,CAAC,GAAG,QAC9E,UAAU,GAAG,EAAE,IAAI,CAAC;AAAA,QACtB;AACA,cAAM,IAAI,aAAa,MAAM;AAC7B,QAAAG,QAAO,QAAQ,EAAE,QAAQ,OAAO,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAChD,QAAAA,QAAO,MAAM,EAAE,QAAQ,OAAO,OAAO,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAAA,MACvF,CAAC;AAAA,IACH,GAAG,OAAO;AAEV,IAAAD,IAAG,iDAAiD,YAAY;AAC9D,YAAM,MAAM,MAAM,KAAK;AACvB,YAAMF,OAAM,CAAC,GAAG,GAAG,YAAY;AAC7B,cAAM,WAAqB,CAAC;AAC5B,cAAM,MAAM,MAAM,IAAI,UAAU,kBAAkB,OAAO,MAAM,KAAK,SAAS,KAAK,EAAE,EAAE,CAAC;AACvF,cAAM,SAAS,UAAU,gBAAgB;AACzC,cAAM,IAAI,QAAQ,MAAM;AACxB,cAAM,IAAI,YAAY,GAAG;AACzB,cAAM,IAAI,QAAQ,UAAU,gBAAgB,CAAC;AAC7C,QAAAG,QAAO,QAAQ,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC;AAAA,MACtC,CAAC;AAAA,IACH,GAAG,OAAO;AAEV,IAAAD,IAAG,qFAAqF,YAAY;AAClG,YAAM,MAAM,MAAM,KAAK;AACvB,YAAMF,OAAM,CAAC,GAAG,GAAG,YAAY;AAC7B,cAAM,QAAkB,CAAC;AACzB,cAAM,UAAoB,CAAC;AAC3B,cAAM,IAAI,UAAU,iBAAiB,OAAO,MAAM,KAAK,MAAM,KAAK,EAAE,EAAE,GAAG;AAAA,UACvE,MAAM;AAAA,QACR,CAAC;AACD,cAAM,IAAI,UAAU,iBAAiB,OAAO,MAAM,KAAK,QAAQ,KAAK,EAAE,EAAE,CAAC;AACzE,cAAM,SAAS,CAAC,UAAU,eAAe,GAAG,UAAU,eAAe,CAAC;AACtE,mBAAW,KAAK,OAAQ,OAAM,IAAI,QAAQ,CAAC;AAC3C,QAAAG,QAAO,KAAK,EAAE,QAAQ,OAAO,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAC7C,QAAAA,QAAO,OAAO,EAAE,QAAQ,KAAK;AAAA,MAC/B,CAAC;AAAA,IACH,GAAG,OAAO;AAEV,0BAAsB,MAAM,IAAI;AAEhC;AAAA,MAAkB;AAAA,MAAM,KAAK;AAAA,MAAa;AAAA,MAAa,CAAC,QACtD,IAAI,QAAQ,UAAU,kBAAkB,CAAC;AAAA,IAC3C;AAEA,UAAM,SAAS,KAAK;AACpB,QAAI,WAAW,OAAW;AAE1B,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,IAAI,MAAM,KAAK;AACrB,cAAM,IAAI,MAAM,OAAO;AACvB,cAAMF,OAAM,CAAC,GAAG,CAAC,GAAG,YAAY;AAC9B,gBAAM,QAAkB,CAAC;AACzB,gBAAM,MAAgB,CAAC;AACvB,gBAAM,MAAgB,CAAC;AACvB,gBAAM,EAAE,UAAU,YAAY,OAAO,MAAM,KAAK,MAAM,KAAK,EAAE,EAAE,GAAG;AAAA,YAChE,MAAM;AAAA,UACR,CAAC;AACD,gBAAM,EAAE,UAAU,YAAY,OAAO,MAAM,KAAK,MAAM,KAAK,EAAE,EAAE,GAAG;AAAA,YAChE,MAAM;AAAA,UACR,CAAC;AACD,gBAAM,EAAE,UAAU,YAAY,OAAO,MAAM,KAAK,IAAI,KAAK,EAAE,EAAE,CAAC;AAC9D,gBAAM,EAAE,UAAU,YAAY,OAAO,MAAM,KAAK,IAAI,KAAK,EAAE,EAAE,CAAC;AAC9D,gBAAM,SAAS,MAAM,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,GAAG,QAAQ,UAAU,YAAY,EAAE,IAAI,CAAC,CAAC;AACnF,qBAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,EAAG,QAAO,IAAI,MAAM,IAAI,IAAI,GAAG,QAAQ,CAAC;AAE5E,gBAAM,SAAS,UAAU,cAAc;AACvC,gBAAM,SAAS,UAAU,cAAc;AACvC,gBAAM,EAAE,QAAQ,MAAM;AACtB,gBAAM,EAAE,QAAQ,MAAM;AAEtB,gBAAMI,OAAM,OAAO,IAAI,CAAC,MAAM,EAAE,EAAE;AAClC,UAAAD,QAAO,MAAM,OAAO,CAAC,OAAOC,KAAI,SAAS,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,QAAQ,CAAC,GAAGA,IAAG,EAAE,KAAK,CAAC;AAC7E,UAAAD,QAAO,IAAI,OAAO,CAAC,OAAOC,KAAI,SAAS,EAAE,CAAC,CAAC,EAAE,QAAQA,IAAG;AACxD,UAAAD,QAAO,IAAI,OAAO,CAAC,OAAOC,KAAI,SAAS,EAAE,CAAC,CAAC,EAAE,QAAQA,IAAG;AAAA,QAC1D,CAAC;AAAA,MACH;AAAA,MACAP;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;AE9LA,SAAS,YAAAQ,WAAU,UAAAC,UAAQ,MAAAC,YAAU;AAc9B,SAAS,wBACd,MACA,MACA,SACM;AACN,QAAM,EAAE,SAAS,IAAI;AACrB,EAAAC,UAAS,0BAA0B,IAAI,IAAI,MAAM;AAC/C,IAAAC,KAAG,sCAAsC,YAAY;AACnD,YAAM,UAAU,MAAM,KAAK;AAC3B,MAAAC,SAAO,QAAQ,aAAa,CAAC,EAAE,UAAU,KAAK;AAAA,IAChD,GAAG,OAAO;AAEV,IAAAD,KAAG,sFAAsF,YAAY;AACnG,YAAM,UAAU,MAAM,KAAK;AAC3B,YAAM,SAAS,oBAAI,IAAwB;AAAA,QACzC,CAAC,aAAa,WAAW,KAAK,CAAC,KAAK,IAAI,IAAI,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC;AAAA,QAC3D,CAAC,yBAAyB,IAAI,YAAY,EAAE,OAAO,mBAAc,CAAC;AAAA,QAClE,CAAC,aAAa,IAAI,WAAW,CAAC,CAAC;AAAA,MACjC,CAAC;AACD,YAAM,OAAO,oBAAI,IAAY;AAC7B,iBAAW,CAAC,KAAK,IAAI,KAAK,QAAQ;AAChC,cAAM,EAAE,IAAI,IAAI,MAAM,QAAQ,IAAI,KAAK,MAAM,0BAA0B;AACvE,aAAK,IAAI,GAAG;AACZ,QAAAC,SAAO,CAAC,GAAI,MAAM,SAAS,GAAG,CAAE,CAAC,EAAE,QAAQ,CAAC,GAAG,IAAI,CAAC;AAAA,MACtD;AACA,MAAAA,SAAO,KAAK,IAAI,EAAE,KAAK,OAAO,IAAI;AAAA,IACpC,GAAG,OAAO;AAEV,IAAAD,KAAG,yDAAyD,YAAY;AACtE,YAAM,UAAU,MAAM,KAAK;AAC3B,YAAM,QAAQ,IAAI,gBAAgB,WAAW,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,0BAA0B;AACxF,YAAM,EAAE,IAAI,IAAI,MAAM,QAAQ;AAAA,QAC5B;AAAA,QACA,WAAW,KAAK,CAAC,CAAC,CAAC;AAAA,QACnB;AAAA,MACF;AACA,MAAAC,SAAO,CAAC,GAAI,MAAM,SAAS,GAAG,CAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;AAAA,IAChD,GAAG,OAAO;AAEV;AAAA,MAAkB;AAAA,MAAM,QAAQ;AAAA,MAAa;AAAA,MAAS,CAAC,YACrD,QAAQ,IAAI,qBAAqB,WAAW,KAAK,CAAC,CAAC,CAAC,GAAG,0BAA0B;AAAA,IACnF;AAAA,EACF,CAAC;AACH;;;ACzDA,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,YAAAC,YAAU,UAAAC,UAAQ,MAAAC,YAAU;AAUrC,IAAM,QAAQ;AAGd,eAAe,cAAc,MAA0C;AACrE,SAAO,KAAK;AAAA,IACV,MAAM;AAAA,IACN,CAAC,QAAkB,KAAmC,QAAQ;AAAA,EAChE;AACF;AAEO,SAAS,oBACd,MACA,OACA,UAAmC,CAAC,GAC9B;AACN,EAAAC,WAAS,6BAA6B,IAAI,IAAI,MAAM;AAClD,IAAAC;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,UAAU,MAAM,MAAM;AAC5B,cAAM,SAAS,MAAM,QAAQ,oBAAoB;AAAA,UAC/C,aAAa;AAAA,UACb,UAAU;AAAA,UACV,UAAU,YAAYC,YAAW,CAAC;AAAA,QACpC,CAAC;AACD,QAAAC,SAAO,OAAO,EAAE,EAAE,WAAW;AAC7B,QAAAA,SAAO,OAAO,YAAY,EAAE,WAAW;AACvC,QAAAA,SAAO,OAAO,WAAW,EAAE,KAAK,GAAI;AACpC,QAAAA,SAAO,OAAO,QAAQ,EAAE,KAAK,KAAK;AAAA,MACpC;AAAA,MACA;AAAA,IACF;AAEA,IAAAF;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,UAAU,MAAM,MAAM;AAC5B,cAAM,SAAS,MAAM,QAAQ,oBAAoB,EAAE,aAAa,KAAK,UAAU,MAAM,CAAC;AACtF,cAAM,SAAS,MAAM,QAAQ,iBAAiB,OAAO,EAAE;AACvD,QAAAE,SAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,CAAC,EAAE,UAAU,MAAM;AAAA,MACrB;AAAA,MACA;AAAA,IACF;AAIA,IAAAF;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,UAAU,MAAM,MAAM;AAC5B,cAAM,SAAS,MAAM,QAAQ,oBAAoB;AAAA,UAC/C,aAAa;AAAA,UACb,UAAU;AAAA,UACV,UAAU,YAAYC,YAAW,CAAC;AAAA,QACpC,CAAC;AACD,YAAI,OAAO,WAAW,YAAa,OAAM,QAAQ,eAAe,OAAO,EAAE;AACzE,cAAM,OAAO,KAAK,MAAM,QAAQ,CAAC;AACjC,cAAM,MAAM,mBAAmBA,YAAW,CAAC;AAE3C,cAAM,QAAQ,MAAM,QAAQ,OAAO,OAAO,IAAI,MAAM,yBAAyB;AAAA,UAC3E,gBAAgB;AAAA,QAClB,CAAC;AACD,cAAM,QAAQ,MAAM,QAAQ,OAAO,OAAO,IAAI,MAAM,yBAAyB;AAAA,UAC3E,gBAAgB;AAAA,QAClB,CAAC;AACD,QAAAC,SAAO,MAAM,UAAU,kDAAkD,EAAE;AAAA,UACzE,MAAM;AAAA,QACR;AACA,QAAAA,SAAO,MAAM,WAAW,EAAE,KAAK,MAAM,WAAW;AAEhD,cAAM,OAAO,MAAM,QAAQ,OAAO,OAAO,IAAI,QAAQ,MAAM,yBAAyB;AAAA,UAClF,gBAAgB,GAAG,GAAG;AAAA,QACxB,CAAC;AACD,QAAAA,SAAO,KAAK,cAAc,MAAM,WAAW,EAAE,KAAK,KAAK;AACvD,cAAM,OAAO,MAAM;AAAA,UACjB,QAAQ,OAAO,OAAO,IAAI,GAAG,yBAAyB,EAAE,gBAAgB,GAAG,GAAG,QAAQ,CAAC;AAAA,QACzF;AACA,QAAAA,SAAO,MAAM,2CAA2C,EAAE,KAAK,yBAAyB;AAAA,MAC1F;AAAA,MACA;AAAA,IACF;AAEA,UAAM,gBAAgB,QAAQ;AAC9B,QAAI,kBAAkB,QAAW;AAC/B,MAAAF;AAAA,QACE;AAAA,QACA,YAAY;AACV,gBAAM,UAAU,MAAM,MAAM;AAC5B,gBAAM,EAAE,SAAS,UAAU,IAAI,cAAc;AAC7C,gBAAM,QAAQ,MAAM,QAAQ,aAAa,SAAS,SAAS;AAC3D,gBAAM,SAAS,MAAM,QAAQ,aAAa,SAAS,SAAS;AAC5D,UAAAE,SAAO,MAAM,EAAE,QAAQ,KAAK;AAAA,QAC9B;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA;AAAA,MAAkB;AAAA,MAAO,QAAQ;AAAA,MAAa;AAAA,MAAyB,CAAC,YACtE,QAAQ,oBAAoB,EAAE,aAAa,KAAK,UAAU,MAAM,CAAC;AAAA,IACnE;AAAA,EACF,CAAC;AACH;;;ACzHA,SAAS,cAAAC,mBAAkB;AAC3B,OAAOC,SAAQ;AACf,SAAS,YAAAC,YAAU,UAAAC,UAAQ,MAAAC,YAAU;AAQrC,eAAe,KAAK,SAAyB,OAAkC;AAC7E,QAAM,YAAY,oBAAoBC,YAAW,CAAC;AAClD,QAAM,SAAmB,CAAC;AAC1B,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,UAAM,EAAE,OAAO,IAAI,MAAM,QAAQ,aAAa;AAAA,MAC5C;AAAA,MACA,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,QAAS,IAAI,IAAK;AAAA,MAClB,OAAO,UAAU,CAAC;AAAA,MAClB,MAAM,QAAQ,CAAC;AAAA,IACjB,CAAC;AACD,WAAO,KAAK,MAAM;AAAA,EACpB;AACA,SAAO;AACT;AAGA,eAAeC,MACb,SACA,OACA,OACA,UAC0B;AAC1B,QAAM,QAAyB,CAAC;AAChC,MAAI;AACJ,KAAG;AACD,UAAM,OAAO,MAAM,QAAQ,kBAAkB,MAAM,WAAW;AAAA,MAC5D;AAAA,MACA,QAAQ,MAAM;AAAA,MACd,GAAI,WAAW,UAAa,EAAE,OAAO;AAAA,IACvC,CAAC;AACD,UAAM,KAAK,IAAI;AACf,aAAS,KAAK,cAAc;AAAA,EAC9B,SAAS,WAAW,UAAa,MAAM,SAAS;AAChD,SAAO;AACT;AAEO,SAAS,mBACd,MACA,OACA,UAA2C,CAAC,GACtC;AACN,EAAAC,WAAS,4BAA4B,IAAI,IAAI,MAAM;AACjD,IAAAC;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,UAAU,MAAM,MAAM;AAC5B,cAAM,YAAY,oBAAoBH,YAAW,CAAC;AAClD,cAAM,EAAE,OAAO,IAAI,MAAM,QAAQ,aAAa;AAAA,UAC5C;AAAA,UACA,YAAY;AAAA,UACZ,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,OAAO;AAAA,UACP,MAAM;AAAA,QACR,CAAC;AACD,QAAAI,SAAO,OAAO,SAAS,EAAE,KAAK,SAAS;AACvC,QAAAA,SAAO,OAAO,MAAM,EAAE,KAAK,CAAC;AAC5B,QAAAA,SAAO,OAAO,EAAE,EAAE,WAAW;AAAA,MAC/B;AAAA,MACA;AAAA,IACF;AAEA,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,UAAU,MAAM,MAAM;AAC5B,cAAM,CAAC,MAAM,IAAI,MAAM,KAAK,SAAS,CAAC;AACtC,cAAM,EAAE,MAAM,IAAI,MAAM,QAAQ,kBAAkB,OAAQ,WAAW;AAAA,UACnE,QAAQ,OAAQ;AAAA,QAClB,CAAC;AACD,QAAAC,SAAO,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,CAAC,OAAQ,EAAE,CAAC;AACnD,QAAAA,SAAO,MAAM,CAAC,EAAG,SAAS,EAAE,KAAK,OAAQ,SAAS;AAAA,MACpD;AAAA,MACA;AAAA,IACF;AAEA,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,UAAU,MAAM,MAAM;AAC5B,cAAM,CAAC,MAAM,IAAI,MAAM,KAAK,SAAS,CAAC;AACtC,cAAM,MAAM,MAAM,QAAQ,mBAAmB,OAAQ,SAAS;AAC9D,QAAAC,SAAO,IAAI,SAAS,EAAE,KAAK,OAAQ,SAAS;AAC5C,QAAAA,SAAO,OAAO,OAAO,IAAI,SAAS,EAAE,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,CAAC,EAAE,KAAK,IAAI,KAAK;AAC9E,YAAI,IAAI,UAAU,EAAG,CAAAA,SAAO,IAAI,OAAO,EAAE,KAAK,CAAC;AAAA,aAC1C;AACH,UAAAA,SAAO,IAAI,OAAO,EAAE,uBAAuB,CAAC;AAC5C,UAAAA,SAAO,IAAI,OAAO,EAAE,oBAAoB,CAAC;AAAA,QAC3C;AACA,YAAI,OAAQ,qBAAqB,WAAY,CAAAA,SAAO,IAAI,KAAK,EAAE,uBAAuB,CAAC;AAAA,MACzF;AAAA,MACA;AAAA,IACF;AAIA,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,UAAU,MAAM,MAAM;AAC5B,cAAME,IAAG;AAAA,UACPA,IAAG;AAAA,YACDA,IAAG,QAAQ,EAAE,KAAK,GAAG,KAAK,EAAE,CAAC;AAAA,YAC7BA,IAAG,QAAQ,EAAE,KAAK,GAAG,KAAK,EAAE,CAAC;AAAA,YAC7B,OAAO,OAAO,UAAU;AACtB,oBAAM,SAAS,MAAM,KAAK,SAAS,QAAQ,KAAK;AAChD,oBAAM,SAAS,OAAO,CAAC,EAAG;AAC1B,oBAAM,WAAW,OAAO,OAAO,CAAC,MAAM,EAAE,qBAAqB,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE;AACpF,oBAAM,QAAQ,MAAMJ;AAAA,gBAClB;AAAA,gBACA,OAAO,CAAC;AAAA,gBACR;AAAA,gBACA,KAAK,KAAK,SAAS,SAAS,KAAK,IAAI;AAAA,cACvC;AACA,oBAAM,SAAS,MAAM,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAE5D,cAAAG,SAAO,IAAI,IAAI,MAAM,EAAE,MAAM,iCAAiC,EAAE,KAAK,OAAO,MAAM;AAClF,cAAAA,SAAO,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,EAAE,QAAQ,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC;AACvD,yBAAW,QAAQ,MAAO,CAAAA,SAAO,KAAK,MAAM,MAAM,EAAE,oBAAoB,KAAK;AAC7E,cAAAA,SAAO,MAAM,IAAI,CAAC,MAAM,EAAE,eAAe,IAAI,CAAC,EAAE;AAAA,gBAC9C,MAAM,IAAI,CAAC,GAAG,MAAM,MAAM,MAAM,SAAS,CAAC;AAAA,cAC5C;AAAA,YACF;AAAA,UACF;AAAA,UACA,EAAE,SAAS,GAAG;AAAA,QAChB;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAEA;AAAA,MAAkB;AAAA,MAAO,QAAQ;AAAA,MAAa;AAAA,MAAuB,CAAC,YACpE,QAAQ,kBAAkB,oBAAoBJ,YAAW,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;AAAA,IAC5E;AAAA,EACF,CAAC;AACH;;;AClJA,SAAS,cAAAM,mBAAkB;AAC3B,OAAOC,SAAQ;AACf,SAAS,YAAAC,YAAU,UAAAC,UAAQ,MAAAC,YAAU;;;ACM9B,SAAS,YAAY,MAAwB;AAClD,SAAO,KAAK,YAAY,EAAE,MAAM,YAAY,KAAK,CAAC;AACpD;AAYO,SAAS,iBAAiB,GAAoC;AACnE,SAAO;AAAA,IACL,IAAI,EAAE;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,MAAM,EAAE;AAAA,MACR,MAAM,EAAE;AAAA,MACR,aAAa,EAAE;AAAA,MACf,QAAQ;AAAA,MACR,aAAa,EAAE;AAAA,MACf,UAAU,EAAE,SAAS,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,MAAM,EAAE,MAAM,YAAY,EAAE,WAAW,EAAE;AAAA,IAC1F;AAAA,EACF;AACF;AAEA,SAAS,SAAS,YAAsB,UAA6B;AACnE,SAAO,WAAW,MAAM,CAAC,MAAM,SAAS,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;AACtE;AAEA,SAAS,YAAY,GAA8B;AACjD,SAAO;AAAA,IACL,GAAG,YAAY,EAAE,IAAI;AAAA,IACrB,GAAG,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,GAAG,YAAY,EAAE,GAAG,GAAG,GAAG,YAAY,EAAE,IAAI,CAAC,CAAC;AAAA,EAC9E;AACF;AAGO,SAAS,aAAa,GAAoB,OAAwB;AACvE,QAAM,IAAI,YAAY,KAAK;AAC3B,SAAO,EAAE,SAAS,KAAK,SAAS,GAAG,CAAC,GAAG,YAAY,CAAC,GAAG,GAAG,YAAY,EAAE,WAAW,CAAC,CAAC;AACvF;AAGO,SAAS,OAAO,GAAoB,OAAuB;AAChE,QAAM,IAAI,YAAY,KAAK;AAC3B,MAAI,SAAS,GAAG,YAAY,EAAE,IAAI,CAAC,EAAG,QAAO;AAC7C,MAAI,SAAS,GAAG,YAAY,CAAC,CAAC,EAAG,QAAO;AACxC,SAAO;AACT;;;AD1BA,SAAS,WAAmB;AAC1B,SAAO,IAAIC,YAAW,EAAE,QAAQ,MAAM,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC;AACxD;AAGA,IAAM,OAAOC,IAAG,OAAO;AAAA,EACrB,MAAMA,IAAG,aAAa,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAAA,EAClD,WAAW;AAAA,EACX,WAAW;AACb,CAAC;AACD,IAAM,QAAQ,CAAC,QAAgBA,IAAG,MAAM,MAAM,EAAE,WAAW,IAAI,CAAC,EAAE,IAAI,CAAC,OAAO,GAAG,KAAK,GAAG,CAAC;AAU1F,IAAM,aAAa;AAEnB,IAAM,aAAuCA,IAAG,OAAO;AAAA,EACrD,MAAM,MAAM,CAAC;AAAA,EACb,aAAa,MAAM,CAAC;AAAA,EACpB,UAAUA,IAAG;AAAA,IACXA,IAAG,OAAO,EAAE,KAAK,MAAM,MAAM,MAAM,CAAC,GAAG,YAAYA,IAAG,QAAQ,EAAE,KAAK,GAAG,KAAK,KAAK,CAAC,EAAE,CAAC;AAAA,IACtF,EAAE,WAAW,EAAE;AAAA,EACjB;AAAA,EACA,YAAYA,IAAG,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC;AACnC,CAAC;AAGD,SAAS,cAAc,OAAyB;AAC9C,SAAO,MAAM,KAAK,EAAE,QAAQ,WAAW,GAAG,CAAC,GAAG,MAAM,IAAI,CAAC,GAAG,MAAM,MAAM,CAAC,CAAC,EAAE;AAC9E;AAEA,SAAS,YAAY,OAAe,KAAiB,GAAW,MAAiC;AAC/F,SAAO;AAAA,IACL,IAAI,GAAG,KAAK,IAAI,CAAC;AAAA,IACjB,MAAM,IAAI,SAAS,KAAK,QAAQ,GAAG,KAAK,IAAI,IAAI,IAAI;AAAA,IACpD,aAAa,IAAI;AAAA,IACjB,UAAU,IAAI;AAAA,IACd,aAAa,IAAI,WAAW,IAAI,CAAC,MAAM,KAAK,CAAC,CAAE;AAAA,EACjD;AACF;AAIA,eAAeC,MACb,SACA,OACA,OACA,iBACA,SACyB;AAEzB,QAAM,WAAW,KAAK,KAAK,kBAAkB,KAAK,IAAI;AACtD,QAAM,QAAwB,CAAC;AAC/B,QAAM,OAAO,oBAAI,IAAY;AAC7B,MAAI;AACJ,aAAS;AACP,UAAM,OAAO,MAAM,QAAQ,OAAO,OAAO;AAAA,MACvC;AAAA,MACA,GAAI,WAAW,UAAa,EAAE,OAAO;AAAA,MACrC,GAAI,YAAY,UAAa,EAAE,QAAQ;AAAA,IACzC,CAAC;AACD,UAAM,KAAK,IAAI;AAGf,UAAM,QAAQ,KAAK,MAAM,IAAI,CAAC,SAAS,KAAK,EAAE,EAAE,OAAO,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;AAC3E,IAAAC,SAAO,OAAO,iBAAiB,KAAK,8BAA8B,MAAM,MAAM,EAAE,EAAE,QAAQ,CAAC,CAAC;AAC5F,eAAW,QAAQ,KAAK,MAAO,MAAK,IAAI,KAAK,EAAE;AAC/C,QAAI,KAAK,eAAe,KAAM,QAAO;AACrC,IAAAA;AAAA,MACE,MAAM;AAAA,MACN,iBAAiB,KAAK,wBAAwB,QAAQ;AAAA,IACxD,EAAE,aAAa,QAAQ;AACvB,aAAS,KAAK;AAAA,EAChB;AACF;AAEA,IAAMC,SAAQ,CAAC,UAA0B,MAAM,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,SAAS,KAAK,EAAE,CAAC;AAG5F,SAAS,gBACP,OACA,UACA,OACA,OACM;AACN,QAAMC,OAAMD,OAAM,KAAK;AACvB,EAAAD,SAAO,IAAI,IAAIE,IAAG,EAAE,MAAM,GAAG,KAAK,gCAAgC,EAAE,KAAKA,KAAI,MAAM;AACnF,EAAAF,SAAO,CAAC,GAAGE,IAAG,EAAE,KAAK,GAAG,GAAG,KAAK,kDAAkD,EAAE;AAAA,IAClF,CAAC,GAAG,QAAQ,EAAE,KAAK;AAAA,EACrB;AACA,aAAW,CAAC,GAAG,IAAI,KAAK,MAAM,QAAQ,GAAG;AACvC,IAAAF,SAAO,KAAK,OAAO,GAAG,KAAK,mBAAmB,IAAI,CAAC,EAAE,EAAE,KAAK,SAAS,MAAM;AAC3E,IAAAA,SAAO,KAAK,MAAM,QAAQ,GAAG,KAAK,UAAU,IAAI,CAAC,gBAAgB,EAAE,oBAAoB,KAAK;AAC5F,IAAAA;AAAA,MACE,KAAK,eAAe;AAAA,MACpB,GAAG,KAAK,gCAAgC,IAAI,CAAC,OAAO,MAAM,MAAM;AAAA,IAClE,EAAE,KAAK,MAAM,MAAM,SAAS,CAAC;AAE7B,QAAI,SAAS,SAAS;AACpB,MAAAA,SAAO,KAAK,MAAM,QAAQ,GAAG,KAAK,UAAU,IAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC;AAAA,EACnF;AACF;AAEA,IAAMG,QAAO;AAEN,SAAS,kBACd,MACA,OACA,UAAiC,CAAC,GAC5B;AACN,QAAM,UAAU,QAAQ,WAAW;AAEnC,EAAAC,WAAS,2BAA2B,IAAI,IAAI,MAAM;AAChD,IAAAC;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,UAAU,MAAM,MAAM;AAC5B,cAAM,SAAS,MAAM,QAAQ,MAAM;AAAA,UACjC,EAAE,IAAI,SAAS,MAAM,WAAW,QAAQ,EAAE,MAAM,SAAS,EAAE;AAAA,UAC3D,EAAE,IAAI,SAAS,MAAM,WAAW,QAAQ,EAAE,MAAM,SAAS,EAAE;AAAA,QAC7D,CAAC;AACD,QAAAL,SAAO,OAAO,OAAO,EAAE,KAAK,CAAC;AAAA,MAC/B;AAAA,MACA;AAAA,IACF;AAEA,IAAAK;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,UAAU,MAAM,MAAM;AAC5B,cAAM,QAAQ,MAAM;AAAA,UAClB,EAAE,IAAI,gBAAgB,MAAM,WAAW,QAAQ,EAAE,MAAM,kBAAkB,EAAE;AAAA,QAC7E,CAAC;AACD,cAAM,SAAS,MAAM,QAAQ,OAAO,YAAY;AAChD,QAAAL,SAAO,OAAO,MAAM,MAAM,EAAE,uBAAuB,CAAC;AACpD,QAAAA,SAAO,OAAO,KAAK,EAAE,uBAAuB,CAAC;AAAA,MAC/C;AAAA,MACA;AAAA,IACF;AAEA,IAAAK;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,UAAU,MAAM,MAAM;AAC5B,cAAM,MAAM,UAAUR,YAAW,CAAC;AAClC,cAAM,QAAQ,MAAM,CAAC,EAAE,IAAI,KAAK,MAAM,WAAW,QAAQ,EAAE,MAAM,YAAY,EAAE,CAAC,CAAC;AACjF,cAAM,QAAQ,OAAO,CAAC,GAAG,CAAC;AAC1B,cAAM,SAAS,MAAM,QAAQ,OAAO,WAAW;AAC/C,QAAAG,SAAO,OAAO,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,GAAG,CAAC,EAAE,cAAc;AAAA,MAC/D;AAAA,MACA;AAAA,IACF;AAEA,IAAAK;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,UAAU,MAAM,MAAM;AAC5B,cAAM,QAAQ,MAAM;AAAA,UAClB,EAAE,IAAI,eAAe,MAAM,WAAW,QAAQ,EAAE,UAAU,SAAS,EAAE;AAAA,UACrE,EAAE,IAAI,eAAe,MAAM,WAAW,QAAQ,EAAE,UAAU,WAAW,EAAE;AAAA,UACvE,EAAE,IAAI,eAAe,MAAM,WAAW,QAAQ,EAAE,UAAU,SAAS,EAAE;AAAA,QACvE,CAAC;AACD,cAAM,QAAQ,MAAM,QAAQ,MAAM,UAAU;AAC5C,QAAAL,SAAO,OAAO,MAAM,KAAK,EAAE,KAAK,QAAQ;AACxC,QAAAA,SAAO,OAAO,MAAM,KAAK,EAAE,KAAK,QAAQ;AACxC,QAAAA,SAAO,MAAM,QAAQ,MAAM,MAAM,CAAC,EAAE,KAAK,IAAI;AAC7C,YAAI,MAAM,OAAO,SAAS,GAAG;AAC3B,UAAAA,SAAO,OAAO,MAAM,OAAO,CAAC,EAAG,KAAK,EAAE,KAAK,QAAQ;AAAA,QACrD;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAEA;AAAA,MAAkB;AAAA,MAAO,QAAQ;AAAA,MAAa;AAAA,MAAY,CAAC,YACzD,QAAQ,OAAO,YAAY,EAAE,OAAO,EAAE,CAAC;AAAA,IACzC;AAEA,IAAAI,WAAS,4CAA4C,MAAM;AAKzD,MAAAC;AAAA,QACE;AAAA,QACA,YAAY;AACV,gBAAM,UAAU,MAAM,MAAM;AAC5B,gBAAMP,IAAG;AAAA,YACPA,IAAG;AAAA;AAAA;AAAA,cAGDA,IAAG,QAAQ,EAAE,KAAK,GAAG,KAAK,GAAG,CAAC;AAAA,cAC9BA,IAAG,MAAMA,IAAG,OAAO,EAAE,OAAO,YAAY,QAAQA,IAAG,OAAO,UAAU,EAAE,CAAC,GAAG;AAAA,gBACxE,WAAW;AAAA,gBACX,MAAM;AAAA,cACR,CAAC;AAAA,cACDA,IAAG,MAAM,MAAM,EAAE,WAAW,EAAE,CAAC;AAAA,cAC/BA,IAAG,QAAQ,EAAE,KAAK,GAAG,KAAK,aAAa,EAAE,CAAC;AAAA,cAC1CA,IAAG,KAAKA,IAAG,QAAQ,CAAC;AAAA,cACpB,OAAO,OAAO,WAAW,YAAY,gBAAgB,aAAa;AAChE,sBAAM,QAAQ,SAAS;AACvB,sBAAM,OAAO,cAAc,KAAK;AAChC,sBAAM,QAAQ,UAAU,IAAI,CAAC,GAAG,MAAM,YAAY,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;AAC1E,oBAAI;AACF,wBAAM,UAAU,MAAM,QAAQ,MAAM,MAAM,IAAI,gBAAgB,CAAC;AAC/D,kBAAAE,SAAO,QAAQ,OAAO,EAAE,KAAK,MAAM,MAAM;AAEzC,wBAAM,UAAU,UAAU;AAAA,oBAAI,CAAC,GAAG,MAChC,EAAE,WAAW,OAAO,MAAM,CAAC,IAAK,YAAY,OAAO,EAAE,QAAQ,GAAG,IAAI;AAAA,kBACtE;AACA,wBAAM,YAAY,QAAQ,OAAO,CAAC,GAAG,MAAM,UAAU,CAAC,EAAG,WAAW,IAAI;AACxE,sBAAI,UAAU,SAAS,EAAG,OAAM,QAAQ,MAAM,UAAU,IAAI,gBAAgB,CAAC;AAE7E,wBAAM,UAAU,QAAQ,OAAO,CAAC,MAAM,SAAS,EAAE,EAAE,CAAC;AACpD,sBAAI,QAAQ,SAAS,EAAG,OAAM,QAAQ,OAAO,QAAQ,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AACrE,wBAAM,OAAO,IAAI,IAAI,QAAQ,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAC7C,wBAAM,OAAO,QAAQ,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;AAElD,wBAAM,QAAQ,CAAC,OAAO,GAAG,UAAU,EAAE,KAAK,GAAG;AAC7C,wBAAM,UAAU,KAAK,OAAO,CAAC,MAAM,aAAa,GAAG,KAAK,CAAC;AACzD,wBAAM,MAAM,MAAMD,MAAK,SAAS,OAAO,OAAO,QAAQ,MAAM;AAC5D;AAAA,oBACE;AAAA,oBACA,QAAQ,IAAI,CAAC,MAAM,EAAE,EAAE;AAAA,oBACvB;AAAA,oBACA,IAAI,KAAK,WAAW,KAAK;AAAA,kBAC3B;AAEA,wBAAM,WAAW,KAAK,cAAc;AACpC,wBAAM,aAAa,QAAQ,OAAO,CAAC,MAAM,EAAE,YAAY,SAAS,QAAQ,CAAC;AACzE,wBAAM,WAAW,MAAMA,MAAK,SAAS,OAAO,OAAO,WAAW,QAAQ;AAAA,oBACpE,aAAa;AAAA,kBACf,CAAC;AACD;AAAA,oBACE;AAAA,oBACA,WAAW,IAAI,CAAC,MAAM,EAAE,EAAE;AAAA,oBAC1B;AAAA,oBACA,IAAI,KAAK,QAAQ,QAAQ,UAAU,KAAK;AAAA,kBAC1C;AAGA,wBAAM,QAAQ,CAAC,GAAGE,OAAM,GAAG,GAAG,GAAGA,OAAM,QAAQ,CAAC;AAChD,kBAAAD;AAAA,oBACE,MAAM,OAAO,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;AAAA,oBACjC;AAAA,kBACF,EAAE,QAAQ,CAAC,CAAC;AAAA,gBACd,UAAE;AACA,wBAAM,QAAQ,OAAO,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAAA,gBAC7C;AAAA,cACF;AAAA,YACF;AAAA,YACA,EAAE,QAAQ;AAAA,UACZ;AAAA,QACF;AAAA,QACAG;AAAA,MACF;AAEA,UAAI,QAAQ,SAAS;AAGnB,QAAAE;AAAA,UACE;AAAA,UACA,YAAY;AACV,kBAAM,UAAU,MAAM,MAAM;AAC5B,kBAAM,SAASP,IAAG,OAAO;AAAA,cACvB,MAAM;AAAA,cACN,QAAQA,IAAG,QAAQ;AAAA,cACnB,OAAOA,IAAG,QAAQ;AAAA,cAClB,WAAWA,IAAG,QAAQ;AAAA,cACtB,oBAAoBA,IAAG,QAAQ,EAAE,KAAK,GAAG,KAAK,GAAG,CAAC;AAAA,YACpD,CAAC;AACD,kBAAMA,IAAG;AAAA,cACPA,IAAG;AAAA,gBACDA,IAAG,MAAM,QAAQ,EAAE,WAAW,GAAG,WAAW,GAAG,CAAC;AAAA,gBAChD;AAAA,gBACAA,IAAG,OAAO,IAAI;AAAA,gBACdA,IAAG,QAAQ,EAAE,KAAK,GAAG,KAAK,GAAG,CAAC;AAAA,gBAC9BA,IAAG,QAAQ,EAAE,KAAK,GAAG,KAAK,GAAG,CAAC;AAAA,gBAC9B,OAAO,WAAW,MAAM,QAAQ,QAAQ,WAAW;AACjD,wBAAM,QAAQ,SAAS;AACvB,wBAAM,OAAO,cAAc,KAAK;AAChC,wBAAM,WAAW,UAAU,IAAI,CAAC,GAAG,MAAuB;AACxD,0BAAM,IAAI,YAAY,OAAO,EAAE,MAAM,GAAG,IAAI;AAC5C,0BAAM,WACJ,EAAE,SAAS,SAAS,IAChB,CAAC,GAAG,EAAE,QAAQ,IACd,CAAC,EAAE,KAAK,MAAM,MAAM,IAAI,YAAY,EAAE,CAAC;AAC7C,wBAAI,EAAE,MAAO,UAAS,CAAC,IAAI,EAAE,GAAG,SAAS,CAAC,GAAI,KAAK,GAAG,IAAI,IAAI;AAC9D,wBAAI,EAAE;AACJ,+BAAS,CAAC,IAAI,EAAE,GAAG,SAAS,CAAC,GAAI,MAAM,GAAG,SAAS,CAAC,EAAG,IAAI,IAAI,IAAI,GAAG;AACxE,2BAAO;AAAA,sBACL,GAAG;AAAA,sBACH,MAAM,EAAE,SAAS,GAAG,EAAE,IAAI,IAAI,IAAI,KAAK,EAAE;AAAA,sBACzC,aAAa,GAAG,EAAE,WAAW,GAAG,IAAI,IAAI,GAAG,OAAO,EAAE,kBAAkB,CAAC;AAAA,sBACvE;AAAA,oBACF;AAAA,kBACF,CAAC;AACD,sBAAI;AACF,0BAAM,QAAQ,MAAM,SAAS,IAAI,gBAAgB,CAAC;AAClD,0BAAM,QAAQ,CAAC,OAAO,MAAM,GAAI,WAAW,OAAO,CAAC,IAAI,CAAC,MAAM,CAAE,EAAE,KAAK,GAAG;AAC1E,0BAAM,OAAO,IAAI,IAAI,SAAS,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AACnD,0BAAM,UAAU,SAAS,OAAO,CAAC,MAAM,aAAa,GAAG,KAAK,CAAC;AAE7D,0BAAM,QAAQG,OAAM,MAAMF,MAAK,SAAS,OAAO,QAAQ,QAAQ,MAAM,CAAC;AACtE,oBAAAC,SAAO,CAAC,GAAG,KAAK,EAAE,KAAK,GAAG,+BAA+B,EAAE;AAAA,sBACzD,QAAQ,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,KAAK;AAAA,oBAChC;AACA,0BAAM,QAAQ,MAAM,IAAI,CAAC,OAAO,OAAO,KAAK,IAAI,EAAE,GAAI,KAAK,CAAC;AAC5D,6BAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,sBAAAA;AAAA,wBACE,MAAM,IAAI,CAAC;AAAA,wBACX,IAAI,KAAK,MAAM,MAAM,IAAI,CAAC,CAAC,UAAU,MAAM,IAAI,CAAC,CAAC,kBAAkB,MAAM,CAAC,CAAC,UAAU,MAAM,CAAC,CAAC;AAAA,sBAC/F,EAAE,uBAAuB,MAAM,CAAC,CAAE;AAAA,oBACpC;AAEA,0BAAM,QAAQC,OAAM,MAAMF,MAAK,SAAS,OAAO,QAAQ,QAAQ,MAAM,CAAC;AACtE,oBAAAC,SAAO,OAAO,IAAI,KAAK,qBAAqB,MAAM,UAAU,MAAM,EAAE,EAAE;AAAA,sBACpE;AAAA,oBACF;AAAA,kBACF,UAAE;AACA,0BAAM,QAAQ,OAAO,SAAS,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAAA,kBAChD;AAAA,gBACF;AAAA,cACF;AAAA,cACA,EAAE,QAAQ;AAAA,YACZ;AAAA,UACF;AAAA,UACAG;AAAA,QACF;AAAA,MACF;AAEA,UAAI,QAAQ,QAAQ;AAGlB,QAAAE;AAAA,UACE;AAAA,UACA,YAAY;AACV,kBAAM,UAAU,MAAM,MAAM;AAC5B,YAAAL,SAAO,QAAQ,aAAa,CAAC,EAAE,UAAU,OAAO;AAChD,kBAAMF,IAAG;AAAA,cACPA,IAAG;AAAA,gBACDA,IAAG,MAAM,YAAY,EAAE,WAAW,KAAK,MAAM,SAAS,CAAC;AAAA,gBACvDA,IAAG,MAAM,MAAM,EAAE,WAAW,EAAE,CAAC;AAAA,gBAC/BA,IAAG,OAAOA,IAAG,QAAQ,EAAE,KAAK,GAAG,KAAK,aAAa,EAAE,CAAC,CAAC;AAAA,gBACrD,OAAO,WAAW,YAAY,mBAAmB;AAC/C,wBAAM,QAAQ,SAAS;AACvB,wBAAM,OAAO,cAAc,KAAK;AAChC,wBAAM,WAAW,UAAU,IAAI,CAAC,GAAG,MAAM,YAAY,OAAO,GAAG,GAAG,IAAI,CAAC;AACvE,sBAAI;AACF,0BAAM,QAAQ,MAAM,SAAS,IAAI,gBAAgB,CAAC;AAClD,0BAAM,QAAQ,CAAC,OAAO,GAAG,UAAU,EAAE,KAAK,GAAG;AAC7C,0BAAM,SAAS,mBAAmB,OAAO,SAAY,KAAK,cAAc;AACxE,0BAAM,UAAU,SAAS;AAAA,sBACvB,CAAC,MACC,aAAa,GAAG,KAAK,MACpB,WAAW,UAAa,EAAE,YAAY,SAAS,MAAM;AAAA,oBAC1D;AACA,0BAAM,WAAW,oBAAI,IAAoB;AACzC,+BAAW,KAAK;AACd,iCAAW,KAAK,EAAE,YAAa,UAAS,IAAI,IAAI,SAAS,IAAI,CAAC,KAAK,KAAK,CAAC;AAE3E,0BAAM,QAAQ,MAAM,QAAQ,MAAM,eAAe;AAAA,sBAC/C;AAAA,sBACA,GAAI,WAAW,UAAa,EAAE,SAAS,EAAE,aAAa,OAAO,EAAE;AAAA,oBACjE,CAAC;AACD,0BAAM,QAAQ,cAAc,KAAK,IAAI,WAAW,SAAY,KAAK,OAAO,MAAM,EAAE;AAChF,oBAAAE;AAAA,sBACE,OAAO,YAAY,MAAM,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;AAAA,sBAC9D;AAAA,oBACF,EAAE,QAAQ,OAAO,YAAY,QAAQ,CAAC;AACtC,0BAAM,UAAU,CAAC,GAAG,SAAS,QAAQ,CAAC,EACnC,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI,EAAE,EACtE,IAAI,CAAC,CAAC,KAAK,MAAM,KAAK;AACzB,oBAAAA;AAAA,sBACE,MAAM,OAAO,IAAI,CAAC,MAAM,EAAE,KAAK;AAAA,sBAC/B,GAAG,KAAK;AAAA,oBACV,EAAE,QAAQ,OAAO;AAAA,kBACnB,UAAE;AACA,0BAAM,QAAQ,OAAO,SAAS,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAAA,kBAChD;AAAA,gBACF;AAAA,cACF;AAAA,cACA,EAAE,QAAQ;AAAA,YACZ;AAAA,UACF;AAAA,UACAG;AAAA,QACF;AAAA,MACF;AAKA,MAAAC,WAAS,iBAAiB,MAAM;AAC9B,cAAM,WAAWN,IAAG;AAAA,UAClB;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AACA,cAAM,WAAWA,IAAG;AAAA,UAClBA,IAAG,OAAO,EAAE,MAAM,UAAU,WAAW,EAAE,CAAC;AAAA,UAC1C;AAAA,UACA;AAAA,UACA,KAAK,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC;AAAA,QACjC;AAEA,cAAM,UAAUA,IAAG,MAAM,UAAU,EAAE,WAAW,EAAE,CAAC,EAAE,IAAI,CAAC,OAAO,GAAG,KAAK,EAAE,CAAC;AAC5E,cAAM,WAAW,IAAI,OAAO,IAAI;AAChC,cAAM,QAAoB,EAAE,MAAM,OAAO,aAAa,KAAK,UAAU,CAAC,GAAG,YAAY,CAAC,CAAC,EAAE;AAEzF,QAAAO;AAAA,UACE;AAAA,UACA,YAAY;AACV,kBAAM,UAAU,MAAM,MAAM;AAC5B,kBAAMP,IAAG;AAAA,cACPA,IAAG;AAAA,gBACDA,IAAG,MAAM,YAAY,EAAE,WAAW,GAAG,CAAC;AAAA,gBACtC;AAAA,gBACA,OAAO,WAAW,QAAQ;AACxB,wBAAM,QAAQ,SAAS;AACvB,wBAAM,OAAO,cAAc,KAAK;AAChC,wBAAM,WAAW,UAAU,IAAI,CAAC,GAAG,MAAM,YAAY,OAAO,GAAG,GAAG,IAAI,CAAC;AACvE,sBAAI;AACF,0BAAM,QAAQ,MAAM,SAAS,IAAI,gBAAgB,CAAC;AAClD,0BAAM,QAAQ,GAAG,KAAK,IAAI,GAAG;AAC7B,0BAAM,WAAW,SAAS,OAAO,CAAC,MAAM,aAAa,GAAG,KAAK,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE;AAC/E,0BAAM,SAAS,MAAM,QAAQ,OAAO,OAAO,EAAE,OAAO,IAAI,CAAC;AACzD,oBAAAE,SAAO,OAAO,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,KAAK,GAAG,KAAK,UAAU,KAAK,CAAC,EAAE;AAAA,sBAClE,SAAS,KAAK;AAAA,oBAChB;AACA,oBAAAA,SAAO,OAAO,OAAO,KAAK,UAAU,KAAK,CAAC,EAAE,KAAK,SAAS,MAAM;AAAA,kBAClE,UAAE;AACA,0BAAM,QAAQ,OAAO,SAAS,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAAA,kBAChD;AAAA,gBACF;AAAA,cACF;AAAA,cACA;AAAA,gBACE,SAAS,UAAU;AAAA;AAAA;AAAA,gBAGnB,UAAU;AAAA,kBACR,CAAC,CAAC,KAAK,GAAG,QAAQ;AAAA,kBAClB,CAAC,CAAC,EAAE,GAAG,OAAO,aAAa,KAAK,QAAQ,GAAG,CAAC,GAAG,EAAE;AAAA,kBACjD,CAAC,CAAC,EAAE,GAAG,OAAO,aAAa,SAAS,CAAC,GAAG,QAAQ;AAAA,gBAClD;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,UACAG;AAAA,QACF;AAEA,QAAAE;AAAA,UACE;AAAA,UACA,YAAY;AACV,kBAAM,UAAU,MAAM,MAAM;AAC5B,kBAAM,QAAQ,SAAS;AACvB,kBAAM,WAA8B,MAAM,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,GAAG,OAAO;AAAA,cACvE,IAAI,GAAG,KAAK,IAAI,CAAC;AAAA,cACjB,MAAM,GAAG,KAAK;AAAA,cACd,aAAa;AAAA,cACb,UAAU,CAAC,EAAE,KAAK,MAAM,MAAM,KAAK,YAAY,IAAI,CAAC;AAAA,cACpD,aAAa,CAAC;AAAA,YAChB,EAAE;AACF,kBAAM,QAAQ,MAAM,SAAS,IAAI,gBAAgB,CAAC;AAClD,gBAAI;AACF,oBAAM,WAAWP,IACd;AAAA,gBACCA,IAAG;AAAA,kBACD;AAAA,kBACAA,IAAG,OAAO,EAAE,MAAM,UAAU,WAAW,EAAE,CAAC;AAAA,kBAC1CA,IAAG,aAAa,KAAK,KAAM,IAAI;AAAA,gBACjC;AAAA,gBACA,EAAE,WAAW,EAAE;AAAA,cACjB,EACC,IAAI,CAAC,OAAO,GAAG,KAAK,EAAE,CAAC,EACvB,OAAO,CAAC,MAAM,YAAY,CAAC,EAAE,WAAW,CAAC;AAC5C,oBAAMA,IAAG;AAAA,gBACPA,IAAG,cAAc,UAAU,OAAO,QAAQ;AACxC,wBAAM,SAAS,MAAM,QAAQ,OAAO,KAAK,EAAE,OAAO,GAAG,CAAC;AACtD,kBAAAE,SAAO,OAAO,MAAM,QAAQ,KAAK,UAAU,GAAG,CAAC,EAAE,KAAK,CAAC;AACvD,kBAAAA,SAAO,OAAO,OAAO,KAAK,UAAU,GAAG,CAAC,EAAE,KAAK,CAAC;AAChD,kBAAAA,SAAO,OAAO,YAAY,KAAK,UAAU,GAAG,CAAC,EAAE,SAAS;AAAA,gBAC1D,CAAC;AAAA,gBACD;AAAA,kBACE,SAAS,UAAU;AAAA,kBACnB,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC,KAAK,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,MAAG,CAAC;AAAA,gBAC7D;AAAA,cACF;AAAA,YACF,UAAE;AACA,oBAAM,QAAQ,OAAO,SAAS,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAAA,YAChD;AAAA,UACF;AAAA,UACAG;AAAA,QACF;AAEA,QAAAE;AAAA,UACE;AAAA,UACA,YAAY;AACV,kBAAM,UAAU,MAAM,MAAM;AAC5B,kBAAM,QAAQ,SAAS;AACvB,kBAAM,WAA8B,MAAM,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,GAAG,OAAO;AAAA,cACvE,IAAI,GAAG,KAAK,IAAI,CAAC;AAAA,cACjB,MAAM,GAAG,KAAK,WAAW,CAAC;AAAA,cAC1B,aAAa;AAAA,cACb,UAAU,CAAC;AAAA,cACX,aAAa,CAAC;AAAA,YAChB,EAAE;AACF,kBAAM,QAAQ,MAAM,SAAS,IAAI,gBAAgB,CAAC;AAClD,gBAAI;AAEF,oBAAM,QAAQ,MAAM,QAAQ,OAAO,OAAO,EAAE,OAAO,EAAE,CAAC;AACtD,cAAAL,SAAO,MAAM,KAAK,EAAE,KAAK,SAAS,MAAM;AACxC,cAAAA,SAAO,MAAM,YAAY,2CAA2C,EAAE,IAAI,SAAS;AAEnF,yBAAW,UAAU,CAAC,gBAAgB,OAAO,IAAI,GAAG;AAClD,sBAAMA;AAAA,kBACJ,QAAQ,OAAO,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC;AAAA,kBAC1C,UAAU,MAAM;AAAA,gBAClB,EAAE,QAAQ,QAAQ;AAAA,cACpB;AACA,kBAAI,QAAQ,aAAa,QAAW;AAClC,2BAAW,UAAU,CAAC,IAAI,KAAK,KAAK,IAAI,GAAG;AACzC,wBAAMA;AAAA,oBACJ,QAAQ,OAAO,OAAO,EAAE,OAAO,GAAG,QAAQ,QAAQ,SAAS,MAAM,EAAE,CAAC;AAAA,oBACpE,oBAAoB,MAAM;AAAA,kBAC5B,EAAE,QAAQ,QAAQ;AAAA,gBACpB;AAAA,cACF;AAEA,oBAAM,OAAO,SAAS,MAAM,GAAG,CAAC;AAChC,oBAAM,QAAQ,OAAO,SAAS,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AACvD,oBAAM,QAAQ,MAAM,QAAQ,OAAO,OAAO,EAAE,OAAO,GAAG,QAAQ,MAAM,WAAY,CAAC;AACjF,cAAAA,SAAO,MAAM,MAAM,MAAM,EAAE,KAAK,CAAC;AACjC,cAAAA,SAAO,MAAM,UAAU,EAAE,SAAS;AAClC,cAAAA,SAAO,MAAM,KAAK,EAAE,KAAK,KAAK,MAAM;AAEpC,kBAAI,QAAQ,aAAa,QAAW;AAClC,2BAAW,UAAU,CAAC,KAAK,QAAQ,KAAK,SAAS,CAAC,GAAG;AACnD,wBAAM,OAAO,MAAM,QAAQ,OAAO,OAAO;AAAA,oBACvC,OAAO;AAAA,oBACP,QAAQ,QAAQ,SAAS,MAAM;AAAA,kBACjC,CAAC;AACD,kBAAAA,SAAO,KAAK,MAAM,QAAQ,UAAU,MAAM,EAAE,EAAE,KAAK,CAAC;AACpD,kBAAAA,SAAO,KAAK,YAAY,UAAU,MAAM,EAAE,EAAE,SAAS;AACrD,kBAAAA,SAAO,KAAK,OAAO,UAAU,MAAM,EAAE,EAAE,KAAK,KAAK,MAAM;AAAA,gBACzD;AAAA,cACF;AAAA,YACF,UAAE;AACA,oBAAM,QAAQ,OAAO,SAAS,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAAA,YAChD;AAAA,UACF;AAAA,UACAG;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AACH;;;AEzmBA,SAAS,YAAAG,YAAU,UAAAC,UAAQ,MAAAC,YAAU;AAIrC,IAAM,UAAU;AAAA,EACd,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,WAAW;AAAA,EACX,aAAa;AAAA,EACb,UAAU;AACZ;AAEO,SAAS,oBACd,MACA,OACA,UAA4C,CAAC,GACvC;AACN,EAAAC,WAAS,6BAA6B,IAAI,IAAI,MAAM;AAClD,IAAAC;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,UAAU,MAAM,MAAM;AAC5B,cAAM,QAAQ,MAAM,QAAQ,KAAK,OAAO;AACxC,QAAAC,SAAO,MAAM,QAAQ,KAAK,CAAC,EAAE,KAAK,IAAI;AACtC,YAAI,MAAM,SAAS,GAAG;AACpB,gBAAM,OAAO,MAAM,CAAC;AACpB,UAAAA,SAAO,OAAO,KAAK,WAAW,EAAE,KAAK,QAAQ;AAC7C,UAAAA,SAAO,OAAO,KAAK,OAAO,EAAE,KAAK,QAAQ;AACzC,UAAAA,SAAO,OAAO,KAAK,aAAa,EAAE,KAAK,QAAQ;AAAA,QACjD;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAEA,sBAAkB,OAAO,QAAQ,aAAa,UAAU,CAAC,YAAY,QAAQ,KAAK,OAAO,CAAC;AAAA,EAC5F,CAAC;AACH;;;ACpCA,SAAS,YAAAC,YAAU,UAAAC,UAAQ,MAAAC,YAAU;AAIrC,IAAMC,WAAU;AAAA,EACd,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,OAAO,CAAC,EAAE,aAAa,KAAM,KAAK,EAAE,CAAC;AACvC;AAEO,SAAS,eACd,MACA,OACA,UAAuC,CAAC,GAClC;AACN,EAAAC,WAAS,wBAAwB,IAAI,IAAI,MAAM;AAC7C,IAAAC;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,UAAU,MAAM,MAAM;AAC5B,cAAM,SAAS,MAAM,QAAQ,UAAUF,QAAO;AAC9C,QAAAG,SAAO,OAAO,OAAO,aAAa,EAAE,KAAK,QAAQ;AACjD,QAAAA,SAAO,OAAO,aAAa,EAAE,uBAAuB,CAAC;AACrD,QAAAA,SAAO,OAAO,WAAW,EAAE,aAAa,CAAC;AACzC,QAAAA,SAAO,OAAO,OAAO,YAAY,CAAC,EAAG,QAAQ,EAAE,KAAK,QAAQ;AAAA,MAC9D;AAAA,MACA;AAAA,IACF;AAEA,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,UAAU,MAAM,MAAM;AAC5B,cAAM,SAAS,MAAM,QAAQ,UAAU;AAAA,UACrC,GAAGF;AAAA,UACH,OAAO,CAAC,EAAE,aAAa,GAAG,KAAK,EAAE,CAAC;AAAA,QACpC,CAAC;AACD,QAAAG,SAAO,OAAO,aAAa,EAAE,KAAK,CAAC;AAAA,MACrC;AAAA,MACA;AAAA,IACF;AAEA;AAAA,MAAkB;AAAA,MAAO,QAAQ;AAAA,MAAa;AAAA,MAAe,CAAC,YAC5D,QAAQ,UAAUH,QAAO;AAAA,IAC3B;AAAA,EACF,CAAC;AACH;;;AC7CA,IAAM,SAAiB;AAAA,EACrB,OAAO,MAAM;AAAA,EACb,OAAO,MAAM;AAAA,EACb,MAAM,MAAM;AAAA,EACZ,MAAM,MAAM;AAAA,EACZ,OAAO,MAAM;AAAA,EACb,OAAO,MAAM;AACf;AAMO,SAAS,eACd,MACA,QACA,MAAyB,CAAC,GACV;AAChB,SAAO,EAAE,MAAM,QAAQ,QAAQ,QAAQ,IAAI;AAC7C;;;ACrBA,SAAS,YAAAI,YAAU,UAAAC,UAAQ,MAAAC,YAAU;AAIrC,IAAM,aAAiC;AAAA,EACrC,WAAW;AAAA,IACT,KAAK,EAAE,UAAU,KAAK,QAAQ,MAAM,QAAQ,QAAQ;AAAA,EACtD;AAAA,EACA,MAAM;AAAA,EACN,SAAS;AAAA,IACP,MAAM;AAAA,IACN,uBAAuB;AAAA,IACvB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AACF;AAEO,SAAS,oBACd,MACA,OACA,UAA4C,CAAC,GACvC;AACN,EAAAC,WAAS,6BAA6B,IAAI,IAAI,MAAM;AAClD,IAAAC;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,UAAU,MAAM,MAAM;AAC5B,cAAM,SAAS,MAAM,QAAQ,SAAS,UAAU;AAChD,QAAAC,SAAO,OAAO,OAAO,KAAK,EAAE,KAAK,SAAS;AAC1C,QAAAA,SAAO,MAAM,QAAQ,OAAO,MAAM,CAAC,EAAE,KAAK,IAAI;AAAA,MAChD;AAAA,MACA;AAAA,IACF;AAEA,IAAAD;AAAA,MACE;AAAA,MACA,YAAY;AACV,cAAM,UAAU,MAAM,MAAM;AAC5B,cAAM,SAAS,MAAM,QAAQ,SAAS,CAAC,CAAuB;AAC9D,YAAI,CAAC,OAAO,OAAO;AACjB,UAAAC,SAAO,OAAO,OAAO,MAAM,EAAE,gBAAgB,CAAC;AAAA,QAChD;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAEA;AAAA,MAAkB;AAAA,MAAO,QAAQ;AAAA,MAAa;AAAA,MAAc,OAAO,YACjE,QAAQ,SAAS,UAAU;AAAA,IAC7B;AAAA,EACF,CAAC;AACH;;;AClDA,SAAS,YAAAC,YAAU,MAAAC,MAAI,UAAAC,gBAAc;AAerC,SAASC,WAAU,IAAyB;AAC1C,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,SAAS,EAAE,GAAG;AAAA,IACd,UAAU,EAAE,SAAS,QAAQ,aAAa,eAAe,SAAS,QAAQ;AAAA,EAC5E;AACF;AAEO,SAAS,sBAAsB,MAAuC;AAC3E,EAAAH,WAAS,mCAAmC,MAAM;AAChD,IAAAC,KAAG,kEAAkE,YAAY;AAC/E,YAAM,MAAM,MAAM,KAAK,MAAM;AAC7B,YAAMG,SAAQD,WAAU,eAAe;AACvC,YAAM,IAAI,OAAOC,MAAK;AACtB,YAAM,IAAI,OAAOA,MAAK;AACtB,MAAAF,SAAO,MAAM,IAAI,iBAAiB,CAAC,EAAE,KAAK,CAAC;AAAA,IAC7C,CAAC;AAED,IAAAD,KAAG,6CAA6C,YAAY;AAC1D,YAAM,MAAM,MAAM,KAAK,MAAM;AAC7B,YAAM,IAAI,OAAOE,WAAU,kBAAkB,CAAC;AAC9C,YAAM,IAAI,OAAOA,WAAU,kBAAkB,CAAC;AAC9C,MAAAD,SAAO,MAAM,IAAI,iBAAiB,CAAC,EAAE,KAAK,CAAC;AAAA,IAC7C,CAAC;AAED,IAAAD,KAAG,kEAAkE,YAAY;AAC/E,YAAM,MAAM,MAAM,KAAK,MAAM;AAC7B,YAAM,SAAS,CAACE,WAAU,WAAW,GAAGA,WAAU,WAAW,GAAGA,WAAU,WAAW,CAAC;AACtF,iBAAW,KAAK,OAAQ,OAAM,IAAI,OAAO,CAAC;AAC1C,iBAAW,KAAK,OAAQ,OAAM,IAAI,OAAO,CAAC;AAC1C,MAAAD,SAAO,MAAM,IAAI,iBAAiB,CAAC,EAAE,KAAK,CAAC;AAAA,IAC7C,CAAC;AAAA,EACH,CAAC;AACH;;;ACPA,eAAe,cAAc,KAAkC;AAC7D,QAAM,WAAW,MAAM,MAAM,GAAG;AAChC,MAAI,CAAC,SAAS,GAAI,OAAM,IAAI,MAAM,OAAO,GAAG,aAAa,SAAS,MAAM,EAAE;AAC1E,SAAO,IAAI,WAAW,MAAM,SAAS,YAAY,CAAC;AACpD;AAEA,IAAM,SAAS;AAAA,EACb,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,UAAU;AAAA,EACV,KAAK;AAAA,EACL,IAAI;AAAA,EACJ,eAAe;AAAA,EACf,UAAU;AAAA,EACV,OAAO,CAAC,MAAM,OAAO,UAAU,CAAC,MAC9B,wBAAwB,MAAM,OAAwD;AAAA,IACpF,UAAU;AAAA,IACV,GAAG;AAAA,EACL,CAAgC;AACpC;AAGO,IAAM,iBAA+D;","names":["describe","expect","it","describe","it","expect","describe","expect","it","describe","it","expect","describe","expect","it","describe","expect","it","describe","it","expect","fc","expect","it","SLOW","it","fc","expect","SLOW","using","rejection","putAll","walk","params","describe","it","expect","describe","expect","it","describe","it","expect","randomUUID","describe","expect","it","fc","describe","expect","it","SLOW","ids","e","SLOW","randomUUID","delay","using","describe","it","expect","ids","describe","expect","it","describe","it","expect","randomUUID","describe","expect","it","describe","it","randomUUID","expect","randomUUID","fc","describe","expect","it","randomUUID","walk","describe","it","expect","fc","randomUUID","fc","describe","expect","it","randomUUID","fc","walk","expect","idsOf","ids","SLOW","describe","it","describe","expect","it","describe","it","expect","describe","expect","it","REQUEST","describe","it","expect","describe","expect","it","describe","it","expect","describe","it","expect","makeEvent","event"]}
|
|
1
|
+
{"version":3,"sources":["../src/analytics.ts","../src/common.ts","../src/document-store.ts","../src/document-store-model.ts","../src/document-store-replace.ts","../src/email.ts","../src/event-bus.ts","../src/event-bus-delivery.ts","../src/event-bus-failure.ts","../src/media-storage.ts","../src/payments.ts","../src/reviews.ts","../src/search.ts","../src/search-oracle.ts","../src/shipping.ts","../src/tax.ts","../src/adapter-context.ts","../src/webhook.ts","../src/security.ts","../src/projection.ts","../src/index.ts"],"sourcesContent":["import { describe, expect, it } from 'vitest'\nimport type { AnalyticsAdapter } from '@nymbalhq/types'\nimport { CASE_MS, healthAndDowntime, type Build, type ContractOptions } from './common.js'\n\nexport function runAnalyticsContract(\n name: string,\n build: Build<AnalyticsAdapter>,\n options: ContractOptions<AnalyticsAdapter> = {},\n): void {\n describe(`AnalyticsAdapter contract: ${name}`, () => {\n it(\n 'track resolves without throwing',\n async () => {\n const adapter = await build()\n await expect(\n adapter.track('product_viewed', { productId: 'prod-1', source: 'test' }),\n ).resolves.not.toThrow()\n },\n CASE_MS,\n )\n\n it(\n 'identify resolves without throwing',\n async () => {\n const adapter = await build()\n await expect(\n adapter.identify('user-1', { email: 'test@example.com', plan: 'free' }),\n ).resolves.not.toThrow()\n },\n CASE_MS,\n )\n\n healthAndDowntime(build, options.unreachable, 'track()', (adapter) =>\n adapter.track('product_viewed', { productId: 'prod-1', source: 'contract-down' }),\n )\n })\n}\n","import { describe, expect, it } from 'vitest'\nimport type { HealthReport } from '@nymbalhq/types'\n\n/** How long a health check, or a call on an unreachable dependency, may take to settle. */\nexport const BOUND_MS = 6000\n\n/** A case's own timeout: the bound, plus room for `build` and the case's own calls. */\nexport const CASE_MS = 30_000\n\n/** Makes the adapter under test: a fresh, initialized one each time it is called. */\nexport type Build<A> = () => A | Promise<A>\n\n/** The options every suite takes. */\nexport interface ContractOptions<A = unknown> {\n /**\n * An adapter whose dependency cannot be reached. Given, the suite adds the downtime cases: `healthCheck()` reports\n * `down`, and one representative operation rejects, each within 6 s. For a client that connects when it is built,\n * build it while the dependency is up and then take the dependency away (close a proxy in front of it).\n */\n unreachable?: Build<A>\n}\n\ninterface Checkable {\n healthCheck?: () => Promise<HealthReport>\n}\n\ntype Settled<T> =\n | { state: 'resolved'; value: T; ms: number }\n | { state: 'rejected'; error: unknown; ms: number }\n | { state: 'hung'; ms: number }\n\n/** How `call` settled within `ms`: a synchronous throw is a rejection, and a call still pending is `hung`. */\nexport async function settle<T>(call: () => T | Promise<T>, ms = BOUND_MS): Promise<Settled<T>> {\n const started = Date.now()\n let timer: ReturnType<typeof setTimeout> | undefined\n const hung = new Promise<{ state: 'hung' }>((resolve) => {\n timer = setTimeout(() => resolve({ state: 'hung' }), ms)\n })\n try {\n const outcome = await Promise.race([\n Promise.resolve()\n .then(call)\n .then(\n (value) => ({ state: 'resolved' as const, value }),\n (error: unknown) => ({ state: 'rejected' as const, error }),\n ),\n hung,\n ])\n return { ...outcome, ms: Date.now() - started }\n } finally {\n clearTimeout(timer)\n }\n}\n\n/** Closes what has a `close()`, without letting a close that hangs (a client on a dead host) hold the case. */\nexport async function release(target: unknown): Promise<void> {\n const close = (target as { close?: unknown } | null)?.close\n if (typeof close !== 'function') return\n let timer: ReturnType<typeof setTimeout> | undefined\n await Promise.race([\n Promise.resolve()\n .then(() => (close as () => unknown).call(target))\n .catch(() => undefined),\n new Promise<void>((resolve) => {\n timer = setTimeout(resolve, 5000)\n }),\n ])\n clearTimeout(timer)\n}\n\nfunction healthOf(target: Checkable): Promise<Settled<HealthReport>> {\n expect(\n typeof target.healthCheck,\n 'healthCheck() is missing: certification needs it, though the type keeps it optional',\n ).toBe('function')\n return settle(() => target.healthCheck!())\n}\n\n/** `healthCheck()` resolves `healthy` or `degraded` within the bound. */\nexport async function expectHealthy(target: Checkable): Promise<void> {\n const health = await healthOf(target)\n expect(health.state, `healthCheck() did not resolve within ${BOUND_MS} ms`).toBe('resolved')\n const status = health.state === 'resolved' ? health.value?.status : undefined\n expect(['healthy', 'degraded'], `healthCheck() reported ${String(status)}`).toContain(status)\n}\n\n/** `healthCheck()` resolves `down` within the bound. */\nexport async function expectDown(target: Checkable): Promise<void> {\n const health = await healthOf(target)\n expect(health.state, `healthCheck() did not resolve within ${BOUND_MS} ms`).toBe('resolved')\n expect(health.state === 'resolved' ? health.value?.status : undefined).toBe('down')\n}\n\n/** `call` rejects within the bound: it neither succeeds on a dead dependency nor hangs on one. */\nexport async function expectRejects(call: () => Promise<unknown>): Promise<void> {\n const outcome = await settle(call)\n expect(\n outcome.state,\n outcome.state === 'hung' ? `still pending after ${BOUND_MS} ms` : 'it succeeded',\n ).toBe('rejected')\n}\n\n/** Builds the adapter, runs `body` on it, and closes it when it has a `close()`. */\nexport async function using<A, T>(build: Build<A>, body: (adapter: A) => Promise<T>): Promise<T> {\n const adapter = await build()\n try {\n return await body(adapter)\n } finally {\n await release(adapter)\n }\n}\n\n/**\n * The health case every suite has, and, when `unreachable` is given, the downtime cases: health `down`, and\n * `operation` (named by `label`) rejecting, each within the bound.\n */\nexport function healthAndDowntime<A extends object>(\n build: Build<A>,\n unreachable: Build<A> | undefined,\n label: string,\n operation: (adapter: A) => Promise<unknown>,\n): void {\n it(\n 'health: healthCheck() resolves healthy or degraded within 6 s',\n () => using(build, (adapter) => expectHealthy(adapter as Checkable)),\n CASE_MS,\n )\n if (unreachable === undefined) return\n describe('unreachable dependency', () => {\n it(\n 'down: healthCheck() reports down within 6 s',\n () => using(unreachable, (adapter) => expectDown(adapter as Checkable)),\n CASE_MS,\n )\n it(\n `down: ${label} rejects within 6 s instead of hanging`,\n () => using(unreachable, (adapter) => expectRejects(() => operation(adapter))),\n CASE_MS,\n )\n })\n}\n","import { describe, expect, it } from 'vitest'\nimport type { DocumentStoreAdapter, QueryParams } from '@nymbalhq/types'\nimport { CASE_MS, healthAndDowntime, type Build, type ContractOptions } from './common.js'\nimport { documentStoreModelCases } from './document-store-model.js'\nimport { documentStoreReplaceCases } from './document-store-replace.js'\n\nexport interface DocumentStoreContractOptions extends ContractOptions<DocumentStoreAdapter> {\n /** A clock the store reads: the TTL cases advance it instead of waiting a one-second TTL out. */\n clock?: { advance(ms: number): void | Promise<void> }\n /** Two stores on one backend under different prefixes, for the prefix isolation cases. */\n isolation?: () => Promise<[DocumentStoreAdapter, DocumentStoreAdapter]>\n}\n\ntype Make = Build<DocumentStoreAdapter>\n\ninterface Doc {\n id: string\n part: string\n v?: unknown\n nested?: { v?: unknown }\n}\n\nconst SLOW = 30_000\n\nasync function using(make: Make, body: (store: DocumentStoreAdapter) => Promise<void>) {\n const store = await make()\n try {\n await body(store)\n } finally {\n await store.close()\n }\n}\n\nasync function rejection(promise: Promise<unknown>): Promise<unknown> {\n return promise.then(\n () => null,\n (error: unknown) => error ?? new Error('rejected with nothing'),\n )\n}\n\nasync function putAll(store: DocumentStoreAdapter, collection: string, docs: Doc[]) {\n for (const doc of docs) await store.put(collection, doc.id, doc)\n}\n\nconst ids = (docs: Doc[]): string[] => docs.map((d) => d.id)\n\nasync function walk(\n store: DocumentStoreAdapter,\n collection: string,\n params: QueryParams,\n between?: (page: number) => Promise<void>,\n): Promise<Doc[][]> {\n const pages: Doc[][] = []\n let cursor: string | undefined\n do {\n const page = await store.query<Doc>(collection, {\n ...params,\n ...(cursor !== undefined && { cursor }),\n })\n pages.push(page.items)\n cursor = page.nextCursor ?? undefined\n if (between !== undefined) await between(pages.length)\n } while (cursor !== undefined && pages.length < 100)\n return pages\n}\n\n/**\n * The document store contract every implementation runs: the reference order and filter of\n * `compareDocumentValues` and `matchesSortKey`, cursors that survive a delete, TTL, conditional puts, batches,\n * isolation between collections (and, given `isolation`, between prefixes), the same as a property against the\n * reference model, an atomic `replaceCollection`, and health (and, given `unreachable`, downtime). `make` returns an\n * empty store each time.\n */\nexport function runDocumentStoreContract(\n name: string,\n make: Make,\n opts: DocumentStoreContractOptions = {},\n): void {\n describe(`DocumentStoreAdapter contract: ${name}`, () => {\n it(\n 'get is null for a missing key; put then get round-trips; a second put overwrites',\n async () => {\n await using(make, async (store) => {\n expect(await store.get('col', 'missing')).toBeNull()\n await store.put('col', 'k1', { name: 'test', value: 42, nested: { list: [1, 'two'] } })\n expect(await store.get('col', 'k1')).toEqual({\n name: 'test',\n value: 42,\n nested: { list: [1, 'two'] },\n })\n await store.put('col', 'k1', { v: 2 })\n expect(await store.get('col', 'k1')).toEqual({ v: 2 })\n })\n },\n CASE_MS,\n )\n\n it(\n 'delete removes the document, and deleting a missing key does not throw',\n async () => {\n await using(make, async (store) => {\n await store.put('col', 'k1', { v: 1 })\n await store.delete('col', 'k1')\n expect(await store.get('col', 'k1')).toBeNull()\n await expect(store.delete('col', 'nope')).resolves.toBeUndefined()\n })\n },\n CASE_MS,\n )\n\n it(\n \"query narrows by partition, and '*' returns the whole collection\",\n async () => {\n await using(make, async (store) => {\n await putAll(store, 'col', [\n { id: 'a', part: 'p' },\n { id: 'b', part: 'q' },\n { id: 'c', part: 'p' },\n ])\n const p = await store.query<Doc>('col', { partitionKey: { field: 'part', value: 'p' } })\n expect(ids(p.items).sort()).toEqual(['a', 'c'])\n const all = await store.query<Doc>('col', { partitionKey: { field: 'part', value: '*' } })\n expect(ids(all.items).sort()).toEqual(['a', 'b', 'c'])\n expect(all.nextCursor).toBeNull()\n })\n },\n CASE_MS,\n )\n\n it(\n \"sortKey eq is strict (1 is not '1', 'a' is not 'A'); gt, lt and between follow compareDocumentValues\",\n async () => {\n await using(make, async (store) => {\n await putAll(store, 'col', [\n { id: 'n1', part: 'p', v: 1 },\n { id: 's1', part: 'p', v: '1' },\n { id: 'n5', part: 'p', v: 5 },\n { id: 'sa', part: 'p', v: 'a' },\n { id: 'sA', part: 'p', v: 'A' },\n { id: 'nul', part: 'p', v: null },\n ])\n const where = async (sortKey: NonNullable<QueryParams['sortKey']>) =>\n ids(\n (\n await store.query<Doc>('col', {\n partitionKey: { field: 'part', value: 'p' },\n sortKey,\n })\n ).items,\n ).sort()\n expect(await where({ field: 'v', operator: 'eq', value: 1 })).toEqual(['n1'])\n expect(await where({ field: 'v', operator: 'eq', value: 'a' })).toEqual(['sa'])\n // Numbers rank before strings, strings before null; 'A' and 'a' tie at base sensitivity.\n expect(await where({ field: 'v', operator: 'lt', value: '0' })).toEqual(['n1', 'n5'])\n expect(await where({ field: 'v', operator: 'gt', value: 5 })).toEqual(\n ['nul', 's1', 'sA', 'sa'].sort(),\n )\n expect(await where({ field: 'v', operator: 'between', value: [2, 'a'] })).toEqual(\n ['n5', 's1', 'sA', 'sa'].sort(),\n )\n })\n },\n CASE_MS,\n )\n\n it(\n 'orderBy orders by value with the collator, nulls and missing last, ties by key, on a dotted path too',\n async () => {\n await using(make, async (store) => {\n await putAll(store, 'col', [\n { id: 'k4', part: 'p', nested: { v: 'b' } },\n { id: 'k1', part: 'p', nested: { v: 'B' } },\n { id: 'k2', part: 'p', nested: { v: 'a' } },\n { id: 'k3', part: 'p', nested: {} },\n { id: 'k5', part: 'p', nested: { v: 10 } },\n { id: 'k6', part: 'p', nested: { v: 9 } },\n { id: 'k0', part: 'p', nested: { v: null } },\n ])\n const asc = await store.query<Doc>('col', {\n partitionKey: { field: 'part', value: 'p' },\n orderBy: { field: 'nested.v', direction: 'asc', nulls: 'last' },\n })\n expect(ids(asc.items)).toEqual(['k6', 'k5', 'k2', 'k1', 'k4', 'k0', 'k3'])\n const desc = await store.query<Doc>('col', {\n partitionKey: { field: 'part', value: 'p' },\n orderBy: { field: 'nested.v', direction: 'desc', nulls: 'last' },\n })\n expect(ids(desc.items)).toEqual(['k1', 'k4', 'k2', 'k5', 'k6', 'k0', 'k3'])\n })\n },\n CASE_MS,\n )\n\n it(\n 'a limit and cursor walk returns every match exactly once, also when a document is deleted mid-walk',\n async () => {\n await using(make, async (store) => {\n const docs = Array.from({ length: 9 }, (_, i) => ({ id: `k${i}`, part: 'p', v: i % 3 }))\n await putAll(store, 'col', docs)\n for (const orderBy of [undefined, { field: 'v', direction: 'asc' as const }]) {\n const params: QueryParams = {\n partitionKey: { field: 'part', value: 'p' },\n limit: 2,\n ...(orderBy !== undefined && { orderBy }),\n }\n const whole = (await walk(store, 'col', params)).flat()\n expect(ids(whole).sort()).toEqual(ids(docs).sort())\n\n // The first cursor's anchor is deleted after the first page: the walk neither restarts nor repeats.\n const anchor = whole[1]!\n const walked = (\n await walk(store, 'col', params, async (page) => {\n if (page === 1) await store.delete('col', anchor.id)\n })\n ).flat()\n expect(new Set(ids(walked)).size).toBe(walked.length)\n expect(ids(walked).sort()).toEqual(ids(docs).sort())\n await store.put('col', anchor.id, anchor)\n }\n })\n },\n SLOW,\n )\n\n it(\n 'a cursor issued under one orderBy is refused under another, and continues under its own',\n async () => {\n await using(make, async (store) => {\n await putAll(\n store,\n 'col',\n Array.from({ length: 5 }, (_, i) => ({ id: `k${i}`, part: 'p', v: i })),\n )\n const base: QueryParams = {\n partitionKey: { field: 'part', value: 'p' },\n orderBy: { field: 'v', direction: 'asc' },\n limit: 2,\n }\n const first = await store.query<Doc>('col', base)\n expect(first.nextCursor).not.toBeNull()\n const cursor = first.nextCursor!\n const other = await rejection(\n store.query('col', { ...base, orderBy: { field: 'v', direction: 'desc' }, cursor }),\n )\n expect(other).toBeInstanceOf(Error)\n const next = await store.query<Doc>('col', { ...base, cursor })\n expect(ids(next.items)).toEqual(['k2', 'k3'])\n })\n },\n CASE_MS,\n )\n\n it(\n 'a document put with a ttl (seconds) is gone from get, query and batchGet once it expires',\n async () => {\n await using(make, async (store) => {\n await store.put('col', 'short', { id: 'short', part: 'p' }, { ttl: 1 })\n await store.put('col', 'kept', { id: 'kept', part: 'p' })\n expect(await store.get('col', 'short')).toEqual({ id: 'short', part: 'p' })\n if (opts.clock !== undefined) {\n await opts.clock.advance(1_001)\n } else {\n const deadline = Date.now() + 4_000\n while ((await store.get('col', 'short')) !== null && Date.now() < deadline) {\n await new Promise((r) => setTimeout(r, 50))\n }\n }\n expect(await store.get('col', 'short')).toBeNull()\n const all = await store.query<Doc>('col', { partitionKey: { field: 'part', value: '*' } })\n expect(ids(all.items)).toEqual(['kept'])\n expect([...(await store.batchGet('col', ['short', 'kept'])).keys()]).toEqual(['kept'])\n })\n },\n SLOW,\n )\n\n it(\n 'a conditional put applies when the field is strictly equal, and otherwise fails condition-failed',\n async () => {\n await using(make, async (store) => {\n await store.put('col', 'c', { version: 1, label: 'v1' })\n await store.put(\n 'col',\n 'c',\n { version: 2, label: 'v2' },\n { conditionKey: 'version', conditionValue: 1 },\n )\n expect(await store.get('col', 'c')).toEqual({ version: 2, label: 'v2' })\n for (const conditionValue of [1, '2']) {\n const failed = await rejection(\n store.put('col', 'c', { version: 3 }, { conditionKey: 'version', conditionValue }),\n )\n expect((failed as { code?: unknown } | null)?.code).toBe('adapter.condition-failed')\n }\n const absent = await rejection(\n store.put(\n 'col',\n 'none',\n { version: 1 },\n { conditionKey: 'version', conditionValue: 1 },\n ),\n )\n expect((absent as { code?: unknown } | null)?.code).toBe('adapter.condition-failed')\n expect(await store.get('col', 'c')).toEqual({ version: 2, label: 'v2' })\n expect(await store.get('col', 'none')).toBeNull()\n })\n },\n CASE_MS,\n )\n\n it(\n 'batchPut stores every item; batchGet returns exactly the stored keys',\n async () => {\n await using(make, async (store) => {\n await store.batchPut(\n 'col',\n new Map([\n ['x', { n: 10 }],\n ['y', { n: 20 }],\n ]),\n )\n const got = await store.batchGet<{ n: number }>('col', ['x', 'y', 'missing'])\n expect([...got.keys()].sort()).toEqual(['x', 'y'])\n expect(got.get('x')).toEqual({ n: 10 })\n expect(await store.get('col', 'y')).toEqual({ n: 20 })\n expect((await store.batchGet('col', [])).size).toBe(0)\n })\n },\n CASE_MS,\n )\n\n it(\n 'collections are isolated for get, query and delete',\n async () => {\n await using(make, async (store) => {\n await store.put('colA', 'key', { id: 'key', part: 'p', from: 'A' })\n await store.put('colB', 'key', { id: 'key', part: 'p', from: 'B' })\n expect(await store.get('colA', 'key')).toEqual({ id: 'key', part: 'p', from: 'A' })\n const inB = await store.query('colB', { partitionKey: { field: 'part', value: '*' } })\n expect(inB.items).toEqual([{ id: 'key', part: 'p', from: 'B' }])\n await store.delete('colA', 'key')\n expect(await store.get('colB', 'key')).toEqual({ id: 'key', part: 'p', from: 'B' })\n })\n },\n CASE_MS,\n )\n\n const isolation = opts.isolation\n if (isolation !== undefined) {\n it(\n 'two stores under different prefixes never see each other’s documents',\n async () => {\n const [one, two] = await isolation()\n try {\n await one.put('col', 'shared', { id: 'shared', part: 'p', owner: 'one' })\n await one.put('col', 'one-only', { id: 'one-only', part: 'p', owner: 'one' })\n await two.put('col', 'shared', { id: 'shared', part: 'p', owner: 'two' })\n expect(await one.get('col', 'shared')).toEqual({\n id: 'shared',\n part: 'p',\n owner: 'one',\n })\n expect(await two.get('col', 'one-only')).toBeNull()\n const inTwo = await two.query('col', { partitionKey: { field: 'part', value: '*' } })\n expect(inTwo.items).toEqual([{ id: 'shared', part: 'p', owner: 'two' }])\n await one.delete('col', 'shared')\n expect(await two.get('col', 'shared')).toEqual({\n id: 'shared',\n part: 'p',\n owner: 'two',\n })\n } finally {\n await one.close()\n await two.close()\n }\n },\n CASE_MS,\n )\n }\n\n documentStoreModelCases(make, opts)\n\n documentStoreReplaceCases(make, opts)\n\n healthAndDowntime(make, opts.unreachable, 'get()', (store) => store.get('contract-down', 'k'))\n })\n}\n","import fc from 'fast-check'\nimport { describe, expect, it } from 'vitest'\nimport {\n compareDocumentValues,\n matchesSortKey,\n type DocumentStoreAdapter,\n type QueryParams,\n} from '@nymbalhq/types'\nimport { CASE_MS, type Build } from './common.js'\n\n// The document store contract as a property against the reference model: each store's page sequence, over the\n// generator domain below, equals the reference (filter with matchesSortKey, order with compareDocumentValues, nulls\n// last, ties by key, slice by `limit`). Kills: a store that filters `eq` as text (1 against '1'), orders strings by\n// bytes instead of the collator, places nulls or missing fields first, ignores a dotted path, restarts or repeats a\n// cursor walk (also across a delete), accepts a cursor under another order, ignores or misreads a TTL, skips a put\n// condition, or leaks across a collection or a prefix.\n\n/** What the model cases read of the suite's options. */\nexport interface ModelOptions {\n clock?: { advance(ms: number): void | Promise<void> }\n isolation?: () => Promise<[DocumentStoreAdapter, DocumentStoreAdapter]>\n}\n\nconst COLLECTION = 'contract-docs'\nconst DECOY = 'contract-decoy'\nconst SLOW = 60_000\n\ntype Value = string | number | null\n\n/** A stored document. `v` and `nested.v` are absent when the generator chose \"missing\". */\ninterface Doc {\n id: string\n part: string\n v?: Value\n nested: { v?: Value }\n label: string\n}\n\ninterface Generated {\n key: string\n part: 'p' | 'q'\n v: Value | undefined\n n: Value | undefined\n}\n\n/** The domain: case, accent and equal-base strings, ints next to numeric strings, and null. */\nconst valueArb: fc.Arbitrary<Value> = fc.oneof(\n fc.constantFrom('a', 'A', 'á', 'b', 'B', 'é', 'e', 'ab', 'Ab', '1', '10', '2'),\n fc.integer({ min: -2, max: 10 }),\n fc.constant(null),\n)\n/** A field holding a domain value, or missing (undefined). */\nconst fieldArb = fc.option(valueArb, { nil: undefined, freq: 4 })\n\nconst docsArb = (minLength: number) =>\n fc.uniqueArray(\n fc.record({\n // Random keys, so key order is unrelated to value order.\n key: fc.stringMatching(/^[a-z0-9]{1,6}$/),\n part: fc.constantFrom<'p' | 'q'>('p', 'q'),\n v: fieldArb,\n n: fieldArb,\n }),\n { minLength, maxLength: 14, selector: (d) => d.key },\n )\n\ntype SortKey = NonNullable<QueryParams['sortKey']>\ntype Direction = 'asc' | 'desc'\n\nconst sortKeyArb: fc.Arbitrary<SortKey | undefined> = fc.option(\n fc.oneof(\n fc.record({\n field: fc.constant('v'),\n operator: fc.constantFrom<'eq' | 'gt' | 'lt'>('eq', 'gt', 'lt'),\n value: valueArb as fc.Arbitrary<unknown>,\n }),\n fc.record({\n field: fc.constant('v'),\n operator: fc.constant<'between'>('between'),\n value: fc.tuple(valueArb, valueArb) as fc.Arbitrary<unknown>,\n }),\n ),\n { nil: undefined },\n)\nconst orderByArb = fc.record({\n field: fc.constantFrom('v', 'nested.v'),\n direction: fc.constantFrom<Direction>('asc', 'desc'),\n})\n\nfunction stored(g: Generated): Doc {\n return {\n id: g.key,\n part: g.part,\n ...(g.v !== undefined && { v: g.v }),\n nested: g.n !== undefined ? { v: g.n } : {},\n label: 'Ünïcödé ✓',\n }\n}\n\nfunction valueAt(doc: Doc, path: string): unknown {\n let value: unknown = doc\n for (const part of path.split('.')) {\n if (value === null || typeof value !== 'object') return undefined\n value = (value as Record<string, unknown>)[part]\n }\n return value\n}\n\nconst nullish = (v: unknown): boolean => v === null || v === undefined\n\ninterface Query {\n partition: 'p' | '*'\n sortKey: SortKey | undefined\n orderBy: { field: string; direction: Direction } | undefined\n}\n\n/** The reference: filter by partition and matchesSortKey, then order (when asked) by compareDocumentValues. */\nfunction reference(docs: Doc[], q: Query): string[] {\n const hits = docs.filter(\n (d) =>\n (q.partition === '*' || d.part === q.partition) &&\n (q.sortKey === undefined || matchesSortKey(d.v, q.sortKey)),\n )\n const { orderBy } = q\n if (orderBy === undefined) return hits.map((d) => d.id).sort()\n return hits\n .sort((a, b) => {\n const x = valueAt(a, orderBy.field)\n const y = valueAt(b, orderBy.field)\n // nulls: 'last' in both directions; a missing field is a null.\n if (nullish(x) !== nullish(y)) return nullish(x) ? 1 : -1\n let c = nullish(x) ? 0 : compareDocumentValues(x, y)\n if (orderBy.direction === 'desc') c = -c\n if (c !== 0) return c\n return a.id < b.id ? -1 : a.id > b.id ? 1 : 0\n })\n .map((d) => d.id)\n}\n\nfunction params(q: Query, limit: number, cursor?: string): QueryParams {\n return {\n partitionKey: { field: 'part', value: q.partition },\n ...(q.sortKey !== undefined && { sortKey: q.sortKey }),\n ...(q.orderBy !== undefined && { orderBy: { ...q.orderBy, nulls: 'last' as const } }),\n limit,\n ...(cursor !== undefined && { cursor }),\n }\n}\n\n/** Every page of a cursor walk. `between` runs after each page; the walk stops after `docs + 2` pages. */\nasync function walk(\n store: DocumentStoreAdapter,\n q: Query,\n limit: number,\n maxPages: number,\n between?: (page: number) => Promise<void>,\n): Promise<{ pages: Doc[][]; ended: boolean }> {\n const pages: Doc[][] = []\n let cursor: string | undefined\n do {\n const page = await store.query<Doc>(COLLECTION, params(q, limit, cursor))\n pages.push(page.items)\n cursor = page.nextCursor ?? undefined\n if (between !== undefined) await between(pages.length)\n } while (cursor !== undefined && pages.length <= maxPages)\n return { pages, ended: cursor === undefined }\n}\n\nconst idsOf = (docs: Doc[]): string[] => docs.map((d) => d.id)\n\nfunction chunk<T>(items: T[], size: number): T[][] {\n const out: T[][] = []\n for (let i = 0; i < items.length; i += size) out.push(items.slice(i, i + size))\n return out\n}\n\n/** A final empty page (a cursor issued on an exact multiple of `limit`) adds nothing to the sequence. */\nfunction withoutTrailingEmpty<T>(pages: T[][]): T[][] {\n return pages.length > 0 && pages[pages.length - 1]!.length === 0 ? pages.slice(0, -1) : pages\n}\n\nasync function storeWith(\n make: Build<DocumentStoreAdapter>,\n generated: Generated[],\n): Promise<{ store: DocumentStoreAdapter; docs: Doc[] }> {\n const store = await make()\n const docs = generated.map(stored)\n for (const doc of docs) await store.put<Doc>(COLLECTION, doc.id, doc)\n // Same keys, same partition, another collection: no query on COLLECTION may return them.\n for (const doc of docs.slice(0, 3)) {\n await store.put<Doc>(DECOY, doc.id, { ...doc, label: 'decoy' })\n }\n return { store, docs }\n}\n\nasync function closing<T>(store: DocumentStoreAdapter, body: () => Promise<T>): Promise<T> {\n try {\n return await body()\n } finally {\n await store.close()\n }\n}\n\nasync function rejection(promise: Promise<unknown>): Promise<unknown> {\n return promise.then(\n () => null,\n (error: unknown) => error ?? new Error('rejected with nothing'),\n )\n}\n\nconst TTL_SECONDS = 1\n\n/** The reference-model cases, registered inside the suite's describe. */\nexport function documentStoreModelCases(make: Build<DocumentStoreAdapter>, opts: ModelOptions): void {\n describe('agrees with the reference model', () => {\n it(\n 'every query’s page sequence equals the reference: filter by partition and sortKey, order with nulls last and ties by key, slice by limit',\n async () => {\n await fc.assert(\n fc.asyncProperty(\n docsArb(0),\n fc.constantFrom<'p' | '*'>('p', '*'),\n sortKeyArb,\n orderByArb,\n fc.integer({ min: 1, max: 5 }),\n async (generated, partition, sortKey, orderBy, limit) => {\n const { store, docs } = await storeWith(make, generated)\n await closing(store, async () => {\n const q: Query = { partition, sortKey, orderBy }\n const expected = reference(docs, q)\n const { pages, ended } = await walk(store, q, limit, docs.length + 2)\n\n expect(ended, 'the cursor walk never ended').toBe(true)\n for (const page of pages) expect(page.length).toBeLessThanOrEqual(limit)\n expect(withoutTrailingEmpty(pages.map(idsOf))).toEqual(chunk(expected, limit))\n const byId = new Map(docs.map((d) => [d.id, d]))\n for (const item of pages.flat()) expect(item).toEqual(byId.get(item.id))\n })\n },\n ),\n { numRuns: 50 },\n )\n },\n SLOW,\n )\n\n it(\n 'without orderBy, a cursor walk returns exactly the reference’s matches, each once',\n async () => {\n await fc.assert(\n fc.asyncProperty(\n docsArb(0),\n fc.constantFrom<'p' | '*'>('p', '*'),\n sortKeyArb,\n fc.integer({ min: 1, max: 5 }),\n async (generated, partition, sortKey, limit) => {\n const { store, docs } = await storeWith(make, generated)\n await closing(store, async () => {\n const q: Query = { partition, sortKey, orderBy: undefined }\n const { pages, ended } = await walk(store, q, limit, docs.length + 2)\n const walked = idsOf(pages.flat())\n\n expect(ended, 'the cursor walk never ended').toBe(true)\n expect(walked.length, `duplicates in ${walked.join(',')}`).toBe(\n new Set(walked).size,\n )\n expect([...walked].sort()).toEqual(reference(docs, q))\n })\n },\n ),\n { numRuns: 40 },\n )\n },\n SLOW,\n )\n\n it(\n 'a cursor walk across a mid-walk delete returns every remaining match exactly once, in the reference order',\n async () => {\n await fc.assert(\n fc.asyncProperty(\n docsArb(3),\n fc.option(orderByArb, { nil: undefined }),\n fc.integer({ min: 1, max: 3 }),\n fc.nat(),\n async (generated, orderBy, limit, pick) => {\n const { store, docs } = await storeWith(make, generated)\n await closing(store, async () => {\n const q: Query = { partition: '*', sortKey: undefined, orderBy }\n const expected = reference(docs, q)\n fc.pre(expected.length > limit)\n // Any match: one already returned, the last one returned (the cursor's anchor), or one still ahead.\n const deleted = expected[pick % expected.length]!\n const { pages, ended } = await walk(store, q, limit, docs.length + 2, async (n) => {\n if (n === 1) await store.delete(COLLECTION, deleted)\n })\n const walked = idsOf(pages.flat())\n\n expect(ended, 'the cursor walk never ended').toBe(true)\n expect(walked.length, `duplicates in ${walked.join(',')}`).toBe(\n new Set(walked).size,\n )\n expect(walked.filter((id) => !expected.includes(id))).toEqual([])\n expect(expected.filter((id) => id !== deleted && !walked.includes(id))).toEqual([])\n if (orderBy !== undefined) {\n expect(walked).toEqual(expected.filter((id) => walked.includes(id)))\n }\n })\n },\n ),\n { numRuns: 50 },\n )\n },\n SLOW,\n )\n\n it(\n 'a cursor issued under one orderBy is refused under another, and continues the walk under its own',\n async () => {\n const generated: Generated[] = ['k1', 'k2', 'k3', 'k4', 'k5'].map((key, i) => ({\n key,\n part: 'p',\n v: 5 - i,\n n: i,\n }))\n const { store, docs } = await storeWith(make, generated)\n await closing(store, async () => {\n const asc: Query = {\n partition: 'p',\n sortKey: undefined,\n orderBy: { field: 'v', direction: 'asc' },\n }\n const first = await store.query<Doc>(COLLECTION, params(asc, 2))\n expect(first.nextCursor).not.toBeNull()\n const cursor = first.nextCursor!\n\n const otherDirection = { ...asc, orderBy: { field: 'v', direction: 'desc' as const } }\n const otherField = { ...asc, orderBy: { field: 'nested.v', direction: 'asc' as const } }\n expect(\n await rejection(store.query(COLLECTION, params(otherDirection, 2, cursor))),\n ).toBeInstanceOf(Error)\n expect(\n await rejection(store.query(COLLECTION, params(otherField, 2, cursor))),\n ).toBeInstanceOf(Error)\n const next = await store.query<Doc>(COLLECTION, params(asc, 2, cursor))\n expect(idsOf(next.items)).toEqual(reference(docs, asc).slice(2, 4))\n })\n },\n SLOW,\n )\n\n it(\n 'a document put with a TTL is returned until it expires, then by no get, query or batchGet; one put without stays',\n async () => {\n const store = await make()\n await closing(store, async () => {\n const short: Doc = { id: 'short', part: 'p', nested: {}, label: 'ttl' }\n const long: Doc = { id: 'long', part: 'p', nested: {}, label: 'no ttl' }\n const putAt = Date.now()\n await store.put<Doc>(COLLECTION, short.id, short, { ttl: TTL_SECONDS })\n await store.put<Doc>(COLLECTION, long.id, long)\n expect(await store.get<Doc>(COLLECTION, short.id)).toEqual(short)\n\n if (opts.clock !== undefined) {\n await opts.clock.advance(TTL_SECONDS * 1000 - 1)\n expect(await store.get<Doc>(COLLECTION, short.id)).toEqual(short)\n await opts.clock.advance(2)\n } else {\n // Polled, not slept: the TTL is the store's to keep, and its expiry is read back as soon as it shows.\n const deadline = putAt + TTL_SECONDS * 1000 + 3000\n while ((await store.get(COLLECTION, short.id)) !== null && Date.now() < deadline) {\n await new Promise((r) => setTimeout(r, 25))\n }\n expect(Date.now() - putAt, 'expired before its TTL').toBeGreaterThanOrEqual(\n TTL_SECONDS * 1000 - 100,\n )\n }\n\n expect(await store.get(COLLECTION, short.id)).toBeNull()\n const all = await store.query<Doc>(COLLECTION, {\n partitionKey: { field: 'part', value: '*' },\n limit: 100,\n })\n expect(idsOf(all.items)).toEqual([long.id])\n const batch = await store.batchGet<Doc>(COLLECTION, [short.id, long.id])\n expect([...batch.keys()]).toEqual([long.id])\n })\n },\n SLOW,\n )\n\n it('a conditional put applies when the field matches, and otherwise fails condition-failed and changes nothing', async () => {\n const store = await make()\n await closing(store, async () => {\n const v1: Doc & { version: number } = {\n id: 'c',\n part: 'p',\n nested: {},\n label: 'v1',\n version: 1,\n }\n const v2 = { ...v1, label: 'v2', version: 2 }\n await store.put(COLLECTION, 'c', v1)\n\n await store.put(COLLECTION, 'c', v2, { conditionKey: 'version', conditionValue: 1 })\n expect(await store.get(COLLECTION, 'c')).toEqual(v2)\n\n const stale = await rejection(\n store.put(\n COLLECTION,\n 'c',\n { ...v1, label: 'v3', version: 3 },\n { conditionKey: 'version', conditionValue: 1 },\n ),\n )\n expect((stale as { code?: unknown } | null)?.code).toBe('adapter.condition-failed')\n expect(await store.get(COLLECTION, 'c')).toEqual(v2)\n\n const absent = await rejection(\n store.put(COLLECTION, 'none', v1, { conditionKey: 'version', conditionValue: 1 }),\n )\n expect((absent as { code?: unknown } | null)?.code).toBe('adapter.condition-failed')\n expect(await store.get(COLLECTION, 'none')).toBeNull()\n })\n }, CASE_MS)\n\n it(\n 'batchPut stores every item and batchGet returns exactly the stored keys, equal to what was put',\n async () => {\n await fc.assert(\n fc.asyncProperty(docsArb(1), async (generated) => {\n const store = await make()\n await closing(store, async () => {\n const docs = generated.map(stored)\n await store.batchPut(COLLECTION, new Map(docs.map((d) => [d.id, d])))\n const asked = [...docs.map((d) => d.id), 'contract-absent']\n const got = await store.batchGet<Doc>(COLLECTION, asked)\n\n expect(got.size).toBe(docs.length)\n for (const doc of docs) {\n expect(got.get(doc.id)).toEqual(doc)\n expect(await store.get<Doc>(COLLECTION, doc.id)).toEqual(doc)\n }\n })\n }),\n { numRuns: 15 },\n )\n },\n SLOW,\n )\n\n it('collections are isolated for get, query and delete', async () => {\n const store = await make()\n await closing(store, async () => {\n const a: Doc = { id: 'same', part: 'p', nested: {}, label: 'A' }\n const b: Doc = { ...a, label: 'B' }\n const onlyA: Doc = { ...a, id: 'only-a' }\n await store.put('contract-col-a', a.id, a)\n await store.put('contract-col-a', onlyA.id, onlyA)\n await store.put('contract-col-b', b.id, b)\n\n expect(await store.get('contract-col-a', 'same')).toEqual(a)\n expect(await store.get('contract-col-b', 'same')).toEqual(b)\n const inB = await store.query<Doc>('contract-col-b', {\n partitionKey: { field: 'part', value: '*' },\n limit: 100,\n })\n expect(idsOf(inB.items)).toEqual([b.id])\n await store.delete('contract-col-a', 'same')\n expect(await store.get('contract-col-b', 'same')).toEqual(b)\n expect(await store.get('contract-col-a', 'only-a')).toEqual(onlyA)\n })\n }, CASE_MS)\n\n if (opts.isolation !== undefined) {\n const isolation = opts.isolation\n it('two instances with different prefixes never see each other’s documents', async () => {\n const [one, two] = await isolation()\n try {\n const mine: Doc = { id: 'shared-key', part: 'p', nested: {}, label: 'one' }\n const theirs: Doc = { ...mine, label: 'two' }\n await one.put(COLLECTION, mine.id, mine)\n await one.put(COLLECTION, 'one-only', { ...mine, id: 'one-only' })\n await two.put(COLLECTION, theirs.id, theirs)\n\n expect(await one.get(COLLECTION, mine.id)).toEqual(mine)\n expect(await two.get(COLLECTION, theirs.id)).toEqual(theirs)\n expect(await two.get(COLLECTION, 'one-only')).toBeNull()\n const inTwo = await two.query<Doc>(COLLECTION, {\n partitionKey: { field: 'part', value: '*' },\n limit: 100,\n })\n expect(idsOf(inTwo.items)).toEqual([theirs.id])\n const batch = await two.batchGet<Doc>(COLLECTION, [mine.id, 'one-only'])\n expect([...batch.values()]).toEqual([theirs])\n\n await one.delete(COLLECTION, mine.id)\n expect(await two.get(COLLECTION, theirs.id)).toEqual(theirs)\n } finally {\n await one.close()\n await two.close()\n }\n }, CASE_MS)\n }\n })\n}\n","import fc from 'fast-check'\nimport { expect, it } from 'vitest'\nimport type { DocumentStoreAdapter } from '@nymbalhq/types'\nimport { CASE_MS, using, type Build } from './common.js'\n\n// The replaceCollection cases of the document store contract: a rebuilt read model is swapped in with it, so readers\n// must never see it half-built. Kills: a replace that merges (stale keys of the old set survive), one that deletes and\n// writes in steps a reader can see between (a partial set), and one that empties the collection before a source that\n// then throws (a failed rebuild leaves nothing).\n\ninterface Doc {\n id: string\n part: string\n v: number\n}\n\nconst SLOW = 60_000\nconst KEYS = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] as const\n\nconst macrotask = () => new Promise<void>((resolve) => setImmediate(resolve))\n\nasync function* entriesOf(docs: Doc[], pause = false): AsyncGenerator<[string, Doc]> {\n for (const doc of docs) {\n if (pause) await macrotask()\n yield [doc.id, doc]\n }\n}\n\n/** The whole collection, in key order, as `id:v` strings: what a reader saw. */\nasync function snapshot(store: DocumentStoreAdapter, collection: string): Promise<string[]> {\n const all = await store.query<Doc>(collection, { partitionKey: { field: 'part', value: '*' } })\n return all.items.map((d) => `${d.id}:${d.v}`)\n}\n\nconst shape = (docs: Doc[]) =>\n [...docs].sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)).map((d) => `${d.id}:${d.v}`)\n\nasync function putAll(store: DocumentStoreAdapter, collection: string, docs: Doc[]) {\n for (const doc of docs) await store.put(collection, doc.id, doc)\n}\n\nconst docsFrom = (keys: readonly string[], v: number): Doc[] =>\n keys.map((id) => ({ id, part: 'p', v }))\n\nexport function documentStoreReplaceCases(\n make: Build<DocumentStoreAdapter>,\n opts: { clock?: { advance(ms: number): void | Promise<void> } },\n): void {\n it(\n 'replaceCollection leaves exactly the new set, whatever the old and new sets: no stale key of the old set survives, and another collection is untouched (property)',\n async () => {\n await using(make, async (store) => {\n let run = 0\n await fc.assert(\n fc.asyncProperty(\n fc.uniqueArray(fc.constantFrom(...KEYS)),\n fc.uniqueArray(fc.constantFrom(...KEYS)),\n async (oldKeys, newKeys) => {\n run += 1\n const collection = `contract-replace-${run}`\n const decoy = `contract-replace-decoy-${run}`\n await putAll(store, collection, docsFrom(oldKeys, 1))\n await putAll(store, decoy, docsFrom(oldKeys, 3))\n\n const next = docsFrom(newKeys, 2)\n await store.replaceCollection(collection, entriesOf(next))\n\n expect(await snapshot(store, collection)).toEqual(shape(next))\n for (const key of oldKeys.filter((k) => !newKeys.includes(k))) {\n expect(await store.get(collection, key), `stale key ${key}`).toBeNull()\n }\n expect(await snapshot(store, decoy)).toEqual(shape(docsFrom(oldKeys, 3)))\n },\n ),\n { numRuns: 25 },\n )\n })\n },\n SLOW,\n )\n\n it(\n 'replaceCollection is atomic to a concurrent reader: polling while the replace runs sees only the full old set or the full new set, never a partial set',\n async () => {\n await using(make, async (store) => {\n const old = docsFrom(['a', 'b', 'c', 'd', 'e', 'f'], 1)\n const next = docsFrom(['d', 'e', 'f', 'g', 'h', 'i'], 2)\n await putAll(store, 'contract-replace-reader', old)\n const allowed = new Set([JSON.stringify(shape(old)), JSON.stringify(shape(next))])\n\n let done = false\n const seen: string[][] = []\n const reader = (async () => {\n while (!done) {\n seen.push(await snapshot(store, 'contract-replace-reader'))\n await macrotask()\n }\n })()\n await store\n .replaceCollection('contract-replace-reader', entriesOf(next, true))\n .finally(() => {\n done = true\n })\n await reader\n\n expect(seen.length, 'the reader read while the replace ran').toBeGreaterThan(0)\n for (const observed of seen) {\n expect(\n allowed.has(JSON.stringify(observed)),\n `a partial set: ${observed.join(' ')}`,\n ).toBe(true)\n }\n expect(await snapshot(store, 'contract-replace-reader')).toEqual(shape(next))\n })\n },\n CASE_MS,\n )\n\n it(\n 'replaceCollection whose source throws part-way rejects with the source’s error and leaves the old set intact',\n async () => {\n await using(make, async (store) => {\n const old = docsFrom(['a', 'b', 'c'], 1)\n await putAll(store, 'contract-replace-failing', old)\n async function* failing(): AsyncGenerator<[string, Doc]> {\n yield ['a', { id: 'a', part: 'p', v: 2 }]\n yield ['z', { id: 'z', part: 'p', v: 2 }]\n throw new Error('contract: the source failed')\n }\n\n const failed = await store.replaceCollection('contract-replace-failing', failing()).then(\n () => null,\n (error: unknown) => error,\n )\n\n expect(String(failed)).toContain('contract: the source failed')\n expect(await snapshot(store, 'contract-replace-failing')).toEqual(shape(old))\n })\n },\n CASE_MS,\n )\n\n it(\n 'replaceCollection with an empty source empties the collection',\n async () => {\n await using(make, async (store) => {\n await putAll(store, 'contract-replace-empty', docsFrom(['a', 'b'], 1))\n await store.replaceCollection('contract-replace-empty', entriesOf([]))\n expect(await snapshot(store, 'contract-replace-empty')).toEqual([])\n expect(await store.get('contract-replace-empty', 'a')).toBeNull()\n })\n },\n CASE_MS,\n )\n\n const clock = opts.clock\n if (clock !== undefined) {\n it(\n 'replaceCollection writes documents without a TTL: a key whose old document had one is still there after that TTL passes',\n async () => {\n await using(make, async (store) => {\n await store.put('contract-replace-ttl', 'a', { id: 'a', part: 'p', v: 1 }, { ttl: 60 })\n await store.replaceCollection('contract-replace-ttl', entriesOf(docsFrom(['a', 'b'], 2)))\n await clock.advance(61_000)\n expect(await snapshot(store, 'contract-replace-ttl')).toEqual(['a:2', 'b:2'])\n })\n },\n CASE_MS,\n )\n }\n}\n","import { describe, expect, it } from 'vitest'\nimport type { EmailAdapter } from '@nymbalhq/types'\nimport { CASE_MS, healthAndDowntime, type Build, type ContractOptions } from './common.js'\n\nconst MAIL = {\n template: 'order-confirmation',\n to: 'test@example.com',\n vars: { orderNumber: 'ORD-001' },\n}\n\nexport function runEmailContract(\n name: string,\n build: Build<EmailAdapter>,\n options: ContractOptions<EmailAdapter> = {},\n): void {\n describe(`EmailAdapter contract: ${name}`, () => {\n it(\n 'sendTransactional resolves with accepted or messageId',\n async () => {\n const adapter = await build()\n const result = await adapter.sendTransactional(MAIL)\n expect(typeof result.accepted).toBe('boolean')\n },\n CASE_MS,\n )\n\n it(\n 'syncCustomerToList resolves without throwing',\n async () => {\n const adapter = await build()\n await expect(\n adapter.syncCustomerToList({\n customerId: 'cust-1',\n orderCount: 0,\n totalSpentMinor: 0,\n segment: 'new',\n createdAt: new Date().toISOString(),\n }),\n ).resolves.not.toThrow()\n },\n CASE_MS,\n )\n\n it(\n 'removeCustomerFromList resolves without throwing',\n async () => {\n const adapter = await build()\n await expect(adapter.removeCustomerFromList('cust-1')).resolves.not.toThrow()\n },\n CASE_MS,\n )\n\n healthAndDowntime(build, options.unreachable, 'sendTransactional()', (adapter) =>\n adapter.sendTransactional(MAIL),\n )\n })\n}\n","import { randomUUID } from 'node:crypto'\nimport { describe, expect, it } from 'vitest'\nimport type { EventBusAdapter, NymbalEvent } from '@nymbalhq/types'\nimport { CASE_MS, healthAndDowntime, type Build, type ContractOptions } from './common.js'\nimport { eventBusDeliveryCases } from './event-bus-delivery.js'\nimport { eventBusFailureCases } from './event-bus-failure.js'\n\nexport interface EventBusContractOptions extends ContractOptions<EventBusAdapter> {\n /** Another instance on the same streams as the bus `make` returned last: only a shared bus passes it. */\n second?: () => Promise<EventBusAdapter>\n /** The bus's own knobs, set small by the caller: the claim and timeout cases assert the windows they bound. */\n timing?: { claimIdleMs: number; ackTimeoutMs: number }\n}\n\ntype Make = Build<EventBusAdapter>\n\nconst SLOW = 30_000\n\nfunction makeEvent(type: string, payload: Record<string, unknown> = {}): NymbalEvent {\n return {\n id: `evt-${randomUUID()}`,\n type,\n timestamp: new Date().toISOString(),\n source: 'contract-tests',\n correlationId: `corr-${randomUUID()}`,\n payload,\n metadata: { storeId: 'test', environment: 'development', version: '0.0.0' },\n }\n}\n\nconst delay = (ms: number): Promise<void> => new Promise((r) => setTimeout(r, ms))\n\nasync function using(buses: EventBusAdapter[], body: () => Promise<void>): Promise<void> {\n try {\n await body()\n } finally {\n for (const bus of buses) await bus.close()\n }\n}\n\n/**\n * The event bus contract every implementation runs. `publish` resolves only after every matching subscription's\n * handler has finished (what a read straight after a command relies on); a throwing unnamed handler is logged and does\n * not reject it, and a throwing named one rejects it with `handler_failed` once the rest have finished; `replay`\n * reaches `derived` subscriptions only; each subscription takes its events in order. With `second`, a named\n * subscription is handled once across instances and an unnamed one on every instance. Then the delivery contract's\n * cases, the handler-failure cases, and health (and, given `unreachable`, downtime).\n */\nexport function runEventBusContract(\n name: string,\n make: Make,\n opts: EventBusContractOptions = {},\n): void {\n describe(`EventBusAdapter contract: ${name}`, () => {\n it(\n 'publish resolves after the matching handler has finished, and never calls a non-matching one',\n async () => {\n const bus = await make()\n await using([bus], async () => {\n const received: unknown[] = []\n const other: unknown[] = []\n await bus.subscribe('test.event.v1', async (e) => {\n await delay(50)\n received.push(e.payload)\n })\n await bus.subscribe('test.other.v1', async (e) => void other.push(e))\n await bus.publish(makeEvent('test.event.v1', { x: 1 }))\n expect(received).toEqual([{ x: 1 }])\n expect(other).toEqual([])\n })\n },\n CASE_MS,\n )\n\n it(\n 'a handler that throws leaves publish resolved and every other handler called',\n async () => {\n const bus = await make()\n await using([bus], async () => {\n const results: string[] = []\n await bus.subscribe('error.test.v1', async () => {\n throw new Error('boom')\n })\n await bus.subscribe('error.test.v1', async () => void results.push('ok'))\n await expect(bus.publish(makeEvent('error.test.v1'))).resolves.toBeUndefined()\n expect(results).toEqual(['ok'])\n })\n },\n CASE_MS,\n )\n\n it(\n 'replay reaches derived subscriptions only',\n async () => {\n const bus = await make()\n await using([bus], async () => {\n const derived: string[] = []\n const sideEffect: string[] = []\n await bus.subscribe('replay.test.v1', async (e) => void derived.push(e.id), {\n name: 'contract-projection',\n derived: true,\n })\n await bus.subscribe('replay.test.v1', async (e) => void sideEffect.push(e.id), {\n name: 'contract-side-effect',\n })\n const events = [makeEvent('replay.test.v1'), makeEvent('replay.test.v1')]\n await bus.replay(events)\n expect(derived).toEqual(events.map((e) => e.id))\n expect(sideEffect).toEqual([])\n })\n },\n CASE_MS,\n )\n\n it(\n 'publishBatch reaches each subscription in batch order, through wildcards and pattern arrays',\n async () => {\n const bus = await make()\n await using([bus], async () => {\n const wildcard: string[] = []\n const listed: string[] = []\n await bus.subscribe('batch.*', async (e) => void wildcard.push(e.id))\n await bus.subscribe(['batch.a.v1', 'batch.c.v1'], async (e) => void listed.push(e.id), {\n name: 'contract-listed',\n })\n const events = ['batch.a.v1', 'batch.b.v1', 'batch.c.v1', 'batch.a.v1'].map((t, seq) =>\n makeEvent(t, { seq }),\n )\n await bus.publishBatch(events)\n expect(wildcard).toEqual(events.map((e) => e.id))\n expect(listed).toEqual(events.filter((e) => e.type !== 'batch.b.v1').map((e) => e.id))\n })\n },\n CASE_MS,\n )\n\n it(\n 'an unsubscribed handler receives nothing more',\n async () => {\n const bus = await make()\n await using([bus], async () => {\n const received: string[] = []\n const sub = await bus.subscribe('unsub.event.v1', async (e) => void received.push(e.id))\n const before = makeEvent('unsub.event.v1')\n await bus.publish(before)\n await bus.unsubscribe(sub)\n await bus.publish(makeEvent('unsub.event.v1'))\n expect(received).toEqual([before.id])\n })\n },\n CASE_MS,\n )\n\n it(\n 'on one instance, a named and an unnamed subscription each handle every event once',\n async () => {\n const bus = await make()\n await using([bus], async () => {\n const named: string[] = []\n const unnamed: string[] = []\n await bus.subscribe('both.event.v1', async (e) => void named.push(e.id), {\n name: 'contract-named',\n })\n await bus.subscribe('both.event.v1', async (e) => void unnamed.push(e.id))\n const events = [makeEvent('both.event.v1'), makeEvent('both.event.v1')]\n for (const e of events) await bus.publish(e)\n expect(named).toEqual(events.map((e) => e.id))\n expect(unnamed).toEqual(named)\n })\n },\n CASE_MS,\n )\n\n eventBusDeliveryCases(make, opts)\n eventBusFailureCases(make, opts)\n\n healthAndDowntime(make, opts.unreachable, 'publish()', (bus) =>\n bus.publish(makeEvent('contract.down.v1')),\n )\n\n const second = opts.second\n if (second === undefined) return\n\n it(\n 'across two instances, a named subscription handles each event once in total, and an unnamed one on each',\n async () => {\n const a = await make()\n const b = await second()\n await using([a, b], async () => {\n const named: string[] = []\n const onA: string[] = []\n const onB: string[] = []\n await a.subscribe('shared.*', async (e) => void named.push(e.id), {\n name: 'contract-shared',\n })\n await b.subscribe('shared.*', async (e) => void named.push(e.id), {\n name: 'contract-shared',\n })\n await a.subscribe('shared.*', async (e) => void onA.push(e.id))\n await b.subscribe('shared.*', async (e) => void onB.push(e.id))\n const events = Array.from({ length: 6 }, (_, seq) => makeEvent('shared.x', { seq }))\n for (const [i, e] of events.entries()) await (i % 2 === 0 ? a : b).publish(e)\n // Each instance's own unnamed subscription is waited on by its own publishes: a fence on each.\n const fenceA = makeEvent('shared.fence')\n const fenceB = makeEvent('shared.fence')\n await a.publish(fenceA)\n await b.publish(fenceB)\n\n const ids = events.map((e) => e.id)\n expect(named.filter((id) => ids.includes(id)).sort()).toEqual([...ids].sort())\n expect(onA.filter((id) => ids.includes(id))).toEqual(ids)\n expect(onB.filter((id) => ids.includes(id))).toEqual(ids)\n })\n },\n SLOW,\n )\n })\n}\n","import { randomUUID } from 'node:crypto'\nimport fc from 'fast-check'\nimport { describe, expect, it } from 'vitest'\nimport type { EventBusAdapter, NymbalEvent } from '@nymbalhq/types'\nimport type { Build } from './common.js'\n\n// The event bus delivery contract. With `second` (another instance on the same streams as the bus `make` returned\n// last) and `timing` (the bus's own knobs, set small) it adds the cases only a shared bus has. Kills: a publish that\n// resolves before its handlers ran (a read straight after a command misses its projection), a throwing named handler\n// that is swallowed or starves another, replay reaching side effects, batch order lost, two instances double-handling a\n// named event, an instance missing an unnamed (admin tab) event, and a dead instance or consumer stalling every\n// publish (every checkout) until the timeout.\n\n/** What the delivery cases read of the suite's options. */\nexport interface DeliveryOptions {\n second?: () => Promise<EventBusAdapter>\n timing?: { claimIdleMs: number; ackTimeoutMs: number }\n}\n\nconst SLOW = 60_000\n\nfunction event(type: string, payload: Record<string, unknown> = {}): NymbalEvent {\n return {\n id: `evt-${randomUUID()}`,\n type,\n timestamp: new Date().toISOString(),\n source: 'contract-contract',\n correlationId: `corr-${randomUUID()}`,\n payload,\n metadata: { storeId: 'contract', environment: 'development', version: '0.0.0' },\n }\n}\n\nconst delay = (ms: number): Promise<void> => new Promise((r) => setTimeout(r, ms))\n\n/** Polls `check` (no fixed sleep); throws naming `label` after `ms`. */\nasync function until(check: () => boolean, label: string, ms: number): Promise<void> {\n const deadline = Date.now() + ms\n while (!check()) {\n if (Date.now() > deadline) throw new Error(`timed out after ${ms} ms waiting for ${label}`)\n await delay(10)\n }\n}\n\nfunction gate(): { wait: Promise<void>; open(): void } {\n let open!: () => void\n const wait = new Promise<void>((r) => {\n open = r\n })\n return { wait, open }\n}\n\nasync function closingAll(buses: EventBusAdapter[], body: () => Promise<void>): Promise<void> {\n try {\n await body()\n } finally {\n for (const bus of buses) await bus.close()\n }\n}\n\nconst TYPES = ['order.created.v1', 'order.paid.v1', 'cart.updated.v1'] as const\n\n/** The delivery cases, registered inside the suite's describe. */\nexport function eventBusDeliveryCases(make: Build<EventBusAdapter>, opts: DeliveryOptions): void {\n describe('keeps the delivery contract', () => {\n it(\n 'publish resolves only after every matching handler has finished: a 200 ms handler, named and unnamed, is done first',\n async () => {\n const bus = await make()\n await closingAll([bus], async () => {\n const finished: string[] = []\n await bus.subscribe('contract.slow.v1', async () => {\n await delay(200)\n finished.push('unnamed')\n })\n await bus.subscribe(\n 'contract.slow.v1',\n async () => {\n await delay(200)\n finished.push('named')\n },\n { name: 'contract-slow' },\n )\n\n const startedAt = Date.now()\n await bus.publish(event('contract.slow.v1'))\n const elapsed = Date.now() - startedAt\n\n expect([...finished].sort()).toEqual(['named', 'unnamed'])\n expect(elapsed).toBeGreaterThanOrEqual(190)\n })\n },\n SLOW,\n )\n\n it(\n 'a throwing named handler rejects publish with handler_failed naming it, and every other matching handler is called, event after event',\n async () => {\n const bus = await make()\n await closingAll([bus], async () => {\n const received: string[] = []\n await bus.subscribe(\n 'contract.boom.v1',\n async () => {\n throw new Error('contract handler failure')\n },\n { name: 'contract-throws' },\n )\n await bus.subscribe('contract.boom.v1', async (e) => {\n received.push(e.id)\n })\n const events = [\n event('contract.boom.v1'),\n event('contract.boom.v1'),\n event('contract.boom.v1'),\n ]\n\n for (const e of events) {\n await expect(bus.publish(e)).rejects.toMatchObject({\n code: 'adapter.handler_failed',\n context: { eventId: e.id, failed: [{ subscription: 'contract-throws' }] },\n })\n }\n\n expect(received).toEqual(events.map((e) => e.id))\n })\n },\n SLOW,\n )\n\n it(\n 'replay reaches derived subscriptions only, in order; a later publish still reaches every subscription',\n async () => {\n const bus = await make()\n await closingAll([bus], async () => {\n const derived: string[] = []\n const sideNamed: string[] = []\n const sideUnnamed: string[] = []\n await bus.subscribe('contract.replay.v1', async (e) => void derived.push(e.id), {\n name: 'contract-projection',\n derived: true,\n })\n await bus.subscribe('contract.replay.v1', async (e) => void sideNamed.push(e.id), {\n name: 'contract-side-effect',\n })\n await bus.subscribe('contract.replay.v1', async (e) => void sideUnnamed.push(e.id))\n const replayed = [event('contract.replay.v1'), event('contract.replay.v1')]\n\n await bus.replay(replayed)\n\n expect(derived).toEqual(replayed.map((e) => e.id))\n expect(sideNamed).toEqual([])\n expect(sideUnnamed).toEqual([])\n\n const live = event('contract.replay.v1')\n await bus.publish(live)\n expect(derived).toEqual([...replayed, live].map((e) => e.id))\n expect(sideNamed).toEqual([live.id])\n expect(sideUnnamed).toEqual([live.id])\n })\n },\n SLOW,\n )\n\n it(\n 'publishBatch reaches each subscription with exactly its matching events, in batch order (wildcards and pattern arrays)',\n async () => {\n await fc.assert(\n fc.asyncProperty(\n fc.array(fc.constantFrom(...TYPES), { minLength: 1, maxLength: 12 }),\n async (types) => {\n const bus = await make()\n await closingAll([bus], async () => {\n const fence = event('contract.fence.v1')\n const subs = [\n { patterns: ['order.*', fence.type], name: undefined },\n {\n patterns: ['cart.updated.v1', 'order.paid.v1', fence.type],\n name: 'contract-arr',\n },\n { patterns: ['order.created.v1', fence.type], name: 'contract-one' },\n ]\n const seen = subs.map(() => [] as string[])\n for (const [i, sub] of subs.entries()) {\n await bus.subscribe(\n sub.patterns,\n async (e) => void seen[i]!.push(e.id),\n sub.name === undefined ? undefined : { name: sub.name },\n )\n }\n const events = types.map((type, seq) => event(type, { seq }))\n\n await bus.publishBatch(events)\n // Each subscription takes its events in order, so once the fence is handled the batch was too.\n await bus.publish(fence)\n\n const matches = (patterns: string[], type: string): boolean =>\n patterns.some((p) =>\n p.endsWith('*') ? type.startsWith(p.slice(0, -1)) : p === type,\n )\n for (const [i, sub] of subs.entries()) {\n const expected = events.filter((e) => matches(sub.patterns, e.type))\n expect(seen[i], sub.patterns.join('|')).toEqual([\n ...expected.map((e) => e.id),\n fence.id,\n ])\n }\n })\n },\n ),\n { numRuns: 15 },\n )\n },\n SLOW,\n )\n\n it(\n 'an unsubscribed handler, by bus.unsubscribe or by its own unsubscribe(), receives nothing more',\n async () => {\n const bus = await make()\n await closingAll([bus], async () => {\n const gone: string[] = []\n const goneToo: string[] = []\n const kept: string[] = []\n const a = await bus.subscribe('contract.unsub.v1', async (e) => void gone.push(e.id), {\n name: 'contract-unsub',\n })\n const b = await bus.subscribe('contract.unsub.v1', async (e) => void goneToo.push(e.id))\n await bus.subscribe('contract.unsub.v1', async (e) => void kept.push(e.id))\n const before = event('contract.unsub.v1')\n await bus.publish(before)\n\n await bus.unsubscribe(a)\n await b.unsubscribe()\n const after = [event('contract.unsub.v1'), event('contract.unsub.v1')]\n for (const e of after) await bus.publish(e)\n\n expect(kept).toEqual([before, ...after].map((e) => e.id))\n expect(gone).toEqual([before.id])\n expect(goneToo).toEqual([before.id])\n })\n },\n SLOW,\n )\n\n it(\n 'on one instance, a named and an unnamed subscription each handle every event once',\n async () => {\n const bus = await make()\n await closingAll([bus], async () => {\n const named: string[] = []\n const unnamed: string[] = []\n await bus.subscribe('contract.both.v1', async (e) => void named.push(e.id), {\n name: 'contract-named',\n })\n await bus.subscribe('contract.both.v1', async (e) => void unnamed.push(e.id))\n const events = Array.from({ length: 6 }, () => event('contract.both.v1'))\n\n for (const e of events) await bus.publish(e)\n\n expect(named).toEqual(events.map((e) => e.id))\n expect(unnamed).toEqual(named)\n })\n },\n SLOW,\n )\n\n const second = opts.second\n if (second === undefined) return\n\n describe('two instances on the same streams', () => {\n const N = 12\n\n it(\n 'one named subscription on both instances handles each of N events exactly once in total',\n async () => {\n const a = await make()\n const b = await second()\n await closingAll([a, b], async () => {\n const byA: string[] = []\n const byB: string[] = []\n await a.subscribe('contract.named.*', async (e) => void byA.push(e.id), {\n name: 'contract-shared',\n })\n await b.subscribe('contract.named.*', async (e) => void byB.push(e.id), {\n name: 'contract-shared',\n })\n const events = Array.from({ length: N }, (_, seq) => event('contract.named.x', { seq }))\n\n for (const [i, e] of events.entries()) await (i % 2 === 0 ? a : b).publish(e)\n // A per-instance group would hand every event to both; these fences make its copies show before the count.\n await b.publish(event('contract.named.fence'))\n await a.publish(event('contract.named.fence'))\n\n const ids = new Set(events.map((e) => e.id))\n const handled = [...byA, ...byB].filter((id) => ids.has(id))\n expect(handled.length).toBe(events.length)\n expect([...handled].sort()).toEqual(events.map((e) => e.id).sort())\n })\n },\n SLOW,\n )\n\n it(\n 'an unnamed subscription on each instance receives all N events, in order, on both',\n async () => {\n const a = await make()\n const b = await second()\n await closingAll([a, b], async () => {\n const onA: string[] = []\n const onB: string[] = []\n await a.subscribe('contract.fanout.*', async (e) => void onA.push(e.id))\n await b.subscribe('contract.fanout.*', async (e) => void onB.push(e.id))\n const events = Array.from({ length: N }, (_, seq) =>\n event('contract.fanout.x', { seq }),\n )\n\n for (const e of events) await a.publish(e)\n const fenceB = event('contract.fanout.fence')\n await b.publish(fenceB)\n\n const ids = events.map((e) => e.id)\n expect(onA.slice(0, N)).toEqual(ids)\n expect(onB.slice(0, N)).toEqual(ids)\n expect(onB[N]).toBe(fenceB.id)\n })\n },\n SLOW,\n )\n\n it(\n 'replay on one instance reaches its own derived handlers and nothing on the other instance',\n async () => {\n const a = await make()\n const b = await second()\n await closingAll([a, b], async () => {\n const derivedA: string[] = []\n const derivedB: string[] = []\n const sideB: string[] = []\n await a.subscribe('contract.rebuild.*', async (e) => void derivedA.push(e.id), {\n name: 'contract-projection',\n derived: true,\n })\n await b.subscribe('contract.rebuild.*', async (e) => void derivedB.push(e.id), {\n name: 'contract-projection',\n derived: true,\n })\n await b.subscribe('contract.rebuild.*', async (e) => void sideB.push(e.id), {\n name: 'contract-side-effect',\n })\n const replayed = [event('contract.rebuild.x'), event('contract.rebuild.x')]\n\n await a.replay(replayed)\n // b reads its groups in stream order: a replay that went through the stream would reach b before this.\n const fence = event('contract.rebuild.fence')\n await b.publish(fence)\n\n expect(derivedA.slice(0, replayed.length)).toEqual(replayed.map((e) => e.id))\n const ids = new Set(replayed.map((e) => e.id))\n expect(derivedB.filter((id) => ids.has(id))).toEqual([])\n expect(sideB).toEqual([fence.id])\n })\n },\n SLOW,\n )\n\n const timing = opts.timing\n if (timing === undefined) return\n const { claimIdleMs, ackTimeoutMs } = timing\n\n it(\n 'groups left by a stopped instance (never unsubscribed) do not delay publish on the other instance',\n async () => {\n const a = await make()\n const b = await second()\n await closingAll([a], async () => {\n await b.subscribe('contract.left.*', async () => undefined, {\n name: 'contract-left-behind',\n })\n await b.subscribe('contract.left.*', async () => undefined)\n await b.close()\n const handled: string[] = []\n await a.subscribe('contract.left.*', async (e) => void handled.push(e.id), {\n name: 'contract-live',\n })\n const e = event('contract.left.x')\n\n const startedAt = Date.now()\n await a.publish(e)\n const elapsed = Date.now() - startedAt\n\n expect(handled).toEqual([e.id])\n expect(elapsed).toBeLessThan(ackTimeoutMs / 2)\n })\n },\n SLOW,\n )\n\n it(\n 'an entry pending on a stopped consumer of a named group is handled by the live one after claimIdleMs and before ackTimeoutMs',\n async () => {\n const a = await make()\n const b = await second()\n const held = gate()\n let closingB: Promise<void> | undefined\n try {\n let receivedByB: number | undefined\n await b.subscribe(\n 'contract.claim.*',\n async () => {\n receivedByB = Date.now()\n await held.wait\n },\n { name: 'contract-claimed' },\n )\n const stranded = event('contract.claim.x')\n // a holds no subscription to the group yet, so this publish waits on nothing and b's consumer takes it.\n await a.publish(stranded)\n await until(() => receivedByB !== undefined, 'b to receive the entry', ackTimeoutMs)\n closingB = b.close()\n\n const byA: Array<{ id: string; at: number }> = []\n await a.subscribe(\n 'contract.claim.*',\n async (e) => void byA.push({ id: e.id, at: Date.now() }),\n {\n name: 'contract-claimed',\n },\n )\n const next = event('contract.claim.x')\n const startedAt = Date.now()\n await a.publish(next)\n const publishMs = Date.now() - startedAt\n await until(\n () => byA.some((h) => h.id === stranded.id),\n 'a to take over the stranded entry',\n ackTimeoutMs * 2,\n )\n\n const claimed = byA.find((h) => h.id === stranded.id)!\n const idle = claimed.at - receivedByB!\n expect(idle, 'taken over before claimIdleMs').toBeGreaterThanOrEqual(claimIdleMs - 50)\n expect(idle, 'taken over only after ackTimeoutMs').toBeLessThan(ackTimeoutMs)\n expect(byA.filter((h) => h.id === stranded.id).length).toBe(1)\n expect(publishMs, 'a publish on the group waited out the timeout').toBeLessThan(\n ackTimeoutMs,\n )\n } finally {\n held.open()\n await closingB\n await a.close()\n }\n },\n SLOW,\n )\n\n it(\n 'an unnamed subscription unsubscribed while publish waits on it lets publish resolve well before ackTimeoutMs',\n async () => {\n const a = await make()\n const held = gate()\n try {\n let entered = false\n const sub = await a.subscribe('contract.wait.*', async () => {\n entered = true\n await held.wait\n })\n const publishing = a.publish(event('contract.wait.x')).then(\n () => Date.now(),\n (error: unknown) => error,\n )\n await until(() => entered, 'the handler to start', ackTimeoutMs)\n\n const unsubscribedAt = Date.now()\n const unsubscribing = a.unsubscribe(sub)\n const outcome = await publishing\n\n expect(typeof outcome, `publish rejected: ${String(outcome)}`).toBe('number')\n expect((outcome as number) - unsubscribedAt).toBeLessThan(ackTimeoutMs / 2)\n held.open()\n await unsubscribing\n } finally {\n held.open()\n await a.close()\n }\n },\n SLOW,\n )\n })\n })\n}\n","import { randomUUID } from 'node:crypto'\nimport { describe, expect, it } from 'vitest'\nimport type { EventBusAdapter, NymbalEvent } from '@nymbalhq/types'\nimport type { Build } from './common.js'\nimport type { DeliveryOptions } from './event-bus-delivery.js'\n\n// What a bus does when a handler throws. A named subscription's throw rejects the publish with `handler_failed`\n// naming it, once every other matching handler has finished; an unnamed one's is logged and fails nothing; a batch is\n// handed out whole before it rejects; replay never rejects. The bus never retries on its own: the store publishes the\n// event again, and that reaches every subscription. With `second` and `timing`, a failure on another instance is\n// reported rather than timed out. Kills: a swallowed error (the store marks the event delivered and the side effect is\n// lost), a rejection before the slow handlers finish, a batch cut short, a claim loop that re-runs the failed handler,\n// and a cross-instance failure read as a success.\n\nconst SLOW = 60_000\n/** How long the slow handler takes: a rejection before it has finished is the defect. */\nconst SLOW_HANDLER_MS = 200\n/** The window a single-process bus is watched for a retry of its own; a shared bus is watched over 3 × claimIdleMs. */\nconst IN_PROCESS_WINDOW_MS = 200\n\nfunction event(type: string, payload: Record<string, unknown> = {}): NymbalEvent {\n return {\n id: `evt-${randomUUID()}`,\n type,\n timestamp: new Date().toISOString(),\n source: 'contract-failure',\n correlationId: `corr-${randomUUID()}`,\n payload,\n metadata: { storeId: 'contract', environment: 'development', version: '0.0.0' },\n }\n}\n\nconst delay = (ms: number): Promise<void> => new Promise((r) => setTimeout(r, ms))\n\nasync function until(check: () => boolean, label: string, ms: number): Promise<void> {\n const deadline = Date.now() + ms\n while (!check()) {\n if (Date.now() > deadline) throw new Error(`timed out after ${ms} ms waiting for ${label}`)\n await delay(10)\n }\n}\n\nfunction gate(): { wait: Promise<void>; open(): void } {\n let open!: () => void\n const wait = new Promise<void>((r) => {\n open = r\n })\n return { wait, open }\n}\n\nasync function closing(buses: EventBusAdapter[], body: () => Promise<void>): Promise<void> {\n try {\n await body()\n } finally {\n for (const bus of buses) await bus.close()\n }\n}\n\ninterface Settled {\n state: 'resolved' | 'rejected'\n error: unknown\n /** When it settled. */\n at: number\n /** How long it took. */\n ms: number\n}\n\nasync function settled(promise: Promise<unknown>): Promise<Settled> {\n const started = Date.now()\n try {\n await promise\n return { state: 'resolved', error: undefined, at: Date.now(), ms: Date.now() - started }\n } catch (error) {\n return { state: 'rejected', error, at: Date.now(), ms: Date.now() - started }\n }\n}\n\ninterface Failure {\n name: string\n code: string\n message: string\n context: {\n eventId?: unknown\n eventType?: unknown\n failed?: Array<{ subscription: string; message: string }>\n }\n}\n\n/** The rejection as the store reads it: by name and code, so a copy of the error class in another package counts. */\nfunction failure(outcome: Settled): Failure {\n expect(outcome.state, 'publish resolved, so the failure was swallowed').toBe('rejected')\n const e = outcome.error as Partial<Failure>\n return {\n name: String(e.name),\n code: String(e.code),\n message: String(e.message),\n context: (e.context ?? {}) as Failure['context'],\n }\n}\n\nconst failedNames = (f: Failure): string[] => (f.context.failed ?? []).map((x) => x.subscription)\n\n/** The handler-failure cases, registered inside the suite's describe. */\nexport function eventBusFailureCases(make: Build<EventBusAdapter>, opts: DeliveryOptions): void {\n const window = opts.timing === undefined ? IN_PROCESS_WINDOW_MS : 3 * opts.timing.claimIdleMs\n\n describe('reports handler failures', () => {\n it(\n 'a named handler that throws rejects publish with handler_failed naming it alone, only after the other named handlers (one of them slow) have each run once and finished; a throwing unnamed handler is named nowhere; replay past a throwing derived handler resolves',\n async () => {\n const bus = await make()\n await closing([bus], async () => {\n const type = 'contract.failure.v1'\n const ran = { a: 0, b: 0, c: 0 }\n const finished: Record<'b' | 'c', number | undefined> = { b: undefined, c: undefined }\n await bus.subscribe(\n type,\n async () => {\n ran.a += 1\n throw new Error('contract handler A refused')\n },\n { name: 'contract-failure-a' },\n )\n await bus.subscribe(\n type,\n async () => {\n ran.b += 1\n await delay(SLOW_HANDLER_MS)\n finished.b = Date.now()\n },\n { name: 'contract-failure-b' },\n )\n await bus.subscribe(\n type,\n async () => {\n ran.c += 1\n finished.c = Date.now()\n },\n { name: 'contract-failure-c' },\n )\n await bus.subscribe(type, async () => {\n throw new Error('contract admin tab refused')\n })\n const e = event(type)\n\n const outcome = await settled(bus.publish(e))\n\n expect(ran).toEqual({ a: 1, b: 1, c: 1 })\n expect(finished.b, 'the slow handler finished before the rejection').toBeLessThanOrEqual(\n outcome.at,\n )\n expect(finished.c).toBeLessThanOrEqual(outcome.at)\n expect(outcome.ms).toBeGreaterThanOrEqual(SLOW_HANDLER_MS - 10)\n\n const rebuilt: string[] = []\n await bus.subscribe(\n 'contract.failure-replay.v1',\n async () => {\n throw new Error('contract projection refused')\n },\n { name: 'contract-failure-projection-a', derived: true },\n )\n await bus.subscribe('contract.failure-replay.v1', async (r) => void rebuilt.push(r.id), {\n name: 'contract-failure-projection-b',\n derived: true,\n })\n const replayed = [\n event('contract.failure-replay.v1'),\n event('contract.failure-replay.v1'),\n ]\n const replay = await settled(bus.replay(replayed))\n expect(replay.state).toBe('resolved')\n expect(rebuilt).toEqual(replayed.map((r) => r.id))\n\n const f = failure(outcome)\n expect([f.name, f.code]).toEqual(['AdapterError', 'adapter.handler_failed'])\n expect([f.context.eventId, f.context.eventType]).toEqual([e.id, e.type])\n expect(failedNames(f)).toEqual(['contract-failure-a'])\n expect(f.context.failed?.[0]?.message).toContain('contract handler A refused')\n })\n },\n SLOW,\n )\n\n it(\n 'publishBatch of three events whose second fails a named handler hands all three, in order, to every subscription and only then rejects with handler_failed naming that event and subscription',\n async () => {\n const bus = await make()\n await closing([bus], async () => {\n const type = 'contract.failure-batch.v1'\n const picky: string[] = []\n const other: string[] = []\n const unnamed: string[] = []\n await bus.subscribe(\n type,\n async (e) => {\n picky.push(e.id)\n if ((e.payload as { seq: number }).seq === 1)\n throw new Error('contract picky refused')\n },\n { name: 'contract-failure-picky' },\n )\n await bus.subscribe(\n type,\n async (e) => {\n await delay(50)\n other.push(e.id)\n },\n { name: 'contract-failure-other' },\n )\n await bus.subscribe(type, async (e) => {\n await delay(50)\n unnamed.push(e.id)\n })\n const events = [0, 1, 2].map((seq) => event(type, { seq }))\n const seenAtRejection: string[][] = []\n\n const outcome = await settled(\n bus.publishBatch(events).catch((error: unknown) => {\n seenAtRejection.push([...picky], [...other], [...unnamed])\n throw error\n }),\n )\n\n const f = failure(outcome)\n expect(f.code).toBe('adapter.handler_failed')\n expect(f.context.eventId).toBe(events[1]!.id)\n expect(failedNames(f)).toEqual(['contract-failure-picky'])\n const ids = events.map((e) => e.id)\n expect(\n seenAtRejection,\n 'what each subscription had been handed when the batch rejected',\n ).toEqual([ids, ids, ids])\n })\n },\n SLOW,\n )\n\n it(\n 'publishing a rejected event again reaches every subscription again and resolves once the failed handler passes; in the window after the rejection the bus ran the failed handler only once per publish',\n async () => {\n const bus = await make()\n await closing([bus], async () => {\n const type = 'contract.failure-again.v1'\n const ran = { a: 0, b: 0, c: 0, unnamed: 0 }\n await bus.subscribe(\n type,\n async () => {\n ran.a += 1\n if (ran.a === 1) throw new Error('contract handler A refused once')\n },\n { name: 'contract-again-a' },\n )\n await bus.subscribe(type, async () => void (ran.b += 1), { name: 'contract-again-b' })\n await bus.subscribe(type, async () => void (ran.c += 1), { name: 'contract-again-c' })\n await bus.subscribe(type, async () => void (ran.unnamed += 1))\n const e = event(type)\n\n const first = await settled(bus.publish(e))\n expect(failure(first).code).toBe('adapter.handler_failed')\n // Watched for a retry the bus would make on its own (a claim of the failed entry): there must be none.\n await delay(window)\n const afterWindow = { ...ran }\n expect(afterWindow.a, 'the failed handler ran again without a publish').toBe(1)\n\n const second = await settled(bus.publish(e))\n\n expect(second.state, String(second.error)).toBe('resolved')\n expect(ran.a).toBe(2)\n expect(ran.b).toBe(2)\n expect(ran.c).toBe(ran.b)\n expect(ran.unnamed).toBe(ran.b)\n expect(ran.b - afterWindow.b, 'the second publish reached B again').toBe(1)\n })\n },\n SLOW,\n )\n\n const second = opts.second\n const timing = opts.timing\n if (second === undefined || timing === undefined) return\n\n it(\n 'a named handler that throws on another instance fails the publish on this one with handler_failed, not publish_timeout, well within ackTimeoutMs',\n async () => {\n const a = await make()\n const b = await second()\n const held = gate()\n let holding: Promise<Settled> | undefined\n try {\n const group = 'contract-remote'\n const hold = 'contract.remote.hold'\n const target = 'contract.remote.target'\n const ranOn: Record<string, string[]> = {}\n const note = (id: string, where: string) => (ranOn[id] ??= []).push(where)\n let aHolding = false\n // a's consumer of the group is kept busy on `hold`, so the next entry can only be read by b's.\n await a.subscribe(\n 'contract.remote.*',\n async (e) => {\n note(e.id, 'a')\n if (e.type === hold) {\n aHolding = true\n await held.wait\n }\n },\n { name: group },\n )\n holding = settled(a.publish(event(hold)))\n await until(() => aHolding, 'a to take the holding entry', timing.ackTimeoutMs)\n\n await b.subscribe(\n 'contract.remote.*',\n async (e) => {\n if (e.type === hold) return\n note(e.id, 'b')\n throw new Error('contract remote handler refused')\n },\n { name: group },\n )\n const e = event(target)\n\n const outcome = await settled(a.publish(e))\n\n expect(ranOn[e.id], 'the failing handler ran on the second instance only').toEqual(['b'])\n const f = failure(outcome)\n expect(f.code, f.message).toBe('adapter.handler_failed')\n expect(failedNames(f)).toEqual([group])\n expect(outcome.ms).toBeLessThan(timing.ackTimeoutMs / 2)\n } finally {\n held.open()\n await holding\n await a.close()\n await b.close()\n }\n },\n SLOW,\n )\n\n it(\n 'a named handler that fails once on another instance, then passes on the second publish within ackTimeoutMs: the first publish rejects and the second resolves, and the handler ran twice',\n async () => {\n const a = await make()\n const b = await second()\n const held = gate()\n let holding: Promise<Settled> | undefined\n try {\n const group = 'contract-remote-once'\n const hold = 'contract.remote-once.hold'\n const target = 'contract.remote-once.target'\n const ranOn: Record<string, string[]> = {}\n const note = (id: string, where: string) => (ranOn[id] ??= []).push(where)\n let aHolding = false\n // a's consumer of the group is kept busy on `hold` throughout, so both publishes are read by b's.\n await a.subscribe(\n 'contract.remote-once.*',\n async (e) => {\n note(e.id, 'a')\n if (e.type === hold) {\n aHolding = true\n await held.wait\n }\n },\n { name: group },\n )\n holding = settled(a.publish(event(hold)))\n await until(() => aHolding, 'a to take the holding entry', timing.ackTimeoutMs)\n\n let runs = 0\n await b.subscribe(\n 'contract.remote-once.*',\n async (e) => {\n if (e.type === hold) return\n note(e.id, 'b')\n runs += 1\n if (runs === 1) throw new Error('contract remote handler refused once')\n },\n { name: group },\n )\n const e = event(target)\n\n const first = await settled(a.publish(e))\n const again = await settled(a.publish(e))\n\n expect(ranOn[e.id], 'the handler ran on the second instance, once per publish').toEqual([\n 'b',\n 'b',\n ])\n expect(failure(first).code).toBe('adapter.handler_failed')\n // The second publish comes while the first one's failure is still within ackTimeoutMs, where a failure\n // recorded per event rather than per delivery would still be read.\n expect(again.at - first.at).toBeLessThan(timing.ackTimeoutMs)\n expect(again.state, String(again.error)).toBe('resolved')\n } finally {\n held.open()\n await holding\n await a.close()\n await b.close()\n }\n },\n SLOW,\n )\n })\n}\n","import { describe, expect, it } from 'vitest'\nimport type { MediaStorage } from '@nymbalhq/types'\nimport { CASE_MS, healthAndDowntime, type Build, type ContractOptions } from './common.js'\n\nexport interface MediaStorageContractOptions extends ContractOptions<MediaStorage> {\n /** Reads back the bytes a URL `put` returned serves: the storage's public URL, or the file a local URL names. */\n fetchUrl: (url: string) => Promise<Uint8Array>\n}\n\n/**\n * The media storage contract every implementation runs: `put` resolves with a URL, and the bytes read back from that\n * URL (through `fetchUrl`, which knows where the storage serves from) are the bytes that were put; then health (and,\n * given `unreachable`, downtime).\n */\nexport function runMediaStorageContract(\n name: string,\n make: Build<MediaStorage>,\n options: MediaStorageContractOptions,\n): void {\n const { fetchUrl } = options\n describe(`MediaStorage contract: ${name}`, () => {\n it('reports put among its capabilities', async () => {\n const storage = await make()\n expect(storage.capabilities()).toContain('put')\n }, CASE_MS)\n\n it('put then a read of the returned url gives back the same bytes, for nested keys too', async () => {\n const storage = await make()\n const bodies = new Map<string, Uint8Array>([\n ['image.png', Uint8Array.from([137, 80, 78, 71, 0, 255, 1])],\n ['products/42/large.jpg', new TextEncoder().encode('jpeg bytes ✓')],\n ['empty.txt', new Uint8Array(0)],\n ])\n const urls = new Set<string>()\n for (const [key, body] of bodies) {\n const { url } = await storage.put(key, body, 'application/octet-stream')\n urls.add(url)\n expect([...(await fetchUrl(url))]).toEqual([...body])\n }\n expect(urls.size).toBe(bodies.size)\n }, CASE_MS)\n\n it('a second put under a key replaces what the url serves', async () => {\n const storage = await make()\n await storage.put('replaced.bin', Uint8Array.from([1, 2, 3]), 'application/octet-stream')\n const { url } = await storage.put(\n 'replaced.bin',\n Uint8Array.from([9]),\n 'application/octet-stream',\n )\n expect([...(await fetchUrl(url))]).toEqual([9])\n }, CASE_MS)\n\n healthAndDowntime(make, options.unreachable, 'put()', (storage) =>\n storage.put('contract-down.bin', Uint8Array.from([1]), 'application/octet-stream'),\n )\n })\n}\n","import { randomUUID } from 'node:crypto'\nimport { describe, expect, it } from 'vitest'\nimport type { PaymentsAdapter } from '@nymbalhq/types'\nimport { CASE_MS, healthAndDowntime, type Build, type ContractOptions } from './common.js'\n\nexport interface PaymentsContractOptions extends ContractOptions<PaymentsAdapter> {\n /** One webhook as the provider would deliver it, signed. Given, the suite parses it twice and compares. */\n signedWebhook?: () => { rawBody: string | Buffer; signature: string }\n}\n\n/** The intent amount of the refund idempotency case: odd, so its two halves differ. */\nconst TOTAL = 1999\n\n/** The code a call rejected with, or null when it resolved. */\nasync function rejectionCode(call: Promise<unknown>): Promise<unknown> {\n return call.then(\n () => null,\n (err: unknown) => (err as { code?: unknown } | null)?.code ?? err,\n )\n}\n\nexport function runPaymentsContract(\n name: string,\n build: Build<PaymentsAdapter>,\n options: PaymentsContractOptions = {},\n): void {\n describe(`PaymentsAdapter contract: ${name}`, () => {\n it(\n 'createPaymentIntent returns a clientSecret and id',\n async () => {\n const adapter = await build()\n const intent = await adapter.createPaymentIntent({\n amountMinor: 1000,\n currency: 'GBP',\n orderRef: `contract-${randomUUID()}`,\n })\n expect(intent.id).toBeTruthy()\n expect(intent.clientSecret).toBeTruthy()\n expect(intent.amountMinor).toBe(1000)\n expect(intent.currency).toBe('GBP')\n },\n CASE_MS,\n )\n\n it(\n 'getPaymentStatus returns a valid status',\n async () => {\n const adapter = await build()\n const intent = await adapter.createPaymentIntent({ amountMinor: 500, currency: 'GBP' })\n const status = await adapter.getPaymentStatus(intent.id)\n expect([\n 'requires_payment_method',\n 'requires_confirmation',\n 'requires_action',\n 'processing',\n 'requires_capture',\n 'succeeded',\n 'cancelled',\n 'failed',\n ]).toContain(status)\n },\n CASE_MS,\n )\n\n // Seen through the payments surface alone: after T/2 twice under one key, the remainder still fits and one more\n // minor unit does not, which holds only when the retry refunded nothing. Kills: a retry that refunds again.\n it(\n 'idempotency: a refund repeated with the same idempotencyKey returns the same refund and refunds once',\n async () => {\n const adapter = await build()\n const intent = await adapter.createPaymentIntent({\n amountMinor: TOTAL,\n currency: 'GBP',\n orderRef: `contract-${randomUUID()}`,\n })\n if (intent.status !== 'succeeded') await adapter.capturePayment(intent.id)\n const half = Math.floor(TOTAL / 2)\n const key = `contract-refund-${randomUUID()}`\n\n const first = await adapter.refund(intent.id, half, 'requested_by_customer', {\n idempotencyKey: key,\n })\n const again = await adapter.refund(intent.id, half, 'requested_by_customer', {\n idempotencyKey: key,\n })\n expect(again.refundId, 'the retry under the same key made another refund').toBe(\n first.refundId,\n )\n expect(again.amountMinor).toBe(first.amountMinor)\n\n const rest = await adapter.refund(intent.id, TOTAL - half, 'requested_by_customer', {\n idempotencyKey: `${key}-rest`,\n })\n expect(rest.amountMinor + first.amountMinor).toBe(TOTAL)\n const over = await rejectionCode(\n adapter.refund(intent.id, 1, 'requested_by_customer', { idempotencyKey: `${key}-over` }),\n )\n expect(over, 'a minor unit past the amount was refunded').toBe('payment.refund_rejected')\n },\n CASE_MS,\n )\n\n const signedWebhook = options.signedWebhook\n if (signedWebhook !== undefined) {\n it(\n 'idempotency: parsing one signed webhook event twice gives equal results',\n async () => {\n const adapter = await build()\n const { rawBody, signature } = signedWebhook()\n const first = await adapter.parseWebhook(rawBody, signature)\n const second = await adapter.parseWebhook(rawBody, signature)\n expect(second).toEqual(first)\n },\n CASE_MS,\n )\n }\n\n healthAndDowntime(build, options.unreachable, 'createPaymentIntent()', (adapter) =>\n adapter.createPaymentIntent({ amountMinor: 100, currency: 'GBP' }),\n )\n })\n}\n","import { randomUUID } from 'node:crypto'\nimport fc from 'fast-check'\nimport { describe, expect, it } from 'vitest'\nimport type { Review, ReviewsAdapter, ReviewsResult } from '@nymbalhq/types'\nimport { CASE_MS, healthAndDowntime, type Build, type ContractOptions } from './common.js'\n\n// Every case seeds under a product of its own, and reads what it seeded with the moderation status the adapter\n// reported on submitReview: one that files reviews for moderation reads them as pending, one that auto-approves as\n// approved.\n\nasync function seed(adapter: ReviewsAdapter, count: number): Promise<Review[]> {\n const productId = `contract-reviews-${randomUUID()}`\n const seeded: Review[] = []\n for (let i = 0; i < count; i++) {\n const { review } = await adapter.submitReview({\n productId,\n customerId: null,\n orderId: null,\n rating: (i % 5) + 1,\n title: `review ${i}`,\n body: `body ${i}`,\n })\n seeded.push(review)\n }\n return seeded\n}\n\n/** Every page from page 1, stopping after `maxPages`: a cursor that never ends shows as a walk that long. */\nasync function walk(\n adapter: ReviewsAdapter,\n first: Review,\n limit: number,\n maxPages: number,\n): Promise<ReviewsResult[]> {\n const pages: ReviewsResult[] = []\n let cursor: string | undefined\n do {\n const page = await adapter.getProductReviews(first.productId, {\n limit,\n status: first.moderationStatus,\n ...(cursor !== undefined && { cursor }),\n })\n pages.push(page)\n cursor = page.nextCursor ?? undefined\n } while (cursor !== undefined && pages.length < maxPages)\n return pages\n}\n\nexport function runReviewsContract(\n name: string,\n build: Build<ReviewsAdapter>,\n options: ContractOptions<ReviewsAdapter> = {},\n): void {\n describe(`ReviewsAdapter contract: ${name}`, () => {\n it(\n 'submitReview returns the created review',\n async () => {\n const adapter = await build()\n const productId = `contract-reviews-${randomUUID()}`\n const { review } = await adapter.submitReview({\n productId,\n customerId: null,\n orderId: null,\n rating: 5,\n title: 'Great!',\n body: 'Really liked it.',\n })\n expect(review.productId).toBe(productId)\n expect(review.rating).toBe(5)\n expect(review.id).toBeTruthy()\n },\n CASE_MS,\n )\n\n it(\n 'getProductReviews returns the submitted review, read under the status submitReview reported',\n async () => {\n const adapter = await build()\n const [review] = await seed(adapter, 1)\n const { items } = await adapter.getProductReviews(review!.productId, {\n status: review!.moderationStatus,\n })\n expect(items.map((r) => r.id)).toEqual([review!.id])\n expect(items[0]!.productId).toBe(review!.productId)\n },\n CASE_MS,\n )\n\n it(\n 'getAggregateRating is consistent: its histogram sums to its count, and an approved review is counted',\n async () => {\n const adapter = await build()\n const [review] = await seed(adapter, 1)\n const agg = await adapter.getAggregateRating(review!.productId)\n expect(agg.productId).toBe(review!.productId)\n expect(Object.values(agg.histogram).reduce((a, b) => a + b, 0)).toBe(agg.count)\n if (agg.count === 0) expect(agg.average).toBe(0)\n else {\n expect(agg.average).toBeGreaterThanOrEqual(1)\n expect(agg.average).toBeLessThanOrEqual(5)\n }\n if (review!.moderationStatus === 'approved') expect(agg.count).toBeGreaterThanOrEqual(1)\n },\n CASE_MS,\n )\n\n // Kills: an adapter that ignores the cursor (page 1 again), returns no next cursor after the first page, or\n // repeats or skips a review between pages.\n it(\n 'pagination: over seeds larger than a page, the cursor walk from page 1 yields each review once, the walk is the seed, no page exceeds limit and nextCursor is null exactly on the last page',\n async () => {\n const adapter = await build()\n await fc.assert(\n fc.asyncProperty(\n fc.integer({ min: 1, max: 5 }),\n fc.integer({ min: 1, max: 8 }),\n async (limit, extra) => {\n const seeded = await seed(adapter, limit + extra)\n const status = seeded[0]!.moderationStatus\n const expected = seeded.filter((r) => r.moderationStatus === status).map((r) => r.id)\n const pages = await walk(\n adapter,\n seeded[0]!,\n limit,\n Math.ceil(expected.length / limit) + 2,\n )\n const walked = pages.flatMap((p) => p.items.map((r) => r.id))\n\n expect(new Set(walked).size, 'a review came back on two pages').toBe(walked.length)\n expect([...walked].sort()).toEqual([...expected].sort())\n for (const page of pages) expect(page.items.length).toBeLessThanOrEqual(limit)\n expect(pages.map((p) => p.nextCursor === null)).toEqual(\n pages.map((_, i) => i === pages.length - 1),\n )\n },\n ),\n { numRuns: 15 },\n )\n },\n 120_000,\n )\n\n healthAndDowntime(build, options.unreachable, 'getProductReviews()', (adapter) =>\n adapter.getProductReviews(`contract-reviews-${randomUUID()}`, { limit: 1 }),\n )\n })\n}\n","import { randomUUID } from 'node:crypto'\nimport fc from 'fast-check'\nimport { describe, expect, it } from 'vitest'\nimport type { SearchAdapter, SearchResult } from '@nymbalhq/types'\nimport { CASE_MS, healthAndDowntime, type Build, type ContractOptions } from './common.js'\nimport {\n matchesQuery,\n searchTerms,\n tierOf,\n toSearchDocument,\n type ContractProduct,\n} from './search-oracle.js'\n\n// The search contract. The cases are index-agnostic: the index may be shared across cases and runs and no runner\n// truncates it. Every generated product carries a run token term in its name and every query puts the token first, so\n// the AND of the query's terms scopes it to the run, the oracle is over the run's products, and the run removes them\n// when it ends.\n\nexport interface SearchContractOptions extends ContractOptions<SearchAdapter> {\n /** The adapter ranks by tiers (every term in the name, then every term in name, SKU or variant name), then score,\n * then id. Native does; a vendor's need not, so the ranking case runs only when the runner says so. */\n ranking?: boolean\n /** The adapter reports `facet` and counts `facet('categoryIds', {query, filters})` within the query's matches. */\n facets?: boolean\n /** This adapter's cursor for an offset, valid or not (it encodes; only search validates), so the malformed-cursor\n * case can build a negative and a non-integer cursor. Without it only the undecodable and the stale cursor run. */\n cursorAt?: (offset: number) => string\n /** fast-check runs per property (default 25). */\n numRuns?: number\n}\n\n// --- Generators ---------------------------------------------------------------------------------------------------\n\n/** One length, a leading letter no generated word uses: no token is a prefix of another or of a generated word. */\nfunction runToken(): string {\n return `t${randomUUID().replace(/-/g, '').slice(0, 15)}`\n}\n\n/** Words over a small alphabet, so they share prefixes and collide often. */\nconst word = fc.string({\n unit: fc.constantFrom('a', 'b', 'c', 'd', '1', '2'),\n minLength: 1,\n maxLength: 3,\n})\nconst words = (max: number) => fc.array(word, { maxLength: max }).map((ws) => ws.join(' '))\n\ninterface GenProduct {\n name: string\n description: string\n // priceMinor's digits overlap the words' digits: a search over every field would match on a price.\n variants: Array<{ sku: string; name: string; priceMinor: number }>\n categories: number[]\n}\n\nconst CATEGORIES = 3\n\nconst genProduct: fc.Arbitrary<GenProduct> = fc.record({\n name: words(3),\n description: words(6),\n variants: fc.array(\n fc.record({ sku: word, name: words(2), priceMinor: fc.integer({ min: 1, max: 2222 }) }),\n { maxLength: 3 },\n ),\n categories: fc.subarray([0, 1, 2]),\n})\n\n/** The run's category ids: one term each, `c0…`, `c1…`; a search over every field would match `c1` on one. */\nfunction runCategories(token: string): string[] {\n return Array.from({ length: CATEGORIES }, (_, k) => `c${k}${token.slice(1)}`)\n}\n\nfunction materialise(token: string, gen: GenProduct, i: number, cats: string[]): ContractProduct {\n return {\n id: `${token}-${i}`,\n name: gen.name === '' ? token : `${token} ${gen.name}`,\n description: gen.description,\n variants: gen.variants,\n categoryIds: gen.categories.map((k) => cats[k]!),\n }\n}\n\n// --- Walking -------------------------------------------------------------------------------------------------------\n\nasync function walk(\n adapter: SearchAdapter,\n query: string,\n limit: number,\n expectedMatches: number,\n filters?: Record<string, unknown>,\n): Promise<SearchResult[]> {\n // Room for every page an exact walk needs, and two more: a walk past it is one whose cursor does not advance.\n const maxPages = Math.ceil(expectedMatches / limit) + 2\n const pages: SearchResult[] = []\n const seen = new Set<string>()\n let cursor: string | undefined\n for (;;) {\n const page = await adapter.search(query, {\n limit,\n ...(cursor !== undefined && { cursor }),\n ...(filters !== undefined && { filters }),\n })\n pages.push(page)\n // Fails at the first repeat rather than after the whole walk: a cursor read as page 1 then costs two pages, not\n // every page, on each of the runs fast-check shrinks through.\n const again = page.items.map((item) => item.id).filter((id) => seen.has(id))\n expect(again, `the walk for \"${query}\": an id came back on page ${pages.length}`).toEqual([])\n for (const item of page.items) seen.add(item.id)\n if (page.nextCursor === null) return pages\n expect(\n pages.length,\n `the walk for \"${query}\" did not end within ${maxPages} pages`,\n ).toBeLessThan(maxPages)\n cursor = page.nextCursor\n }\n}\n\nconst idsOf = (pages: SearchResult[]) => pages.flatMap((p) => p.items.map((item) => item.id))\n\n/** One walk against the oracle's match set: each match once, an exact total, no page past limit, a last page. */\nfunction expectExactWalk(\n pages: SearchResult[],\n expected: string[],\n limit: number,\n label: string,\n): void {\n const ids = idsOf(pages)\n expect(new Set(ids).size, `${label}: an id came back on two pages`).toBe(ids.length)\n expect([...ids].sort(), `${label}: the walk's union is not the oracle's match set`).toEqual(\n [...expected].sort(),\n )\n for (const [i, page] of pages.entries()) {\n expect(page.total, `${label}: total on page ${i + 1}`).toBe(expected.length)\n expect(page.items.length, `${label}: page ${i + 1} exceeds limit`).toBeLessThanOrEqual(limit)\n expect(\n page.nextCursor === null,\n `${label}: nextCursor is null on page ${i + 1} of ${pages.length}`,\n ).toBe(i === pages.length - 1)\n // With an exact total the page that completes the walk is the last: only a walk with no match has an empty page.\n if (expected.length > 0)\n expect(page.items.length, `${label}: page ${i + 1} is empty`).toBeGreaterThan(0)\n }\n}\n\nconst SLOW = 180_000\n\nexport function runSearchContract(\n name: string,\n build: Build<SearchAdapter>,\n options: SearchContractOptions = {},\n): void {\n const numRuns = options.numRuns ?? 25\n\n describe(`SearchAdapter contract: ${name}`, () => {\n it(\n 'index returns count of indexed documents',\n async () => {\n const adapter = await build()\n const result = await adapter.index([\n { id: 'doc-1', type: 'product', fields: { name: 'Widget' } },\n { id: 'doc-2', type: 'product', fields: { name: 'Gadget' } },\n ])\n expect(result.indexed).toBe(2)\n },\n CASE_MS,\n )\n\n it(\n 'search returns indexed documents',\n async () => {\n const adapter = await build()\n await adapter.index([\n { id: 'search-doc-1', type: 'product', fields: { name: 'Searchable Item' } },\n ])\n const result = await adapter.search('Searchable')\n expect(result.items.length).toBeGreaterThanOrEqual(1)\n expect(result.total).toBeGreaterThanOrEqual(1)\n },\n CASE_MS,\n )\n\n it(\n 'remove deletes documents from index',\n async () => {\n const adapter = await build()\n const tag = `remove-${randomUUID()}`\n await adapter.index([{ id: tag, type: 'product', fields: { name: 'To Remove' } }])\n await adapter.remove([tag])\n const result = await adapter.search('To Remove')\n expect(result.items.find((i) => i.id === tag)).toBeUndefined()\n },\n CASE_MS,\n )\n\n it(\n 'facet returns values for a field',\n async () => {\n const adapter = await build()\n await adapter.index([\n { id: 'facet-doc-1', type: 'product', fields: { category: 'shirts' } },\n { id: 'facet-doc-2', type: 'product', fields: { category: 'trousers' } },\n { id: 'facet-doc-3', type: 'product', fields: { category: 'shirts' } },\n ])\n const facet = await adapter.facet('category')\n expect(typeof facet.field).toBe('string')\n expect(typeof facet.label).toBe('string')\n expect(Array.isArray(facet.values)).toBe(true)\n if (facet.values.length > 0) {\n expect(typeof facet.values[0]!.value).toBe('string')\n }\n },\n CASE_MS,\n )\n\n healthAndDowntime(build, options.unreachable, 'search()', (adapter) =>\n adapter.search('contract', { limit: 1 }),\n )\n\n describe('pages, ranking, facets and hostile input', () => {\n // Kills: a cursor that is ignored (page 1 again, or no next page), a total that counts the page or a capped\n // prefix, a filter that is skipped or only applied with a query, a removed doc that lingers, a re-index that\n // appends instead of replacing, and a tokeniser other than the oracle's (a price or category id searched,\n // punctuation kept, a prefix not matched).\n it(\n 'over generated catalogues and page sizes, the cursor walk yields each oracle match exactly once, total is exact on every page, nextCursor is null exactly on the last page and no page exceeds limit, with and without a category filter, after removals and re-indexes',\n async () => {\n const adapter = await build()\n await fc.assert(\n fc.asyncProperty(\n // The page size first: fast-check shrinks the arguments in order, so a failing walk shrinks its limit\n // before its catalogue, and the catalogue's products are shrunk once there are few of them.\n fc.integer({ min: 1, max: 40 }),\n fc.array(fc.record({ first: genProduct, second: fc.option(genProduct) }), {\n maxLength: 300,\n size: 'large',\n }),\n fc.array(word, { maxLength: 2 }),\n fc.integer({ min: 0, max: CATEGORIES - 1 }),\n fc.func(fc.boolean()),\n async (limit, catalogue, queryWords, filterCategory, removeIt) => {\n const token = runToken()\n const cats = runCategories(token)\n const first = catalogue.map((c, i) => materialise(token, c.first, i, cats))\n try {\n const indexed = await adapter.index(first.map(toSearchDocument))\n expect(indexed.indexed).toBe(first.length)\n // Re-indexes: the second version replaces the first.\n const current = catalogue.map((c, i) =>\n c.second === null ? first[i]! : materialise(token, c.second, i, cats),\n )\n const rewritten = current.filter((_, i) => catalogue[i]!.second !== null)\n if (rewritten.length > 0) await adapter.index(rewritten.map(toSearchDocument))\n // Removals.\n const removed = current.filter((p) => removeIt(p.id))\n if (removed.length > 0) await adapter.remove(removed.map((p) => p.id))\n const gone = new Set(removed.map((p) => p.id))\n const live = current.filter((p) => !gone.has(p.id))\n\n const query = [token, ...queryWords].join(' ')\n const matches = live.filter((p) => matchesQuery(p, query))\n const all = await walk(adapter, query, limit, matches.length)\n expectExactWalk(\n all,\n matches.map((p) => p.id),\n limit,\n `\"${query}\" limit ${limit}`,\n )\n\n const category = cats[filterCategory]!\n const inCategory = matches.filter((p) => p.categoryIds.includes(category))\n const filtered = await walk(adapter, query, limit, inCategory.length, {\n categoryIds: category,\n })\n expectExactWalk(\n filtered,\n inCategory.map((p) => p.id),\n limit,\n `\"${query}\" in ${category} limit ${limit}`,\n )\n\n // No removed id on any page of either walk.\n const shown = [...idsOf(all), ...idsOf(filtered)]\n expect(\n shown.filter((id) => gone.has(id)),\n 'a removed id came back',\n ).toEqual([])\n } finally {\n await adapter.remove(first.map((p) => p.id))\n }\n },\n ),\n { numRuns },\n )\n },\n SLOW,\n )\n\n if (options.ranking) {\n // Kills: an order by engine score alone (ts_rank_cd lets a description repeating the term outrank a name\n // hit), by insertion order, or one that differs between two walks of the same query.\n it(\n 'for any query, every all-terms-in-name match ranks above every other match and every name/SKU/variant-name match above every description-only match, however often the description repeats the term, and the same query walks in the same order twice',\n async () => {\n const adapter = await build()\n const placed = fc.record({\n base: genProduct,\n inName: fc.boolean(),\n inSku: fc.boolean(),\n inVariant: fc.boolean(),\n descriptionRepeats: fc.integer({ min: 0, max: 10 }),\n })\n await fc.assert(\n fc.asyncProperty(\n fc.array(placed, { minLength: 1, maxLength: 60 }),\n word,\n fc.option(word),\n fc.integer({ min: 1, max: 30 }),\n fc.integer({ min: 1, max: 30 }),\n async (catalogue, term, second, limitA, limitB) => {\n const token = runToken()\n const cats = runCategories(token)\n const products = catalogue.map((c, i): ContractProduct => {\n const p = materialise(token, c.base, i, cats)\n const variants =\n p.variants.length > 0\n ? [...p.variants]\n : [{ sku: 'zz', name: '', priceMinor: 1 }]\n if (c.inSku) variants[0] = { ...variants[0]!, sku: `${term}9` }\n if (c.inVariant)\n variants[0] = { ...variants[0]!, name: `${variants[0]!.name} ${term}` }\n return {\n ...p,\n name: c.inName ? `${p.name} ${term}` : p.name,\n description: `${p.description}${` ${term}`.repeat(c.descriptionRepeats)}`,\n variants,\n }\n })\n try {\n await adapter.index(products.map(toSearchDocument))\n const query = [token, term, ...(second === null ? [] : [second])].join(' ')\n const byId = new Map(products.map((p) => [p.id, p]))\n const matches = products.filter((p) => matchesQuery(p, query))\n\n const order = idsOf(await walk(adapter, query, limitA, matches.length))\n expect([...order].sort(), 'the walk is not the match set').toEqual(\n matches.map((p) => p.id).sort(),\n )\n const tiers = order.map((id) => tierOf(byId.get(id)!, query))\n for (let i = 1; i < tiers.length; i++) {\n expect(\n tiers[i - 1],\n `\"${query}\": ${order[i - 1]} (tier ${tiers[i - 1]}) ranked above ${order[i]} (tier ${tiers[i]})`,\n ).toBeGreaterThanOrEqual(tiers[i]!)\n }\n\n const again = idsOf(await walk(adapter, query, limitB, matches.length))\n expect(again, `\"${query}\" walked at limit ${limitA}, then ${limitB}`).toEqual(\n order,\n )\n } finally {\n await adapter.remove(products.map((p) => p.id))\n }\n },\n ),\n { numRuns },\n )\n },\n SLOW,\n )\n }\n\n if (options.facets) {\n // Kills: a facet that ignores the query or the filters, counts a capped prefix, or lists a category with\n // no match.\n it(\n \"facet('categoryIds', {query, filters}) counts, per category id, exactly the oracle's matches in that category under the filters, lists no category without one, and orders by count descending, then value\",\n async () => {\n const adapter = await build()\n expect(adapter.capabilities()).toContain('facet')\n await fc.assert(\n fc.asyncProperty(\n fc.array(genProduct, { maxLength: 150, size: 'medium' }),\n fc.array(word, { maxLength: 2 }),\n fc.option(fc.integer({ min: 0, max: CATEGORIES - 1 })),\n async (catalogue, queryWords, filterCategory) => {\n const token = runToken()\n const cats = runCategories(token)\n const products = catalogue.map((g, i) => materialise(token, g, i, cats))\n try {\n await adapter.index(products.map(toSearchDocument))\n const query = [token, ...queryWords].join(' ')\n const filter = filterCategory === null ? undefined : cats[filterCategory]!\n const matches = products.filter(\n (p) =>\n matchesQuery(p, query) &&\n (filter === undefined || p.categoryIds.includes(filter)),\n )\n const expected = new Map<string, number>()\n for (const p of matches)\n for (const c of p.categoryIds) expected.set(c, (expected.get(c) ?? 0) + 1)\n\n const facet = await adapter.facet('categoryIds', {\n query,\n ...(filter !== undefined && { filters: { categoryIds: filter } }),\n })\n const label = `facet for \"${query}\"${filter === undefined ? '' : ` in ${filter}`}`\n expect(\n Object.fromEntries(facet.values.map((v) => [v.value, v.count])),\n label,\n ).toEqual(Object.fromEntries(expected))\n const ordered = [...expected.entries()]\n .sort((a, b) => b[1] - a[1] || (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0))\n .map(([value]) => value)\n expect(\n facet.values.map((v) => v.value),\n `${label}: order`,\n ).toEqual(ordered)\n } finally {\n await adapter.remove(products.map((p) => p.id))\n }\n },\n ),\n { numRuns },\n )\n },\n SLOW,\n )\n }\n\n // Kills: raw input reaching FTS MATCH or to_tsquery (a syntax error, or an operator that changes the match),\n // a tokeniser on either side other than the oracle's (case, punctuation, non-ASCII), an empty query that returns\n // everything, and a malformed cursor read as page 1 or a stale one that errors.\n describe('hostile input', () => {\n const operator = fc.constantFrom(\n '\"',\n '*',\n 'NEAR',\n 'NEAR(',\n ':',\n '&',\n '|',\n '!',\n '(',\n ')',\n '-',\n '^',\n 'AND',\n 'OR',\n 'NOT',\n \"'\",\n '\\\\',\n '{',\n '}',\n '<->',\n ':*',\n '+',\n '%',\n '_',\n ';',\n '\\u0000',\n )\n const fragment = fc.oneof(\n fc.string({ unit: 'binary', maxLength: 6 }),\n operator,\n word,\n word.map((w) => w.toUpperCase()),\n )\n // Fragments glued together, so an operator sits against a word as it would in a typed query.\n const hostile = fc.array(fragment, { maxLength: 6 }).map((fs) => fs.join(''))\n const longTerm = 'a'.repeat(2047)\n const plain: GenProduct = { name: 'a b', description: 'c', variants: [], categories: [0] }\n\n it(\n \"any string after the run token, full unicode and FTS operators included, never throws and returns exactly the oracle's matches for the query's normalised terms\",\n async () => {\n const adapter = await build()\n await fc.assert(\n fc.asyncProperty(\n fc.array(genProduct, { maxLength: 40 }),\n hostile,\n async (catalogue, raw) => {\n const token = runToken()\n const cats = runCategories(token)\n const products = catalogue.map((g, i) => materialise(token, g, i, cats))\n try {\n await adapter.index(products.map(toSearchDocument))\n const query = `${token} ${raw}`\n const expected = products.filter((p) => matchesQuery(p, query)).map((p) => p.id)\n const result = await adapter.search(query, { limit: 100 })\n expect(result.items.map((d) => d.id).sort(), JSON.stringify(query)).toEqual(\n expected.sort(),\n )\n expect(result.total, JSON.stringify(query)).toBe(expected.length)\n } finally {\n await adapter.remove(products.map((p) => p.id))\n }\n },\n ),\n {\n numRuns: numRuns * 2,\n // A term one byte past Postgres's longest lexeme (2046 bytes; terms are ASCII, so bytes are\n // characters): in the query, in a description, and in both.\n examples: [\n [[plain], longTerm],\n [[{ ...plain, description: `c ${longTerm}` }], ''],\n [[{ ...plain, description: longTerm }], longTerm],\n ],\n },\n )\n },\n SLOW,\n )\n\n it(\n 'input with no terms returns no items, total 0 and no next page, over an index that holds products',\n async () => {\n const adapter = await build()\n const token = runToken()\n const products: ContractProduct[] = Array.from({ length: 5 }, (_, i) => ({\n id: `${token}-${i}`,\n name: `${token} a b`,\n description: 'c d',\n variants: [{ sku: 'a1', name: 'b', priceMinor: 100 }],\n categoryIds: [],\n }))\n await adapter.index(products.map(toSearchDocument))\n try {\n const termless = fc\n .array(\n fc.oneof(\n operator,\n fc.string({ unit: 'binary', maxLength: 4 }),\n fc.constantFrom(' ', '\\t', '\\n'),\n ),\n { maxLength: 6 },\n )\n .map((fs) => fs.join(''))\n .filter((s) => searchTerms(s).length === 0)\n await fc.assert(\n fc.asyncProperty(termless, async (raw) => {\n const result = await adapter.search(raw, { limit: 20 })\n expect(result.items.length, JSON.stringify(raw)).toBe(0)\n expect(result.total, JSON.stringify(raw)).toBe(0)\n expect(result.nextCursor, JSON.stringify(raw)).toBeNull()\n }),\n {\n numRuns: numRuns * 2,\n examples: [[''], [' '], [' '], ['*'], ['\"'], ['-'], ['é']],\n },\n )\n } finally {\n await adapter.remove(products.map((p) => p.id))\n }\n },\n SLOW,\n )\n\n it(\n 'a malformed cursor (undecodable, negative, non-integer) rejects, and a cursor at or past total, as after a removal between two pages, is an empty page with nextCursor null',\n async () => {\n const adapter = await build()\n const token = runToken()\n const products: ContractProduct[] = Array.from({ length: 6 }, (_, i) => ({\n id: `${token}-${i}`,\n name: `${token} cursor ${i}`,\n description: '',\n variants: [],\n categoryIds: [],\n }))\n await adapter.index(products.map(toSearchDocument))\n try {\n // A page-2 cursor taken while all six match, used after four are removed: its offset is past total.\n const first = await adapter.search(token, { limit: 4 })\n expect(first.total).toBe(products.length)\n expect(first.nextCursor, 'six matches at limit 4 have a second page').not.toBeNull()\n\n for (const cursor of ['not a cursor', '%%%', '!!']) {\n await expect(\n adapter.search(token, { limit: 2, cursor }),\n `cursor ${cursor}`,\n ).rejects.toThrow()\n }\n if (options.cursorAt !== undefined) {\n for (const offset of [-1, -20, 1.5, 0.25]) {\n await expect(\n adapter.search(token, { limit: 2, cursor: options.cursorAt(offset) }),\n `cursor at offset ${offset}`,\n ).rejects.toThrow()\n }\n }\n\n const kept = products.slice(0, 2)\n await adapter.remove(products.slice(2).map((p) => p.id))\n const stale = await adapter.search(token, { limit: 4, cursor: first.nextCursor! })\n expect(stale.items.length).toBe(0)\n expect(stale.nextCursor).toBeNull()\n expect(stale.total).toBe(kept.length)\n\n if (options.cursorAt !== undefined) {\n for (const offset of [kept.length, kept.length + 7]) {\n const past = await adapter.search(token, {\n limit: 4,\n cursor: options.cursorAt(offset),\n })\n expect(past.items.length, `offset ${offset}`).toBe(0)\n expect(past.nextCursor, `offset ${offset}`).toBeNull()\n expect(past.total, `offset ${offset}`).toBe(kept.length)\n }\n }\n } finally {\n await adapter.remove(products.map((p) => p.id))\n }\n },\n SLOW,\n )\n })\n })\n })\n}\n","import type { SearchDocument } from '@nymbalhq/types'\n\n// The search suite's oracle: one tokeniser, for query, index and expectation. A term is a maximal run of ASCII letters\n// and digits after lowercasing; everything else separates terms. A product matches a query iff the query has a term\n// and every query term is a prefix of one of the product's terms in name, SKU, variant name or description. Nothing\n// else it carries (slug, status, prices, category ids) is searched.\n\n/** The terms of a text, as search sees them. */\nexport function searchTerms(text: string): string[] {\n return text.toLowerCase().match(/[a-z0-9]+/g) ?? []\n}\n\n/** A product as the search handler indexes it, before it is a SearchDocument. */\nexport interface ContractProduct {\n id: string\n name: string\n description: string\n variants: Array<{ sku: string; name: string; priceMinor: number }>\n categoryIds: string[]\n}\n\n/** The document the search handler indexes for the product. */\nexport function toSearchDocument(p: ContractProduct): SearchDocument {\n return {\n id: p.id,\n type: 'product',\n fields: {\n slug: p.id,\n name: p.name,\n description: p.description,\n status: 'active',\n categoryIds: p.categoryIds,\n variants: p.variants.map((v) => ({ sku: v.sku, name: v.name, priceMinor: v.priceMinor })),\n },\n }\n}\n\nfunction prefixed(queryTerms: string[], docTerms: string[]): boolean {\n return queryTerms.every((q) => docTerms.some((d) => d.startsWith(q)))\n}\n\nfunction strongTerms(p: ContractProduct): string[] {\n return [\n ...searchTerms(p.name),\n ...p.variants.flatMap((v) => [...searchTerms(v.sku), ...searchTerms(v.name)]),\n ]\n}\n\n/** Does the product match the query. */\nexport function matchesQuery(p: ContractProduct, query: string): boolean {\n const q = searchTerms(query)\n return q.length > 0 && prefixed(q, [...strongTerms(p), ...searchTerms(p.description)])\n}\n\n/** 2: every term matches in the name; 1: every term matches in name, SKU or variant name; 0: otherwise. */\nexport function tierOf(p: ContractProduct, query: string): number {\n const q = searchTerms(query)\n if (prefixed(q, searchTerms(p.name))) return 2\n if (prefixed(q, strongTerms(p))) return 1\n return 0\n}\n","import { describe, expect, it } from 'vitest'\nimport type { ShippingAdapter } from '@nymbalhq/types'\nimport { CASE_MS, healthAndDowntime, type Build, type ContractOptions } from './common.js'\n\nconst REQUEST = {\n fromPostalCode: 'SW1A 1AA',\n toPostalCode: 'EC1A 1BB',\n toCountry: 'GB',\n weightGrams: 500,\n currency: 'GBP',\n}\n\nexport function runShippingContract(\n name: string,\n build: Build<ShippingAdapter>,\n options: ContractOptions<ShippingAdapter> = {},\n): void {\n describe(`ShippingAdapter contract: ${name}`, () => {\n it(\n 'rate returns an array of shipping options',\n async () => {\n const adapter = await build()\n const rates = await adapter.rate(REQUEST)\n expect(Array.isArray(rates)).toBe(true)\n if (rates.length > 0) {\n const rate = rates[0]!\n expect(typeof rate.amountMinor).toBe('number')\n expect(typeof rate.carrier).toBe('string')\n expect(typeof rate.estimatedDays).toBe('number')\n }\n },\n CASE_MS,\n )\n\n healthAndDowntime(build, options.unreachable, 'rate()', (adapter) => adapter.rate(REQUEST))\n })\n}\n","import { describe, expect, it } from 'vitest'\nimport type { TaxAdapter } from '@nymbalhq/types'\nimport { CASE_MS, healthAndDowntime, type Build, type ContractOptions } from './common.js'\n\nconst REQUEST = {\n currency: 'GBP',\n shippingCountry: 'GB',\n shippingRegion: 'England',\n lines: [{ amountMinor: 1000, qty: 2 }],\n}\n\nexport function runTaxContract(\n name: string,\n build: Build<TaxAdapter>,\n options: ContractOptions<TaxAdapter> = {},\n): void {\n describe(`TaxAdapter contract: ${name}`, () => {\n it(\n 'calculate returns totalTaxMinor >= 0',\n async () => {\n const adapter = await build()\n const result = await adapter.calculate(REQUEST)\n expect(typeof result.totalTaxMinor).toBe('number')\n expect(result.totalTaxMinor).toBeGreaterThanOrEqual(0)\n expect(result.ratePerLine).toHaveLength(1)\n expect(typeof result.ratePerLine[0]!.taxMinor).toBe('number')\n },\n CASE_MS,\n )\n\n it(\n 'calculate with zero amount returns zero tax',\n async () => {\n const adapter = await build()\n const result = await adapter.calculate({\n ...REQUEST,\n lines: [{ amountMinor: 0, qty: 1 }],\n })\n expect(result.totalTaxMinor).toBe(0)\n },\n CASE_MS,\n )\n\n healthAndDowntime(build, options.unreachable, 'calculate()', (adapter) =>\n adapter.calculate(REQUEST),\n )\n })\n}\n","import type { AdapterContext, Logger, Slot } from '@nymbalhq/types'\n\nconst silent: Logger = {\n trace: () => undefined,\n debug: () => undefined,\n info: () => undefined,\n warn: () => undefined,\n error: () => undefined,\n child: () => silent,\n}\n\n/**\n * The AdapterContext the kernel hands a package's `createAdapter`, with a silent logger: `config` is a commerce slot's\n * `config` record or a primitive's connection block.\n */\nexport function adapterContext(\n slot: Slot,\n config: Record<string, unknown>,\n env: NodeJS.ProcessEnv = {},\n): AdapterContext {\n return { slot, config, logger: silent, env }\n}\n","import { describe, expect, it } from 'vitest'\nimport {\n webhookDeliveryProblem,\n type CommerceAdapter,\n type WebhookDelivery,\n type WebhookHeaders,\n} from '@nymbalhq/types'\nimport { CASE_MS, using, type Build } from './common.js'\n\n/** One delivery as the provider sends it: the exact bytes and the headers its signature is in. */\nexport interface WebhookRequest {\n rawBody: Buffer\n headers: WebhookHeaders\n}\n\nexport interface WebhookContractOptions {\n /** One signed delivery carrying at least one event, as the provider would send it. */\n delivery: () => WebhookRequest\n /** The same delivery with one byte of its body changed. Given, the suite checks it is not verified. */\n tampered?: () => WebhookRequest\n}\n\ntype Receiving = CommerceAdapter & Required<Pick<CommerceAdapter, 'receiveWebhook'>>\n\nfunction receiving(adapter: CommerceAdapter): Receiving {\n expect(typeof adapter.receiveWebhook, 'the adapter has no receiveWebhook').toBe('function')\n return adapter as Receiving\n}\n\nasync function receive(\n adapter: CommerceAdapter,\n request: WebhookRequest,\n): Promise<WebhookDelivery> {\n return receiving(adapter).receiveWebhook(request.rawBody, request.headers)\n}\n\n/**\n * Certifies an adapter's `receiveWebhook`: one delivery received twice is one delivery, a tampered one is refused,\n * and every event it hands on is the adapter's own type with a plain JSON object payload.\n */\nexport function runWebhookContract(\n name: string,\n build: Build<CommerceAdapter>,\n options: WebhookContractOptions,\n): void {\n describe(`webhook contract: ${name}`, () => {\n // Kills: a delivery id minted per call, so each provider retry is processed as a new delivery.\n it(\n 'idempotency: one delivery received twice gives one deliveryId and equal events',\n () =>\n using(build, async (adapter) => {\n const first = await receive(adapter, options.delivery())\n const second = await receive(adapter, options.delivery())\n expect(first.verified, 'the signed delivery was not verified').toBe(true)\n expect(typeof first.deliveryId === 'string' && first.deliveryId !== '').toBe(true)\n expect(second.deliveryId, 'the same delivery got another deliveryId').toBe(\n first.deliveryId,\n )\n expect(second.events).toEqual(first.events)\n }),\n CASE_MS,\n )\n\n const tampered = options.tampered\n if (tampered !== undefined) {\n it(\n 'verification: a tampered delivery is not verified',\n () =>\n using(build, async (adapter) => {\n const outcome = await receive(adapter, tampered()).then(\n (delivery) => ({ verified: delivery.verified, code: null }),\n (err: unknown) => ({\n verified: false,\n code: (err as { code?: unknown } | null)?.code,\n }),\n )\n expect(outcome.verified, 'a tampered delivery was verified').toBe(false)\n if (outcome.code !== null) expect(String(outcome.code)).toMatch(/webhook_invalid$/)\n }),\n CASE_MS,\n )\n }\n\n // Kills: an adapter that hands on a kernel event (payment.captured.v1), another adapter's, or a class-instance\n // payload: whatever the kernel's route would answer 500 for on a live delivery.\n it(\n \"namespace: every event is the adapter's own, declared and versioned\",\n () =>\n using(build, async (adapter) => {\n const delivery = await receive(adapter, options.delivery())\n expect(delivery.verified, 'the signed delivery was not verified').toBe(true)\n expect(delivery.events.length, 'the delivery carried no event to check').toBeGreaterThan(\n 0,\n )\n expect(\n webhookDeliveryProblem(adapter.providerName, adapter.producesEvents, delivery),\n 'the kernel would refuse this delivery',\n ).toBeNull()\n }),\n CASE_MS,\n )\n })\n}\n","import { describe, expect, it } from 'vitest'\nimport type { SecurityAdapter, SecurityConfigLike } from '@nymbalhq/types'\nimport { CASE_MS, healthAndDowntime, type Build, type ContractOptions } from './common.js'\n\nconst testConfig: SecurityConfigLike = {\n rateLimit: {\n api: { requests: 100, window: '1m', action: 'block' },\n },\n csrf: false,\n headers: {\n hsts: true,\n contentSecurityPolicy: \"default-src 'self'\",\n referrerPolicy: 'strict-origin-when-cross-origin',\n xFrameOptions: 'DENY',\n },\n}\n\nexport function runSecurityContract(\n name: string,\n build: Build<SecurityAdapter>,\n options: ContractOptions<SecurityAdapter> = {},\n): void {\n describe(`SecurityAdapter contract: ${name}`, () => {\n it(\n 'validate accepts a valid config',\n async () => {\n const adapter = await build()\n const result = await adapter.validate(testConfig)\n expect(typeof result.valid).toBe('boolean')\n expect(Array.isArray(result.errors)).toBe(true)\n },\n CASE_MS,\n )\n\n it(\n 'validate of empty config reports errors',\n async () => {\n const adapter = await build()\n const result = await adapter.validate({} as SecurityConfigLike)\n if (!result.valid) {\n expect(result.errors.length).toBeGreaterThan(0)\n }\n },\n CASE_MS,\n )\n\n healthAndDowntime(build, options.unreachable, 'validate()', async (adapter) =>\n adapter.validate(testConfig),\n )\n })\n}\n","import { describe, it, expect } from 'vitest'\nimport type { NymbalEvent } from '@nymbalhq/types'\n\nexport interface ProjectionContractOptions {\n /**\n * Build a fresh projection handler context. Returns:\n * - `handle(event)` — processes the event through the idempotency-guarded handler\n * - `applicationCount()` — returns how many times the underlying handler actually ran\n */\n build: () => Promise<{\n handle: (event: NymbalEvent) => Promise<void>\n applicationCount: () => Promise<number>\n }>\n}\n\nfunction makeEvent(id: string): NymbalEvent {\n return {\n id,\n type: 'test.event.v1',\n timestamp: new Date().toISOString(),\n source: 'test',\n correlationId: 'corr-1',\n payload: { id },\n metadata: { storeId: 'test', environment: 'development', version: '0.0.0' },\n }\n}\n\nexport function runProjectionContract(opts: ProjectionContractOptions): void {\n describe('Projection idempotency contract', () => {\n it('processing the same event twice applies the mutation only once', async () => {\n const ctx = await opts.build()\n const event = makeEvent('dedup-evt-001')\n await ctx.handle(event)\n await ctx.handle(event)\n expect(await ctx.applicationCount()).toBe(1)\n })\n\n it('distinct events each apply their mutation', async () => {\n const ctx = await opts.build()\n await ctx.handle(makeEvent('distinct-evt-001'))\n await ctx.handle(makeEvent('distinct-evt-002'))\n expect(await ctx.applicationCount()).toBe(2)\n })\n\n it('after reprocessing a batch the count equals unique event count', async () => {\n const ctx = await opts.build()\n const events = [makeEvent('batch-001'), makeEvent('batch-002'), makeEvent('batch-003')]\n for (const e of events) await ctx.handle(e)\n for (const e of events) await ctx.handle(e)\n expect(await ctx.applicationCount()).toBe(3)\n })\n })\n}\n","import type { Slot } from '@nymbalhq/types'\nimport { runAnalyticsContract } from './analytics.js'\nimport type { Build } from './common.js'\nimport { runDocumentStoreContract } from './document-store.js'\nimport { runEmailContract } from './email.js'\nimport { runEventBusContract } from './event-bus.js'\nimport type { CONTRACT_KINDS } from './kinds.js'\nimport { runMediaStorageContract, type MediaStorageContractOptions } from './media-storage.js'\nimport { runPaymentsContract } from './payments.js'\nimport { runReviewsContract } from './reviews.js'\nimport { runSearchContract } from './search.js'\nimport { runShippingContract } from './shipping.js'\nimport { runTaxContract } from './tax.js'\n\nexport { adapterContext } from './adapter-context.js'\nexport { BOUND_MS, type Build, type ContractOptions } from './common.js'\nexport { CONTRACT_KINDS } from './kinds.js'\nexport { runDocumentStoreContract, type DocumentStoreContractOptions } from './document-store.js'\nexport { runEventBusContract, type EventBusContractOptions } from './event-bus.js'\nexport { runMediaStorageContract, type MediaStorageContractOptions } from './media-storage.js'\nexport { runPaymentsContract, type PaymentsContractOptions } from './payments.js'\nexport { runEmailContract } from './email.js'\nexport { runReviewsContract } from './reviews.js'\nexport { runSearchContract, type SearchContractOptions } from './search.js'\nexport {\n matchesQuery,\n searchTerms,\n toSearchDocument,\n type ContractProduct,\n} from './search-oracle.js'\nexport { runAnalyticsContract } from './analytics.js'\nexport { runShippingContract } from './shipping.js'\nexport { runTaxContract } from './tax.js'\nexport { runWebhookContract, type WebhookContractOptions, type WebhookRequest } from './webhook.js'\nexport { runSecurityContract } from './security.js'\nexport { runProjectionContract } from './projection.js'\nexport type { ProjectionContractOptions } from './projection.js'\n\n/** What a suite certifies: a commerce slot or an infrastructure primitive. */\nexport type ContractKind = Slot\n\n/** A kind's suite, as `nymbal test:contracts` calls it: `build` makes a fresh adapter for each case. */\nexport type ContractSuite = (\n name: string,\n build: Build<unknown>,\n options?: Record<string, unknown>,\n) => void\n\n/** A URL's bytes over HTTP: how a media storage's public URL is read back when the caller names no `fetchUrl`. */\nasync function fetchOverHttp(url: string): Promise<Uint8Array> {\n const response = await fetch(url)\n if (!response.ok) throw new Error(`GET ${url} answered ${response.status}`)\n return new Uint8Array(await response.arrayBuffer())\n}\n\nconst suites = {\n payments: runPaymentsContract as ContractSuite,\n email: runEmailContract as ContractSuite,\n reviews: runReviewsContract as ContractSuite,\n search: runSearchContract as ContractSuite,\n analytics: runAnalyticsContract as ContractSuite,\n shipping: runShippingContract as ContractSuite,\n tax: runTaxContract as ContractSuite,\n documentStore: runDocumentStoreContract as ContractSuite,\n eventBus: runEventBusContract as ContractSuite,\n media: (name, build, options = {}) =>\n runMediaStorageContract(\n name,\n build as Parameters<typeof runMediaStorageContract>[1],\n {\n fetchUrl: fetchOverHttp,\n ...options,\n } as MediaStorageContractOptions,\n ),\n} satisfies Record<(typeof CONTRACT_KINDS)[number], ContractSuite>\n\n/** Each kind's suite, one for every kind in CONTRACT_KINDS. Each is typed here, at the CLI's boundary. */\nexport const contractSuites: Partial<Record<ContractKind, ContractSuite>> = suites\n"],"mappings":"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","names":["describe","expect","it","describe","it","expect","describe","expect","it","describe","expect","it","describe","it","expect","fc","expect","it","SLOW","it","fc","expect","SLOW","using","rejection","putAll","walk","params","describe","it","expect","describe","expect","it","describe","it","expect","randomUUID","describe","expect","it","fc","describe","expect","it","SLOW","ids","e","randomUUID","describe","expect","it","SLOW","event","delay","until","gate","closing","ids","second","e","SLOW","randomUUID","delay","using","describe","it","expect","ids","describe","expect","it","describe","it","expect","randomUUID","describe","expect","it","describe","it","randomUUID","expect","randomUUID","fc","describe","expect","it","randomUUID","walk","describe","it","expect","fc","randomUUID","fc","describe","expect","it","randomUUID","fc","walk","expect","idsOf","ids","SLOW","describe","it","describe","expect","it","describe","it","expect","describe","expect","it","REQUEST","describe","it","expect","describe","expect","it","expect","describe","it","describe","expect","it","describe","it","expect","describe","it","expect","makeEvent","event"]}
|