@pattern-stack/codegen 0.18.0 → 0.20.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.
Files changed (129) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/README.md +51 -0
  3. package/consumer-skills/codegen/SKILL.md +32 -0
  4. package/consumer-skills/entities/SKILL.md +2 -0
  5. package/consumer-skills/events/authoring-events.md +31 -0
  6. package/dist/{chunk-COGHTKXY.js → chunk-27ETSJ2X.js} +2 -2
  7. package/dist/{chunk-X6BP6LI5.js → chunk-3YCUIGPG.js} +10 -10
  8. package/dist/{chunk-BK5ICA2F.js → chunk-4MVGAMUA.js} +4 -4
  9. package/dist/{chunk-LQ6PYFU6.js → chunk-4OC5MSHO.js} +47 -1
  10. package/dist/chunk-4OC5MSHO.js.map +1 -0
  11. package/dist/{chunk-3A34R6CI.js → chunk-5LXOJGO2.js} +4 -4
  12. package/dist/{chunk-T6C4LFLC.js → chunk-7YGORYZD.js} +4 -4
  13. package/dist/{chunk-PKDS6QIJ.js → chunk-ATVGYF3D.js} +7 -7
  14. package/dist/{chunk-2TVVBC53.js → chunk-BORNCTH3.js} +2 -2
  15. package/dist/{chunk-7MMS36AN.js → chunk-CUSMC2KK.js} +10 -10
  16. package/dist/{chunk-V4AF6DI4.js → chunk-DUBZOXJC.js} +9 -2
  17. package/dist/{chunk-V4AF6DI4.js.map → chunk-DUBZOXJC.js.map} +1 -1
  18. package/dist/chunk-DUUCU77W.js +211 -0
  19. package/dist/chunk-DUUCU77W.js.map +1 -0
  20. package/dist/{chunk-OFRRBC7M.js → chunk-E2BRT5IB.js} +15 -1
  21. package/dist/chunk-E2BRT5IB.js.map +1 -0
  22. package/dist/{chunk-VQOAATIG.js → chunk-FLYF76CU.js} +4 -4
  23. package/dist/{chunk-43SBT72G.js → chunk-I6UXRJ3Q.js} +4 -4
  24. package/dist/{chunk-VHAR2BGH.js → chunk-INO47JXD.js} +5 -5
  25. package/dist/{chunk-BGULBWKJ.js → chunk-JOBQ6RUU.js} +1 -1
  26. package/dist/chunk-JOBQ6RUU.js.map +1 -0
  27. package/dist/{chunk-C5E7H553.js → chunk-KBO5OOON.js} +4 -4
  28. package/dist/{chunk-R4BPUUB5.js → chunk-KHQ72A5F.js} +54 -6
  29. package/dist/chunk-KHQ72A5F.js.map +1 -0
  30. package/dist/{chunk-CFFTPWHM.js → chunk-KK5A7B2T.js} +70 -5
  31. package/dist/chunk-KK5A7B2T.js.map +1 -0
  32. package/dist/{chunk-RKNW56RU.js → chunk-LARB26EI.js} +73 -6
  33. package/dist/chunk-LARB26EI.js.map +1 -0
  34. package/dist/{chunk-2VGVSL2D.js → chunk-LQXBQO72.js} +6 -6
  35. package/dist/{chunk-K2I6XIK5.js → chunk-MVKW2BCR.js} +2 -2
  36. package/dist/{chunk-EWYI5GGJ.js → chunk-NYJYK6J4.js} +15 -15
  37. package/dist/{chunk-IN3EWFB4.js → chunk-QSJ3J4HE.js} +6 -6
  38. package/dist/{chunk-TBGTMALE.js → chunk-SGSWVNNB.js} +4 -4
  39. package/dist/chunk-SYVZ4MD2.js +1 -0
  40. package/dist/{chunk-NXHL5YII.js → chunk-T6SCOJF4.js} +4 -4
  41. package/dist/{chunk-YZLBU6O2.js → chunk-WKNOEVWQ.js} +5 -5
  42. package/dist/runtime/base-classes/index.js +17 -17
  43. package/dist/runtime/subsystems/auth/auth.module.js +3 -3
  44. package/dist/runtime/subsystems/auth/index.js +10 -10
  45. package/dist/runtime/subsystems/bridge/bridge-delivery-handler.js +2 -2
  46. package/dist/runtime/subsystems/bridge/bridge-delivery.drizzle-backend.js +3 -3
  47. package/dist/runtime/subsystems/bridge/bridge-delivery.schema.js +2 -2
  48. package/dist/runtime/subsystems/bridge/bridge-outbox-drain-hook.js +6 -6
  49. package/dist/runtime/subsystems/bridge/bridge.module.js +18 -18
  50. package/dist/runtime/subsystems/bridge/index.js +21 -21
  51. package/dist/runtime/subsystems/cache/cache.drizzle-backend.js +2 -2
  52. package/dist/runtime/subsystems/cache/cache.module.js +3 -3
  53. package/dist/runtime/subsystems/cache/index.js +5 -5
  54. package/dist/runtime/subsystems/events/domain-events.schema.js +1 -1
  55. package/dist/runtime/subsystems/events/event-bus.drizzle-backend.d.ts +19 -32
  56. package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js +3 -3
  57. package/dist/runtime/subsystems/events/event-bus.memory-backend.d.ts +18 -1
  58. package/dist/runtime/subsystems/events/event-bus.memory-backend.js +1 -1
  59. package/dist/runtime/subsystems/events/event-bus.protocol.d.ts +45 -1
  60. package/dist/runtime/subsystems/events/event-scheduler.d.ts +96 -0
  61. package/dist/runtime/subsystems/events/event-scheduler.js +25 -0
  62. package/dist/runtime/subsystems/events/event-scheduler.js.map +1 -0
  63. package/dist/runtime/subsystems/events/events-errors.d.ts +12 -1
  64. package/dist/runtime/subsystems/events/events-errors.js +5 -3
  65. package/dist/runtime/subsystems/events/events.module.d.ts +41 -2
  66. package/dist/runtime/subsystems/events/events.module.js +11 -8
  67. package/dist/runtime/subsystems/events/generated/bus.js +3 -3
  68. package/dist/runtime/subsystems/events/generated/index.js +3 -3
  69. package/dist/runtime/subsystems/events/generated/registry.d.ts +6 -0
  70. package/dist/runtime/subsystems/events/generated/registry.js +1 -1
  71. package/dist/runtime/subsystems/events/index.d.ts +4 -3
  72. package/dist/runtime/subsystems/events/index.js +38 -14
  73. package/dist/runtime/subsystems/index.d.ts +1 -0
  74. package/dist/runtime/subsystems/index.js +117 -116
  75. package/dist/runtime/subsystems/integration/build-change-source.js +2 -2
  76. package/dist/runtime/subsystems/integration/index.js +36 -36
  77. package/dist/runtime/subsystems/integration/integration.module.js +4 -4
  78. package/dist/runtime/subsystems/jobs/index.js +33 -33
  79. package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js +5 -5
  80. package/dist/runtime/subsystems/jobs/job-orchestrator.drizzle-backend.js +3 -3
  81. package/dist/runtime/subsystems/jobs/job-orchestrator.memory-backend.js +2 -2
  82. package/dist/runtime/subsystems/jobs/job-run-service.drizzle-backend.js +2 -2
  83. package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.js +3 -3
  84. package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js +3 -3
  85. package/dist/runtime/subsystems/jobs/job-worker.js +2 -2
  86. package/dist/runtime/subsystems/jobs/job-worker.module.js +11 -11
  87. package/dist/runtime/subsystems/jobs/jobs-domain.module.js +9 -9
  88. package/dist/runtime/subsystems/storage/index.js +4 -4
  89. package/dist/runtime/subsystems/storage/storage.module.js +2 -2
  90. package/dist/src/cli/index.js +168 -22
  91. package/dist/src/cli/index.js.map +1 -1
  92. package/dist/src/index.js +12 -12
  93. package/package.json +1 -1
  94. package/runtime/subsystems/events/domain-events.schema.ts +16 -0
  95. package/runtime/subsystems/events/event-bus.drizzle-backend.ts +103 -1
  96. package/runtime/subsystems/events/event-bus.memory-backend.ts +57 -1
  97. package/runtime/subsystems/events/event-bus.protocol.ts +47 -0
  98. package/runtime/subsystems/events/event-scheduler.ts +351 -0
  99. package/runtime/subsystems/events/events-errors.ts +14 -0
  100. package/runtime/subsystems/events/events.module.ts +78 -1
  101. package/runtime/subsystems/events/generated/registry.ts +1 -0
  102. package/runtime/subsystems/events/index.ts +25 -3
  103. package/dist/chunk-BGULBWKJ.js.map +0 -1
  104. package/dist/chunk-CFFTPWHM.js.map +0 -1
  105. package/dist/chunk-FN2PYDPP.js +0 -1
  106. package/dist/chunk-LQ6PYFU6.js.map +0 -1
  107. package/dist/chunk-OFRRBC7M.js.map +0 -1
  108. package/dist/chunk-R4BPUUB5.js.map +0 -1
  109. package/dist/chunk-RKNW56RU.js.map +0 -1
  110. /package/dist/{chunk-COGHTKXY.js.map → chunk-27ETSJ2X.js.map} +0 -0
  111. /package/dist/{chunk-X6BP6LI5.js.map → chunk-3YCUIGPG.js.map} +0 -0
  112. /package/dist/{chunk-BK5ICA2F.js.map → chunk-4MVGAMUA.js.map} +0 -0
  113. /package/dist/{chunk-3A34R6CI.js.map → chunk-5LXOJGO2.js.map} +0 -0
  114. /package/dist/{chunk-T6C4LFLC.js.map → chunk-7YGORYZD.js.map} +0 -0
  115. /package/dist/{chunk-PKDS6QIJ.js.map → chunk-ATVGYF3D.js.map} +0 -0
  116. /package/dist/{chunk-2TVVBC53.js.map → chunk-BORNCTH3.js.map} +0 -0
  117. /package/dist/{chunk-7MMS36AN.js.map → chunk-CUSMC2KK.js.map} +0 -0
  118. /package/dist/{chunk-VQOAATIG.js.map → chunk-FLYF76CU.js.map} +0 -0
  119. /package/dist/{chunk-43SBT72G.js.map → chunk-I6UXRJ3Q.js.map} +0 -0
  120. /package/dist/{chunk-VHAR2BGH.js.map → chunk-INO47JXD.js.map} +0 -0
  121. /package/dist/{chunk-C5E7H553.js.map → chunk-KBO5OOON.js.map} +0 -0
  122. /package/dist/{chunk-2VGVSL2D.js.map → chunk-LQXBQO72.js.map} +0 -0
  123. /package/dist/{chunk-K2I6XIK5.js.map → chunk-MVKW2BCR.js.map} +0 -0
  124. /package/dist/{chunk-EWYI5GGJ.js.map → chunk-NYJYK6J4.js.map} +0 -0
  125. /package/dist/{chunk-IN3EWFB4.js.map → chunk-QSJ3J4HE.js.map} +0 -0
  126. /package/dist/{chunk-TBGTMALE.js.map → chunk-SGSWVNNB.js.map} +0 -0
  127. /package/dist/{chunk-FN2PYDPP.js.map → chunk-SYVZ4MD2.js.map} +0 -0
  128. /package/dist/{chunk-NXHL5YII.js.map → chunk-T6SCOJF4.js.map} +0 -0
  129. /package/dist/{chunk-YZLBU6O2.js.map → chunk-WKNOEVWQ.js.map} +0 -0
