@attestplane/attestplane 0.0.1-alpha.1 → 0.0.3-alpha

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 (106) hide show
  1. package/README.md +17 -10
  2. package/dist/adapter_conformance.d.ts +46 -0
  3. package/dist/adapter_conformance.d.ts.map +1 -0
  4. package/dist/adapter_conformance.js +160 -0
  5. package/dist/adapter_conformance.js.map +1 -0
  6. package/dist/adapters/langfuse.d.ts +51 -0
  7. package/dist/adapters/langfuse.d.ts.map +1 -0
  8. package/dist/adapters/langfuse.js +157 -0
  9. package/dist/adapters/langfuse.js.map +1 -0
  10. package/dist/adapters/langsmith.d.ts +53 -0
  11. package/dist/adapters/langsmith.d.ts.map +1 -0
  12. package/dist/adapters/langsmith.js +173 -0
  13. package/dist/adapters/langsmith.js.map +1 -0
  14. package/dist/adapters.d.ts +88 -0
  15. package/dist/adapters.d.ts.map +1 -0
  16. package/dist/adapters.js +109 -0
  17. package/dist/adapters.js.map +1 -0
  18. package/dist/anchoring.d.ts +119 -0
  19. package/dist/anchoring.d.ts.map +1 -0
  20. package/dist/anchoring.js +340 -0
  21. package/dist/anchoring.js.map +1 -0
  22. package/dist/canonical.d.ts +11 -2
  23. package/dist/canonical.d.ts.map +1 -1
  24. package/dist/canonical.js +44 -31
  25. package/dist/canonical.js.map +1 -1
  26. package/dist/canonical_text.d.ts +30 -0
  27. package/dist/canonical_text.d.ts.map +1 -0
  28. package/dist/canonical_text.js +100 -0
  29. package/dist/canonical_text.js.map +1 -0
  30. package/dist/der.d.ts +55 -0
  31. package/dist/der.d.ts.map +1 -0
  32. package/dist/der.js +200 -0
  33. package/dist/der.js.map +1 -0
  34. package/dist/event_payloads.d.ts +118 -0
  35. package/dist/event_payloads.d.ts.map +1 -0
  36. package/dist/event_payloads.js +348 -0
  37. package/dist/event_payloads.js.map +1 -0
  38. package/dist/event_types.d.ts +47 -0
  39. package/dist/event_types.d.ts.map +1 -0
  40. package/dist/event_types.js +63 -0
  41. package/dist/event_types.js.map +1 -0
  42. package/dist/hashchain.d.ts +1 -0
  43. package/dist/hashchain.d.ts.map +1 -1
  44. package/dist/hashchain.js +25 -1
  45. package/dist/hashchain.js.map +1 -1
  46. package/dist/index.d.ts +22 -1
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +23 -1
  49. package/dist/index.js.map +1 -1
  50. package/dist/index_version.d.ts +9 -0
  51. package/dist/index_version.d.ts.map +1 -0
  52. package/dist/index_version.js +11 -0
  53. package/dist/index_version.js.map +1 -0
  54. package/dist/intoto.d.ts +48 -0
  55. package/dist/intoto.d.ts.map +1 -0
  56. package/dist/intoto.js +106 -0
  57. package/dist/intoto.js.map +1 -0
  58. package/dist/obligations.d.ts +41 -0
  59. package/dist/obligations.d.ts.map +1 -0
  60. package/dist/obligations.js +312 -0
  61. package/dist/obligations.js.map +1 -0
  62. package/dist/proof_bundle.d.ts +186 -0
  63. package/dist/proof_bundle.d.ts.map +1 -0
  64. package/dist/proof_bundle.js +299 -0
  65. package/dist/proof_bundle.js.map +1 -0
  66. package/dist/reason_codes.d.ts +38 -0
  67. package/dist/reason_codes.d.ts.map +1 -0
  68. package/dist/reason_codes.js +97 -0
  69. package/dist/reason_codes.js.map +1 -0
  70. package/dist/replay_verifier.d.ts +43 -0
  71. package/dist/replay_verifier.d.ts.map +1 -0
  72. package/dist/replay_verifier.js +98 -0
  73. package/dist/replay_verifier.js.map +1 -0
  74. package/dist/rfc3161.d.ts +52 -0
  75. package/dist/rfc3161.d.ts.map +1 -0
  76. package/dist/rfc3161.js +480 -0
  77. package/dist/rfc3161.js.map +1 -0
  78. package/dist/settlement_verifier.d.ts +34 -0
  79. package/dist/settlement_verifier.d.ts.map +1 -0
  80. package/dist/settlement_verifier.js +139 -0
  81. package/dist/settlement_verifier.js.map +1 -0
  82. package/dist/signing/base.d.ts +101 -0
  83. package/dist/signing/base.d.ts.map +1 -0
  84. package/dist/signing/base.js +144 -0
  85. package/dist/signing/base.js.map +1 -0
  86. package/dist/signing/providers.d.ts +113 -0
  87. package/dist/signing/providers.d.ts.map +1 -0
  88. package/dist/signing/providers.js +230 -0
  89. package/dist/signing/providers.js.map +1 -0
  90. package/dist/signing/signer.d.ts +66 -0
  91. package/dist/signing/signer.d.ts.map +1 -0
  92. package/dist/signing/signer.js +146 -0
  93. package/dist/signing/signer.js.map +1 -0
  94. package/dist/signing/trust_roots.d.ts +71 -0
  95. package/dist/signing/trust_roots.d.ts.map +1 -0
  96. package/dist/signing/trust_roots.js +267 -0
  97. package/dist/signing/trust_roots.js.map +1 -0
  98. package/dist/signing/verifier_ext.d.ts +77 -0
  99. package/dist/signing/verifier_ext.d.ts.map +1 -0
  100. package/dist/signing/verifier_ext.js +340 -0
  101. package/dist/signing/verifier_ext.js.map +1 -0
  102. package/dist/verifier.d.ts +39 -0
  103. package/dist/verifier.d.ts.map +1 -0
  104. package/dist/verifier.js +374 -0
  105. package/dist/verifier.js.map +1 -0
  106. package/package.json +1 -1
