@open-agent-toolkit/cli 0.1.45 → 0.1.48

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 (112) hide show
  1. package/assets/agents/oat-phase-implementer.md +202 -191
  2. package/assets/agents/oat-reviewer.md +12 -2
  3. package/assets/config/dispatch-matrix-recommendation.json +120 -13
  4. package/assets/docs/cli-utilities/config-and-local-state.md +7 -0
  5. package/assets/docs/cli-utilities/configuration.md +183 -84
  6. package/assets/docs/cli-utilities/workflow-gates.md +161 -27
  7. package/assets/docs/contributing/skills.md +14 -8
  8. package/assets/docs/provider-sync/config.md +5 -1
  9. package/assets/docs/provider-sync/manifest-and-drift.md +6 -1
  10. package/assets/docs/provider-sync/providers.md +42 -5
  11. package/assets/docs/provider-sync/scope-and-surface.md +3 -2
  12. package/assets/docs/reference/cli-reference.md +3 -1
  13. package/assets/docs/reference/oat-directory-structure.md +27 -26
  14. package/assets/docs/workflows/projects/artifacts.md +31 -1
  15. package/assets/docs/workflows/projects/dispatch-ceiling.md +235 -174
  16. package/assets/docs/workflows/projects/implementation-execution.md +283 -253
  17. package/assets/docs/workflows/projects/lifecycle.md +26 -5
  18. package/assets/docs/workflows/projects/reviews.md +27 -2
  19. package/assets/migration/pjm-restructure.md +1 -1
  20. package/assets/public-package-versions.json +4 -4
  21. package/assets/skills/oat-project-implement/SKILL.md +347 -178
  22. package/assets/skills/oat-project-import-plan/SKILL.md +173 -16
  23. package/assets/skills/oat-project-next/SKILL.md +2 -2
  24. package/assets/skills/oat-project-plan/SKILL.md +122 -92
  25. package/assets/skills/oat-project-plan-writing/SKILL.md +246 -15
  26. package/assets/skills/oat-project-quick-start/SKILL.md +156 -94
  27. package/assets/skills/oat-project-review-provide/SKILL.md +94 -22
  28. package/dist/commands/config/index.d.ts +2 -2
  29. package/dist/commands/config/index.d.ts.map +1 -1
  30. package/dist/commands/config/index.js +129 -53
  31. package/dist/commands/doctor/index.d.ts +2 -2
  32. package/dist/commands/doctor/index.d.ts.map +1 -1
  33. package/dist/commands/doctor/index.js +102 -31
  34. package/dist/commands/gate/index.d.ts +7 -1
  35. package/dist/commands/gate/index.d.ts.map +1 -1
  36. package/dist/commands/gate/index.js +544 -67
  37. package/dist/commands/gate/review-verdict.d.ts +16 -0
  38. package/dist/commands/gate/review-verdict.d.ts.map +1 -1
  39. package/dist/commands/gate/review-verdict.js +72 -9
  40. package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
  41. package/dist/commands/project/dispatch-ceiling/index.js +586 -23
  42. package/dist/commands/providers/codex/index.d.ts +4 -0
  43. package/dist/commands/providers/codex/index.d.ts.map +1 -0
  44. package/dist/commands/providers/codex/index.js +7 -0
  45. package/dist/commands/providers/codex/materialize.d.ts +5 -0
  46. package/dist/commands/providers/codex/materialize.d.ts.map +1 -0
  47. package/dist/commands/providers/codex/materialize.js +157 -0
  48. package/dist/commands/providers/index.d.ts +2 -2
  49. package/dist/commands/providers/index.d.ts.map +1 -1
  50. package/dist/commands/providers/index.js +4 -2
  51. package/dist/commands/providers/providers.types.d.ts +23 -0
  52. package/dist/commands/providers/providers.types.d.ts.map +1 -1
  53. package/dist/commands/shared/codex-strays.d.ts.map +1 -1
  54. package/dist/commands/shared/codex-strays.js +11 -1
  55. package/dist/commands/shared/frontmatter.d.ts +4 -0
  56. package/dist/commands/shared/frontmatter.d.ts.map +1 -1
  57. package/dist/commands/shared/frontmatter.js +23 -0
  58. package/dist/commands/status/index.d.ts +5 -1
  59. package/dist/commands/status/index.d.ts.map +1 -1
  60. package/dist/commands/status/index.js +10 -4
  61. package/dist/commands/sync/index.d.ts.map +1 -1
  62. package/dist/commands/sync/index.js +10 -3
  63. package/dist/commands/sync/sync.types.d.ts +5 -1
  64. package/dist/commands/sync/sync.types.d.ts.map +1 -1
  65. package/dist/config/dispatch-ceiling-preset.d.ts +4 -0
  66. package/dist/config/dispatch-ceiling-preset.d.ts.map +1 -1
  67. package/dist/config/dispatch-ceiling-preset.js +3 -0
  68. package/dist/config/dispatch-policy-options.d.ts +20 -0
  69. package/dist/config/dispatch-policy-options.d.ts.map +1 -0
  70. package/dist/config/dispatch-policy-options.js +96 -0
  71. package/dist/config/oat-config.d.ts +25 -2
  72. package/dist/config/oat-config.d.ts.map +1 -1
  73. package/dist/config/oat-config.js +154 -24
  74. package/dist/config/resolve.d.ts +8 -0
  75. package/dist/config/resolve.d.ts.map +1 -1
  76. package/dist/config/resolve.js +66 -2
  77. package/dist/engine/index.d.ts +1 -1
  78. package/dist/engine/index.d.ts.map +1 -1
  79. package/dist/engine/index.js +1 -1
  80. package/dist/engine/scanner.d.ts +1 -0
  81. package/dist/engine/scanner.d.ts.map +1 -1
  82. package/dist/engine/scanner.js +17 -1
  83. package/dist/fs/paths.d.ts +4 -0
  84. package/dist/fs/paths.d.ts.map +1 -1
  85. package/dist/fs/paths.js +18 -1
  86. package/dist/providers/ceiling/registry.d.ts +8 -5
  87. package/dist/providers/ceiling/registry.d.ts.map +1 -1
  88. package/dist/providers/ceiling/registry.js +25 -7
  89. package/dist/providers/codex/codec/catalog.d.ts +14 -0
  90. package/dist/providers/codex/codec/catalog.d.ts.map +1 -0
  91. package/dist/providers/codex/codec/catalog.js +21 -0
  92. package/dist/providers/codex/codec/config-merge.d.ts +6 -0
  93. package/dist/providers/codex/codec/config-merge.d.ts.map +1 -1
  94. package/dist/providers/codex/codec/config-merge.js +7 -0
  95. package/dist/providers/codex/codec/materialize.d.ts +16 -0
  96. package/dist/providers/codex/codec/materialize.d.ts.map +1 -0
  97. package/dist/providers/codex/codec/materialize.js +58 -0
  98. package/dist/providers/codex/codec/shared.d.ts +20 -0
  99. package/dist/providers/codex/codec/shared.d.ts.map +1 -1
  100. package/dist/providers/codex/codec/shared.js +107 -6
  101. package/dist/providers/codex/codec/sync-extension.d.ts +7 -1
  102. package/dist/providers/codex/codec/sync-extension.d.ts.map +1 -1
  103. package/dist/providers/codex/codec/sync-extension.js +299 -52
  104. package/dist/providers/identity/availability.d.ts +24 -1
  105. package/dist/providers/identity/availability.d.ts.map +1 -1
  106. package/dist/providers/identity/availability.js +253 -19
  107. package/dist/providers/identity/stamp.d.ts.map +1 -1
  108. package/dist/providers/identity/stamp.js +4 -0
  109. package/dist/shared/types.d.ts +1 -0
  110. package/dist/shared/types.d.ts.map +1 -1
  111. package/dist/shared/types.js +4 -0
  112. package/package.json +2 -2
