@substrat-run/contract-tests 0.122.1 → 0.124.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ import type { ScopeHostFixture } from './scope-host-suite.js';
2
+ export declare function emittedReportContractSuite(adapterName: string, makeFixture: () => Promise<ScopeHostFixture>): void;
3
+ //# sourceMappingURL=emitted-suite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emitted-suite.d.ts","sourceRoot":"","sources":["../src/emitted-suite.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAG9D,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,GAC3C,IAAI,CA8FN"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Contract suite for the per-request record's scope half (#1746): `ScopeStub.subjectKind`
3
+ * and `InvokeOptions.onEmitted`.
4
+ *
5
+ * What it pins is the invocation log line's honesty about what a request touched. The line
6
+ * names the entities and event types an operation emitted, so a reader can facet requests
7
+ * by entity without joining the spine. That is only worth having if the list is the
8
+ * operation's OWN work: not its consumers' follow-on events, not a rolled-back
9
+ * sub-transaction's, not a failed call's, and not a replay's. Each case below is one of
10
+ * those, driven against a real scope on both adapters, because the DO answers across an
11
+ * RPC hop and the SQLite host does not, and the difference is exactly where a report gets
12
+ * lost or double-counted.
13
+ */
14
+ import { describe, it, expect, beforeAll, afterAll } from 'vitest';
15
+ import { platformActorId, principalId, scopeId, tenantId } from '@substrat-run/contracts';
16
+ import { EMITTED_REPORT_CAP, ulid } from '@substrat-run/kernel';
17
+ import { emittedMod } from './modules.js';
18
+ export function emittedReportContractSuite(adapterName, makeFixture) {
19
+ describe(`invocation emitted report (#1746): ${adapterName}`, () => {
20
+ let fixture;
21
+ let host;
22
+ let stub;
23
+ const t1 = tenantId.parse(ulid());
24
+ const s1 = scopeId.parse(ulid());
25
+ const alice = principalId.parse(ulid());
26
+ const staff = platformActorId.parse(ulid());
27
+ /** Every report the host delivered for one call — so "never called" is `[]`. */
28
+ const run = async (operation, input, extra = {}) => {
29
+ const reports = [];
30
+ let error;
31
+ try {
32
+ await stub.invoke(operation, input, { ...extra, onEmitted: (r) => reports.push(r) });
33
+ }
34
+ catch (e) {
35
+ error = e;
36
+ }
37
+ return { reports, error };
38
+ };
39
+ beforeAll(async () => {
40
+ fixture = await makeFixture();
41
+ host = fixture.host;
42
+ host.registerModule(emittedMod);
43
+ await host.admin.createTenant(staff, { id: t1, slug: 'emitted-tenant', name: 'Emitted Tenant' });
44
+ await host.admin.grantEntitlement(staff, t1, 'emitted');
45
+ await host.provisionScope(staff, { tenantId: t1, scopeId: s1, vertical: 'emitted-vertical' });
46
+ await host.admin.activateScope(staff, t1, s1);
47
+ stub = await host.getScope(alice, t1, s1);
48
+ });
49
+ afterAll(async () => {
50
+ await fixture.cleanup();
51
+ });
52
+ it('says which kind of subject a principal stub acts as', () => {
53
+ expect(stub.subjectKind).toBe('principal');
54
+ });
55
+ it("reports the operation's own events, in order, and none of its consumers'", async () => {
56
+ const a = `a-${ulid()}`;
57
+ const b = `b-${ulid()}`;
58
+ const { reports, error } = await run('emitted/touch', { ids: [a, b] });
59
+ expect(error).toBeUndefined();
60
+ // Two `emitted.echoed` rows were committed in the same invocation by the consumer.
61
+ // They are the consumer's work, and naming them would say this request touched
62
+ // entities its handler never saw.
63
+ expect(reports).toEqual([
64
+ {
65
+ events: [
66
+ { type: 'emitted.touched', entity: `emitted-thing:${a}` },
67
+ { type: 'emitted.touched', entity: `emitted-thing:${b}` },
68
+ ],
69
+ total: 2,
70
+ },
71
+ ]);
72
+ });
73
+ it('reports an empty list for an operation that emitted nothing', async () => {
74
+ // A fact, not an absence: a read touched nothing, and that is worth saying.
75
+ expect((await run('emitted/read')).reports).toEqual([{ events: [], total: 0 }]);
76
+ });
77
+ it('never reports for a call that rolled back', async () => {
78
+ const { reports, error } = await run('emitted/fail', { ids: [`f-${ulid()}`] });
79
+ expect(error).toBeDefined();
80
+ expect(reports).toEqual([]);
81
+ });
82
+ it("leaves out a rolled-back sub-transaction's emit", async () => {
83
+ const kept = `k-${ulid()}`;
84
+ const { reports } = await run('emitted/partial', { kept, dropped: `d-${ulid()}` });
85
+ expect(reports).toEqual([{ events: [{ type: 'emitted.touched', entity: `emitted-thing:${kept}` }], total: 1 }]);
86
+ });
87
+ it('caps the list and keeps the uncapped count', async () => {
88
+ const ids = Array.from({ length: EMITTED_REPORT_CAP + 5 }, (_, i) => `c${i}-${ulid()}`);
89
+ const { reports } = await run('emitted/touch', { ids });
90
+ expect(reports).toHaveLength(1);
91
+ expect(reports[0].total).toBe(EMITTED_REPORT_CAP + 5);
92
+ expect(reports[0].events.map((e) => e.entity)).toEqual(ids.slice(0, EMITTED_REPORT_CAP).map((id) => `emitted-thing:${id}`));
93
+ });
94
+ it('does not report a replay, which committed nothing', async () => {
95
+ const idempotencyKey = `key-${ulid()}`;
96
+ const input = { ids: [`r-${ulid()}`] };
97
+ expect((await run('emitted/touch', input, { idempotencyKey })).reports).toHaveLength(1);
98
+ expect((await run('emitted/touch', input, { idempotencyKey })).reports).toEqual([]);
99
+ });
100
+ });
101
+ }
102
+ //# sourceMappingURL=emitted-suite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emitted-suite.js","sourceRoot":"","sources":["../src/emitted-suite.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -11,6 +11,8 @@ export { searchContractSuite } from './search-suite.js';
11
11
  export { entityVersionContractSuite } from './entity-version-suite.js';
