@dyrected/core 2.5.51 → 2.5.52

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 (165) hide show
  1. package/dist/__tests__/admin-auth.test.d.ts +2 -0
  2. package/dist/__tests__/admin-auth.test.d.ts.map +1 -0
  3. package/dist/__tests__/admin-auth.test.js +440 -0
  4. package/dist/__tests__/admin-auth.test.js.map +1 -0
  5. package/dist/__tests__/config.test.js +57 -0
  6. package/dist/__tests__/config.test.js.map +1 -1
  7. package/dist/__tests__/email.service.test.d.ts +2 -0
  8. package/dist/__tests__/email.service.test.d.ts.map +1 -0
  9. package/dist/__tests__/email.service.test.js +46 -0
  10. package/dist/__tests__/email.service.test.js.map +1 -0
  11. package/dist/__tests__/fixtures/editorial-workflow.d.ts +9 -0
  12. package/dist/__tests__/fixtures/editorial-workflow.d.ts.map +1 -0
  13. package/dist/__tests__/fixtures/editorial-workflow.js +12 -0
  14. package/dist/__tests__/fixtures/editorial-workflow.js.map +1 -0
  15. package/dist/__tests__/mocks.d.ts +6 -0
  16. package/dist/__tests__/mocks.d.ts.map +1 -1
  17. package/dist/__tests__/mocks.js +8 -0
  18. package/dist/__tests__/mocks.js.map +1 -1
  19. package/dist/__tests__/openapi.test.d.ts +2 -0
  20. package/dist/__tests__/openapi.test.d.ts.map +1 -0
  21. package/dist/__tests__/openapi.test.js +95 -0
  22. package/dist/__tests__/openapi.test.js.map +1 -0
  23. package/dist/__tests__/parse-sort.test.d.ts +2 -0
  24. package/dist/__tests__/parse-sort.test.d.ts.map +1 -0
  25. package/dist/__tests__/parse-sort.test.js +24 -0
  26. package/dist/__tests__/parse-sort.test.js.map +1 -0
  27. package/dist/__tests__/preferences.test.d.ts +2 -0
  28. package/dist/__tests__/preferences.test.d.ts.map +1 -0
  29. package/dist/__tests__/preferences.test.js +168 -0
  30. package/dist/__tests__/preferences.test.js.map +1 -0
  31. package/dist/__tests__/router.test.js +4 -0
  32. package/dist/__tests__/router.test.js.map +1 -1
  33. package/dist/__tests__/where.test.js +9 -1
  34. package/dist/__tests__/where.test.js.map +1 -1
  35. package/dist/__tests__/workflow.test.d.ts +2 -0
  36. package/dist/__tests__/workflow.test.d.ts.map +1 -0
  37. package/dist/__tests__/workflow.test.js +497 -0
  38. package/dist/__tests__/workflow.test.js.map +1 -0
  39. package/dist/app-config-DLK6bCaP.d.cts +1390 -0
  40. package/dist/app-config-DLK6bCaP.d.ts +1390 -0
  41. package/dist/app-config-oOarB6Fw.d.cts +1411 -0
  42. package/dist/app-config-oOarB6Fw.d.ts +1411 -0
  43. package/dist/auth/token.d.ts +2 -0
  44. package/dist/auth/token.d.ts.map +1 -1
  45. package/dist/auth/token.js.map +1 -1
  46. package/dist/controllers/admin-auth.controller.d.ts +68 -0
  47. package/dist/controllers/admin-auth.controller.d.ts.map +1 -0
  48. package/dist/controllers/admin-auth.controller.js +414 -0
  49. package/dist/controllers/admin-auth.controller.js.map +1 -0
  50. package/dist/controllers/collection.controller.d.ts +69 -0
  51. package/dist/controllers/collection.controller.d.ts.map +1 -1
  52. package/dist/controllers/collection.controller.js +232 -7
  53. package/dist/controllers/collection.controller.js.map +1 -1
  54. package/dist/controllers/global.controller.js +19 -3
  55. package/dist/controllers/global.controller.js.map +1 -1
  56. package/dist/controllers/media.controller.d.ts +2 -0
  57. package/dist/controllers/media.controller.d.ts.map +1 -1
  58. package/dist/controllers/media.controller.js +13 -6
  59. package/dist/controllers/media.controller.js.map +1 -1
  60. package/dist/index.d.cts +2 -2
  61. package/dist/index.d.ts +2 -2
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js.map +1 -1
  64. package/dist/router.d.ts.map +1 -1
  65. package/dist/router.js +168 -6
  66. package/dist/router.js.map +1 -1
  67. package/dist/server.cjs +54 -8
  68. package/dist/server.d.cts +7 -1
  69. package/dist/server.d.ts +7 -1
  70. package/dist/server.js +54 -8
  71. package/dist/services/email-template.d.ts +46 -0
  72. package/dist/services/email-template.d.ts.map +1 -0
  73. package/dist/services/email-template.js +88 -0
  74. package/dist/services/email-template.js.map +1 -0
  75. package/dist/services/email.service.d.ts.map +1 -1
  76. package/dist/services/email.service.js +25 -148
  77. package/dist/services/email.service.js.map +1 -1
  78. package/dist/services/population.service.d.ts.map +1 -1
  79. package/dist/services/population.service.js +27 -1
  80. package/dist/services/population.service.js.map +1 -1
  81. package/dist/types/access.d.ts +38 -0
  82. package/dist/types/access.d.ts.map +1 -0
  83. package/dist/types/access.js +2 -0
  84. package/dist/types/access.js.map +1 -0
  85. package/dist/types/adapters.d.ts +146 -0
  86. package/dist/types/adapters.d.ts.map +1 -0
  87. package/dist/types/adapters.js +2 -0
  88. package/dist/types/adapters.js.map +1 -0
  89. package/dist/types/admin-auth.d.ts +132 -0
  90. package/dist/types/admin-auth.d.ts.map +1 -0
  91. package/dist/types/admin-auth.js +2 -0
  92. package/dist/types/admin-auth.js.map +1 -0
  93. package/dist/types/admin.d.ts +65 -0
  94. package/dist/types/admin.d.ts.map +1 -0
  95. package/dist/types/admin.js +2 -0
  96. package/dist/types/admin.js.map +1 -0
  97. package/dist/types/app-config.d.ts +143 -0
  98. package/dist/types/app-config.d.ts.map +1 -0
  99. package/dist/types/app-config.js +2 -0
  100. package/dist/types/app-config.js.map +1 -0
  101. package/dist/types/documents.d.ts +65 -0
  102. package/dist/types/documents.d.ts.map +1 -0
  103. package/dist/types/documents.js +2 -0
  104. package/dist/types/documents.js.map +1 -0
  105. package/dist/types/hooks.d.ts +122 -0
  106. package/dist/types/hooks.d.ts.map +1 -0
  107. package/dist/types/hooks.js +2 -0
  108. package/dist/types/hooks.js.map +1 -0
  109. package/dist/types/index.d.ts +12 -1748
  110. package/dist/types/index.d.ts.map +1 -1
  111. package/dist/types/index.js +12 -2
  112. package/dist/types/index.js.map +1 -1
  113. package/dist/types/request.d.ts +42 -0
  114. package/dist/types/request.d.ts.map +1 -0
  115. package/dist/types/request.js +2 -0
  116. package/dist/types/request.js.map +1 -0
  117. package/dist/types/schema-config.d.ts +303 -0
  118. package/dist/types/schema-config.d.ts.map +1 -0
  119. package/dist/types/schema-config.js +2 -0
  120. package/dist/types/schema-config.js.map +1 -0
  121. package/dist/types/schema-core.d.ts +294 -0
  122. package/dist/types/schema-core.d.ts.map +1 -0
  123. package/dist/types/schema-core.js +2 -0
  124. package/dist/types/schema-core.js.map +1 -0
  125. package/dist/types/schema-inference.d.ts +73 -0
  126. package/dist/types/schema-inference.d.ts.map +1 -0
  127. package/dist/types/schema-inference.js +2 -0
  128. package/dist/types/schema-inference.js.map +1 -0
  129. package/dist/types/workflows.d.ts +84 -0
  130. package/dist/types/workflows.d.ts.map +1 -0
  131. package/dist/types/workflows.js +7 -0
  132. package/dist/types/workflows.js.map +1 -0
  133. package/dist/utils/admin-auth.d.ts +5 -0
  134. package/dist/utils/admin-auth.d.ts.map +1 -0
  135. package/dist/utils/admin-auth.js +39 -0
  136. package/dist/utils/admin-auth.js.map +1 -0
  137. package/dist/utils/config.d.ts.map +1 -1
  138. package/dist/utils/config.js +86 -1
  139. package/dist/utils/config.js.map +1 -1
  140. package/dist/utils/hooks.d.ts.map +1 -1
  141. package/dist/utils/hooks.js +12 -8
  142. package/dist/utils/hooks.js.map +1 -1
  143. package/dist/utils/openapi.d.ts.map +1 -1
  144. package/dist/utils/openapi.js +559 -48
  145. package/dist/utils/openapi.js.map +1 -1
  146. package/dist/utils/parse-sort.d.ts +7 -0
  147. package/dist/utils/parse-sort.d.ts.map +1 -0
  148. package/dist/utils/parse-sort.js +23 -0
  149. package/dist/utils/parse-sort.js.map +1 -0
  150. package/dist/utils/swagger.d.ts +6 -0
  151. package/dist/utils/swagger.d.ts.map +1 -1
  152. package/dist/utils/swagger.js +13 -2
  153. package/dist/utils/swagger.js.map +1 -1
  154. package/dist/utils/upload-validation.d.ts +23 -0
  155. package/dist/utils/upload-validation.d.ts.map +1 -0
  156. package/dist/utils/upload-validation.js +44 -0
  157. package/dist/utils/upload-validation.js.map +1 -0
  158. package/dist/utils/where-sanitizer.d.ts.map +1 -1
  159. package/dist/utils/where-sanitizer.js +4 -0
  160. package/dist/utils/where-sanitizer.js.map +1 -1
  161. package/dist/workflows.d.ts +54 -0
  162. package/dist/workflows.d.ts.map +1 -0
  163. package/dist/workflows.js +282 -0
  164. package/dist/workflows.js.map +1 -0
  165. package/package.json +1 -1
