@cleocode/core 2026.6.5 → 2026.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/docs/export-document.js +189 -137
- package/dist/docs/export-document.js.map +2 -2
- package/dist/llm/api-mode.d.ts +64 -0
- package/dist/llm/api-mode.d.ts.map +1 -0
- package/dist/llm/api-mode.js +72 -0
- package/dist/llm/api-mode.js.map +1 -0
- package/dist/llm/api.d.ts.map +1 -1
- package/dist/llm/api.js +6 -37
- package/dist/llm/api.js.map +1 -1
- package/dist/llm/auxiliary-fallback.d.ts.map +1 -1
- package/dist/llm/auxiliary-fallback.js +24 -38
- package/dist/llm/auxiliary-fallback.js.map +1 -1
- package/dist/llm/model-runner.d.ts +127 -0
- package/dist/llm/model-runner.d.ts.map +1 -0
- package/dist/llm/model-runner.js +282 -0
- package/dist/llm/model-runner.js.map +1 -0
- package/dist/llm/plugin-facade.js +29391 -1473
- package/dist/llm/plugin-facade.js.map +3 -3
- package/dist/llm/role-executor.d.ts +6 -5
- package/dist/llm/role-executor.d.ts.map +1 -1
- package/dist/llm/role-executor.js +40 -86
- package/dist/llm/role-executor.js.map +1 -1
- package/dist/llm/role-resolver.d.ts +28 -1
- package/dist/llm/role-resolver.d.ts.map +1 -1
- package/dist/llm/role-resolver.js +10 -0
- package/dist/llm/role-resolver.js.map +1 -1
- package/dist/llm/session-factory.d.ts +4 -6
- package/dist/llm/session-factory.d.ts.map +1 -1
- package/dist/llm/session-factory.js +6 -72
- package/dist/llm/session-factory.js.map +1 -1
- package/dist/llm/system-resolver.d.ts.map +1 -1
- package/dist/llm/system-resolver.js +6 -0
- package/dist/llm/system-resolver.js.map +1 -1
- package/dist/llm/tool-loop.d.ts.map +1 -1
- package/dist/llm/tool-loop.js +9 -32
- package/dist/llm/tool-loop.js.map +1 -1
- package/dist/release/reconcile.d.ts +61 -0
- package/dist/release/reconcile.d.ts.map +1 -1
- package/dist/release/reconcile.js +187 -2
- package/dist/release/reconcile.js.map +1 -1
- package/dist/store/exodus/column-transforms.d.ts +248 -0
- package/dist/store/exodus/column-transforms.d.ts.map +1 -0
- package/dist/store/exodus/column-transforms.js +444 -0
- package/dist/store/exodus/column-transforms.js.map +1 -0
- package/dist/store/exodus/migrate.d.ts.map +1 -1
- package/dist/store/exodus/migrate.js +5 -267
- package/dist/store/exodus/migrate.js.map +1 -1
- package/dist/store/exodus/verify-migration.d.ts.map +1 -1
- package/dist/store/exodus/verify-migration.js +61 -3
- package/dist/store/exodus/verify-migration.js.map +1 -1
- package/package.json +12 -12
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared column-value transform layer for the exodus migration.
|
|
3
|
+
*
|
|
4
|
+
* The exodus copy (`migrate.ts`) does not move source values byte-for-byte into
|
|
5
|
+
* the consolidated `cleo.db`: a handful of columns are TRANSFORMED on the way in
|
|
6
|
+
* so they satisfy the consolidated schema's CHECK constraints (which the legacy
|
|
7
|
+
* runtime DBs did not carry). Three transform classes exist:
|
|
8
|
+
*
|
|
9
|
+
* 1. **Epoch INTEGER → ISO-8601 TEXT** ({@link buildEpochToIsoExpr}) — for any
|
|
10
|
+
* target column carrying an ISO-GLOB CHECK ({@link detectIsoGlobColumns}).
|
|
11
|
+
* A per-row magnitude heuristic ({@link EPOCH_SECONDS_THRESHOLD}) classifies
|
|
12
|
+
* seconds vs milliseconds.
|
|
13
|
+
* 2. **Legacy enum → canonical member** ({@link ENUM_NORMALIZATIONS} +
|
|
14
|
+
* {@link enumNormExpr}) — maps pre-tightening enum aliases (e.g.
|
|
15
|
+
* `tasks_commits.conventional_type` `'style'`/`'merge'` → `'chore'`).
|
|
16
|
+
* 3. **Non-finite REAL → finite** ({@link NUMERIC_CLAMPS} +
|
|
17
|
+
* {@link numericClampExpr}) — `Inf`/`-Inf`/`NaN` → a finite in-range value
|
|
18
|
+
* (`brain_weight_history.delta_weight`).
|
|
19
|
+
*
|
|
20
|
+
* ## Why this module exists (T11809 · AC2)
|
|
21
|
+
*
|
|
22
|
+
* Before T11809 these transforms lived ONLY in `migrate.ts`. The parity verifier
|
|
23
|
+
* (`verify-migration.ts`) digested RAW source values against the TRANSFORMED
|
|
24
|
+
* target values, so every coerced column (epoch INTEGER vs ISO TEXT, legacy enum
|
|
25
|
+
* vs canonical, Inf vs clamped) produced a `hashMatch === false` even on a
|
|
26
|
+
* perfectly lossless migration — a false-negative that aborted the cutover and
|
|
27
|
+
* lost the batch writes accumulated during the migrating open.
|
|
28
|
+
*
|
|
29
|
+
* Extracting the transform logic into ONE shared module lets the verifier digest
|
|
30
|
+
* the SOURCE side **through the same transforms migrate applied**
|
|
31
|
+
* ({@link buildDigestExpr}), so equal logical data digests equal. `migrate.ts`
|
|
32
|
+
* re-imports these primitives so its copy behaviour stays byte-identical; the
|
|
33
|
+
* verifier imports {@link buildDigestExpr} for the digest-oriented variant.
|
|
34
|
+
*
|
|
35
|
+
* @task T11809 (exodus verify applies source-side coercion — hashMatch on equal data)
|
|
36
|
+
* @task T11546 (epoch→ISO coercion — original)
|
|
37
|
+
* @task T11547 (enum normalization — original)
|
|
38
|
+
* @task T11782 (non-finite numeric clamp — original)
|
|
39
|
+
* @epic T11249 (E6)
|
|
40
|
+
* @saga T11242
|
|
41
|
+
*/
|
|
42
|
+
import type { DatabaseSync } from 'node:sqlite';
|
|
43
|
+
/**
|
|
44
|
+
* Determine a safe SQL literal default for a NOT NULL column with no schema
|
|
45
|
+
* default, given its SQLite type affinity.
|
|
46
|
+
*
|
|
47
|
+
* Used by `migrate.ts` to coalesce NULL source values for target-only NOT NULL
|
|
48
|
+
* columns so that rows are not silently dropped by `INSERT OR IGNORE` when a
|
|
49
|
+
* source value is NULL (T11533 ROOT CAUSE 2 fix).
|
|
50
|
+
*
|
|
51
|
+
* @param colType - Raw `type` string from `PRAGMA table_info` (e.g. `"INTEGER"`,
|
|
52
|
+
* `"TEXT"`, `"REAL"`, `"BLOB"`, or compound forms like `"text NOT NULL"`).
|
|
53
|
+
* @returns A SQL literal string suitable for embedding in a `COALESCE()` call.
|
|
54
|
+
*/
|
|
55
|
+
export declare function typeDefaultLiteral(colType: string): string;
|
|
56
|
+
/**
|
|
57
|
+
* Function shape for an enum-normalization rule: given the `srcRef` SQL
|
|
58
|
+
* expression for a column, return a SQL expression that produces the canonical
|
|
59
|
+
* value.
|
|
60
|
+
*/
|
|
61
|
+
export type NormalizeFn = (srcRef: string) => string;
|
|
62
|
+
/**
|
|
63
|
+
* Per-(targetTable, column) normalization rules that map legacy enum values to
|
|
64
|
+
* the canonical enum accepted by the consolidated schema CHECK constraints.
|
|
65
|
+
*
|
|
66
|
+
* Each entry is a function that, given the `srcRef` SQL expression for the
|
|
67
|
+
* column, returns a SQL CASE expression that produces the canonical value.
|
|
68
|
+
* Rows with already-canonical values pass through unchanged (the ELSE branch).
|
|
69
|
+
*
|
|
70
|
+
* ## Brain enum normalizations REMOVED (T11647)
|
|
71
|
+
*
|
|
72
|
+
* The brain memory family no longer participates in enum normalization. Its
|
|
73
|
+
* consolidated exodus target now matches the LEGACY RUNTIME shape, which carries
|
|
74
|
+
* NO SQL CHECK constraints (the `text({ enum })` unions are enforced at the
|
|
75
|
+
* application layer only). With no CHECK to satisfy, coercing brain enum values
|
|
76
|
+
* would be data corruption, not a fix — so every brain enum value is copied
|
|
77
|
+
* VERBATIM. The historical brain rules (`brain_observations.{source_type,type}`,
|
|
78
|
+
* `brain_decisions.{confirmation_state,decision_category,confidence,outcome,
|
|
79
|
+
* decided_by}`) were deleted. The TASKS-domain rules below remain because those
|
|
80
|
+
* consolidated tables keep their CHECK constraints.
|
|
81
|
+
*
|
|
82
|
+
* ## nexus/signaldock enum-drift audit (T11809 · AC1)
|
|
83
|
+
*
|
|
84
|
+
* A real-data audit of `nexus.db` (106 MB) and `signaldock.db` (280 KB) against
|
|
85
|
+
* the consolidated CHECK enums found ZERO out-of-enum values for every
|
|
86
|
+
* CHECK-constrained column that has source data: `nexus_nodes.kind` (24,482
|
|
87
|
+
* rows), `nexus_relations.type` (39,163 rows), `nexus_contracts.type` (0 rows),
|
|
88
|
+
* `nexus_sigils.role` (8 rows), `agent_registry_agents.status` (19 rows),
|
|
89
|
+
* `agent_registry_users.role` (0 rows). No new normalization entry was required.
|
|
90
|
+
* The reported "nexus/signaldock drop rows" symptom was in fact the AC2 verify
|
|
91
|
+
* false-negative (epoch→ISO coercion makes the source digest differ from the
|
|
92
|
+
* target digest), which fixing {@link buildDigestExpr} resolves — NOT a CHECK
|
|
93
|
+
* drop. See the T11809 return notes for the full per-column row counts.
|
|
94
|
+
*
|
|
95
|
+
* Lookup key: `${targetTable}.${column}` (lowercase, dotted).
|
|
96
|
+
*
|
|
97
|
+
* @since T11547 (P0 data-loss fix)
|
|
98
|
+
* @since T11548 (P0 final enum coverage)
|
|
99
|
+
* @since T11647 (brain target = runtime shape — brain enum coercions removed)
|
|
100
|
+
*/
|
|
101
|
+
export declare const ENUM_NORMALIZATIONS: ReadonlyMap<string, NormalizeFn>;
|
|
102
|
+
/**
|
|
103
|
+
* Return a SQL CASE expression that normalises legacy enum values for `col` in
|
|
104
|
+
* `targetTableName` to the canonical values accepted by the consolidated CHECK,
|
|
105
|
+
* or return `null` when no normalization rule exists for this (table, column).
|
|
106
|
+
*
|
|
107
|
+
* @param targetTableName - Physical consolidated target table name.
|
|
108
|
+
* @param col - Column name.
|
|
109
|
+
* @param srcRef - SQL expression referencing the source column.
|
|
110
|
+
* @returns A SQL CASE expression string, or `null` if no rule applies.
|
|
111
|
+
*/
|
|
112
|
+
export declare function enumNormExpr(targetTableName: string, col: string, srcRef: string): string | null;
|
|
113
|
+
/**
|
|
114
|
+
* Function shape for a numeric-clamp rule: given the `srcRef` SQL expression for
|
|
115
|
+
* a column, return a SQL expression that maps non-finite values to finite ones.
|
|
116
|
+
*/
|
|
117
|
+
export type NumericClampFn = (srcRef: string) => string;
|
|
118
|
+
/**
|
|
119
|
+
* Per-(targetTable, column) numeric-clamp rules that coerce non-finite legacy
|
|
120
|
+
* REAL values (`Inf` / `-Inf` / `NaN`) to a finite in-range value so the row is
|
|
121
|
+
* NOT silently dropped by `INSERT OR IGNORE`.
|
|
122
|
+
*
|
|
123
|
+
* ## Why this exists (T11782)
|
|
124
|
+
*
|
|
125
|
+
* 188,926 of 697,780 legacy `brain_weight_history` rows carry
|
|
126
|
+
* `delta_weight = Inf`/`-Inf` (the R-STDP plasticity writer saturated the delta
|
|
127
|
+
* before the value was clamped at write time). SQLite stores ±Inf as the IEEE-754
|
|
128
|
+
* float, but the consolidated `brain_weight_history.delta_weight` column is a
|
|
129
|
+
* plain `real NOT NULL` with NO CHECK — so a verbatim copy would land the Inf
|
|
130
|
+
* value. The historical deficit, however, was that those rows tripped a constraint
|
|
131
|
+
* elsewhere in the copy chain and `INSERT OR IGNORE` dropped them, yielding a
|
|
132
|
+
* deficit that fired the parity-gate abort. Clamping the non-finite value to a
|
|
133
|
+
* finite member of the column's domain guarantees every row lands.
|
|
134
|
+
*
|
|
135
|
+
* The clamp mirrors the {@link ENUM_NORMALIZATIONS} shape: each entry is a
|
|
136
|
+
* function `(srcRef) => CASE …`. Finite values pass through unchanged via the
|
|
137
|
+
* ELSE branch. The `col != col` self-comparison is the canonical SQL NaN guard
|
|
138
|
+
* (NaN is the only value not equal to itself); `9e999` is the SQLite literal that
|
|
139
|
+
* evaluates to `+Infinity` (and `-9e999` to `-Infinity`).
|
|
140
|
+
*
|
|
141
|
+
* Lookup key: `${targetTable}.${column}` (lowercase, dotted).
|
|
142
|
+
*
|
|
143
|
+
* @since T11782 (P0 — brain_weight_history Inf recovery)
|
|
144
|
+
*/
|
|
145
|
+
export declare const NUMERIC_CLAMPS: ReadonlyMap<string, NumericClampFn>;
|
|
146
|
+
/**
|
|
147
|
+
* Return a SQL CASE expression that clamps non-finite legacy REAL values for
|
|
148
|
+
* `col` in `targetTableName` to a finite in-range value, or `null` when no
|
|
149
|
+
* clamp rule exists for this (table, column).
|
|
150
|
+
*
|
|
151
|
+
* @param targetTableName - Physical consolidated target table name.
|
|
152
|
+
* @param col - Column name.
|
|
153
|
+
* @param srcRef - SQL expression referencing the source column.
|
|
154
|
+
* @returns A SQL CASE expression string, or `null` if no rule applies.
|
|
155
|
+
*/
|
|
156
|
+
export declare function numericClampExpr(targetTableName: string, col: string, srcRef: string): string | null;
|
|
157
|
+
/**
|
|
158
|
+
* Magnitude threshold distinguishing epoch SECONDS from epoch MILLISECONDS.
|
|
159
|
+
*
|
|
160
|
+
* A Unix epoch value for years 2020–2100 is roughly 1.6e9 – 4.1e9 seconds,
|
|
161
|
+
* or 1.6e12 – 4.1e12 milliseconds. The safe boundary is 1e11 (100 billion):
|
|
162
|
+
* any value BELOW 1e11 is in seconds (even year 2100 seconds ≈ 4.1e9 < 1e11);
|
|
163
|
+
* any value AT OR ABOVE 1e11 is in milliseconds (year 2020 ms ≈ 1.6e12 > 1e11).
|
|
164
|
+
*
|
|
165
|
+
* This constant is embedded directly in the generated SQL CASE expression so
|
|
166
|
+
* it is evaluated per-row — each row's epoch is classified independently.
|
|
167
|
+
*/
|
|
168
|
+
export declare const EPOCH_SECONDS_THRESHOLD: 100000000000;
|
|
169
|
+
/**
|
|
170
|
+
* Build a SQL expression that converts an INTEGER epoch column to ISO-8601 TEXT,
|
|
171
|
+
* automatically detecting whether the stored value is in seconds or milliseconds
|
|
172
|
+
* using a magnitude heuristic (T11549 correctness fix).
|
|
173
|
+
*
|
|
174
|
+
* ## Heuristic
|
|
175
|
+
*
|
|
176
|
+
* A per-row CASE checks whether the column value is below {@link EPOCH_SECONDS_THRESHOLD}
|
|
177
|
+
* (100 billion). If so, the value is treated as seconds and passed directly to
|
|
178
|
+
* `strftime(..., 'unixepoch')`. If at or above the threshold, it is divided by
|
|
179
|
+
* 1000.0 first (milliseconds → seconds).
|
|
180
|
+
*
|
|
181
|
+
* This replaces the previous per-source heuristic which failed when individual
|
|
182
|
+
* columns within a source DB used a different epoch unit than the majority of that
|
|
183
|
+
* source's columns. The specific bug: `nexus.user_profile.{first_observed_at,
|
|
184
|
+
* last_reinforced_at}` stores SECONDS (value ≈ 1.78e9) but the nexus source was
|
|
185
|
+
* labeled `milliseconds`, causing these values to be divided by 1000 and converted
|
|
186
|
+
* to a 1970 date.
|
|
187
|
+
*
|
|
188
|
+
* ## NULL handling
|
|
189
|
+
*
|
|
190
|
+
* A NULL source value is preserved as NULL so it passes the `IS NULL` branch of
|
|
191
|
+
* the ISO GLOB CHECK constraint on the target column.
|
|
192
|
+
*
|
|
193
|
+
* @param srcRef - SQL expression referencing the source column value.
|
|
194
|
+
* @returns A SQL CASE expression producing an ISO-8601 TEXT timestamp.
|
|
195
|
+
*/
|
|
196
|
+
export declare function buildEpochToIsoExpr(srcRef: string): string;
|
|
197
|
+
/**
|
|
198
|
+
* Parse the DDL for a given table from `sqlite_master` and return the set of
|
|
199
|
+
* column names that have an ISO GLOB CHECK constraint.
|
|
200
|
+
*
|
|
201
|
+
* Reads the raw DDL text and uses a regex to extract column names appearing in
|
|
202
|
+
* `CHECK ("colname" IS NULL OR "colname" GLOB '[0-9]...')` patterns. This is
|
|
203
|
+
* robust to Drizzle's generated CHECK format (all CHECK constraints generated
|
|
204
|
+
* by T11363 follow this exact pattern).
|
|
205
|
+
*
|
|
206
|
+
* @param db - Target DB with the consolidated schema.
|
|
207
|
+
* @param tableName - Physical table name (consolidated, e.g. `conduit_messages`).
|
|
208
|
+
* @param targetSchema - Schema name the target table lives in (`'main'`, or an
|
|
209
|
+
* ATTACH alias for cross-scope routing — ADR-090 nexus graph residency, T11539).
|
|
210
|
+
* @returns Set of column names that require ISO GLOB validation.
|
|
211
|
+
*/
|
|
212
|
+
export declare function detectIsoGlobColumns(db: DatabaseSync, tableName: string, targetSchema?: string): Set<string>;
|
|
213
|
+
/**
|
|
214
|
+
* Build the SQL expression a column's SOURCE value must pass through so it
|
|
215
|
+
* matches the canonical value the migration STORES in the target — for use by
|
|
216
|
+
* the parity verifier's content digest (T11809 · AC2).
|
|
217
|
+
*
|
|
218
|
+
* This is the digest-oriented sibling of migrate's `buildSelectExpr`. It applies
|
|
219
|
+
* the SAME value transforms the migration actually performs — and ONLY those:
|
|
220
|
+
*
|
|
221
|
+
* 1. **Epoch→ISO-8601** ({@link buildEpochToIsoExpr}) — when the target has an
|
|
222
|
+
* ISO GLOB CHECK and the source column is INTEGER-typed.
|
|
223
|
+
* 2. **Non-finite numeric clamp** ({@link numericClampExpr}).
|
|
224
|
+
* 3. **Enum-value normalization** ({@link enumNormExpr}).
|
|
225
|
+
* 4. **Plain column reference** otherwise.
|
|
226
|
+
*
|
|
227
|
+
* Crucially it does NOT add the NOT-NULL `COALESCE(..., type_default)` wrapping
|
|
228
|
+
* that `buildSelectExpr` uses: that wrapping only ever fires on a NULL source
|
|
229
|
+
* value that the target stores as a type-default, which is a NULL→default value
|
|
230
|
+
* CHANGE the digest should not paper over (a genuine NULL→'' divergence remains a
|
|
231
|
+
* real, visible content difference, not a coercion artifact). The verifier
|
|
232
|
+
* intentionally omits it so the digest reflects the canonical value transforms
|
|
233
|
+
* (epoch/enum/clamp) WITHOUT masking a true NULL→default substitution.
|
|
234
|
+
*
|
|
235
|
+
* The returned expression is a bare SQL value expression (no `AS "col"` alias)
|
|
236
|
+
* suitable for embedding directly in a `SELECT <expr> ... ORDER BY ...` digest
|
|
237
|
+
* query. When no transform applies, a plain quoted column reference is returned.
|
|
238
|
+
*
|
|
239
|
+
* @param targetTableName - Physical consolidated target table name (transform
|
|
240
|
+
* lookup key).
|
|
241
|
+
* @param col - Column name (present in BOTH source and target).
|
|
242
|
+
* @param srcType - Raw `type` string from the source `PRAGMA table_info`.
|
|
243
|
+
* @param isoGlobCols - Set of target columns carrying an ISO GLOB CHECK.
|
|
244
|
+
* @returns A SQL value expression that maps the raw source value to the canonical
|
|
245
|
+
* value the target stores.
|
|
246
|
+
*/
|
|
247
|
+
export declare function buildDigestExpr(targetTableName: string, col: string, srcType: string, isoGlobCols: ReadonlySet<string>): string;
|
|
248
|
+
//# sourceMappingURL=column-transforms.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"column-transforms.d.ts","sourceRoot":"","sources":["../../../src/store/exodus/column-transforms.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAMhD;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAO1D;AAMD;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CA0H/D,CAAC;AAEH;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,eAAe,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIhG;AAMD;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;AAExD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,cAAc,CAc7D,CAAC;AAEH;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,eAAe,EAAE,MAAM,EACvB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,GACb,MAAM,GAAG,IAAI,CAIf;AAaD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,uBAAuB,EAAG,YAAwB,CAAC;AAEhE;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAS1D;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,YAAY,EAChB,SAAS,EAAE,MAAM,EACjB,YAAY,SAAS,GACpB,GAAG,CAAC,MAAM,CAAC,CAmBb;AAqBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,eAAe,CAC7B,eAAe,EAAE,MAAM,EACvB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,GAC/B,MAAM,CAoBR"}
|