12
12
  export { timelineContractSuite } from './timeline-suite.js';
13
13
  export { concurrencyContractSuite } from './concurrency-suite.js';
14
+ export { emittedReportContractSuite } from './emitted-suite.js';
15
+ export { moduleLogContractSuite } from './module-log-suite.js';
14
16
  export { idempotencyContractSuite } from './idempotency-suite.js';
15
17
  export { listContractSuite } from './list-suite.js';
16
18
  export { scheduleContractSuite } from './schedule-suite.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -9,6 +9,8 @@ export { searchContractSuite } from './search-suite.js';
9
9
  export { entityVersionContractSuite } from './entity-version-suite.js';
10
10
  export { timelineContractSuite } from './timeline-suite.js';
11
11
  export { concurrencyContractSuite } from './concurrency-suite.js';
12
+ export { emittedReportContractSuite } from './emitted-suite.js';
13
+ export { moduleLogContractSuite } from './module-log-suite.js';
12
14
  export { idempotencyContractSuite } from './idempotency-suite.js';
13
15
  export { listContractSuite } from './list-suite.js';
14
16
  export { scheduleContractSuite } from './schedule-suite.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,iCAAiC,EAAE,MAAM,kCAAkC,CAAC;AACrF,OAAO,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;AAE7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EACL,2BAA2B,EAC3B,YAAY,EACZ,oBAAoB,EACpB,cAAc,EACd,sBAAsB,EACtB,YAAY,EACZ,cAAc,GAEf,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,+BAA+B,EAAE,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,yBAAyB,EAA4B,MAAM,0BAA0B,CAAC;AAE/F,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAE/F,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE5E,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAOxF,OAAO,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,0BAA0B,EAC1B,mBAAmB,EACnB,OAAO,EACP,eAAe,EACf,OAAO,EACP,MAAM,EACN,cAAc,EACd,OAAO,EACP,eAAe,EACf,WAAW,EACX,aAAa,EACb,WAAW,EACX,OAAO,EACP,OAAO,EACP,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,OAAO,EACP,eAAe,EACf,QAAQ,EACR,gBAAgB,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,mBAAmB,GAEpB,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,iCAAiC,EAAE,MAAM,kCAAkC,CAAC;AACrF,OAAO,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;AAE7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EACL,2BAA2B,EAC3B,YAAY,EACZ,oBAAoB,EACpB,cAAc,EACd,sBAAsB,EACtB,YAAY,EACZ,cAAc,GAEf,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,+BAA+B,EAAE,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,yBAAyB,EAA4B,MAAM,0BAA0B,CAAC;AAE/F,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAE/F,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE5E,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAOxF,OAAO,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,0BAA0B,EAC1B,mBAAmB,EACnB,OAAO,EACP,eAAe,EACf,OAAO,EACP,MAAM,EACN,cAAc,EACd,OAAO,EACP,eAAe,EACf,WAAW,EACX,aAAa,EACb,WAAW,EACX,OAAO,EACP,OAAO,EACP,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,OAAO,EACP,eAAe,EACf,QAAQ,EACR,gBAAgB,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,mBAAmB,GAEpB,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { type ModuleLogLine } from '@substrat-run/kernel';
