@graphit/cli 0.2.322 → 0.2.323
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/.claude-plugin/marketplace.json +3 -3
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/bin/graphit +1 -1
- package/bin/graphit.ps1 +1 -1
- package/dist/api/client.js +15 -0
- package/dist/api/client.js.map +1 -1
- package/dist/commands/ds-config.js +2 -2
- package/dist/commands/ds-config.js.map +1 -1
- package/dist/commands/ds.js +2 -2
- package/dist/commands/ds.js.map +1 -1
- package/dist/commands/kb.js +347 -15
- package/dist/commands/kb.js.map +1 -1
- package/dist/commands/query.js +3 -3
- package/dist/commands/query.js.map +1 -1
- package/dist/index.js +0 -8
- package/dist/index.js.map +1 -1
- package/dist/skill-guard.js +2 -1
- package/dist/skill-guard.js.map +1 -1
- package/package.json +1 -1
- package/scripts/verb-policy-source.json +30 -102
- package/skills/graphit/SKILL.md +31 -39
- package/skills/graphit/VERSION.json +1 -1
- package/skills/graphit/references/data-source-refresh.md +27 -0
- package/skills/graphit/references/data-sources.md +27 -122
- package/skills/graphit/references/filters-advanced.md +2 -2
- package/skills/graphit/references/governance-explained.md +18 -29
- package/skills/graphit/references/governance.md +20 -83
- package/skills/graphit/references/kb-actions.md +28 -81
- package/skills/graphit/references/kb-discovery.md +35 -64
- package/skills/graphit/references/kb-scope.md +17 -15
- package/skills/graphit/references/kb-structure.md +28 -54
- package/skills/graphit/references/kb-traversal.md +24 -96
- package/skills/graphit/references/metric-families.md +19 -0
- package/skills/graphit/references/migration.md +2 -2
- package/skills/graphit/references/onboarding.md +5 -4
- package/skills/graphit/references/presentations.md +1 -1
- package/skills/graphit/references/runtime.md +6 -6
- package/skills/graphit/references/semantic-authoring.md +65 -0
- package/skills/graphit/references/sql-reference.md +10 -20
- package/dist/commands/kb-constraints.d.ts +0 -14
- package/dist/commands/kb-constraints.js +0 -53
- package/dist/commands/kb-constraints.js.map +0 -1
- package/dist/commands/kb-create.d.ts +0 -2
- package/dist/commands/kb-create.js +0 -296
- package/dist/commands/kb-create.js.map +0 -1
- package/dist/commands/kb-delete.d.ts +0 -2
- package/dist/commands/kb-delete.js +0 -37
- package/dist/commands/kb-delete.js.map +0 -1
- package/dist/commands/kb-read.d.ts +0 -2
- package/dist/commands/kb-read.js +0 -223
- package/dist/commands/kb-read.js.map +0 -1
- package/dist/commands/kb-shared.d.ts +0 -43
- package/dist/commands/kb-shared.js +0 -81
- package/dist/commands/kb-shared.js.map +0 -1
- package/dist/commands/kb-update.d.ts +0 -2
- package/dist/commands/kb-update.js +0 -240
- package/dist/commands/kb-update.js.map +0 -1
- package/dist/commands/sl/index.d.ts +0 -2
- package/dist/commands/sl/index.js +0 -263
- package/dist/commands/sl/index.js.map +0 -1
- package/skills/graphit/references/parameterized-metrics.md +0 -77
|
@@ -77,7 +77,7 @@ deck.slide({
|
|
|
77
77
|
html: `
|
|
78
78
|
<h2>Live Data</h2>
|
|
79
79
|
<div data-graphit-id="spend-chart" data-graphit-label="Ad Spend"
|
|
80
|
-
data-graphit-sql="SELECT {{
|
|
80
|
+
data-graphit-sql="SELECT {{ Dimension('campaign__media_source') }} AS source, {{ Metric('total_ad_spend') }} AS spend FROM MARKETING_UA_DS GROUP BY 1 ORDER BY spend DESC LIMIT 6"
|
|
81
81
|
data-graphit-ds="MARKETING_UA_DS">
|
|
82
82
|
<div id="chart1" class="gh-loading">
|
|
83
83
|
<div class="gh-loading-overlay"><svg class="gh-loading-spin" width="24" height="24" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="10" stroke="#e5e5e5" stroke-width="2.5"/><path d="M12 2a10 10 0 0 1 10 10" stroke="#4DB6AC" stroke-width="2.5" stroke-linecap="round"/></svg></div>
|
|
@@ -30,7 +30,7 @@ const result = await graphit.resolve({
|
|
|
30
30
|
|
|
31
31
|
MUST: every resolve feeding a rendered graph, KPI, or table carries attribution - `target` (the entity wrapper or an element inside it), or `sourceEntityId` plus `targetEntityIds` when one result feeds several graphs. Attribution records the live filtered query behind that entity's details panel; unattributed, the panel shows `data-graphit-sql` as an unrun example, so a user changing a filter sees the SQL never move. Saving a page with filters or params and zero attributed resolves returns an `unattributed_resolves` warning. Queries feeding page chrome need no attribution and no entity, but belong on the primitives - `graphit.cascade` for option lists, `graphit.dataBounds` for a column's min/max, `graphit.rank` for top-N (`filters-advanced.md`) - never hand-written entity-less SQL.
|
|
32
32
|
|
|
33
|
-
CRITICAL: use
|
|
33
|
+
CRITICAL: use `{{ Metric('name') }}`, `{{ Dimension('entity__name') }}`, or Graphit's `{{ Measure('name') }}` extension inside `data-graphit-sql` whenever the semantic asset exists. The server expands it into the governed tier. See `governance.md`.
|
|
34
34
|
|
|
35
35
|
Error handling: `graphit.resolve()` rejects on timeout (120s), bad SQL, or an invalid data source ID. Wrap calls in try/catch and show a user-visible error in the target element on failure. Verify the SQL returns data via the CLI before embedding it.
|
|
36
36
|
|
|
@@ -41,7 +41,7 @@ Every visible element - chart, KPI card, table, text section - must be wrapped s
|
|
|
41
41
|
```html
|
|
42
42
|
<div data-graphit-id="revenue-trend"
|
|
43
43
|
data-graphit-label="Revenue Trend"
|
|
44
|
-
data-graphit-sql="SELECT {{
|
|
44
|
+
data-graphit-sql="SELECT {{ Dimension('order__region') }} AS region, {{ Metric('revenue') }} AS revenue FROM ORDERS_DS GROUP BY region"
|
|
45
45
|
data-graphit-ds="ORDERS_DS">
|
|
46
46
|
<!-- chart, KPI, or table content here -->
|
|
47
47
|
</div>
|
|
@@ -55,7 +55,7 @@ Every visible element - chart, KPI card, table, text section - must be wrapped s
|
|
|
55
55
|
| `data-graphit-ds` | Data source name (same as the FROM table) or id | `"ORDERS_DS"` |
|
|
56
56
|
| `data-graphit-state` | Not an entity attribute - a SIBLING wrapper around a user-changeable control, naming the state key saved views capture (`filters.md`) | `"country"` |
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
Semantic references are derived automatically from the final grammar; the compiler resolves them and shows asset chips in the details panel. Missing any one attribute breaks the entity; missing the wrapper makes the element invisible to the platform.
|
|
59
59
|
|
|
60
60
|
**JavaScript may populate an entity, never create one.** Every entity - including on hidden tabs, collapsed panels, and lazily-shown views - exists as static markup in the HTML you save; JavaScript fills its chart host, wires listeners, and toggles visibility. Nothing server-side runs your JavaScript, so a card built at render time (`host.innerHTML = charts.map(...)`) does not exist for governance, lineage, the KB graph, `list-entities`, or a later `get-entity`. A save whose `data-graphit-id`s are reachable only by running your JavaScript is REFUSED and the error names them. A dynamic **query** is supported - the attribute carries the canonical template; a dynamic **entity** is not.
|
|
61
61
|
|
|
@@ -74,14 +74,14 @@ A filtered entity uses `graphit.bind(el, { params, deps, render })` (`filters.md
|
|
|
74
74
|
|
|
75
75
|
```html
|
|
76
76
|
<div data-graphit-id="explorer" data-graphit-label="Metric Explorer" data-graphit-ds="UA_DS"
|
|
77
|
-
data-graphit-sql="SELECT day, {{
|
|
78
|
-
data-graphit-vocab="metric:
|
|
77
|
+
data-graphit-sql="SELECT day, {{ Metric('roas') }} AS roas FROM UA_DS GROUP BY 1"
|
|
78
|
+
data-graphit-vocab="metric:revenue,metric:roas,dimension:campaign__country"></div>
|
|
79
79
|
```
|
|
80
80
|
```js
|
|
81
81
|
graphit.resolve({ sql: buildSql(picked), dataSourceId: "UA_DS", runtimeComposed: true, sourceEntityId: "explorer" });
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
Use comma-separated lowercase declarations such as `metric:revenue`, `dimension:order__region`, and `measure:order_total`. Every declared name must exist; unknown names and wildcards refuse. Undeclared inline SQL is invisible to lineage and governance. Existing runtime-composed queries are first-class, not debt; migrate query ownership only when asked (`migration.md`).
|
|
85
85
|
|
|
86
86
|
**Label equals the visible title.** `data-graphit-label` MUST match the card's visible heading exactly - users find their chart by that label in @ mention dropdowns and entity panels, and a mismatch means they cannot find it.
|
|
87
87
|
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Semantic Authoring
|
|
2
|
+
|
|
3
|
+
Load when creating or changing semantic models or metrics.
|
|
4
|
+
|
|
5
|
+
## Syntax boundary
|
|
6
|
+
|
|
7
|
+
Graphit accepts the MetricFlow 0.211 execution shape: semantic models contain
|
|
8
|
+
entities, dimensions, and measures; metrics are top-level objects with `type`
|
|
9
|
+
and `type_params`. Do not emit newer measureless/Fusion authoring syntax, dbt
|
|
10
|
+
project YAML, Jinja, `ref()` expressions, or source declarations on this
|
|
11
|
+
surface. Those belong to dbt project import/export, not Graphit authoring.
|
|
12
|
+
|
|
13
|
+
Public dbt/MetricFlow concepts:
|
|
14
|
+
|
|
15
|
+
- semantic model, entity, dimension, measure, metric, and group
|
|
16
|
+
- simple, ratio, and derived metric composition
|
|
17
|
+
- entity-qualified dimension paths
|
|
18
|
+
|
|
19
|
+
Graphit extensions and assets:
|
|
20
|
+
|
|
21
|
+
- `meta.graphit.family` and `axes` group concrete metric variants
|
|
22
|
+
- topics are curated Graphit metadata, deliberately not dbt `tags`
|
|
23
|
+
- rules are separate Graphit objects targeting semantic identities by name;
|
|
24
|
+
never embed them in dbt metadata
|
|
25
|
+
- verification attribution, provenance, and data-source bindings are
|
|
26
|
+
server-owned; use dedicated actions instead of hand-authoring them
|
|
27
|
+
|
|
28
|
+
Do not expose or depend on storage collection names, revision fields, feature
|
|
29
|
+
flags, cache keys, or compiler implementation details.
|
|
30
|
+
|
|
31
|
+
## Semantic model
|
|
32
|
+
|
|
33
|
+
A semantic model owns:
|
|
34
|
+
|
|
35
|
+
- lowercase name and physical model/binding
|
|
36
|
+
- group placement
|
|
37
|
+
- primary grain/entity
|
|
38
|
+
- entities for joins
|
|
39
|
+
- dimensions for grouping/filtering
|
|
40
|
+
- measures for aggregation input
|
|
41
|
+
- defaults such as aggregation time dimension
|
|
42
|
+
|
|
43
|
+
Measure-bearing models need a valid aggregation time dimension. Primary/unique entity claims require grain evidence; never guess uniqueness. Time-aware shapes require the platform time-spine prerequisite.
|
|
44
|
+
|
|
45
|
+
Nested lists replace whole lists on update. Read the model and preserve every sibling.
|
|
46
|
+
|
|
47
|
+
## Metrics
|
|
48
|
+
|
|
49
|
+
Only these shapes are served by the shipping fragment path:
|
|
50
|
+
|
|
51
|
+
- **simple:** one measure object
|
|
52
|
+
- **ratio:** numerator and denominator metric objects
|
|
53
|
+
- **derived:** expression over declared metric inputs or aliases
|
|
54
|
+
|
|
55
|
+
Metric-level and per-input filters must resolve through declared semantic identities. Bare strings where an input object is required are refused.
|
|
56
|
+
|
|
57
|
+
Cumulative, conversion, shifted inputs, time-spine joins, and null-fill are unavailable until Project #289. Use a supported decomposition or clearly labeled free SQL; do not create an unusable governed definition.
|
|
58
|
+
|
|
59
|
+
## Verification
|
|
60
|
+
|
|
61
|
+
Create defaults to verified on human-driven CLI paths; `--unverified` creates a draft. Promote or demote with dedicated verify/unverify actions. Never replace `meta` only to toggle verification.
|
|
62
|
+
|
|
63
|
+
## Final check
|
|
64
|
+
|
|
65
|
+
Re-read the root, verify nested completeness, inspect group/binding, and use the returned receipt. A degraded freshness result may mean the write landed; do not retry blindly.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# SQL Reference
|
|
2
2
|
|
|
3
|
-
Consult when writing queries. Data
|
|
3
|
+
Consult when writing queries. Data-source queries run DuckDB. Warehouse queries run the connected Snowflake or BigQuery dialect. Governance parses the same dialect. Read physical columns through metadata discovery or semantic-model physical detail; never use DDL through the SELECT-only query surface.
|
|
4
4
|
|
|
5
5
|
## DuckDB vs Snowflake Translation
|
|
6
6
|
|
|
@@ -138,22 +138,20 @@ The canvas `percent` format only appends `%` (it does not multiply by 100), so m
|
|
|
138
138
|
|
|
139
139
|
## Presenting Query Results
|
|
140
140
|
|
|
141
|
-
After every
|
|
142
|
-
|
|
143
|
-
**When using KB reference syntax** (`{{metric:X}}`, `{{dim:X}}`), show all five sections:
|
|
141
|
+
After every query, show all five sections below. Use `--verbose` to obtain the resolved SQL. Executable SQL uses semantic references; narration uses backticked exact asset names so Graphit can render clickable KB pills.
|
|
144
142
|
|
|
145
143
|
~~~
|
|
146
|
-
**KB Assets:** dimension
|
|
144
|
+
**KB Assets:** dimension `campaign__category`, metrics `total_installs` and `cpi`, semantic model `marketing_ua`
|
|
147
145
|
|
|
148
146
|
**Query:**
|
|
149
147
|
```sql
|
|
150
148
|
SELECT
|
|
151
|
-
{{
|
|
152
|
-
{{
|
|
153
|
-
{{
|
|
149
|
+
{{ Dimension('campaign__category') }} AS category,
|
|
150
|
+
{{ Metric('total_installs') }} AS installs,
|
|
151
|
+
{{ Metric('cpi') }} AS cpi
|
|
154
152
|
FROM MARKETING_UA_DS
|
|
155
153
|
WHERE ACTIVITY_TIME >= '2026-01-01'
|
|
156
|
-
GROUP BY {{
|
|
154
|
+
GROUP BY {{ Dimension('campaign__category') }}
|
|
157
155
|
ORDER BY installs DESC
|
|
158
156
|
```
|
|
159
157
|
|
|
@@ -179,17 +177,9 @@ ORDER BY installs DESC
|
|
|
179
177
|
| Retargeting | 12,300 | $1.24 |
|
|
180
178
|
| Connected TV | 3,100 | $2.80 |
|
|
181
179
|
|
|
182
|
-
**Governance:** governed - 3
|
|
183
|
-
~~~
|
|
184
|
-
|
|
185
|
-
**When using inline SQL** (no `{{metric:X}}`), present it the same way (query + results + governance), but the footer states the ad-hoc tier and offers the governed rewrite:
|
|
186
|
-
|
|
187
|
-
~~~
|
|
188
|
-
**Governance:** ad-hoc - 0 KB refs. Consider using `{{metric:TOTAL_SPEND}}` for governed tier.
|
|
180
|
+
**Governance:** governed - 3 semantic refs; 2 rules enforced (`exclude_organic`, `min_spend`). Max rows: 1,000.
|
|
189
181
|
~~~
|
|
190
182
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
**Always use `--verbose`** to get the resolved SQL; if the user didn't pass it, re-run with it.
|
|
183
|
+
For inline SQL, use the same sections but state the ad-hoc tier and offer a governed rewrite, for example: **Governance:** ad-hoc - 0 semantic refs. Consider `{{ Metric('total_spend') }}`. Author a supported root definition first when needed; provide an ad-hoc reason only when nothing governed fits.
|
|
194
184
|
|
|
195
|
-
|
|
185
|
+
For zero rows, explain the checks performed and likely cause, such as date range, filter, or empty source.
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure parsers for `graphit kb create/update rule` --constraint / --apply-on flags.
|
|
3
|
-
*
|
|
4
|
-
* Extracted from kb.ts so they are unit-testable without Commander or the API
|
|
5
|
-
* client (mirrors query-timeout.ts). Issue #548: the required_where quote
|
|
6
|
-
* stripper used to remove ANY leading/trailing quote, so a predicate ending in
|
|
7
|
-
* a SQL string literal lost its closing quote
|
|
8
|
-
* (`MEDIA_SOURCE != 'organic'` -> `MEDIA_SOURCE != 'organic`), producing
|
|
9
|
-
* unparseable SQL that the backend rejected - the constraint never persisted.
|
|
10
|
-
*/
|
|
11
|
-
/** Strip wrapping quotes only when the value is wrapped in a matched pair. */
|
|
12
|
-
export declare function unwrapQuotes(value: string): string;
|
|
13
|
-
export declare function parseConstraintFlags(specs: string[]): Record<string, unknown>[];
|
|
14
|
-
export declare function parseApplyOnFlags(specs: string[]): Record<string, string>[];
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure parsers for `graphit kb create/update rule` --constraint / --apply-on flags.
|
|
3
|
-
*
|
|
4
|
-
* Extracted from kb.ts so they are unit-testable without Commander or the API
|
|
5
|
-
* client (mirrors query-timeout.ts). Issue #548: the required_where quote
|
|
6
|
-
* stripper used to remove ANY leading/trailing quote, so a predicate ending in
|
|
7
|
-
* a SQL string literal lost its closing quote
|
|
8
|
-
* (`MEDIA_SOURCE != 'organic'` -> `MEDIA_SOURCE != 'organic`), producing
|
|
9
|
-
* unparseable SQL that the backend rejected - the constraint never persisted.
|
|
10
|
-
*/
|
|
11
|
-
/** Strip wrapping quotes only when the value is wrapped in a matched pair. */
|
|
12
|
-
export function unwrapQuotes(value) {
|
|
13
|
-
const first = value[0];
|
|
14
|
-
if (value.length >= 2 &&
|
|
15
|
-
(first === '"' || first === "'") &&
|
|
16
|
-
value[value.length - 1] === first) {
|
|
17
|
-
return value.slice(1, -1);
|
|
18
|
-
}
|
|
19
|
-
return value;
|
|
20
|
-
}
|
|
21
|
-
export function parseConstraintFlags(specs) {
|
|
22
|
-
return specs.map((spec) => {
|
|
23
|
-
const colonIdx = spec.indexOf(":");
|
|
24
|
-
if (colonIdx < 0)
|
|
25
|
-
throw new Error(`Invalid constraint: "${spec}". Use type:value (e.g., forbidden_column:email)`);
|
|
26
|
-
const type = spec.slice(0, colonIdx);
|
|
27
|
-
const value = spec.slice(colonIdx + 1);
|
|
28
|
-
switch (type) {
|
|
29
|
-
case "required_where":
|
|
30
|
-
return { type, predicate: unwrapQuotes(value) };
|
|
31
|
-
case "forbidden_column":
|
|
32
|
-
case "required_filter":
|
|
33
|
-
case "required_aggregation":
|
|
34
|
-
return { type, column: value };
|
|
35
|
-
case "value_restriction": {
|
|
36
|
-
const [col, op, ...valueParts] = value.split(":");
|
|
37
|
-
const operator = op === "not_in" ? "not_in" : "in";
|
|
38
|
-
return { type, column: col, values: valueParts.join(":").split(","), operator };
|
|
39
|
-
}
|
|
40
|
-
default:
|
|
41
|
-
throw new Error(`Unknown constraint type: "${type}"`);
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
export function parseApplyOnFlags(specs) {
|
|
46
|
-
return specs.map((spec) => {
|
|
47
|
-
const colonIdx = spec.indexOf(":");
|
|
48
|
-
if (colonIdx < 0)
|
|
49
|
-
throw new Error(`Invalid apply-on: "${spec}". Use type:NAME (e.g., table:USERS)`);
|
|
50
|
-
return { type: spec.slice(0, colonIdx), name: spec.slice(colonIdx + 1) };
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
//# sourceMappingURL=kb-constraints.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"kb-constraints.js","sourceRoot":"","sources":["../../src/commands/kb-constraints.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,8EAA8E;AAC9E,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACvB,IACE,KAAK,CAAC,MAAM,IAAI,CAAC;QACjB,CAAC,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,CAAC;QAChC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,KAAK,EACjC,CAAC;QACD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAAe;IAClD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,QAAQ,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,IAAI,kDAAkD,CAAC,CAAC;QAClH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QACrC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;QACvC,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,gBAAgB;gBACnB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;YAClD,KAAK,kBAAkB,CAAC;YACxB,KAAK,iBAAiB,CAAC;YACvB,KAAK,sBAAsB;gBACzB,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;YACjC,KAAK,mBAAmB,CAAC,CAAC,CAAC;gBACzB,MAAM,CAAC,GAAG,EAAE,EAAE,EAAE,GAAG,UAAU,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAClD,MAAM,QAAQ,GAAG,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;gBACnD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC;YAClF,CAAC;YACD;gBACE,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,GAAG,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAe;IAC/C,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,QAAQ,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,sCAAsC,CAAC,CAAC;QACpG,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,EAAE,CAAC;IAC3E,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,296 +0,0 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
2
|
-
import { apiClient } from "../api/client.js";
|
|
3
|
-
import { output, errorOutput, getOutputFormat } from "../output/format.js";
|
|
4
|
-
import { writeStderr } from "../stderr.js";
|
|
5
|
-
import { styledIntro, styledOutro, styledSuccess, formatBold, } from "../output/styled.js";
|
|
6
|
-
import { parseConstraintFlags, parseApplyOnFlags } from "./kb-constraints.js";
|
|
7
|
-
import { renderValidation, renderVisibility, withVisibility, } from "./kb-shared.js";
|
|
8
|
-
// Project #254 Phase 1: kb create verbs (metric/dimension/rule/domain/synonym/
|
|
9
|
-
// relationship/topic/template). Tables are created from data sources.
|
|
10
|
-
export function addKBCreateCommands(kb) {
|
|
11
|
-
const create = kb
|
|
12
|
-
.command("create")
|
|
13
|
-
.description("Create KB entities. Tables are created from data sources - use 'graphit ds create'.");
|
|
14
|
-
create
|
|
15
|
-
.command("metric")
|
|
16
|
-
.description("Create a new metric")
|
|
17
|
-
.requiredOption("--name <name>", "Metric name (UPPER_SNAKE_CASE)")
|
|
18
|
-
.requiredOption("--sql <expr>", "SQL calculation expression")
|
|
19
|
-
.requiredOption("--table <table>", "Primary table")
|
|
20
|
-
.option("--description <desc>", "Business meaning of the metric - what it counts and when to use it", "")
|
|
21
|
-
.option("--topics <topics>", "Comma-separated topic names")
|
|
22
|
-
.option("--default-dimensions <dims>", "Comma-separated dimension names this metric naturally groups by")
|
|
23
|
-
.option("--parameters <json>", "JSON array of parameter definitions")
|
|
24
|
-
.option("--parameters-file <path>", "Read parameters JSON from file")
|
|
25
|
-
.option("--skip-validate", "Skip pre-creation data validation")
|
|
26
|
-
.option("--unverified", "Create as a draft instead of verified (default: verified)")
|
|
27
|
-
.action(async function () {
|
|
28
|
-
try {
|
|
29
|
-
const opts = this.opts();
|
|
30
|
-
const fmt = getOutputFormat(this);
|
|
31
|
-
const topics = opts.topics ? opts.topics.split(",").map((s) => s.trim()).filter(Boolean) : [];
|
|
32
|
-
const defaultDimensions = opts.defaultDimensions ? opts.defaultDimensions.split(",").map((s) => s.trim()).filter(Boolean) : [];
|
|
33
|
-
let parameters = [];
|
|
34
|
-
if (opts.parametersFile) {
|
|
35
|
-
parameters = JSON.parse(await readFile(opts.parametersFile, "utf-8"));
|
|
36
|
-
}
|
|
37
|
-
else if (opts.parameters) {
|
|
38
|
-
parameters = JSON.parse(opts.parameters);
|
|
39
|
-
}
|
|
40
|
-
const skipValidate = opts.skipValidate ? "true" : "false";
|
|
41
|
-
const resp = await apiClient.post(`/api/v1/cli/kb/metric?skip_validate=${skipValidate}`, {
|
|
42
|
-
name: opts.name,
|
|
43
|
-
calculation: opts.sql,
|
|
44
|
-
table: opts.table,
|
|
45
|
-
description: opts.description,
|
|
46
|
-
topics,
|
|
47
|
-
default_dimensions: defaultDimensions,
|
|
48
|
-
parameters,
|
|
49
|
-
unverified: Boolean(opts.unverified),
|
|
50
|
-
});
|
|
51
|
-
if (fmt === "styled") {
|
|
52
|
-
styledIntro(`graphit kb create metric`);
|
|
53
|
-
styledSuccess(`Metric ${formatBold(String(resp.entity.name))} created`);
|
|
54
|
-
renderValidation(this, resp);
|
|
55
|
-
renderVisibility(this, resp);
|
|
56
|
-
styledOutro();
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
const out = withVisibility(this, { ...resp.entity }, resp);
|
|
60
|
-
if (resp.validation)
|
|
61
|
-
out.validation = resp.validation;
|
|
62
|
-
output(this, out, { keyValue: true });
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
catch (err) {
|
|
66
|
-
errorOutput(err);
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
create
|
|
70
|
-
.command("dimension")
|
|
71
|
-
.description("Create a new dimension")
|
|
72
|
-
.requiredOption("--name <name>", "Dimension name (UPPER_SNAKE_CASE)")
|
|
73
|
-
.requiredOption("--expr <expr>", "SQL expression")
|
|
74
|
-
.requiredOption("--table <table>", "Primary table")
|
|
75
|
-
.option("--type <type>", "Semantic type: categorical, temporal, quantitative, boolean, geographic (auto-inferred if omitted)")
|
|
76
|
-
.option("--output-type <outputType>", "SQL output type: VARCHAR, NUMBER, BOOLEAN, DATE, TIMESTAMP (auto-inferred if omitted)")
|
|
77
|
-
.option("--description <desc>", "Business meaning of the dimension - what it slices and when to use it", "")
|
|
78
|
-
.option("--topics <topics>", "Comma-separated topic names")
|
|
79
|
-
.option("--skip-validate", "Skip pre-creation data validation")
|
|
80
|
-
.option("--unverified", "Create as a draft instead of verified (default: verified)")
|
|
81
|
-
.action(async function () {
|
|
82
|
-
try {
|
|
83
|
-
const opts = this.opts();
|
|
84
|
-
const fmt = getOutputFormat(this);
|
|
85
|
-
const topics = opts.topics ? opts.topics.split(",").map((s) => s.trim()).filter(Boolean) : [];
|
|
86
|
-
const body = {
|
|
87
|
-
name: opts.name,
|
|
88
|
-
expression: opts.expr,
|
|
89
|
-
table: opts.table,
|
|
90
|
-
description: opts.description,
|
|
91
|
-
topics,
|
|
92
|
-
unverified: Boolean(opts.unverified),
|
|
93
|
-
};
|
|
94
|
-
if (opts.type)
|
|
95
|
-
body.semantic_type = opts.type;
|
|
96
|
-
if (opts.outputType)
|
|
97
|
-
body.output_type = opts.outputType;
|
|
98
|
-
const skipValidate = opts.skipValidate ? "true" : "false";
|
|
99
|
-
const resp = await apiClient.post(`/api/v1/cli/kb/dimension?skip_validate=${skipValidate}`, body);
|
|
100
|
-
if (fmt === "styled") {
|
|
101
|
-
styledIntro(`graphit kb create dimension`);
|
|
102
|
-
styledSuccess(`Dimension ${formatBold(String(resp.entity.name))} created`);
|
|
103
|
-
renderValidation(this, resp);
|
|
104
|
-
renderVisibility(this, resp);
|
|
105
|
-
styledOutro();
|
|
106
|
-
}
|
|
107
|
-
else {
|
|
108
|
-
const out = withVisibility(this, { ...resp.entity }, resp);
|
|
109
|
-
if (resp.validation)
|
|
110
|
-
out.validation = resp.validation;
|
|
111
|
-
output(this, out, { keyValue: true });
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
catch (err) {
|
|
115
|
-
errorOutput(err);
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
create
|
|
119
|
-
.command("rule")
|
|
120
|
-
.description("Create a new rule. Without --apply-on the rule governs the whole --table, which cascades to every metric and dimension on it. Use --apply-on metric:NAME / dimension:NAME to govern only specific assets instead. A rule must apply to at least one asset (targetless rules are rejected).")
|
|
121
|
-
.requiredOption("--name <name>", "Rule name (UPPER_SNAKE_CASE)")
|
|
122
|
-
.requiredOption("--sql <expr>", "Rule content/SQL")
|
|
123
|
-
.requiredOption("--table <table>", "Table the rule is about (validation context, and the whole-table target unless --apply-on narrows it)")
|
|
124
|
-
.option("--description <desc>", "What the rule enforces and why it exists", "")
|
|
125
|
-
.option("--topics <topics>", "Comma-separated topic names")
|
|
126
|
-
.option("--constraint <spec...>", "Enforceable constraints (e.g., required_where:\"x=1\" forbidden_column:email)")
|
|
127
|
-
.option("--enforcement-mode <mode>", "Rule enforcement: advisory|always|conditional")
|
|
128
|
-
.option("--apply-on <targets...>", "What the rule governs. Omit to govern the whole --table (cascades to every metric/dimension on it). Use metric:NAME / dimension:NAME to govern only those assets. Cannot mix a table target with metric/dimension targets.")
|
|
129
|
-
.option("--skip-validate", "Skip pre-creation data validation")
|
|
130
|
-
.option("--unverified", "Create as a draft instead of verified (default: verified)")
|
|
131
|
-
.action(async function () {
|
|
132
|
-
try {
|
|
133
|
-
const opts = this.opts();
|
|
134
|
-
const fmt = getOutputFormat(this);
|
|
135
|
-
const topics = opts.topics ? opts.topics.split(",").map((s) => s.trim()).filter(Boolean) : [];
|
|
136
|
-
const constraints = opts.constraint ? parseConstraintFlags(opts.constraint) : undefined;
|
|
137
|
-
const applyOn = opts.applyOn ? parseApplyOnFlags(opts.applyOn) : undefined;
|
|
138
|
-
const skipValidate = opts.skipValidate ? "true" : "false";
|
|
139
|
-
const resp = await apiClient.post(`/api/v1/cli/kb/rule?skip_validate=${skipValidate}`, {
|
|
140
|
-
name: opts.name,
|
|
141
|
-
content: opts.sql,
|
|
142
|
-
table: opts.table,
|
|
143
|
-
description: opts.description,
|
|
144
|
-
topics,
|
|
145
|
-
constraints,
|
|
146
|
-
enforcement_mode: opts.enforcementMode,
|
|
147
|
-
apply_on: applyOn,
|
|
148
|
-
unverified: Boolean(opts.unverified),
|
|
149
|
-
});
|
|
150
|
-
if (fmt === "styled") {
|
|
151
|
-
styledIntro(`graphit kb create rule`);
|
|
152
|
-
styledSuccess(`Rule ${formatBold(String(resp.entity.name))} created`);
|
|
153
|
-
renderValidation(this, resp);
|
|
154
|
-
renderVisibility(this, resp);
|
|
155
|
-
styledOutro();
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
158
|
-
const out = withVisibility(this, { ...resp.entity }, resp);
|
|
159
|
-
if (resp.validation)
|
|
160
|
-
out.validation = resp.validation;
|
|
161
|
-
output(this, out, { keyValue: true });
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
catch (err) {
|
|
165
|
-
errorOutput(err);
|
|
166
|
-
}
|
|
167
|
-
});
|
|
168
|
-
create
|
|
169
|
-
.command("domain")
|
|
170
|
-
.description("Create a new domain")
|
|
171
|
-
.requiredOption("--name <name>", "Domain name (UPPER_SNAKE_CASE)")
|
|
172
|
-
.option("--description <desc>", "What this domain covers - the business area its tables and assets belong to", "")
|
|
173
|
-
.option("--color <hex>", "Hex color for UI", "#4DB6AC")
|
|
174
|
-
.action(async function () {
|
|
175
|
-
try {
|
|
176
|
-
const opts = this.opts();
|
|
177
|
-
const resp = await apiClient.post("/api/v1/cli/kb/domain", {
|
|
178
|
-
name: opts.name,
|
|
179
|
-
description: opts.description,
|
|
180
|
-
color: opts.color,
|
|
181
|
-
});
|
|
182
|
-
output(this, resp.entity, { keyValue: true });
|
|
183
|
-
}
|
|
184
|
-
catch (err) {
|
|
185
|
-
errorOutput(err);
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
create
|
|
189
|
-
.command("synonym")
|
|
190
|
-
.description("Create a new synonym")
|
|
191
|
-
.requiredOption("--term <term>", "Synonym term (e.g., GMV)")
|
|
192
|
-
.requiredOption("--canonical <name>", "Canonical asset name (e.g., TOTAL_REVENUE)")
|
|
193
|
-
.requiredOption("--type <type>", "Canonical type: metric, column, or table")
|
|
194
|
-
.option("--description <desc>", "When this synonym applies - the phrasing users say for the canonical asset", "")
|
|
195
|
-
.option("--unverified", "Create as a draft instead of verified (default: verified)")
|
|
196
|
-
.action(async function () {
|
|
197
|
-
try {
|
|
198
|
-
const opts = this.opts();
|
|
199
|
-
const resp = await apiClient.post("/api/v1/cli/kb/synonym", {
|
|
200
|
-
term: opts.term,
|
|
201
|
-
canonical: opts.canonical,
|
|
202
|
-
canonical_type: opts.type,
|
|
203
|
-
description: opts.description,
|
|
204
|
-
unverified: Boolean(opts.unverified),
|
|
205
|
-
});
|
|
206
|
-
renderVisibility(this, resp);
|
|
207
|
-
output(this, withVisibility(this, { ...resp.entity }, resp), { keyValue: true });
|
|
208
|
-
}
|
|
209
|
-
catch (err) {
|
|
210
|
-
errorOutput(err);
|
|
211
|
-
}
|
|
212
|
-
});
|
|
213
|
-
create
|
|
214
|
-
.command("relationship")
|
|
215
|
-
.description("Create a new relationship (JOIN between tables)")
|
|
216
|
-
.requiredOption("--name <name>", "Relationship name (e.g., ORDERS_TO_CUSTOMERS)")
|
|
217
|
-
.requiredOption("--primary-table <table>", "Primary table")
|
|
218
|
-
.requiredOption("--primary-column <col>", "Primary column")
|
|
219
|
-
.requiredOption("--related-table <table>", "Related table")
|
|
220
|
-
.requiredOption("--related-column <col>", "Related column")
|
|
221
|
-
.option("--description <desc>", "What this join represents in the business", "")
|
|
222
|
-
.action(async function () {
|
|
223
|
-
try {
|
|
224
|
-
const opts = this.opts();
|
|
225
|
-
const resp = await apiClient.post("/api/v1/cli/kb/relationship", {
|
|
226
|
-
name: opts.name,
|
|
227
|
-
primary_table: opts.primaryTable,
|
|
228
|
-
primary_column: opts.primaryColumn,
|
|
229
|
-
related_table: opts.relatedTable,
|
|
230
|
-
related_column: opts.relatedColumn,
|
|
231
|
-
description: opts.description,
|
|
232
|
-
});
|
|
233
|
-
renderVisibility(this, resp);
|
|
234
|
-
output(this, withVisibility(this, { ...resp.entity }, resp), { keyValue: true });
|
|
235
|
-
}
|
|
236
|
-
catch (err) {
|
|
237
|
-
errorOutput(err);
|
|
238
|
-
}
|
|
239
|
-
});
|
|
240
|
-
create
|
|
241
|
-
.command("topic")
|
|
242
|
-
.description("Create a new topic (business-concept tag)")
|
|
243
|
-
.requiredOption("--name <name>", "Topic name (UPPER_SNAKE_CASE)")
|
|
244
|
-
.option("--description <desc>", "What this topic tags - the business concept its assets share", "")
|
|
245
|
-
.action(async function () {
|
|
246
|
-
try {
|
|
247
|
-
const opts = this.opts();
|
|
248
|
-
const resp = await apiClient.post("/api/v1/cli/kb/topic", {
|
|
249
|
-
name: opts.name,
|
|
250
|
-
description: opts.description,
|
|
251
|
-
});
|
|
252
|
-
output(this, resp.entity, { keyValue: true });
|
|
253
|
-
}
|
|
254
|
-
catch (err) {
|
|
255
|
-
errorOutput(err);
|
|
256
|
-
}
|
|
257
|
-
});
|
|
258
|
-
create
|
|
259
|
-
.command("template")
|
|
260
|
-
.description("Create a reusable template (chart, KPI, or filter control)")
|
|
261
|
-
.requiredOption("--name <name>", "Template name (UPPER_SNAKE_CASE)")
|
|
262
|
-
.option("--render-code <code>", "JS function body for rendering")
|
|
263
|
-
.option("--file <path>", "Read render code from a local file")
|
|
264
|
-
.option("--description <desc>", "What the template renders and when to reach for it", "")
|
|
265
|
-
.option("--chart-types <types>", "Related chart types (comma-separated)", "")
|
|
266
|
-
.action(async function () {
|
|
267
|
-
try {
|
|
268
|
-
const opts = this.opts();
|
|
269
|
-
let renderCode;
|
|
270
|
-
if (opts.file) {
|
|
271
|
-
renderCode = await readFile(opts.file, "utf-8");
|
|
272
|
-
}
|
|
273
|
-
else if (opts.renderCode) {
|
|
274
|
-
renderCode = opts.renderCode;
|
|
275
|
-
}
|
|
276
|
-
else {
|
|
277
|
-
writeStderr(JSON.stringify({ error: "Provide --render-code or --file" }));
|
|
278
|
-
process.exit(1);
|
|
279
|
-
}
|
|
280
|
-
const chartTypes = opts.chartTypes
|
|
281
|
-
? opts.chartTypes.split(",").map((s) => s.trim()).filter(Boolean)
|
|
282
|
-
: [];
|
|
283
|
-
const resp = await apiClient.post("/api/v1/cli/kb/template", {
|
|
284
|
-
name: opts.name,
|
|
285
|
-
render_code: renderCode,
|
|
286
|
-
description: opts.description,
|
|
287
|
-
chart_types: chartTypes,
|
|
288
|
-
});
|
|
289
|
-
output(this, resp.entity, { keyValue: true });
|
|
290
|
-
}
|
|
291
|
-
catch (err) {
|
|
292
|
-
errorOutput(err);
|
|
293
|
-
}
|
|
294
|
-
});
|
|
295
|
-
}
|
|
296
|
-
//# sourceMappingURL=kb-create.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"kb-create.js","sourceRoot":"","sources":["../../src/commands/kb-create.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { apiClient } from "../api/client.js";
|
|
2
|
-
import { errorOutput } from "../output/format.js";
|
|
3
|
-
import { writeStderr } from "../stderr.js";
|
|
4
|
-
import { KB_ARG_TYPE, KB_ARG_NAME } from "./kb-shared.js";
|
|
5
|
-
// Project #254 Phase 1: kb delete verb.
|
|
6
|
-
export function addKBDeleteCommands(kb) {
|
|
7
|
-
kb.command("delete")
|
|
8
|
-
.argument("<type>", KB_ARG_TYPE)
|
|
9
|
-
.argument("<name>", KB_ARG_NAME)
|
|
10
|
-
.description("Delete a KB entity (requires --yes flag)")
|
|
11
|
-
.requiredOption("--yes", "Confirm deletion")
|
|
12
|
-
// Project #272 F-6: a private asset belonging to another member can block a
|
|
13
|
-
// shared asset's delete, and the refusal names who to ask. --force is the
|
|
14
|
-
// other half of that: it proceeds anyway, and the backend notifies them.
|
|
15
|
-
// Deliberately NOT a second confirmation prompt (founder decision 4) - --yes
|
|
16
|
-
// already covers the destructive action, and a second gate teaches people to
|
|
17
|
-
// click through gates.
|
|
18
|
-
.option("--force", "Delete even though another member's private asset blocks it")
|
|
19
|
-
.action(async function (type, name) {
|
|
20
|
-
try {
|
|
21
|
-
const validTypes = ["metric", "dimension", "rule", "template", "synonym", "domain", "relationship", "topic"];
|
|
22
|
-
if (!validTypes.includes(type)) {
|
|
23
|
-
writeStderr(JSON.stringify({
|
|
24
|
-
error: `Delete not supported for '${type}'. Supported: ${validTypes.join(", ")}`,
|
|
25
|
-
}));
|
|
26
|
-
process.exit(1);
|
|
27
|
-
}
|
|
28
|
-
const force = this.opts().force === true;
|
|
29
|
-
await apiClient.delete(`/api/v1/cli/kb/${type}/${encodeURIComponent(name)}${force ? "?force=true" : ""}`);
|
|
30
|
-
console.log(JSON.stringify({ status: "deleted", type, name: name.toUpperCase(), ...(force ? { forced: true } : {}) }));
|
|
31
|
-
}
|
|
32
|
-
catch (err) {
|
|
33
|
-
errorOutput(err);
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
//# sourceMappingURL=kb-delete.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"kb-delete.js","sourceRoot":"","sources":["../../src/commands/kb-delete.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE1D,wCAAwC;AAExC,MAAM,UAAU,mBAAmB,CAAC,EAAW;IAC7C,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC;SACjB,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;SAC/B,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;SAC/B,WAAW,CAAC,0CAA0C,CAAC;SACvD,cAAc,CAAC,OAAO,EAAE,kBAAkB,CAAC;QAC5C,4EAA4E;QAC5E,0EAA0E;QAC1E,yEAAyE;QACzE,6EAA6E;QAC7E,6EAA6E;QAC7E,uBAAuB;SACtB,MAAM,CAAC,SAAS,EAAE,6DAA6D,CAAC;SAChF,MAAM,CAAC,KAAK,WAA0B,IAAY,EAAE,IAAY;QAC/D,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,CAAC,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;YAC7G,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC/B,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC;oBACzB,KAAK,EAAE,6BAA6B,IAAI,iBAAiB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;iBACjF,CAAC,CAAC,CAAC;gBACJ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC;YACzC,MAAM,SAAS,CAAC,MAAM,CACpB,kBAAkB,IAAI,IAAI,kBAAkB,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAClF,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACzH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|