@knowvah/dot-engine 1.9.0 → 2.0.1
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 +232 -30
- package/dist/api/builder.d.ts +3 -0
- package/dist/api/builder.d.ts.map +1 -1
- package/dist/api/edge-ops.d.ts +7 -0
- package/dist/api/edge-ops.d.ts.map +1 -1
- package/dist/api/geometry.d.ts +5 -2
- package/dist/api/geometry.d.ts.map +1 -1
- package/dist/api.js +159 -31
- package/dist/api.js.map +3 -3
- package/dist/async/collect.d.ts +49 -0
- package/dist/async/collect.d.ts.map +1 -0
- package/dist/async/fonts.d.ts +20 -0
- package/dist/async/fonts.d.ts.map +1 -0
- package/dist/async/render-async.d.ts +91 -0
- package/dist/async/render-async.d.ts.map +1 -0
- package/dist/async/render-into.d.ts +38 -0
- package/dist/async/render-into.d.ts.map +1 -0
- package/dist/async/sanitize.d.ts +28 -0
- package/dist/async/sanitize.d.ts.map +1 -0
- package/dist/common/htmltable-types.d.ts +3 -3
- package/dist/common/htmltable-types.d.ts.map +1 -1
- package/dist/common/make-label.d.ts.map +1 -1
- package/dist/common/poly-shapes.d.ts.map +1 -1
- package/dist/common/textmeasure-factory.d.ts +2 -0
- package/dist/common/textmeasure-factory.d.ts.map +1 -1
- package/dist/common/utils-inputscale.d.ts +19 -0
- package/dist/common/utils-inputscale.d.ts.map +1 -0
- package/dist/errors.d.ts +61 -5
- package/dist/errors.d.ts.map +1 -1
- package/dist/gvc/context.d.ts +36 -4
- package/dist/gvc/context.d.ts.map +1 -1
- package/dist/gvc/device.d.ts +5 -2
- package/dist/gvc/device.d.ts.map +1 -1
- package/dist/gvc/image-resolver.d.ts +16 -16
- package/dist/gvc/image-resolver.d.ts.map +1 -1
- package/dist/gvc/job.d.ts +1 -9
- package/dist/gvc/job.d.ts.map +1 -1
- package/dist/gvc/usershape.d.ts +2 -12
- package/dist/gvc/usershape.d.ts.map +1 -1
- package/dist/index.d.ts +27 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7682 -5535
- package/dist/index.js.map +4 -4
- package/dist/label/index.d.ts.map +1 -1
- package/dist/label/node.d.ts +0 -6
- package/dist/label/node.d.ts.map +1 -1
- package/dist/label/rectangle.d.ts +1 -7
- package/dist/label/rectangle.d.ts.map +1 -1
- package/dist/layout/circo/circular.d.ts +8 -5
- package/dist/layout/circo/circular.d.ts.map +1 -1
- package/dist/layout/dot/pack-components.d.ts +0 -19
- package/dist/layout/dot/pack-components.d.ts.map +1 -1
- package/dist/layout/dot/position.d.ts +7 -2
- package/dist/layout/dot/position.d.ts.map +1 -1
- package/dist/layout/fdp/derive.d.ts.map +1 -1
- package/dist/layout/fdp/index.d.ts.map +1 -1
- package/dist/layout/fdp/init.d.ts.map +1 -1
- package/dist/layout/fdp/layout.d.ts.map +1 -1
- package/dist/layout/fdp/normalize.d.ts +2 -1
- package/dist/layout/fdp/normalize.d.ts.map +1 -1
- package/dist/layout/fdp/ports.d.ts +0 -10
- package/dist/layout/fdp/ports.d.ts.map +1 -1
- package/dist/layout/fdp/xlayout.d.ts +0 -16
- package/dist/layout/fdp/xlayout.d.ts.map +1 -1
- package/dist/layout/neato/adjust-info.d.ts +117 -0
- package/dist/layout/neato/adjust-info.d.ts.map +1 -0
- package/dist/layout/neato/cdt-surface.d.ts.map +1 -1
- package/dist/layout/neato/constraint-adjust.d.ts +40 -0
- package/dist/layout/neato/constraint-adjust.d.ts.map +1 -0
- package/dist/layout/neato/edge-len.d.ts +20 -0
- package/dist/layout/neato/edge-len.d.ts.map +1 -0
- package/dist/layout/neato/fdp-adjust.d.ts +32 -4
- package/dist/layout/neato/fdp-adjust.d.ts.map +1 -1
- package/dist/layout/neato/index.d.ts +9 -6
- package/dist/layout/neato/index.d.ts.map +1 -1
- package/dist/layout/neato/init.d.ts +4 -11
- package/dist/layout/neato/init.d.ts.map +1 -1
- package/dist/layout/neato/kk-paths.d.ts +50 -0
- package/dist/layout/neato/kk-paths.d.ts.map +1 -0
- package/dist/layout/neato/kk-solve.d.ts +14 -0
- package/dist/layout/neato/kk-solve.d.ts.map +1 -0
- package/dist/layout/neato/kk.d.ts +44 -0
- package/dist/layout/neato/kk.d.ts.map +1 -0
- package/dist/layout/neato/multispline-router.d.ts.map +1 -1
- package/dist/layout/neato/poly.d.ts +50 -0
- package/dist/layout/neato/poly.d.ts.map +1 -0
- package/dist/layout/neato/sc-adjust.d.ts +2 -9
- package/dist/layout/neato/sc-adjust.d.ts.map +1 -1
- package/dist/layout/neato/sgd-dijkstra.d.ts +20 -0
- package/dist/layout/neato/sgd-dijkstra.d.ts.map +1 -0
- package/dist/layout/neato/sgd.d.ts +14 -9
- package/dist/layout/neato/sgd.d.ts.map +1 -1
- package/dist/layout/neato/simple-scale.d.ts +15 -0
- package/dist/layout/neato/simple-scale.d.ts.map +1 -0
- package/dist/layout/neato/start.d.ts +51 -0
- package/dist/layout/neato/start.d.ts.map +1 -0
- package/dist/layout/neato/vpsc-adjust.d.ts +21 -0
- package/dist/layout/neato/vpsc-adjust.d.ts.map +1 -0
- package/dist/layout/sfdp/index.d.ts.map +1 -1
- package/dist/layout/sfdp/init.d.ts +0 -9
- package/dist/layout/sfdp/init.d.ts.map +1 -1
- package/dist/layout/sfdp/spring-driver.d.ts.map +1 -1
- package/dist/layout/twopi/circle.d.ts +0 -7
- package/dist/layout/twopi/circle.d.ts.map +1 -1
- package/dist/ortho/ortho-parallel.d.ts.map +1 -1
- package/dist/ortho/trap-query.d.ts.map +1 -1
- package/dist/parser/index.d.ts +9 -5
- package/dist/parser/index.d.ts.map +1 -1
- package/dist/render/index.d.ts +2 -0
- package/dist/render/index.d.ts.map +1 -1
- package/dist/render/public.d.ts +9 -3
- package/dist/render/public.d.ts.map +1 -1
- package/dist/render/xdot-public.d.ts +7 -2
- package/dist/render/xdot-public.d.ts.map +1 -1
- package/dist/render.js +7468 -5556
- package/dist/render.js.map +4 -4
- package/dist/util/xml.d.ts.map +1 -1
- package/dist/vpsc/Solver.d.ts +1 -0
- package/dist/vpsc/Solver.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/api/builder.ts +73 -5
- package/src/api/edge-ops.ts +19 -0
- package/src/api/geometry.ts +22 -5
- package/src/async/collect.ts +204 -0
- package/src/async/fonts.ts +61 -0
- package/src/async/render-async.ts +205 -0
- package/src/async/render-into.ts +115 -0
- package/src/async/sanitize.ts +150 -0
- package/src/common/htmltable-types.ts +4 -5
- package/src/common/make-label.ts +10 -1
- package/src/common/poly-shapes.ts +4 -1
- package/src/common/textmeasure-factory.ts +11 -0
- package/src/common/utils-inputscale.ts +31 -0
- package/src/errors.ts +188 -5
- package/src/gvc/context.ts +96 -17
- package/src/gvc/device.ts +11 -6
- package/src/gvc/image-resolver.ts +25 -2
- package/src/gvc/job.ts +3 -1
- package/src/gvc/usershape.ts +6 -0
- package/src/index.ts +59 -43
- package/src/label/index.ts +6 -2
- package/src/label/node.ts +2 -1
- package/src/label/rectangle.ts +4 -2
- package/src/layout/circo/circular.ts +9 -6
- package/src/layout/dot/pack-components.ts +6 -2
- package/src/layout/dot/position.ts +21 -3
- package/src/layout/fdp/derive.ts +7 -6
- package/src/layout/fdp/index.ts +45 -5
- package/src/layout/fdp/init.ts +7 -6
- package/src/layout/fdp/layout.ts +2 -1
- package/src/layout/fdp/normalize.ts +12 -8
- package/src/layout/fdp/ports.ts +3 -2
- package/src/layout/fdp/xlayout.ts +8 -5
- package/src/layout/neato/adjust-info.ts +332 -0
- package/src/layout/neato/cdt-surface.ts +50 -30
- package/src/layout/neato/constraint-adjust.ts +466 -0
- package/src/layout/neato/edge-len.ts +36 -0
- package/src/layout/neato/fdp-adjust.ts +120 -12
- package/src/layout/neato/index.ts +36 -54
- package/src/layout/neato/init.ts +21 -36
- package/src/layout/neato/kk-paths.ts +146 -0
- package/src/layout/neato/kk-solve.ts +64 -0
- package/src/layout/neato/kk.ts +322 -0
- package/src/layout/neato/multispline-router.ts +4 -3
- package/src/layout/neato/poly.ts +493 -0
- package/src/layout/neato/sc-adjust.ts +2 -16
- package/src/layout/neato/sgd-dijkstra.ts +125 -0
- package/src/layout/neato/sgd.ts +63 -40
- package/src/layout/neato/simple-scale.ts +54 -0
- package/src/layout/neato/start.ts +222 -0
- package/src/layout/neato/vpsc-adjust.ts +93 -0
- package/src/layout/sfdp/index.ts +4 -5
- package/src/layout/sfdp/init.ts +40 -4
- package/src/layout/sfdp/spring-driver.ts +30 -1
- package/src/layout/twopi/circle.ts +2 -1
- package/src/ortho/ortho-parallel.ts +2 -1
- package/src/ortho/trap-query.ts +2 -1
- package/src/parser/index.ts +11 -11
- package/src/render/index.ts +5 -0
- package/src/render/public.ts +24 -24
- package/src/render/svg.ts +1 -1
- package/src/render/xdot-public.ts +19 -18
- package/src/util/xml.ts +24 -30
- package/src/vpsc/Solver.ts +5 -3
package/README.md
CHANGED
|
@@ -77,42 +77,114 @@ structured error — see [Error handling](#error-handling).
|
|
|
77
77
|
|
|
78
78
|
## Error handling
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
dot-engine raises two kinds of error:
|
|
81
|
+
|
|
82
|
+
- `err instanceof DotEngineError` — dot-engine failed on this input: bad DOT
|
|
83
|
+
(`ParseError`), a layout/render failure (`RenderError`, including
|
|
84
|
+
`UNKNOWN_LAYOUT` and `UNSUPPORTED_FEATURE`), or a dot-engine bug
|
|
85
|
+
(`InternalError`).
|
|
86
|
+
- A standard `TypeError` / `RangeError` / `Error` with `code: 'ERR_…'` — the call
|
|
87
|
+
was wrong (bad argument type, unregistered engine, wrong call order).
|
|
88
|
+
|
|
89
|
+
Branch on `.code`, not on message text. For a result-style alternative that does
|
|
90
|
+
not throw for bad DOT, use `tryRenderSvg`:
|
|
82
91
|
|
|
83
92
|
```ts
|
|
84
93
|
import { tryRenderSvg } from '@knowvah/dot-engine';
|
|
85
94
|
|
|
86
95
|
const result = tryRenderSvg('digraph { a ->', 'dot');
|
|
87
|
-
if (result.svg) {
|
|
96
|
+
if (result.svg !== undefined) {
|
|
88
97
|
// success
|
|
89
98
|
} else {
|
|
90
|
-
const err = result.errors[0];
|
|
91
|
-
console.error(err
|
|
99
|
+
const err = result.errors?.[0];
|
|
100
|
+
console.error(err?.code, err?.friendlyMessage, err?.location);
|
|
92
101
|
// 'SYNTAX_UNEXPECTED_EOF' · 'The DOT source ended unexpectedly …' · { line, column, offset }
|
|
93
102
|
}
|
|
94
103
|
```
|
|
95
104
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
`
|
|
115
|
-
|
|
105
|
+
`tryRenderSvg` returns for any DOT input and throws only for invalid arguments.
|
|
106
|
+
Each entry in `errors` is plain data (`type`, `code`, `message`,
|
|
107
|
+
`friendlyMessage`, plus `location` / `expected` when present) with no `cause` and
|
|
108
|
+
no stack.
|
|
109
|
+
|
|
110
|
+
Every code, class, and the exceptions each public function can throw:
|
|
111
|
+
[Errors and exceptions](https://dot-engine.knowvah.com/guide/errors).
|
|
112
|
+
|
|
113
|
+
## Migrating to 2.0
|
|
114
|
+
|
|
115
|
+
2.0 changes which errors are thrown. Code that branches on `.code` keeps working
|
|
116
|
+
for DOT errors; the changes below are the ones that can affect callers.
|
|
117
|
+
|
|
118
|
+
| Situation | Before | After |
|
|
119
|
+
|-----------|--------|-------|
|
|
120
|
+
| `parse(non-string)` / `renderSvg(non-string, …)` | `ParseError` `GENERIC_ERROR` | `TypeError` `ERR_INVALID_ARG_TYPE` |
|
|
121
|
+
| Engine argument not registered | `RenderError` `RENDER_ERROR` | `TypeError` `ERR_INVALID_ARG_VALUE` |
|
|
122
|
+
| `tryRenderSvg` with invalid arguments (non-string source, unregistered engine) | Returned `{ errors: [...] }` (`GENERIC_ERROR` / `RENDER_ERROR`) | Throws `TypeError` (`ERR_INVALID_ARG_TYPE` / `ERR_INVALID_ARG_VALUE`) |
|
|
123
|
+
| Engine argument not registered, but the DOT sets a valid `layout=` | Rendered with the attribute's engine | `TypeError` `ERR_INVALID_ARG_VALUE` (the argument is checked first) |
|
|
124
|
+
| Format argument not registered (`render(g, 'pdf')`) | `RenderError` `RENDER_ERROR` | `TypeError` `ERR_INVALID_ARG_VALUE` |
|
|
125
|
+
| DOT `layout="foo"` unknown | `RenderError` `RENDER_ERROR` | `RenderError` `UNKNOWN_LAYOUT` (`type: 'semantic'`) |
|
|
126
|
+
| `render(null)` / `getDrawOps(null)` | `RenderError` ("Cannot read properties of null") | `TypeError` `ERR_INVALID_ARG_TYPE` |
|
|
127
|
+
| `getLayout(null)` / `addEdge(null, …)` | Raw `TypeError` (no code) | `TypeError` `ERR_INVALID_ARG_TYPE` |
|
|
128
|
+
| `getLayout` before layout | `RenderError` `GENERIC_ERROR` | `Error` `ERR_INVALID_STATE` |
|
|
129
|
+
| Builder fails to create a node or subgraph | `RenderError` `GENERIC_ERROR` | `InternalError` `INTERNAL_ERROR` |
|
|
130
|
+
| `ctx.layout` / `freeLayout` with a non-object `g` or non-string engine; `bestRenderer` with a non-string format | Incidental `TypeError` / generic `Error` | `TypeError` `ERR_INVALID_ARG_TYPE` |
|
|
131
|
+
| `getLayout(g, { yAxis: 'other' })` | Silently treated as y-up | `TypeError` `ERR_INVALID_ARG_VALUE` |
|
|
132
|
+
| `createGraph`, builder methods and handles with wrong argument types; `addEdge` with a non-string `name` | Accepted or coerced | `TypeError` `ERR_INVALID_ARG_TYPE` |
|
|
133
|
+
| `setImageSizer` / `setImageResolver` / `setTextMeasurer` with a wrong value | Accepted; failed later inside layout | `TypeError` `ERR_INVALID_ARG_TYPE` |
|
|
134
|
+
| Foreign throw inside layout or render (a bug) | `RenderError` `RENDER_ERROR`, original stack lost | `InternalError` `INTERNAL_ERROR`, `cause` is the original error |
|
|
135
|
+
|
|
136
|
+
Internal throw sites ported from Graphviz C keep the same condition and message;
|
|
137
|
+
only the class changes:
|
|
138
|
+
|
|
139
|
+
| Group | Before | After |
|
|
140
|
+
|-------|--------|-------|
|
|
141
|
+
| C `assert` / uncaught C++ `throw` sites (neato gts triangulation and multispline router, vpsc solver, ortho, label index, pack-components, fdp ports, twopi circle, gvc job) | `Error` | `InternalError` `INTERNAL_ERROR` |
|
|
142
|
+
| C `agerr` + `exit` sites (label rectangle-tree overflow, XML escape of malformed UTF-8) | `Error` | `RenderError` `RENDER_ERROR` |
|
|
143
|
+
| Graphviz features the port has not implemented (fdp overlap modes, sfdp `smoothing=` / `rotation=`, special shapes) | `Error` | `RenderError` `UNSUPPORTED_FEATURE` (`type: 'semantic'`) |
|
|
144
|
+
| gts constrained-Delaunay paths where C continues instead of failing | `Error` | No throw; behaviour now matches C |
|
|
145
|
+
|
|
146
|
+
Attributes that rendered an approximation in 1.x and now throw
|
|
147
|
+
`RenderError` `UNSUPPORTED_FEATURE`. The conditions are exact; the full list,
|
|
148
|
+
with every message, is the table in
|
|
149
|
+
[Errors and exceptions](./docs-site/guide/errors.md#unsupported-feature-reference):
|
|
150
|
+
|
|
151
|
+
| Engine | Attribute | Throws when |
|
|
152
|
+
|--------|-----------|-------------|
|
|
153
|
+
| neato | `mode=hier` | Always |
|
|
154
|
+
| neato | `mode=ipsep` | Only when Graphviz builds constraints (`diredgeconstraints`, `overlap=ipsep`, or a top-level cluster); otherwise unchanged |
|
|
155
|
+
| neato | `start=self` | `mode` is `major` or `ipsep` |
|
|
156
|
+
| neato | `model=subset` | `mode` is `major` or `KK` |
|
|
157
|
+
| neato | `model=circuit` | `mode` is `major`, or `KK` on a connected graph |
|
|
158
|
+
| neato, twopi, circo, sfdp | `overlap=voronoi` | 2+ nodes and Graphviz's own overlap count (node polygons, not bounding boxes) is above 0. circo: single-component graphs; sfdp: new in 2.0 (the mode was previously ignored); only when `overlap` is not a prism mode |
|
|
159
|
+
| fdp | `splines=compound` | Always |
|
|
160
|
+
| fdp | `overlap=` `voronoi`, `oscale`, `vpsc`, `ipsep`, `ortho*`, `portho*` | The mode is reached after the force-iteration tries |
|
|
161
|
+
| sfdp | `label_scheme=1`..`4` | A `\|edgelabel\|` node exists and Graphviz takes the edge-label path |
|
|
162
|
+
| sfdp | `quadtree=none` or `quadtree=fast` | Always |
|
|
163
|
+
|
|
164
|
+
Behaviour fixes. These render differently from 1.x because 1.x did not match
|
|
165
|
+
Graphviz; no code change is needed:
|
|
166
|
+
|
|
167
|
+
| Area | Before | After |
|
|
168
|
+
|------|--------|-------|
|
|
169
|
+
| dot `nslimit` | Ignored; network simplex ran to convergence | Caps the x-coordinate iterations, as Graphviz does |
|
|
170
|
+
| neato `start=regular` | Treated as random | Nodes start on a regular polygon, as Graphviz does |
|
|
171
|
+
| neato `start=randomN` | Only digit-led values were seeded | `N` seeds the generator, as Graphviz does |
|
|
172
|
+
| neato and fdp `inputscale` | Ignored | Divides user `pos` values (and fdp cluster `coords`); `0` or a negative value means 72, absent means no scaling |
|
|
173
|
+
| neato `mode=KK` | Ran stress majorization | Runs Kamada-Kawai, as Graphviz. A disconnected graph without `pack` or `packmode` is laid out whole, not packed |
|
|
174
|
+
| neato `mode=sgd` | Ran stress majorization | Runs stochastic gradient descent, as Graphviz; honours edge `len` and seeds from `start`. Graphviz seeds from the clock when `start` is unset, so set `start=<n>` for reproducible output |
|
|
175
|
+
| neato unknown `mode` value | Ignored without a message | Warns `Illegal value X for attribute "mode" in graph G - ignored` and runs `major`, as Graphviz |
|
|
176
|
+
| neato, twopi, circo, sfdp `overlap=oscale`, `ortho*`, `portho*` | Ignored; overlaps left in place | Removed, as Graphviz (`oscale` scales, the others run constraint-based removal) |
|
|
177
|
+
| neato `overlap=vpsc` | Gap of `nodesep/2` between nodes | Gap of `2*sep` (additive) or 2 x 4 pt, as Graphviz; output changes on every graph using this mode |
|
|
178
|
+
| sfdp `overlap=` any non-prism mode other than `voronoi` | Ignored except `scale` | Runs Graphviz's removal after layout (`voronoi` with overlapping nodes is now an error; see above) |
|
|
179
|
+
| fdp cluster `coords` set only on a subgraph | Ignored | Honoured, as Graphviz |
|
|
180
|
+
| `overlap=voronoi` with nodes that only touch by bounding box | `UNSUPPORTED_FEATURE` | Renders: the overlap test now uses node polygons, as Graphviz |
|
|
181
|
+
| `ctx.freeLayout(g, engine)` | Cleaned up with the engine argument | Cleans up with the engine that ran the layout |
|
|
182
|
+
| XML escaping in UTF-8 mode (no public API sets this mode) | Decoded UTF-16 units as UTF-8 bytes, so a character such as U+00FF raised `RENDER_ERROR` | Escapes by code point (`😀`), matching Graphviz; a lone surrogate still raises `RENDER_ERROR` |
|
|
183
|
+
| fdp edges to cluster endpoints under spline routing (for example `splines=true`) | Drew line segments silently | Also prints the Graphviz warning (`splines and cluster edges not supported - using line segments`) |
|
|
184
|
+
|
|
185
|
+
New exports: `DotEngineError`, `InternalError`, `isGvError`, and the type
|
|
186
|
+
`UsageErrorCode`. `GvErrorCode` gains `INTERNAL_ERROR`, `UNKNOWN_LAYOUT` and
|
|
187
|
+
`UNSUPPORTED_FEATURE`.
|
|
116
188
|
|
|
117
189
|
## Layout engines
|
|
118
190
|
|
|
@@ -150,6 +222,55 @@ caller-supplied hook may be required:
|
|
|
150
222
|
setImageSizer((src) => ({ w: 64, h: 64 })); // return null if unknown
|
|
151
223
|
```
|
|
152
224
|
|
|
225
|
+
### Rendering into a page
|
|
226
|
+
|
|
227
|
+
`renderSvgInto` renders DOT, **waits for the web fonts the graph uses**, and
|
|
228
|
+
replaces the children of an element with the resulting `<svg>`. Insertion goes
|
|
229
|
+
through `DOMParser` + `importNode` (never `innerHTML`) and the SVG is scrubbed by
|
|
230
|
+
default (see [Security](#security)).
|
|
231
|
+
|
|
232
|
+
```html
|
|
233
|
+
<div id="graph"></div>
|
|
234
|
+
<script type="module">
|
|
235
|
+
import { renderSvgInto } from '@knowvah/dot-engine';
|
|
236
|
+
|
|
237
|
+
const dot = 'digraph { node [fontname="JetBrains Mono"]; a -> b }';
|
|
238
|
+
const { element, fontIssues } = await renderSvgInto('graph', dot, 'dot');
|
|
239
|
+
|
|
240
|
+
for (const { face, reason } of fontIssues) {
|
|
241
|
+
// reason is 'failed' (the face errored) or 'timeout' (not loaded within
|
|
242
|
+
// fontTimeoutMs, default 3000). Layout used a fallback font for this face.
|
|
243
|
+
console.warn(`font ${face}: ${reason}`);
|
|
244
|
+
}
|
|
245
|
+
</script>
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Fonts only need prefetching when they are declared with `@font-face`; an unloaded
|
|
249
|
+
face is measured as the fallback font and the labels come out the wrong size.
|
|
250
|
+
`fontIssues` never causes a rejection — it reports what could not be loaded.
|
|
251
|
+
|
|
252
|
+
To get the SVG string instead of inserting it, use `renderSvgAsync`. It also
|
|
253
|
+
accepts an **async** `imageSizer` (and `imageResolver`), awaited once per distinct
|
|
254
|
+
image before layout:
|
|
255
|
+
|
|
256
|
+
```ts
|
|
257
|
+
import { renderSvgAsync } from '@knowvah/dot-engine';
|
|
258
|
+
|
|
259
|
+
const { svg, fontIssues } = await renderSvgAsync(
|
|
260
|
+
'digraph { a [label=<<TABLE><TR><TD><IMG SRC="logo.png"/></TD></TR></TABLE>>] }',
|
|
261
|
+
'dot',
|
|
262
|
+
{
|
|
263
|
+
imageSizer: async (src) => {
|
|
264
|
+
const img = new Image();
|
|
265
|
+
img.src = src;
|
|
266
|
+
await img.decode(); // a rejection counts as "unknown size" (a miss)
|
|
267
|
+
return { w: img.naturalWidth, h: img.naturalHeight };
|
|
268
|
+
},
|
|
269
|
+
fontTimeoutMs: 5000,
|
|
270
|
+
},
|
|
271
|
+
);
|
|
272
|
+
```
|
|
273
|
+
|
|
153
274
|
### Text measurement
|
|
154
275
|
|
|
155
276
|
Layout needs to know how wide each label is. By default this uses a **built-in,
|
|
@@ -216,22 +337,67 @@ a **Content-Security-Policy** on the host page as the control point:
|
|
|
216
337
|
If you cannot set a CSP, sanitize the returned markup (e.g. DOMPurify with an
|
|
217
338
|
SVG profile) before inserting it, or render from trusted DOT only.
|
|
218
339
|
|
|
340
|
+
### `renderSvgInto` and the built-in scrubber
|
|
341
|
+
|
|
342
|
+
`renderSvgInto` sanitizes by default, so inserting untrusted DOT does not need
|
|
343
|
+
extra work for the common vectors. The built-in scrubber **removes**:
|
|
344
|
+
|
|
345
|
+
- `<script>` and `<foreignObject>` elements (with their subtrees),
|
|
346
|
+
- every `on*` event-handler attribute,
|
|
347
|
+
- `href` / `xlink:href` values using `javascript:` or `vbscript:`, and `data:`
|
|
348
|
+
hrefs other than `data:image/*` on `<image>`,
|
|
349
|
+
- SMIL animations (`set`, `animate`, `animateMotion`, `animateTransform`) that
|
|
350
|
+
target `href` or an event handler,
|
|
351
|
+
- `xml-stylesheet` processing instructions.
|
|
352
|
+
|
|
353
|
+
It **keeps** `http(s)` hrefs and image origins (they are normal, working links
|
|
354
|
+
and images) and `data:image/*` on `<image>`. Origin policy is therefore still
|
|
355
|
+
yours: it is a deny-list for the vectors this library's own output can carry,
|
|
356
|
+
**not** a replacement for a Content-Security-Policy, which remains recommended.
|
|
357
|
+
|
|
358
|
+
Options, in precedence order:
|
|
359
|
+
|
|
360
|
+
- `trusted: true` — insert exactly as rendered, no sanitizing. Only for DOT you
|
|
361
|
+
authored.
|
|
362
|
+
- `sanitize: (svg: string) => string` — replace the built-in scrubber with your
|
|
363
|
+
own, e.g. DOMPurify:
|
|
364
|
+
|
|
365
|
+
```ts
|
|
366
|
+
import DOMPurify from 'dompurify';
|
|
367
|
+
import { renderSvgInto } from '@knowvah/dot-engine';
|
|
368
|
+
|
|
369
|
+
await renderSvgInto('graph', dot, 'dot', {
|
|
370
|
+
sanitize: (svg) => DOMPurify.sanitize(svg, { USE_PROFILES: { svg: true } }),
|
|
371
|
+
});
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
- neither — the built-in scrubber runs.
|
|
375
|
+
|
|
376
|
+
`renderSvgAsync` and `renderAsync` return raw markup and do **not** sanitize;
|
|
377
|
+
the caveats above apply to their output exactly as for `renderSvg`.
|
|
378
|
+
|
|
219
379
|
## Public API
|
|
220
380
|
|
|
221
381
|
```ts
|
|
222
|
-
// Primary entry point. Throws a
|
|
382
|
+
// Primary entry point. Throws a DotEngineError (ParseError / RenderError /
|
|
383
|
+
// InternalError) for bad input, or a TypeError with a code for a bad call.
|
|
223
384
|
function renderSvg(dotSource: string, engine: string): string;
|
|
224
385
|
|
|
225
|
-
// Result-style entry point: returns { svg } or { errors: [GvError] }
|
|
386
|
+
// Result-style entry point: returns { svg } or { errors: [GvError] } for any DOT
|
|
387
|
+
// input; throws only for invalid arguments.
|
|
226
388
|
function tryRenderSvg(dotSource: string, engine: string): RenderResult;
|
|
227
389
|
|
|
228
390
|
// Structured error contract (see "Error handling").
|
|
229
391
|
interface GvError { type; code; message; friendlyMessage; location?; expected?; }
|
|
230
392
|
interface RenderResult { svg?: string; errors?: GvError[]; }
|
|
231
393
|
type GvErrorType = 'syntax' | 'semantic' | 'render';
|
|
232
|
-
type GvErrorCode = 'SYNTAX_ERROR' | 'SYNTAX_UNEXPECTED_EOF' | /* …
|
|
233
|
-
|
|
234
|
-
class
|
|
394
|
+
type GvErrorCode = 'SYNTAX_ERROR' | 'SYNTAX_UNEXPECTED_EOF' | /* …10 total */ 'GENERIC_ERROR';
|
|
395
|
+
type UsageErrorCode = 'ERR_INVALID_ARG_TYPE' | 'ERR_INVALID_ARG_VALUE' | 'ERR_OUT_OF_RANGE' | 'ERR_INVALID_STATE';
|
|
396
|
+
abstract class DotEngineError extends Error implements GvError {}
|
|
397
|
+
class ParseError extends DotEngineError { /* type:'syntax' */ }
|
|
398
|
+
class RenderError extends DotEngineError { /* type:'render' | 'semantic' */ }
|
|
399
|
+
class InternalError extends DotEngineError { /* type:'render' */ }
|
|
400
|
+
function isGvError(e: unknown): e is GvError;
|
|
235
401
|
|
|
236
402
|
// Parse DOT into the in-memory graph model (without laying it out).
|
|
237
403
|
function parse(dotSource: string): Graph;
|
|
@@ -240,6 +406,42 @@ function parse(dotSource: string): Graph;
|
|
|
240
406
|
function setImageSizer(sizer: ImageSizer | null): void;
|
|
241
407
|
type ImageSizer = (src: string) => { w: number; h: number } | null;
|
|
242
408
|
|
|
409
|
+
// Async counterparts: prefetch web fonts and image data, then render. Font
|
|
410
|
+
// problems never reject; they are returned in `fontIssues`.
|
|
411
|
+
function renderSvgAsync(
|
|
412
|
+
dotSource: string,
|
|
413
|
+
engine: EngineName,
|
|
414
|
+
opts?: AsyncSvgOptions,
|
|
415
|
+
): Promise<{ svg: string; fontIssues: FontIssue[] }>;
|
|
416
|
+
function renderAsync(
|
|
417
|
+
g: Graph,
|
|
418
|
+
format: OutputFormat,
|
|
419
|
+
opts?: AsyncRenderOptions,
|
|
420
|
+
): Promise<{ output: string; fontIssues: FontIssue[] }>;
|
|
421
|
+
|
|
422
|
+
// Render and insert into the element with the given id (browser; sanitizes by
|
|
423
|
+
// default).
|
|
424
|
+
function renderSvgInto(
|
|
425
|
+
id: string,
|
|
426
|
+
src: string,
|
|
427
|
+
engine: EngineName,
|
|
428
|
+
opts?: RenderSvgIntoOptions,
|
|
429
|
+
): Promise<{ element: SVGSVGElement; fontIssues: FontIssue[] }>;
|
|
430
|
+
|
|
431
|
+
type FontIssue = { face: string; reason: 'failed' | 'timeout' };
|
|
432
|
+
interface AsyncRenderOptions extends RenderOptions {
|
|
433
|
+
imageSizer?: (src: string) => Promise<{ w: number; h: number } | null>;
|
|
434
|
+
imageResolver?: (src: string) => Promise<{ bytes: Uint8Array; mime?: string } | Uint8Array | null>;
|
|
435
|
+
fontTimeoutMs?: number; // default 3000
|
|
436
|
+
fontSet?: FontSetLike; // default document.fonts
|
|
437
|
+
}
|
|
438
|
+
type AsyncSvgOptions = Omit<AsyncRenderOptions, 'engine'>;
|
|
439
|
+
interface RenderSvgIntoOptions extends AsyncSvgOptions {
|
|
440
|
+
sanitize?: (svg: string) => string;
|
|
441
|
+
trusted?: boolean;
|
|
442
|
+
document?: Document;
|
|
443
|
+
}
|
|
444
|
+
|
|
243
445
|
// Multi-format render + structured xdot draw-ops (from `@knowvah/dot-engine/render`,
|
|
244
446
|
// also re-exported from the root package).
|
|
245
447
|
function render(g: Graph, format: OutputFormat, opts?: { engine?: string }): string;
|
package/dist/api/builder.d.ts
CHANGED
|
@@ -72,6 +72,9 @@ export interface GvGraphBuilder {
|
|
|
72
72
|
* The builder's `.graph` is a fresh Graph ready for handoff to layout/render.
|
|
73
73
|
* Defaults: directed=true, strict=false, name=''.
|
|
74
74
|
*
|
|
75
|
+
* @throws TypeError `ERR_INVALID_ARG_TYPE` if `opts` or one of its fields has
|
|
76
|
+
* the wrong type. Builder and handle methods throw the same for wrong
|
|
77
|
+
* argument types, and `InternalError` if node/subgraph creation fails.
|
|
75
78
|
* @see lib/cgraph/graph.c:agopen
|
|
76
79
|
*/
|
|
77
80
|
export declare function createGraph(opts?: CreateGraphOptions): GvGraphBuilder;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/api/builder.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,KAAK,EAAkB,MAAM,mBAAmB,CAAC;AAU1D,+BAA+B;AAC/B,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC;;;;;OAKG;IACH,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACxC;AAED;;;GAGG;AACH,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC;;;OAGG;IACH,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACxC;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC;IAC9D,OAAO,CACL,IAAI,EAAE,MAAM,GAAG,MAAM,EACrB,IAAI,EAAE,MAAM,GAAG,MAAM,EACrB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,MAAM,CAAC;IACV,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,cAAc,CAAC;IAC1E,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC;;;;;OAKG;IACH,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;CACvB;
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/api/builder.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,KAAK,EAAkB,MAAM,mBAAmB,CAAC;AAU1D,+BAA+B;AAC/B,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC;;;;;OAKG;IACH,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACxC;AAED;;;GAGG;AACH,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC;;;OAGG;IACH,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACxC;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC;IAC9D,OAAO,CACL,IAAI,EAAE,MAAM,GAAG,MAAM,EACrB,IAAI,EAAE,MAAM,GAAG,MAAM,EACrB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,MAAM,CAAC;IACV,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,cAAc,CAAC;IAC1E,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC;;;;;OAKG;IACH,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;CACvB;AAmPD;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,IAAI,CAAC,EAAE,kBAAkB,GAAG,cAAc,CAIrE"}
|
package/dist/api/edge-ops.d.ts
CHANGED
|
@@ -8,6 +8,11 @@
|
|
|
8
8
|
import type { Graph } from '../model/graph.js';
|
|
9
9
|
import type { Node } from '../model/node.js';
|
|
10
10
|
import { Edge } from '../model/edge.js';
|
|
11
|
+
/**
|
|
12
|
+
* Argument check shared by the /api entry points: a non-null object.
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
export declare function requireObject(param: string, v: unknown): void;
|
|
11
16
|
/**
|
|
12
17
|
* Create and insert an edge from `tail` to `head` in graph `g`.
|
|
13
18
|
*
|
|
@@ -39,6 +44,8 @@ import { Edge } from '../model/edge.js';
|
|
|
39
44
|
* // edge.tail === a, edge.head === b
|
|
40
45
|
* ```
|
|
41
46
|
*
|
|
47
|
+
* @throws TypeError `ERR_INVALID_ARG_TYPE` if `g`, `tail` or `head` is not an
|
|
48
|
+
* object, or `name` is neither undefined nor a string
|
|
42
49
|
* @see lib/cgraph/edge.c:agedge
|
|
43
50
|
*/
|
|
44
51
|
export declare function addEdge(g: Graph, tail: Node, head: Node, name?: string): Edge;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edge-ops.d.ts","sourceRoot":"","sources":["../../src/api/edge-ops.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"edge-ops.d.ts","sourceRoot":"","sources":["../../src/api/edge-ops.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAGxC;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,GAAG,IAAI,CAI7D;AAkDD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,OAAO,CACrB,CAAC,EAAE,KAAK,EACR,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,IAAI,EACV,IAAI,CAAC,EAAE,MAAM,GACZ,IAAI,CAkBN"}
|
package/dist/api/geometry.d.ts
CHANGED
|
@@ -237,12 +237,15 @@ export interface LayoutSnapshot {
|
|
|
237
237
|
* Must be called **after** `ctx.layout(g, engine)` (or `render`) has run.
|
|
238
238
|
* Before layout the geometry fields hold calloc-zero defaults (every node at
|
|
239
239
|
* the origin, an empty bounding box), so a not-yet-laid-out graph is rejected
|
|
240
|
-
* with
|
|
240
|
+
* with an `ERR_INVALID_STATE` error rather than returning that all-zero snapshot as if it
|
|
241
241
|
* were real geometry.
|
|
242
242
|
*
|
|
243
243
|
* @param g - Laid-out graph (internal model; not mutated by this function).
|
|
244
244
|
* @param opts - Coordinate options; defaults to `{ yAxis: 'down' }`.
|
|
245
|
-
* @throws
|
|
245
|
+
* @throws TypeError (`ERR_INVALID_ARG_TYPE`) if `g` is not an object or `opts`
|
|
246
|
+
* is not an object; (`ERR_INVALID_ARG_VALUE`) if `opts.yAxis` is not
|
|
247
|
+
* `'up'` or `'down'`.
|
|
248
|
+
* @throws Error (`ERR_INVALID_STATE`) if `g` has not been laid out.
|
|
246
249
|
*
|
|
247
250
|
* @see lib/common/types.h:GD_bb, ND_coord, ED_spl
|
|
248
251
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geometry.d.ts","sourceRoot":"","sources":["../../src/api/geometry.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"geometry.d.ts","sourceRoot":"","sources":["../../src/api/geometry.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAW/C,+CAA+C;AAC/C,MAAM,MAAM,KAAK,GAAG,IAAI,GAAG,MAAM,CAAC;AAElC;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG;IAAE,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAEhD;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc;IAC7B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,MAAM,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACnC;;;OAGG;IACH,EAAE,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9B;;;OAGG;IACH,EAAE,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9B,8EAA8E;IAC9E,KAAK,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjC;;;OAGG;IACH,SAAS,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC;;;OAGG;IACH,SAAS,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC;;;OAGG;IACH,MAAM,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,eAAe;IAC9B,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,KAAK,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACjE;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAgMD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,eAAe,GAAG,cAAc,CAwB1E"}
|