@ixo/topic-protocol 1.0.0-rc.4 → 1.0.0-rc.6

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 (59) hide show
  1. package/README.md +10 -1
  2. package/dist/profiles/releases/1.0.0-rc.4.json +8915 -0
  3. package/dist/schemas/v2/capsule.schema.json +29 -0
  4. package/dist/schemas/v2/common.schema.json +68 -0
  5. package/dist/schemas/v2/operation.schema.json +308 -0
  6. package/dist/schemas/v2/projection.schema.json +205 -0
  7. package/dist/schemas/v2/record.schema.json +56 -0
  8. package/dist/schemas/v2/topic.schema.json +84 -0
  9. package/dist/src/shapes/availability.d.ts +1 -0
  10. package/dist/src/shapes/availability.js +3 -1
  11. package/dist/src/shapes/availability.js.map +1 -1
  12. package/dist/src/shapes/canonical.js +3 -2
  13. package/dist/src/shapes/canonical.js.map +1 -1
  14. package/dist/src/shapes/commands.js +1 -1
  15. package/dist/src/shapes/commands.js.map +1 -1
  16. package/dist/src/shapes/progress.js +14 -1
  17. package/dist/src/shapes/progress.js.map +1 -1
  18. package/dist/src/shapes/recipes.js +31 -1
  19. package/dist/src/shapes/recipes.js.map +1 -1
  20. package/dist/src/shapes/releases.d.ts +1 -1
  21. package/dist/src/shapes/releases.js +4 -1
  22. package/dist/src/shapes/releases.js.map +1 -1
  23. package/dist/src/shapes/resolver.js +7 -1
  24. package/dist/src/shapes/resolver.js.map +1 -1
  25. package/dist/src/v2/canonical.d.ts +3 -0
  26. package/dist/src/v2/canonical.js +25 -0
  27. package/dist/src/v2/canonical.js.map +1 -0
  28. package/dist/src/v2/capsule.d.ts +10 -0
  29. package/dist/src/v2/capsule.js +46 -0
  30. package/dist/src/v2/capsule.js.map +1 -0
  31. package/dist/src/v2/compat.d.ts +14 -0
  32. package/dist/src/v2/compat.js +96 -0
  33. package/dist/src/v2/compat.js.map +1 -0
  34. package/dist/src/v2/ids.d.ts +3 -0
  35. package/dist/src/v2/ids.js +11 -0
  36. package/dist/src/v2/ids.js.map +1 -0
  37. package/dist/src/v2/index.d.ts +9 -0
  38. package/dist/src/v2/index.js +9 -0
  39. package/dist/src/v2/index.js.map +1 -0
  40. package/dist/src/v2/matrix.d.ts +46 -0
  41. package/dist/src/v2/matrix.js +151 -0
  42. package/dist/src/v2/matrix.js.map +1 -0
  43. package/dist/src/v2/project.d.ts +14 -0
  44. package/dist/src/v2/project.js +268 -0
  45. package/dist/src/v2/project.js.map +1 -0
  46. package/dist/src/v2/types.d.ts +195 -0
  47. package/dist/src/v2/types.js +19 -0
  48. package/dist/src/v2/types.js.map +1 -0
  49. package/dist/src/v2/validate.d.ts +650 -0
  50. package/dist/src/v2/validate.js +45 -0
  51. package/dist/src/v2/validate.js.map +1 -0
  52. package/package.json +7 -1
  53. package/profiles/releases/1.0.0-rc.4.json +8915 -0
  54. package/recipes/agent-delivery.json +85 -1
  55. package/recipes/blueprint-design.json +85 -1
  56. package/recipes/registry.json +10 -10
  57. package/recipes/research-brief.json +85 -1
  58. package/recipes/software-build.json +85 -1
  59. package/recipes/verified-work-payment.json +85 -1