@@ -28,3 +28,17 @@ export class MissingTenantIdError extends Error {
28
28
  );
29
29
  }
30
30
  }
31
+
32
+ /**
33
+ * Thrown (ADR-039) when a scheduled event's `schedule` config is invalid at
34
+ * runtime — a malformed `schedule.every` duration, or a scheduled event with no
35
+ * direction/pool to route by. Codegen validates `schedule` at `gen-all` time;
36
+ * this is the boot backstop for a hand-edited registry or version skew. Raised
37
+ * by `EventScheduler` construction / `parseEvery`.
38
+ */
39
+ export class ScheduleConfigError extends Error {
40
+ override readonly name = 'ScheduleConfigError';
41
+ constructor(message: string) {
42
+ super(`ScheduleConfigError: ${message}`);
43
+ }
44
+ }
@@ -44,7 +44,18 @@
44
44
  * `new Class()` which silently left `db` / `redisUrl` undefined
45
45
  * (issue #108).
46
46
  */
47
- import { Module, type DynamicModule, type Provider, type Type } from '@nestjs/common';
47
+ import {
48
+ Inject,
49
+ Injectable,
50
+ Logger,
51
+ Module,
52
+ Optional,
53
+ type DynamicModule,
54
+ type OnModuleDestroy,
55
+ type OnModuleInit,
56
+ type Provider,
57
+ type Type,
58
+ } from '@nestjs/common';
48
59
  import {
49
60
  EVENT_BUS,
50
61
  EVENT_READ_PORT,
@@ -57,6 +68,12 @@ import { DRIZZLE } from '../../constants/tokens';
57
68
  import type { DrizzleClient } from '../../types/drizzle';
58
69
  import { DrizzleEventBus } from './event-bus.drizzle-backend';
59
70
  import { MemoryEventBus } from './event-bus.memory-backend';
71
+ import type { IEventBus } from './event-bus.protocol';
72
+ import {
73
+ EventScheduler,
74
+ scheduledEventsFromRegistry,
75
+ type RegistrySchedule,
76
+ } from './event-scheduler';
60
77
  // #6 — `RedisEventBus` is lazy-loaded only when `backend: 'redis'` is selected.
61
78
  // The file is filtered out of the vendor set for non-redis installs (see
62
79
  // `backendFileFilter` in src/cli/commands/subsystem.ts); the dynamic-string
@@ -151,6 +168,62 @@ export interface EventsModuleOptions {
151
168
  * keeps the bundled bus.
152
169
  */
153
170
  typedBus?: Type<unknown>;
171
+ /**
172
+ * ADR-039 — the consumer's generated `eventRegistry`, threaded so the
173
+ * `EventScheduler` can read the `schedule:` block + routing metadata of every
174
+ * scheduled event. Package mode: the generated subsystem barrel passes the
175
+ * consumer's `eventRegistry` (the bundled one is the package's empty/fixture
176
+ * registry, which the package can't see the consumer's events through — same
177
+ * reason `typedBus` is threaded). Omitted ⇒ no scheduler is spawned (vendored
178
+ * tree reads its own bundled registry only if the barrel passes it; tests
179
+ * pass a registry directly).
180
+ *
181
+ * Structural shape: each value needs `schedule?` + `direction` + `pool`. The
182
+ * generated `EventMetadata` satisfies it; typing it loosely here avoids a
183
+ * runtime dependency on the generated types from the module file.
184
+ */
185
+ eventRegistry?: Record<
186
+ string,
187
+ { schedule?: RegistrySchedule; direction: string | null; pool: string | null }
188
+ >;
189
+ }
190
+
191
+ /**
192
+ * Lifecycle holder for the `EventScheduler` (ADR-039). Registered as a provider
193
+ * on the drizzle/memory `forRoot` branches; Nest drives `onModuleInit` (after
194
+ * the bus is constructed) and `onModuleDestroy`. Reads the scheduled-event set
195
+ * from the threaded `eventRegistry` and starts the materialiser. No-op when
196
+ * nothing declared `schedule:`, or under the redis backend (no outbox history).
197
+ */
198
+ @Injectable()
199
+ export class EventSchedulerLifecycle implements OnModuleInit, OnModuleDestroy {
200
+ private readonly logger = new Logger(EventSchedulerLifecycle.name);
201
+ private scheduler: EventScheduler | null = null;
202
+
203
+ constructor(
204
+ @Inject(EVENT_BUS) private readonly bus: IEventBus,
205
+ @Optional()
206
+ @Inject(EVENTS_MODULE_OPTIONS)
207
+ private readonly opts: EventsModuleOptions | null = null,
208
+ ) {}
209
+
210
+ async onModuleInit(): Promise<void> {
211
+ const registry = this.opts?.eventRegistry;
212
+ if (!registry) return;
213
+ if (typeof this.bus.materializeScheduledEvent !== 'function') return; // redis
214
+ const schedules = scheduledEventsFromRegistry(registry);
215
+ if (schedules.length === 0) return;
216
+ this.scheduler = new EventScheduler(this.bus, schedules);
217
+ await this.scheduler.start();
218
+ this.logger.log(`EventScheduler wired for ${schedules.length} scheduled event(s).`);
219
+ }
220
+
221
+ async onModuleDestroy(): Promise<void> {
222
+ if (this.scheduler) {
223
+ this.scheduler.stop();
224
+ this.scheduler = null;
225
+ }
226
+ }
154
227
  }
155
228
 
156
229
  export interface EventsModuleAsyncOptions {
@@ -317,6 +390,10 @@ export class EventsModule {
317
390
  // IEventReadPort on the same instance as EVENT_BUS. The redis
318
391
  // backend retains no history and does not provide this token.
319
392
  { provide: EVENT_READ_PORT, useExisting: EVENT_BUS },
393
+ // ADR-039 — the scheduler lifecycle. No-op unless `eventRegistry` was
394
+ // threaded AND some event declared `schedule:`. Drizzle/memory only
395
+ // (the redis branch above never reaches here).
396
+ EventSchedulerLifecycle,
320
397
  ...buildTypedBusProviders(multiTenant, options.typedBus),
321
398
  ],
322
399
  exports: [EVENT_BUS, EVENT_READ_PORT, TYPED_EVENT_BUS, EVENTS_MULTI_TENANT],
@@ -14,6 +14,7 @@ export interface EventMetadata {
14
14
  destination?: string;
15
15
  version: number;
16
16
  retry: { attempts: number; backoff: 'linear' | 'exponential' };
17
+ schedule?: { every: string | number; align: boolean; catchUp: boolean; maxCatchUpSlots: number };
17
18
  }
18
19
 
19
20
  export const eventRegistry = {
@@ -3,7 +3,12 @@
3
3
  *
4
4
  * Import the module in AppModule, inject the bus via EVENT_BUS token.
5
5
  */
6
- export type { DomainEvent, IEventBus, DrizzleTransaction } from './event-bus.protocol';
6
+ export type {
7
+ DomainEvent,
8
+ IEventBus,
9
+ DrizzleTransaction,
10
+ ScheduledEventSpec,
11
+ } from './event-bus.protocol';
7
12
  // Augmentable event registry (ADR-037, package-mode trigger typing). A
8
13
  // package-mode consumer's generated events code augments `DomainEventRegistry`
9
14
  // via `declare module '@pattern-stack/codegen/runtime/subsystems/events/index'`
@@ -30,9 +35,26 @@ export {
30
35
  TYPED_EVENT_BUS,
31
36
  } from './events.tokens';
32
37
  export { TypedEventBus } from './generated/bus';
33
- export { MissingTenantIdError } from './events-errors';
34
- export { EventsModule } from './events.module';
38
+ export { MissingTenantIdError, ScheduleConfigError } from './events-errors';
39
+ export { EventsModule, EventSchedulerLifecycle } from './events.module';
35
40
  export type { EventsModuleOptions } from './events.module';
41
+ // ADR-039 — declarative time-based scheduling (time as an event source).
42
+ export {
43
+ EventScheduler,
44
+ parseEvery,
45
+ slotStartFor,
46
+ nextSlotStart,
47
+ slotKeyFor,
48
+ resolveScheduledEvent,
49
+ scheduledEventsFromRegistry,
50
+ SCHEDULE_KEY_PREFIX,
51
+ SCHEDULE_FLOOR_MS,
52
+ } from './event-scheduler';
53
+ export type {
54
+ ScheduledEvent,
55
+ RegistrySchedule,
56
+ EventSchedulerOptions,
57
+ } from './event-scheduler';
36
58
  export { MemoryEventBus } from './event-bus.memory-backend';
37
59
  export { DrizzleEventBus } from './event-bus.drizzle-backend';
38
60
  // #6 — backend-specific implementation classes are NOT re-exported here.
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../runtime/subsystems/events/generated/registry.ts"],"sourcesContent":["// AUTO-GENERATED by @pattern-stack/codegen. Do not edit.\n// Run `codegen entity new --all` to refresh.\n\n\nimport type { EventTypeName } from './types';\n\nexport interface EventMetadata {\n\ttype: EventTypeName;\n\ttier: 'domain' | 'audit';\n\tdirection: 'inbound' | 'change' | 'outbound' | null;\n\tpool: 'events_inbound' | 'events_change' | 'events_outbound' | null;\n\taggregate?: string;\n\tsource?: string;\n\tdestination?: string;\n\tversion: number;\n\tretry: { attempts: number; backoff: 'linear' | 'exponential' };\n}\n\nexport const eventRegistry = {\n\t'contact_created': {\n\t\ttype: 'contact_created',\n\t\ttier: 'domain',\n\t\tdirection: 'change',\n\t\tpool: 'events_change',\n\t\taggregate: 'contact',\n\t\tversion: 1,\n\t\tretry: { attempts: 3, backoff: 'exponential' },\n\t},\n\t'contact_marked_champion': {\n\t\ttype: 'contact_marked_champion',\n\t\ttier: 'domain',\n\t\tdirection: 'change',\n\t\tpool: 'events_change',\n\t\taggregate: 'contact',\n\t\tversion: 1,\n\t\tretry: { attempts: 3, backoff: 'exponential' },\n\t},\n\t'contact_merged': {\n\t\ttype: 'contact_merged',\n\t\ttier: 'domain',\n\t\tdirection: 'change',\n\t\tpool: 'events_change',\n\t\taggregate: 'contact',\n\t\tversion: 1,\n\t\tretry: { attempts: 3, backoff: 'exponential' },\n\t},\n\t'crm_sync_started': {\n\t\ttype: 'crm_sync_started',\n\t\ttier: 'audit',\n\t\tdirection: null,\n\t\tpool: null,\n\t\tversion: 1,\n\t\tretry: { attempts: 3, backoff: 'exponential' },\n\t},\n\t'deal_created': {\n\t\ttype: 'deal_created',\n\t\ttier: 'domain',\n\t\tdirection: 'change',\n\t\tpool: 'events_change',\n\t\taggregate: 'deal',\n\t\tversion: 1,\n\t\tretry: { attempts: 3, backoff: 'exponential' },\n\t},\n\t'deal_stage_changed': {\n\t\ttype: 'deal_stage_changed',\n\t\ttier: 'domain',\n\t\tdirection: 'change',\n\t\tpool: 'events_change',\n\t\taggregate: 'deal',\n\t\tversion: 1,\n\t\tretry: { attempts: 3, backoff: 'exponential' },\n\t},\n\t'stripe_payment_received': {\n\t\ttype: 'stripe_payment_received',\n\t\ttier: 'domain',\n\t\tdirection: 'inbound',\n\t\tpool: 'events_inbound',\n\t\tsource: 'stripe',\n\t\tversion: 1,\n\t\tretry: { attempts: 5, backoff: 'exponential' },\n\t},\n\t'webhook_outbound_contact_sync': {\n\t\ttype: 'webhook_outbound_contact_sync',\n\t\ttier: 'domain',\n\t\tdirection: 'outbound',\n\t\tpool: 'events_outbound',\n\t\taggregate: 'contact',\n\t\tdestination: 'crm',\n\t\tversion: 1,\n\t\tretry: { attempts: 3, backoff: 'exponential' },\n\t},\n} as const satisfies Record<EventTypeName, EventMetadata>;\n\nexport function getEventMetadata<T extends EventTypeName>(type: T): EventMetadata {\n\tconst meta = eventRegistry[type];\n\tif (!meta) {\n\t\tthrow new Error(`No registry entry for event type '${String(type)}' — declare events under events/*.yaml and re-run \\`codegen entity new --all\\`.`);\n\t}\n\treturn meta;\n}\n"],"mappings":";AAkBO,IAAM,gBAAgB;AAAA,EAC5B,mBAAmB;AAAA,IAClB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,WAAW;AAAA,IACX,MAAM;AAAA,IACN,WAAW;AAAA,IACX,SAAS;AAAA,IACT,OAAO,EAAE,UAAU,GAAG,SAAS,cAAc;AAAA,EAC9C;AAAA,EACA,2BAA2B;AAAA,IAC1B,MAAM;AAAA,IACN,MAAM;AAAA,IACN,WAAW;AAAA,IACX,MAAM;AAAA,IACN,WAAW;AAAA,IACX,SAAS;AAAA,IACT,OAAO,EAAE,UAAU,GAAG,SAAS,cAAc;AAAA,EAC9C;AAAA,EACA,kBAAkB;AAAA,IACjB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,WAAW;AAAA,IACX,MAAM;AAAA,IACN,WAAW;AAAA,IACX,SAAS;AAAA,IACT,OAAO,EAAE,UAAU,GAAG,SAAS,cAAc;AAAA,EAC9C;AAAA,EACA,oBAAoB;AAAA,IACnB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,WAAW;AAAA,IACX,MAAM;AAAA,IACN,SAAS;AAAA,IACT,OAAO,EAAE,UAAU,GAAG,SAAS,cAAc;AAAA,EAC9C;AAAA,EACA,gBAAgB;AAAA,IACf,MAAM;AAAA,IACN,MAAM;AAAA,IACN,WAAW;AAAA,IACX,MAAM;AAAA,IACN,WAAW;AAAA,IACX,SAAS;AAAA,IACT,OAAO,EAAE,UAAU,GAAG,SAAS,cAAc;AAAA,EAC9C;AAAA,EACA,sBAAsB;AAAA,IACrB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,WAAW;AAAA,IACX,MAAM;AAAA,IACN,WAAW;AAAA,IACX,SAAS;AAAA,IACT,OAAO,EAAE,UAAU,GAAG,SAAS,cAAc;AAAA,EAC9C;AAAA,EACA,2BAA2B;AAAA,IAC1B,MAAM;AAAA,IACN,MAAM;AAAA,IACN,WAAW;AAAA,IACX,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,OAAO,EAAE,UAAU,GAAG,SAAS,cAAc;AAAA,EAC9C;AAAA,EACA,iCAAiC;AAAA,IAChC,MAAM;AAAA,IACN,MAAM;AAAA,IACN,WAAW;AAAA,IACX,MAAM;AAAA,IACN,WAAW;AAAA,IACX,aAAa;AAAA,IACb,SAAS;AAAA,IACT,OAAO,EAAE,UAAU,GAAG,SAAS,cAAc;AAAA,EAC9C;AACD;AAEO,SAAS,iBAA0C,MAAwB;AACjF,QAAM,OAAO,cAAc,IAAI;AAC/B,MAAI,CAAC,MAAM;AACV,UAAM,IAAI,MAAM,qCAAqC,OAAO,IAAI,CAAC,sFAAiF;AAAA,EACnJ;AACA,SAAO;AACR;","names":[]}