@@ -3,6 +3,8 @@ export interface ReviewGateVerdict {
3
3
  reviewType: 'code' | 'artifact' | 'unknown';
4
4
  scope: string | null;
5
5
  invocation: string | null;
6
+ project: string | null;
7
+ gateInvocation?: ReviewArtifactGateInvocation;
6
8
  counts: {
7
9
  critical: number;
8
10
  important: number;
@@ -12,11 +14,25 @@ export interface ReviewGateVerdict {
12
14
  blocking: boolean;
13
15
  normalization?: {
14
16
  insertedSeverities: Severity[];
17
+ persisted: boolean;
15
18
  };
16
19
  }
20
+ export interface ReviewArtifactGateInvocation {
21
+ runId: string | null;
22
+ targetId: string | null;
23
+ runtime: string | null;
24
+ model: string | null;
25
+ reasoningEffort: string | null;
26
+ source: string | null;
27
+ }
17
28
  export type Severity = keyof ReviewGateVerdict['counts'];
29
+ export interface ReviewGateArtifactSnapshot {
30
+ readonly content: string;
31
+ readonly signature: string;
32
+ }
18
33
  export interface ParseReviewGateVerdictOptions {
19
34
  normalizeMissingEmptySeveritySections?: boolean;
35
+ artifactSnapshot?: ReviewGateArtifactSnapshot;
20
36
  }
21
37
  export declare function severityDisplayName(severity: Severity): string;
22
38
  export declare function parseReviewGateVerdict(artifactPath: string, options?: ParseReviewGateVerdictOptions): Promise<ReviewGateVerdict>;
@@ -1 +1 @@
1
- {"version":3,"file":"review-verdict.d.ts","sourceRoot":"","sources":["../../../src/commands/gate/review-verdict.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IAC5C,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE;QACd,kBAAkB,EAAE,QAAQ,EAAE,CAAC;KAChC,CAAC;CACH;AAED,MAAM,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,QAAQ,CAAC,CAAC;AAEzD,MAAM,WAAW,6BAA6B;IAC5C,qCAAqC,CAAC,EAAE,OAAO,CAAC;CACjD;AAqID,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAE9D;AAqRD,wBAAsB,sBAAsB,CAC1C,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,6BAAkC,GAC1C,OAAO,CAAC,iBAAiB,CAAC,CAsD5B"}
1
+ {"version":3,"file":"review-verdict.d.ts","sourceRoot":"","sources":["../../../src/commands/gate/review-verdict.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IAC5C,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,cAAc,CAAC,EAAE,4BAA4B,CAAC;IAC9C,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE;QACd,kBAAkB,EAAE,QAAQ,EAAE,CAAC;QAC/B,SAAS,EAAE,OAAO,CAAC;KACpB,CAAC;CACH;AAED,MAAM,WAAW,4BAA4B;IAC3C,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,QAAQ,CAAC,CAAC;AAEzD,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,6BAA6B;IAC5C,qCAAqC,CAAC,EAAE,OAAO,CAAC;IAChD,gBAAgB,CAAC,EAAE,0BAA0B,CAAC;CAC/C;AA6LD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAE9D;AAgSD,wBAAsB,sBAAsB,CAC1C,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,6BAAkC,GAC1C,OAAO,CAAC,iBAAiB,CAAC,CAiF5B"}
@@ -1,3 +1,4 @@
1
+ import { createHash } from 'node:crypto';
1
2
  import { readFile, writeFile } from 'node:fs/promises';
2
3
  import { getFrontmatterBlock } from '../shared/frontmatter.js';
3
4
  import YAML from 'yaml';
@@ -13,12 +14,50 @@ const FRONTMATTER_COUNT_KEYS = {
13
14
  medium: ['oat_review_medium_count', 'medium'],
14
15
  minor: ['oat_review_minor_count', 'minor'],
15
16
  };
17
+ function artifactContentSignature(content) {
18
+ return createHash('sha256').update(content).digest('hex');
19
+ }
20
+ async function assertArtifactContentCurrent(artifactPath, expectedContent) {
21
+ let currentContent;
22
+ try {
23
+ currentContent = await readFile(artifactPath, 'utf8');
24
+ }
25
+ catch (error) {
26
+ const detail = error instanceof Error ? error.message : String(error);
27
+ throw new Error(`Unable to verify review artifact snapshot at ${artifactPath}: ${detail}`, { cause: error });
28
+ }
29
+ if (artifactContentSignature(currentContent) !==
30
+ artifactContentSignature(expectedContent)) {
31
+ throw new Error(`Review artifact at ${artifactPath} changed after gate correlation; rerun the gate so correlation and verdict evaluation use one immutable snapshot.`);
32
+ }
33
+ }
16
34
  function normalizeReviewType(value) {
17
35
  return value === 'code' || value === 'artifact' ? value : 'unknown';
18
36
  }
19
37
  function stringOrNull(value) {
20
38
  return typeof value === 'string' && value.trim() ? value.trim() : null;
21
39
  }
40
+ function readGateInvocation(frontmatter) {
41
+ const keys = [
42
+ 'oat_gate_run_id',
43
+ 'oat_gate_target',
44
+ 'oat_gate_runtime',
45
+ 'oat_invocation_model',
46
+ 'oat_invocation_reasoning_effort',
47
+ 'oat_invocation_source',
48
+ ];
49
+ if (!keys.some((key) => key in frontmatter)) {
50
+ return undefined;
51
+ }
52
+ return {
53
+ runId: stringOrNull(frontmatter['oat_gate_run_id']),
54
+ targetId: stringOrNull(frontmatter['oat_gate_target']),
55
+ runtime: stringOrNull(frontmatter['oat_gate_runtime']),
56
+ model: stringOrNull(frontmatter['oat_invocation_model']),
57
+ reasoningEffort: stringOrNull(frontmatter['oat_invocation_reasoning_effort']),
58
+ source: stringOrNull(frontmatter['oat_invocation_source']),
59
+ };
60
+ }
22
61
  function parseCountValue(value) {
23
62
  const numberValue = typeof value === 'number'
24
63
  ? value
@@ -244,7 +283,7 @@ function insertMissingSeveritySection(content, severity) {
244
283
  const needsTrailingBlank = suffix.length > 0 ? '\n' : '';
245
284
  return `${content.slice(0, insertionPoint)}${insertion}${needsTrailingBlank}${suffix}`;
246
285
  }
247
- async function normalizeMissingEmptySeveritySections(artifactPath, content, counts) {
286
+ async function normalizeMissingEmptySeveritySections(artifactPath, content, counts, persist) {
248
287
  if (!findFindingsSection(content)) {
249
288
  throw new Error(`Review artifact at ${artifactPath} does not contain a ## Findings section, so missing severity headings cannot be safely normalized.`);
250
289
  }
@@ -257,10 +296,16 @@ async function normalizeMissingEmptySeveritySections(artifactPath, content, coun
257
296
  normalizedContent = insertMissingSeveritySection(normalizedContent, severity);
258
297
  insertedSeverities.push(severity);
259
298
  }
260
- if (insertedSeverities.length > 0) {
299
+ if (insertedSeverities.length > 0 && persist) {
300
+ await assertArtifactContentCurrent(artifactPath, content);
261
301
  await writeFile(artifactPath, normalizedContent, 'utf8');
302
+ await assertArtifactContentCurrent(artifactPath, normalizedContent);
262
303
  }
263
- return { content: normalizedContent, insertedSeverities };
304
+ return {
305
+ content: normalizedContent,
306
+ insertedSeverities,
307
+ persisted: insertedSeverities.length > 0 && persist,
308
+ };
264
309
  }
265
310
  function resolveCounts(content, frontmatter) {
266
311
  const frontmatterCounts = readFrontmatterCounts(frontmatter);
@@ -275,12 +320,21 @@ function resolveCounts(content, frontmatter) {
275
320
  }
276
321
  export async function parseReviewGateVerdict(artifactPath, options = {}) {
277
322
  let content;
278
- try {
279
- content = await readFile(artifactPath, 'utf8');
323
+ if (options.artifactSnapshot) {
324
+ content = options.artifactSnapshot.content;
325
+ if (artifactContentSignature(content) !== options.artifactSnapshot.signature) {
326
+ throw new Error(`Review artifact snapshot signature at ${artifactPath} does not match its content.`);
327
+ }
328
+ await assertArtifactContentCurrent(artifactPath, content);
280
329
  }
281
- catch (error) {
282
- const detail = error instanceof Error ? error.message : String(error);
283
- throw new Error(`Unable to read review artifact at ${artifactPath}: ${detail}`, { cause: error });
330
+ else {
331
+ try {
332
+ content = await readFile(artifactPath, 'utf8');
333
+ }
334
+ catch (error) {
335
+ const detail = error instanceof Error ? error.message : String(error);
336
+ throw new Error(`Unable to read review artifact at ${artifactPath}: ${detail}`, { cause: error });
337
+ }
284
338
  }
285
339
  const frontmatterBlock = getFrontmatterBlock(content);
286
340
  const frontmatter = frontmatterBlock
@@ -288,10 +342,12 @@ export async function parseReviewGateVerdict(artifactPath, options = {}) {
288
342
  : {};
289
343
  let counts = resolveCounts(content, frontmatter);
290
344
  let insertedSeverities = [];
345
+ let normalizationPersisted = false;
291
346
  if (counts && options.normalizeMissingEmptySeveritySections) {
292
- const normalized = await normalizeMissingEmptySeveritySections(artifactPath, content, counts);
347
+ const normalized = await normalizeMissingEmptySeveritySections(artifactPath, content, counts, !options.artifactSnapshot);
293
348
  content = normalized.content;
294
349
  insertedSeverities = normalized.insertedSeverities;
350
+ normalizationPersisted = normalized.persisted;
295
351
  }
296
352
  if (!counts) {
297
353
  counts = parseFindingsSectionCounts(content, artifactPath);
@@ -299,17 +355,24 @@ export async function parseReviewGateVerdict(artifactPath, options = {}) {
299
355
  if (!counts) {
300
356
  throw new Error(`Review artifact at ${artifactPath} does not contain recognizable review findings or explicit verdict counts.`);
301
357
  }
358
+ const gateInvocation = readGateInvocation(frontmatter);
359
+ if (options.artifactSnapshot) {
360
+ await assertArtifactContentCurrent(artifactPath, options.artifactSnapshot.content);
361
+ }
302
362
  return {
303
363
  artifactPath,
304
364
  reviewType: normalizeReviewType(frontmatter['oat_review_type']),
305
365
  scope: stringOrNull(frontmatter['oat_review_scope']),
306
366
  invocation: stringOrNull(frontmatter['oat_review_invocation']),
367
+ project: stringOrNull(frontmatter['oat_project']),
368
+ ...(gateInvocation ? { gateInvocation } : {}),
307
369
  counts,
308
370
  blocking: hasBlockingFindings(counts),
309
371
  ...(insertedSeverities.length > 0
310
372
  ? {
311
373
  normalization: {
312
374
  insertedSeverities,
375
+ persisted: normalizationPersisted,
313
376
  },
314
377
  }
315
378
  : {}),
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/dispatch-ceiling/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAO9B,OAAO,EAML,KAAK,uBAAuB,EAU7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,iBAAiB,CAAC;AAazB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8BpC,UAAU,2BAA2B;IACnC,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,sBAAsB,EAAE,CACtB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,MAAM,CAAC,UAAU,KACnB,OAAO,CAAC,cAAc,CAAC,CAAC;IAC7B,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC7E,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;CAC/B;AAs+CD,wBAAgB,mCAAmC,CACjD,SAAS,GAAE,OAAO,CAAC,2BAA2B,CAAM,GACnD,OAAO,CAyDT"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/dispatch-ceiling/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAY9B,OAAO,EAUL,KAAK,uBAAuB,EAY7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,iBAAiB,CAAC;AAezB,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAiC5C,UAAU,2BAA2B;IACnC,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,sBAAsB,EAAE,CACtB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,MAAM,CAAC,UAAU,KACnB,OAAO,CAAC,cAAc,CAAC,CAAC;IAC7B,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC7E,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;CAC/B;AA+0ED,wBAAgB,mCAAmC,CACjD,SAAS,GAAE,OAAO,CAAC,2BAA2B,CAAM,GACnD,OAAO,CAwFT"}