@refrakt-md/runes 0.38.0 → 0.40.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/dist/attribute-presets.d.ts +3 -2
- package/dist/attribute-presets.d.ts.map +1 -1
- package/dist/attribute-presets.js +2 -1
- package/dist/attribute-presets.js.map +1 -1
- package/dist/collection-helpers.d.ts +21 -2
- package/dist/collection-helpers.d.ts.map +1 -1
- package/dist/collection-helpers.js +72 -15
- package/dist/collection-helpers.js.map +1 -1
- package/dist/composed-rune.d.ts +59 -0
- package/dist/composed-rune.d.ts.map +1 -0
- package/dist/composed-rune.js +129 -0
- package/dist/composed-rune.js.map +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +73 -40
- package/dist/config.js.map +1 -1
- package/dist/data-pipeline.d.ts +24 -10
- package/dist/data-pipeline.d.ts.map +1 -1
- package/dist/data-pipeline.js +34 -56
- package/dist/data-pipeline.js.map +1 -1
- package/dist/file-ref-resolve.js +9 -13
- package/dist/file-ref-resolve.js.map +1 -1
- package/dist/index.d.ts +14 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -5
- package/dist/index.js.map +1 -1
- package/dist/lib/composition.d.ts +152 -0
- package/dist/lib/composition.d.ts.map +1 -0
- package/dist/lib/composition.js +1120 -0
- package/dist/lib/composition.js.map +1 -0
- package/dist/lib/index.d.ts +63 -4
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +137 -8
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/preprocess.d.ts +64 -0
- package/dist/lib/preprocess.d.ts.map +1 -0
- package/dist/lib/preprocess.js +72 -0
- package/dist/lib/preprocess.js.map +1 -0
- package/dist/lib/registers.d.ts +132 -0
- package/dist/lib/registers.d.ts.map +1 -0
- package/dist/lib/registers.js +329 -0
- package/dist/lib/registers.js.map +1 -0
- package/dist/lib/resolver.d.ts +21 -1
- package/dist/lib/resolver.d.ts.map +1 -1
- package/dist/lib/resolver.js +41 -18
- package/dist/lib/resolver.js.map +1 -1
- package/dist/lib/schema-side-table.d.ts +26 -0
- package/dist/lib/schema-side-table.d.ts.map +1 -0
- package/dist/lib/schema-side-table.js +34 -0
- package/dist/lib/schema-side-table.js.map +1 -0
- package/dist/lib/schema-table.d.ts +59 -9
- package/dist/lib/schema-table.d.ts.map +1 -1
- package/dist/lib/schema-table.js +158 -22
- package/dist/lib/schema-table.js.map +1 -1
- package/dist/lib/slot-markers.d.ts +38 -0
- package/dist/lib/slot-markers.d.ts.map +1 -0
- package/dist/lib/slot-markers.js +105 -0
- package/dist/lib/slot-markers.js.map +1 -0
- package/dist/lib/slots.d.ts +99 -0
- package/dist/lib/slots.d.ts.map +1 -0
- package/dist/lib/slots.js +448 -0
- package/dist/lib/slots.js.map +1 -0
- package/dist/plugins.d.ts +3 -0
- package/dist/plugins.d.ts.map +1 -1
- package/dist/plugins.js +53 -4
- package/dist/plugins.js.map +1 -1
- package/dist/reference.d.ts +18 -0
- package/dist/reference.d.ts.map +1 -1
- package/dist/reference.js +34 -1
- package/dist/reference.js.map +1 -1
- package/dist/registers-pipeline.d.ts +51 -0
- package/dist/registers-pipeline.d.ts.map +1 -0
- package/dist/registers-pipeline.js +224 -0
- package/dist/registers-pipeline.js.map +1 -0
- package/dist/schema-row.d.ts +5 -0
- package/dist/schema-row.d.ts.map +1 -1
- package/dist/schema-row.js +1 -0
- package/dist/schema-row.js.map +1 -1
- package/dist/tags/data.d.ts +2 -2
- package/dist/tags/data.d.ts.map +1 -1
- package/dist/tags/data.js +6 -4
- package/dist/tags/data.js.map +1 -1
- package/dist/tags/figure.d.ts +10 -4
- package/dist/tags/figure.d.ts.map +1 -1
- package/dist/tags/figure.js +65 -20
- package/dist/tags/figure.js.map +1 -1
- package/dist/tags/include.d.ts +51 -7
- package/dist/tags/include.d.ts.map +1 -1
- package/dist/tags/include.js +216 -7
- package/dist/tags/include.js.map +1 -1
- package/dist/tags/sandbox.d.ts.map +1 -1
- package/dist/tags/sandbox.js +13 -3
- package/dist/tags/sandbox.js.map +1 -1
- package/dist/tags/snippet.d.ts +9 -10
- package/dist/tags/snippet.d.ts.map +1 -1
- package/dist/tags/snippet.js +213 -10
- package/dist/tags/snippet.js.map +1 -1
- package/dist/universal-attributes.d.ts +1 -1
- package/package.json +3 -3
- package/dist/include-pipeline.d.ts +0 -52
- package/dist/include-pipeline.d.ts.map +0 -1
- package/dist/include-pipeline.js +0 -206
- package/dist/include-pipeline.js.map +0 -1
- package/dist/snippet-pipeline.d.ts +0 -44
- package/dist/snippet-pipeline.d.ts.map +0 -1
- package/dist/snippet-pipeline.js +0 -307
- package/dist/snippet-pipeline.js.map +0 -1
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { Node } from '@markdoc/markdoc';
|
|
2
|
+
import type { PreprocessContext, PreprocessPage } from '@refrakt-md/types';
|
|
3
|
+
import { SchemaSideTable } from './schema-side-table.js';
|
|
4
|
+
/**
|
|
5
|
+
* Per-rune preprocessing (SPEC-141).
|
|
6
|
+
*
|
|
7
|
+
* A rune that resolves itself before the transform — `include`, `snippet`,
|
|
8
|
+
* `data` — declares a `preprocess` hook on its schema, beside `transform`.
|
|
9
|
+
* One walk ({@link preprocessTree}) visits the page AST and dispatches to the
|
|
10
|
+
* hook of whichever tag it meets. The ordering between preprocessors is not
|
|
11
|
+
* stated anywhere: it is tree order.
|
|
12
|
+
*
|
|
13
|
+
* That is a valid order because the producer/consumer graph is acyclic by
|
|
14
|
+
* construction. `include` pastes a file's AST and `data` clones its row
|
|
15
|
+
* template **at their own node**, so anything they produce is below that point
|
|
16
|
+
* and the walk meets it next. Nothing runs the other way: `snippet` resolves to
|
|
17
|
+
* a `fence`, whose content is raw text that is never re-parsed as Markdoc.
|
|
18
|
+
*/
|
|
19
|
+
/** The context a rune's `preprocess` hook receives. */
|
|
20
|
+
export interface RunePreprocessContext extends PreprocessContext {
|
|
21
|
+
/**
|
|
22
|
+
* The nodes enclosing the one being preprocessed, outermost first — the
|
|
23
|
+
* page's `document` node is always the first entry, and the direct parent
|
|
24
|
+
* is the last (SPEC-141 D4). A replacement is not an ancestor of what it
|
|
25
|
+
* contains: by the time the walk descends into it, the tag is gone.
|
|
26
|
+
*/
|
|
27
|
+
readonly ancestors: readonly Node[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* A rune's preprocess hook (SPEC-141 D1).
|
|
31
|
+
*
|
|
32
|
+
* Receives the rune's own tag node — not the tree. Returning a node replaces
|
|
33
|
+
* the tag with it; returning an array splices those nodes in its place (an
|
|
34
|
+
* empty array removes the tag); returning nothing leaves it alone. The walk
|
|
35
|
+
* then continues into whatever is now at that position, so the hook never has
|
|
36
|
+
* to resolve the tags its own output contains.
|
|
37
|
+
*/
|
|
38
|
+
export type RunePreprocess = (node: Node, page: PreprocessPage, ctx: RunePreprocessContext) => Node | Node[] | void;
|
|
39
|
+
/**
|
|
40
|
+
* Schema → its rune's preprocess hook. Recorded by `createContentModelSchema`
|
|
41
|
+
* and kept off the Markdoc schema object, the same shape as
|
|
42
|
+
* `schemaRuneStructures`: Markdoc never reads it, and only {@link preprocessTree}
|
|
43
|
+
* does.
|
|
44
|
+
*/
|
|
45
|
+
export declare const schemaPreprocessors: SchemaSideTable<RunePreprocess>;
|
|
46
|
+
/**
|
|
47
|
+
* Resolve every preprocessing rune in a page AST, in tree order.
|
|
48
|
+
*
|
|
49
|
+
* `schemas` is the page's tag table — the same `tags` the transform will use,
|
|
50
|
+
* core and plugin runes merged — and any of them that declares a `preprocess`
|
|
51
|
+
* hook takes part. Mutates `ast` in place; returns it when anything changed,
|
|
52
|
+
* and nothing otherwise, matching the `PluginPipelineHooks.preprocess` contract.
|
|
53
|
+
*
|
|
54
|
+
* **The walk descends into a replacement** (SPEC-141 D3). After a hook
|
|
55
|
+
* replaces its tag, the walk revisits the same position, so a producer's
|
|
56
|
+
* output is resolved where it lands: a `{% snippet %}` in a `{% data %}` row
|
|
57
|
+
* template is reached after the row is bound (BUG-027), and a subquery `data`
|
|
58
|
+
* per outer row. Termination needs no depth limit: `include` leaves no
|
|
59
|
+
* `include` tags behind (it expands nested ones itself, under its cycle
|
|
60
|
+
* stack), `data`'s output consumes one level of the authored body per pass,
|
|
61
|
+
* and `snippet`'s fence contains no tags at all.
|
|
62
|
+
*/
|
|
63
|
+
export declare function preprocessTree(ast: Node, page: PreprocessPage, ctx: PreprocessContext, schemas: Record<string, unknown>): Node | void;
|
|
64
|
+
//# sourceMappingURL=preprocess.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preprocess.d.ts","sourceRoot":"","sources":["../../src/lib/preprocess.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAU,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD;;;;;;;;;;;;;;GAcG;AAEH,uDAAuD;AACvD,MAAM,WAAW,qBAAsB,SAAQ,iBAAiB;IAC/D;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,EAAE,SAAS,IAAI,EAAE,CAAC;CACpC;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,cAAc,GAAG,CAC5B,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,cAAc,EACpB,GAAG,EAAE,qBAAqB,KACtB,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;AAE1B;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,iCAAwC,CAAC;AAEzE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAC7B,GAAG,EAAE,IAAI,EACT,IAAI,EAAE,cAAc,EACpB,GAAG,EAAE,iBAAiB,EACtB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,IAAI,GAAG,IAAI,CA4Cb"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { SchemaSideTable } from './schema-side-table.js';
|
|
2
|
+
/**
|
|
3
|
+
* Schema → its rune's preprocess hook. Recorded by `createContentModelSchema`
|
|
4
|
+
* and kept off the Markdoc schema object, the same shape as
|
|
5
|
+
* `schemaRuneStructures`: Markdoc never reads it, and only {@link preprocessTree}
|
|
6
|
+
* does.
|
|
7
|
+
*/
|
|
8
|
+
export const schemaPreprocessors = new SchemaSideTable();
|
|
9
|
+
/**
|
|
10
|
+
* Resolve every preprocessing rune in a page AST, in tree order.
|
|
11
|
+
*
|
|
12
|
+
* `schemas` is the page's tag table — the same `tags` the transform will use,
|
|
13
|
+
* core and plugin runes merged — and any of them that declares a `preprocess`
|
|
14
|
+
* hook takes part. Mutates `ast` in place; returns it when anything changed,
|
|
15
|
+
* and nothing otherwise, matching the `PluginPipelineHooks.preprocess` contract.
|
|
16
|
+
*
|
|
17
|
+
* **The walk descends into a replacement** (SPEC-141 D3). After a hook
|
|
18
|
+
* replaces its tag, the walk revisits the same position, so a producer's
|
|
19
|
+
* output is resolved where it lands: a `{% snippet %}` in a `{% data %}` row
|
|
20
|
+
* template is reached after the row is bound (BUG-027), and a subquery `data`
|
|
21
|
+
* per outer row. Termination needs no depth limit: `include` leaves no
|
|
22
|
+
* `include` tags behind (it expands nested ones itself, under its cycle
|
|
23
|
+
* stack), `data`'s output consumes one level of the authored body per pass,
|
|
24
|
+
* and `snippet`'s fence contains no tags at all.
|
|
25
|
+
*/
|
|
26
|
+
export function preprocessTree(ast, page, ctx, schemas) {
|
|
27
|
+
const hooks = new Map();
|
|
28
|
+
for (const [name, schema] of Object.entries(schemas)) {
|
|
29
|
+
if (!schema || typeof schema !== 'object')
|
|
30
|
+
continue;
|
|
31
|
+
const hook = schemaPreprocessors.get(schema);
|
|
32
|
+
if (hook)
|
|
33
|
+
hooks.set(name, hook);
|
|
34
|
+
}
|
|
35
|
+
if (hooks.size === 0)
|
|
36
|
+
return;
|
|
37
|
+
let mutated = false;
|
|
38
|
+
const ancestors = [];
|
|
39
|
+
const walk = (parent) => {
|
|
40
|
+
const children = parent.children;
|
|
41
|
+
if (!children || children.length === 0)
|
|
42
|
+
return;
|
|
43
|
+
ancestors.push(parent);
|
|
44
|
+
for (let i = 0; i < children.length; i++) {
|
|
45
|
+
const child = children[i];
|
|
46
|
+
const hook = child.type === 'tag' && child.tag ? hooks.get(child.tag) : undefined;
|
|
47
|
+
if (hook) {
|
|
48
|
+
// A prototype link rather than a spread, so a context whose
|
|
49
|
+
// diagnostics are methods on a class keeps them.
|
|
50
|
+
const hookCtx = Object.create(ctx, {
|
|
51
|
+
ancestors: { value: [...ancestors], enumerable: true },
|
|
52
|
+
});
|
|
53
|
+
const result = hook(child, page, hookCtx);
|
|
54
|
+
// Returning the node itself is "leave it alone" too — treating it as
|
|
55
|
+
// a replacement would revisit it forever.
|
|
56
|
+
if (result !== undefined && result !== child) {
|
|
57
|
+
const replacement = Array.isArray(result) ? result : [result];
|
|
58
|
+
children.splice(i, 1, ...replacement);
|
|
59
|
+
mutated = true;
|
|
60
|
+
// Revisit this position: the walk descends into the replacement.
|
|
61
|
+
i--;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
walk(child);
|
|
66
|
+
}
|
|
67
|
+
ancestors.pop();
|
|
68
|
+
};
|
|
69
|
+
walk(ast);
|
|
70
|
+
return mutated ? ast : undefined;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=preprocess.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preprocess.js","sourceRoot":"","sources":["../../src/lib/preprocess.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AA4CzD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,eAAe,EAAkB,CAAC;AAEzE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,cAAc,CAC7B,GAAS,EACT,IAAoB,EACpB,GAAsB,EACtB,OAAgC;IAEhC,MAAM,KAAK,GAAG,IAAI,GAAG,EAA0B,CAAC;IAChD,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACtD,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;YAAE,SAAS;QACpD,MAAM,IAAI,GAAG,mBAAmB,CAAC,GAAG,CAAC,MAAgB,CAAC,CAAC;QACvD,IAAI,IAAI;YAAE,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACjC,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO;IAE7B,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,MAAM,SAAS,GAAW,EAAE,CAAC;IAE7B,MAAM,IAAI,GAAG,CAAC,MAAY,EAAQ,EAAE;QACnC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAC/C,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1C,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC1B,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAClF,IAAI,IAAI,EAAE,CAAC;gBACV,4DAA4D;gBAC5D,iDAAiD;gBACjD,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE;oBAClC,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,GAAG,SAAS,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE;iBACtD,CAA0B,CAAC;gBAC5B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;gBAC1C,qEAAqE;gBACrE,0CAA0C;gBAC1C,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;oBAC9C,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;oBAC9D,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,WAAW,CAAC,CAAC;oBACtC,OAAO,GAAG,IAAI,CAAC;oBACf,iEAAiE;oBACjE,CAAC,EAAE,CAAC;oBACJ,SAAS;gBACV,CAAC;YACF,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,CAAC;QACb,CAAC;QACD,SAAS,CAAC,GAAG,EAAE,CAAC;IACjB,CAAC,CAAC;IAEF,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { SchemaSideTable } from './schema-side-table.js';
|
|
2
|
+
/**
|
|
3
|
+
* Declarative entity and edge registration — SPEC-144 / WORK-611.
|
|
4
|
+
*
|
|
5
|
+
* A rune says *what it registers* — which named source holds the id, which
|
|
6
|
+
* sources to carry into the data bag, which two hold an edge's endpoints — and
|
|
7
|
+
* one core participant (`createRegistersHooks`) does the registering in the
|
|
8
|
+
* existing Phase 2 / Phase 3 slots. Plugins keep `PluginPipelineHooks` for
|
|
9
|
+
* everything else; this is a generic participant beside them.
|
|
10
|
+
*
|
|
11
|
+
* The vocabulary is closed (ADR-036, SPEC-144 D1): every value is a string, a
|
|
12
|
+
* boolean, or a list or record of those. No expression form, no predicate, no
|
|
13
|
+
* function. A domain that needs more writes a plugin hook — the plan plugin is
|
|
14
|
+
* the standing example (D5).
|
|
15
|
+
*
|
|
16
|
+
* **Where a value comes from** (D3, decided in WORK-611). A source is a bare
|
|
17
|
+
* name, resolved the way the hand-written helpers always did: a `refs` entry —
|
|
18
|
+
* a node carrying `data-name=<source>` inside the rune, read as its text — and
|
|
19
|
+
* otherwise the rune's `data-rune-fields` bag. `createComponentRenderable`
|
|
20
|
+
* rejects a rune whose properties and refs share a name (ADR-008), so the two
|
|
21
|
+
* namespaces are disjoint and a bare name cannot mean two things. A name that
|
|
22
|
+
* resolves to neither is a typo, and `validate` reports it with file and line
|
|
23
|
+
* (`registers-source-unresolved`), the same audit a schema-table source gets.
|
|
24
|
+
*/
|
|
25
|
+
/** One data-bag entry: `'role'` carries source `role` as key `role`;
|
|
26
|
+
* `{ name: 'title' }` carries source `title` as key `name`. */
|
|
27
|
+
export type RegistersDataEntry = string | Readonly<Record<string, string>>;
|
|
28
|
+
/** The data bag: an ordered field list, or one source holding a JSON object
|
|
29
|
+
* that *is* the bag. Key order follows the declaration. */
|
|
30
|
+
export type RegistersData = readonly RegistersDataEntry[] | {
|
|
31
|
+
readonly json: string;
|
|
32
|
+
};
|
|
33
|
+
export interface RegistersEntity {
|
|
34
|
+
/** Registry type. Defaults to the rune name. */
|
|
35
|
+
type?: string;
|
|
36
|
+
/** The source holding the entity's id. A rune instance whose id is empty
|
|
37
|
+
* registers nothing and warns. */
|
|
38
|
+
idFrom: string;
|
|
39
|
+
/** `'site'` (default) or `'page'` — see `EntityRegistration.scope`. */
|
|
40
|
+
scope?: 'site' | 'page';
|
|
41
|
+
/** What to carry in the entity's data bag. Nothing is added implicitly. */
|
|
42
|
+
data?: RegistersData;
|
|
43
|
+
/** Alternative names, split from a data-bag key. The name index the
|
|
44
|
+
* participant builds in Phase 3 adds each alias after the ids, and an alias
|
|
45
|
+
* already present keeps its first owner. */
|
|
46
|
+
aliases?: {
|
|
47
|
+
readonly from: string;
|
|
48
|
+
readonly separator?: string;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export interface RegistersEdge {
|
|
52
|
+
/** Registry type of the edge's own entry. Defaults to the rune name. */
|
|
53
|
+
type?: string;
|
|
54
|
+
/** Source holding the source entity's id (or alias). */
|
|
55
|
+
from: string;
|
|
56
|
+
/** Source holding the target entity's id (or alias). */
|
|
57
|
+
to: string;
|
|
58
|
+
/** The relationship-graph edge kind: a literal, or `{ field }` naming a key
|
|
59
|
+
* of the edge's data bag. An empty field value falls back to the type. */
|
|
60
|
+
kind: string | {
|
|
61
|
+
readonly field: string;
|
|
62
|
+
};
|
|
63
|
+
/** Contribute the reverse edge too: a literal, or `{ field }` naming a data
|
|
64
|
+
* key whose value is `'true'`. Default `false`. */
|
|
65
|
+
bidirectional?: boolean | {
|
|
66
|
+
readonly field: string;
|
|
67
|
+
};
|
|
68
|
+
/** Further sources for the edge entry's data bag. */
|
|
69
|
+
data?: readonly RegistersDataEntry[];
|
|
70
|
+
}
|
|
71
|
+
/** A rune's `registers` block: exactly one of `entity` or `edge`. */
|
|
72
|
+
export interface RegistersDeclaration {
|
|
73
|
+
entity?: RegistersEntity;
|
|
74
|
+
edge?: RegistersEdge;
|
|
75
|
+
}
|
|
76
|
+
/** The name index a declaring plugin's aggregate slot receives in Phase 3. */
|
|
77
|
+
export interface RegistersIndex {
|
|
78
|
+
/** Every declared entity by id and by alias. Ids are set in type
|
|
79
|
+
* declaration order, then registry order, so a later id replaces an earlier
|
|
80
|
+
* one; an alias never replaces anything already present. */
|
|
81
|
+
entityByName: Map<string, import('@refrakt-md/types').EntityRegistration>;
|
|
82
|
+
}
|
|
83
|
+
/** Declarations recorded by `createContentModelSchema`, keyed by schema — the
|
|
84
|
+
* same pattern as `schemaTables`, for the same reason: tooling has only the
|
|
85
|
+
* schema to read from. */
|
|
86
|
+
export declare const schemaRegisters: SchemaSideTable<RegistersDeclaration>;
|
|
87
|
+
/** The `registers` block a rune declares, if it declares one. */
|
|
88
|
+
export declare function registersFor(schema: unknown): RegistersDeclaration | undefined;
|
|
89
|
+
/**
|
|
90
|
+
* Check a declaration against the closed vocabulary, throwing on the first
|
|
91
|
+
* violation. Runs at schema construction, so a malformed block fails the
|
|
92
|
+
* import that defines it rather than a build that happens to use it.
|
|
93
|
+
*/
|
|
94
|
+
export declare function validateRegistersDeclaration(decl: unknown, where?: string): void;
|
|
95
|
+
declare function dataEntries(data: readonly RegistersDataEntry[], where?: string): Array<{
|
|
96
|
+
key: string;
|
|
97
|
+
source: string;
|
|
98
|
+
}>;
|
|
99
|
+
/** Every source a declaration reads from the rune's output, with the role it
|
|
100
|
+
* plays — what the validate-time audit and `inspect` check. */
|
|
101
|
+
export declare function registersSources(decl: RegistersDeclaration): Array<{
|
|
102
|
+
source: string;
|
|
103
|
+
role: string;
|
|
104
|
+
}>;
|
|
105
|
+
type AnyTag = {
|
|
106
|
+
name?: string;
|
|
107
|
+
attributes?: Record<string, unknown>;
|
|
108
|
+
children?: unknown[];
|
|
109
|
+
};
|
|
110
|
+
/** Read one source off a rune's tag: a ref's text, else its field-bag value,
|
|
111
|
+
* else `''`. The D3 rule — see the module comment. */
|
|
112
|
+
export declare function readRegistersSource(tag: AnyTag, source: string): string;
|
|
113
|
+
/**
|
|
114
|
+
* Sources a declaration names that the rune does not provide — WORK-611.
|
|
115
|
+
*
|
|
116
|
+
* The same rule `auditSchemaSources` applies to a schema table: a source
|
|
117
|
+
* resolves if a node in the rune's output carries the name, if the field bag
|
|
118
|
+
* has it, or if it is one of the rune's declared attributes (an optional
|
|
119
|
+
* attribute left unset emits nothing, which is "this input did not exercise
|
|
120
|
+
* it", not a typo). What is left resolves to nothing, ever.
|
|
121
|
+
*
|
|
122
|
+
* `tree` is the rune's `Markdoc.transform` output, before the identity
|
|
123
|
+
* transform consumes the bag.
|
|
124
|
+
*/
|
|
125
|
+
export declare function auditRegistersSources(decl: RegistersDeclaration, tree: unknown, declaredAttributes?: readonly string[]): Array<{
|
|
126
|
+
source: string;
|
|
127
|
+
role: string;
|
|
128
|
+
}>;
|
|
129
|
+
/** One line per declaration, for `inspect` and the reference. */
|
|
130
|
+
export declare function describeRegisters(decl: RegistersDeclaration, rune: string): string[];
|
|
131
|
+
export { dataEntries as registersDataEntries };
|
|
132
|
+
//# sourceMappingURL=registers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registers.d.ts","sourceRoot":"","sources":["../../src/lib/registers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import Markdoc from '@markdoc/markdoc';
|
|
2
|
+
import { readField } from '@refrakt-md/transform';
|
|
3
|
+
import { SchemaSideTable } from './schema-side-table.js';
|
|
4
|
+
/** Declarations recorded by `createContentModelSchema`, keyed by schema — the
|
|
5
|
+
* same pattern as `schemaTables`, for the same reason: tooling has only the
|
|
6
|
+
* schema to read from. */
|
|
7
|
+
export const schemaRegisters = new SchemaSideTable();
|
|
8
|
+
/** The `registers` block a rune declares, if it declares one. */
|
|
9
|
+
export function registersFor(schema) {
|
|
10
|
+
return schema && typeof schema === 'object' ? schemaRegisters.get(schema) : undefined;
|
|
11
|
+
}
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// The closed vocabulary, checked at construction
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
const ENTITY_KEYS = new Set(['type', 'idFrom', 'scope', 'data', 'aliases']);
|
|
16
|
+
const EDGE_KEYS = new Set(['type', 'from', 'to', 'kind', 'bidirectional', 'data']);
|
|
17
|
+
/**
|
|
18
|
+
* Check a declaration against the closed vocabulary, throwing on the first
|
|
19
|
+
* violation. Runs at schema construction, so a malformed block fails the
|
|
20
|
+
* import that defines it rather than a build that happens to use it.
|
|
21
|
+
*/
|
|
22
|
+
export function validateRegistersDeclaration(decl, where = 'registers') {
|
|
23
|
+
assertInert(decl, where);
|
|
24
|
+
const fail = (msg) => {
|
|
25
|
+
throw new Error(`${where}: ${msg}`);
|
|
26
|
+
};
|
|
27
|
+
if (!isRecord(decl))
|
|
28
|
+
fail('must be an object');
|
|
29
|
+
const d = decl;
|
|
30
|
+
const keys = Object.keys(d);
|
|
31
|
+
if (keys.some((k) => k !== 'entity' && k !== 'edge')) {
|
|
32
|
+
fail(`unknown key "${keys.find((k) => k !== 'entity' && k !== 'edge')}"; use "entity" or "edge"`);
|
|
33
|
+
}
|
|
34
|
+
if ((d.entity === undefined) === (d.edge === undefined)) {
|
|
35
|
+
fail('declare exactly one of "entity" or "edge"');
|
|
36
|
+
}
|
|
37
|
+
if (d.entity !== undefined) {
|
|
38
|
+
const e = d.entity;
|
|
39
|
+
if (!isRecord(e))
|
|
40
|
+
fail('entity must be an object');
|
|
41
|
+
checkKeys(e, ENTITY_KEYS, `${where}.entity`);
|
|
42
|
+
optionalName(e.type, `${where}.entity.type`);
|
|
43
|
+
requireName(e.idFrom, `${where}.entity.idFrom`);
|
|
44
|
+
if (e.scope !== undefined && e.scope !== 'site' && e.scope !== 'page') {
|
|
45
|
+
fail(`entity.scope must be "site" or "page"`);
|
|
46
|
+
}
|
|
47
|
+
const dataKeys = checkData(e.data, `${where}.entity.data`, true);
|
|
48
|
+
if (e.aliases !== undefined) {
|
|
49
|
+
const a = e.aliases;
|
|
50
|
+
if (!isRecord(a))
|
|
51
|
+
fail('entity.aliases must be an object');
|
|
52
|
+
checkKeys(a, new Set(['from', 'separator']), `${where}.entity.aliases`);
|
|
53
|
+
requireName(a.from, `${where}.entity.aliases.from`);
|
|
54
|
+
if (a.separator !== undefined && (typeof a.separator !== 'string' || a.separator === '')) {
|
|
55
|
+
fail('entity.aliases.separator must be a non-empty string');
|
|
56
|
+
}
|
|
57
|
+
// Aliases are expanded in Phase 3 from the registered entry, so the
|
|
58
|
+
// value has to be in the bag.
|
|
59
|
+
if (dataKeys !== 'json' && !dataKeys.includes(a.from)) {
|
|
60
|
+
fail(`entity.aliases.from "${a.from}" must name a key of entity.data`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (d.edge !== undefined) {
|
|
65
|
+
const e = d.edge;
|
|
66
|
+
if (!isRecord(e))
|
|
67
|
+
fail('edge must be an object');
|
|
68
|
+
checkKeys(e, EDGE_KEYS, `${where}.edge`);
|
|
69
|
+
optionalName(e.type, `${where}.edge.type`);
|
|
70
|
+
requireName(e.from, `${where}.edge.from`);
|
|
71
|
+
requireName(e.to, `${where}.edge.to`);
|
|
72
|
+
const dataKeys = checkData(e.data, `${where}.edge.data`, false);
|
|
73
|
+
const bagKeys = ['from', 'to', ...dataKeys, 'name'];
|
|
74
|
+
for (const field of ['kind', 'bidirectional']) {
|
|
75
|
+
const v = e[field];
|
|
76
|
+
if (v === undefined && field === 'bidirectional')
|
|
77
|
+
continue;
|
|
78
|
+
if (field === 'kind' && typeof v === 'string') {
|
|
79
|
+
if (v === '')
|
|
80
|
+
fail('edge.kind must not be empty');
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (field === 'bidirectional' && typeof v === 'boolean')
|
|
84
|
+
continue;
|
|
85
|
+
if (!isRecord(v))
|
|
86
|
+
fail(`edge.${field} must be a literal or { field }`);
|
|
87
|
+
checkKeys(v, new Set(['field']), `${where}.edge.${field}`);
|
|
88
|
+
const name = v.field;
|
|
89
|
+
requireName(name, `${where}.edge.${field}.field`);
|
|
90
|
+
if (!bagKeys.includes(name)) {
|
|
91
|
+
fail(`edge.${field}.field "${name}" must name a key of the edge's data bag`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function isRecord(v) {
|
|
97
|
+
return !!v && typeof v === 'object' && !Array.isArray(v);
|
|
98
|
+
}
|
|
99
|
+
function checkKeys(rec, allowed, where) {
|
|
100
|
+
for (const k of Object.keys(rec)) {
|
|
101
|
+
if (!allowed.has(k)) {
|
|
102
|
+
throw new Error(`${where}: unknown key "${k}" (allowed: ${[...allowed].join(', ')})`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function requireName(v, where) {
|
|
107
|
+
if (typeof v !== 'string' || v === '')
|
|
108
|
+
throw new Error(`${where} must be a non-empty string`);
|
|
109
|
+
}
|
|
110
|
+
function optionalName(v, where) {
|
|
111
|
+
if (v !== undefined)
|
|
112
|
+
requireName(v, where);
|
|
113
|
+
}
|
|
114
|
+
/** Validate a `data` declaration and return the bag keys it produces, or
|
|
115
|
+
* `'json'` for the JSON form (whose keys are not known until build time). */
|
|
116
|
+
function checkData(data, where, allowJson) {
|
|
117
|
+
if (data === undefined)
|
|
118
|
+
return [];
|
|
119
|
+
if (isRecord(data)) {
|
|
120
|
+
if (!allowJson)
|
|
121
|
+
throw new Error(`${where} must be a list`);
|
|
122
|
+
checkKeys(data, new Set(['json']), where);
|
|
123
|
+
requireName(data.json, `${where}.json`);
|
|
124
|
+
return 'json';
|
|
125
|
+
}
|
|
126
|
+
if (!Array.isArray(data))
|
|
127
|
+
throw new Error(`${where} must be a list or { json }`);
|
|
128
|
+
const keys = [];
|
|
129
|
+
for (const entry of dataEntries(data, where)) {
|
|
130
|
+
if (keys.includes(entry.key))
|
|
131
|
+
throw new Error(`${where}: key "${entry.key}" appears twice`);
|
|
132
|
+
keys.push(entry.key);
|
|
133
|
+
}
|
|
134
|
+
return keys;
|
|
135
|
+
}
|
|
136
|
+
function dataEntries(data, where = 'data') {
|
|
137
|
+
return data.map((entry) => {
|
|
138
|
+
if (typeof entry === 'string') {
|
|
139
|
+
requireName(entry, where);
|
|
140
|
+
return { key: entry, source: entry };
|
|
141
|
+
}
|
|
142
|
+
const pairs = isRecord(entry) ? Object.entries(entry) : [];
|
|
143
|
+
if (pairs.length !== 1) {
|
|
144
|
+
throw new Error(`${where}: an entry is a source name or a single { key: source } pair`);
|
|
145
|
+
}
|
|
146
|
+
const [key, source] = pairs[0];
|
|
147
|
+
requireName(key, where);
|
|
148
|
+
requireName(source, `${where}.${key}`);
|
|
149
|
+
return { key, source: source };
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
/** No functions, no class instances, nothing `JSON` would drop or reshape:
|
|
153
|
+
* the declaration must round-trip through `JSON.parse(JSON.stringify(…))`. */
|
|
154
|
+
function assertInert(v, where) {
|
|
155
|
+
if (v === null || typeof v === 'string' || typeof v === 'boolean')
|
|
156
|
+
return;
|
|
157
|
+
if (Array.isArray(v)) {
|
|
158
|
+
for (const [i, x] of v.entries())
|
|
159
|
+
assertInert(x, `${where}[${i}]`);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (typeof v === 'object' && Object.getPrototypeOf(v) === Object.prototype) {
|
|
163
|
+
for (const [k, x] of Object.entries(v)) {
|
|
164
|
+
if (x === undefined)
|
|
165
|
+
throw new Error(`${where}.${k}: undefined is not a value; omit the key`);
|
|
166
|
+
assertInert(x, `${where}.${k}`);
|
|
167
|
+
}
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
throw new Error(`${where}: a registers declaration holds only strings, booleans, lists and plain objects ` +
|
|
171
|
+
`(found ${typeof v === 'function' ? 'a function' : typeof v}) — ADR-036`);
|
|
172
|
+
}
|
|
173
|
+
// ---------------------------------------------------------------------------
|
|
174
|
+
// Sources
|
|
175
|
+
// ---------------------------------------------------------------------------
|
|
176
|
+
/** Every source a declaration reads from the rune's output, with the role it
|
|
177
|
+
* plays — what the validate-time audit and `inspect` check. */
|
|
178
|
+
export function registersSources(decl) {
|
|
179
|
+
const out = [];
|
|
180
|
+
if (decl.entity) {
|
|
181
|
+
out.push({ source: decl.entity.idFrom, role: 'idFrom' });
|
|
182
|
+
const data = decl.entity.data;
|
|
183
|
+
if (data && !Array.isArray(data)) {
|
|
184
|
+
out.push({ source: data.json, role: 'data (json)' });
|
|
185
|
+
}
|
|
186
|
+
else if (data) {
|
|
187
|
+
for (const { key, source } of dataEntries(data)) {
|
|
188
|
+
out.push({ source, role: `data.${key}` });
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
if (decl.edge) {
|
|
193
|
+
out.push({ source: decl.edge.from, role: 'from' });
|
|
194
|
+
out.push({ source: decl.edge.to, role: 'to' });
|
|
195
|
+
for (const { key, source } of dataEntries(decl.edge.data ?? [])) {
|
|
196
|
+
out.push({ source, role: `data.${key}` });
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return out;
|
|
200
|
+
}
|
|
201
|
+
function isTag(n) {
|
|
202
|
+
return (!!n &&
|
|
203
|
+
typeof n === 'object' &&
|
|
204
|
+
(Markdoc.Tag.isTag(n) || n.$$mdtype === 'Tag'));
|
|
205
|
+
}
|
|
206
|
+
/** The first node inside this rune carrying `data-name=<name>`. Bounded at
|
|
207
|
+
* nested runes: a name is unique per rune, and a `character-section` inside a
|
|
208
|
+
* `character` names its own heading `name` too (see `findAllByName`). */
|
|
209
|
+
function findRef(root, name) {
|
|
210
|
+
for (const c of root.children ?? []) {
|
|
211
|
+
if (!isTag(c))
|
|
212
|
+
continue;
|
|
213
|
+
if (c.attributes?.['data-rune'] !== undefined)
|
|
214
|
+
continue;
|
|
215
|
+
if (c.attributes?.['data-name'] === name)
|
|
216
|
+
return c;
|
|
217
|
+
const hit = findRef(c, name);
|
|
218
|
+
if (hit)
|
|
219
|
+
return hit;
|
|
220
|
+
}
|
|
221
|
+
return undefined;
|
|
222
|
+
}
|
|
223
|
+
function text(node) {
|
|
224
|
+
if (typeof node === 'string')
|
|
225
|
+
return node;
|
|
226
|
+
if (!isTag(node))
|
|
227
|
+
return '';
|
|
228
|
+
return (node.children ?? []).map(text).join('');
|
|
229
|
+
}
|
|
230
|
+
/** Read one source off a rune's tag: a ref's text, else its field-bag value,
|
|
231
|
+
* else `''`. The D3 rule — see the module comment. */
|
|
232
|
+
export function readRegistersSource(tag, source) {
|
|
233
|
+
const ref = findRef(tag, source);
|
|
234
|
+
if (ref)
|
|
235
|
+
return text(ref).trim();
|
|
236
|
+
return readField(tag, source) ?? '';
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Sources a declaration names that the rune does not provide — WORK-611.
|
|
240
|
+
*
|
|
241
|
+
* The same rule `auditSchemaSources` applies to a schema table: a source
|
|
242
|
+
* resolves if a node in the rune's output carries the name, if the field bag
|
|
243
|
+
* has it, or if it is one of the rune's declared attributes (an optional
|
|
244
|
+
* attribute left unset emits nothing, which is "this input did not exercise
|
|
245
|
+
* it", not a typo). What is left resolves to nothing, ever.
|
|
246
|
+
*
|
|
247
|
+
* `tree` is the rune's `Markdoc.transform` output, before the identity
|
|
248
|
+
* transform consumes the bag.
|
|
249
|
+
*/
|
|
250
|
+
export function auditRegistersSources(decl, tree, declaredAttributes = []) {
|
|
251
|
+
const root = findRuneRoot(tree);
|
|
252
|
+
const bag = root ? parseBag(root) : {};
|
|
253
|
+
const declared = new Set();
|
|
254
|
+
for (const a of declaredAttributes) {
|
|
255
|
+
declared.add(a);
|
|
256
|
+
declared.add(kebab(a));
|
|
257
|
+
}
|
|
258
|
+
return registersSources(decl).filter(({ source }) => !(declared.has(source) ||
|
|
259
|
+
declared.has(kebab(source)) ||
|
|
260
|
+
Object.hasOwn(bag, source) ||
|
|
261
|
+
(root && findRef(root, source))));
|
|
262
|
+
}
|
|
263
|
+
function findRuneRoot(node) {
|
|
264
|
+
if (Array.isArray(node)) {
|
|
265
|
+
for (const c of node) {
|
|
266
|
+
const hit = findRuneRoot(c);
|
|
267
|
+
if (hit)
|
|
268
|
+
return hit;
|
|
269
|
+
}
|
|
270
|
+
return undefined;
|
|
271
|
+
}
|
|
272
|
+
if (!isTag(node))
|
|
273
|
+
return undefined;
|
|
274
|
+
if (node.attributes?.['data-rune'] !== undefined)
|
|
275
|
+
return node;
|
|
276
|
+
return findRuneRoot(node.children ?? []);
|
|
277
|
+
}
|
|
278
|
+
function parseBag(tag) {
|
|
279
|
+
const raw = tag.attributes?.['data-rune-fields'];
|
|
280
|
+
if (typeof raw !== 'string')
|
|
281
|
+
return {};
|
|
282
|
+
try {
|
|
283
|
+
return JSON.parse(raw);
|
|
284
|
+
}
|
|
285
|
+
catch {
|
|
286
|
+
return {};
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
const kebab = (s) => s.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
|
|
290
|
+
/** One line per declaration, for `inspect` and the reference. */
|
|
291
|
+
export function describeRegisters(decl, rune) {
|
|
292
|
+
const lines = [];
|
|
293
|
+
const dataLine = (data) => {
|
|
294
|
+
if (!data)
|
|
295
|
+
return '(none)';
|
|
296
|
+
if (!Array.isArray(data))
|
|
297
|
+
return `the JSON object in "${data.json}"`;
|
|
298
|
+
return dataEntries(data)
|
|
299
|
+
.map(({ key, source }) => (key === source ? key : `${key} <- ${source}`))
|
|
300
|
+
.join(', ');
|
|
301
|
+
};
|
|
302
|
+
if (decl.entity) {
|
|
303
|
+
const e = decl.entity;
|
|
304
|
+
lines.push(`entity ${e.type ?? rune} (scope: ${e.scope ?? 'site'})`);
|
|
305
|
+
lines.push(` id <- ${e.idFrom}`);
|
|
306
|
+
lines.push(` data ${dataLine(e.data)}`);
|
|
307
|
+
if (e.aliases) {
|
|
308
|
+
lines.push(` aliases <- ${e.aliases.from}, split on "${e.aliases.separator ?? ','}"`);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
if (decl.edge) {
|
|
312
|
+
const e = decl.edge;
|
|
313
|
+
const kind = typeof e.kind === 'string' ? e.kind : `data.${e.kind.field}`;
|
|
314
|
+
const bidi = e.bidirectional === undefined
|
|
315
|
+
? 'no'
|
|
316
|
+
: typeof e.bidirectional === 'boolean'
|
|
317
|
+
? String(e.bidirectional)
|
|
318
|
+
: `data.${e.bidirectional.field}`;
|
|
319
|
+
lines.push(`edge ${e.type ?? rune} (id: from→to)`);
|
|
320
|
+
lines.push(` from <- ${e.from}`);
|
|
321
|
+
lines.push(` to <- ${e.to}`);
|
|
322
|
+
lines.push(` kind ${kind}`);
|
|
323
|
+
lines.push(` both ${bidi}`);
|
|
324
|
+
lines.push(` data from, to, ${e.data?.length ? `${dataLine(e.data)}, ` : ''}name`);
|
|
325
|
+
}
|
|
326
|
+
return lines;
|
|
327
|
+
}
|
|
328
|
+
export { dataEntries as registersDataEntries };
|
|
329
|
+
//# sourceMappingURL=registers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registers.js","sourceRoot":"","sources":["../../src/lib/registers.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,kBAAkB,CAAC;AAEvC,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAiFzD;;2BAE2B;AAC3B,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,eAAe,EAAwB,CAAC;AAE3E,iEAAiE;AACjE,MAAM,UAAU,YAAY,CAAC,MAAe;IAC3C,OAAO,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,MAAgB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACjG,CAAC;AAED,8EAA8E;AAC9E,iDAAiD;AACjD,8EAA8E;AAE9E,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;AAC5E,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC;AAEnF;;;;GAIG;AACH,MAAM,UAAU,4BAA4B,CAAC,IAAa,EAAE,KAAK,GAAG,WAAW;IAC9E,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACzB,MAAM,IAAI,GAAG,CAAC,GAAW,EAAS,EAAE;QACnC,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK,GAAG,EAAE,CAAC,CAAC;IACrC,CAAC,CAAC;IACF,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAC/C,MAAM,CAAC,GAAG,IAA+B,CAAC;IAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC5B,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,MAAM,CAAC,EAAE,CAAC;QACtD,IAAI,CACH,gBAAgB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,MAAM,CAAC,2BAA2B,CAC3F,CAAC;IACH,CAAC;IACD,IAAI,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,EAAE,CAAC;QACzD,IAAI,CAAC,2CAA2C,CAAC,CAAC;IACnD,CAAC;IAED,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,CAAC,GAAG,CAAC,CAAC,MAAiC,CAAC;QAC9C,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,IAAI,CAAC,0BAA0B,CAAC,CAAC;QACnD,SAAS,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,KAAK,SAAS,CAAC,CAAC;QAC7C,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,KAAK,cAAc,CAAC,CAAC;QAC7C,WAAW,CAAC,CAAC,CAAC,MAAM,EAAE,GAAG,KAAK,gBAAgB,CAAC,CAAC;QAChD,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;YACvE,IAAI,CAAC,uCAAuC,CAAC,CAAC;QAC/C,CAAC;QACD,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,KAAK,cAAc,EAAE,IAAI,CAAC,CAAC;QACjE,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC7B,MAAM,CAAC,GAAG,CAAC,CAAC,OAAkC,CAAC;YAC/C,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAAE,IAAI,CAAC,kCAAkC,CAAC,CAAC;YAC3D,SAAS,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,EAAE,GAAG,KAAK,iBAAiB,CAAC,CAAC;YACxE,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,KAAK,sBAAsB,CAAC,CAAC;YACpD,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,CAAC,SAAS,KAAK,EAAE,CAAC,EAAE,CAAC;gBAC1F,IAAI,CAAC,qDAAqD,CAAC,CAAC;YAC7D,CAAC;YACD,oEAAoE;YACpE,8BAA8B;YAC9B,IAAI,QAAQ,KAAK,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAc,CAAC,EAAE,CAAC;gBACjE,IAAI,CAAC,wBAAwB,CAAC,CAAC,IAAI,kCAAkC,CAAC,CAAC;YACxE,CAAC;QACF,CAAC;IACF,CAAC;IAED,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,CAAC,CAAC,IAA+B,CAAC;QAC5C,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,IAAI,CAAC,wBAAwB,CAAC,CAAC;QACjD,SAAS,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC;QACzC,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,KAAK,YAAY,CAAC,CAAC;QAC3C,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,KAAK,YAAY,CAAC,CAAC;QAC1C,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,KAAK,UAAU,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,KAAK,YAAY,EAAE,KAAK,CAAa,CAAC;QAC5E,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,QAAQ,EAAE,MAAM,CAAC,CAAC;QACpD,KAAK,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,eAAe,CAAU,EAAE,CAAC;YACxD,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;YACnB,IAAI,CAAC,KAAK,SAAS,IAAI,KAAK,KAAK,eAAe;gBAAE,SAAS;YAC3D,IAAI,KAAK,KAAK,MAAM,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;gBAC/C,IAAI,CAAC,KAAK,EAAE;oBAAE,IAAI,CAAC,6BAA6B,CAAC,CAAC;gBAClD,SAAS;YACV,CAAC;YACD,IAAI,KAAK,KAAK,eAAe,IAAI,OAAO,CAAC,KAAK,SAAS;gBAAE,SAAS;YAClE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAAE,IAAI,CAAC,QAAQ,KAAK,iCAAiC,CAAC,CAAC;YACvE,SAAS,CAAC,CAA4B,EAAE,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,GAAG,KAAK,SAAS,KAAK,EAAE,CAAC,CAAC;YACtF,MAAM,IAAI,GAAI,CAA6B,CAAC,KAAK,CAAC;YAClD,WAAW,CAAC,IAAI,EAAE,GAAG,KAAK,SAAS,KAAK,QAAQ,CAAC,CAAC;YAClD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAc,CAAC,EAAE,CAAC;gBACvC,IAAI,CAAC,QAAQ,KAAK,WAAW,IAAI,0CAA0C,CAAC,CAAC;YAC9E,CAAC;QACF,CAAC;IACF,CAAC;AACF,CAAC;AAED,SAAS,QAAQ,CAAC,CAAU;IAC3B,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED,SAAS,SAAS,CAAC,GAA4B,EAAE,OAAoB,EAAE,KAAa;IACnF,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,kBAAkB,CAAC,eAAe,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvF,CAAC;IACF,CAAC;AACF,CAAC;AAED,SAAS,WAAW,CAAC,CAAU,EAAE,KAAa;IAC7C,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,6BAA6B,CAAC,CAAC;AAC/F,CAAC;AAED,SAAS,YAAY,CAAC,CAAU,EAAE,KAAa;IAC9C,IAAI,CAAC,KAAK,SAAS;QAAE,WAAW,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AAC5C,CAAC;AAED;8EAC8E;AAC9E,SAAS,SAAS,CAAC,IAAa,EAAE,KAAa,EAAE,SAAkB;IAClE,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IAClC,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACpB,IAAI,CAAC,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,iBAAiB,CAAC,CAAC;QAC3D,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QAC1C,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC;QACxC,OAAO,MAAM,CAAC;IACf,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,6BAA6B,CAAC,CAAC;IACjF,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,IAA4B,EAAE,KAAK,CAAC,EAAE,CAAC;QACtE,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,UAAU,KAAK,CAAC,GAAG,iBAAiB,CAAC,CAAC;QAC5F,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACtB,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,SAAS,WAAW,CACnB,IAAmC,EACnC,KAAK,GAAG,MAAM;IAEd,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACzB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC/B,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAC1B,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QACtC,CAAC;QACD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,8DAA8D,CAAC,CAAC;QACzF,CAAC;QACD,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAC/B,WAAW,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACxB,WAAW,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,GAAG,EAAE,CAAC,CAAC;QACvC,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAgB,EAAE,CAAC;IAC1C,CAAC,CAAC,CAAC;AACJ,CAAC;AAED;+EAC+E;AAC/E,SAAS,WAAW,CAAC,CAAU,EAAE,KAAa;IAC7C,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,SAAS;QAAE,OAAO;IAC1E,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACtB,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE;YAAE,WAAW,CAAC,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC;QACnE,OAAO;IACR,CAAC;IACD,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,SAAS,EAAE,CAAC;QAC5E,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAA4B,CAAC,EAAE,CAAC;YACnE,IAAI,CAAC,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,IAAI,CAAC,0CAA0C,CAAC,CAAC;YAC9F,WAAW,CAAC,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC;QACjC,CAAC;QACD,OAAO;IACR,CAAC;IACD,MAAM,IAAI,KAAK,CACd,GAAG,KAAK,kFAAkF;QACzF,UAAU,OAAO,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CACzE,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;gEACgE;AAChE,MAAM,UAAU,gBAAgB,CAC/B,IAA0B;IAE1B,MAAM,GAAG,GAA4C,EAAE,CAAC;IACxD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QACjB,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QACzD,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;QAC9B,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAG,IAAyB,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;QAC5E,CAAC;aAAM,IAAI,IAAI,EAAE,CAAC;YACjB,KAAK,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,WAAW,CAAC,IAA4B,CAAC,EAAE,CAAC;gBACzE,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,EAAE,EAAE,CAAC,CAAC;YAC3C,CAAC;QACF,CAAC;IACF,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACf,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACnD,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/C,KAAK,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,CAAC;YACjE,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,EAAE,EAAE,CAAC,CAAC;QAC3C,CAAC;IACF,CAAC;IACD,OAAO,GAAG,CAAC;AACZ,CAAC;AAQD,SAAS,KAAK,CAAC,CAAU;IACxB,OAAO,CACN,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,KAAK,QAAQ;QACrB,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAK,CAA2B,CAAC,QAAQ,KAAK,KAAK,CAAC,CACzE,CAAC;AACH,CAAC;AAED;;0EAE0E;AAC1E,SAAS,OAAO,CAAC,IAAY,EAAE,IAAY;IAC1C,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;QACrC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YAAE,SAAS;QACxB,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC,WAAW,CAAC,KAAK,SAAS;YAAE,SAAS;QACxD,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC,WAAW,CAAC,KAAK,IAAI;YAAE,OAAO,CAAC,CAAC;QACnD,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QAC7B,IAAI,GAAG;YAAE,OAAO,GAAG,CAAC;IACrB,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,SAAS,IAAI,CAAC,IAAa;IAC1B,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC1C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAC5B,OAAO,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACjD,CAAC;AAED;uDACuD;AACvD,MAAM,UAAU,mBAAmB,CAAC,GAAW,EAAE,MAAc;IAC9D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,GAAG;QAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACjC,OAAO,SAAS,CAAC,GAAY,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;AAC9C,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,qBAAqB,CACpC,IAA0B,EAC1B,IAAa,EACb,qBAAwC,EAAE;IAE1C,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAChC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACvC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,KAAK,MAAM,CAAC,IAAI,kBAAkB,EAAE,CAAC;QACpC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAChB,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC,MAAM,CACnC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CACd,CAAC,CACA,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC;QACpB,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC3B,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC;QAC1B,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAC/B,CACF,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,IAAa;IAClC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACtB,MAAM,GAAG,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;YAC5B,IAAI,GAAG;gBAAE,OAAO,GAAG,CAAC;QACrB,CAAC;QACD,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IACnC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC,WAAW,CAAC,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAC9D,OAAO,YAAY,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,QAAQ,CAAC,GAAW;IAC5B,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC,kBAAkB,CAAC,CAAC;IACjD,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IACvC,IAAI,CAAC;QACJ,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,EAAE,CAAC;IACX,CAAC;AACF,CAAC;AAED,MAAM,KAAK,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;AAEpF,iEAAiE;AACjE,MAAM,UAAU,iBAAiB,CAAC,IAA0B,EAAE,IAAY;IACzE,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,QAAQ,GAAG,CAAC,IAA+B,EAAE,EAAE;QACpD,IAAI,CAAC,IAAI;YAAE,OAAO,QAAQ,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;YAAE,OAAO,uBAAwB,IAAyB,CAAC,IAAI,GAAG,CAAC;QAC3F,OAAO,WAAW,CAAC,IAA4B,CAAC;aAC9C,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,OAAO,MAAM,EAAE,CAAC,CAAC;aACxE,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,CAAC,CAAC;IACF,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QACjB,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,IAAI,IAAI,aAAa,CAAC,CAAC,KAAK,IAAI,MAAM,GAAG,CAAC,CAAC;QACvE,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QACvC,KAAK,CAAC,IAAI,CAAC,aAAa,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC5C,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,IAAI,eAAe,CAAC,CAAC,OAAO,CAAC,SAAS,IAAI,GAAG,GAAG,CAAC,CAAC;QACxF,CAAC;IACF,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACf,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;QACpB,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAC1E,MAAM,IAAI,GACT,CAAC,CAAC,aAAa,KAAK,SAAS;YAC5B,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,OAAO,CAAC,CAAC,aAAa,KAAK,SAAS;gBACrC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC;gBACzB,CAAC,CAAC,QAAQ,CAAC,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;QACrC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,IAAI,IAAI,iBAAiB,CAAC,CAAC;QACvD,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACrC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;QAChC,KAAK,CAAC,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;QAChC,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACxF,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,OAAO,EAAE,WAAW,IAAI,oBAAoB,EAAE,CAAC"}
|