2
+ import type { ScopeHostFixture } from './scope-host-suite.js';
3
+ export declare function moduleLogContractSuite(adapterName: string, makeFixture: () => Promise<ScopeHostFixture & {
4
+ logs: () => ModuleLogLine[];
5
+ }>): void;
6
+ //# sourceMappingURL=module-log-suite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-log-suite.d.ts","sourceRoot":"","sources":["../src/module-log-suite.ts"],"names":[],"mappings":"AAWA,OAAO,EAAQ,KAAK,aAAa,EAAkC,MAAM,sBAAsB,CAAC;AAChG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAG9D,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,OAAO,CAAC,gBAAgB,GAAG;IAAE,IAAI,EAAE,MAAM,aAAa,EAAE,CAAA;CAAE,CAAC,GAC7E,IAAI,CAuEN"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Contract suite for `ctx.log` (#1746, #1747): what the HOST stamps on a module's log line.
3
+ *
4
+ * The line's worth is that a reader can trust its fields without trusting the module: the
5
+ * tenant and scope it is filed under, the operation, the invocation it joins to, and who
6
+ * the code ran as. So every case here drives a real scope and reads the line the host
7
+ * wrote, on both adapters — the DO builds its context inside workerd, the SQLite host in
8
+ * process, and either could stamp the wrong invocation or let a field through.
9
+ */
10
+ import { describe, it, expect, beforeAll, afterAll } from 'vitest';
11
+ import { platformActorId, principalId, scopeId, tenantId } from '@substrat-run/contracts';
12
+ import { ulid } from '@substrat-run/kernel';
13
+ import { loggedMod } from './modules.js';
14
+ export function moduleLogContractSuite(adapterName, makeFixture) {
15
+ describe(`ctx.log (#1746, #1747): ${adapterName}`, () => {
16
+ let fixture;
17
+ let host;
18
+ let stub;
19
+ const t1 = tenantId.parse(ulid());
20
+ const s1 = scopeId.parse(ulid());
21
+ const alice = principalId.parse(ulid());
22
+ const staff = platformActorId.parse(ulid());
23
+ /** This suite's lines for one call, in the order they were written. */
24
+ const linesFor = (invocationId) => fixture.logs().filter((l) => l.invocationId === invocationId);
25
+ beforeAll(async () => {
26
+ fixture = await makeFixture();
27
+ host = fixture.host;
28
+ host.registerModule(loggedMod);
29
+ await host.admin.createTenant(staff, { id: t1, slug: 'logged-tenant', name: 'Logged Tenant' });
30
+ await host.admin.grantEntitlement(staff, t1, 'logged');
31
+ await host.provisionScope(staff, { tenantId: t1, scopeId: s1, vertical: 'logged-vertical' });
32
+ await host.admin.activateScope(staff, t1, s1);
33
+ stub = await host.getScope(alice, t1, s1);
34
+ });
35
+ afterAll(async () => {
36
+ await fixture.cleanup();
37
+ });
38
+ it('stamps tenant, scope, operation, invocation and who — and keeps the template', async () => {
39
+ const invocationId = ulid();
40
+ const ticketId = `t-${ulid()}`;
41
+ await stub.invoke('logged/act', { ticketId }, { invocationId });
42
+ const [line] = linesFor(invocationId).filter((l) => l.operation === 'logged/act');
43
+ expect(line).toMatchObject({
44
+ substrat: 'log',
45
+ level: 'info',
46
+ template: 'reply to {ticketId} sent',
47
+ message: `reply to ${ticketId} sent`,
48
+ tenantId: t1,
49
+ scopeId: s1,
50
+ operation: 'logged/act',
51
+ invocationId,
52
+ principalKind: 'principal',
53
+ });
54
+ // The caller's `tenantId` and `operation` stayed fields; the stamp is the host's.
55
+ expect(line.fields).toMatchObject({ ticketId, tenantId: 'forged', operation: 'forged' });
56
+ });
57
+ it("stamps a consumer's line with the same invocation, no operation, and `system`", async () => {
58
+ const invocationId = ulid();
59
+ await stub.invoke('logged/act', { ticketId: `t-${ulid()}` }, { invocationId });
60
+ const consumer = linesFor(invocationId).find((l) => l.template === 'saw {type}');
61
+ expect(consumer).toMatchObject({
62
+ level: 'warn',
63
+ message: 'saw logged.acted',
64
+ operation: null,
65
+ invocationId,
66
+ principalKind: 'system',
67
+ tenantId: t1,
68
+ scopeId: s1,
69
+ });
70
+ });
71
+ it('writes the line of an operation that then rolled back', async () => {
72
+ const invocationId = ulid();
73
+ await expect(stub.invoke('logged/fail', { ticketId: 'x' }, { invocationId })).rejects.toThrow();
74
+ expect(linesFor(invocationId)).toEqual([
75
+ expect.objectContaining({ level: 'error', template: 'could not reach {ticketId}', operation: 'logged/fail' }),
76
+ ]);
77
+ });
78
+ });
79
+ }
80
+ //# sourceMappingURL=module-log-suite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-log-suite.js","sourceRoot":"","sources":["../src/module-log-suite.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAC1F,OAAO,EAAE,IAAI,EAAsD,MAAM,sBAAsB,CAAC;AAEhG,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,MAAM,UAAU,sBAAsB,CACpC,WAAmB,EACnB,WAA8E;IAE9E,QAAQ,CAAC,2BAA2B,WAAW,EAAE,EAAE,GAAG,EAAE;QACtD,IAAI,OAA2D,CAAC;QAChE,IAAI,IAAe,CAAC;QACpB,IAAI,IAAe,CAAC;QACpB,MAAM,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QAClC,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACjC,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACxC,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QAE5C,uEAAuE;QACvE,MAAM,QAAQ,GAAG,CAAC,YAAoB,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,YAAY,CAAC,CAAC;QAEzG,SAAS,CAAC,KAAK,IAAI,EAAE;YACnB,OAAO,GAAG,MAAM,WAAW,EAAE,CAAC;YAC9B,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;YACpB,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;YAC/B,MAAM,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,CAAC;YAC/F,MAAM,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,KAAK,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC;YACvD,MAAM,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,iBAAiB,EAAE,CAAC,CAAC;YAC7F,MAAM,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;YAC9C,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,KAAK,IAAI,EAAE;YAClB,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QAC1B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8EAA8E,EAAE,KAAK,IAAI,EAAE;YAC5F,MAAM,YAAY,GAAG,IAAI,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE,EAAE,CAAC;YAC/B,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC;YAChE,MAAM,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,YAAY,CAAC,CAAC;YAClF,MAAM,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC;gBACzB,QAAQ,EAAE,KAAK;gBACf,KAAK,EAAE,MAAM;gBACb,QAAQ,EAAE,0BAA0B;gBACpC,OAAO,EAAE,YAAY,QAAQ,OAAO;gBACpC,QAAQ,EAAE,EAAE;gBACZ,OAAO,EAAE,EAAE;gBACX,SAAS,EAAE,YAAY;gBACvB,YAAY;gBACZ,aAAa,EAAE,WAAW;aAC3B,CAAC,CAAC;YACH,kFAAkF;YAClF,MAAM,CAAC,IAAK,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC5F,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+EAA+E,EAAE,KAAK,IAAI,EAAE;YAC7F,MAAM,YAAY,GAAG,IAAI,EAAE,CAAC;YAC5B,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,QAAQ,EAAE,KAAK,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC;YAC/E,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,YAAY,CAAC,CAAC;YACjF,MAAM,CAAC,QAAQ,CAAC,CAAC,aAAa,CAAC;gBAC7B,KAAK,EAAE,MAAM;gBACb,OAAO,EAAE,kBAAkB;gBAC3B,SAAS,EAAE,IAAI;gBACf,YAAY;gBACZ,aAAa,EAAE,QAAQ;gBACvB,QAAQ,EAAE,EAAE;gBACZ,OAAO,EAAE,EAAE;aACZ,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;YACrE,MAAM,YAAY,GAAG,IAAI,EAAE,CAAC;YAC5B,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAChG,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC;gBACrC,MAAM,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,4BAA4B,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC;aAC9G,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}