usertrust-verify 1.5.0 → 2.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.
package/README.md CHANGED
@@ -22,6 +22,38 @@ All hashes: valid (847/847)
22
22
  - **Head anchor** — the fsync'd `events.jsonl.meta` sidecar records the last hash and the total event count. The verifier fails if the log has been **truncated or deleted** (a shorter-but-internally-consistent chain no longer passes).
23
23
  - **Segment continuity** — a rotated vault (multiple `*.jsonl` segments) is verified as one continuous chain by sequence number; a missing whole segment is detected as a sequence gap.
24
24
  - **Merkle root** — recomputes the RFC 6962 root over the event hashes.
25
+ - **External anchors** (optional) — binds the vault to Ed25519-signed checkpoints held in an append-only store the vault operator cannot rewrite. This upgrades the guarantee from *tamper-evident if you trust the operator's files* to **independently verifiable**: even a fully re-hashed, internally-consistent rewrite fails against the externally-held root.
26
+
27
+ ## Verify against external anchors
28
+
29
+ You fetch the checkpoint(s) from the operator's append-only store yourself (`aws s3 cp`, `git show`, a SIEM export) and pin the vault's public key **out-of-band** — the verifier deliberately never reads trust material from the vault under audit, and works fully offline.
30
+
31
+ ```bash
32
+ # Full checkpoint history (strongest)
33
+ usertrust-verify .usertrust --anchors anchors.jsonl --pubkey root.pem
34
+
35
+ # Single checkpoint via stdin
36
+ aws s3 cp s3://…/000000000042.json - | usertrust-verify .usertrust --anchor - --pubkey root.pem
37
+
38
+ # CI gate: externally anchored, fresh, verified — or exit 1
39
+ usertrust-verify .usertrust --anchors anchors.jsonl --pubkey root.pem \
40
+ --require-anchor --require-external-anchor --max-unanchored-events 5000
41
+
42
+ # Transparency-log receipts (repeatable; JSON or JSONL; - = stdin)
43
+ usertrust-verify .usertrust --anchors anchors.jsonl --pubkey root.pem \
44
+ --rekor-receipts .usertrust/audit/anchors/rekor/000000000042.json
45
+
46
+ # A self-hosted log needs its key pinned too (repeatable — any pinned key may verify)
47
+ usertrust-verify .usertrust --anchors anchors.jsonl --pubkey root.pem \
48
+ --rekor-receipts receipts.jsonl --rekor-pubkey rekor-internal.pem
49
+
50
+ # One operator-supplied handoff file: usertrust anchor export-bundle
51
+ usertrust-verify .usertrust --bundle audit-bundle.json --pubkey root.pem
52
+ ```
53
+
54
+ `--rekor-receipts` verification is offline and fail-closed: the signed-note checkpoint and its ECDSA P-256 signature, an RFC 9162 inclusion proof, and the binding of the log entry to your record all have to check out, or you get `ANCHOR_INVALID` (reason `rekor-receipt-invalid`) and exit 1. A verified receipt also makes `--max-anchor-age` measure against the log's attested `integratedTime` instead of the operator's own timestamp. Without `--rekor-pubkey`, the embedded rekor.sigstore.dev key is used **only** for receipts whose log host is `rekor.sigstore.dev`; any other log must be pinned explicitly. `--bundle` takes `{v:1, records, rekorReceipts}` and is parsed strictly — unknown fields, a version other than 1, or oversized lists are errors.
55
+
56
+ Result states: `ANCHORED_VERIFIED`, `UNANCHORED` (legacy vaults — valid, weaker, labeled), `ANCHOR_UNVERIFIABLE`, `ANCHOR_STALE`, and the hard failures `ANCHOR_INVALID` / `ANCHOR_MISMATCH` (rewrite, rollback, deletion, or fork against the signed checkpoints — always exit 1). After a key rotation, keep pinning the original root key and pass the announced successor fingerprints with `--successor-pin`. See the [anchoring guide](https://github.com/usertools-ai/usertrust/blob/master/docs/anchoring.md) for the operator side.
25
57
 
26
58
  ## Exit codes (CI-safe)
27
59
 
@@ -55,6 +87,18 @@ if (!result.valid) {
55
87
  }
56
88
  ```
57
89
 
90
+ With external anchors:
91
+
92
+ ```typescript
93
+ import { verifyVaultWithAnchors, exitCodeForAnchored } from "usertrust-verify";
94
+
95
+ const result = verifyVaultWithAnchors(".usertrust", {
96
+ externalAnchorsRaw: [anchorsJsonl], // fetched by YOU, not by the verifier
97
+ trust: { rootPem: pinnedPublicKeyPem }, // pinned out-of-band, never from the vault
98
+ });
99
+ process.exit(exitCodeForAnchored(result, { requireExternalAnchor: true }));
100
+ ```
101
+
58
102
  `verifyVault` re-implements canonicalization and hashing independently of `usertrust` and must stay byte-for-byte identical to the writer — a differential test in the repo pins that invariant.
59
103
 
60
104
  ## License
@@ -0,0 +1,229 @@
1
+ /**
2
+ * External Anchor Verification — Zero-dependency standalone
3
+ *
4
+ * INTENTIONAL DUPLICATION: this file exists byte-for-byte in BOTH
5
+ * packages/verify/src/anchor-verify.ts and
6
+ * packages/core/src/audit/anchor-verify.ts — only the import paths differ.
7
+ * The anchor differential/parity tests pin the two together; any change must
8
+ * land in both packages.
9
+ *
10
+ * Verifies signed anchor checkpoints (spec: docs/superpowers/specs/
11
+ * 2026-07-26-external-anchoring-design.md) against a caller-pinned trust root:
12
+ * - strict record parsing (unknown fields / range violations are INVALID)
13
+ * - Ed25519 signature verification via node:crypto (ECDSA P-256 helper kept
14
+ * alg-agile for Phase 2 transparency-log checkpoints)
15
+ * - anchor-chain verification: prevAnchorHash linkage, anchorSeq contiguity,
16
+ * key epochs via cross-signed rotation records, fork/duplicate semantics
17
+ * - vault binding: Merkle root / head hash at each anchored treeSize, with
18
+ * externally-bound consistency proofs between anchors
19
+ * - the spec §7.2 state machine (UNANCHORED / ANCHORED_VERIFIED / ANCHOR_STALE
20
+ * / ANCHOR_UNVERIFIABLE / ANCHOR_INVALID / ANCHOR_MISMATCH)
21
+ *
22
+ * Trust NEVER comes from the vault under audit: the caller pins the genesis
23
+ * root key (and optional rotation-successor pins) out-of-band.
24
+ */
25
+ import { type KeyObject } from "node:crypto";
26
+ import { type MerkleInclusionProof } from "./verify.js";
27
+ export interface AnchorRotation {
28
+ readonly nextKeyId: string;
29
+ readonly nextPublicKeySpki: string;
30
+ }
31
+ export interface AnchorRecord {
32
+ readonly v: 1;
33
+ readonly vaultId: string;
34
+ readonly anchorSeq: number;
35
+ readonly prevAnchorHash: string;
36
+ readonly treeSize: number;
37
+ readonly lastHash: string;
38
+ readonly merkleRoot: string;
39
+ readonly timestamp: string;
40
+ readonly keyId: string;
41
+ readonly rotation?: AnchorRotation;
42
+ readonly sig: string;
43
+ }
44
+ /** Caller-pinned trust material. NEVER read from the vault under audit. */
45
+ export interface AnchorTrust {
46
+ /** THE pinned genesis root key (PEM). anchorSeq 1 MUST verify under it. */
47
+ readonly rootPem: string;
48
+ /** Optional out-of-band pins for rotation successors. */
49
+ readonly successorPinsPem?: readonly string[];
50
+ }
51
+ export type AnchorState = "UNANCHORED" | "ANCHORED_VERIFIED" | "ANCHOR_STALE" | "ANCHOR_UNVERIFIABLE" | "ANCHOR_INVALID" | "ANCHOR_MISMATCH";
52
+ export type AnchorSource = "external" | "vault-mirror" | "none";
53
+ export type WitnessStatus = "agrees" | "disagrees" | "unreachable" | "not-consulted";
54
+ export interface WitnessInput {
55
+ readonly requested: boolean;
56
+ readonly ok?: boolean;
57
+ readonly error?: string;
58
+ }
59
+ export interface AnchorEvaluationOptions {
60
+ readonly maxAnchorAgeMs?: number;
61
+ readonly maxUnanchoredEvents?: number;
62
+ readonly expectedVaultId?: string;
63
+ /** Injectable clock for tests. Defaults to Date.now(). */
64
+ readonly nowMs?: number;
65
+ /**
66
+ * Witness-attested integration time (ms) for the NEWEST anchor, from a
67
+ * transparency-log receipt the caller already verified. When present it
68
+ * replaces the operator-claimed timestamp as the input to --max-anchor-age:
69
+ * it is the one time in the record the vault operator cannot choose.
70
+ */
71
+ readonly attestedTimeMs?: number;
72
+ }
73
+ export interface AnchorEvaluationInput {
74
+ /** Globally sequence-ordered stored event hashes (verifyVault ordering). */
75
+ readonly orderedHashes: readonly string[];
76
+ /** Caller-fetched external anchor records (already parsed). */
77
+ readonly externalAnchors: readonly AnchorRecord[];
78
+ /** Parse errors from caller-supplied artifacts (fail-closed). */
79
+ readonly externalErrors: readonly string[];
80
+ /** Records from the vault-local mirror — CACHE, never a trust root alone. */
81
+ readonly mirrorAnchors: readonly AnchorRecord[];
82
+ readonly mirrorErrors: readonly string[];
83
+ readonly trust: AnchorTrust | null;
84
+ readonly witness: WitnessInput;
85
+ readonly opts?: AnchorEvaluationOptions;
86
+ }
87
+ export interface AnchorEvaluation {
88
+ anchorState: AnchorState;
89
+ /** false only on ANCHOR_INVALID / ANCHOR_MISMATCH. */
90
+ anchorsValid: boolean;
91
+ anchorSource: AnchorSource;
92
+ anchorCount: number;
93
+ latestAnchor: {
94
+ anchorSeq: number;
95
+ treeSize: number;
96
+ lastHash: string;
97
+ keyId: string;
98
+ timestamp: string;
99
+ } | null;
100
+ unanchoredTail: {
101
+ events: number;
102
+ sinceTimestampMs: number | null;
103
+ };
104
+ witness: {
105
+ requested: boolean;
106
+ status: WitnessStatus;
107
+ error?: string;
108
+ };
109
+ reasons: string[];
110
+ warnings: string[];
111
+ errors: string[];
112
+ }
113
+ /**
114
+ * Strict parse of a single anchor record. Unknown fields, missing fields, and
115
+ * range violations are all rejected (fail-closed — spec §3 strict-parse rules;
116
+ * range checks run BEFORE any Merkle primitive so a validly-signed-but-
117
+ * degenerate record yields a deterministic verdict, never a throw).
118
+ * Returns `{ record }` or `{ error }` with a code-prefixed message.
119
+ */
120
+ export declare function parseAnchorRecord(raw: string): {
121
+ record: AnchorRecord | null;
122
+ error: string | null;
123
+ };
124
+ /** Parse a JSONL (or single-JSON) anchors artifact. Every line must parse. */
125
+ export declare function parseAnchorsContent(content: string): {
126
+ records: AnchorRecord[];
127
+ errors: string[];
128
+ };
129
+ /** Signing pre-image = canonicalize(record − sig). Spec §3. */
130
+ export declare function anchorSigningPreimage(record: AnchorRecord): string;
131
+ /** sha256 hex of the signing pre-image — what the successor's prevAnchorHash carries. */
132
+ export declare function anchorPayloadHash(record: AnchorRecord): string;
133
+ export declare function keyIdFromSpkiDer(der: Buffer): string;
134
+ export declare function publicKeyFromPem(pem: string): KeyObject | null;
135
+ export declare function publicKeyFromSpkiBase64(b64: string): KeyObject | null;
136
+ export declare function keyIdFromKeyObject(key: KeyObject): string;
137
+ /**
138
+ * Raw signature verification over UTF-8 data. Ed25519 for usertrust anchor
139
+ * records; ECDSA P-256 kept alg-agile for Phase 2 transparency-log checkpoints
140
+ * (Rekor signs with ECDSA — spec reconciliation R2). Never throws.
141
+ */
142
+ export declare function verifySignatureRaw(alg: "ed25519" | "ecdsa-p256", dataUtf8: string, publicKey: KeyObject, sigBase64: string): boolean;
143
+ /**
144
+ * Verify one record's Ed25519 signature against explicit candidate keys.
145
+ * The candidate whose keyId matches the record's keyId is used; a record whose
146
+ * keyId matches none of the candidates fails with a distinct error.
147
+ */
148
+ export declare function verifyAnchorSignature(record: AnchorRecord, candidateKeysPem: readonly string[]): {
149
+ ok: boolean;
150
+ keyId: string;
151
+ errors: string[];
152
+ };
153
+ /** Committed-field equality: everything except timestamp and sig. */
154
+ export declare function committedFieldsEqual(a: AnchorRecord, b: AnchorRecord): boolean;
155
+ /**
156
+ * Collapse same-anchorSeq records WITHIN one stream (store or mirror):
157
+ * identical committed content = benign duplicate (warn, keep first);
158
+ * divergent committed content = fork evidence (MISMATCH).
159
+ */
160
+ export declare function dedupeAnchorSet(records: readonly AnchorRecord[]): {
161
+ unique: AnchorRecord[];
162
+ /** Committed-equal twins collapsed out — still signature-checked by the walk. */
163
+ dropped: AnchorRecord[];
164
+ warnings: string[];
165
+ errors: string[];
166
+ mismatchReasons: string[];
167
+ };
168
+ export interface AnchorChainResult {
169
+ /** anchorSeq-ordered records that entered the walk. */
170
+ records: AnchorRecord[];
171
+ errors: string[];
172
+ /** ANCHOR_INVALID-class reason codes. */
173
+ invalidReasons: string[];
174
+ /** ANCHOR_MISMATCH-class reason codes. */
175
+ mismatchReasons: string[];
176
+ warnings: string[];
177
+ }
178
+ /**
179
+ * Verify the anchor stream as its own hash chain under the pinned trust root:
180
+ * signatures per key epoch (rotations walked forward from the root),
181
+ * prevAnchorHash linkage from GENESIS, anchorSeq contiguity from 1, treeSize
182
+ * monotonicity, single vaultId, and — when event hashes are supplied —
183
+ * consistency binding between consecutive anchored roots. The proof's
184
+ * firstRoot/secondRoot are compared to the SIGNED roots before
185
+ * verifyConsistencyProof is called: the bare call checks only internal proof
186
+ * consistency and passes unconditionally on locally generated proofs
187
+ * (spec §7.2 — omitting the binding recreates F1).
188
+ *
189
+ * Callers pass a set already deduped per stream (dedupeAnchorSet); same-seq
190
+ * survivors here are treated as forks.
191
+ */
192
+ export declare function verifyAnchorChain(records: readonly AnchorRecord[], trust: AnchorTrust, eventHashes?: readonly string[]): AnchorChainResult;
193
+ /**
194
+ * Gather the globally sequence-ordered stored event hashes of a vault, using
195
+ * the exact segment-gathering and ordering semantics of verifyVault
196
+ * (events.jsonl first, then every other *.jsonl sorted; order by persisted
197
+ * global `sequence` when every event has one, else file order). Malformed
198
+ * lines are skipped here — chain-level errors are verifyVault's job, not the
199
+ * anchor evaluator's.
200
+ */
201
+ export declare function gatherOrderedEventHashes(vaultPath: string): string[];
202
+ /** Read the vault-local anchor mirror (cache, never a trust root alone). */
203
+ export declare function readAnchorMirror(vaultPath: string): {
204
+ records: AnchorRecord[];
205
+ errors: string[];
206
+ };
207
+ /**
208
+ * The more severe of two states. Exported so callers layering evidence ON TOP
209
+ * of the state machine (the glue's Rekor receipts) escalate by the SAME
210
+ * severity ordering the machine itself uses, rather than hardcoding one.
211
+ */
212
+ export declare function worseAnchorState(a: AnchorState, b: AnchorState): AnchorState;
213
+ /**
214
+ * The spec §7.2 state machine. Pure function over gathered inputs so both
215
+ * packages (and the differential test) evaluate identically. Evaluation order
216
+ * per constraints §4.2: discover → trust check → parse/signature → content
217
+ * cross-checks → freshness; worst state wins. The witness-fetch-failure rule
218
+ * (AC-2.4) caps the state below ANCHORED_VERIFIED without discarding
219
+ * caller-supplied artifacts.
220
+ */
221
+ export declare function evaluateAnchoredVault(input: AnchorEvaluationInput): AnchorEvaluation;
222
+ /**
223
+ * Verify a Merkle inclusion proof against a SIGNED EXTERNAL anchor record —
224
+ * root and treeSize come from the record, never recomputed from the events
225
+ * under check (spec §7.1; closes F1). The record must verify under the pinned
226
+ * root or a supplied successor pin.
227
+ */
228
+ export declare function verifyInclusionAgainstAnchor(proof: MerkleInclusionProof, record: AnchorRecord, trust: AnchorTrust): boolean;
229
+ //# sourceMappingURL=anchor-verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anchor-verify.d.ts","sourceRoot":"","sources":["../src/anchor-verify.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAuD,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAKlG,OAAO,EAGN,KAAK,oBAAoB,EAGzB,MAAM,aAAa,CAAC;AAIrB,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC;IACd,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC;IACnC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACrB;AAED,2EAA2E;AAC3E,MAAM,WAAW,WAAW;IAC3B,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,yDAAyD;IACzD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9C;AAED,MAAM,MAAM,WAAW,GACpB,YAAY,GACZ,mBAAmB,GACnB,cAAc,GACd,qBAAqB,GACrB,gBAAgB,GAChB,iBAAiB,CAAC;AAErB,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,cAAc,GAAG,MAAM,CAAC;AAChE,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,WAAW,GAAG,aAAa,GAAG,eAAe,CAAC;AAErF,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,uBAAuB;IACvC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,0DAA0D;IAC1D,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,qBAAqB;IACrC,4EAA4E;IAC5E,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,+DAA+D;IAC/D,QAAQ,CAAC,eAAe,EAAE,SAAS,YAAY,EAAE,CAAC;IAClD,iEAAiE;IACjE,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,6EAA6E;IAC7E,QAAQ,CAAC,aAAa,EAAE,SAAS,YAAY,EAAE,CAAC;IAChD,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,IAAI,CAAC,EAAE,uBAAuB,CAAC;CACxC;AAED,MAAM,WAAW,gBAAgB;IAChC,WAAW,EAAE,WAAW,CAAC;IACzB,sDAAsD;IACtD,YAAY,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,YAAY,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE;QACb,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;KAClB,GAAG,IAAI,CAAC;IACT,cAAc,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACpE,OAAO,EAAE;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,aAAa,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACvE,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;CACjB;AAuDD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG;IAC/C,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB,CAoFA;AAED,8EAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG;IACrD,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,MAAM,EAAE,MAAM,EAAE,CAAC;CACjB,CAgBA;AAID,+DAA+D;AAC/D,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAGlE;AAED,yFAAyF;AACzF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAE9D;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAM9D;AAED,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAMrE;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAEzD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CACjC,GAAG,EAAE,SAAS,GAAG,YAAY,EAC7B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,MAAM,GACf,OAAO,CAeT;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACpC,MAAM,EAAE,YAAY,EACpB,gBAAgB,EAAE,SAAS,MAAM,EAAE,GACjC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAiBlD;AAID,qEAAqE;AACrE,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,GAAG,OAAO,CAM9E;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG;IAClE,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,iFAAiF;IACjF,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC1B,CAyBA;AAID,MAAM,WAAW,iBAAiB;IACjC,uDAAuD;IACvD,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,yCAAyC;IACzC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,0CAA0C;IAC1C,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAChC,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,KAAK,EAAE,WAAW,EAClB,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,GAC7B,iBAAiB,CAqNnB;AAID;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CA4CpE;AAED,4EAA4E;AAC5E,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG;IACpD,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,MAAM,EAAE,MAAM,EAAE,CAAC;CACjB,CAQA;AAaD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,GAAG,WAAW,CAE5E;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,qBAAqB,GAAG,gBAAgB,CAgPpF;AAID;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC3C,KAAK,EAAE,oBAAoB,EAC3B,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,WAAW,GAChB,OAAO,CAIT"}