@@ -0,0 +1,650 @@
1
+ export declare const SCHEMAS_V2: Readonly<{
2
+ capsule: {
3
+ $schema: string;
4
+ $id: string;
5
+ title: string;
6
+ description: string;
7
+ type: string;
8
+ required: string[];
9
+ properties: {
10
+ version: {
11
+ const: number;
12
+ };
13
+ topic: {
14
+ $ref: string;
15
+ };
16
+ messages: {
17
+ type: string;
18
+ maxItems: number;
19
+ items: {
20
+ type: string;
21
+ required: string[];
22
+ properties: {
23
+ eventId: {
24
+ $ref: string;
25
+ };
26
+ sender: {
27
+ $ref: string;
28
+ };
29
+ body: {
30
+ type: string;
31
+ };
32
+ at: {
33
+ $ref: string;
34
+ };
35
+ };
36
+ additionalProperties: boolean;
37
+ };
38
+ };
39
+ hint: {
40
+ type: string;
41
+ minLength: number;
42
+ };
43
+ };
44
+ additionalProperties: boolean;
45
+ };
46
+ operation: {
47
+ $schema: string;
48
+ $id: string;
49
+ title: string;
50
+ description: string;
51
+ type: string;
52
+ required: string[];
53
+ properties: {
54
+ version: {
55
+ const: number;
56
+ };
57
+ id: {
58
+ type: string;
59
+ pattern: string;
60
+ description: string;
61
+ };
62
+ topicId: {
63
+ $ref: string;
64
+ };
65
+ type: {
66
+ type: string;
67
+ enum: string[];
68
+ };
69
+ actor: {
70
+ $ref: string;
71
+ };
72
+ createdAt: {
73
+ $ref: string;
74
+ };
75
+ fields: {
76
+ type: string;
77
+ minProperties: number;
78
+ properties: {
79
+ title: {
80
+ $ref: string;
81
+ };
82
+ owner: {
83
+ oneOf: ({
84
+ $ref: string;
85
+ type?: never;
86
+ } | {
87
+ type: string;
88
+ $ref?: never;
89
+ })[];
90
+ };
91
+ due: {
92
+ oneOf: ({
93
+ $ref: string;
94
+ type?: never;
95
+ } | {
96
+ type: string;
97
+ $ref?: never;
98
+ })[];
99
+ };
100
+ intent: {
101
+ oneOf: ({
102
+ $ref: string;
103
+ type?: never;
104
+ } | {
105
+ type: string;
106
+ $ref?: never;
107
+ })[];
108
+ };
109
+ outcome: {
110
+ oneOf: ({
111
+ $ref: string;
112
+ type?: never;
113
+ } | {
114
+ type: string;
115
+ $ref?: never;
116
+ })[];
117
+ };
118
+ };
119
+ additionalProperties: boolean;
120
+ };
121
+ status: {
122
+ $ref: string;
123
+ };
124
+ reason: {
125
+ $ref: string;
126
+ };
127
+ on: {
128
+ type: string;
129
+ minLength: number;
130
+ };
131
+ ref: {
132
+ $ref: string;
133
+ };
134
+ file: {
135
+ $ref: string;
136
+ };
137
+ resource: {
138
+ type: string;
139
+ minLength: number;
140
+ };
141
+ fileId: {
142
+ type: string;
143
+ minLength: number;
144
+ };
145
+ relation: {
146
+ $ref: string;
147
+ };
148
+ targetTopicId: {
149
+ $ref: string;
150
+ };
151
+ flowUri: {
152
+ type: string;
153
+ minLength: number;
154
+ };
155
+ };
156
+ allOf: ({
157
+ if: {
158
+ properties: {
159
+ type: {
160
+ const: string;
161
+ enum?: never;
162
+ };
163
+ };
164
+ required: string[];
165
+ };
166
+ then: {
167
+ properties: {
168
+ fields: boolean;
169
+ status?: never;
170
+ reason?: never;
171
+ ref?: never;
172
+ file?: never;
173
+ resource?: never;
174
+ fileId?: never;
175
+ relation?: never;
176
+ targetTopicId?: never;
177
+ flowUri?: never;
178
+ };
179
+ required: string[];
180
+ };
181
+ } | {
182
+ if: {
183
+ properties: {
184
+ type: {
185
+ const: string;
186
+ enum?: never;
187
+ };
188
+ };
189
+ required: string[];
190
+ };
191
+ then: {
192
+ properties: {
193
+ status: boolean;
194
+ fields?: never;
195
+ reason?: never;
196
+ ref?: never;
197
+ file?: never;
198
+ resource?: never;
199
+ fileId?: never;
200
+ relation?: never;
201
+ targetTopicId?: never;
202
+ flowUri?: never;
203
+ };
204
+ required: string[];
205
+ };
206
+ } | {
207
+ if: {
208
+ properties: {
209
+ type: {
210
+ const: string;
211
+ enum?: never;
212
+ };
213
+ };
214
+ required: string[];
215
+ };
216
+ then: {
217
+ properties: {
218
+ reason: boolean;
219
+ fields?: never;
220
+ status?: never;
221
+ ref?: never;
222
+ file?: never;
223
+ resource?: never;
224
+ fileId?: never;
225
+ relation?: never;
226
+ targetTopicId?: never;
227
+ flowUri?: never;
228
+ };
229
+ required: string[];
230
+ };
231
+ } | {
232
+ if: {
233
+ properties: {
234
+ type: {
235
+ enum: string[];
236
+ const?: never;
237
+ };
238
+ };
239
+ required: string[];
240
+ };
241
+ then: {
242
+ properties: {
243
+ ref: boolean;
244
+ fields?: never;
245
+ status?: never;
246
+ reason?: never;
247
+ file?: never;
248
+ resource?: never;
249
+ fileId?: never;
250
+ relation?: never;
251
+ targetTopicId?: never;
252
+ flowUri?: never;
253
+ };
254
+ required: string[];
255
+ };
256
+ } | {
257
+ if: {
258
+ properties: {
259
+ type: {
260
+ const: string;
261
+ enum?: never;
262
+ };
263
+ };
264
+ required: string[];
265
+ };
266
+ then: {
267
+ properties: {
268
+ file: boolean;
269
+ fields?: never;
270
+ status?: never;
271
+ reason?: never;
272
+ ref?: never;
273
+ resource?: never;
274
+ fileId?: never;
275
+ relation?: never;
276
+ targetTopicId?: never;
277
+ flowUri?: never;
278
+ };
279
+ required: string[];
280
+ };
281
+ } | {
282
+ if: {
283
+ properties: {
284
+ type: {
285
+ const: string;
286
+ enum?: never;
287
+ };
288
+ };
289
+ required: string[];
290
+ };
291
+ then: {
292
+ properties: {
293
+ resource: boolean;
294
+ fileId: boolean;
295
+ fields?: never;
296
+ status?: never;
297
+ reason?: never;
298
+ ref?: never;
299
+ file?: never;
300
+ relation?: never;
301
+ targetTopicId?: never;
302
+ flowUri?: never;
303
+ };
304
+ required: string[];
305
+ };
306
+ } | {
307
+ if: {
308
+ properties: {
309
+ type: {
310
+ enum: string[];
311
+ const?: never;
312
+ };
313
+ };
314
+ required: string[];
315
+ };
316
+ then: {
317
+ properties: {
318
+ relation: boolean;
319
+ targetTopicId: boolean;
320
+ fields?: never;
321
+ status?: never;
322
+ reason?: never;
323
+ ref?: never;
324
+ file?: never;
325
+ resource?: never;
326
+ fileId?: never;
327
+ flowUri?: never;
328
+ };
329
+ required: string[];
330
+ };
331
+ } | {
332
+ if: {
333
+ properties: {
334
+ type: {
335
+ const: string;
336
+ enum?: never;
337
+ };
338
+ };
339
+ required: string[];
340
+ };
341
+ then: {
342
+ properties: {
343
+ flowUri: boolean;
344
+ fields?: never;
345
+ status?: never;
346
+ reason?: never;
347
+ ref?: never;
348
+ file?: never;
349
+ resource?: never;
350
+ fileId?: never;
351
+ relation?: never;
352
+ targetTopicId?: never;
353
+ };
354
+ required: string[];
355
+ };
356
+ })[];
357
+ additionalProperties: boolean;
358
+ };
359
+ projection: {
360
+ $schema: string;
361
+ $id: string;
362
+ title: string;
363
+ description: string;
364
+ type: string;
365
+ required: string[];
366
+ properties: {
367
+ version: {
368
+ const: number;
369
+ };
370
+ id: {
371
+ $ref: string;
372
+ };
373
+ anchor: {
374
+ $ref: string;
375
+ };
376
+ title: {
377
+ $ref: string;
378
+ };
379
+ kind: {
380
+ $ref: string;
381
+ };
382
+ baseKind: {
383
+ $ref: string;
384
+ };
385
+ status: {
386
+ $ref: string;
387
+ };
388
+ owner: {
389
+ $ref: string;
390
+ };
391
+ due: {
392
+ $ref: string;
393
+ };
394
+ intent: {
395
+ $ref: string;
396
+ };
397
+ outcome: {
398
+ $ref: string;
399
+ };
400
+ blocked: {
401
+ $ref: string;
402
+ };
403
+ createdBy: {
404
+ $ref: string;
405
+ };
406
+ createdAt: {
407
+ $ref: string;
408
+ };
409
+ updatedBy: {
410
+ $ref: string;
411
+ };
412
+ updatedAt: {
413
+ $ref: string;
414
+ };
415
+ links: {
416
+ type: string;
417
+ items: {
418
+ $ref: string;
419
+ };
420
+ };
421
+ files: {
422
+ type: string;
423
+ items: {
424
+ $ref: string;
425
+ };
426
+ };
427
+ relations: {
428
+ type: string;
429
+ items: {
430
+ type: string;
431
+ required: string[];
432
+ properties: {
433
+ relation: {
434
+ $ref: string;
435
+ };
436
+ topicId: {
437
+ $ref: string;
438
+ };
439
+ by: {
440
+ $ref: string;
441
+ };
442
+ at: {
443
+ $ref: string;
444
+ };
445
+ };
446
+ additionalProperties: boolean;
447
+ };
448
+ };
449
+ flow: {
450
+ type: string;
451
+ required: string[];
452
+ properties: {
453
+ flowUri: {
454
+ type: string;
455
+ minLength: number;
456
+ };
457
+ by: {
458
+ $ref: string;
459
+ };
460
+ at: {
461
+ $ref: string;
462
+ };
463
+ };
464
+ additionalProperties: boolean;
465
+ };
466
+ records: {
467
+ type: string;
468
+ required: string[];
469
+ properties: {
470
+ decisions: {
471
+ type: string;
472
+ items: {
473
+ $ref: string;
474
+ };
475
+ };
476
+ outcomes: {
477
+ type: string;
478
+ items: {
479
+ $ref: string;
480
+ };
481
+ };
482
+ artifacts: {
483
+ type: string;
484
+ items: {
485
+ $ref: string;
486
+ };
487
+ };
488
+ receipts: {
489
+ type: string;
490
+ items: {
491
+ $ref: string;
492
+ };
493
+ };
494
+ };
495
+ additionalProperties: boolean;
496
+ };
497
+ etag: {
498
+ type: string;
499
+ pattern: string;
500
+ description: string;
501
+ };
502
+ rejected: {
503
+ type: string;
504
+ items: {
505
+ type: string;
506
+ required: string[];
507
+ properties: {
508
+ id: {
509
+ type: string;
510
+ minLength: number;
511
+ };
512
+ reason: {
513
+ type: string;
514
+ enum: string[];
515
+ };
516
+ };
517
+ additionalProperties: boolean;
518
+ };
519
+ };
520
+ };
521
+ additionalProperties: boolean;
522
+ };
523
+ record: {
524
+ $schema: string;
525
+ $id: string;
526
+ title: string;
527
+ description: string;
528
+ type: string;
529
+ required: string[];
530
+ properties: {
531
+ version: {
532
+ const: number;
533
+ };
534
+ id: {
535
+ type: string;
536
+ pattern: string;
537
+ description: string;
538
+ };
539
+ topicId: {
540
+ $ref: string;
541
+ };
542
+ type: {
543
+ $ref: string;
544
+ };
545
+ text: {
546
+ $ref: string;
547
+ };
548
+ author: {
549
+ $ref: string;
550
+ };
551
+ createdAt: {
552
+ $ref: string;
553
+ };
554
+ refs: {
555
+ type: string;
556
+ items: {
557
+ $ref: string;
558
+ };
559
+ maxItems: number;
560
+ };
561
+ data: {
562
+ type: string;
563
+ };
564
+ supersedes: {
565
+ type: string;
566
+ pattern: string;
567
+ };
568
+ };
569
+ additionalProperties: boolean;
570
+ };
571
+ topic: {
572
+ $schema: string;
573
+ $id: string;
574
+ title: string;
575
+ description: string;
576
+ type: string;
577
+ required: string[];
578
+ properties: {
579
+ version: {
580
+ const: number;
581
+ };
582
+ id: {
583
+ $ref: string;
584
+ };
585
+ title: {
586
+ $ref: string;
587
+ };
588
+ kind: {
589
+ $ref: string;
590
+ };
591
+ baseKind: {
592
+ $ref: string;
593
+ };
594
+ createdBy: {
595
+ $ref: string;
596
+ };
597
+ createdAt: {
598
+ $ref: string;
599
+ };
600
+ owner: {
601
+ $ref: string;
602
+ };
603
+ due: {
604
+ $ref: string;
605
+ };
606
+ intent: {
607
+ $ref: string;
608
+ };
609
+ outcome: {
610
+ $ref: string;
611
+ };
612
+ };
613
+ if: {
614
+ properties: {
615
+ kind: {
616
+ enum: string[];
617
+ };
618
+ };
619
+ required: string[];
620
+ };
621
+ then: {
622
+ not: {
623
+ properties: {
624
+ baseKind: boolean;
625
+ };
626
+ required: string[];
627
+ };
628
+ };
629
+ else: {
630
+ properties: {
631
+ baseKind: boolean;
632
+ };
633
+ required: string[];
634
+ };
635
+ additionalProperties: boolean;
636
+ };
637
+ }>;
638
+ export type SchemaNameV2 = keyof typeof SCHEMAS_V2;
639
+ export interface ValidationIssueV2 {
640
+ readonly path: string;
641
+ readonly message: string;
642
+ }
643
+ export type ValidationResultV2 = {
644
+ readonly ok: true;
645
+ } | {
646
+ readonly ok: false;
647
+ readonly issues: readonly ValidationIssueV2[];
648
+ };
649
+ export declare function validateV2(name: SchemaNameV2, value: unknown): ValidationResultV2;
650
+ export declare function assertV2(name: SchemaNameV2, value: unknown): void;
@@ -0,0 +1,45 @@
1
+ import { Ajv2020 } from "ajv/dist/2020.js";
2
+ import * as formatsModule from "ajv-formats";
3
+ import capsule from "../../schemas/v2/capsule.schema.json" with { type: "json" };
4
+ import common from "../../schemas/v2/common.schema.json" with { type: "json" };
5
+ import operation from "../../schemas/v2/operation.schema.json" with { type: "json" };
6
+ import projection from "../../schemas/v2/projection.schema.json" with { type: "json" };
7
+ import record from "../../schemas/v2/record.schema.json" with { type: "json" };
8
+ import topic from "../../schemas/v2/topic.schema.json" with { type: "json" };
9
+ import { TopicProtocolError } from "../errors.js";
10
+ export const SCHEMAS_V2 = Object.freeze({
11
+ capsule,
12
+ operation,
13
+ projection,
14
+ record,
15
+ topic,
16
+ });
17
+ const ajv = new Ajv2020({ allErrors: true, strict: true, schemas: [common, record, projection] });
18
+ formatsModule.default(ajv);
19
+ const compiled = new Map();
20
+ function validatorFor(name) {
21
+ const existing = compiled.get(name);
22
+ if (existing !== undefined)
23
+ return existing;
24
+ const schema = SCHEMAS_V2[name];
25
+ const validator = ajv.getSchema(schema.$id) ?? ajv.compile(schema);
26
+ compiled.set(name, validator);
27
+ return validator;
28
+ }
29
+ export function validateV2(name, value) {
30
+ const validator = validatorFor(name);
31
+ if (validator(value))
32
+ return { ok: true };
33
+ const issues = (validator.errors ?? []).map((error) => ({
34
+ path: error.instancePath.length === 0 ? "/" : error.instancePath,
35
+ message: error.message ?? "is invalid",
36
+ }));
37
+ return { ok: false, issues };
38
+ }
39
+ export function assertV2(name, value) {
40
+ const result = validateV2(name, value);
41
+ if (result.ok)
42
+ return;
43
+ throw new TopicProtocolError("CONTRACT_VALIDATION_FAILED", `Protocol 2.0 ${name} failed validation`, { schema: name, issues: result.issues });
44
+ }
45
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/v2/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAyB,MAAM,kBAAkB,CAAC;AAClE,OAAO,KAAK,aAAa,MAAM,aAAa,CAAC;AAG7C,OAAO,OAAO,MAAM,sCAAsC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACjF,OAAO,MAAM,MAAM,qCAAqC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC/E,OAAO,SAAS,MAAM,wCAAwC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACrF,OAAO,UAAU,MAAM,yCAAyC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACvF,OAAO,MAAM,MAAM,qCAAqC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC/E,OAAO,KAAK,MAAM,oCAAoC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;IACtC,OAAO;IACP,SAAS;IACT,UAAU;IACV,MAAM;IACN,KAAK;CACN,CAAC,CAAC;AAaH,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC;AACjG,aAAa,CAAC,OAAoC,CAAC,GAAG,CAAC,CAAC;AACzD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkC,CAAC;AAE3D,SAAS,YAAY,CAAC,IAAkB;IACtC,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IAC5C,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAChC,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACnE,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC9B,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAkB,EAAE,KAAc;IAC3D,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,SAAS,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IAC1C,MAAM,MAAM,GAAG,CAAC,SAAS,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACtD,IAAI,EAAE,KAAK,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY;QAChE,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,YAAY;KACvC,CAAC,CAAC,CAAC;IACJ,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAkB,EAAE,KAAc;IACzD,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACvC,IAAI,MAAM,CAAC,EAAE;QAAE,OAAO;IACtB,MAAM,IAAI,kBAAkB,CAC1B,4BAA4B,EAC5B,gBAAgB,IAAI,oBAAoB,EACxC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CACxC,CAAC;AACJ,CAAC"}