@weasel-js/diagram 1.13.0 → 1.14.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 +122 -17
- package/dist/{chunk-Y72FK3Y7.js → chunk-5VNPLOIX.js} +94 -6
- package/dist/chunk-5VNPLOIX.js.map +1 -0
- package/dist/{chunk-ESFIS7BB.js → chunk-62SMY45E.js} +918 -574
- package/dist/chunk-62SMY45E.js.map +1 -0
- package/dist/{chunk-FAQXYGMX.js → chunk-TBG6DFB2.js} +3 -3
- package/dist/{chunk-FAQXYGMX.js.map → chunk-TBG6DFB2.js.map} +1 -1
- package/dist/{chunk-L4H444QI.js → chunk-VB6HUKNG.js} +659 -185
- package/dist/chunk-VB6HUKNG.js.map +1 -0
- package/dist/{chunk-QU4QZUC6.js → chunk-ZWXM5F4I.js} +141 -39
- package/dist/chunk-ZWXM5F4I.js.map +1 -0
- package/dist/{dataTypes-DW-MljuN.d.ts → dataTypes-BIkhAOc4.d.ts} +13 -2
- package/dist/effect-audio.d.ts +2 -1
- package/dist/effect-audio.js +6 -5
- package/dist/effect-audio.js.map +1 -1
- package/dist/effect.d.ts +46 -16
- package/dist/effect.js +257 -102
- package/dist/effect.js.map +1 -1
- package/dist/icons.table.js +262 -0
- package/dist/icons.table.js.map +1 -1
- package/dist/icons.table.json +262 -0
- package/dist/index.d.ts +491 -167
- package/dist/index.js +586 -36
- package/dist/index.js.map +1 -1
- package/dist/labelTrait-BBjRgxbz.d.ts +44 -0
- package/dist/layout.d.ts +4 -3
- package/dist/{layout.entry-CQoPNfzA.d.ts → layout.entry-Ca6pVvqo.d.ts} +23 -2
- package/dist/layout.js +2 -2
- package/dist/{stageTypes-DvnR8cKQ.d.ts → stageTypes-UiO25hcn.d.ts} +7 -0
- package/dist/{types-vbW21fHm.d.ts → types-B0n2CNTW.d.ts} +108 -81
- package/package.json +11 -9
- package/dist/chunk-ESFIS7BB.js.map +0 -1
- package/dist/chunk-L4H444QI.js.map +0 -1
- package/dist/chunk-QU4QZUC6.js.map +0 -1
- package/dist/chunk-Y72FK3Y7.js.map +0 -1
package/dist/effect.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { DiagramView, reorderContribution, ANYWHERE, isBodyEnd, sequenceSlots } from './chunk-
|
|
2
|
-
import './chunk-
|
|
3
|
-
import { stageFromType, LOOK_THEME, drawableWires, uniqueStages, shownPorts, valueRowId, NO_VALUE, previewRowId, formatParam, stageStyle, PROBLEM_COLOR, typeColors, kindOf, boxNode, portOn, wireStyle, isControl, wireEdge, sceneStyles, uniqueGroups, wireEdges, exitLabel, splitProblem, checkPipeline, PREVIEW_DENSITY, runOrder, PREVIEW_SIZE, closeBitmaps, previewsOf, paramValues } from './chunk-
|
|
4
|
-
export { LOOK_THEME, NO_VALUE, PREVIEW_SIZE, PROBLEM_COLOR, checkPipeline, drawableWires, exitLabel, formatParam, isControl, kindOf, portOn, previewRowId, runOrder, shownPorts, stageFromType, stageRows, stageStyle, typeColors, uniqueGroups, uniqueStages, valueRowId, wireEdges, wireStyle } from './chunk-
|
|
5
|
-
import { diagramScene, diagramPages, edgeIdOf, titleIdOf, groupLabelIdOf, nestGroups, groupMinWidth, LABEL_PLACEMENT, EDGE_DERIVE_PATH } from './chunk-
|
|
6
|
-
import { portOf, insetOf, diagramNodeOf, DEFAULT_GROUP_INSET, SIDE_TRACK_GAP, widenForMinWidth, rankGaps, portSitesOf, labelCenter } from './chunk-
|
|
1
|
+
import { DiagramView, reorderContribution, ANYWHERE, isBodyEnd, sequenceSlots } from './chunk-62SMY45E.js';
|
|
2
|
+
import './chunk-5VNPLOIX.js';
|
|
3
|
+
import { stageFromType, LOOK_THEME, drawableWires, uniqueStages, shownPorts, valueRowId, NO_VALUE, previewRowId, formatParam, stageStyle, PROBLEM_COLOR, typeColors, kindOf, boxNode, portOn, wireStyle, isControl, wireEdge, sceneStyles, uniqueGroups, wireEdges, exitLabel, splitProblem, checkPipeline, PREVIEW_DENSITY, runOrder, PREVIEW_SIZE, closeBitmaps, previewsOf, paramValues } from './chunk-TBG6DFB2.js';
|
|
4
|
+
export { LOOK_THEME, NO_VALUE, PREVIEW_SIZE, PROBLEM_COLOR, checkPipeline, drawableWires, exitLabel, formatParam, isControl, kindOf, portOn, previewRowId, runOrder, shownPorts, stageFromType, stageRows, stageStyle, typeColors, uniqueGroups, uniqueStages, valueRowId, wireEdges, wireStyle } from './chunk-TBG6DFB2.js';
|
|
5
|
+
import { diagramScene, diagramPages, edgeIdOf, titleIdOf, groupLabelIdOf, nestGroups, groupMinWidth, LABEL_PLACEMENT, EDGE_DERIVE_PATH } from './chunk-ZWXM5F4I.js';
|
|
6
|
+
import { portOf, insetOf, diagramNodeOf, DEFAULT_GROUP_INSET, SIDE_TRACK_GAP, widenForMinWidth, rankGaps, portSitesOf, labelCenter, resolveOutline } from './chunk-VB6HUKNG.js';
|
|
7
|
+
import { moveItems, imeKey, isNoopDrop } from '@weasel-js/headless';
|
|
8
|
+
import { useLatest, bitmapSrc, ActionDisabledReason, worldPosesOf, RIGID_POSE_COMPOSITION, IDENTITY_POSE_COMPOSITION, pointAlongPath } from '@weasel-js/core';
|
|
7
9
|
import { polygonFromPoints } from '@weasel-js/core/math';
|
|
10
|
+
import { pathToD, transformPath, pathFromD, worldCoords } from '@weasel-js/geom';
|
|
8
11
|
import { forwardRef, useMemo, useRef, useState, useImperativeHandle, useEffect, useCallback, useSyncExternalStore } from 'react';
|
|
9
|
-
import { useLatest, bitmapSrc, ActionDisabledReason, pointAlongPath } from '@weasel-js/core';
|
|
10
12
|
import { releaseImageSource } from '@weasel-js/core/renderer';
|
|
11
13
|
import { jsx } from 'react/jsx-runtime';
|
|
12
14
|
import { useLatest as useLatest$1, adoptCssOnce, useVisibleRaf } from '@weasel-js/react';
|
|
@@ -113,8 +115,6 @@ function moveGroup(doc, id, offset) {
|
|
|
113
115
|
...boxes !== void 0 ? { groupBoxes: boxes } : {}
|
|
114
116
|
};
|
|
115
117
|
}
|
|
116
|
-
|
|
117
|
-
// src/effect/lookRoutes.ts
|
|
118
118
|
var EPS = 1e-3;
|
|
119
119
|
var near = (a, b) => Math.abs(a.x - b.x) <= EPS && Math.abs(a.y - b.y) <= EPS;
|
|
120
120
|
var copy = (p) => ({ x: p.x, y: p.y });
|
|
@@ -139,9 +139,10 @@ function wireEnds(specs, edge) {
|
|
|
139
139
|
const spec = specs.find((s) => s.id === edge);
|
|
140
140
|
const trait = spec?.data?.diagram;
|
|
141
141
|
const [from, to] = spec?.dependsOn ?? [];
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
142
|
+
const world = worldPosesOf(specs, RIGID_POSE_COMPOSITION);
|
|
143
|
+
const point = (node, port2) => {
|
|
144
|
+
const n = node === void 0 || port2 === void 0 ? void 0 : specs.find((s) => s.id === node);
|
|
145
|
+
return n === void 0 ? void 0 : portOf({ id: node, kind: n.kind ?? "mark", data: n.data }, world.get(node), port2)?.point;
|
|
145
146
|
};
|
|
146
147
|
const a = point(from, trait?.from?.port);
|
|
147
148
|
const b = point(to, trait?.to?.port);
|
|
@@ -206,11 +207,24 @@ function removeStages(doc, ids) {
|
|
|
206
207
|
});
|
|
207
208
|
}
|
|
208
209
|
function pruneRoutes(doc, rewired = []) {
|
|
209
|
-
const pruned = pruneLookRoutes(doc, rewired);
|
|
210
|
+
const pruned = pruneLabels(pruneLookRoutes(doc, rewired));
|
|
210
211
|
if (pruned.routes === void 0) return pruned;
|
|
211
212
|
const ids = new Set(doc.pipeline.wires.flatMap((w) => w.id === void 0 || rewired.includes(w.id) ? [] : [w.id]));
|
|
212
213
|
return { ...pruned, routes: Object.fromEntries(Object.entries(pruned.routes).filter(([id]) => ids.has(id))) };
|
|
213
214
|
}
|
|
215
|
+
function pruneLabels(doc) {
|
|
216
|
+
if (doc.labels === void 0) return doc;
|
|
217
|
+
const ids = new Set(doc.pipeline.wires.flatMap((w) => w.id === void 0 ? [] : [w.id]));
|
|
218
|
+
const kept = Object.entries(doc.labels).filter(([id]) => ids.has(id));
|
|
219
|
+
const { labels: _was, ...rest } = doc;
|
|
220
|
+
return kept.length > 0 ? { ...rest, labels: Object.fromEntries(kept) } : rest;
|
|
221
|
+
}
|
|
222
|
+
function setWireLabel(doc, wire, placement) {
|
|
223
|
+
const { [wire]: _was, ...others } = doc.labels ?? {};
|
|
224
|
+
const { labels: _all, ...rest } = doc;
|
|
225
|
+
const labels = placement === null ? others : { ...others, [wire]: placement };
|
|
226
|
+
return Object.keys(labels).length > 0 ? { ...rest, labels } : rest;
|
|
227
|
+
}
|
|
214
228
|
function setWireRoute(doc, wire, points) {
|
|
215
229
|
const { [wire]: _was, ...rest } = doc.routes ?? {};
|
|
216
230
|
return { ...doc, routes: points.length > 0 ? { ...rest, [wire]: points.map((p) => ({ x: p.x, y: p.y })) } : rest };
|
|
@@ -332,12 +346,6 @@ function chainLinks(pipeline, chain) {
|
|
|
332
346
|
return { mainIn, mainOut, between: between2 };
|
|
333
347
|
}
|
|
334
348
|
var portsOf = (p, stage, side) => p.stages.find((s) => s.id === stage)?.[side] ?? [];
|
|
335
|
-
function movedChain(chain, i, j, to) {
|
|
336
|
-
const run = chain.slice(i, j + 1);
|
|
337
|
-
const out = [...chain.slice(0, i), ...chain.slice(j + 1)];
|
|
338
|
-
out.splice(to > j ? to - run.length : to, 0, ...run);
|
|
339
|
-
return out;
|
|
340
|
-
}
|
|
341
349
|
function moveInChain(doc, stage, to) {
|
|
342
350
|
return moveRunInChain(doc, stage, stage, to);
|
|
343
351
|
}
|
|
@@ -346,7 +354,8 @@ function moveRunInChain(doc, first, last, to) {
|
|
|
346
354
|
const chain = mainChain(p);
|
|
347
355
|
const i = chain.indexOf(first);
|
|
348
356
|
const j = chain.indexOf(last);
|
|
349
|
-
|
|
357
|
+
const run = Array.from({ length: j - i + 1 }, (_, k) => i + k);
|
|
358
|
+
if (i < 0 || j < i || !Number.isInteger(to) || to < 0 || to > chain.length || isNoopDrop(run, to)) return null;
|
|
350
359
|
const { mainIn, mainOut, between: between2 } = chainLinks(p, chain);
|
|
351
360
|
const wIn = i > 0 ? between2[i - 1] : void 0;
|
|
352
361
|
const wOut = j < chain.length - 1 ? between2[j] : void 0;
|
|
@@ -354,8 +363,8 @@ function moveRunInChain(doc, first, last, to) {
|
|
|
354
363
|
const gone = new Set([wIn, wOut, wAB].filter((k) => k !== void 0));
|
|
355
364
|
const kept = p.wires.filter((_, k) => !gone.has(k));
|
|
356
365
|
const free = (ref) => !kept.some((w) => w.to.stage === ref.stage && w.to.port === ref.port);
|
|
357
|
-
const pick = (id, side, type) => portsOf(p, id, side).find((
|
|
358
|
-
const typeOf = (id,
|
|
366
|
+
const pick = (id, side, type) => portsOf(p, id, side).find((port2) => (type === void 0 || port2.type === type) && (side === "outputs" || free({ stage: id, port: port2.id })))?.id;
|
|
367
|
+
const typeOf = (id, port2) => [...portsOf(p, id, "inputs"), ...portsOf(p, id, "outputs")].find((x) => x.id === port2)?.type;
|
|
359
368
|
const made = [];
|
|
360
369
|
const prev = chain[i - 1];
|
|
361
370
|
const next = chain[j + 1];
|
|
@@ -386,7 +395,7 @@ function moveRunInChain(doc, first, last, to) {
|
|
|
386
395
|
wires.push({ id: nextWireId({ ...p, wires }), from: m.from, to: m.to });
|
|
387
396
|
}
|
|
388
397
|
const pipeline = { ...p, wires };
|
|
389
|
-
const want =
|
|
398
|
+
const want = moveItems(chain, run, to);
|
|
390
399
|
const got = mainChain(pipeline);
|
|
391
400
|
if (got.length !== want.length || got.some((id, k) => id !== want[k])) return null;
|
|
392
401
|
return pruneRoutes({ ...doc, pipeline }, [...gone].flatMap((k) => p.wires[k].id ?? []));
|
|
@@ -394,6 +403,49 @@ function moveRunInChain(doc, first, last, to) {
|
|
|
394
403
|
function canMoveInChain(doc, stage, to) {
|
|
395
404
|
return moveInChain(doc, stage, to) !== null;
|
|
396
405
|
}
|
|
406
|
+
var DIAGONAL = [0, 1, 1, 0, 0, 0];
|
|
407
|
+
var SYMMETRIC = /* @__PURE__ */ new Set(["rect", "diamond", "ellipse"]);
|
|
408
|
+
var anchor = (at) => ({ u: at.v, v: at.u });
|
|
409
|
+
var vec = (p) => ({ x: p.y, y: p.x });
|
|
410
|
+
var transposeD = (d) => pathToD(transformPath(pathFromD(d), DIAGONAL));
|
|
411
|
+
function outline(o) {
|
|
412
|
+
if (typeof o === "string" && SYMMETRIC.has(o)) return o;
|
|
413
|
+
const path = typeof o === "string" ? resolveOutline(o).path({ x: 0, y: 0, width: 1, height: 1 }) : o;
|
|
414
|
+
return transformPath(path, DIAGONAL);
|
|
415
|
+
}
|
|
416
|
+
function port(p) {
|
|
417
|
+
const out = { ...p, at: anchor(p.at) };
|
|
418
|
+
if (p.sites !== void 0) {
|
|
419
|
+
out.sites = p.sites.map((s) => ({ ...s, ...anchor(s), ...s.normal ? { normal: vec(s.normal) } : {} }));
|
|
420
|
+
}
|
|
421
|
+
if (p.normal) out.normal = vec(p.normal);
|
|
422
|
+
return out;
|
|
423
|
+
}
|
|
424
|
+
function mark(m) {
|
|
425
|
+
if ("d" in m) return { ...m, d: transposeD(m.d) };
|
|
426
|
+
return {
|
|
427
|
+
...m,
|
|
428
|
+
at: anchor(m.at),
|
|
429
|
+
...m.self !== void 0 ? { self: anchor(m.self) } : {},
|
|
430
|
+
...m.offset !== void 0 ? { offset: vec(m.offset) } : {}
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
function transpose(node) {
|
|
434
|
+
const { width, height, ...rest } = node;
|
|
435
|
+
return {
|
|
436
|
+
...rest,
|
|
437
|
+
...node.outline !== void 0 ? { outline: outline(node.outline) } : {},
|
|
438
|
+
...node.ports !== void 0 ? { ports: node.ports.map(port) } : {},
|
|
439
|
+
...node.marks !== void 0 ? { marks: node.marks.map(mark) } : {},
|
|
440
|
+
...height !== void 0 ? { width: height } : {},
|
|
441
|
+
...width !== void 0 ? { height: width } : {}
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
var flowing = (symbol) => (stage, pipeline, options) => {
|
|
445
|
+
if (options?.direction !== "down") return symbol(stage, pipeline, options);
|
|
446
|
+
const row = { ...options, direction: "right", controlSide: options.controlSide === "right" ? "bottom" : "top" };
|
|
447
|
+
return transpose(symbol(stage, pipeline, row));
|
|
448
|
+
};
|
|
397
449
|
|
|
398
450
|
// src/effect/symbolParts.ts
|
|
399
451
|
function along(side, i, n) {
|
|
@@ -468,7 +520,10 @@ var hexagon = (stage, pipeline, options) => ({
|
|
|
468
520
|
lines: [stage.title],
|
|
469
521
|
ports: [...inputs(stage, pipeline, options, void 0, onHexagon), ...onHexagon(stage.outputs ?? [], "right")]
|
|
470
522
|
});
|
|
471
|
-
var
|
|
523
|
+
var CUT_SIZE = 10;
|
|
524
|
+
var CUT_GAP = 3;
|
|
525
|
+
var CUT_CHAR = 0.6 * CUT_SIZE;
|
|
526
|
+
var stepAlong = (titleGap) => (stage, pipeline, options) => {
|
|
472
527
|
if (!canBand(stage)) return diamond(stage, pipeline, options);
|
|
473
528
|
const exits = stage.outputs ?? [];
|
|
474
529
|
const n = exits.length;
|
|
@@ -483,10 +538,10 @@ var step = (stage, pipeline, options) => {
|
|
|
483
538
|
text: String(cut),
|
|
484
539
|
at: { u: riser(k), v: 1 },
|
|
485
540
|
self: { u: 0.5, v: 0 },
|
|
486
|
-
offset: { x: 0, y:
|
|
487
|
-
style: { fontSize:
|
|
541
|
+
offset: { x: 0, y: CUT_GAP },
|
|
542
|
+
style: { fontSize: CUT_SIZE }
|
|
488
543
|
}));
|
|
489
|
-
marks.push(title(stage, options,
|
|
544
|
+
marks.push(title(stage, options, titleGap));
|
|
490
545
|
return {
|
|
491
546
|
outline: "rect",
|
|
492
547
|
lines: [],
|
|
@@ -497,6 +552,12 @@ var step = (stage, pipeline, options) => {
|
|
|
497
552
|
marks
|
|
498
553
|
};
|
|
499
554
|
};
|
|
555
|
+
var step = (stage, pipeline, options) => {
|
|
556
|
+
if (options?.direction !== "down") return stepAlong(18)(stage, pipeline, options);
|
|
557
|
+
if (options.controlSide === "right") return flowing(stepAlong(18))(stage, pipeline, options);
|
|
558
|
+
const widest = Math.max(0, ...(stage.split?.at ?? []).map((cut) => String(cut).length * CUT_CHAR));
|
|
559
|
+
return flowing(stepAlong(Math.max(18, CUT_GAP + widest + 4)))(stage, pipeline, options);
|
|
560
|
+
};
|
|
500
561
|
var TRIANGLE = [[0, 0], [1, 0.5], [0, 1]];
|
|
501
562
|
var COMPARATOR = outlineOf(TRIANGLE);
|
|
502
563
|
var EXIT_AT = 0.7;
|
|
@@ -615,10 +676,14 @@ var demux = (stage, pipeline, options) => {
|
|
|
615
676
|
var LEVER_FIRST = "M0.2 0.5 L0.78 0.27";
|
|
616
677
|
var CONTACT_FIRST = dot(0.8, 0.25, 0.07);
|
|
617
678
|
var CONTACT_SECOND = dot(0.8, 0.75, 0.07);
|
|
618
|
-
var
|
|
679
|
+
var THROWN_ALONG = [
|
|
619
680
|
[LEVER_FIRST, "M0.2 0.5 L0.78 0.73"],
|
|
620
681
|
[CONTACT_FIRST, CONTACT_SECOND],
|
|
621
682
|
[CONTACT_SECOND, CONTACT_FIRST]
|
|
683
|
+
];
|
|
684
|
+
var THROWN_SECOND = new Map([
|
|
685
|
+
...THROWN_ALONG,
|
|
686
|
+
...THROWN_ALONG.map(([from, to]) => [transposeD(from), transposeD(to)])
|
|
622
687
|
]);
|
|
623
688
|
var thrownToSecond = (d) => THROWN_SECOND.get(d);
|
|
624
689
|
var switchSymbol = (stage, pipeline, options) => {
|
|
@@ -646,15 +711,15 @@ var switchSymbol = (stage, pipeline, options) => {
|
|
|
646
711
|
};
|
|
647
712
|
};
|
|
648
713
|
var BRANCH_SYMBOLS = Object.freeze({
|
|
649
|
-
diamond,
|
|
650
|
-
bar,
|
|
651
|
-
demux,
|
|
652
|
-
switch: switchSymbol,
|
|
653
|
-
hexagon,
|
|
714
|
+
diamond: flowing(diamond),
|
|
715
|
+
bar: flowing(bar),
|
|
716
|
+
demux: flowing(demux),
|
|
717
|
+
switch: flowing(switchSymbol),
|
|
718
|
+
hexagon: flowing(hexagon),
|
|
654
719
|
step,
|
|
655
|
-
comparator,
|
|
656
|
-
crossover,
|
|
657
|
-
fork
|
|
720
|
+
comparator: flowing(comparator),
|
|
721
|
+
crossover: flowing(crossover),
|
|
722
|
+
fork: flowing(fork)
|
|
658
723
|
});
|
|
659
724
|
var NEEDS = {
|
|
660
725
|
bar: canBand,
|
|
@@ -679,7 +744,7 @@ function sidePorts(stage) {
|
|
|
679
744
|
...(stage.outputs ?? []).map((p) => ({ id: p.id, at: { u: 1, v: 0.5 } }))
|
|
680
745
|
];
|
|
681
746
|
}
|
|
682
|
-
var untyped = (ports) => (ports ?? []).map(({ type: _type, ...
|
|
747
|
+
var untyped = (ports) => (ports ?? []).map(({ type: _type, ...port2 }) => port2);
|
|
683
748
|
function nodeOf(stage, pipeline, branch, theme) {
|
|
684
749
|
if (kindOf(stage) !== "decision") {
|
|
685
750
|
return { ...boxNode(stage, { showParams: false, rowPorts: false, ports: sidePorts(stage) }), padding: COMPACT_PADDING };
|
|
@@ -823,8 +888,8 @@ function ownerOf(stages) {
|
|
|
823
888
|
const parent = spec.parent;
|
|
824
889
|
if (parent !== void 0 && stages.has(parent)) return parent;
|
|
825
890
|
const deps = spec.dependsOn;
|
|
826
|
-
const
|
|
827
|
-
return
|
|
891
|
+
const anchor2 = Array.isArray(deps) && deps.length === 1 ? deps[0] : void 0;
|
|
892
|
+
return anchor2 !== void 0 && stages.has(anchor2) ? anchor2 : void 0;
|
|
828
893
|
};
|
|
829
894
|
}
|
|
830
895
|
function wireEnds2(spec) {
|
|
@@ -859,9 +924,10 @@ function costSpec(stage, own, of, text, problem) {
|
|
|
859
924
|
const fill = problem ? { paint: { color: PROBLEM_COLOR } } : titleData.fill ?? { paint: { color: stageStyle(of).text } };
|
|
860
925
|
const width = text.length * fontSize * 0.6;
|
|
861
926
|
const height = Math.ceil(fontSize * 1.2);
|
|
862
|
-
const
|
|
927
|
+
const world = worldPosesOf([stage, ...own], RIGID_POSE_COMPOSITION);
|
|
928
|
+
const box = world.get(stage.id);
|
|
863
929
|
const top = Math.min(box.y, ...own.flatMap((s) => {
|
|
864
|
-
const p = s.
|
|
930
|
+
const p = world.get(s.id);
|
|
865
931
|
return s !== stage && p !== void 0 && p.y + p.height <= box.y ? [p.y] : [];
|
|
866
932
|
}));
|
|
867
933
|
return {
|
|
@@ -885,8 +951,8 @@ function useRunPortOptions(color, pipeline, run) {
|
|
|
885
951
|
shape: "circle",
|
|
886
952
|
sizePx: 8,
|
|
887
953
|
// Every port a look declares has a value type; the compass defaults have none.
|
|
888
|
-
showsPort: (
|
|
889
|
-
fill: (
|
|
954
|
+
showsPort: (port2) => port2.type !== void 0,
|
|
955
|
+
fill: (port2) => ({ paint: { color: color(port2.type), ...faded.has(port2.nodeId) ? { opacity: DIM } : {} } })
|
|
890
956
|
};
|
|
891
957
|
}, [color, missed]);
|
|
892
958
|
}
|
|
@@ -1010,10 +1076,15 @@ function orient(p, a, b) {
|
|
|
1010
1076
|
if (canWire(p, b, a)) return { from: b, to: a };
|
|
1011
1077
|
return null;
|
|
1012
1078
|
}
|
|
1013
|
-
var
|
|
1079
|
+
var same = (a, b) => a.stage === b.stage && a.port === b.port;
|
|
1080
|
+
var takesMany = (p, to) => p.stages.find((s) => s.id === to.stage)?.inputs?.find((i) => i.id === to.port)?.many === true;
|
|
1081
|
+
var fed = (p, from, to, except) => {
|
|
1082
|
+
const many = takesMany(p, to);
|
|
1083
|
+
return p.wires.some((w) => same(w.to, to) && (!many || same(w.from, from)) && (except === void 0 || w.id !== except));
|
|
1084
|
+
};
|
|
1014
1085
|
function wireFor(p, a, b, except) {
|
|
1015
1086
|
const wire = orient(p, a, b);
|
|
1016
|
-
return wire !== null && !fed(p, wire.to, except) ? wire : null;
|
|
1087
|
+
return wire !== null && !fed(p, wire.from, wire.to, except) ? wire : null;
|
|
1017
1088
|
}
|
|
1018
1089
|
function pinShown(doc, specs) {
|
|
1019
1090
|
const shown = Object.fromEntries([...stageBoxes(doc, specs)].map(([id, b]) => [id, { x: b.x, y: b.y }]));
|
|
@@ -1021,7 +1092,8 @@ function pinShown(doc, specs) {
|
|
|
1021
1092
|
}
|
|
1022
1093
|
function stageBoxes(doc, specs) {
|
|
1023
1094
|
const ids = new Set(doc.pipeline.stages.map((s) => s.id));
|
|
1024
|
-
|
|
1095
|
+
const world = worldPosesOf(specs, RIGID_POSE_COMPOSITION);
|
|
1096
|
+
return new Map(specs.filter((s) => ids.has(s.id)).map((s) => [s.id, world.get(s.id)]));
|
|
1025
1097
|
}
|
|
1026
1098
|
function editHandlers(now, unpick, rename = () => {
|
|
1027
1099
|
}) {
|
|
@@ -1040,7 +1112,7 @@ function editHandlers(now, unpick, rename = () => {
|
|
|
1040
1112
|
held = false;
|
|
1041
1113
|
const reports = { moves: drag.moves.splice(0), boxes: drag.boxes.splice(0) };
|
|
1042
1114
|
const { doc, built, specs, onChange } = now();
|
|
1043
|
-
const boxes =
|
|
1115
|
+
const boxes = worldPosesOf(specs, RIGID_POSE_COMPOSITION);
|
|
1044
1116
|
const out = dragEdit(pinShown(ensureWireIds(doc), specs), built, reports, (id) => boxes.get(id));
|
|
1045
1117
|
if (out !== null) onChange(out.doc, out.label);
|
|
1046
1118
|
});
|
|
@@ -1064,7 +1136,7 @@ function editHandlers(now, unpick, rename = () => {
|
|
|
1064
1136
|
if (id === void 0 || wire === void 0 || c.port === void 0) return null;
|
|
1065
1137
|
const moved = { stage: c.node, port: c.port };
|
|
1066
1138
|
const [from, to] = c.end === "from" ? [moved, wire.to] : [wire.from, moved];
|
|
1067
|
-
return canWire(d.pipeline, from, to) && !fed(d.pipeline, to, id) ? reconnectWire(d, id, c.end, moved) : null;
|
|
1139
|
+
return canWire(d.pipeline, from, to) && !fed(d.pipeline, from, to, id) ? reconnectWire(d, id, c.end, moved) : null;
|
|
1068
1140
|
}),
|
|
1069
1141
|
onEditRoute: (c) => commit("Edit route", (d, b) => {
|
|
1070
1142
|
const id = b.wireOf(c.edge);
|
|
@@ -1078,6 +1150,11 @@ function editHandlers(now, unpick, rename = () => {
|
|
|
1078
1150
|
const ends = wireEnds(specs, c.edge);
|
|
1079
1151
|
return ends === void 0 ? null : setLookRoute(d, look, id, c.waypoints, ends);
|
|
1080
1152
|
}),
|
|
1153
|
+
onMoveLabel: (m) => commit("Move label", (d, b) => {
|
|
1154
|
+
const id = b.wireOf(m.edge);
|
|
1155
|
+
if (id === void 0 || m.placement === null && d.labels?.[id] === void 0) return null;
|
|
1156
|
+
return setWireLabel(d, id, m.placement);
|
|
1157
|
+
}),
|
|
1081
1158
|
onDelete: (r) => commit("Delete", (d, b) => {
|
|
1082
1159
|
unpick();
|
|
1083
1160
|
const stages = r.nodes.flatMap((n) => b.stageOf(n) ?? []);
|
|
@@ -1105,14 +1182,14 @@ function useEditorPicks(built, given) {
|
|
|
1105
1182
|
const [group, setGroup] = useState(null);
|
|
1106
1183
|
const [edge, setEdge] = useState(null);
|
|
1107
1184
|
const latest = useLatest$1({ built, given });
|
|
1108
|
-
const pick = useCallback((id) => {
|
|
1185
|
+
const pick = useCallback((id, ids = id === null ? [] : [id]) => {
|
|
1109
1186
|
const { built: b, given: g } = latest.current;
|
|
1110
1187
|
const s = id === null ? void 0 : b.stageOf(id);
|
|
1111
1188
|
const k = id === null ? void 0 : b.groupOf(id);
|
|
1112
1189
|
setStage(s ?? null);
|
|
1113
1190
|
setGroup(k ?? null);
|
|
1114
1191
|
setEdge(id !== null && s === void 0 && k === void 0 && b.wireOf(id) !== void 0 ? id : null);
|
|
1115
|
-
g.onSelect?.(s ?? null);
|
|
1192
|
+
g.onSelect?.(s ?? null, ids.filter((i) => isPart(b, i)));
|
|
1116
1193
|
g.onSelectGroup?.(k ?? null);
|
|
1117
1194
|
}, [latest]);
|
|
1118
1195
|
const unpick = useCallback(() => setEdge(null), []);
|
|
@@ -1166,6 +1243,7 @@ function GroupTitleField({ initial, onDone }) {
|
|
|
1166
1243
|
onChange: (e) => setText(e.target.value),
|
|
1167
1244
|
onKeyDown: (e) => {
|
|
1168
1245
|
e.stopPropagation();
|
|
1246
|
+
if (imeKey(e.nativeEvent)) return;
|
|
1169
1247
|
if (e.key === "Enter") finish(text.trim());
|
|
1170
1248
|
else if (e.key === "Escape") finish(null);
|
|
1171
1249
|
},
|
|
@@ -1390,6 +1468,7 @@ function clearLabel(path, size, offset, keepOut) {
|
|
|
1390
1468
|
}
|
|
1391
1469
|
return void 0;
|
|
1392
1470
|
}
|
|
1471
|
+
var worldSpecs = (data, options) => diagramScene(data, { ...options, composition: IDENTITY_POSE_COMPOSITION });
|
|
1393
1472
|
var inkOf = (id, specs) => specs.filter((s) => s.id === id || s.parent === id || String(s.id).startsWith(`${id}/mark:`)).map((s) => s.pose);
|
|
1394
1473
|
function walledIn(grid, walls) {
|
|
1395
1474
|
if (walls.length === 0) return grid;
|
|
@@ -1404,7 +1483,7 @@ function walledIn(grid, walls) {
|
|
|
1404
1483
|
};
|
|
1405
1484
|
}
|
|
1406
1485
|
function routeWires(wires, nodes, laid) {
|
|
1407
|
-
const specs =
|
|
1486
|
+
const specs = worldSpecs({ nodes, edges: wires.map((w) => w.edge), ...laid.groups !== void 0 ? { groups: laid.groups } : {} }, {
|
|
1408
1487
|
layout: "none",
|
|
1409
1488
|
router: laid.router,
|
|
1410
1489
|
...laid.measure !== void 0 ? { measure: laid.measure } : {}
|
|
@@ -1412,9 +1491,9 @@ function routeWires(wires, nodes, laid) {
|
|
|
1412
1491
|
const spec = new Map(specs.map((s) => [s.id, s]));
|
|
1413
1492
|
const ink = new Map(nodes.map((n) => [n.id, inkOf(n.id, specs)]));
|
|
1414
1493
|
const grid = { ...laid.grid, ink: laid.grid.columns.map((_, c) => [...ink].flatMap(([id, b]) => laid.column.get(id) === c ? b : [])) };
|
|
1415
|
-
const end = (stage,
|
|
1494
|
+
const end = (stage, port2) => {
|
|
1416
1495
|
const s = spec.get(stage);
|
|
1417
|
-
const [site, ...sites] = portSitesOf({ id: stage, data: s.data }, s.pose,
|
|
1496
|
+
const [site, ...sites] = portSitesOf({ id: stage, data: s.data }, s.pose, port2);
|
|
1418
1497
|
return { column: laid.column.get(stage), point: site?.point ?? { x: 0, y: 0 }, normal: site?.normal ?? null, sites };
|
|
1419
1498
|
};
|
|
1420
1499
|
const walls = nestGroups(laid.groups ?? [], (id) => ink.has(id)).flatMap((g) => {
|
|
@@ -1438,7 +1517,7 @@ function routeWires(wires, nodes, laid) {
|
|
|
1438
1517
|
return { waypoints, path: routeOf(spec.get(edge.from), edge.fromPort, spec.get(edge.to), edge.toPort, laid.router, waypoints) };
|
|
1439
1518
|
});
|
|
1440
1519
|
const segments = routes.map(({ path }) => {
|
|
1441
|
-
const c = path?.kind === "polygon" ? path
|
|
1520
|
+
const c = path?.kind === "polygon" ? worldCoords(path) : [];
|
|
1442
1521
|
return Array.from({ length: Math.max(0, c.length / 2 - 1) }, (_, i) => {
|
|
1443
1522
|
const [x0, y0, x1, y1] = [c[2 * i], c[2 * i + 1], c[2 * i + 2], c[2 * i + 3]];
|
|
1444
1523
|
return { x: Math.min(x0, x1) - 1, y: Math.min(y0, y1) - 1, width: Math.abs(x1 - x0) + 2, height: Math.abs(y1 - y0) + 2 };
|
|
@@ -1482,11 +1561,11 @@ function laneHeights(count, least, needs, insets) {
|
|
|
1482
1561
|
}
|
|
1483
1562
|
function lanePorts(stage, box, lane, band) {
|
|
1484
1563
|
const side = (ports, u) => ports.map((p) => {
|
|
1485
|
-
const
|
|
1564
|
+
const same2 = ports.filter((q) => q.type === p.type);
|
|
1486
1565
|
const [top, bottom] = band(lane.get(p.type));
|
|
1487
1566
|
const a = Math.max(top, box.y);
|
|
1488
1567
|
const b = Math.min(bottom, box.y + box.height);
|
|
1489
|
-
const y = a + (b - a) * (
|
|
1568
|
+
const y = a + (b - a) * (same2.indexOf(p) + 1) / (same2.length + 1);
|
|
1490
1569
|
return { id: p.id, type: p.type, at: { u, v: (y - box.y) / box.height }, normal: { x: u === 0 ? -1 : 1, y: 0 } };
|
|
1491
1570
|
});
|
|
1492
1571
|
return [...side(stage.inputs ?? [], 0), ...side(stage.outputs ?? [], 1)];
|
|
@@ -1499,7 +1578,7 @@ function controlSideOf(stage, pipeline, lane) {
|
|
|
1499
1578
|
return control.length > 0 && signal.length > 0 && mean(control) > mean(signal) ? "bottom" : "top";
|
|
1500
1579
|
}
|
|
1501
1580
|
function sizesOf(nodes, groups, measure) {
|
|
1502
|
-
const specs =
|
|
1581
|
+
const specs = worldSpecs({ nodes, edges: [], groups }, { layout: "none", ...measure !== void 0 ? { measure } : {} });
|
|
1503
1582
|
const pose = new Map(specs.map((s) => [s.id, s.pose]));
|
|
1504
1583
|
const spec = new Map(specs.map((s) => [s.id, s]));
|
|
1505
1584
|
const nested = nestGroups(groups, (id) => nodes.some((n) => n.id === id)).map((g) => ({ members: g.members, inset: insetOf(diagramNodeOf({ id: g.id, kind: "mark", data: spec.get(g.id)?.data })?.group?.inset) }));
|
|
@@ -1645,10 +1724,27 @@ var lanes = (pipeline, options = {}) => {
|
|
|
1645
1724
|
// src/effect/rack.ts
|
|
1646
1725
|
var SKIP_OUT = "~skip-out";
|
|
1647
1726
|
var SKIP_IN = "~skip-in";
|
|
1727
|
+
var TAP = "~tap:";
|
|
1728
|
+
var untapped = (port2) => port2.startsWith(TAP) ? port2.slice(TAP.length) : port2;
|
|
1648
1729
|
var SIDE_PORT_GAP = 24;
|
|
1649
|
-
var
|
|
1650
|
-
|
|
1651
|
-
|
|
1730
|
+
var ROW = {
|
|
1731
|
+
anchor: (along2, across) => ({ u: along2, v: across }),
|
|
1732
|
+
along: (at) => at.u,
|
|
1733
|
+
across: (at) => at.v,
|
|
1734
|
+
normal: (across) => ({ x: 0, y: across * 2 - 1 })
|
|
1735
|
+
};
|
|
1736
|
+
var COLUMN = {
|
|
1737
|
+
anchor: (along2, across) => ({ u: across, v: along2 }),
|
|
1738
|
+
along: (at) => at.v,
|
|
1739
|
+
across: (at) => at.u,
|
|
1740
|
+
normal: (across) => ({ x: across * 2 - 1, y: 0 })
|
|
1741
|
+
};
|
|
1742
|
+
var spreadAt = (frame, ports, across) => ports.map((p, i) => ({ id: p.id, type: p.type, at: frame.anchor((i + 1) / (ports.length + 1), across), normal: frame.normal(across) }));
|
|
1743
|
+
function roomFor(frame, ports) {
|
|
1744
|
+
const count = (across) => ports.filter((p) => {
|
|
1745
|
+
const along2 = frame.along(p.at);
|
|
1746
|
+
return frame.across(p.at) === across && along2 > 0 && along2 < 1;
|
|
1747
|
+
}).length;
|
|
1652
1748
|
return (Math.max(count(0), count(1)) + 1) * SIDE_PORT_GAP;
|
|
1653
1749
|
}
|
|
1654
1750
|
function rackWires(pipeline, skips) {
|
|
@@ -1684,26 +1780,37 @@ function rackWires(pipeline, skips) {
|
|
|
1684
1780
|
}
|
|
1685
1781
|
return wires;
|
|
1686
1782
|
}
|
|
1783
|
+
function tapped(wires, line, boxed) {
|
|
1784
|
+
return wires.map((w) => {
|
|
1785
|
+
const from = line.at.get(w.from.stage);
|
|
1786
|
+
const to = line.at.get(w.to.stage);
|
|
1787
|
+
const across = from !== void 0 && to !== void 0 && to - from > 1 && !w.arc && boxed(w.from.stage) && w.from.port === line.mainOut.get(w.from.stage) && w.to.port !== line.mainIn.get(w.to.stage);
|
|
1788
|
+
return across ? { ...w, from: { stage: w.from.stage, port: TAP + w.from.port }, exit: w.exit ?? w.from } : w;
|
|
1789
|
+
});
|
|
1790
|
+
}
|
|
1687
1791
|
function lineOf(pipeline, ordered, chain) {
|
|
1688
1792
|
const { mainIn, mainOut } = chainLinks(pipeline, ordered);
|
|
1689
1793
|
return { at: new Map(chain.map((id, i) => [id, i])), mainIn, mainOut };
|
|
1690
1794
|
}
|
|
1691
|
-
function portsOf2(stage, line, wires, near2, far) {
|
|
1692
|
-
if (!line.at.has(stage.id)) return [...spreadAt(stage.outputs ?? [], far), ...spreadAt(stage.inputs ?? [], near2)];
|
|
1693
|
-
const typed = (p,
|
|
1795
|
+
function portsOf2(stage, line, wires, frame, near2, far) {
|
|
1796
|
+
if (!line.at.has(stage.id)) return [...spreadAt(frame, stage.outputs ?? [], far), ...spreadAt(frame, stage.inputs ?? [], near2)];
|
|
1797
|
+
const typed = (p, anchor2) => ({ id: p.id, type: p.type, at: anchor2 });
|
|
1694
1798
|
const out = [];
|
|
1695
1799
|
const side = [];
|
|
1696
1800
|
for (const p of stage.inputs ?? []) {
|
|
1697
|
-
if (p.id === line.mainIn.get(stage.id)) out.push(typed(p,
|
|
1801
|
+
if (p.id === line.mainIn.get(stage.id)) out.push(typed(p, frame.anchor(0, 0.5)));
|
|
1698
1802
|
else side.push(p);
|
|
1699
1803
|
}
|
|
1700
1804
|
for (const p of stage.outputs ?? []) {
|
|
1701
|
-
if (p.id === line.mainOut.get(stage.id)) out.push(typed(p,
|
|
1805
|
+
if (p.id === line.mainOut.get(stage.id)) out.push(typed(p, frame.anchor(1, 0.5)));
|
|
1702
1806
|
else side.push(p);
|
|
1703
1807
|
}
|
|
1704
|
-
|
|
1808
|
+
const main = portOn(stage, line.mainOut.get(stage.id) ?? "");
|
|
1809
|
+
const taps = new Set(wires.flatMap((w) => w.from.stage === stage.id && w.from.port.startsWith(TAP) ? [w.from.port] : []));
|
|
1810
|
+
if (main !== void 0) for (const id of taps) side.push({ ...main, id });
|
|
1811
|
+
out.push(...spreadAt(frame, side, near2));
|
|
1705
1812
|
const type = portOn(stage, line.mainOut.get(stage.id) ?? line.mainIn.get(stage.id) ?? "")?.type;
|
|
1706
|
-
const arc = (id,
|
|
1813
|
+
const arc = (id, along2) => ({ id, at: frame.anchor(along2, far), ...type !== void 0 ? { type } : {} });
|
|
1707
1814
|
if (wires.some((w) => w.arc && w.from.stage === stage.id)) out.push(arc(SKIP_OUT, 0.75));
|
|
1708
1815
|
if (wires.some((w) => w.arc && w.to.stage === stage.id)) out.push(arc(SKIP_IN, 0.25));
|
|
1709
1816
|
return out;
|
|
@@ -1711,6 +1818,8 @@ function portsOf2(stage, line, wires, near2, far) {
|
|
|
1711
1818
|
var rack = (pipeline, options = {}) => {
|
|
1712
1819
|
const theme = options.theme ?? LOOK_THEME;
|
|
1713
1820
|
const color = typeColors(pipeline, options.colors, theme.series);
|
|
1821
|
+
const down = options.direction === "down";
|
|
1822
|
+
const frame = down ? COLUMN : ROW;
|
|
1714
1823
|
const below = options.side !== "above";
|
|
1715
1824
|
const near2 = below ? 1 : 0;
|
|
1716
1825
|
const far = below ? 0 : 1;
|
|
@@ -1720,16 +1829,18 @@ var rack = (pipeline, options = {}) => {
|
|
|
1720
1829
|
const skips = options.collapseSkips === false ? [] : skipDecisions(pipeline, ordered);
|
|
1721
1830
|
const gone = new Set(skips.map((s) => s.decision.id));
|
|
1722
1831
|
const chain = ordered.filter((id) => !gone.has(id));
|
|
1723
|
-
const wires = rackWires(pipeline, skips);
|
|
1724
1832
|
const line = lineOf(pipeline, ordered, chain);
|
|
1833
|
+
const decisions = new Set(stages.filter((st) => kindOf(st) === "decision").map((st) => st.id));
|
|
1834
|
+
const wires = tapped(rackWires(pipeline, skips), line, (id) => !decisions.has(id));
|
|
1725
1835
|
const kept = stages.filter((s) => !gone.has(s.id));
|
|
1726
|
-
const
|
|
1836
|
+
const flow = { direction: down ? "down" : "right", controlSide: down ? below ? "right" : "left" : below ? "bottom" : "top" };
|
|
1727
1837
|
const nodes = kept.map((stage) => {
|
|
1728
|
-
if (kindOf(stage) === "decision") return { id: stage.id, ...branchNode(stage, pipeline, options.branch, {
|
|
1729
|
-
const ports = portsOf2(stage, line, wires, near2, far);
|
|
1838
|
+
if (kindOf(stage) === "decision") return { id: stage.id, ...branchNode(stage, pipeline, options.branch, { ...flow, style: stageStyle(stage, theme) }) };
|
|
1839
|
+
const ports = portsOf2(stage, line, wires, frame, near2, far);
|
|
1730
1840
|
const node = boxNode(stage, { showParams: options.showParams !== false, rowPorts: false, ports, run: options });
|
|
1731
|
-
const room = roomFor(ports);
|
|
1732
|
-
|
|
1841
|
+
const room = roomFor(frame, ports);
|
|
1842
|
+
if (room <= 2 * SIDE_PORT_GAP) return node;
|
|
1843
|
+
return down ? { ...node, height: Math.max(node.height ?? 0, room) } : { ...node, width: room };
|
|
1733
1844
|
});
|
|
1734
1845
|
const byId = new Map(kept.map((s) => [s.id, s]));
|
|
1735
1846
|
const edges = wires.map((wire) => {
|
|
@@ -1750,7 +1861,7 @@ var rack = (pipeline, options = {}) => {
|
|
|
1750
1861
|
scene: {
|
|
1751
1862
|
layout: "chain",
|
|
1752
1863
|
layoutOptions: {
|
|
1753
|
-
direction: "right",
|
|
1864
|
+
direction: down ? "down" : "right",
|
|
1754
1865
|
chain,
|
|
1755
1866
|
chainSide: below ? "after" : "before",
|
|
1756
1867
|
...options.nodeGap !== void 0 ? { nodeGap: options.nodeGap } : {},
|
|
@@ -1760,14 +1871,14 @@ var rack = (pipeline, options = {}) => {
|
|
|
1760
1871
|
...sceneStyles(kept, edges, theme)
|
|
1761
1872
|
},
|
|
1762
1873
|
color,
|
|
1763
|
-
order: { axis: "x", items: chain.map((id) => ({ id })) },
|
|
1874
|
+
order: { axis: down ? "y" : "x", items: chain.map((id) => ({ id })) },
|
|
1764
1875
|
exits: new Map(wires.flatMap((wire, i) => wire.exit === void 0 ? [] : [[edgeIdOf(edges[i].edge), wire.exit]]))
|
|
1765
1876
|
};
|
|
1766
1877
|
};
|
|
1767
1878
|
|
|
1768
1879
|
// src/effect/editorMapping.ts
|
|
1769
1880
|
var endsKey = (from, to) => JSON.stringify([from.stage, from.port, to.stage, to.port]);
|
|
1770
|
-
var edgeEnds = (e) => endsKey({ stage: e.from, port: e.fromPort ?? "" }, { stage: e.to, port: e.toPort ?? "" });
|
|
1881
|
+
var edgeEnds = (e) => endsKey({ stage: e.from, port: untapped(e.fromPort ?? "") }, { stage: e.to, port: e.toPort ?? "" });
|
|
1771
1882
|
function editorScene(doc, look = "nodeGraph", options) {
|
|
1772
1883
|
const drawn = drawLook(doc, look, options);
|
|
1773
1884
|
const stages = new Set(doc.pipeline.stages.map((s) => s.id));
|
|
@@ -1783,10 +1894,16 @@ function editorScene(doc, look = "nodeGraph", options) {
|
|
|
1783
1894
|
return id === void 0 ? [] : [[edgeIdOf(e), id]];
|
|
1784
1895
|
}));
|
|
1785
1896
|
const routes = look === "nodeGraph" ? doc.routes : void 0;
|
|
1786
|
-
const
|
|
1897
|
+
const { labels } = doc;
|
|
1898
|
+
const edges = routes === void 0 && labels === void 0 ? drawn.data.edges : drawn.data.edges.map((e) => {
|
|
1787
1899
|
const id = wires.get(edgeIdOf(e));
|
|
1788
|
-
const route = id === void 0 ? void 0 : routes[id];
|
|
1789
|
-
|
|
1900
|
+
const route = id === void 0 ? void 0 : routes?.[id];
|
|
1901
|
+
const label = id === void 0 ? void 0 : labels?.[id];
|
|
1902
|
+
return {
|
|
1903
|
+
...e,
|
|
1904
|
+
...route !== void 0 ? { waypoints: route } : {},
|
|
1905
|
+
...label !== void 0 ? { labelPlacement: label } : {}
|
|
1906
|
+
};
|
|
1790
1907
|
});
|
|
1791
1908
|
return {
|
|
1792
1909
|
...drawn,
|
|
@@ -1948,9 +2065,7 @@ function groupMove(doc, order, units, move) {
|
|
|
1948
2065
|
}
|
|
1949
2066
|
function laneMove(doc, order, move) {
|
|
1950
2067
|
const types = order.items.flatMap((i) => laneTypeOf(i.id) ?? []);
|
|
1951
|
-
|
|
1952
|
-
moved.splice(move.to > move.from ? move.to - 1 : move.to, 0, types[move.from]);
|
|
1953
|
-
return setLaneOrder(doc, moved);
|
|
2068
|
+
return setLaneOrder(doc, moveItems(types, [move.from], move.to));
|
|
1954
2069
|
}
|
|
1955
2070
|
function unitsBefore(move) {
|
|
1956
2071
|
const units = move.order.filter((id) => id !== move.id);
|
|
@@ -2017,7 +2132,8 @@ function renameGroupContribution(now, rename) {
|
|
|
2017
2132
|
invoker: {
|
|
2018
2133
|
timing: "immediate",
|
|
2019
2134
|
run(_, params) {
|
|
2020
|
-
const
|
|
2135
|
+
const world = params?.world;
|
|
2136
|
+
const group = world ? under(world) : void 0;
|
|
2021
2137
|
if (group !== void 0) rename(group);
|
|
2022
2138
|
}
|
|
2023
2139
|
}
|
|
@@ -2049,7 +2165,7 @@ function freeSpot(boxes, size, view) {
|
|
|
2049
2165
|
const last = boxes.reduce((a, b) => b.x + b.width > a.x + a.width ? b : a);
|
|
2050
2166
|
return { x: last.x + last.width + PLACE_GAP, y: last.y };
|
|
2051
2167
|
}
|
|
2052
|
-
var EffectEditor = forwardRef(function EffectEditor2({ doc, onChange, run, selected, onSelect, selectedGroup, onSelectGroup, look = "nodeGraph", options, width, height, background, className }, ref) {
|
|
2168
|
+
var EffectEditor = forwardRef(function EffectEditor2({ doc, onChange, run, selected, onSelect, selectedGroup, onSelectGroup, look = "nodeGraph", options, width, height, maxScale, bounded, refit, background, className }, ref) {
|
|
2053
2169
|
const built = useMemo(() => editorScene(doc, look, options), [doc, look, options]);
|
|
2054
2170
|
const specs = useMemo(() => applyLookRoutes(diagramScene(built.data, built.scene), doc, look, built).map((s) => s.pickable === false || isPart(built, s.id) ? s : { ...s, pickable: false }), [built, doc, look]);
|
|
2055
2171
|
const painted = useMemo(() => paintRun(doc.pipeline, specs, run, built.exits), [doc.pipeline, specs, run, built]);
|
|
@@ -2113,6 +2229,9 @@ var EffectEditor = forwardRef(function EffectEditor2({ doc, onChange, run, selec
|
|
|
2113
2229
|
width,
|
|
2114
2230
|
height,
|
|
2115
2231
|
minScale: EFFECT_MIN_SCALE,
|
|
2232
|
+
...maxScale !== void 0 ? { maxScale } : {},
|
|
2233
|
+
...bounded !== void 0 ? { bounded } : {},
|
|
2234
|
+
...refit !== void 0 ? { refit } : {},
|
|
2116
2235
|
anchor: "start",
|
|
2117
2236
|
ports: "connect",
|
|
2118
2237
|
portOptions,
|
|
@@ -2120,9 +2239,11 @@ var EffectEditor = forwardRef(function EffectEditor2({ doc, onChange, run, selec
|
|
|
2120
2239
|
onConnect: handlers.onConnect,
|
|
2121
2240
|
onReconnect: handlers.onReconnect,
|
|
2122
2241
|
onEditRoute: handlers.onEditRoute,
|
|
2242
|
+
onMoveLabel: handlers.onMoveLabel,
|
|
2123
2243
|
onDelete: handlers.onDelete,
|
|
2124
2244
|
...look === "nodeGraph" ? { onMove: handlers.onMove } : { ambient },
|
|
2125
2245
|
...look === "nodeGraph" ? { onEditContainer: handlers.onEditContainer } : {},
|
|
2246
|
+
selectionMode: "multiple",
|
|
2126
2247
|
onSelect: picks.pick,
|
|
2127
2248
|
...picks.shown !== void 0 ? { selected: picks.shown } : {},
|
|
2128
2249
|
...pages !== void 0 ? { pages } : {},
|
|
@@ -2145,9 +2266,9 @@ function draw(width, height, paint) {
|
|
|
2145
2266
|
paint(canvas.getContext("2d"));
|
|
2146
2267
|
return canvas.transferToImageBitmap();
|
|
2147
2268
|
}
|
|
2148
|
-
function need(ctx,
|
|
2149
|
-
const value = ctx.inputs[
|
|
2150
|
-
if (value === void 0) throw new Error(`${
|
|
2269
|
+
function need(ctx, port2) {
|
|
2270
|
+
const value = ctx.inputs[port2];
|
|
2271
|
+
if (value === void 0) throw new Error(`${port2} is not connected`);
|
|
2151
2272
|
return value;
|
|
2152
2273
|
}
|
|
2153
2274
|
function decide(ctx, value) {
|
|
@@ -2324,14 +2445,14 @@ function createPass(pipeline, opts) {
|
|
|
2324
2445
|
const values = {};
|
|
2325
2446
|
const previews = {};
|
|
2326
2447
|
const seen = { ...inputs2, ...outputs };
|
|
2327
|
-
for (const
|
|
2328
|
-
const value = seen[
|
|
2448
|
+
for (const port2 of shownPorts(stage)) {
|
|
2449
|
+
const value = seen[port2.id];
|
|
2329
2450
|
if (value === void 0) continue;
|
|
2330
|
-
const kind = opts.kinds?.[
|
|
2451
|
+
const kind = opts.kinds?.[port2.type];
|
|
2331
2452
|
const text = kind?.show !== void 0 ? kind.show(value) : plainText(value);
|
|
2332
|
-
if (text !== void 0) values[
|
|
2453
|
+
if (text !== void 0) values[port2.id] = text;
|
|
2333
2454
|
const preview = opts.previews === false ? void 0 : await kind?.preview?.(value, size);
|
|
2334
|
-
if (preview !== void 0) previews[
|
|
2455
|
+
if (preview !== void 0) previews[port2.id] = preview;
|
|
2335
2456
|
}
|
|
2336
2457
|
const full = {
|
|
2337
2458
|
...entry,
|
|
@@ -2376,11 +2497,11 @@ function createPass(pipeline, opts) {
|
|
|
2376
2497
|
const given = new Set(Object.values(sources));
|
|
2377
2498
|
const done = /* @__PURE__ */ new Set();
|
|
2378
2499
|
for (const [id, outputs] of made) {
|
|
2379
|
-
for (const
|
|
2380
|
-
const value = outputs[
|
|
2500
|
+
for (const port2 of stages.get(id)?.outputs ?? []) {
|
|
2501
|
+
const value = outputs[port2.id];
|
|
2381
2502
|
if (value === void 0 || given.has(value) || done.has(value)) continue;
|
|
2382
2503
|
done.add(value);
|
|
2383
|
-
opts.kinds?.[
|
|
2504
|
+
opts.kinds?.[port2.type]?.dispose?.(value);
|
|
2384
2505
|
}
|
|
2385
2506
|
}
|
|
2386
2507
|
made.clear();
|
|
@@ -2389,9 +2510,9 @@ function createPass(pipeline, opts) {
|
|
|
2389
2510
|
}
|
|
2390
2511
|
function passThrough(stage, inputs2) {
|
|
2391
2512
|
const out = {};
|
|
2392
|
-
for (const
|
|
2393
|
-
const from = (stage.inputs ?? []).find((i) => i.type ===
|
|
2394
|
-
if (from !== void 0) out[
|
|
2513
|
+
for (const port2 of stage.outputs ?? []) {
|
|
2514
|
+
const from = (stage.inputs ?? []).find((i) => i.type === port2.type && inputs2[i.id] !== void 0);
|
|
2515
|
+
if (from !== void 0) out[port2.id] = inputs2[from.id];
|
|
2395
2516
|
}
|
|
2396
2517
|
return out;
|
|
2397
2518
|
}
|
|
@@ -2418,6 +2539,7 @@ function createEffectRunner(opts) {
|
|
|
2418
2539
|
let controller = new AbortController();
|
|
2419
2540
|
let tail = Promise.resolve();
|
|
2420
2541
|
let pending = 0;
|
|
2542
|
+
let behind = false;
|
|
2421
2543
|
let published = [];
|
|
2422
2544
|
const listeners = /* @__PURE__ */ new Set();
|
|
2423
2545
|
const set = (next) => {
|
|
@@ -2479,6 +2601,7 @@ function createEffectRunner(opts) {
|
|
|
2479
2601
|
controller.abort();
|
|
2480
2602
|
controller = new AbortController();
|
|
2481
2603
|
dropStepping();
|
|
2604
|
+
behind = false;
|
|
2482
2605
|
set({ run: void 0, playing: false, time: 0 });
|
|
2483
2606
|
},
|
|
2484
2607
|
advance(seconds) {
|
|
@@ -2486,6 +2609,17 @@ function createEffectRunner(opts) {
|
|
|
2486
2609
|
state = { ...state, time: state.time + seconds };
|
|
2487
2610
|
if (pending === 0) void enqueue(wholeRun(state.time));
|
|
2488
2611
|
},
|
|
2612
|
+
seek(seconds) {
|
|
2613
|
+
state = { ...state, time: seconds };
|
|
2614
|
+
if (pending === 0) void enqueue(wholeRun(seconds));
|
|
2615
|
+
else if (!behind) {
|
|
2616
|
+
behind = true;
|
|
2617
|
+
void enqueue((signal) => {
|
|
2618
|
+
behind = false;
|
|
2619
|
+
return wholeRun(state.time)(signal);
|
|
2620
|
+
});
|
|
2621
|
+
}
|
|
2622
|
+
},
|
|
2489
2623
|
setPipeline(next) {
|
|
2490
2624
|
if (next === pipeline) return;
|
|
2491
2625
|
pipeline = next;
|
|
@@ -2520,7 +2654,7 @@ function createEffectRunner(opts) {
|
|
|
2520
2654
|
};
|
|
2521
2655
|
}
|
|
2522
2656
|
function useEffectRunner(opts) {
|
|
2523
|
-
const { pipeline, sources, evaluators, kinds, previews, previewSize, target, requestFrame, cancelFrame } = opts;
|
|
2657
|
+
const { pipeline, sources, evaluators, kinds, previews, previewSize, target, requestFrame, cancelFrame, clock } = opts;
|
|
2524
2658
|
const [runner] = useState(() => createEffectRunner(opts));
|
|
2525
2659
|
useEffect(() => {
|
|
2526
2660
|
runner.setPipeline(pipeline);
|
|
@@ -2553,9 +2687,30 @@ function useEffectRunner(opts) {
|
|
|
2553
2687
|
});
|
|
2554
2688
|
useEffect(() => {
|
|
2555
2689
|
last.current = null;
|
|
2556
|
-
if (state.playing) loop.request();
|
|
2690
|
+
if (state.playing && clock === void 0) loop.request();
|
|
2557
2691
|
else loop.cancel();
|
|
2558
|
-
}, [state.playing, loop]);
|
|
2692
|
+
}, [state.playing, loop, clock]);
|
|
2693
|
+
useEffect(() => {
|
|
2694
|
+
if (clock === void 0) return;
|
|
2695
|
+
const c = clock.clock;
|
|
2696
|
+
const follow = () => {
|
|
2697
|
+
if (c.rate !== 0) runner.play();
|
|
2698
|
+
else runner.pause();
|
|
2699
|
+
};
|
|
2700
|
+
follow();
|
|
2701
|
+
if (runner.state.time !== c.elapsed / 1e3) runner.seek(c.elapsed / 1e3);
|
|
2702
|
+
const offClock = c.subscribe(follow);
|
|
2703
|
+
const offFrame = clock.onFrame((elapsed) => runner.seek(elapsed / 1e3));
|
|
2704
|
+
const offRunner = runner.subscribe(() => {
|
|
2705
|
+
const { playing } = runner.state;
|
|
2706
|
+
if (playing !== (c.rate !== 0)) c.rate = playing ? c.speed : 0;
|
|
2707
|
+
});
|
|
2708
|
+
return () => {
|
|
2709
|
+
offClock();
|
|
2710
|
+
offFrame();
|
|
2711
|
+
offRunner();
|
|
2712
|
+
};
|
|
2713
|
+
}, [runner, clock]);
|
|
2559
2714
|
useEffect(() => {
|
|
2560
2715
|
runner.drawn(state.run);
|
|
2561
2716
|
}, [runner, state.run]);
|
|
@@ -2563,6 +2718,6 @@ function useEffectRunner(opts) {
|
|
|
2563
2718
|
return { ...state, runner };
|
|
2564
2719
|
}
|
|
2565
2720
|
|
|
2566
|
-
export { AT_COLOR, BRANCH_SYMBOLS, COMPACT_PADDING, EFFECT_LOOKS, EFFECT_MIN_SCALE, EffectChart, EffectEditor, IMAGE_STAGE_TYPES, LANE_INSET, REORDER_LANES_ACTION_ID, addStage, addWire, applyLookRoutes, branchNode, canMoveInChain, canWire, chainLinks, compact, costText, createEffectRunner, createPass, editorScene, ensureWireIds, groupContents, groupStages, imageEvaluators, imageValueKinds, laneId, laneTypeOf, lanes, mainChain, moveGroup, moveInChain, moveStages, moveToGroup, nextGroupId, nextStageId, nextWireId, nodeGraph, paintRun, pruneLookRoutes, rack, reconnectWire, removeStages, removeWires, renameGroup, runPipeline, setGroupBox, setLaneOrder, setLookRoute, setParam, setWireRoute, symbolNameFor, testCard, ungroup, useEffectRunner, wireEnds };
|
|
2721
|
+
export { AT_COLOR, BRANCH_SYMBOLS, COMPACT_PADDING, EFFECT_LOOKS, EFFECT_MIN_SCALE, EffectChart, EffectEditor, IMAGE_STAGE_TYPES, LANE_INSET, REORDER_LANES_ACTION_ID, addStage, addWire, applyLookRoutes, branchNode, canMoveInChain, canWire, chainLinks, compact, costText, createEffectRunner, createPass, editorScene, ensureWireIds, groupContents, groupStages, imageEvaluators, imageValueKinds, laneId, laneTypeOf, lanes, mainChain, moveGroup, moveInChain, moveStages, moveToGroup, nextGroupId, nextStageId, nextWireId, nodeGraph, paintRun, pruneLookRoutes, rack, reconnectWire, removeStages, removeWires, renameGroup, runPipeline, setGroupBox, setLaneOrder, setLookRoute, setParam, setWireLabel, setWireRoute, symbolNameFor, testCard, ungroup, useEffectRunner, wireEnds };
|
|
2567
2722
|
//# sourceMappingURL=effect.js.map
|
|
2568
2723
|
//# sourceMappingURL=effect.js.map
|