@primust/verifier 1.0.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 (46) hide show
  1. package/LICENSE +93 -0
  2. package/dist/bounded-trace.d.ts +46 -0
  3. package/dist/bounded-trace.d.ts.map +1 -0
  4. package/dist/bounded-trace.js +558 -0
  5. package/dist/bounded-trace.js.map +1 -0
  6. package/dist/cli.d.ts +18 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +391 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/index.d.ts +13 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +13 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/key-cache.d.ts +20 -0
  15. package/dist/key-cache.d.ts.map +1 -0
  16. package/dist/key-cache.js +68 -0
  17. package/dist/key-cache.js.map +1 -0
  18. package/dist/scoped.d.ts +35 -0
  19. package/dist/scoped.d.ts.map +1 -0
  20. package/dist/scoped.js +582 -0
  21. package/dist/scoped.js.map +1 -0
  22. package/dist/types.d.ts +60 -0
  23. package/dist/types.d.ts.map +1 -0
  24. package/dist/types.js +5 -0
  25. package/dist/types.js.map +1 -0
  26. package/dist/upstream_resolver.d.ts +60 -0
  27. package/dist/upstream_resolver.d.ts.map +1 -0
  28. package/dist/upstream_resolver.js +126 -0
  29. package/dist/upstream_resolver.js.map +1 -0
  30. package/dist/v29-envelope.d.ts +55 -0
  31. package/dist/v29-envelope.d.ts.map +1 -0
  32. package/dist/v29-envelope.js +450 -0
  33. package/dist/v29-envelope.js.map +1 -0
  34. package/dist/verifier.d.ts +36 -0
  35. package/dist/verifier.d.ts.map +1 -0
  36. package/dist/verifier.js +1235 -0
  37. package/dist/verifier.js.map +1 -0
  38. package/dist/verifier.test.d.ts +2 -0
  39. package/dist/verifier.test.d.ts.map +1 -0
  40. package/dist/verifier.test.js +395 -0
  41. package/dist/verifier.test.js.map +1 -0
  42. package/dist/verify-html-template.d.ts +45 -0
  43. package/dist/verify-html-template.d.ts.map +1 -0
  44. package/dist/verify-html-template.js +182 -0
  45. package/dist/verify-html-template.js.map +1 -0
  46. package/package.json +52 -0