@@ -0,0 +1,497 @@
1
+ import { describe, it, expect, vi, beforeEach } from "vitest";
2
+ import { InMemoryAdapter } from "./mocks.js";
3
+ import { defineCollection, defineConfig } from "../index.js";
4
+ import { publishingWorkflow, initializeWorkflowDocument, materializeWorkflowDocument, transitionWorkflow, saveWorkflowDraft, createWorkflowDocument, dispatchPendingLifecycleEvents, WORKFLOW_HISTORY_COLLECTION, LIFECYCLE_EVENTS_COLLECTION, } from "../workflows.js";
5
+ import { EditorialPosts } from "./fixtures/editorial-workflow.js";
6
+ import { generateOpenApi } from "../utils/openapi.js";
7
+ // ─── Shared config builders ───────────────────────────────────────────────────
8
+ function makeConfig(db) {
9
+ return defineConfig({ collections: [EditorialPosts], globals: [], db });
10
+ }
11
+ function makeUser(role) {
12
+ return { sub: `user-${role}`, email: `${role}@test.com`, roles: [role], collection: "users" };
13
+ }
14
+ async function seedPost(db, id) {
15
+ const raw = { id, title: "Hello", body: "World" };
16
+ const initialized = initializeWorkflowDocument(raw, publishingWorkflow());
17
+ const doc = { id, ...initialized };
18
+ await db.create({ collection: "posts", data: doc });
19
+ return doc;
20
+ }
21
+ // ─── Tests ────────────────────────────────────────────────────────────────────
22
+ describe("publishingWorkflow template", () => {
23
+ it("initializes a document with __workflow in draft state", () => {
24
+ const doc = initializeWorkflowDocument({ title: "Test" }, publishingWorkflow());
25
+ const workflow = doc.__workflow;
26
+ expect(workflow.state).toBe("draft");
27
+ expect(workflow.revision).toBe(1);
28
+ expect(workflow.publishedRevision).toBeUndefined();
29
+ expect(workflow.publishedAt).toBeUndefined();
30
+ expect(workflow.publishedBy).toBeUndefined();
31
+ });
32
+ it("includes correct states and transitions in the template", () => {
33
+ const wf = publishingWorkflow();
34
+ const stateNames = wf.states.map((s) => s.name);
35
+ expect(stateNames).toContain("draft");
36
+ expect(stateNames).toContain("in_review");
37
+ expect(stateNames).toContain("published");
38
+ const transitionNames = wf.transitions.map((t) => t.name);
39
+ expect(transitionNames).toContain("submit");
40
+ expect(transitionNames).toContain("publish");
41
+ expect(transitionNames).toContain("reject");
42
+ expect(transitionNames).toContain("unpublish");
43
+ });
44
+ it("adds workflow operations and metadata to OpenAPI", () => {
45
+ const spec = generateOpenApi(defineConfig({ collections: [EditorialPosts], globals: [] }));
46
+ expect(spec.paths["/api/collections/posts/{id}/transitions/{transition}"]?.post).toBeTruthy();
47
+ expect(spec.paths["/api/collections/posts/{id}/workflow-history"]?.get).toBeTruthy();
48
+ expect(spec.components.schemas.posts.properties._workflow.$ref).toBe("#/components/schemas/WorkflowMetadata");
49
+ });
50
+ });
51
+ describe("workflow document visibility", () => {
52
+ const stored = {
53
+ id: "post-live",
54
+ title: "Working draft",
55
+ __published: { title: "Live title" },
56
+ __workflow: { state: "draft", revision: 2, publishedRevision: 1 },
57
+ };
58
+ it("serves the published snapshot to anonymous users and viewers", () => {
59
+ const workflow = publishingWorkflow();
60
+ expect(materializeWorkflowDocument(stored, workflow)?.title).toBe("Live title");
61
+ expect(materializeWorkflowDocument(stored, workflow, makeUser("admin"))?.title).toBe("Working draft");
62
+ expect(materializeWorkflowDocument(stored, workflow, {
63
+ sub: "viewer",
64
+ roles: ["viewer"],
65
+ collection: "users",
66
+ })?.title).toBe("Live title");
67
+ });
68
+ it("does not expose an unpublished draft to a viewer", () => {
69
+ const draft = { id: "draft", title: "Secret", __workflow: { state: "draft", revision: 1 } };
70
+ expect(materializeWorkflowDocument(draft, publishingWorkflow(), {
71
+ sub: "viewer",
72
+ roles: ["viewer"],
73
+ collection: "users",
74
+ })).toBeNull();
75
+ });
76
+ });
77
+ describe("saveWorkflowDraft", () => {
78
+ let db;
79
+ let config;
80
+ beforeEach(() => {
81
+ db = new InMemoryAdapter();
82
+ config = makeConfig(db);
83
+ });
84
+ it("increments the revision and writes an outbox event", async () => {
85
+ const post = await seedPost(db, "post-1");
86
+ const collection = config.collections[0];
87
+ await saveWorkflowDraft({
88
+ config,
89
+ collection,
90
+ id: "post-1",
91
+ originalDoc: post,
92
+ data: { title: "Updated Title" },
93
+ });
94
+ const updated = await db.findOne({ collection: "posts", id: "post-1" });
95
+ const workflow = updated.__workflow;
96
+ expect(workflow.revision).toBe(2);
97
+ expect(updated.title).toBe("Updated Title");
98
+ // Outbox event written
99
+ const events = await db.find({ collection: LIFECYCLE_EVENTS_COLLECTION });
100
+ expect(events.total).toBeGreaterThan(0);
101
+ const event = events.docs[0];
102
+ expect(event.name).toBe("revision.created");
103
+ expect(event.status).toBe("pending");
104
+ });
105
+ });
106
+ describe("createWorkflowDocument", () => {
107
+ let db;
108
+ let config;
109
+ beforeEach(() => {
110
+ db = new InMemoryAdapter();
111
+ config = makeConfig(db);
112
+ });
113
+ it("creates a doc in draft state with revision 1 and an outbox event", async () => {
114
+ const collection = config.collections[0];
115
+ const rawData = { title: "Brand New" };
116
+ const initializedData = initializeWorkflowDocument(rawData, publishingWorkflow());
117
+ const { doc } = await createWorkflowDocument({
118
+ config,
119
+ collection,
120
+ data: initializedData,
121
+ });
122
+ const workflow = doc.__workflow;
123
+ expect(workflow.state).toBe("draft");
124
+ expect(workflow.revision).toBe(1);
125
+ const events = await db.find({ collection: LIFECYCLE_EVENTS_COLLECTION });
126
+ expect(events.total).toBe(1);
127
+ expect(events.docs[0].name).toBe("revision.created");
128
+ });
129
+ });
130
+ describe("transitionWorkflow", () => {
131
+ let db;
132
+ let config;
133
+ beforeEach(() => {
134
+ db = new InMemoryAdapter();
135
+ config = makeConfig(db);
136
+ });
137
+ it("editor can submit a draft for review", async () => {
138
+ await seedPost(db, "post-1");
139
+ const collection = config.collections[0];
140
+ const editor = makeUser("editor");
141
+ const result = await transitionWorkflow({
142
+ config,
143
+ collection,
144
+ id: "post-1",
145
+ transitionName: "submit",
146
+ user: editor,
147
+ req: { query: {}, headers: {} },
148
+ });
149
+ const workflow = result.__workflow;
150
+ expect(workflow.state).toBe("in_review");
151
+ // History entry created
152
+ const history = await db.find({ collection: WORKFLOW_HISTORY_COLLECTION });
153
+ expect(history.total).toBe(1);
154
+ expect(history.docs[0].from).toBe("draft");
155
+ expect(history.docs[0].to).toBe("in_review");
156
+ });
157
+ it("editor cannot publish directly (lacks capability)", async () => {
158
+ await seedPost(db, "post-2");
159
+ // Move to in_review first using a publisher
160
+ const collection = config.collections[0];
161
+ await transitionWorkflow({
162
+ config,
163
+ collection,
164
+ id: "post-2",
165
+ transitionName: "submit",
166
+ user: makeUser("editor"),
167
+ req: { query: {}, headers: {} },
168
+ });
169
+ // Now editor tries to publish — should be denied
170
+ const editor = makeUser("editor");
171
+ await expect(transitionWorkflow({
172
+ config,
173
+ collection,
174
+ id: "post-2",
175
+ transitionName: "publish",
176
+ user: editor,
177
+ req: { query: {}, headers: {} },
178
+ })).rejects.toThrow(/not permitted|403|permission/i);
179
+ });
180
+ it("publisher can publish a submitted doc — promotes __published snapshot", async () => {
181
+ await seedPost(db, "post-3");
182
+ const collection = config.collections[0];
183
+ const editor = makeUser("editor");
184
+ const publisher = makeUser("publisher");
185
+ await transitionWorkflow({
186
+ config,
187
+ collection,
188
+ id: "post-3",
189
+ transitionName: "submit",
190
+ user: editor,
191
+ req: { query: {}, headers: {} },
192
+ });
193
+ const result = await transitionWorkflow({
194
+ config,
195
+ collection,
196
+ id: "post-3",
197
+ transitionName: "publish",
198
+ user: publisher,
199
+ req: { query: {}, headers: {} },
200
+ });
201
+ const workflow = result.__workflow;
202
+ expect(workflow.state).toBe("published");
203
+ expect(workflow.publishedRevision).toBe(1);
204
+ expect(workflow.publishedAt).toBeTruthy();
205
+ expect(workflow.publishedBy).toBe(publisher.sub);
206
+ // __published snapshot present
207
+ const stored = await db.findOne({ collection: "posts", id: "post-3" });
208
+ expect(stored.__published).toBeTruthy();
209
+ expect(stored.__published.title).toBe("Hello");
210
+ });
211
+ it("publisher can reject and the state returns to draft", async () => {
212
+ await seedPost(db, "post-4");
213
+ const collection = config.collections[0];
214
+ await transitionWorkflow({
215
+ config,
216
+ collection,
217
+ id: "post-4",
218
+ transitionName: "submit",
219
+ user: makeUser("editor"),
220
+ req: { query: {}, headers: {} },
221
+ });
222
+ const result = await transitionWorkflow({
223
+ config,
224
+ collection,
225
+ id: "post-4",
226
+ transitionName: "reject",
227
+ user: makeUser("publisher"),
228
+ comment: "Needs more detail.",
229
+ req: { query: {}, headers: {} },
230
+ });
231
+ const workflow = result.__workflow;
232
+ expect(workflow.state).toBe("draft");
233
+ const history = await db.find({ collection: WORKFLOW_HISTORY_COLLECTION });
234
+ const rejectEntry = history.docs.find((h) => h.transition === "reject");
235
+ expect(rejectEntry).toBeTruthy();
236
+ expect(rejectEntry.comment).toBe("Needs more detail.");
237
+ });
238
+ it("unpublish clears the __published snapshot and moves back to draft", async () => {
239
+ await seedPost(db, "post-5");
240
+ const collection = config.collections[0];
241
+ const editor = makeUser("editor");
242
+ const publisher = makeUser("publisher");
243
+ await transitionWorkflow({
244
+ config,
245
+ collection,
246
+ id: "post-5",
247
+ transitionName: "submit",
248
+ user: editor,
249
+ req: { query: {}, headers: {} },
250
+ });
251
+ await transitionWorkflow({
252
+ config,
253
+ collection,
254
+ id: "post-5",
255
+ transitionName: "publish",
256
+ user: publisher,
257
+ req: { query: {}, headers: {} },
258
+ });
259
+ const result = await transitionWorkflow({
260
+ config,
261
+ collection,
262
+ id: "post-5",
263
+ transitionName: "unpublish",
264
+ user: publisher,
265
+ req: { query: {}, headers: {} },
266
+ });
267
+ const workflow = result.__workflow;
268
+ expect(workflow.state).toBe("draft");
269
+ const stored = await db.findOne({ collection: "posts", id: "post-5" });
270
+ expect(stored.__published).toBeNull();
271
+ });
272
+ it("rejects a stale transition when expectedRevision does not match", async () => {
273
+ await seedPost(db, "post-6");
274
+ const collection = config.collections[0];
275
+ await expect(transitionWorkflow({
276
+ config,
277
+ collection,
278
+ id: "post-6",
279
+ transitionName: "submit",
280
+ user: makeUser("editor"),
281
+ expectedRevision: 99, // wrong
282
+ req: { query: {}, headers: {} },
283
+ })).rejects.toThrow(/changed since it was loaded|stale|revision/i);
284
+ });
285
+ it("leaves the document unchanged when a transition is rejected (atomic guarantee)", async () => {
286
+ await seedPost(db, "post-7");
287
+ const collection = config.collections[0];
288
+ // Attempt a forbidden transition
289
+ try {
290
+ await transitionWorkflow({
291
+ config,
292
+ collection,
293
+ id: "post-7",
294
+ transitionName: "publish",
295
+ user: makeUser("editor"), // no publish capability
296
+ req: { query: {}, headers: {} },
297
+ });
298
+ }
299
+ catch {
300
+ // expected
301
+ }
302
+ const stored = await db.findOne({ collection: "posts", id: "post-7" });
303
+ const workflow = stored.__workflow;
304
+ expect(workflow.state).toBe("draft"); // unchanged
305
+ const history = await db.find({ collection: WORKFLOW_HISTORY_COLLECTION });
306
+ expect(history.total).toBe(0); // no history written
307
+ });
308
+ it("emits a workflow.transitioned outbox event on every successful transition", async () => {
309
+ await seedPost(db, "post-8");
310
+ const collection = config.collections[0];
311
+ await transitionWorkflow({
312
+ config,
313
+ collection,
314
+ id: "post-8",
315
+ transitionName: "submit",
316
+ user: makeUser("editor"),
317
+ req: { query: {}, headers: {} },
318
+ });
319
+ const events = await db.find({ collection: LIFECYCLE_EVENTS_COLLECTION });
320
+ const transitioned = events.docs.find((e) => e.name === "workflow.transitioned");
321
+ expect(transitioned).toBeTruthy();
322
+ expect(transitioned.payload.transition).toBe("submit");
323
+ });
324
+ it("emits an entry.published event when the doc enters the published state", async () => {
325
+ await seedPost(db, "post-9");
326
+ const collection = config.collections[0];
327
+ await transitionWorkflow({
328
+ config,
329
+ collection,
330
+ id: "post-9",
331
+ transitionName: "submit",
332
+ user: makeUser("editor"),
333
+ req: { query: {}, headers: {} },
334
+ });
335
+ await transitionWorkflow({
336
+ config,
337
+ collection,
338
+ id: "post-9",
339
+ transitionName: "publish",
340
+ user: makeUser("publisher"),
341
+ req: { query: {}, headers: {} },
342
+ });
343
+ const events = await db.find({ collection: LIFECYCLE_EVENTS_COLLECTION });
344
+ const published = events.docs.find((e) => e.name === "entry.published");
345
+ expect(published).toBeTruthy();
346
+ expect(published.collection).toBe("posts");
347
+ });
348
+ it("collections without workflow are unaffected (backward compat)", async () => {
349
+ // Plain collection, no workflow
350
+ const plain = defineCollection({
351
+ slug: "plain",
352
+ fields: [{ name: "title", type: "text" }],
353
+ });
354
+ const plainConfig = defineConfig({ collections: [plain], globals: [], db });
355
+ await db.create({ collection: "plain", data: { id: "p-1", title: "Hello" } });
356
+ // Reading back a plain doc should have no __workflow
357
+ const doc = await db.findOne({ collection: "plain", id: "p-1" });
358
+ expect(doc.__workflow).toBeUndefined();
359
+ // No lifecycle events from plain collection operations
360
+ const events = await db.find({ collection: LIFECYCLE_EVENTS_COLLECTION });
361
+ expect(events.total).toBe(0);
362
+ });
363
+ });
364
+ describe("dispatchPendingLifecycleEvents", () => {
365
+ let db;
366
+ let config;
367
+ beforeEach(() => {
368
+ db = new InMemoryAdapter();
369
+ config = makeConfig(db);
370
+ });
371
+ it("calls registered handlers and marks events delivered", async () => {
372
+ // Seed a pending event directly
373
+ const handler = vi.fn().mockResolvedValue(undefined);
374
+ const configWithHandler = {
375
+ ...config,
376
+ events: {
377
+ handlers: [handler],
378
+ maxAttempts: 3,
379
+ retryDelayMs: 100,
380
+ },
381
+ };
382
+ await db.create({
383
+ collection: LIFECYCLE_EVENTS_COLLECTION,
384
+ data: {
385
+ id: "evt-1",
386
+ name: "revision.created",
387
+ collection: "posts",
388
+ documentId: "p1",
389
+ status: "pending",
390
+ attempts: 0,
391
+ payload: { collection: "posts", documentId: "p1", revision: 1 },
392
+ occurredAt: new Date().toISOString(),
393
+ createdAt: new Date().toISOString(),
394
+ nextAttemptAt: new Date().toISOString(),
395
+ },
396
+ });
397
+ const dispatched = await dispatchPendingLifecycleEvents(configWithHandler, 50);
398
+ expect(dispatched).toBe(1);
399
+ expect(handler).toHaveBeenCalledOnce();
400
+ const events = await db.find({ collection: LIFECYCLE_EVENTS_COLLECTION });
401
+ expect(events.docs[0].status).toBe("delivered");
402
+ });
403
+ it("increments attempt count and retries on handler failure", async () => {
404
+ const handler = vi.fn().mockRejectedValue(new Error("webhook down"));
405
+ const configWithHandler = {
406
+ ...config,
407
+ events: {
408
+ handlers: [handler],
409
+ maxAttempts: 3,
410
+ retryDelayMs: 100,
411
+ },
412
+ };
413
+ await db.create({
414
+ collection: LIFECYCLE_EVENTS_COLLECTION,
415
+ data: {
416
+ id: "evt-2",
417
+ name: "revision.created",
418
+ collection: "posts",
419
+ documentId: "p1",
420
+ status: "pending",
421
+ attempts: 0,
422
+ payload: { collection: "posts", documentId: "p1", revision: 1 },
423
+ occurredAt: new Date().toISOString(),
424
+ createdAt: new Date().toISOString(),
425
+ nextAttemptAt: new Date().toISOString(),
426
+ },
427
+ });
428
+ await dispatchPendingLifecycleEvents(configWithHandler, 50);
429
+ const events = await db.find({ collection: LIFECYCLE_EVENTS_COLLECTION });
430
+ const event = events.docs[0];
431
+ expect(event.status).toBe("failed"); // transitioned to failed status first
432
+ expect(event.attempts).toBe(1);
433
+ });
434
+ it("preserves stable event IDs across retries (no duplicate IDs)", async () => {
435
+ const eventId = "stable-evt-id";
436
+ await db.create({
437
+ collection: LIFECYCLE_EVENTS_COLLECTION,
438
+ data: {
439
+ id: eventId,
440
+ name: "revision.created",
441
+ collection: "posts",
442
+ documentId: "p1",
443
+ status: "pending",
444
+ attempts: 0,
445
+ payload: { collection: "posts", documentId: "p1", revision: 1 },
446
+ occurredAt: new Date().toISOString(),
447
+ createdAt: new Date().toISOString(),
448
+ nextAttemptAt: new Date().toISOString(),
449
+ },
450
+ });
451
+ // No handlers configured — event should stay with same ID
452
+ await dispatchPendingLifecycleEvents(config, 50);
453
+ const stored = await db.findOne({ collection: LIFECYCLE_EVENTS_COLLECTION, id: eventId });
454
+ expect(stored).not.toBeNull();
455
+ expect(stored.id).toBe(eventId);
456
+ });
457
+ it("does not process events whose nextAttemptAt is in the future", async () => {
458
+ const futureDate = new Date(Date.now() + 60_000).toISOString();
459
+ await db.create({
460
+ collection: LIFECYCLE_EVENTS_COLLECTION,
461
+ data: {
462
+ id: "evt-future",
463
+ name: "revision.created",
464
+ collection: "posts",
465
+ documentId: "p1",
466
+ status: "pending",
467
+ attempts: 1,
468
+ payload: {},
469
+ occurredAt: new Date().toISOString(),
470
+ createdAt: new Date().toISOString(),
471
+ nextAttemptAt: futureDate,
472
+ },
473
+ });
474
+ const dispatched = await dispatchPendingLifecycleEvents(config, 50);
475
+ expect(dispatched).toBe(0);
476
+ });
477
+ it("does not retry events that exhausted maxAttempts", async () => {
478
+ const handler = vi.fn();
479
+ const exhaustedConfig = { ...config, events: { handlers: [handler], maxAttempts: 3 } };
480
+ await db.create({
481
+ collection: LIFECYCLE_EVENTS_COLLECTION,
482
+ data: {
483
+ id: "evt-exhausted",
484
+ name: "revision.created",
485
+ collection: "posts",
486
+ documentId: "p1",
487
+ status: "failed",
488
+ attempts: 3,
489
+ payload: {},
490
+ occurredAt: new Date().toISOString(),
491
+ },
492
+ });
493
+ expect(await dispatchPendingLifecycleEvents(exhaustedConfig, 50)).toBe(0);
494
+ expect(handler).not.toHaveBeenCalled();
495
+ });
496
+ });
497
+ //# sourceMappingURL=workflow.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow.test.js","sourceRoot":"","sources":["../../src/__tests__/workflow.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EACL,kBAAkB,EAClB,0BAA0B,EAC1B,2BAA2B,EAC3B,kBAAkB,EAClB,iBAAiB,EACjB,sBAAsB,EACtB,8BAA8B,EAC9B,2BAA2B,EAC3B,2BAA2B,GAC5B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,iFAAiF;AAEjF,SAAS,UAAU,CAAC,EAAmB;IACrC,OAAO,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC,cAAc,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;AAC1E,CAAC;AAED,SAAS,QAAQ,CAAC,IAAsC;IACtD,OAAO,EAAE,GAAG,EAAE,QAAQ,IAAI,EAAE,EAAE,KAAK,EAAE,GAAG,IAAI,WAAW,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;AAChG,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,EAAmB,EAAE,EAAU;IACrD,MAAM,GAAG,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAClD,MAAM,WAAW,GAAG,0BAA0B,CAAC,GAAG,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAC1E,MAAM,GAAG,GAAG,EAAE,EAAE,EAAE,GAAG,WAAW,EAAE,CAAC;IACnC,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;IACpD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,iFAAiF;AAEjF,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAC3C,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,GAAG,GAAG,0BAA0B,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAChF,MAAM,QAAQ,GAAG,GAAG,CAAC,UAA8B,CAAC;QACpD,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,aAAa,EAAE,CAAC;QACnD,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,aAAa,EAAE,CAAC;QAC7C,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,aAAa,EAAE,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,EAAE,GAAG,kBAAkB,EAAE,CAAC;QAChC,MAAM,UAAU,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAChD,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACtC,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAC1C,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAE1C,MAAM,eAAe,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC1D,MAAM,CAAC,eAAe,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,CAAC,eAAe,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAC7C,MAAM,CAAC,eAAe,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,CAAC,eAAe,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,IAAI,GAAG,eAAe,CAAC,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC,cAAc,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAC3F,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,sDAAsD,CAAC,EAAE,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;QAC9F,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,8CAA8C,CAAC,EAAE,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC;QACrF,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;IAChH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC5C,MAAM,MAAM,GAAG;QACb,EAAE,EAAE,WAAW;QACf,KAAK,EAAE,eAAe;QACtB,WAAW,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE;QACpC,UAAU,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE;KAClE,CAAC;IAEF,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAC;QACtC,MAAM,CAAC,2BAA2B,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAChF,MAAM,CAAC,2BAA2B,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACtG,MAAM,CAAC,2BAA2B,CAAC,MAAM,EAAE,QAAQ,EAAE;YACnD,GAAG,EAAE,QAAQ;YACb,KAAK,EAAE,CAAC,QAAQ,CAAC;YACjB,UAAU,EAAE,OAAO;SACpB,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,KAAK,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5F,MAAM,CAAC,2BAA2B,CAAC,KAAK,EAAE,kBAAkB,EAAE,EAAE;YAC9D,GAAG,EAAE,QAAQ;YACb,KAAK,EAAE,CAAC,QAAQ,CAAC;YACjB,UAAU,EAAE,OAAO;SACpB,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IACjB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,IAAI,EAAmB,CAAC;IACxB,IAAI,MAAqC,CAAC;IAE1C,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;QAC3B,MAAM,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;QAClE,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC1C,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAEzC,MAAM,iBAAiB,CAAC;YACtB,MAAM;YACN,UAAU;YACV,EAAE,EAAE,QAAQ;YACZ,WAAW,EAAE,IAAI;YACjB,IAAI,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE;SACjC,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;QACxE,MAAM,QAAQ,GAAG,OAAO,CAAC,UAA8B,CAAC;QACxD,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAE5C,uBAAuB;QACvB,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,2BAA2B,EAAE,CAAC,CAAC;QAC1E,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACxC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAC5C,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,IAAI,EAAmB,CAAC;IACxB,IAAI,MAAqC,CAAC;IAE1C,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;QAC3B,MAAM,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;QAChF,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QACzC,MAAM,OAAO,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;QACvC,MAAM,eAAe,GAAG,0BAA0B,CAAC,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAClF,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,sBAAsB,CAAC;YAC3C,MAAM;YACN,UAAU;YACV,IAAI,EAAE,eAAe;SACtB,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,GAAG,CAAC,UAA8B,CAAC;QACpD,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAElC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,2BAA2B,EAAE,CAAC,CAAC;QAC1E,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,IAAI,EAAmB,CAAC;IACxB,IAAI,MAAqC,CAAC;IAE1C,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;QAC3B,MAAM,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,MAAM,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC7B,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAElC,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC;YACtC,MAAM;YACN,UAAU;YACV,EAAE,EAAE,QAAQ;YACZ,cAAc,EAAE,QAAQ;YACxB,IAAI,EAAE,MAAM;YACZ,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;SAChC,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,MAAM,CAAC,UAA8B,CAAC;QACvD,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAEzC,wBAAwB;QACxB,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,2BAA2B,EAAE,CAAC,CAAC;QAC3E,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3C,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC7B,4CAA4C;QAC5C,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QACzC,MAAM,kBAAkB,CAAC;YACvB,MAAM;YACN,UAAU;YACV,EAAE,EAAE,QAAQ;YACZ,cAAc,EAAE,QAAQ;YACxB,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC;YACxB,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;SAChC,CAAC,CAAC;QAEH,iDAAiD;QACjD,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAClC,MAAM,MAAM,CACV,kBAAkB,CAAC;YACjB,MAAM;YACN,UAAU;YACV,EAAE,EAAE,QAAQ;YACZ,cAAc,EAAE,SAAS;YACzB,IAAI,EAAE,MAAM;YACZ,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;SAChC,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;QACrF,MAAM,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC7B,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAClC,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;QAExC,MAAM,kBAAkB,CAAC;YACvB,MAAM;YACN,UAAU;YACV,EAAE,EAAE,QAAQ;YACZ,cAAc,EAAE,QAAQ;YACxB,IAAI,EAAE,MAAM;YACZ,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;SAChC,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC;YACtC,MAAM;YACN,UAAU;YACV,EAAE,EAAE,QAAQ;YACZ,cAAc,EAAE,SAAS;YACzB,IAAI,EAAE,SAAS;YACf,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;SAChC,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,MAAM,CAAC,UAA8B,CAAC;QACvD,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,UAAU,EAAE,CAAC;QAC1C,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAEjD,+BAA+B;QAC/B,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;QACvE,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,UAAU,EAAE,CAAC;QACxC,MAAM,CAAE,MAAM,CAAC,WAAmB,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;QACnE,MAAM,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC7B,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QACzC,MAAM,kBAAkB,CAAC;YACvB,MAAM;YACN,UAAU;YACV,EAAE,EAAE,QAAQ;YACZ,cAAc,EAAE,QAAQ;YACxB,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC;YACxB,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;SAChC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC;YACtC,MAAM;YACN,UAAU;YACV,EAAE,EAAE,QAAQ;YACZ,cAAc,EAAE,QAAQ;YACxB,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC;YAC3B,OAAO,EAAE,oBAAoB;YAC7B,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;SAChC,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,MAAM,CAAC,UAA8B,CAAC;QACvD,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAErC,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,2BAA2B,EAAE,CAAC,CAAC;QAC3E,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC;QAC7E,MAAM,CAAC,WAAW,CAAC,CAAC,UAAU,EAAE,CAAC;QACjC,MAAM,CAAC,WAAY,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;QACjF,MAAM,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC7B,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAClC,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;QAExC,MAAM,kBAAkB,CAAC;YACvB,MAAM;YACN,UAAU;YACV,EAAE,EAAE,QAAQ;YACZ,cAAc,EAAE,QAAQ;YACxB,IAAI,EAAE,MAAM;YACZ,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;SAChC,CAAC,CAAC;QACH,MAAM,kBAAkB,CAAC;YACvB,MAAM;YACN,UAAU;YACV,EAAE,EAAE,QAAQ;YACZ,cAAc,EAAE,SAAS;YACzB,IAAI,EAAE,SAAS;YACf,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;SAChC,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC;YACtC,MAAM;YACN,UAAU;YACV,EAAE,EAAE,QAAQ;YACZ,cAAc,EAAE,WAAW;YAC3B,IAAI,EAAE,SAAS;YACf,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;SAChC,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,MAAM,CAAC,UAA8B,CAAC;QACvD,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;QACvE,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,QAAQ,EAAE,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;QAC/E,MAAM,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC7B,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAEzC,MAAM,MAAM,CACV,kBAAkB,CAAC;YACjB,MAAM;YACN,UAAU;YACV,EAAE,EAAE,QAAQ;YACZ,cAAc,EAAE,QAAQ;YACxB,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC;YACxB,gBAAgB,EAAE,EAAE,EAAE,QAAQ;YAC9B,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;SAChC,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,6CAA6C,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gFAAgF,EAAE,KAAK,IAAI,EAAE;QAC9F,MAAM,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC7B,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAEzC,iCAAiC;QACjC,IAAI,CAAC;YACH,MAAM,kBAAkB,CAAC;gBACvB,MAAM;gBACN,UAAU;gBACV,EAAE,EAAE,QAAQ;gBACZ,cAAc,EAAE,SAAS;gBACzB,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,wBAAwB;gBAClD,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;aAChC,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,WAAW;QACb,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;QACvE,MAAM,QAAQ,GAAG,MAAM,CAAC,UAA8B,CAAC;QACvD,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY;QAClD,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,2BAA2B,EAAE,CAAC,CAAC;QAC3E,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,qBAAqB;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2EAA2E,EAAE,KAAK,IAAI,EAAE;QACzF,MAAM,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC7B,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAEzC,MAAM,kBAAkB,CAAC;YACvB,MAAM;YACN,UAAU;YACV,EAAE,EAAE,QAAQ;YACZ,cAAc,EAAE,QAAQ;YACxB,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC;YACxB,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;SAChC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,2BAA2B,EAAE,CAAC,CAAC;QAC1E,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,uBAAuB,CAAC,CAAC;QACtF,MAAM,CAAC,YAAY,CAAC,CAAC,UAAU,EAAE,CAAC;QAClC,MAAM,CAAC,YAAa,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;QACtF,MAAM,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC7B,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAEzC,MAAM,kBAAkB,CAAC;YACvB,MAAM;YACN,UAAU;YACV,EAAE,EAAE,QAAQ;YACZ,cAAc,EAAE,QAAQ;YACxB,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC;YACxB,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;SAChC,CAAC,CAAC;QACH,MAAM,kBAAkB,CAAC;YACvB,MAAM;YACN,UAAU;YACV,EAAE,EAAE,QAAQ;YACZ,cAAc,EAAE,SAAS;YACzB,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC;YAC3B,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;SAChC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,2BAA2B,EAAE,CAAC,CAAC;QAC1E,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,iBAAiB,CAAC,CAAC;QAC7E,MAAM,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,CAAC;QAC/B,MAAM,CAAC,SAAU,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC7E,gCAAgC;QAChC,MAAM,KAAK,GAAG,gBAAgB,CAAC;YAC7B,IAAI,EAAE,OAAO;YACb,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;SAC1C,CAAC,CAAC;QACH,MAAM,WAAW,GAAG,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QAC5E,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;QAE9E,qDAAqD;QACrD,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACjE,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,aAAa,EAAE,CAAC;QAEvC,uDAAuD;QACvD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,2BAA2B,EAAE,CAAC,CAAC;QAC1E,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC9C,IAAI,EAAmB,CAAC;IACxB,IAAI,MAAqC,CAAC;IAE1C,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;QAC3B,MAAM,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACpE,gCAAgC;QAChC,MAAM,OAAO,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QACrD,MAAM,iBAAiB,GAAG;YACxB,GAAG,MAAM;YACT,MAAM,EAAE;gBACN,QAAQ,EAAE,CAAC,OAAO,CAAC;gBACnB,WAAW,EAAE,CAAC;gBACd,YAAY,EAAE,GAAG;aAClB;SACF,CAAC;QAEF,MAAM,EAAE,CAAC,MAAM,CAAC;YACd,UAAU,EAAE,2BAA2B;YACvC,IAAI,EAAE;gBACJ,EAAE,EAAE,OAAO;gBACX,IAAI,EAAE,kBAAkB;gBACxB,UAAU,EAAE,OAAO;gBACnB,UAAU,EAAE,IAAI;gBAChB,MAAM,EAAE,SAAS;gBACjB,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE;gBAC/D,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACpC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,aAAa,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACxC;SACF,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,MAAM,8BAA8B,CAAC,iBAAwB,EAAE,EAAE,CAAC,CAAC;QAEtF,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3B,MAAM,CAAC,OAAO,CAAC,CAAC,oBAAoB,EAAE,CAAC;QAEvC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,2BAA2B,EAAE,CAAC,CAAC;QAC1E,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACvE,MAAM,OAAO,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;QACrE,MAAM,iBAAiB,GAAG;YACxB,GAAG,MAAM;YACT,MAAM,EAAE;gBACN,QAAQ,EAAE,CAAC,OAAO,CAAC;gBACnB,WAAW,EAAE,CAAC;gBACd,YAAY,EAAE,GAAG;aAClB;SACF,CAAC;QAEF,MAAM,EAAE,CAAC,MAAM,CAAC;YACd,UAAU,EAAE,2BAA2B;YACvC,IAAI,EAAE;gBACJ,EAAE,EAAE,OAAO;gBACX,IAAI,EAAE,kBAAkB;gBACxB,UAAU,EAAE,OAAO;gBACnB,UAAU,EAAE,IAAI;gBAChB,MAAM,EAAE,SAAS;gBACjB,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE;gBAC/D,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACpC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,aAAa,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACxC;SACF,CAAC,CAAC;QAEH,MAAM,8BAA8B,CAAC,iBAAwB,EAAE,EAAE,CAAC,CAAC;QAEnE,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,2BAA2B,EAAE,CAAC,CAAC;QAC1E,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,sCAAsC;QAC3E,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC5E,MAAM,OAAO,GAAG,eAAe,CAAC;QAChC,MAAM,EAAE,CAAC,MAAM,CAAC;YACd,UAAU,EAAE,2BAA2B;YACvC,IAAI,EAAE;gBACJ,EAAE,EAAE,OAAO;gBACX,IAAI,EAAE,kBAAkB;gBACxB,UAAU,EAAE,OAAO;gBACnB,UAAU,EAAE,IAAI;gBAChB,MAAM,EAAE,SAAS;gBACjB,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE;gBAC/D,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACpC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,aAAa,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACxC;SACF,CAAC,CAAC;QAEH,0DAA0D;QAC1D,MAAM,8BAA8B,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAEjD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,2BAA2B,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAC1F,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC9B,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC5E,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QAC/D,MAAM,EAAE,CAAC,MAAM,CAAC;YACd,UAAU,EAAE,2BAA2B;YACvC,IAAI,EAAE;gBACJ,EAAE,EAAE,YAAY;gBAChB,IAAI,EAAE,kBAAkB;gBACxB,UAAU,EAAE,OAAO;gBACnB,UAAU,EAAE,IAAI;gBAChB,MAAM,EAAE,SAAS;gBACjB,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE,EAAE;gBACX,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACpC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,aAAa,EAAE,UAAU;aAC1B;SACF,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,MAAM,8BAA8B,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACpE,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,OAAO,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QACxB,MAAM,eAAe,GAAG,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;QACvF,MAAM,EAAE,CAAC,MAAM,CAAC;YACd,UAAU,EAAE,2BAA2B;YACvC,IAAI,EAAE;gBACJ,EAAE,EAAE,eAAe;gBACnB,IAAI,EAAE,kBAAkB;gBACxB,UAAU,EAAE,OAAO;gBACnB,UAAU,EAAE,IAAI;gBAChB,MAAM,EAAE,QAAQ;gBAChB,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE,EAAE;gBACX,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACrC;SACF,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,8BAA8B,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1E,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}