@ifc-lite/flow-nodes 0.2.0 → 0.5.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 +1 -0
- package/dist/apply-table-node.d.ts.map +1 -1
- package/dist/apply-table-node.js +7 -6
- package/dist/apply-table-node.js.map +1 -1
- package/dist/aps-client.d.ts +55 -0
- package/dist/aps-client.d.ts.map +1 -0
- package/dist/aps-client.js +194 -0
- package/dist/aps-client.js.map +1 -0
- package/dist/aps-nodes.d.ts +3 -0
- package/dist/aps-nodes.d.ts.map +1 -0
- package/dist/aps-nodes.js +192 -0
- package/dist/aps-nodes.js.map +1 -0
- package/dist/aps-table.d.ts +24 -0
- package/dist/aps-table.d.ts.map +1 -0
- package/dist/aps-table.js +123 -0
- package/dist/aps-table.js.map +1 -0
- package/dist/base64.d.ts +8 -0
- package/dist/base64.d.ts.map +1 -0
- package/dist/base64.js +59 -0
- package/dist/base64.js.map +1 -0
- package/dist/bcf-client.d.ts +36 -0
- package/dist/bcf-client.d.ts.map +1 -0
- package/dist/bcf-client.js +108 -0
- package/dist/bcf-client.js.map +1 -0
- package/dist/bcf-nodes.d.ts +3 -0
- package/dist/bcf-nodes.d.ts.map +1 -0
- package/dist/bcf-nodes.js +181 -0
- package/dist/bcf-nodes.js.map +1 -0
- package/dist/csv-nodes.d.ts.map +1 -1
- package/dist/csv-nodes.js +3 -4
- package/dist/csv-nodes.js.map +1 -1
- package/dist/documents-fetch.d.ts +23 -0
- package/dist/documents-fetch.d.ts.map +1 -0
- package/dist/documents-fetch.js +48 -0
- package/dist/documents-fetch.js.map +1 -0
- package/dist/documents-nodes.d.ts +5 -0
- package/dist/documents-nodes.d.ts.map +1 -0
- package/dist/documents-nodes.js +167 -0
- package/dist/documents-nodes.js.map +1 -0
- package/dist/host.d.ts +28 -0
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js.map +1 -1
- package/dist/http-request-node.d.ts +9 -0
- package/dist/http-request-node.d.ts.map +1 -0
- package/dist/http-request-node.js +109 -0
- package/dist/http-request-node.js.map +1 -0
- package/dist/index.d.ts +20 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -5
- package/dist/index.js.map +1 -1
- package/dist/model-nodes.d.ts.map +1 -1
- package/dist/model-nodes.js +11 -6
- package/dist/model-nodes.js.map +1 -1
- package/dist/open-model-node.d.ts +3 -0
- package/dist/open-model-node.d.ts.map +1 -0
- package/dist/open-model-node.js +47 -0
- package/dist/open-model-node.js.map +1 -0
- package/dist/script-node.d.ts.map +1 -1
- package/dist/script-node.js +55 -21
- package/dist/script-node.js.map +1 -1
- package/dist/secrets.d.ts +88 -0
- package/dist/secrets.d.ts.map +1 -0
- package/dist/secrets.js +202 -0
- package/dist/secrets.js.map +1 -0
- package/dist/speckle/client.d.ts +52 -0
- package/dist/speckle/client.d.ts.map +1 -0
- package/dist/speckle/client.js +153 -0
- package/dist/speckle/client.js.map +1 -0
- package/dist/speckle/geometry.d.ts +37 -0
- package/dist/speckle/geometry.d.ts.map +1 -0
- package/dist/speckle/geometry.js +126 -0
- package/dist/speckle/geometry.js.map +1 -0
- package/dist/speckle/mapping.d.ts +62 -0
- package/dist/speckle/mapping.d.ts.map +1 -0
- package/dist/speckle/mapping.js +208 -0
- package/dist/speckle/mapping.js.map +1 -0
- package/dist/speckle/parameters.d.ts +49 -0
- package/dist/speckle/parameters.d.ts.map +1 -0
- package/dist/speckle/parameters.js +95 -0
- package/dist/speckle/parameters.js.map +1 -0
- package/dist/speckle/refusals.d.ts +45 -0
- package/dist/speckle/refusals.d.ts.map +1 -0
- package/dist/speckle/refusals.js +40 -0
- package/dist/speckle/refusals.js.map +1 -0
- package/dist/speckle/units.d.ts +13 -0
- package/dist/speckle/units.d.ts.map +1 -0
- package/dist/speckle/units.js +59 -0
- package/dist/speckle/units.js.map +1 -0
- package/dist/speckle/url.d.ts +35 -0
- package/dist/speckle/url.d.ts.map +1 -0
- package/dist/speckle/url.js +48 -0
- package/dist/speckle/url.js.map +1 -0
- package/dist/speckle-receive-node.d.ts +9 -0
- package/dist/speckle-receive-node.d.ts.map +1 -0
- package/dist/speckle-receive-node.js +180 -0
- package/dist/speckle-receive-node.js.map +1 -0
- package/dist/xlsx-io.d.ts.map +1 -1
- package/dist/xlsx-io.js +3 -3
- package/dist/xlsx-io.js.map +1 -1
- package/dist/xlsx-nodes.d.ts.map +1 -1
- package/dist/xlsx-nodes.js +1 -40
- package/dist/xlsx-nodes.js.map +1 -1
- package/package.json +11 -9
- package/dist/strict-cell.d.ts +0 -20
- package/dist/strict-cell.d.ts.map +0 -1
- package/dist/strict-cell.js +0 -33
- package/dist/strict-cell.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -3,12 +3,18 @@
|
|
|
3
3
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
4
|
import { NodeRegistry } from '@ifc-lite/flow';
|
|
5
5
|
import { applyTableNode } from './apply-table-node.js';
|
|
6
|
+
import { bcfNodes } from './bcf-nodes.js';
|
|
7
|
+
import { apsNodes } from './aps-nodes.js';
|
|
6
8
|
import { connectorNodes } from './connector-nodes.js';
|
|
7
9
|
import { coreNodes } from './core-nodes.js';
|
|
8
10
|
import { csvNodes } from './csv-nodes.js';
|
|
11
|
+
import { documentsNodes } from './documents-nodes.js';
|
|
9
12
|
import { elementNodes } from './element-nodes.js';
|
|
13
|
+
import { httpRequestNode } from './http-request-node.js';
|
|
10
14
|
import { modelNodes } from './model-nodes.js';
|
|
15
|
+
import { openModelNode } from './open-model-node.js';
|
|
11
16
|
import { scriptListNode, scriptNode } from './script-node.js';
|
|
17
|
+
import { speckleReceiveNode } from './speckle-receive-node.js';
|
|
12
18
|
import { tableNodes } from './table-nodes.js';
|
|
13
19
|
import { viewerNodes } from './viewer-nodes.js';
|
|
14
20
|
import { writeNodes } from './write-nodes.js';
|
|
@@ -16,6 +22,7 @@ import { xlsxNodes } from './xlsx-nodes.js';
|
|
|
16
22
|
export { requireCapability, toRef, toSdkRef, resolveByGlobalId, rememberGlobalId, forgetGlobalId, invalidateGlobalIdIndex } from './host.js';
|
|
17
23
|
export { columnTypeOf, VALUE_TYPE_BY_COLUMN_TYPE } from './table-nodes.js';
|
|
18
24
|
export { readXlsxTable, writeXlsxTable } from './xlsx-io.js';
|
|
25
|
+
export { declaredSecrets, referencedSecrets, validateSecretReferences, resolveSecretValues, interpolateSecrets, buildRedactionMap, redactText, redactDeep, MIN_REDACTED_SECRET_LENGTH, usableSecretNames, } from './secrets.js';
|
|
19
26
|
/** Every standard node, in one registry. */
|
|
20
27
|
export function createStandardRegistry() {
|
|
21
28
|
return new NodeRegistry().registerAll([
|
|
@@ -31,20 +38,42 @@ export function createStandardRegistry() {
|
|
|
31
38
|
applyTableNode,
|
|
32
39
|
scriptNode,
|
|
33
40
|
scriptListNode,
|
|
41
|
+
httpRequestNode,
|
|
42
|
+
...bcfNodes,
|
|
43
|
+
...apsNodes,
|
|
44
|
+
speckleReceiveNode,
|
|
45
|
+
...documentsNodes,
|
|
46
|
+
openModelNode,
|
|
34
47
|
]);
|
|
35
48
|
}
|
|
36
|
-
/**
|
|
49
|
+
/**
|
|
50
|
+
* What a viewer-embedded host offers. `network` is `true`: the viewer DOES
|
|
51
|
+
* attempt `network.fetch` (subject to the browser's own CORS enforcement —
|
|
52
|
+
* a blocked request surfaces as an explicit CORS error, not an empty
|
|
53
|
+
* success; see `HttpRequest`'s node doc and `runner.ts`). `secrets` is
|
|
54
|
+
* always empty: the browser has no `process.env` and must never persist a
|
|
55
|
+
* secret, so a graph that references one shows `unavailable` before it
|
|
56
|
+
* runs rather than failing mid-run (#5167 phase 3.5).
|
|
57
|
+
*/
|
|
37
58
|
export const BROWSER_FEATURES = {
|
|
38
|
-
backend: new Set(['viewer', 'visibility', 'selection', 'mutate', 'store', 'files', 'sandbox']),
|
|
39
|
-
network:
|
|
59
|
+
backend: new Set(['viewer', 'visibility', 'selection', 'mutate', 'store', 'files', 'sandbox', 'openModel']),
|
|
60
|
+
network: true,
|
|
40
61
|
secrets: new Set(),
|
|
41
62
|
};
|
|
42
63
|
/**
|
|
43
|
-
* What the CLI's
|
|
64
|
+
* What the CLI's / MCP's headless backend offers. It implements the viewer
|
|
44
65
|
* methods as inert no-ops, so `viewer`/`visibility`/`selection` are
|
|
45
66
|
* deliberately absent here: a viewer node must report `noop`, not pretend.
|
|
67
|
+
* `network` is always `true`: both headless callers have a real, unrestricted
|
|
68
|
+
* `fetch` (no CORS), so a `network.fetch` bridge is always configured — the
|
|
69
|
+
* per-request host allow-list check still runs against the graph's actual
|
|
70
|
+
* grants (see `network-request.ts`). `secrets` is exactly the set of env var
|
|
71
|
+
* names the caller passes (CLI: `Object.keys(process.env)`; MCP: the same —
|
|
72
|
+
* see `flow.ts` in `@ifc-lite/cli` and `@ifc-lite/mcp`), never guessed here.
|
|
73
|
+
* `openModel` is listed because both headless callers implement
|
|
74
|
+
* `FlowHost.openModel` (`model.openFromSource`).
|
|
46
75
|
*/
|
|
47
76
|
export function headlessFeatures(secrets = []) {
|
|
48
|
-
return { backend: new Set(['mutate', 'store', 'files', 'sandbox']), network:
|
|
77
|
+
return { backend: new Set(['mutate', 'store', 'files', 'sandbox', 'openModel']), network: true, secrets: new Set(secrets) };
|
|
49
78
|
}
|
|
50
79
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D,OAAO,EAAE,YAAY,EAAqB,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D,OAAO,EAAE,YAAY,EAAqB,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAC7I,OAAO,EAAE,YAAY,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAE3E,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG7D,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,wBAAwB,EACxB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,UAAU,EACV,0BAA0B,EAC1B,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAGtB,4CAA4C;AAC5C,MAAM,UAAU,sBAAsB;IACpC,OAAO,IAAI,YAAY,EAAY,CAAC,WAAW,CAAC;QAC9C,GAAG,SAAS;QACZ,GAAG,UAAU;QACb,GAAG,UAAU;QACb,GAAG,WAAW;QACd,GAAG,UAAU;QACb,GAAG,YAAY;QACf,GAAG,QAAQ;QACX,GAAG,SAAS;QACZ,GAAG,cAAc;QACjB,cAAc;QACd,UAAU;QACV,cAAc;QACd,eAAe;QACf,GAAG,QAAQ;QACX,GAAG,QAAQ;QACX,kBAAkB;QAClB,GAAG,cAAc;QACjB,aAAa;KACd,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAiB;IAC5C,OAAO,EAAE,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;IAC3G,OAAO,EAAE,IAAI;IACb,OAAO,EAAE,IAAI,GAAG,EAAE;CACnB,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,gBAAgB,CAAC,UAA4B,EAAE;IAC7D,OAAO,EAAE,OAAO,EAAE,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;AAC9H,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-nodes.d.ts","sourceRoot":"","sources":["../src/model-nodes.ts"],"names":[],"mappings":"AAaA,OAAO,EAUL,KAAK,WAAW,EACjB,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"model-nodes.d.ts","sourceRoot":"","sources":["../src/model-nodes.ts"],"names":[],"mappings":"AAaA,OAAO,EAUL,KAAK,WAAW,EACjB,MAAM,WAAW,CAAC;AAmBnB,eAAO,MAAM,UAAU,EAAE,WAAW,EAwLnC,CAAC"}
|
package/dist/model-nodes.js
CHANGED
|
@@ -12,13 +12,18 @@ function query(ctx, modelId) {
|
|
|
12
12
|
const id = typeof modelId === 'string' && modelId.length > 0 ? modelId : ctx.host.defaultModelId;
|
|
13
13
|
return id ? q.model(id) : q;
|
|
14
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Optional model id wired from `model.openFromSource`: it wins over the
|
|
17
|
+
* `model` param, and the edge makes the read run after the model is open.
|
|
18
|
+
*/
|
|
19
|
+
const MODEL_ID_INPUT = { name: 'modelId', type: SCALAR_ITEM, optional: true, nullable: true };
|
|
15
20
|
export const modelNodes = [
|
|
16
21
|
{
|
|
17
22
|
type: 'model.select',
|
|
18
23
|
title: 'Select',
|
|
19
24
|
category: 'model',
|
|
20
25
|
doc: 'Entities matching an IfcOpenShell-style selector, e.g. `IfcWall, Pset_WallCommon.IsExternal=TRUE`.',
|
|
21
|
-
inputs: [],
|
|
26
|
+
inputs: [MODEL_ID_INPUT],
|
|
22
27
|
outputs: [{ name: 'entities', type: ENTITY_LIST }],
|
|
23
28
|
params: [
|
|
24
29
|
{ name: 'selector', kind: 'string', default: 'IfcWall' },
|
|
@@ -26,16 +31,16 @@ export const modelNodes = [
|
|
|
26
31
|
],
|
|
27
32
|
capabilities: ['model.read'],
|
|
28
33
|
reads: 'model',
|
|
29
|
-
run: (ctx,
|
|
34
|
+
run: (ctx, i, p) => {
|
|
30
35
|
requireCapability(ctx, 'model.read');
|
|
31
|
-
return { entities: query(ctx, p.model).select(str(p.selector, 'selector')).toArray().map(toRef) };
|
|
36
|
+
return { entities: query(ctx, i.modelId ?? p.model).select(str(p.selector, 'selector')).toArray().map(toRef) };
|
|
32
37
|
},
|
|
33
38
|
},
|
|
34
39
|
{
|
|
35
40
|
type: 'model.byType',
|
|
36
41
|
title: 'By type',
|
|
37
42
|
category: 'model',
|
|
38
|
-
inputs: [],
|
|
43
|
+
inputs: [MODEL_ID_INPUT],
|
|
39
44
|
outputs: [{ name: 'entities', type: ENTITY_LIST }],
|
|
40
45
|
params: [
|
|
41
46
|
{ name: 'type', kind: 'string', default: 'IfcWall' },
|
|
@@ -43,9 +48,9 @@ export const modelNodes = [
|
|
|
43
48
|
],
|
|
44
49
|
capabilities: ['model.read'],
|
|
45
50
|
reads: 'model',
|
|
46
|
-
run: (ctx,
|
|
51
|
+
run: (ctx, i, p) => {
|
|
47
52
|
requireCapability(ctx, 'model.read');
|
|
48
|
-
return { entities: query(ctx, p.model).byType(str(p.type, 'type')).toArray().map(toRef) };
|
|
53
|
+
return { entities: query(ctx, i.modelId ?? p.model).byType(str(p.type, 'type')).toArray().map(toRef) };
|
|
49
54
|
},
|
|
50
55
|
},
|
|
51
56
|
{
|
package/dist/model-nodes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-nodes.js","sourceRoot":"","sources":["../src/model-nodes.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAW/D,OAAO,EACL,YAAY,EACZ,WAAW,EACX,WAAW,EACX,WAAW,EACX,QAAQ,EACR,iBAAiB,EACjB,KAAK,EACL,QAAQ,GAGT,MAAM,WAAW,CAAC;AAEnB,MAAM,GAAG,GAAG,CAAC,CAAU,EAAE,IAAY,EAAU,EAAE;IAC/C,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,IAAI,IAAI,8BAA8B,CAAC,CAAC;IACrG,OAAO,CAAC,CAAC;AACX,CAAC,CAAC;AAEF,SAAS,KAAK,CAAC,GAAQ,EAAE,OAAgB;IACvC,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;IAC/B,MAAM,EAAE,GAAG,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC;IACjG,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAkB;IACvC;QACE,IAAI,EAAE,cAAc;QACpB,KAAK,EAAE,QAAQ;QACf,QAAQ,EAAE,OAAO;QACjB,GAAG,EAAE,oGAAoG;QACzG,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"model-nodes.js","sourceRoot":"","sources":["../src/model-nodes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-model-node.d.ts","sourceRoot":"","sources":["../src/open-model-node.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAkC,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7E,eAAO,MAAM,aAAa,EAAE,WA2B3B,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
/**
|
|
5
|
+
* `model.openFromSource` — open a file a previous node fetched (typically
|
|
6
|
+
* `documents.download`) as a model, through the host's own load path
|
|
7
|
+
* (`FlowHost.openModel`): the viewer's canonical `addModel`/`loadFile`
|
|
8
|
+
* pipeline, or the CLI's / MCP's headless loader. The node never parses
|
|
9
|
+
* the bytes itself, so no second ingest pipeline exists.
|
|
10
|
+
*
|
|
11
|
+
* The `modelId` output is what sequences the rest of the graph: wire it
|
|
12
|
+
* into `model.select` / `model.byType`'s `modelId` input so those reads
|
|
13
|
+
* run after the model is open and address it.
|
|
14
|
+
*/
|
|
15
|
+
import { fromBase64 } from './base64.js';
|
|
16
|
+
import { requireCapability, SCALAR_ITEM } from './host.js';
|
|
17
|
+
export const openModelNode = {
|
|
18
|
+
type: 'model.openFromSource',
|
|
19
|
+
title: 'Open model from source',
|
|
20
|
+
category: 'model',
|
|
21
|
+
doc: 'Opens a downloaded IFC file (base64 `data`, e.g. from Download document) as a model on the host. Wire `modelId` into a model read node to query the opened model.',
|
|
22
|
+
inputs: [
|
|
23
|
+
{ name: 'data', type: SCALAR_ITEM },
|
|
24
|
+
{ name: 'name', type: SCALAR_ITEM, optional: true, nullable: true },
|
|
25
|
+
],
|
|
26
|
+
outputs: [{ name: 'modelId', type: SCALAR_ITEM }],
|
|
27
|
+
params: [{ name: 'name', kind: 'string', default: 'model.ifc', doc: 'File name, used when the `name` input is not wired; its extension picks the format.' }],
|
|
28
|
+
capabilities: ['model.create'],
|
|
29
|
+
requires: { backend: ['openModel'] },
|
|
30
|
+
// Loading a model changes what every later read sees, so it is a write
|
|
31
|
+
// (never memoised, and it advances the cache's write generation).
|
|
32
|
+
writes: 'model',
|
|
33
|
+
volatile: true,
|
|
34
|
+
run: async (ctx, i, p) => {
|
|
35
|
+
requireCapability(ctx, 'model.create');
|
|
36
|
+
const open = ctx.host.openModel;
|
|
37
|
+
if (!open)
|
|
38
|
+
throw new Error('model.openFromSource: this host cannot open models');
|
|
39
|
+
const bytes = fromBase64(typeof i.data === 'string' ? i.data : '');
|
|
40
|
+
if (bytes.byteLength === 0)
|
|
41
|
+
throw new Error('model.openFromSource: "data" is empty');
|
|
42
|
+
const name = typeof i.name === 'string' && i.name.length > 0 ? i.name : typeof p.name === 'string' && p.name.length > 0 ? p.name : 'model.ifc';
|
|
43
|
+
const { modelId } = await open.call(ctx.host, bytes, name);
|
|
44
|
+
return { modelId };
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
//# sourceMappingURL=open-model-node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-model-node.js","sourceRoot":"","sources":["../src/open-model-node.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAoB,MAAM,WAAW,CAAC;AAE7E,MAAM,CAAC,MAAM,aAAa,GAAgB;IACxC,IAAI,EAAE,sBAAsB;IAC5B,KAAK,EAAE,wBAAwB;IAC/B,QAAQ,EAAE,OAAO;IACjB,GAAG,EAAE,mKAAmK;IACxK,MAAM,EAAE;QACN,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE;QACnC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;KACpE;IACD,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IACjD,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,qFAAqF,EAAE,CAAC;IAC5J,YAAY,EAAE,CAAC,cAAc,CAAC;IAC9B,QAAQ,EAAE,EAAE,OAAO,EAAE,CAAC,WAAW,CAAC,EAAE;IACpC,uEAAuE;IACvE,kEAAkE;IAClE,MAAM,EAAE,OAAO;IACf,QAAQ,EAAE,IAAI;IACd,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE;QACvB,iBAAiB,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QACvC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;QAChC,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;QACjF,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACnE,IAAI,KAAK,CAAC,UAAU,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QACrF,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC;QAC/I,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAC3D,OAAO,EAAE,OAAO,EAAE,CAAC;IACrB,CAAC;CACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"script-node.d.ts","sourceRoot":"","sources":["../src/script-node.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"script-node.d.ts","sourceRoot":"","sources":["../src/script-node.ts"],"names":[],"mappings":"AA8BA,OAAO,EAAmD,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AA0H9F,eAAO,MAAM,UAAU,EAAE,WAgBxB,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,WAsB5B,CAAC"}
|
package/dist/script-node.js
CHANGED
|
@@ -17,38 +17,57 @@
|
|
|
17
17
|
* no `bcf`, `ids`, `spatial`); that difference is documented, not papered
|
|
18
18
|
* over. Sandbox permissions are derived from the graph's grants: mutation
|
|
19
19
|
* is only enabled when a `model.mutate` grant exists.
|
|
20
|
+
*
|
|
21
|
+
* A lane whose code made a network request calls `ctx.markVolatile()`, so
|
|
22
|
+
* the scheduler does not memoise that run: rerunning the graph fetches
|
|
23
|
+
* again instead of replaying a stale response. A script that never calls
|
|
24
|
+
* `bim.network.fetch` stays memoisable even in a graph holding a grant.
|
|
20
25
|
*/
|
|
21
26
|
import { createSandbox } from '@ifc-lite/sandbox';
|
|
22
27
|
import { ANY_ITEM, ANY_LIST, requireCapability } from './host.js';
|
|
23
28
|
/**
|
|
24
|
-
* One sandbox per (BimContext, permission set), kept for the
|
|
25
|
-
* the context: QuickJS module init is the expensive part, and a
|
|
26
|
-
* several Script nodes (or a re-run) must not pay it per lane.
|
|
27
|
-
* rather than through `bim.sandbox` because that path
|
|
28
|
-
* `@ifc-lite/sandbox` relative to the SDK package, which
|
|
29
|
-
* install cannot resolve headlessly.
|
|
29
|
+
* One sandbox per (BimContext, transport, permission set), kept for the
|
|
30
|
+
* lifetime of the context: QuickJS module init is the expensive part, and a
|
|
31
|
+
* graph with several Script nodes (or a re-run) must not pay it per lane.
|
|
32
|
+
* Created here rather than through `bim.sandbox` because that path
|
|
33
|
+
* dynamically imports `@ifc-lite/sandbox` relative to the SDK package, which
|
|
34
|
+
* a pnpm-isolated install cannot resolve headlessly.
|
|
30
35
|
*/
|
|
31
36
|
const sandboxes = new WeakMap();
|
|
32
|
-
function sandboxFor(bim, permissions, timeoutMs) {
|
|
33
|
-
const key = JSON.stringify({ permissions, timeoutMs });
|
|
37
|
+
function sandboxFor(bim, permissions, timeoutMs, networkGrants, transport) {
|
|
38
|
+
const key = JSON.stringify({ permissions, timeoutMs, networkGrants });
|
|
34
39
|
let perContext = sandboxes.get(bim);
|
|
35
40
|
if (!perContext) {
|
|
36
41
|
perContext = new Map();
|
|
37
42
|
sandboxes.set(bim, perContext);
|
|
38
43
|
}
|
|
39
|
-
let
|
|
40
|
-
if (!
|
|
44
|
+
let perTransport = perContext.get(transport);
|
|
45
|
+
if (!perTransport) {
|
|
46
|
+
perTransport = new Map();
|
|
47
|
+
perContext.set(transport, perTransport);
|
|
48
|
+
}
|
|
49
|
+
const cache = perTransport;
|
|
50
|
+
let entry = cache.get(key);
|
|
51
|
+
if (!entry) {
|
|
52
|
+
const counting = (url, init) => {
|
|
53
|
+
created.requests += 1;
|
|
54
|
+
return transport ? transport(url, init) : fetch(url, init);
|
|
55
|
+
};
|
|
41
56
|
// A rejected creation (a wasm load failure, a transient resource limit)
|
|
42
57
|
// must not be cached: every later lane would await the same rejection for
|
|
43
58
|
// the lifetime of the context, turning one hiccup into a dead node.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
59
|
+
const sandbox = createSandbox(bim, {
|
|
60
|
+
permissions, limits: { timeoutMs }, network: { grants: networkGrants, transport: counting },
|
|
61
|
+
}).catch((err) => {
|
|
62
|
+
if (cache.get(key) === created)
|
|
63
|
+
cache.delete(key);
|
|
47
64
|
throw err;
|
|
48
65
|
});
|
|
49
|
-
|
|
66
|
+
const created = { sandbox, requests: 0 };
|
|
67
|
+
entry = created;
|
|
68
|
+
cache.set(key, entry);
|
|
50
69
|
}
|
|
51
|
-
return
|
|
70
|
+
return entry;
|
|
52
71
|
}
|
|
53
72
|
/** Evaluate `params.code` with `inputs` in scope and return its last expression. */
|
|
54
73
|
async function evaluate(ctx, inputs, params) {
|
|
@@ -57,6 +76,7 @@ async function evaluate(ctx, inputs, params) {
|
|
|
57
76
|
// read the model through a capability the graph never had.
|
|
58
77
|
requireCapability(ctx, 'model.read');
|
|
59
78
|
const grants = ctx.host.grants;
|
|
79
|
+
const networkGrants = ctx.host.networkGrants ?? [];
|
|
60
80
|
const has = (scope, action) => !grants || grants.some((g) => g.scope === scope && g.action === action);
|
|
61
81
|
const permissions = {
|
|
62
82
|
query: true,
|
|
@@ -67,6 +87,9 @@ async function evaluate(ctx, inputs, params) {
|
|
|
67
87
|
export: has('export', 'create'),
|
|
68
88
|
lens: true,
|
|
69
89
|
files: true,
|
|
90
|
+
// `bim.network` exists only when the graph holds a `network.fetch` grant;
|
|
91
|
+
// every call is still checked against those grants (#5446 review).
|
|
92
|
+
network: networkGrants.some((g) => g.scope === 'network' && g.action === 'fetch'),
|
|
70
93
|
};
|
|
71
94
|
const injected = JSON.stringify({ a: inputs.a ?? null, b: inputs.b ?? null, c: inputs.c ?? null });
|
|
72
95
|
// Every lane shares one sandbox, and QuickJS evaluates a program in the
|
|
@@ -79,12 +102,23 @@ async function evaluate(ctx, inputs, params) {
|
|
|
79
102
|
// `inputs` in scope, and the last expression as the value (`eval` returns
|
|
80
103
|
// its program's completion value, which a function body would not).
|
|
81
104
|
const code = `(function (inputs) { return eval(${JSON.stringify(String(params.code ?? ''))}); })(${injected})`;
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
105
|
+
const entry = sandboxFor(ctx.host.bim, permissions, Number(params.timeoutMs) || 30_000, networkGrants, ctx.host.networkTransport);
|
|
106
|
+
const sandbox = await entry.sandbox;
|
|
107
|
+
const requestsBefore = entry.requests;
|
|
108
|
+
let result;
|
|
109
|
+
try {
|
|
110
|
+
// Plain JavaScript by contract: skipping the TypeScript strip avoids
|
|
111
|
+
// initialising esbuild-wasm, which only works in the browser. It is also
|
|
112
|
+
// what keeps the wrapper above honest — the source reaches `eval`
|
|
113
|
+
// verbatim, not as something a transpiler rewrote.
|
|
114
|
+
result = await sandbox.eval(code, { typescript: false });
|
|
115
|
+
}
|
|
116
|
+
finally {
|
|
117
|
+
// In `finally`: a lane that fetched and then threw yields null under
|
|
118
|
+
// lifting, and that null must not be memoised either.
|
|
119
|
+
if (entry.requests !== requestsBefore)
|
|
120
|
+
ctx.markVolatile?.();
|
|
121
|
+
}
|
|
88
122
|
for (const entry of result.logs) {
|
|
89
123
|
const level = entry.level === 'error' ? 'error' : entry.level === 'warn' ? 'warn' : 'info';
|
|
90
124
|
ctx.log(level, entry.args.map((a) => (typeof a === 'string' ? a : JSON.stringify(a))).join(' '));
|
package/dist/script-node.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"script-node.js","sourceRoot":"","sources":["../src/script-node.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D
|
|
1
|
+
{"version":3,"file":"script-node.js","sourceRoot":"","sources":["../src/script-node.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secrets from the host environment (#5167 phase 3.5).
|
|
3
|
+
*
|
|
4
|
+
* A node param references a secret with `{{secret:NAME}}` inside a
|
|
5
|
+
* string value (or a string nested inside a `json`-kind param, e.g. a
|
|
6
|
+
* header map). The grammar itself is recognised by `@ifc-lite/flow`'s
|
|
7
|
+
* `referencedSecrets` (availability needs it too); this module is the one
|
|
8
|
+
* place declared-vs-referenced is cross-checked and `process.env` is read —
|
|
9
|
+
* shared by `packages/cli/src/commands/flow.ts` (`flow run`) and
|
|
10
|
+
* `packages/mcp/src/tools/flow.ts` (`run_flow`), the only two callers
|
|
11
|
+
* allowed to read `process.env` for a flow graph. The viewer never calls
|
|
12
|
+
* this module: `HostFeatures.secrets` is always the empty set there, so
|
|
13
|
+
* a graph referencing a secret shows `unavailable` before it runs (see
|
|
14
|
+
* `availability.ts`), not this module's validation error.
|
|
15
|
+
*
|
|
16
|
+
* Two checks run BEFORE any node executes:
|
|
17
|
+
* 1. every `{{secret:NAME}}` reference must be covered by a declared
|
|
18
|
+
* `secret.read:NAME` capability in the graph — an undeclared
|
|
19
|
+
* reference is a validation error, not a silently-empty string;
|
|
20
|
+
* 2. every declared-and-referenced secret must actually be set in the
|
|
21
|
+
* environment — a referenced-but-unset secret is also a validation
|
|
22
|
+
* error, not an empty string interpolated into a request.
|
|
23
|
+
*
|
|
24
|
+
* Redaction (`buildRedactionMap` / `redactDeep`) is a separate, later
|
|
25
|
+
* step the caller applies at the OUTER boundary — right before writing
|
|
26
|
+
* to stdout, an MCP response, or a log sink — so a secret value that
|
|
27
|
+
* reaches a remote response body (a server echoing back an Authorization
|
|
28
|
+
* header) and comes back into the run's own output is still caught, not
|
|
29
|
+
* just the point where `{{secret:NAME}}` was first substituted. See the
|
|
30
|
+
* module doc trade-offs below on the minimum-length cutoff.
|
|
31
|
+
*/
|
|
32
|
+
import { referencedSecrets, type FlowDocument } from '@ifc-lite/flow';
|
|
33
|
+
export { referencedSecrets };
|
|
34
|
+
export interface SecretValidationError {
|
|
35
|
+
readonly nodeId: string;
|
|
36
|
+
readonly param: string;
|
|
37
|
+
readonly name: string;
|
|
38
|
+
readonly reason: 'undeclared' | 'unset';
|
|
39
|
+
readonly message: string;
|
|
40
|
+
}
|
|
41
|
+
/** Every `secret:NAME` the graph's capabilities declare (from `secret.read:<NAME>` grants). */
|
|
42
|
+
export declare function declaredSecrets(doc: FlowDocument): ReadonlySet<string>;
|
|
43
|
+
/**
|
|
44
|
+
* Validate every `{{secret:NAME}}` reference against the graph's declared
|
|
45
|
+
* capabilities AND the environment, before any node runs. Returns an empty
|
|
46
|
+
* array when the graph is clean (including "no secrets used at all").
|
|
47
|
+
*/
|
|
48
|
+
export declare function validateSecretReferences(doc: FlowDocument, env: Readonly<Record<string, string | undefined>>): SecretValidationError[];
|
|
49
|
+
/** Resolve every declared-and-referenced secret's value from `env`. Call only after `validateSecretReferences` returns no errors. */
|
|
50
|
+
export declare function resolveSecretValues(doc: FlowDocument, env: Readonly<Record<string, string | undefined>>): ReadonlyMap<string, string>;
|
|
51
|
+
/** Return a new document with every `{{secret:NAME}}` reference in node params replaced by its resolved value. The input document is never mutated. */
|
|
52
|
+
export declare function interpolateSecrets(doc: FlowDocument, values: ReadonlyMap<string, string>): FlowDocument;
|
|
53
|
+
/** Minimum secret length worth redacting (see module doc): shorter values risk mass-redacting incidental substrings of ordinary text. */
|
|
54
|
+
export declare const MIN_REDACTED_SECRET_LENGTH = 6;
|
|
55
|
+
/**
|
|
56
|
+
* Reverse map (value → marker) for every resolved secret at least
|
|
57
|
+
* `MIN_REDACTED_SECRET_LENGTH` characters long. A secret shorter than
|
|
58
|
+
* that is a real gap (documented, not silently accepted): a 4-character
|
|
59
|
+
* token could coincide with ordinary text often enough that scrubbing it
|
|
60
|
+
* everywhere would make legitimate output unreadable, so this module
|
|
61
|
+
* accepts that a very short secret is not redactable by substring match
|
|
62
|
+
* at all.
|
|
63
|
+
*/
|
|
64
|
+
export declare function buildRedactionMap(values: ReadonlyMap<string, string>): ReadonlyMap<string, string>;
|
|
65
|
+
/**
|
|
66
|
+
* Replace every occurrence of a redacted secret value with its marker, in ONE
|
|
67
|
+
* pass, trying the longest value first at each position. Sequential
|
|
68
|
+
* replacement let a shorter secret inside a longer one match first
|
|
69
|
+
* (`abcdef` inside `abcdefghi` left `<secret:A>ghi`, exposing B's suffix),
|
|
70
|
+
* and could match inside a marker already written (#5446 review).
|
|
71
|
+
*/
|
|
72
|
+
export declare function redactText(text: string, redaction: ReadonlyMap<string, string>): string;
|
|
73
|
+
/**
|
|
74
|
+
* Walk an arbitrary JSON-ish value (a run summary, a log entry, a thrown
|
|
75
|
+
* error's message) and redact every string found, at any depth — this is
|
|
76
|
+
* what catches a secret that travelled through a response body and back
|
|
77
|
+
* into the run's own output, not just the literal param it was
|
|
78
|
+
* interpolated into.
|
|
79
|
+
*/
|
|
80
|
+
/**
|
|
81
|
+
* The env names a host may report as available secrets: set, and long
|
|
82
|
+
* enough to be redacted. `resolveSecretValues` refuses a shorter value, so
|
|
83
|
+
* counting it as available made `flow validate` pass a graph the run then
|
|
84
|
+
* refused (#5446 review).
|
|
85
|
+
*/
|
|
86
|
+
export declare function usableSecretNames(env: Readonly<Record<string, string | undefined>>): string[];
|
|
87
|
+
export declare function redactDeep<T>(value: T, redaction: ReadonlyMap<string, string>): T;
|
|
88
|
+
//# sourceMappingURL=secrets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../src/secrets.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,EAAE,iBAAiB,EAAqB,KAAK,YAAY,EAAiB,MAAM,gBAAgB,CAAC;AAExG,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAG7B,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,+FAA+F;AAC/F,wBAAgB,eAAe,CAAC,GAAG,EAAE,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,CAWtE;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,GAAG,qBAAqB,EAAE,CAyBtI;AAED,qIAAqI;AACrI,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAkBrI;AAaD,uJAAuJ;AACvJ,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,YAAY,CAQvG;AAED,yIAAyI;AACzI,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAE5C;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAWlG;AAMD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAKvF;AAED;;;;;;GAMG;AACH;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,GAAG,MAAM,EAAE,CAI7F;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAejF"}
|