@@ -0,0 +1,340 @@
1
+ // SPDX-FileCopyrightText: 2026 The Attestplane Authors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /**
4
+ * Verifier extension — TypeScript mirror of
5
+ * `sdk/python/src/attestplane/signing/verifier_ext.py`.
6
+ *
7
+ * Adds two functions alongside the existing
8
+ * `verifyChainWithAnchors` in `../anchoring.ts`:
9
+ *
10
+ * - `verifyChainWithSignatures` — signature-only path.
11
+ * - `verifyChainFull` — unified chain + signature + anchor.
12
+ *
13
+ * Pipeline ordering (architect review § 1 decision 8): chain →
14
+ * signature → anchor. Each step always runs (no short-circuit) for
15
+ * forensic completeness.
16
+ *
17
+ * Plurality priority (T6 review decision 7):
18
+ * `valid > expired_key > invalid > unknown_key > unsigned`. Any single
19
+ * `valid` signature for a seq lifts that seq to `valid`.
20
+ *
21
+ * Coverage (T6 review decision 7, option a): a `valid` segment-head
22
+ * signature at seq=N covers seqs {previous-signed-head + 1 .. N} via
23
+ * chain-integrity transitivity. Per-event signatures cover their
24
+ * explicit `signed_seq` only.
25
+ */
26
+ import { createPublicKey, verify as ed25519Verify } from 'node:crypto';
27
+ import { verifyChainWithAnchors, } from '../anchoring.js';
28
+ import { SIGNATURE_SCHEMA_VERSION, SigningError, deriveKeyId, } from './base.js';
29
+ import { buildPerEventPayload, buildSegmentHeadPayload } from './signer.js';
30
+ /** Lower rank = better. Used to merge multiple signatures per seq. */
31
+ export const STATUS_RANK = Object.freeze({
32
+ valid: 0,
33
+ expired_key: 1,
34
+ invalid: 2,
35
+ unknown_key: 3,
36
+ unsigned: 4,
37
+ });
38
+ function bytesEqual(a, b) {
39
+ if (a.length !== b.length)
40
+ return false;
41
+ for (let i = 0; i < a.length; i++) {
42
+ if (a[i] !== b[i])
43
+ return false;
44
+ }
45
+ return true;
46
+ }
47
+ function loadEd25519PublicKey(der) {
48
+ return createPublicKey({
49
+ key: Buffer.from(der),
50
+ format: 'der',
51
+ type: 'spki',
52
+ });
53
+ }
54
+ function verifySingleSignature(record, index, eventsBySeq, chainId, trustRoots, verificationTime) {
55
+ const base = {
56
+ record_index: index,
57
+ signed_seq: record.signed_seq,
58
+ key_id: record.key_id,
59
+ };
60
+ // 1. Schema version.
61
+ if (record.signature_schema_version !== SIGNATURE_SCHEMA_VERSION) {
62
+ return {
63
+ ...base,
64
+ status: 'invalid',
65
+ reason: `signature_schema_version=${record.signature_schema_version} ` +
66
+ `unsupported (expected ${SIGNATURE_SCHEMA_VERSION})`,
67
+ };
68
+ }
69
+ if (record.signed_payload.length === 0) {
70
+ return { ...base, status: 'invalid', reason: 'signed_payload is empty' };
71
+ }
72
+ // 2. Self-consistency: key_id derives from public_key_der.
73
+ const derived = deriveKeyId(record.public_key_der);
74
+ if (derived !== record.key_id) {
75
+ return {
76
+ ...base,
77
+ status: 'invalid',
78
+ reason: `record.key_id (${record.key_id}) does not derive from public_key_der (got ${derived})`,
79
+ };
80
+ }
81
+ // 3. TrustRoots lookup.
82
+ const entry = trustRoots.lookup(record.key_id);
83
+ if (entry === null) {
84
+ return {
85
+ ...base,
86
+ status: 'unknown_key',
87
+ reason: `key_id ${JSON.stringify(record.key_id)} not in trust roots`,
88
+ };
89
+ }
90
+ // 4. Validity window.
91
+ const vt = verificationTime.getTime();
92
+ if (vt < entry.valid_from.getTime()) {
93
+ return {
94
+ ...base,
95
+ status: 'expired_key',
96
+ reason: `verification_time ${verificationTime.toISOString()} ` +
97
+ `precedes valid_from ${entry.valid_from.toISOString()}`,
98
+ };
99
+ }
100
+ if (vt > entry.valid_until.getTime()) {
101
+ return {
102
+ ...base,
103
+ status: 'expired_key',
104
+ reason: `verification_time ${verificationTime.toISOString()} ` +
105
+ `exceeds valid_until ${entry.valid_until.toISOString()}`,
106
+ };
107
+ }
108
+ // 5. Ed25519 signature verification.
109
+ let pubkey;
110
+ try {
111
+ pubkey = loadEd25519PublicKey(record.public_key_der);
112
+ }
113
+ catch (exc) {
114
+ return {
115
+ ...base,
116
+ status: 'invalid',
117
+ reason: `public_key_der not parseable: ${exc.message}`,
118
+ };
119
+ }
120
+ if (pubkey.asymmetricKeyType !== 'ed25519') {
121
+ return {
122
+ ...base,
123
+ status: 'invalid',
124
+ reason: `v1 supports Ed25519 keys only; got ${String(pubkey.asymmetricKeyType)}`,
125
+ };
126
+ }
127
+ if (!bytesEqual(entry.public_key_der, record.public_key_der)) {
128
+ return {
129
+ ...base,
130
+ status: 'invalid',
131
+ reason: "record.public_key_der does not match trust-root entry's public_key_der " +
132
+ '(same key_id, different bytes — tamper signal)',
133
+ };
134
+ }
135
+ const ok = ed25519Verify(null, Buffer.from(record.signed_payload), pubkey, Buffer.from(record.signature));
136
+ if (!ok) {
137
+ return {
138
+ ...base,
139
+ status: 'invalid',
140
+ reason: 'Ed25519 verify failed',
141
+ };
142
+ }
143
+ // 6. Payload semantics cross-check.
144
+ const target = eventsBySeq.get(record.signed_seq);
145
+ if (target === undefined) {
146
+ return {
147
+ ...base,
148
+ status: 'invalid',
149
+ reason: `signed_seq=${record.signed_seq} not in chain`,
150
+ };
151
+ }
152
+ if (!bytesEqual(target.event_hash, record.signed_event_hash)) {
153
+ return {
154
+ ...base,
155
+ status: 'invalid',
156
+ reason: `signed_event_hash mismatch at seq=${record.signed_seq}`,
157
+ };
158
+ }
159
+ if (record.signature_mode === 'segment_head') {
160
+ const expected = buildSegmentHeadPayload(chainId, {
161
+ seq: target.seq,
162
+ event_hash: target.event_hash,
163
+ });
164
+ if (!bytesEqual(expected, record.signed_payload)) {
165
+ let payloadChainId = '<unparsable>';
166
+ try {
167
+ const parsed = JSON.parse(Buffer.from(record.signed_payload).toString('utf-8'));
168
+ payloadChainId = parsed.chain_id;
169
+ }
170
+ catch {
171
+ // payloadChainId stays as '<unparsable>'
172
+ }
173
+ return {
174
+ ...base,
175
+ status: 'invalid',
176
+ reason: `signed_payload does not match expected canonical bytes for segment_head at seq=${record.signed_seq}; payload chain_id=${JSON.stringify(payloadChainId)}, verifier chain_id=${JSON.stringify(chainId)}`,
177
+ };
178
+ }
179
+ }
180
+ else {
181
+ const expected = buildPerEventPayload(target.event);
182
+ if (!bytesEqual(expected, record.signed_payload)) {
183
+ return {
184
+ ...base,
185
+ status: 'invalid',
186
+ reason: `signed_payload does not match canonicalize(event) for per_event at seq=${record.signed_seq}`,
187
+ };
188
+ }
189
+ }
190
+ return { ...base, status: 'valid', reason: null };
191
+ }
192
+ function mergeStatusAtSeq(perSeq) {
193
+ const result = new Map();
194
+ for (const [seq, statuses] of perSeq.entries()) {
195
+ let best = statuses[0];
196
+ let bestRank = STATUS_RANK[best];
197
+ for (let i = 1; i < statuses.length; i++) {
198
+ const s = statuses[i];
199
+ const r = STATUS_RANK[s];
200
+ if (r < bestRank) {
201
+ best = s;
202
+ bestRank = r;
203
+ }
204
+ }
205
+ result.set(seq, best);
206
+ }
207
+ return result;
208
+ }
209
+ function computeSignedSegmentCount(events, perSeqStatus, perSeqModes) {
210
+ const validSegmentHeads = [];
211
+ const validPerEvents = new Set();
212
+ for (const [seq, status] of perSeqStatus.entries()) {
213
+ if (status !== 'valid')
214
+ continue;
215
+ const modes = perSeqModes.get(seq) ?? new Set();
216
+ if (modes.has('segment_head'))
217
+ validSegmentHeads.push(seq);
218
+ if (modes.has('per_event'))
219
+ validPerEvents.add(seq);
220
+ }
221
+ validSegmentHeads.sort((a, b) => a - b);
222
+ const covered = new Set(validPerEvents);
223
+ let prevHead = -1;
224
+ for (const headSeq of validSegmentHeads) {
225
+ for (let s = prevHead + 1; s <= headSeq; s++) {
226
+ covered.add(s);
227
+ }
228
+ prevHead = headSeq;
229
+ }
230
+ const chainSeqs = new Set(events.map((e) => e.seq));
231
+ let count = 0;
232
+ for (const s of covered) {
233
+ if (chainSeqs.has(s))
234
+ count++;
235
+ }
236
+ return count;
237
+ }
238
+ export function verifyChainWithSignatures(events, signatures, options) {
239
+ if (!options.chain_id) {
240
+ throw new SigningError('verifyChainWithSignatures requires non-empty chain_id');
241
+ }
242
+ const actualWhen = options.verification_time ?? new Date();
243
+ if (Number.isNaN(actualWhen.getTime())) {
244
+ throw new SigningError('verifyChainWithSignatures requires a valid Date for verification_time');
245
+ }
246
+ const eventsBySeq = new Map();
247
+ for (const ev of events)
248
+ eventsBySeq.set(ev.seq, ev);
249
+ const results = [];
250
+ const perSeqStatuses = new Map();
251
+ const perSeqModes = new Map();
252
+ for (let i = 0; i < signatures.length; i++) {
253
+ const rec = signatures[i];
254
+ const result = verifySingleSignature(rec, i, eventsBySeq, options.chain_id, options.trust_roots, actualWhen);
255
+ results.push(result);
256
+ const seqList = perSeqStatuses.get(rec.signed_seq) ?? [];
257
+ seqList.push(result.status);
258
+ perSeqStatuses.set(rec.signed_seq, seqList);
259
+ const modeSet = perSeqModes.get(rec.signed_seq) ?? new Set();
260
+ modeSet.add(rec.signature_mode);
261
+ perSeqModes.set(rec.signed_seq, modeSet);
262
+ }
263
+ const perSeqStatus = mergeStatusAtSeq(perSeqStatuses);
264
+ let signatureStatus;
265
+ if (signatures.length === 0) {
266
+ signatureStatus = 'unsigned';
267
+ }
268
+ else {
269
+ // Bundle-level = worst (highest rank) status across signed seqs.
270
+ let worst = 'valid';
271
+ let worstRank = STATUS_RANK.valid;
272
+ for (const s of perSeqStatus.values()) {
273
+ const r = STATUS_RANK[s];
274
+ if (r > worstRank) {
275
+ worst = s;
276
+ worstRank = r;
277
+ }
278
+ }
279
+ signatureStatus = worst;
280
+ }
281
+ const signedSegmentCount = computeSignedSegmentCount(events, perSeqStatus, perSeqModes);
282
+ let firstBadIdx = null;
283
+ for (const r of results) {
284
+ if (r.status !== 'valid') {
285
+ firstBadIdx = r.record_index;
286
+ break;
287
+ }
288
+ }
289
+ return {
290
+ signature_status: signatureStatus,
291
+ signature_results: results,
292
+ signed_segment_count: signedSegmentCount,
293
+ first_bad_signature_index: firstBadIdx,
294
+ };
295
+ }
296
+ export function verifyChainFull(events, options = {}) {
297
+ const anchors = options.anchors ?? [];
298
+ const signatures = options.signatures ?? [];
299
+ const anchorOpts = {
300
+ ...(options.anchor_options ?? {}),
301
+ ...(options.verification_time !== undefined
302
+ ? { verificationTime: options.verification_time }
303
+ : {}),
304
+ };
305
+ const anchorResult = verifyChainWithAnchors(events, anchors, anchorOpts);
306
+ let sigStatus = 'unsigned';
307
+ let sigResults = [];
308
+ let signedCount = 0;
309
+ let firstBad = null;
310
+ if (signatures.length > 0) {
311
+ if (!options.chain_id || !options.trust_roots) {
312
+ throw new SigningError('verifyChainFull: signatures provided but chain_id or trust_roots is missing');
313
+ }
314
+ const sigOpts = {
315
+ chain_id: options.chain_id,
316
+ trust_roots: options.trust_roots,
317
+ ...(options.verification_time !== undefined
318
+ ? { verification_time: options.verification_time }
319
+ : {}),
320
+ };
321
+ const sigOut = verifyChainWithSignatures(events, signatures, sigOpts);
322
+ sigStatus = sigOut.signature_status;
323
+ sigResults = sigOut.signature_results;
324
+ signedCount = sigOut.signed_segment_count;
325
+ firstBad = sigOut.first_bad_signature_index;
326
+ }
327
+ return {
328
+ chain_ok: anchorResult.chain_ok,
329
+ chain_reason: anchorResult.chain_reason,
330
+ anchored_seqs: anchorResult.anchored_seqs,
331
+ unanchored_seqs: anchorResult.unanchored_seqs,
332
+ anchor_results: anchorResult.anchor_results,
333
+ signature_status: sigStatus,
334
+ signature_results: sigResults,
335
+ signed_segment_count: signedCount,
336
+ first_bad_signature_index: firstBad,
337
+ ok: anchorResult.chain_ok && anchorResult.anchor_results.every((a) => a.valid),
338
+ };
339
+ }
340
+ //# sourceMappingURL=verifier_ext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifier_ext.js","sourceRoot":"","sources":["../../src/signing/verifier_ext.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * High-level proof-bundle verifier (TypeScript port of
3
+ * `sdk/python/src/attestplane/verifier.py`).
4
+ *
5
+ * Takes a parsed bundle object, performs a lightweight shape check
6
+ * (sufficient to safely rehydrate; callers needing full JSON Schema
7
+ * validation can run any standard validator against
8
+ * `schemas/v1/proof_bundle.schema.json`), rehydrates the contained
9
+ * events, re-walks the chain with `verifyChain`, and returns a
10
+ * `BundleVerificationResult`.
11
+ *
12
+ * Pure with respect to the bundle: no mutation, no signing, no I/O
13
+ * other than optionally reading a file when using `verifyProofBundleFile`.
14
+ */
15
+ import { type VerificationResult } from './hashchain.js';
16
+ export declare class BundleVerificationError extends Error {
17
+ constructor(message: string);
18
+ }
19
+ export declare class BundleSchemaError extends BundleVerificationError {
20
+ constructor(message: string);
21
+ }
22
+ export interface BundleVerificationResult {
23
+ readonly ok: boolean;
24
+ readonly chain_result: VerificationResult;
25
+ readonly bundle_reported_ok: boolean;
26
+ readonly agreement: boolean;
27
+ readonly event_count: number;
28
+ readonly bundle_version: number;
29
+ readonly chain_id: string;
30
+ readonly head_hash_hex: string;
31
+ readonly metadata_ok: boolean;
32
+ readonly metadata_reason: string | null;
33
+ readonly policy_trace_refs_ok: boolean;
34
+ readonly policy_trace_refs_reason: string | null;
35
+ }
36
+ export declare function shortSummary(result: BundleVerificationResult): string;
37
+ export declare function verifyProofBundle(raw: unknown): BundleVerificationResult;
38
+ export declare function verifyProofBundleFile(path: string): Promise<BundleVerificationResult>;
39
+ //# sourceMappingURL=verifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifier.d.ts","sourceRoot":"","sources":["../src/verifier.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AAKH,OAAO,EAGL,KAAK,kBAAkB,EAGxB,MAAM,gBAAgB,CAAC;AAUxB,qBAAa,uBAAwB,SAAQ,KAAK;gBACpC,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,iBAAkB,SAAQ,uBAAuB;gBAChD,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,YAAY,EAAE,kBAAkB,CAAC;IAC1C,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;IACrC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAC;IACvC,QAAQ,CAAC,wBAAwB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClD;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,wBAAwB,GAAG,MAAM,CAcrE;AAiUD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,wBAAwB,CAwBxE;AAED,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAkB3F"}