@beehexa/hexasync-template-model 2608.15.1 → 2608.20.18

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.
@@ -1,195 +0,0 @@
1
- /**
2
- * A node's address — [AD-33](AD-33-node-addressing.md), decided by Jazz on 2026-08-10.
3
- *
4
- * An address is the **path to the node**, segments joined by `:`. It replaces three schemes that three
5
- * implementations invented independently, two of which were positional:
6
- *
7
- * | | scheme | how it failed |
8
- * | --- | --- | --- |
9
- * | VS Code extension | `n0`, `s0n0`, `g0`, `c0` | ordinal — every id shifts when step order changes |
10
- * | CLI + dashboard | `<stage>_<stepKey>`, plus `_D_<n>` / `_IF_<n>` for branches | stable for authored steps; the **branch counter is positional** |
11
- *
12
- * A counter re-numbers on an edit that renamed nothing, which is exactly the breakage a click contract exists to
13
- * prevent. A path does not: the diamond at `…:key_STEP:next:if` keeps that address however many steps are added
14
- * around it. **That is the whole argument**, and it is why AD-33 replaced an earlier recommendation to standardise
15
- * on `_D_<n>` — a recommendation that was itself the defect it criticised.
16
- *
17
- * ### Why this is in `model` and not in a flow package
18
- *
19
- * `objects:id_X:metrics:id_Y:facet:Z` is not a flow. It addresses **any** node in a profile, so it serves three
20
- * consumers at once: a diagram's click target, a provenance anchor, and the citation FR-24–28 needs for an MCP
21
- * resource. A flow package owning the scheme would force the other two to invent a second one.
22
- *
23
- * ### Two layers, because mermaid cannot hold a `:`
24
- *
25
- * | layer | form | example |
26
- * | --- | --- | --- |
27
- * | canonical address | `:`-joined | `pullers:id_**XPullerId**:pullSteps:key_GET_ORDERS:next:if` |
28
- * | rendered mermaid id | `:` → `__`, then sanitised | `pullers__id___XPullerId____pullSteps__key_GET_ORDERS__next__if` |
29
- *
30
- * The projection is safe because of a measurement, re-taken 2026-08-10 over every array-valued step stage in the
31
- * corpus (5,819 authored `key` values, 12,366 including `output.yaml`): **0 contain `:`** and **0 contain `__`**, in
32
- * both populations. So `__` is an unambiguous segment boundary and the round trip is lossless.
33
- *
34
- * ⚠️ The same re-measurement corrected AD-33's third claim: **1** key is not `[A-Za-z0-9_]` —
35
- * `!CHECK_EXISTS_ITEMS` — and the `!` is the composer's REMOVAL directive, not part of the name. Hence rule 6 and
36
- * `normalizeComponentKey` below. Read raw, that address would name a node the composer deletes.
37
- */
38
- import { normalizeComponentKey } from './componentKey.js';
39
- /** The separator between address segments. Measured absent from all 2,144+ authored keys. */
40
- export const ADDRESS_SEPARATOR = ':';
41
- /** What a `:` becomes when rendered into a mermaid id, which admits only `[A-Za-z0-9_]`. */
42
- export const RENDERED_SEPARATOR = '__';
43
- /** A key segment — `pullers`, `pullSteps`, `next`, `if`. */
44
- export const keySegment = (name) => ({
45
- kind: 'key',
46
- name,
47
- });
48
- /**
49
- * An identity segment, from a component's raw `id` or `key` value.
50
- *
51
- * ### `id_` carries the AUTHORED value, tokens and all
52
- *
53
- * Jazz's own example is `pullers:id_**LightspeedXSeriesPullerId**`, not the composed GUID. An address describes the
54
- * **source**, and the authored form is identical across environments where a resolved GUID is not. It renders as
55
- * `id___LightspeedXSeriesPullerId__`, which is ugly and harmless: nothing parses a rendered id for navigation,
56
- * because the node index carries file, location and source text.
57
- *
58
- * Returns `undefined` for an absent identity, and for a value whose `!` marks it **removed** — a node the composer
59
- * deletes has no address in the composed document, and minting one would be a citation to something that is not
60
- * there.
61
- */
62
- export function identitySegment(raw, which) {
63
- const normalized = normalizeComponentKey(raw);
64
- if (!normalized || normalized.id === '' || normalized.removes)
65
- return undefined;
66
- if (carriesSeparator(normalized.id))
67
- return undefined;
68
- return which === 'id'
69
- ? { kind: 'id', value: normalized.id }
70
- : { kind: 'componentKey', value: normalized.id };
71
- }
72
- /** A dictionary tail, e.g. a metric facet's key. */
73
- export function entrySegment(raw) {
74
- const normalized = normalizeComponentKey(raw);
75
- if (!normalized || normalized.id === '' || normalized.removes)
76
- return undefined;
77
- if (carriesSeparator(normalized.id))
78
- return undefined;
79
- return { kind: 'entry', value: normalized.id };
80
- }
81
- /**
82
- * A value that cannot be a segment, because it carries the separator.
83
- *
84
- * AD-33's `:`-freedom measurement covers **step keys** — 0 of 12,366 — and rule 5's "dictionary tail" has no such
85
- * measurement. The corpus already contains one: `pullers[0].pullSteps[0].data.queries.date_modified:min`. Accepted
86
- * verbatim, `entrySegment('date_modified:min')` makes a 7-segment path yield 8 segments, so `addressSegments` and
87
- * `addressMatches` split at the wrong place — and `nodeAddress([keySegment('pullers'), identitySegment('X:pullSteps:key_Y', 'id')])`
88
- * is byte-identical to the address of step `Y` in stage `pullSteps` of puller `X`.
89
- *
90
- * Nothing is broken today, and that is exactly why this is a guard rather than a comment: the algebra should be
91
- * structurally safe, not statistically safe. A refused segment is dropped, which is the same treatment a removed
92
- * component gets — an address that would be ambiguous is worse than a shorter one.
93
- */
94
- function carriesSeparator(value) {
95
- return value.includes(ADDRESS_SEPARATOR);
96
- }
97
- /** One segment's canonical text. */
98
- function textOf(segment) {
99
- switch (segment.kind) {
100
- case 'key':
101
- return segment.name;
102
- case 'id':
103
- return `id_${segment.value}`;
104
- case 'componentKey':
105
- return `key_${segment.value}`;
106
- case 'entry':
107
- return segment.value;
108
- }
109
- }
110
- /**
111
- * The canonical address for a path.
112
- *
113
- * `undefined` segments are dropped rather than rendered as blanks, so a caller can pass
114
- * `identitySegment(step.key, 'key')` without first checking it — a step with no key still gets the address of the
115
- * stage that holds it, which is a true statement about a lesser-known node rather than an address with a hole in it.
116
- *
117
- * A segment whose TEXT is empty is dropped for the same reason, and this is the structural home of that rule (Story
118
- * 4.6 review, LOW-1). `identitySegment` already refuses an empty id, but `keySegment('')` is a defined segment holding
119
- * no text, so an empty `collection` or an empty base string produced `:creationSteps:key_FORM` — an address whose
120
- * separator claims a level that was never there. That was first patched at one call site in `frontend-flow`; the class
121
- * belongs here, where every caller gets it. Whitespace counts as empty: a segment of spaces is not a level either.
122
- */
123
- export function nodeAddress(segments) {
124
- return segments
125
- .filter((s) => s !== undefined)
126
- .map(textOf)
127
- .filter((text) => text.trim() !== '')
128
- .join(ADDRESS_SEPARATOR);
129
- }
130
- /**
131
- * The rendered form for a mermaid node id.
132
- *
133
- * Two steps, in this order: `:` → `__`, then sanitise anything still outside `[A-Za-z0-9_]`. Sanitising first would
134
- * turn a stray character into `_` and make it indistinguishable from a separator.
135
- */
136
- export function renderedNodeId(address) {
137
- return address
138
- .split(ADDRESS_SEPARATOR)
139
- .join(RENDERED_SEPARATOR)
140
- .replace(/[^A-Za-z0-9_]/g, '_');
141
- }
142
- /** The segments of a canonical address, as text. */
143
- export function addressSegments(address) {
144
- return address === '' ? [] : address.split(ADDRESS_SEPARATOR);
145
- }
146
- /**
147
- * Does `address` name this node, or one inside it?
148
- *
149
- * **Whole-segment**, which is what makes AD-33's prefix-capture fix structural rather than a rule. The corpus has
150
- * **924 pairs** of unique step keys where one prefixes another, and fixture 01 contains one directly:
151
- * `SAVE_SALES_RETURN` and `SAVE_SALES_RETURN_DETAILS`, both named in one Scriban expression. As segments they are
152
- * simply different, so `includes()`-style capture cannot happen — no word-boundary regex, no side payload map.
153
- */
154
- export function addressMatches(address, candidate) {
155
- /**
156
- * An EMPTY address matches nothing (Story 4.1 review, LOW-4). `[].every(...)` is `true`, so an empty `address`
157
- * previously "contained" every node in the profile — and it is reachable: `nodeAddress([])` and a path whose only
158
- * segment was refused both return `''`. A node with no address is not an ancestor of anything.
159
- */
160
- if (address === '' || candidate === '')
161
- return false;
162
- if (address === candidate)
163
- return true;
164
- const own = addressSegments(address);
165
- const other = addressSegments(candidate);
166
- if (other.length <= own.length)
167
- return false;
168
- return own.every((segment, index) => other[index] === segment);
169
- }
170
- /**
171
- * The address, among those a caller already knows, that a rendered mermaid id refers to.
172
- *
173
- * ### There is deliberately NO reverse function, and the first draft of this module had one
174
- *
175
- * `addressOfRenderedId` looked reasonable and was unsound. It reversed `__` → `:` and accepted the result if it
176
- * re-rendered to the same id — but that check proves round-trip *consistency*, not *uniqueness*, and the projection
177
- * is genuinely many-to-one once sanitisation is involved. Its own test caught it: both
178
- *
179
- * ```
180
- * pullers:id_**XPullerId**:pullSteps:key_GET_ORDERS:next:if ← the real address
181
- * pullers:id:_XPullerId::pullSteps:key_GET_ORDERS:next:if ← a different node entirely
182
- * ```
183
- *
184
- * render to `pullers__id___XPullerId____pullSteps__key_GET_ORDERS__next__if`. So it would have returned the second
185
- * for a click on the first: precisely the wrong-node navigation its own docblock claimed to prevent.
186
- *
187
- * The direction that IS sound is forward-only, and it is all a consumer needs — Story 4.1 AC-4 puts the address on
188
- * every node in the index, so a click handler always has the candidates in hand and never has to invert anything.
189
- */
190
- export function addressForRenderedId(rendered, known) {
191
- const matches = known.filter((address) => renderedNodeId(address) === rendered);
192
- // Two known addresses rendering alike is not a node to navigate to — it is an ambiguity to report as none.
193
- return matches.length === 1 ? matches[0] : undefined;
194
- }
195
- //# sourceMappingURL=nodeAddress.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"nodeAddress.js","sourceRoot":"","sources":["../src/nodeAddress.ts"],"names":[],"mappings":"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"}
@@ -1,200 +0,0 @@
1
- /**
2
- * Which properties name another component — measured, not assumed (Stories 3.4 and 3.7).
3
- *
4
- * This list was originally guessed from what the collections are called, and the guess was wrong
5
- * in both directions. It is now derived from the corpus: every `*Id` / `*Ids` property in nine
6
- * real projects was resolved against the effective graph and kept only if its values are actually
7
- * component ids. The measured figures are recorded here because a list like this decays silently
8
- * — a property added next year will not announce itself — and the next person needs to know how
9
- * to re-derive it rather than how to guess again.
10
- *
11
- * Resolution rates, measured over real projects (hits / occurrences):
12
- *
13
- * taskId 651/651 100% metricId 0/651 0%
14
- * connectorId 413/413 100% providerId 0/27 0%
15
- * connectionId 284/284 100% columnIds 0/11 0%
16
- * entityId 115/115 100% credentialId 0/5 0%
17
- * objectIds 90/90 100% profileId 0/5 0%
18
- * targetId 59/59 100% systemId 0/4 0%
19
- * fromConnectionId 54/54 100% integrationAppId 0/4 0%
20
- * objectId 50/50 100% itemIds 0/3 0%
21
- * object_id 13/13 100%
22
- * pusherId 5/5 100%
23
- * tableId 4/4 100%
24
- * pullerId 2/2 100%
25
- *
26
- * Two findings worth stating plainly, because both contradict what was written down before:
27
- *
28
- * 1. **`taskId` is real, and is the most-used reference property in the corpus.** Story 3.7's AC
29
- * calls it "the ideation document's illustrative `taskId`, which does not exist" — that is
30
- * false. It appears 291 times in authored partials and resolves 651/651. The AC's underlying
31
- * instruction — key these to REAL property names — is right, and following it is what turned
32
- * up the error in its own example.
33
- * 2. **`validationId`, `transformationId`, `pullerIds` and `pusherIds` were invented** from the
34
- * collection names and have zero authored occurrences. Removed. `pullerId` was on the same
35
- * guessed list but turned out to be real (2/2), so it is kept — on the measurement, not on
36
- * the fact that a `pullers` collection exists.
37
- *
38
- * The values are often COMPOSE-TIME TOKENS — `taskId: "**Sapo_Orders_Task_Id**"` — and they
39
- * resolve because the graph keys components in token form (Story 3.1). Keying on substituted
40
- * values would have made every one of these references dangle.
41
- */
42
- export declare const isTokenForm: (value: string) => boolean;
43
- /**
44
- * A target collection chosen by a sibling property's value.
45
- *
46
- * `entityId` means a Task under `entityType: TASK` and something outside the template under
47
- * `PROFILE`. The discriminator is read from the value's own containing map, so it is available
48
- * wherever the reference is — the relation walk holds the node, and the cursor holds the parent.
49
- */
50
- export interface ReferenceDiscriminator {
51
- /** Sibling properties consulted in order; the first one present decides. */
52
- readonly siblings: readonly string[];
53
- /** Sibling value → target collection. `undefined` means "not a reference to a component". */
54
- readonly byValue: ReadonlyMap<string, string | undefined>;
55
- /** The collection when no discriminating sibling is present. */
56
- readonly fallback?: string;
57
- }
58
- /** A property that names another component, and the collection it points into when that is fixed. */
59
- export interface ReferenceProperty {
60
- readonly property: string;
61
- /** The collection the target lives in, when the property only ever points at one. */
62
- readonly collection?: string;
63
- /** The collection when it is decided by a sibling rather than by the property name. */
64
- readonly discriminator?: ReferenceDiscriminator;
65
- /**
66
- * Resolve only when the value is `**Token**` form.
67
- *
68
- * Set where the same property also legitimately holds a runtime UUID, so that a UUID reads as
69
- * "not a component reference" instead of "a reference that is broken".
70
- */
71
- readonly tokenFormOnly?: boolean;
72
- /**
73
- * Collections whose OWN entries this property does not reference from (FR-47, Story 1.7).
74
- *
75
- * A property name can mean two different things depending on where it sits. `connectorId` in a step
76
- * argument names a connection in this project and resolves 413/413. `connectorId` on a `connectors[]`
77
- * entry is the entry's own **platform** identity — the connector product it reaches — and points at
78
- * nothing in the workspace, exactly as its legacy spelling `providerId` does (measured 0/27, which is why
79
- * `providerId` sits in `NON_REFERENCE_ID_PROPERTIES`).
80
- *
81
- * Without this, FR-3's rename would give every converted connection a dangling-reference finding, and
82
- * FR-2's own promise — that writing the modern spelling produces no error — would be broken by the rule
83
- * registry immediately after the schema stopped breaking it.
84
- *
85
- * Position, not value: the value is a well-formed id either way, so no amount of inspecting it can tell
86
- * the two apart. The enclosing collection is the only thing that can.
87
- */
88
- readonly opaqueInCollections?: readonly string[];
89
- }
90
- export declare const REFERENCE_PROPERTY_LIST: readonly ReferenceProperty[];
91
- /** What a property means at one position: whether it references, and what it points into. */
92
- export interface ReferenceKind {
93
- /** The collection the target lives in, when it is known. */
94
- readonly collection?: string;
95
- /** The property name to report, which for a nested block is `table.id` rather than `id`. */
96
- readonly property: string;
97
- }
98
- /**
99
- * Resolve what a reference property means beside its siblings.
100
- *
101
- * Returns `undefined` when this property/value/context is NOT a component reference — a raw UUID
102
- * in `entityId`, or `entityType: SELF`. That is a distinct answer from "a reference that does not
103
- * resolve", and collapsing the two is what puts diagnostics on correct files.
104
- */
105
- export declare function resolveReferenceKind(property: string, value: string, siblings?: Record<string, unknown>,
106
- /**
107
- * The collection whose entry this property sits inside — `connectors`, `pullers`, `objects`, … — as the
108
- * walker already tracks it. Optional so existing callers keep compiling; supplying it is what lets a
109
- * property mean one thing in a step argument and another on a component of its own collection (FR-47).
110
- */
111
- enclosingCollection?: string): ReferenceKind | undefined;
112
- /** Fast membership test for the walk in `queries.ts`. */
113
- export declare const REFERENCE_PROPERTIES: readonly string[];
114
- export declare const referencePropertyFor: (property: string) => ReferenceProperty | undefined;
115
- /**
116
- * `*Id` properties MEASURED at 0% resolution — not references, recorded so their absence reads
117
- * as a decision rather than an oversight.
118
- *
119
- * They hold runtime UUIDs, environment tokens or payload field names. Without this list the next
120
- * reader sees `metricId` missing from the set above and adds it, and every metric configuration
121
- * in the corpus grows a dangling-reference diagnostic.
122
- *
123
- * Every entry here has a row in the table above. `templateId` and `reportId` were previously
124
- * listed and have been REMOVED: they never occurred in the sampled projects at all, so "resolved
125
- * 0%" was never true of them — no-occurrences is not the same measurement as never-resolves, and
126
- * a list whose stated basis is measurement must not carry entries that were only assumed. They
127
- * do appear elsewhere in the corpus (`reportId` ~91 authored occurrences), so they are left
128
- * deliberately unclassified until someone measures them.
129
- */
130
- export declare const NON_REFERENCE_ID_PROPERTIES: readonly string[];
131
- /**
132
- * Blocks whose `id` names a component — the corpus's DOMINANT reference form.
133
- *
134
- * `objectAssociations` wires a Task to its entities like this:
135
- *
136
- * objectAssociations:
137
- * "**Orders_Task_Id**":
138
- * table: { id: "**Orders_Table_Id**" }
139
- * puller: { id: "**Orders_Puller_Id**", resultKey: rows }
140
- *
141
- * Counted across the corpus's AUTHORED partials (`output.yaml` and `__configs` excluded):
142
- *
143
- * nested `table:` 1,575 flat `tableId:` 308
144
- * nested `puller:` 1,695 flat `pullerId:` 38
145
- * nested `pusher:` 912 flat `pusherId:` 48
146
- * ----- ---
147
- * 4,182 394
148
- *
149
- * The nested form outnumbers the flat one by roughly 10:1 — it is how the corpus wires a Task to
150
- * its entities, and a registry built only on flat property names saw NONE of it. The flat form is
151
- * a real minority, not noise, so both are supported.
152
- *
153
- * (An earlier draft of this comment said "4 / 2 / 5" and "three orders of magnitude". Those were
154
- * the nine-project RESOLUTION sample from the table above, quoted under a corpus-wide heading —
155
- * a different measurement of a different population. Corrected 2026-08-02.)
156
- *
157
- * The block carries more than the id (`resultKey`, for one), so the reference is the block's
158
- * `id` specifically, reported as `table.id` rather than as `table`.
159
- */
160
- export declare const NESTED_REFERENCE_BLOCKS: readonly ReferenceProperty[];
161
- export declare const nestedReferenceBlockFor: (property: string) => ReferenceProperty | undefined;
162
- /**
163
- * Collections whose component KEY is itself a reference into another collection.
164
- *
165
- * An `objectAssociations` entry is keyed BY the objectId it describes — that is what makes it
166
- * that object's association rather than a component that merely shares its name. Modelling it
167
- * matters twice: `getRelatedTask` can answer for an association, and renaming a Task has to
168
- * carry the association key with it, which only shows up in a blast radius if the key is an edge.
169
- */
170
- export declare const COLLECTIONS_KEYED_BY_REFERENCE: ReadonlyMap<string, string>;
171
- /** The property name reported for a reference carried by a component's own key. */
172
- export declare const KEY_REFERENCE_PROPERTY = "(key)";
173
- /**
174
- * The connector a connection names — `connectorId` first, `providerId` second (FR-1, AD-24).
175
- *
176
- * The read order exists in four places: `BaseStepExecutor` (untyped), `ConnectorDefinition.ResolvedConnectorId`
177
- * (typed), `WebhookPartitioner` (via the accessor) and — found missing by the Epic 1 review — the CLI's task
178
- * tooling. FR-1 says *every* runtime path, and the CLI reading only the legacy spelling meant a
179
- * `connectorId`-only connection, exactly what FR-3's rename produces at scale, hard-stopped task generation
180
- * with *"Connector undefined not found"*.
181
- *
182
- * Blank counts as absent, matching the untyped path: `Guid.Empty` has no equivalent here, but an empty string
183
- * does, and a half-written `connectorId: ""` must not beat a real legacy value.
184
- */
185
- export declare function resolvedConnectorIdOf(connection: {
186
- connectorId?: unknown;
187
- providerId?: unknown;
188
- } | null | undefined): string | undefined;
189
- /**
190
- * An identity that is STILL a token after composition — the variable failed, and `VAR-1` owns that.
191
- *
192
- * ⛔ A NAME for `isTokenForm`, not a second implementation. It shipped as a byte-identical copy of the regex
193
- * 350 lines above its original, in the file whose own docstring says *"ONE definition, deliberately … Epic 1's
194
- * review found what happens when a rule this small gets written three times."* Found by the Epic 2 review; kept
195
- * as an alias rather than deleted because the two names say different things at their call sites — one asks
196
- * "is this the shape a reference resolves in", the other "did substitution fail here".
197
- */
198
- export declare const isUnresolvedToken: (value: string) => boolean;
199
- export declare function isWellFormedConnectorIdentity(value: string): boolean;
200
- //# sourceMappingURL=references.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"references.d.ts","sourceRoot":"","sources":["../src/references.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AA6CH,eAAO,MAAM,WAAW,GAAI,OAAO,MAAM,KAAG,OACb,CAAC;AAEhC;;;;;;GAMG;AACH,MAAM,WAAW,sBAAsB;IACrC,4EAA4E;IAC5E,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,6FAA6F;IAC7F,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAC1D,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,qGAAqG;AACrG,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,qFAAqF;IACrF,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,uFAAuF;IACvF,QAAQ,CAAC,aAAa,CAAC,EAAE,sBAAsB,CAAC;IAChD;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAClD;AAmBD,eAAO,MAAM,uBAAuB,EAAE,SAAS,iBAAiB,EAqD/D,CAAC;AAEF,6FAA6F;AAC7F,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,4FAA4F;IAC5F,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;AAClC;;;;GAIG;AACH,mBAAmB,CAAC,EAAE,MAAM,GAC3B,aAAa,GAAG,SAAS,CAoC3B;AAED,yDAAyD;AACzD,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EACF,CAAC;AAIjD,eAAO,MAAM,oBAAoB,GAC/B,UAAU,MAAM,KACf,iBAAiB,GAAG,SAAkC,CAAC;AAE1D;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,2BAA2B,EAAE,SAAS,MAAM,EASxD,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,uBAAuB,EAAE,SAAS,iBAAiB,EAI/D,CAAC;AAMF,eAAO,MAAM,uBAAuB,GAClC,UAAU,MAAM,KACf,iBAAiB,GAAG,SAAyC,CAAC;AAEjE;;;;;;;GAOG;AACH,eAAO,MAAM,8BAA8B,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAyBnE,CAAC;AAEL,mFAAmF;AACnF,eAAO,MAAM,sBAAsB,UAAU,CAAC;AAE9C;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EACR;IAAE,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,GACnE,MAAM,GAAG,SAAS,CAgBpB;AAqBD;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,UA7WK,MAAM,KAAG,OA6WA,CAAC;AAE7C,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAMpE"}