package/dist/cli.js ADDED
@@ -0,0 +1,391 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * primust-verify CLI
4
+ *
5
+ * Usage:
6
+ * primust-verify vpec_<id>.json
7
+ * primust-verify vpec_<id>.json --production
8
+ * primust-verify vpec_<id>.json --trust-root ./my-pubkey.pem
9
+ * primust-verify vpec_<id>.json --skip-network
10
+ * primust-verify vpec_<id>.json --json
11
+ *
12
+ * Exit codes:
13
+ * 0 = valid (production)
14
+ * 1 = invalid / tampered
15
+ * 2 = valid but sandbox-only (or system error)
16
+ */
17
+ import { readFileSync } from 'node:fs';
18
+ import { parseArgs } from 'node:util';
19
+ import { verify } from './verifier.js';
20
+ import { createUpstreamRootResolver } from './upstream_resolver.js';
21
+ const PROOF_LEVEL_DISPLAY = {
22
+ mathematical: 'mathematical',
23
+ verifiable_inference: 'verifiable_inference',
24
+ operator_bound: 'operator_bound',
25
+ execution: 'execution',
26
+ witnessed: 'witnessed',
27
+ attestation: 'attestation',
28
+ };
29
+ function formatProofLevel(level) {
30
+ return PROOF_LEVEL_DISPLAY[level] ?? level;
31
+ }
32
+ function formatDistribution(dist) {
33
+ const levels = ['mathematical', 'verifiable_inference', 'operator_bound', 'execution', 'witnessed', 'attestation'];
34
+ return levels
35
+ .filter((l) => typeof dist[l] === 'number' && dist[l] > 0)
36
+ .map((l) => `${formatProofLevel(l)}: ${dist[l]}`)
37
+ .join(' ');
38
+ }
39
+ function formatGapsSummary(gaps) {
40
+ if (gaps.length === 0)
41
+ return '0';
42
+ const counts = {};
43
+ for (const g of gaps) {
44
+ counts[g.severity] = (counts[g.severity] ?? 0) + 1;
45
+ }
46
+ const parts = Object.entries(counts).map(([sev, n]) => `${n} ${sev}`);
47
+ return `${gaps.length} (${parts.join(', ')})`;
48
+ }
49
+ function formatTimestamp(result) {
50
+ let ts = result.signed_at;
51
+ if (result.timestamp_anchor_valid === true) {
52
+ ts += ' (RFC 3161 \u2713)';
53
+ }
54
+ return ts;
55
+ }
56
+ /* ── V23-2: --format human — relying-party readable certificate ── */
57
+ function formatHumanCertificate(artifact, result) {
58
+ const sig = result.valid ? 'VALID \u2713' : 'INVALID \u2717';
59
+ const env = artifact.environment === 'sandbox'
60
+ ? 'SANDBOX \u2014 not audit-acceptable'
61
+ : 'PRODUCTION';
62
+ const lines = [];
63
+ lines.push(`GOVERNANCE CREDENTIAL${' '.repeat(28)}${sig}`);
64
+ lines.push('\u2500'.repeat(56));
65
+ lines.push('');
66
+ lines.push(`Credential ID: ${result.vpec_id}`);
67
+ lines.push(`System: ${result.workflow_id}`);
68
+ lines.push(`Environment: ${env}`);
69
+ const started = artifact.started_at ?? '';
70
+ const closed = artifact.closed_at ?? '';
71
+ if (started || closed) {
72
+ lines.push(`Run: ${started} \u2192 ${closed}`);
73
+ }
74
+ lines.push('');
75
+ lines.push('SIGNATURE');
76
+ lines.push(` Status: ${sig}`);
77
+ lines.push(` Signed by: Primust, Inc.`);
78
+ lines.push(` Timestamp: ${result.timestamp_anchor_valid ? 'DigiCert RFC 3161' : 'unsigned'}`);
79
+ lines.push(` Issued: ${result.signed_at}`);
80
+ lines.push('');
81
+ lines.push('GOVERNANCE PROOF');
82
+ const ps = artifact.provable_surface;
83
+ lines.push(` Provable surface: ${ps != null ? `${(ps * 100).toFixed(1)}%` : '\u2014'}`);
84
+ const records = artifact.records ?? [];
85
+ lines.push(` Checks run: ${records.length}`);
86
+ lines.push(` Open gaps: ${result.gaps.length}`);
87
+ // Action coverage (v23)
88
+ const ac = artifact.action_coverage;
89
+ if (ac) {
90
+ lines.push('');
91
+ lines.push('ACTION COVERAGE');
92
+ const total = ac.total_actions;
93
+ const gov = ac.governed_actions;
94
+ const ungov = ac.ungoverned_actions;
95
+ const cov = ac.coverage_pct ?? 0;
96
+ lines.push(` Actions taken: ${total}`);
97
+ lines.push(` Governed: ${gov} (${(cov * 100).toFixed(1)}%)`);
98
+ lines.push(` Ungoverned: ${ungov} (${((1 - cov) * 100).toFixed(1)}%)`);
99
+ // Rich mode — per-action detail
100
+ const ungovList = ac.ungoverned;
101
+ if (ungovList && ungovList.length > 0) {
102
+ lines.push('');
103
+ const cu = ac.consequential_ungoverned ?? {};
104
+ const cuIndices = cu.sequence_indices ?? [];
105
+ for (const u of ungovList) {
106
+ const idx = u.sequence_index ?? '?';
107
+ const atype = u.action_type ?? 'unknown';
108
+ const tname = u.tool_name;
109
+ let label = ` #${idx} ${atype}`;
110
+ if (tname)
111
+ label += `: ${tname}`;
112
+ label += cuIndices.includes(idx)
113
+ ? ' \u26A0 consequential \u2014 no check ran'
114
+ : ' \u2014 no check ran';
115
+ lines.push(label);
116
+ }
117
+ }
118
+ // Strict mode — indices only
119
+ const ungovIndices = ac.ungoverned_sequence_indices;
120
+ if (ungovIndices && ungovIndices.length > 0 && !ungovList) {
121
+ lines.push('');
122
+ lines.push(` Ungoverned at indices: ${JSON.stringify(ungovIndices)}`);
123
+ const cuCount = ac.consequential_ungoverned_count;
124
+ if (cuCount)
125
+ lines.push(` ${cuCount} consequential`);
126
+ lines.push('');
127
+ lines.push(' Per-action detail available via:');
128
+ lines.push(' primust verify-activity vpec.json activity_export.json');
129
+ }
130
+ }
131
+ // Check summaries with evidence_metadata (rich mode)
132
+ const metadataMode = artifact.metadata_mode;
133
+ if (records.length > 0 && metadataMode === 'rich') {
134
+ lines.push('');
135
+ lines.push('GOVERNANCE CHECKS');
136
+ const shown = records.slice(0, 10);
137
+ for (const r of shown) {
138
+ let checkId = r.manifest_id ?? r.check_id ?? 'unknown';
139
+ if (checkId.includes('@'))
140
+ checkId = checkId.split('@')[0];
141
+ const checkResult = r.check_result ?? 'unknown';
142
+ const em = r.evidence_metadata;
143
+ let line = ` ${checkId}: ${checkResult}`;
144
+ if (em) {
145
+ const details = [];
146
+ if ('entity_count' in em)
147
+ details.push(`${em.entity_count} entities`);
148
+ if ('risk_score' in em)
149
+ details.push(`risk ${em.risk_score}`);
150
+ if ('action_taken' in em)
151
+ details.push(em.action_taken);
152
+ if (details.length > 0)
153
+ line += ` (${details.join(', ')})`;
154
+ }
155
+ lines.push(line);
156
+ }
157
+ if (records.length > 10) {
158
+ lines.push(` ... and ${records.length - 10} more checks`);
159
+ }
160
+ }
161
+ lines.push('');
162
+ lines.push('WHAT THIS PROVES');
163
+ lines.push(' Governance checks ran on the actions listed in this credential');
164
+ lines.push(' at the stated proof levels. This credential was issued at the');
165
+ lines.push(' time of the governed run and has not been altered since.');
166
+ lines.push('');
167
+ lines.push('WHAT THIS DOES NOT PROVE');
168
+ lines.push(' That the checks run constitute sufficient evidence for any');
169
+ lines.push(' specific regulatory requirement. That determination belongs');
170
+ lines.push(' to the customer, their compliance function, and their auditors.');
171
+ lines.push('');
172
+ lines.push('VERIFY INDEPENDENTLY');
173
+ lines.push(` verify.primust.com/${result.vpec_id}`);
174
+ lines.push(` primust verify ${result.vpec_id}.json`);
175
+ lines.push('\u2500'.repeat(56));
176
+ return lines.join('\n');
177
+ }
178
+ function printHumanResult(result) {
179
+ const dist = result.proof_distribution;
180
+ const cov = result.coverage;
181
+ if (result.valid) {
182
+ console.log(`\n \u2713 VPEC ${result.vpec_id} \u2014 VALID`);
183
+ }
184
+ else {
185
+ console.log(`\n \u2717 VPEC ${result.vpec_id} \u2014 INVALID`);
186
+ for (const err of result.errors) {
187
+ console.log(` Error: ${err}`);
188
+ }
189
+ }
190
+ const distStr = formatDistribution(dist);
191
+ if (distStr) {
192
+ console.log(` Distribution: ${distStr}`);
193
+ }
194
+ console.log(` Workflow: ${result.workflow_id}`);
195
+ console.log(` Org: ${result.org_id}`);
196
+ console.log(` Signed: ${formatTimestamp(result)}`);
197
+ console.log(` Signer: ${result.signer_id} / kid: ${result.kid}`);
198
+ console.log(` Rekor: ${result.rekor_status}`);
199
+ if (cov && typeof cov.policy_coverage_pct === 'number') {
200
+ let covStr = `${cov.policy_coverage_pct}% policy`;
201
+ if (typeof cov.instrumentation_surface_pct === 'number') {
202
+ covStr += ` | ${cov.instrumentation_surface_pct}% instrumentation surface`;
203
+ }
204
+ console.log(` Coverage: ${covStr}`);
205
+ }
206
+ console.log(` Gaps: ${formatGapsSummary(result.gaps)}`);
207
+ if (result.process_context_hash) {
208
+ console.log(` Process hash: ${result.process_context_hash}`);
209
+ }
210
+ console.log(` Test mode: ${result.test_mode}`);
211
+ if (result.test_mode && result.valid) {
212
+ console.log(` \u26A0 TEST CREDENTIAL \u2014 not for production use`);
213
+ }
214
+ if (result.warnings.length > 0) {
215
+ for (const w of result.warnings) {
216
+ console.log(` Warning: ${w}`);
217
+ }
218
+ }
219
+ console.log('');
220
+ }
221
+ export async function main(args) {
222
+ let parsed;
223
+ try {
224
+ parsed = parseArgs({
225
+ args: args ?? process.argv.slice(2),
226
+ options: {
227
+ production: { type: 'boolean', default: false },
228
+ 'skip-network': { type: 'boolean', default: false },
229
+ 'trust-root': { type: 'string' },
230
+ json: { type: 'boolean', default: false },
231
+ format: { type: 'string' },
232
+ human: { type: 'boolean', default: false },
233
+ help: { type: 'boolean', short: 'h', default: false },
234
+ // Follow-6 #79: parent-root upstream-VPEC anchor check. When the
235
+ // local SqliteStore (or an envelope file) contains the parent
236
+ // VPEC's commitment_root, the verifier upgrades the legacy
237
+ // "unanchored" warning to a cryptographic equality check.
238
+ 'upstream-db': { type: 'string' },
239
+ 'upstream-envelope': { type: 'string', multiple: true },
240
+ },
241
+ allowPositionals: true,
242
+ });
243
+ }
244
+ catch (err) {
245
+ console.error(`Error: ${err.message}`);
246
+ return 2;
247
+ }
248
+ if (parsed.values.help || parsed.positionals.length === 0) {
249
+ console.log('Usage: primust-verify [format] <artifact.json> [options]');
250
+ console.log('');
251
+ console.log('Formats: vpec, pack, w3c-vc, dsse, scitt, receipt, all');
252
+ console.log('If format omitted, auto-detects from file contents.');
253
+ console.log('');
254
+ console.log('Options:');
255
+ console.log(' --production Require production environment');
256
+ console.log(' --skip-network Skip online checks');
257
+ console.log(' --trust-root Custom public key path');
258
+ console.log(' --json Output as JSON');
259
+ console.log(' --format human Human-readable certificate for non-technical relying parties');
260
+ console.log(' --human Shorthand for --format human');
261
+ console.log(' --upstream-db <path> SqliteStore with cached parent VPEC roots');
262
+ console.log(' (defaults to PRIMUST_RUNTIME_DB_PATH or');
263
+ console.log(' ~/.primust/runtime.db when present).');
264
+ console.log(' --upstream-envelope <path> JSON envelope file mapping');
265
+ console.log(' upstream_vpec_id → commitment_root_poseidon2');
266
+ console.log(' (repeatable; merged with --upstream-db).');
267
+ return parsed.values.help ? 0 : 2;
268
+ }
269
+ // Support subcommand: primust verify vpec artifact.json
270
+ const FORMATS = new Set(['vpec', 'pack', 'w3c-vc', 'dsse', 'scitt', 'receipt', 'all']);
271
+ let format = null;
272
+ let filePath;
273
+ if (parsed.positionals.length >= 2 && FORMATS.has(parsed.positionals[0])) {
274
+ format = parsed.positionals[0];
275
+ filePath = parsed.positionals[1];
276
+ }
277
+ else {
278
+ filePath = parsed.positionals[0];
279
+ }
280
+ const jsonOutput = parsed.values.json ?? false;
281
+ const humanCert = parsed.values.human || parsed.values.format === 'human';
282
+ // Read artifact file
283
+ let rawJson;
284
+ try {
285
+ rawJson = readFileSync(filePath, 'utf-8');
286
+ }
287
+ catch {
288
+ const msg = `Error: file not found: ${filePath}`;
289
+ if (jsonOutput) {
290
+ console.error(msg);
291
+ }
292
+ else {
293
+ console.error(msg);
294
+ }
295
+ return 2;
296
+ }
297
+ let artifact;
298
+ try {
299
+ artifact = JSON.parse(rawJson);
300
+ }
301
+ catch {
302
+ const msg = `Error: invalid JSON in ${filePath}`;
303
+ if (jsonOutput) {
304
+ console.error(msg);
305
+ }
306
+ else {
307
+ console.error(msg);
308
+ }
309
+ return 2;
310
+ }
311
+ // ── Follow-6 #79: build upstream-root resolver ──
312
+ // The CLI wires the parent-VPEC anchor check whenever the caller
313
+ // passes --upstream-db (or --upstream-envelope). When neither flag
314
+ // is supplied we leave the resolver undefined so legacy callers
315
+ // keep the existing "unanchored" warning behavior — strict backward
316
+ // compat for tests / scripts that don't know about the flag.
317
+ let resolver;
318
+ const dbPath = parsed.values['upstream-db'];
319
+ const envelopePaths = parsed.values['upstream-envelope'] ?? [];
320
+ if (dbPath || envelopePaths.length > 0) {
321
+ const envelopes = new Map();
322
+ for (const ep of envelopePaths) {
323
+ try {
324
+ const env = JSON.parse(readFileSync(ep, 'utf-8'));
325
+ // Two accepted shapes:
326
+ // - { vpec_id: 'vpec_xxx', commitment_root_poseidon2: 'poseidon2:…' }
327
+ // - { '<vpec_id>': '<root>', ... } (flat map)
328
+ if (typeof env.vpec_id === 'string' && typeof env.commitment_root_poseidon2 === 'string') {
329
+ envelopes.set(env.vpec_id, env.commitment_root_poseidon2);
330
+ }
331
+ else {
332
+ for (const [k, v] of Object.entries(env)) {
333
+ if (typeof v === 'string')
334
+ envelopes.set(k, v);
335
+ }
336
+ }
337
+ }
338
+ catch (err) {
339
+ const msg = `Error: cannot read upstream envelope ${ep}: ${err.message}`;
340
+ console.error(msg);
341
+ return 2;
342
+ }
343
+ }
344
+ resolver = createUpstreamRootResolver({
345
+ dbPath,
346
+ envelopes: envelopes.size > 0 ? envelopes : undefined,
347
+ });
348
+ }
349
+ // Run verification
350
+ let result;
351
+ try {
352
+ result = await verify(artifact, {
353
+ production: parsed.values.production,
354
+ skip_network: parsed.values['skip-network'],
355
+ trust_root: parsed.values['trust-root'],
356
+ }, resolver);
357
+ }
358
+ catch (err) {
359
+ const msg = `Error: verification failed: ${err.message}`;
360
+ if (jsonOutput) {
361
+ console.error(msg);
362
+ }
363
+ else {
364
+ console.error(msg);
365
+ }
366
+ return 2;
367
+ }
368
+ // Output
369
+ if (jsonOutput) {
370
+ console.log(JSON.stringify(result, null, 2));
371
+ }
372
+ else if (humanCert) {
373
+ console.log(formatHumanCertificate(artifact, result));
374
+ }
375
+ else {
376
+ printHumanResult(result);
377
+ }
378
+ if (result.valid && artifact.environment === 'sandbox') {
379
+ console.log('\nSANDBOX — not audit-acceptable.');
380
+ console.log('Change key to pk_live_xxx for production.\n');
381
+ return 2;
382
+ }
383
+ return result.valid ? 0 : 1;
384
+ }
385
+ // Run if invoked directly
386
+ const isDirectRun = process.argv[1] && (process.argv[1].endsWith('/cli.js') ||
387
+ process.argv[1].endsWith('/cli.ts'));
388
+ if (isDirectRun) {
389
+ main().then((code) => process.exit(code));
390
+ }
391
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAEpE,MAAM,mBAAmB,GAA2B;IAClD,YAAY,EAAE,cAAc;IAC5B,oBAAoB,EAAE,sBAAsB;IAC5C,cAAc,EAAE,gBAAgB;IAChC,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,WAAW;IACtB,WAAW,EAAE,aAAa;CAC3B,CAAC;AAEF,SAAS,gBAAgB,CAAC,KAAa;IACrC,OAAO,mBAAmB,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC;AAC7C,CAAC;AAED,SAAS,kBAAkB,CAAC,IAA6B;IACvD,MAAM,MAAM,GAAG,CAAC,cAAc,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;IACnH,OAAO,MAAM;SACV,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAK,IAAI,CAAC,CAAC,CAAY,GAAG,CAAC,CAAC;SACrE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;SAChD,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAiC;IAC1D,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IAClC,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACrD,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;IACtE,OAAO,GAAG,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;AAChD,CAAC;AAED,SAAS,eAAe,CAAC,MAA0B;IACjD,IAAI,EAAE,GAAG,MAAM,CAAC,SAAS,CAAC;IAC1B,IAAI,MAAM,CAAC,sBAAsB,KAAK,IAAI,EAAE,CAAC;QAC3C,EAAE,IAAI,oBAAoB,CAAC;IAC7B,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,sEAAsE;AAEtE,SAAS,sBAAsB,CAAC,QAAiC,EAAE,MAA0B;IAC3F,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,gBAAgB,CAAC;IAC7D,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,KAAK,SAAS;QAC5C,CAAC,CAAC,qCAAqC;QACvC,CAAC,CAAC,YAAY,CAAC;IAEjB,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,wBAAwB,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC;IAC3D,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAChC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,qBAAqB,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAClD,KAAK,CAAC,IAAI,CAAC,qBAAqB,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;IACtD,KAAK,CAAC,IAAI,CAAC,qBAAqB,GAAG,EAAE,CAAC,CAAC;IAEvC,MAAM,OAAO,GAAI,QAAQ,CAAC,UAAqB,IAAI,EAAE,CAAC;IACtD,MAAM,MAAM,GAAI,QAAQ,CAAC,SAAoB,IAAI,EAAE,CAAC;IACpD,IAAI,OAAO,IAAI,MAAM,EAAE,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,qBAAqB,OAAO,WAAW,MAAM,EAAE,CAAC,CAAC;IAC9D,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACxB,KAAK,CAAC,IAAI,CAAC,qBAAqB,GAAG,EAAE,CAAC,CAAC;IACvC,KAAK,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IAC9C,KAAK,CAAC,IAAI,CAAC,qBAAqB,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;IACpG,KAAK,CAAC,IAAI,CAAC,qBAAqB,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;IACpD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC/B,MAAM,EAAE,GAAI,QAAQ,CAAC,gBAA8C,CAAC;IACpE,KAAK,CAAC,IAAI,CAAC,uBAAuB,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;IACzF,MAAM,OAAO,GAAI,QAAQ,CAAC,OAA0C,IAAI,EAAE,CAAC;IAC3E,KAAK,CAAC,IAAI,CAAC,qBAAqB,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAClD,KAAK,CAAC,IAAI,CAAC,qBAAqB,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAEtD,wBAAwB;IACxB,MAAM,EAAE,GAAG,QAAQ,CAAC,eAA6D,CAAC;IAClF,IAAI,EAAE,EAAE,CAAC;QACP,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC9B,MAAM,KAAK,GAAG,EAAE,CAAC,aAAuB,CAAC;QACzC,MAAM,GAAG,GAAG,EAAE,CAAC,gBAA0B,CAAC;QAC1C,MAAM,KAAK,GAAG,EAAE,CAAC,kBAA4B,CAAC;QAC9C,MAAM,GAAG,GAAI,EAAE,CAAC,YAAuB,IAAI,CAAC,CAAC;QAC7C,KAAK,CAAC,IAAI,CAAC,qBAAqB,KAAK,EAAE,CAAC,CAAC;QACzC,KAAK,CAAC,IAAI,CAAC,qBAAqB,GAAG,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACrE,KAAK,CAAC,IAAI,CAAC,qBAAqB,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAE7E,gCAAgC;QAChC,MAAM,SAAS,GAAG,EAAE,CAAC,UAAwD,CAAC;QAC9E,IAAI,SAAS,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,MAAM,EAAE,GAAI,EAAE,CAAC,wBAAoD,IAAI,EAAE,CAAC;YAC1E,MAAM,SAAS,GAAI,EAAE,CAAC,gBAA6B,IAAI,EAAE,CAAC;YAC1D,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;gBAC1B,MAAM,GAAG,GAAG,CAAC,CAAC,cAAc,IAAI,GAAG,CAAC;gBACpC,MAAM,KAAK,GAAG,CAAC,CAAC,WAAW,IAAI,SAAS,CAAC;gBACzC,MAAM,KAAK,GAAG,CAAC,CAAC,SAA+B,CAAC;gBAChD,IAAI,KAAK,GAAG,MAAM,GAAG,MAAM,KAAK,EAAE,CAAC;gBACnC,IAAI,KAAK;oBAAE,KAAK,IAAI,KAAK,KAAK,EAAE,CAAC;gBACjC,KAAK,IAAI,SAAS,CAAC,QAAQ,CAAC,GAAa,CAAC;oBACxC,CAAC,CAAC,+CAA+C;oBACjD,CAAC,CAAC,0BAA0B,CAAC;gBAC/B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACpB,CAAC;QACH,CAAC;QAED,6BAA6B;QAC7B,MAAM,YAAY,GAAG,EAAE,CAAC,2BAAmD,CAAC;QAC5E,IAAI,YAAY,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YAC1D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,4BAA4B,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;YACvE,MAAM,OAAO,GAAG,EAAE,CAAC,8BAAoD,CAAC;YACxE,IAAI,OAAO;gBAAE,KAAK,CAAC,IAAI,CAAC,KAAK,OAAO,gBAAgB,CAAC,CAAC;YACtD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;YACjD,KAAK,CAAC,IAAI,CAAC,4DAA4D,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;IAED,qDAAqD;IACrD,MAAM,YAAY,GAAG,QAAQ,CAAC,aAAmC,CAAC;IAClE,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,YAAY,KAAK,MAAM,EAAE,CAAC;QAClD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAChC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACnC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,IAAI,OAAO,GAAI,CAAC,CAAC,WAAsB,IAAK,CAAC,CAAC,QAAmB,IAAI,SAAS,CAAC;YAC/E,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3D,MAAM,WAAW,GAAG,CAAC,CAAC,YAAY,IAAI,SAAS,CAAC;YAChD,MAAM,EAAE,GAAG,CAAC,CAAC,iBAAwD,CAAC;YAEtE,IAAI,IAAI,GAAG,KAAK,OAAO,KAAK,WAAW,EAAE,CAAC;YAC1C,IAAI,EAAE,EAAE,CAAC;gBACP,MAAM,OAAO,GAAa,EAAE,CAAC;gBAC7B,IAAI,cAAc,IAAI,EAAE;oBAAE,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,YAAY,WAAW,CAAC,CAAC;gBACtE,IAAI,YAAY,IAAI,EAAE;oBAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,CAAC,CAAC;gBAC9D,IAAI,cAAc,IAAI,EAAE;oBAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,YAAsB,CAAC,CAAC;gBAClE,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;oBAAE,IAAI,IAAI,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;YAC9D,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,aAAa,OAAO,CAAC,MAAM,GAAG,EAAE,cAAc,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC/B,KAAK,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;IAC/E,KAAK,CAAC,IAAI,CAAC,iEAAiE,CAAC,CAAC;IAC9E,KAAK,CAAC,IAAI,CAAC,4DAA4D,CAAC,CAAC;IACzE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IACvC,KAAK,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;IAC3E,KAAK,CAAC,IAAI,CAAC,+DAA+D,CAAC,CAAC;IAC5E,KAAK,CAAC,IAAI,CAAC,mEAAmE,CAAC,CAAC;IAChF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACnC,KAAK,CAAC,IAAI,CAAC,wBAAwB,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IACrD,KAAK,CAAC,IAAI,CAAC,oBAAoB,MAAM,CAAC,OAAO,OAAO,CAAC,CAAC;IACtD,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAEhC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,gBAAgB,CAAC,MAA0B;IAClD,MAAM,IAAI,GAAG,MAAM,CAAC,kBAA6C,CAAC;IAClE,MAAM,GAAG,GAAG,MAAM,CAAC,QAAmC,CAAC;IAEvD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,CAAC,OAAO,eAAe,CAAC,CAAC;IAChE,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,CAAC,OAAO,iBAAiB,CAAC,CAAC;QAChE,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACzC,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,sBAAsB,OAAO,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,sBAAsB,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,sBAAsB,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,sBAAsB,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,sBAAsB,MAAM,CAAC,SAAS,WAAW,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;IAC3E,OAAO,CAAC,GAAG,CAAC,sBAAsB,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;IAEzD,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,mBAAmB,KAAK,QAAQ,EAAE,CAAC;QACvD,IAAI,MAAM,GAAG,GAAG,GAAG,CAAC,mBAAmB,UAAU,CAAC;QAClD,IAAI,OAAO,GAAG,CAAC,2BAA2B,KAAK,QAAQ,EAAE,CAAC;YACxD,MAAM,IAAI,MAAM,GAAG,CAAC,2BAA2B,2BAA2B,CAAC;QAC7E,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,sBAAsB,MAAM,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,sBAAsB,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEpE,IAAI,MAAM,CAAC,oBAAoB,EAAE,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,sBAAsB,MAAM,CAAC,oBAAoB,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,sBAAsB,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;IAEtD,IAAI,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAC;IAC1E,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,IAAe;IACxC,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,GAAG,SAAS,CAAC;YACjB,IAAI,EAAE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YACnC,OAAO,EAAE;gBACP,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;gBAC/C,cAAc,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;gBACnD,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAChC,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;gBACzC,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC1B,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;gBAC1C,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE;gBACrD,iEAAiE;gBACjE,8DAA8D;gBAC9D,2DAA2D;gBAC3D,0DAA0D;gBAC1D,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBACjC,mBAAmB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;aACxD;YACD,gBAAgB,EAAE,IAAI;SACvB,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,UAAW,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAClD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1D,OAAO,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAC;QACxE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;QACnE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;QAClE,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;QAC1D,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,kFAAkF,CAAC,CAAC;QAChG,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;QAChE,OAAO,CAAC,GAAG,CAAC,2EAA2E,CAAC,CAAC;QACzF,OAAO,CAAC,GAAG,CAAC,yEAAyE,CAAC,CAAC;QACvF,OAAO,CAAC,GAAG,CAAC,uEAAuE,CAAC,CAAC;QACrF,OAAO,CAAC,GAAG,CAAC,4DAA4D,CAAC,CAAC;QAC1E,OAAO,CAAC,GAAG,CAAC,8EAA8E,CAAC,CAAC;QAC5F,OAAO,CAAC,GAAG,CAAC,0EAA0E,CAAC,CAAC;QACxF,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC;IAED,wDAAwD;IACxD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;IACvF,IAAI,MAAM,GAAkB,IAAI,CAAC;IACjC,IAAI,QAAgB,CAAC;IACrB,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,IAAI,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACzE,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAC/B,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC;SAAM,CAAC;QACN,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC;IACD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,KAAK,CAAC;IAC/C,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,OAAO,CAAC;IAE1E,qBAAqB;IACrB,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,GAAG,GAAG,0BAA0B,QAAQ,EAAE,CAAC;QACjD,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,QAAiC,CAAC;IACtC,IAAI,CAAC;QACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,GAAG,GAAG,0BAA0B,QAAQ,EAAE,CAAC;QACjD,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,mDAAmD;IACnD,iEAAiE;IACjE,mEAAmE;IACnE,gEAAgE;IAChE,oEAAoE;IACpE,6DAA6D;IAC7D,IAAI,QAA0C,CAAC;IAC/C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAuB,CAAC;IAClE,MAAM,aAAa,GAAI,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAA0B,IAAI,EAAE,CAAC;IACzF,IAAI,MAAM,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC5C,KAAK,MAAM,EAAE,IAAI,aAAa,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,CAA4B,CAAC;gBAC7E,uBAAuB;gBACvB,uEAAuE;gBACvE,+CAA+C;gBAC/C,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,yBAAyB,KAAK,QAAQ,EAAE,CAAC;oBACzF,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,yBAAyB,CAAC,CAAC;gBAC5D,CAAC;qBAAM,CAAC;oBACN,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;wBACzC,IAAI,OAAO,CAAC,KAAK,QAAQ;4BAAE,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oBACjD,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,GAAG,GAAG,wCAAwC,EAAE,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC;gBACpF,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACnB,OAAO,CAAC,CAAC;YACX,CAAC;QACH,CAAC;QACD,QAAQ,GAAG,0BAA0B,CAAC;YACpC,MAAM;YACN,SAAS,EAAE,SAAS,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;SACtD,CAAC,CAAC;IACL,CAAC;IAED,mBAAmB;IACnB,IAAI,MAA0B,CAAC;IAC/B,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,MAAM,CACnB,QAAQ,EACR;YACE,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU;YACpC,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC;YAC3C,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC;SACxC,EACD,QAAQ,CACT,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,+BAAgC,GAAa,CAAC,OAAO,EAAE,CAAC;QACpE,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,SAAS;IACT,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC;SAAM,IAAI,SAAS,EAAE,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;IACxD,CAAC;SAAM,CAAC;QACN,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC;IAED,IAAI,MAAM,CAAC,KAAK,IAAI,QAAQ,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;QAC3D,OAAO,CAAC,CAAC;IACX,CAAC;IAED,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9B,CAAC;AAED,0BAA0B;AAC1B,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC;IACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CACpC,CAAC;AAEF,IAAI,WAAW,EAAE,CAAC;IAChB,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,13 @@
1
+ export { verify } from './verifier';
2
+ export type { UpstreamRootResolver, VerifyOptions, VerificationResult, RekorStatus, } from './types';
3
+ export { generateVerifyHtml } from './verify-html-template';
4
+ export { seedKeyCache } from './key-cache';
5
+ export { REASONS, buildMerkleRoot, canonicalJson, canonicalJsonString, canonicalNumber, verifyBoundedTrace, } from './bounded-trace';
6
+ export type { BoundedTraceResult, ReasonCode } from './bounded-trace';
7
+ export { SCOPED_REASONS, verifyScopedCertificates, } from './scoped';
8
+ export type { ScopedCertificatesResult, ScopedReason } from './scoped';
9
+ export { createUpstreamRootResolver, closeResolver, } from './upstream_resolver';
10
+ export type { UpstreamResolverOptions } from './upstream_resolver';
11
+ export { ENVELOPE_VERSION, ALLOWED_KINDS, ALLOWED_TRUST_EDGES, PROOF_TIER_HIERARCHY, canonicalJson as canonicalJsonV29, canonicalHash as canonicalHashV29, validateEnvelopeShape, reproduceAggregations, validateAggregations, reproduceTierCeiling, validateRecordsAgainstHarness, validateRuntimeBindingHash, reproduceManifestCanonicalHash, validateManifestCanonicalHash, verifyV29, } from './v29-envelope';
12
+ export type { V29VerifyResult, ProofTier } from './v29-envelope';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACpC,YAAY,EACV,oBAAoB,EACpB,aAAa,EACb,kBAAkB,EAClB,WAAW,GACZ,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EACL,OAAO,EACP,eAAe,EACf,aAAa,EACb,mBAAmB,EACnB,eAAe,EACf,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EACL,cAAc,EACd,wBAAwB,GACzB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,wBAAwB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAKvE,OAAO,EACL,0BAA0B,EAC1B,aAAa,GACd,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAInE,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,IAAI,gBAAgB,EACjC,aAAa,IAAI,gBAAgB,EACjC,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,6BAA6B,EAC7B,0BAA0B,EAC1B,8BAA8B,EAC9B,6BAA6B,EAC7B,SAAS,GACV,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,13 @@
1
+ export { verify } from './verifier';
2
+ export { generateVerifyHtml } from './verify-html-template';
3
+ export { seedKeyCache } from './key-cache';
4
+ export { REASONS, buildMerkleRoot, canonicalJson, canonicalJsonString, canonicalNumber, verifyBoundedTrace, } from './bounded-trace';
5
+ export { SCOPED_REASONS, verifyScopedCertificates, } from './scoped';
6
+ // Cross-org upstream-VPEC resolver (Follow-7)
7
+ // UpstreamRootResolver type is canonical from ./types (Follow-6); we
8
+ // only re-export the resolver factory + its options here.
9
+ export { createUpstreamRootResolver, closeResolver, } from './upstream_resolver';
10
+ // v29 Layer 1 — ProofCheck envelope + manifest + runtime-binding
11
+ // conformance. Mirror of packages/verifier-py/.../v29_envelope.py.
12
+ export { ENVELOPE_VERSION, ALLOWED_KINDS, ALLOWED_TRUST_EDGES, PROOF_TIER_HIERARCHY, canonicalJson as canonicalJsonV29, canonicalHash as canonicalHashV29, validateEnvelopeShape, reproduceAggregations, validateAggregations, reproduceTierCeiling, validateRecordsAgainstHarness, validateRuntimeBindingHash, reproduceManifestCanonicalHash, validateManifestCanonicalHash, verifyV29, } from './v29-envelope';
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAOpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EACL,OAAO,EACP,eAAe,EACf,aAAa,EACb,mBAAmB,EACnB,eAAe,EACf,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,cAAc,EACd,wBAAwB,GACzB,MAAM,UAAU,CAAC;AAGlB,8CAA8C;AAC9C,qEAAqE;AACrE,0DAA0D;AAC1D,OAAO,EACL,0BAA0B,EAC1B,aAAa,GACd,MAAM,qBAAqB,CAAC;AAG7B,iEAAiE;AACjE,mEAAmE;AACnE,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,IAAI,gBAAgB,EACjC,aAAa,IAAI,gBAAgB,EACjC,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,6BAA6B,EAC7B,0BAA0B,EAC1B,8BAA8B,EAC9B,6BAA6B,EAC7B,SAAS,GACV,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Public key cache for VPEC signature verification.
3
+ *
4
+ * Fetches public keys from trust anchor URLs and caches by key ID.
5
+ * Supports pinned trust roots for offline/air-gapped verification.
6
+ */
7
+ /**
8
+ * Resolve a public key by key ID.
9
+ *
10
+ * @param kid - Key identifier from VPEC signature field
11
+ * @param publicKeyUrl - URL to fetch the PEM/base64url key
12
+ * @param trustRoot - Optional local PEM file path or content for offline mode
13
+ */
14
+ /**
15
+ * Pre-seed the in-memory key cache. Used by evidence-pack assembler
16
+ * to inject the signer's public key before verification runs.
17
+ */
18
+ export declare function seedKeyCache(kid: string, publicKey: string): void;
19
+ export declare function getKey(kid: string, publicKeyUrl: string, trustRoot?: string): Promise<string>;
20
+ //# sourceMappingURL=key-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-cache.d.ts","sourceRoot":"","sources":["../src/key-cache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH;;;;;;GAMG;AACH;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAEjE;AAED,wBAAsB,MAAM,CAC1B,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,EACpB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CAgDjB"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Public key cache for VPEC signature verification.
3
+ *
4
+ * Fetches public keys from trust anchor URLs and caches by key ID.
5
+ * Supports pinned trust roots for offline/air-gapped verification.
6
+ */
7
+ import { readFileSync, existsSync } from 'node:fs';
8
+ // In-memory cache: kid → base64url public key
9
+ const cache = new Map();
10
+ /**
11
+ * Resolve a public key by key ID.
12
+ *
13
+ * @param kid - Key identifier from VPEC signature field
14
+ * @param publicKeyUrl - URL to fetch the PEM/base64url key
15
+ * @param trustRoot - Optional local PEM file path or content for offline mode
16
+ */
17
+ /**
18
+ * Pre-seed the in-memory key cache. Used by evidence-pack assembler
19
+ * to inject the signer's public key before verification runs.
20
+ */
21
+ export function seedKeyCache(kid, publicKey) {
22
+ cache.set(kid, publicKey);
23
+ }
24
+ export async function getKey(kid, publicKeyUrl, trustRoot) {
25
+ // Pinned trust root — zero network calls
26
+ if (trustRoot) {
27
+ // If it looks like a file path, read it
28
+ if (existsSync(trustRoot)) {
29
+ return readFileSync(trustRoot, 'utf-8').trim();
30
+ }
31
+ // Otherwise treat as inline key content
32
+ return trustRoot.trim();
33
+ }
34
+ // Check cache
35
+ const cached = cache.get(kid);
36
+ if (cached)
37
+ return cached;
38
+ // Fetch from URL with retries
39
+ if (!publicKeyUrl) {
40
+ throw new Error(`No public_key_url for kid=${kid}`);
41
+ }
42
+ let lastError = null;
43
+ for (let attempt = 0; attempt < 3; attempt++) {
44
+ try {
45
+ const resp = await fetch(publicKeyUrl, {
46
+ headers: { Accept: 'application/x-pem-file' },
47
+ signal: AbortSignal.timeout(10_000),
48
+ });
49
+ if (!resp.ok) {
50
+ throw new Error(`HTTP ${resp.status}`);
51
+ }
52
+ const pem = (await resp.text()).trim();
53
+ if (!pem) {
54
+ throw new Error('Empty response');
55
+ }
56
+ cache.set(kid, pem);
57
+ return pem;
58
+ }
59
+ catch (e) {
60
+ lastError = e instanceof Error ? e : new Error(String(e));
61
+ if (attempt < 2) {
62
+ await new Promise(r => setTimeout(r, 500 * (attempt + 1)));
63
+ }
64
+ }
65
+ }
66
+ throw new Error(`Failed to fetch key from ${publicKeyUrl} after 3 attempts: ${lastError?.message}`);
67
+ }
68
+ //# sourceMappingURL=key-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-cache.js","sourceRoot":"","sources":["../src/key-cache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEnD,8CAA8C;AAC9C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;AAExC;;;;;;GAMG;AACH;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,SAAiB;IACzD,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,GAAW,EACX,YAAoB,EACpB,SAAkB;IAElB,yCAAyC;IACzC,IAAI,SAAS,EAAE,CAAC;QACd,wCAAwC;QACxC,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1B,OAAO,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QACjD,CAAC;QACD,wCAAwC;QACxC,OAAO,SAAS,CAAC,IAAI,EAAE,CAAC;IAC1B,CAAC;IAED,cAAc;IACd,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,8BAA8B;IAC9B,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,IAAI,SAAS,GAAiB,IAAI,CAAC;IACnC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;QAC7C,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,YAAY,EAAE;gBACrC,OAAO,EAAE,EAAE,MAAM,EAAE,wBAAwB,EAAE;gBAC7C,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;aACpC,CAAC,CAAC;YAEH,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACzC,CAAC;YAED,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YACvC,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;YACpC,CAAC;YAED,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YACpB,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,SAAS,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1D,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;gBAChB,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7D,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,4BAA4B,YAAY,sBAAsB,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;AACtG,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Reference TypeScript verifier for the `scoped_certificates` VPEC section.
3
+ *
4
+ * Ported from verifier-py/src/primust_verify/scoped.py. Validates the
5
+ * top-level `scoped_certificates` array + matching
6
+ * `scoped_certificates_commitment` emitted by the SDK's
7
+ * `primust.scoped.bundle` module (SCOPED_CERT_SPEC_v27 §14).
8
+ *
9
+ * Trust-chain scope:
10
+ * 1. Every entry carries a known `certificate_type` discriminator.
11
+ * 2. Every entry has the required structural fields for its type.
12
+ * 3. The array is in canonical order: lexicographic by
13
+ * (certificate_type, canonical_sha256(payload)).
14
+ * 4. The declared commitment byte-matches the recomputed Merkle root
15
+ * over the ordered canonical-JSON leaves. Empty bundle uses the
16
+ * well-known `sha256(canonical({scoped_certificates: []}))`.
17
+ *
18
+ * SI-3 (VPEC verifiability): this module's output MUST agree with the
19
+ * Python reference (`primust_verify.scoped`) byte-for-byte across the
20
+ * shared fixture corpus at
21
+ * packages/verifier-py/tests/fixtures/scoped_v1/. The conformance runner
22
+ * in scripts/scoped_conformance.py gates that in CI.
23
+ */
24
+ import { buildMerkleRoot, canonicalJson, canonicalJsonString } from "./bounded-trace";
25
+ export declare const SCOPED_REASONS: readonly ["ok", "missing_section", "malformed_section", "missing_commitment", "malformed_commitment", "missing_discriminator", "unknown_certificate_type", "schema_validation_failed", "ordering_violation", "commitment_mismatch"];
26
+ export type ScopedReason = (typeof SCOPED_REASONS)[number];
27
+ export interface ScopedCertificatesResult {
28
+ valid: boolean;
29
+ reason: ScopedReason;
30
+ entry_count: number;
31
+ details: Record<string, unknown>;
32
+ }
33
+ export declare function verifyScopedCertificates(vpecLike: Record<string, unknown>): ScopedCertificatesResult;
34
+ export { canonicalJson, canonicalJsonString, buildMerkleRoot };
35
+ //# sourceMappingURL=scoped.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scoped.d.ts","sourceRoot":"","sources":["../src/scoped.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,EACL,eAAe,EACf,aAAa,EACb,mBAAmB,EACpB,MAAM,iBAAiB,CAAC;AAmazB,eAAO,MAAM,cAAc,qOAWjB,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,YAAY,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AA+DD,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,wBAAwB,CA8F1B;AAGD,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,eAAe,EAAE,CAAC"}