@field/cascade 0.11.0 → 0.13.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/AGENTS.md +8 -5
- package/ARCHITECTURE.md +5 -4
- package/CHANGELOG.md +245 -0
- package/README.md +1 -1
- package/dist/assets/AgentPanel-1JugFjE4.css +1 -0
- package/dist/assets/AgentPanel-BDL5MddA.js +5 -0
- package/dist/assets/{CodeEditor-4O7FQ__R.js → CodeEditor-C-xYG-Wn.js} +120 -120
- package/dist/assets/CodePanel-CtXd50m6.js +2 -0
- package/dist/assets/CookInfoPanel-B3NMhKJF.css +1 -0
- package/dist/assets/CookInfoPanel-DG4_TRsX.js +2 -0
- package/dist/assets/CustomNodeDialog-CHfZUs-r.js +1 -0
- package/dist/assets/DefinitionNode-CaRTXQ_b.js +1 -0
- package/dist/assets/DefinitionPanel-C3CxZY9r.js +1 -0
- package/dist/assets/DefinitionPanel-VNLnAiQD.css +1 -0
- package/dist/assets/OpenGraphDialog-BLdr6k_q.js +1 -0
- package/dist/assets/ProjectSettings-ZnvmIAir.js +2 -0
- package/dist/assets/{SettingsDialog-Bz8JxISH.js → SettingsDialog-CBX3Wa87.js} +1 -1
- package/dist/assets/TimelinePanel-CDeR0arY.css +1 -0
- package/dist/assets/TimelinePanel-CWgnFH1e.js +1 -0
- package/dist/assets/{VersionHistoryDialog-D5Z0nJ5-.js → VersionHistoryDialog-BOSoW1R-.js} +1 -1
- package/dist/assets/assert-BO2_erPD.js +1 -0
- package/dist/assets/assert-hvykGCnP.js +1 -0
- package/dist/assets/builder-BmBKcDix.js +1 -0
- package/dist/assets/camera-DFF7YA3F.js +1 -0
- package/dist/assets/checks-DAvyO9Gf.js +1 -0
- package/dist/assets/contactSheet-N1NcaWxw.js +2 -0
- package/dist/assets/{core-Yqi0Ni61.js → core-DB-MkGjj.js} +3 -4
- package/dist/assets/coreTypes-DtnDATZ7.js +1 -0
- package/dist/assets/{cssMode-CxUzc4vp.js → cssMode-DPVckSOc.js} +1 -1
- package/dist/assets/definitions-B227e7f_.js +1 -0
- package/dist/assets/definitions-D0WOUJd7.js +1 -0
- package/dist/assets/{editor.api-BNFb25CX.js → editor.api-Dkutg_Z1.js} +1 -1
- package/dist/assets/expressions-X-Z-GrgW.js +5 -0
- package/dist/assets/file-DAL6IfjV.js +1 -0
- package/dist/assets/filters-D3k1LRMa.js +1 -0
- package/dist/assets/{freemarker2-0ZDnWxeM.js → freemarker2-CLiLKk3B.js} +1 -1
- package/dist/assets/generators-BhDxRAFC.js +1 -0
- package/dist/assets/geo-BsMImJIJ.js +1 -0
- package/dist/assets/geo-C4YngDob.js +2 -0
- package/dist/assets/{handlebars-Cy18MoaD.js → handlebars-CcD3aMeL.js} +1 -1
- package/dist/assets/{html-B-2Dx7nq.js → html-DvZWGfqb.js} +1 -1
- package/dist/assets/{htmlMode-DUAc9B_d.js → htmlMode-DUD3VaoN.js} +1 -1
- package/dist/assets/image-0SfH-snh.js +1 -0
- package/dist/assets/image-Ck-RdGU4.js +2 -0
- package/dist/assets/index-BWnrmIB9.js +137 -0
- package/dist/assets/index-DIaxEONI.css +1 -0
- package/dist/assets/io-BGmt2g0D.js +1 -0
- package/dist/assets/{javascript-DeQsDqP5.js → javascript-Cap2ahgh.js} +1 -1
- package/dist/assets/{jsonMode-BiFwJVSk.js → jsonMode-B0uLjp9C.js} +1 -1
- package/dist/assets/{liquid-BLoHH68a.js → liquid-CnxwhfLn.js} +1 -1
- package/dist/assets/{lspLanguageFeatures-CNFgm1Kv.js → lspLanguageFeatures-Dn9hlKX6.js} +1 -1
- package/dist/assets/math-GeULS-sk.js +1 -0
- package/dist/assets/{mdx-CFXQVNfs.js → mdx-BV3jbrVa.js} +1 -1
- package/dist/assets/pop-KMF_qloi.js +1 -0
- package/dist/assets/preload-helper-Czpn1I53.js +1 -0
- package/dist/assets/{python-Cf7S7p2E.js → python-CGyFk4XK.js} +1 -1
- package/dist/assets/{razor-CMHBcG-g.js → razor-CQfzX3-N.js} +1 -1
- package/dist/assets/remap-5SjXQU-q.js +1 -0
- package/dist/assets/renderMarkdown-ork0Oir7.js +67 -0
- package/dist/assets/studioImages-CAyH-0Pl.js +1 -0
- package/dist/assets/text-ZpX7qNkx.js +2 -0
- package/dist/assets/time-P_OiBhcf.js +1 -0
- package/dist/assets/{tsMode-BEih0GDj.js → tsMode-BOeXzO9H.js} +1 -1
- package/dist/assets/{typescript-COEKYD_a.js → typescript-J1SnE_Tu.js} +1 -1
- package/dist/assets/{workers-BNhAhMNn.js → workers-CYwwTiVF.js} +1 -1
- package/dist/assets/{xml-CPiMpnPl.js → xml-DnPRNzK9.js} +1 -1
- package/dist/assets/{yaml-Bgp1ITLR.js → yaml-BmmYBNa9.js} +1 -1
- package/dist/cli/DefinitionNode-P7AA4TAU.js +15 -0
- package/dist/cli/{Graph-ZJJTRQTM.js → Graph-OB6EWSGL.js} +12 -12
- package/dist/cli/assert-GROGQNCQ.js +25 -0
- package/dist/cli/checks-3WB44XBL.js +189 -0
- package/dist/cli/{chunk-3JTJHF7V.js → chunk-2L34ERS2.js} +4 -4
- package/dist/cli/chunk-53LGFPWX.js +138 -0
- package/dist/cli/chunk-5ORUQ6ES.js +267 -0
- package/dist/cli/{chunk-YAT5Y25U.js → chunk-7QE2ZNSN.js} +3 -3
- package/dist/cli/{chunk-SGJAET2L.js → chunk-BPODRH52.js} +8 -4
- package/dist/cli/{chunk-XWDSKG7N.js → chunk-BZ63XQ3I.js} +2 -2
- package/dist/cli/{chunk-FCDXJ6EK.js → chunk-CTPLRSWF.js} +2 -13
- package/dist/cli/{chunk-WIH4TEIS.js → chunk-EZRWJ4G2.js} +1 -1
- package/dist/cli/{chunk-BIJO5OFS.js → chunk-FWMSGKEH.js} +1 -1
- package/dist/cli/{chunk-POMMNKZZ.js → chunk-G23A2BZZ.js} +38 -5
- package/dist/cli/{chunk-35D343DC.js → chunk-GRIN2DDP.js} +19 -1
- package/dist/cli/{chunk-WKURDVYP.js → chunk-JEW5MPGI.js} +28 -331
- package/dist/cli/chunk-JVOCK5W4.js +83 -0
- package/dist/cli/chunk-KBGUO27Q.js +15 -0
- package/dist/cli/{chunk-GFS6W3C5.js → chunk-L6B6FUQP.js} +54 -32
- package/dist/cli/chunk-LTXWBXOM.js +438 -0
- package/dist/cli/chunk-MI5JLQYA.js +220 -0
- package/dist/cli/{chunk-A4OAMOZH.js → chunk-NJFMDXHR.js} +13 -3
- package/dist/cli/{chunk-DUIUFVU2.js → chunk-OBZAP3GG.js} +49 -23
- package/dist/cli/chunk-QAGATJGE.js +336 -0
- package/dist/cli/{chunk-EUIAC3U3.js → chunk-QKL7CCRS.js} +966 -132
- package/dist/cli/{chunk-RLCAJBVR.js → chunk-TJW67QSI.js} +8 -7
- package/dist/cli/{chunk-RQZ4SX5R.js → chunk-W5PJ5RMP.js} +156 -84
- package/dist/cli/chunk-W7OUAT7J.js +122 -0
- package/dist/cli/chunk-WGKPJZDY.js +364 -0
- package/dist/cli/{chunk-D6BUOHUG.js → chunk-X4WKAOQP.js} +4 -4
- package/dist/cli/{chunk-VVGSLVSF.js → chunk-X566FWBV.js} +6 -1
- package/dist/cli/chunk-YH637PDL.js +317 -0
- package/dist/cli/chunk-ZSCUZE6I.js +112 -0
- package/dist/cli/{cliCommands-UQSFGEHF.js → cliCommands-XVFRD7CF.js} +23 -17
- package/dist/cli/{commands-Q23M26QM.js → commands-M2XLTPTZ.js} +129 -47
- package/dist/cli/contactSheet-2PQVRUFW.js +11 -0
- package/dist/cli/{definitions-HF2FTHYU.js → definitions-BPOPW52L.js} +7 -7
- package/dist/cli/{doctorCommand-B7BPQMN6.js → doctorCommand-RAEI7GVY.js} +36 -6
- package/dist/cli/{edit-JHCPTQFT.js → edit-S5KEQ5RA.js} +3 -3
- package/dist/cli/editorCommands-5BBG4S6V.js +41 -0
- package/dist/cli/{encode-HAUZTYPT.js → encode-ICPEPMH5.js} +2 -2
- package/dist/cli/file-3HTQHPYQ.js +41 -0
- package/dist/cli/filters-6ODFWYK4.js +379 -0
- package/dist/cli/generators-YU7GB4MD.js +210 -0
- package/dist/cli/{geo-4RNK3QVN.js → geo-6ZPGKZRU.js} +7 -7
- package/dist/cli/{graphCommands-6BMAKGQE.js → graphCommands-MULQ7VD2.js} +4 -4
- package/dist/cli/{graphFile-VPSQ6OF7.js → graphFile-CITF36ZM.js} +25 -19
- package/dist/cli/{headlessCanvas-5XLDZT7M.js → headlessCanvas-ENRHC7GS.js} +3 -2
- package/dist/cli/{helpCommand-3VRE3KVO.js → helpCommand-X2QDANM3.js} +9 -7
- package/dist/cli/image-TXELZZK5.js +55 -0
- package/dist/cli/index.js +14 -14
- package/dist/cli/{math-ZRMLKU2D.js → math-RSYRQ3C6.js} +5 -5
- package/dist/cli/{mcp-ZLEEMYGF.js → mcp-YRIGRLYQ.js} +4 -4
- package/dist/cli/{parity-KINARCP2.js → parity-3N3HTKWX.js} +42 -36
- package/dist/cli/{pop-USDFXB7H.js → pop-B7SIIYKN.js} +5 -5
- package/dist/cli/project-SJF5ZF3F.js +12 -0
- package/dist/cli/{projectDefinition-DMTZN2NE.js → projectDefinition-F3D7UIHJ.js} +8 -8
- package/dist/cli/{projectRuntime-Z5PJOH47.js → projectRuntime-NY4XMDFH.js} +19 -12
- package/dist/cli/registerStandardNodes-BXJCB6E4.js +744 -0
- package/dist/cli/{render-YURAPPUI.js → render-Y23W6MY6.js} +29 -22
- package/dist/cli/{runCommand-PI764LEG.js → runCommand-XOG7AVC5.js} +3 -3
- package/dist/cli/runner-DNJO5WO2.js +43 -0
- package/dist/cli/runtime/image.ts +27 -2
- package/dist/cli/runtime/io.ts +78 -0
- package/dist/cli/share-B7HTCOJX.js +166 -0
- package/dist/cli/stageCache-TY2BFZJR.js +15 -0
- package/dist/cli/{stageRunner-KUNIMQKJ.js → stageRunner-KY2EJP7X.js} +2 -2
- package/dist/cli/text-MB3EKR4H.js +126 -0
- package/dist/cli/{verbs-RCE3K4VQ.js → verbs-PI2JH5FI.js} +2 -2
- package/dist/cli/webBuild-2K4COCGY.js +44 -0
- package/dist/contracts/capabilities.d.ts +39 -1
- package/dist/contracts/color.d.ts +8 -0
- package/dist/contracts/color.js +23 -0
- package/dist/contracts/definition.d.ts +10 -0
- package/dist/contracts/schema.d.ts +1 -1
- package/dist/contracts/schema.js +1 -0
- package/dist/contracts/validate.js +11 -1
- package/dist/contracts/values.d.ts +24 -0
- package/dist/image.d.ts +15 -0
- package/dist/image.js +36 -2
- package/dist/index.html +8 -2
- package/dist/io.d.ts +29 -0
- package/dist/io.js +40 -0
- package/dist/player/app.js +11 -7
- package/dist/player/editor.js +3 -2
- package/dist/player/editorEngine.js +3 -2
- package/dist/player/embed.js +2 -0
- package/dist/player/types.d.ts +6 -0
- package/dist/runtime/builtins/assert/checks.d.ts +18 -0
- package/dist/runtime/builtins/assert/checks.js +207 -0
- package/dist/runtime/builtins/assert/definitions.d.ts +130 -0
- package/dist/runtime/builtins/assert/definitions.js +54 -0
- package/dist/runtime/builtins/assert/index.d.ts +152 -0
- package/dist/runtime/builtins/assert/index.js +36 -0
- package/dist/runtime/builtins/image/contactSheet.d.ts +3 -165
- package/dist/runtime/builtins/image/contactSheet.js +0 -49
- package/dist/runtime/builtins/image/definitions.d.ts +950 -0
- package/dist/runtime/builtins/image/definitions.js +343 -0
- package/dist/runtime/builtins/image/file.d.ts +8 -0
- package/dist/runtime/builtins/image/file.js +37 -0
- package/dist/runtime/builtins/image/filters.d.ts +8 -0
- package/dist/runtime/builtins/image/filters.js +394 -0
- package/dist/runtime/builtins/image/generators.d.ts +7 -0
- package/dist/runtime/builtins/image/generators.js +144 -0
- package/dist/runtime/builtins/image/index.d.ts +947 -4
- package/dist/runtime/builtins/image/index.js +41 -6
- package/dist/runtime/builtins/image/io.d.ts +100 -0
- package/dist/runtime/builtins/image/io.js +142 -0
- package/dist/runtime/builtins/image/planar.d.ts +55 -0
- package/dist/runtime/builtins/image/planar.js +274 -0
- package/dist/runtime/builtins/image/simplex.d.ts +22 -0
- package/dist/runtime/builtins/image/simplex.js +92 -0
- package/dist/runtime/builtins/image/text.d.ts +4 -0
- package/dist/runtime/builtins/image/text.js +141 -0
- package/dist/runtime/builtins/index.d.ts +3 -0
- package/dist/runtime/builtins/index.js +7 -0
- package/dist/runtime/definition/architecture.js +89 -0
- package/dist/runtime/gpu.d.ts +25 -0
- package/dist/runtime/gpu.js +40 -0
- package/dist/runtime/runtime.d.ts +2 -0
- package/dist/runtime/runtime.js +268 -44
- package/dist/runtime/types.d.ts +30 -0
- package/doc/CLI_REFERENCE.md +21 -3
- package/doc/EDITOR_EXPORT.md +26 -0
- package/doc/MCP.md +2 -1
- package/doc/NODE_REFERENCE.md +286 -14
- package/doc/PROJECT_AUTHORING.md +158 -4
- package/doc/WEB_PLAYER.md +9 -1
- package/package.json +4 -1
- package/dist/assets/CodePanel-BU-autmq.js +0 -2
- package/dist/assets/CustomNodeDialog-BRpDfOV5.js +0 -1
- package/dist/assets/OpenGraphDialog-BwbRlC0X.js +0 -1
- package/dist/assets/ProjectSettings-DLOXLxcA.js +0 -2
- package/dist/assets/definitions-GreEMXLV.js +0 -1
- package/dist/assets/geo-u0n_jOsD.js +0 -1
- package/dist/assets/image-cAa-Nu9O.js +0 -2062
- package/dist/assets/index-5ZtDAuy2.js +0 -220
- package/dist/assets/index-7vae6YFC.css +0 -1
- package/dist/assets/math-DioIQOPJ.js +0 -1
- package/dist/assets/pop-DC_TQG9t.js +0 -1
- package/dist/cli/chunk-36P5K3SD.js +0 -631
- package/dist/cli/chunk-4UDFYF5G.js +0 -132
- package/dist/cli/chunk-53NMBJAO.js +0 -35
- package/dist/cli/chunk-MIIEFUGG.js +0 -623
- package/dist/cli/chunk-QBBKRNGY.js +0 -90
- package/dist/cli/chunk-WPUDGEFY.js +0 -20
- package/dist/cli/editorCommands-UIF5YLUZ.js +0 -33
- package/dist/cli/project-K3QIPGBB.js +0 -12
- package/dist/cli/registerStandardNodes-S2VLMF6J.js +0 -3081
- package/dist/cli/runner-RA6UKEPD.js +0 -37
- package/dist/cli/webBuild-GT4PZT5D.js +0 -37
- package/dist/runtime/builtins/headless.d.ts +0 -19
- package/dist/runtime/builtins/headless.js +0 -25
|
@@ -0,0 +1,744 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CORE_TYPES,
|
|
3
|
+
Node,
|
|
4
|
+
isCoreType,
|
|
5
|
+
registerNodeClasses
|
|
6
|
+
} from "./chunk-CTPLRSWF.js";
|
|
7
|
+
import "./chunk-RUU3YWXU.js";
|
|
8
|
+
import {
|
|
9
|
+
randomFromSeed,
|
|
10
|
+
remap
|
|
11
|
+
} from "./chunk-RXDIMXN5.js";
|
|
12
|
+
import "./chunk-HFHWYL55.js";
|
|
13
|
+
import "./chunk-CO22XHNG.js";
|
|
14
|
+
import "./chunk-FWMSGKEH.js";
|
|
15
|
+
|
|
16
|
+
// src/nodes/core/nodes/SwitchNode.ts
|
|
17
|
+
var SwitchNode = class extends Node {
|
|
18
|
+
constructor(id, graph) {
|
|
19
|
+
super(id, "Switch", graph);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Get the index of the currently active input
|
|
23
|
+
* Used by connection rendering to grey out inactive wires
|
|
24
|
+
*/
|
|
25
|
+
get activeInputIndex() {
|
|
26
|
+
const inputs = this.getVariadicInputs();
|
|
27
|
+
return Math.min(this.props.index?.value ?? 0, inputs.length - 1);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Check if a specific input port is active (for connection coloring)
|
|
31
|
+
*/
|
|
32
|
+
isInputActive(portId) {
|
|
33
|
+
const inputs = this.getVariadicInputs();
|
|
34
|
+
const activeIdx = this.activeInputIndex;
|
|
35
|
+
const portIndex = inputs.findIndex((p) => p.id === portId);
|
|
36
|
+
return portIndex === activeIdx;
|
|
37
|
+
}
|
|
38
|
+
setup() {
|
|
39
|
+
this.setVariadic();
|
|
40
|
+
this.output = this.out("output");
|
|
41
|
+
const index = this.param("index", 0, { type: "int", min: 0, max: 0, step: 1 });
|
|
42
|
+
index.documentField = "props";
|
|
43
|
+
this.watchProp("index", () => this.update());
|
|
44
|
+
this.onUpdate = () => this.update();
|
|
45
|
+
this.onReady = () => this.update();
|
|
46
|
+
}
|
|
47
|
+
onCook() {
|
|
48
|
+
this.update();
|
|
49
|
+
}
|
|
50
|
+
update() {
|
|
51
|
+
const inputs = this.getVariadicInputs();
|
|
52
|
+
const connectedCount = inputs.filter((p) => p.connections.length > 0).length;
|
|
53
|
+
this.updatePropParams("index", { max: Math.max(0, connectedCount - 1) });
|
|
54
|
+
const idx = Math.min(this.props.index.value, inputs.length - 1);
|
|
55
|
+
const selectedInput = inputs[idx];
|
|
56
|
+
if (selectedInput) {
|
|
57
|
+
this.output.setValue(selectedInput.value);
|
|
58
|
+
if (this.isPreviewValue(selectedInput.value)) {
|
|
59
|
+
this.preview = selectedInput.value;
|
|
60
|
+
} else {
|
|
61
|
+
this.preview = null;
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
this.output.setValue(null);
|
|
65
|
+
this.preview = null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// src/nodes/core/nodes/MergeNode.ts
|
|
71
|
+
var MergeNode = class extends Node {
|
|
72
|
+
constructor(id, graph) {
|
|
73
|
+
super(id, "Merge", graph);
|
|
74
|
+
}
|
|
75
|
+
setup() {
|
|
76
|
+
this.setVariadic();
|
|
77
|
+
this.output = this.out("output");
|
|
78
|
+
this.addParm("append", {
|
|
79
|
+
value: false,
|
|
80
|
+
type: "boolean",
|
|
81
|
+
displayName: "Append Mode",
|
|
82
|
+
hidden: () => {
|
|
83
|
+
const inputs = this.getVariadicInputs();
|
|
84
|
+
return !Array.isArray(inputs[0]?.value);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
this.watchProp("append", () => this.update());
|
|
88
|
+
this.onUpdate = () => this.update();
|
|
89
|
+
this.onReady = () => this.update();
|
|
90
|
+
}
|
|
91
|
+
update() {
|
|
92
|
+
const inputs = this.getVariadicInputs();
|
|
93
|
+
const values = inputs.filter((p) => p.value !== null).map((p) => p.value);
|
|
94
|
+
const appendMode = this.props.append.value;
|
|
95
|
+
if (appendMode && values.length > 0 && Array.isArray(values[0])) {
|
|
96
|
+
const result = [...values[0], ...values.slice(1)];
|
|
97
|
+
this.output.setValue(result);
|
|
98
|
+
} else {
|
|
99
|
+
this.output.setValue(values);
|
|
100
|
+
}
|
|
101
|
+
this.preview = null;
|
|
102
|
+
for (const val of values) {
|
|
103
|
+
if (val instanceof HTMLCanvasElement || val instanceof HTMLImageElement) {
|
|
104
|
+
this.preview = val;
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
// src/nodes/core/nodes/SubnetNode.ts
|
|
112
|
+
var SubnetNode = class extends Node {
|
|
113
|
+
constructor(id, graph) {
|
|
114
|
+
super(id, "Subnet", graph);
|
|
115
|
+
}
|
|
116
|
+
setup() {
|
|
117
|
+
this.onUpdate = () => this.update();
|
|
118
|
+
this.onReady = () => {
|
|
119
|
+
this.syncPorts();
|
|
120
|
+
this.update();
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Override: Subnets are networks and can contain children
|
|
125
|
+
*/
|
|
126
|
+
isNetwork() {
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Add a child node to this subnet
|
|
131
|
+
*/
|
|
132
|
+
addChild(node) {
|
|
133
|
+
node.parent = this;
|
|
134
|
+
this._children.push(node);
|
|
135
|
+
if (node.type === "Input" || node.type === "Output") {
|
|
136
|
+
this.syncPorts();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Remove a child node from this subnet
|
|
141
|
+
*/
|
|
142
|
+
removeChild(node) {
|
|
143
|
+
const index = this._children.indexOf(node);
|
|
144
|
+
if (index !== -1) {
|
|
145
|
+
const wasInputOutput = node.type === "Input" || node.type === "Output";
|
|
146
|
+
this._children.splice(index, 1);
|
|
147
|
+
node.parent = null;
|
|
148
|
+
if (wasInputOutput) {
|
|
149
|
+
this.syncPorts();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Sync input/output ports based on child Input/Output nodes
|
|
155
|
+
*/
|
|
156
|
+
syncPorts() {
|
|
157
|
+
const inputNodes = this._children.filter((n) => n.type === "Input");
|
|
158
|
+
const maxInputIndex = inputNodes.reduce((max, node) => {
|
|
159
|
+
const idx = node.inputIndex ?? 0;
|
|
160
|
+
return Math.max(max, idx);
|
|
161
|
+
}, -1);
|
|
162
|
+
const outputNodes = this._children.filter((n) => n.type === "Output");
|
|
163
|
+
const maxOutputIndex = outputNodes.reduce((max, node) => {
|
|
164
|
+
const idx = node.outputIndex ?? 0;
|
|
165
|
+
return Math.max(max, idx);
|
|
166
|
+
}, -1);
|
|
167
|
+
const requiredInputs = maxInputIndex + 1;
|
|
168
|
+
const currentInputs = this.inputs.length;
|
|
169
|
+
for (let i = currentInputs; i < requiredInputs; i++) {
|
|
170
|
+
const boundary = inputNodes.find((n) => n.inputIndex === i);
|
|
171
|
+
const port = this.in(boundary?.inputName || `input_${i}`, null, {
|
|
172
|
+
type: boundary?.dataType || "any"
|
|
173
|
+
});
|
|
174
|
+
port.onChange = (value) => {
|
|
175
|
+
this._children.filter((n) => n.type === "Input" && n.inputIndex === i).forEach((n) => n.markDirty());
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
for (let i = requiredInputs; i < currentInputs; i++) {
|
|
179
|
+
if (this.inputs[i]) {
|
|
180
|
+
this.inputs[i].options = { ...this.inputs[i].options, hidden: true };
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
for (let i = 0; i < requiredInputs; i++) {
|
|
184
|
+
if (this.inputs[i]) {
|
|
185
|
+
const boundary = inputNodes.find((n) => n.inputIndex === i);
|
|
186
|
+
this.inputs[i].name = boundary?.inputName || `input_${i}`;
|
|
187
|
+
this.inputs[i].dataType = boundary?.dataType || "any";
|
|
188
|
+
this.inputs[i].options = { ...this.inputs[i].options, hidden: false };
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
const requiredOutputs = maxOutputIndex + 1;
|
|
192
|
+
const currentOutputs = this.outputs.length;
|
|
193
|
+
for (let i = currentOutputs; i < requiredOutputs; i++) {
|
|
194
|
+
const boundary = outputNodes.find((n) => n.outputIndex === i);
|
|
195
|
+
this.out(boundary?.outputName || `output_${i}`, "param", {
|
|
196
|
+
type: boundary?.dataType || "any"
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
for (let i = requiredOutputs; i < currentOutputs; i++) {
|
|
200
|
+
if (this.outputs[i]) {
|
|
201
|
+
this.outputs[i].options = { ...this.outputs[i].options, hidden: true };
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
for (let i = 0; i < requiredOutputs; i++) {
|
|
205
|
+
if (this.outputs[i]) {
|
|
206
|
+
const boundary = outputNodes.find((n) => n.outputIndex === i);
|
|
207
|
+
this.outputs[i].name = boundary?.outputName || `output_${i}`;
|
|
208
|
+
this.outputs[i].dataType = boundary?.dataType || "any";
|
|
209
|
+
this.outputs[i].options = { ...this.outputs[i].options, hidden: false };
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
this.inputs = [...this.inputs];
|
|
213
|
+
this.outputs = [...this.outputs];
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Get the node that defines this subnet's output
|
|
217
|
+
* Priority: Output node > cooking node > last node
|
|
218
|
+
*/
|
|
219
|
+
outputNode() {
|
|
220
|
+
const outputNode = this._children.find((n) => n.type === "Output");
|
|
221
|
+
if (outputNode) return outputNode;
|
|
222
|
+
const cookingNode = this._children.find((n) => n.cook);
|
|
223
|
+
if (cookingNode) return cookingNode;
|
|
224
|
+
return this._children.length > 0 ? this._children[this._children.length - 1] : null;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Get the cooking (display) node in this subnet
|
|
228
|
+
*/
|
|
229
|
+
displayNode() {
|
|
230
|
+
return this._children.find((n) => n.cook) ?? null;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Get all Input nodes inside this subnet
|
|
234
|
+
*/
|
|
235
|
+
indirectInputs() {
|
|
236
|
+
return this._children.filter((n) => n.type === "Input");
|
|
237
|
+
}
|
|
238
|
+
update() {
|
|
239
|
+
const outputNodes = this._children.filter((n) => n.type === "Output");
|
|
240
|
+
const outputByIndex = /* @__PURE__ */ new Map();
|
|
241
|
+
for (const node of outputNodes) {
|
|
242
|
+
const idx = node.outputIndex ?? 0;
|
|
243
|
+
outputByIndex.set(idx, node);
|
|
244
|
+
}
|
|
245
|
+
for (let i = 0; i < this.outputs.length; i++) {
|
|
246
|
+
const outNode = outputByIndex.get(i);
|
|
247
|
+
if (outNode && outNode.inputs.length > 0) {
|
|
248
|
+
const value = outNode.inputs[0].value;
|
|
249
|
+
this.outputs[i].setValue(value);
|
|
250
|
+
if (i === 0 && (value instanceof HTMLCanvasElement || value instanceof HTMLImageElement)) {
|
|
251
|
+
this.preview = value;
|
|
252
|
+
}
|
|
253
|
+
} else if (i === 0) {
|
|
254
|
+
const cookingNode = this._children.find((n) => n.cook);
|
|
255
|
+
if (cookingNode && cookingNode.outputs.length > 0) {
|
|
256
|
+
this.outputs[i].setValue(cookingNode.outputs[0].value);
|
|
257
|
+
if (cookingNode.preview) {
|
|
258
|
+
this.preview = cookingNode.preview;
|
|
259
|
+
}
|
|
260
|
+
} else {
|
|
261
|
+
this.outputs[i].setValue(null);
|
|
262
|
+
}
|
|
263
|
+
} else {
|
|
264
|
+
this.outputs[i].setValue(null);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
if (this.outputs.length === 0 || !outputByIndex.has(0)) {
|
|
268
|
+
const cookingNode = this._children.find((n) => n.cook);
|
|
269
|
+
if (!cookingNode?.preview) {
|
|
270
|
+
this.preview = null;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
// src/nodes/core/nodes/InputNode.ts
|
|
277
|
+
var TYPE_CHOICES = CORE_TYPES.map((type) => ({ value: type, label: type }));
|
|
278
|
+
var InputNode = class extends Node {
|
|
279
|
+
constructor(id, graph) {
|
|
280
|
+
super(id, "Input", graph);
|
|
281
|
+
}
|
|
282
|
+
setup() {
|
|
283
|
+
this.output = this.out("output");
|
|
284
|
+
this.addParm("inputIndex", {
|
|
285
|
+
value: 0,
|
|
286
|
+
type: "int",
|
|
287
|
+
params: { min: 0, step: 1 },
|
|
288
|
+
displayName: "Input Index"
|
|
289
|
+
});
|
|
290
|
+
this.addParm("inputName", {
|
|
291
|
+
value: "",
|
|
292
|
+
type: "text",
|
|
293
|
+
displayName: "Input Name"
|
|
294
|
+
});
|
|
295
|
+
this.addParm("dataType", {
|
|
296
|
+
value: "any",
|
|
297
|
+
type: "select",
|
|
298
|
+
params: { options: TYPE_CHOICES },
|
|
299
|
+
displayName: "Data Type"
|
|
300
|
+
});
|
|
301
|
+
const syncParent = () => {
|
|
302
|
+
if (this.parent && this.parent.syncPorts) {
|
|
303
|
+
this.parent.syncPorts();
|
|
304
|
+
}
|
|
305
|
+
this.update();
|
|
306
|
+
};
|
|
307
|
+
this.watchProp("inputIndex", syncParent);
|
|
308
|
+
this.watchProp("inputName", syncParent);
|
|
309
|
+
this.watchProp("dataType", () => {
|
|
310
|
+
this.output.dataType = this.dataType;
|
|
311
|
+
syncParent();
|
|
312
|
+
});
|
|
313
|
+
this.onUpdate = () => this.update();
|
|
314
|
+
this.onReady = () => this.update();
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Get the input index this node represents
|
|
318
|
+
*/
|
|
319
|
+
get inputIndex() {
|
|
320
|
+
return this.props.inputIndex?.value ?? 0;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Get the input name (for documentation)
|
|
324
|
+
*/
|
|
325
|
+
get inputName() {
|
|
326
|
+
return this.props.inputName?.value ?? "";
|
|
327
|
+
}
|
|
328
|
+
get dataType() {
|
|
329
|
+
const value = this.props.dataType?.value;
|
|
330
|
+
return typeof value === "string" && isCoreType(value) ? value : "any";
|
|
331
|
+
}
|
|
332
|
+
update() {
|
|
333
|
+
if (this.parent && this.parent.inputs.length > 0) {
|
|
334
|
+
const idx = this.inputIndex;
|
|
335
|
+
const parentInput = this.parent.inputs[idx];
|
|
336
|
+
if (parentInput) {
|
|
337
|
+
this.output.setValue(parentInput.value);
|
|
338
|
+
if (this.isPreviewValue(parentInput.value)) {
|
|
339
|
+
this.preview = parentInput.value;
|
|
340
|
+
} else {
|
|
341
|
+
this.preview = null;
|
|
342
|
+
}
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
this.output.setValue(null);
|
|
347
|
+
this.preview = null;
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
// src/nodes/core/nodes/OutputNode.ts
|
|
352
|
+
var TYPE_CHOICES2 = CORE_TYPES.map((type) => ({ value: type, label: type }));
|
|
353
|
+
var OutputNode = class extends Node {
|
|
354
|
+
constructor(id, graph) {
|
|
355
|
+
super(id, "Output", graph);
|
|
356
|
+
}
|
|
357
|
+
setup() {
|
|
358
|
+
this.in("input", null);
|
|
359
|
+
this.addParm("outputIndex", {
|
|
360
|
+
value: 0,
|
|
361
|
+
type: "int",
|
|
362
|
+
params: { min: 0, step: 1 },
|
|
363
|
+
displayName: "Output Index"
|
|
364
|
+
});
|
|
365
|
+
this.addParm("outputName", {
|
|
366
|
+
value: "",
|
|
367
|
+
type: "text",
|
|
368
|
+
displayName: "Output Name"
|
|
369
|
+
});
|
|
370
|
+
this.addParm("dataType", {
|
|
371
|
+
value: "any",
|
|
372
|
+
type: "select",
|
|
373
|
+
params: { options: TYPE_CHOICES2 },
|
|
374
|
+
displayName: "Data Type"
|
|
375
|
+
});
|
|
376
|
+
const syncParent = () => {
|
|
377
|
+
if (this.parent && this.parent.syncPorts) {
|
|
378
|
+
this.parent.syncPorts();
|
|
379
|
+
}
|
|
380
|
+
this.update();
|
|
381
|
+
};
|
|
382
|
+
this.watchProp("outputIndex", syncParent);
|
|
383
|
+
this.watchProp("outputName", syncParent);
|
|
384
|
+
this.watchProp("dataType", () => {
|
|
385
|
+
if (this.inputs[0]) this.inputs[0].dataType = this.dataType;
|
|
386
|
+
syncParent();
|
|
387
|
+
});
|
|
388
|
+
this.onUpdate = () => this.update();
|
|
389
|
+
this.onReady = () => this.update();
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Get the output index this node represents
|
|
393
|
+
*/
|
|
394
|
+
get outputIndex() {
|
|
395
|
+
return this.props.outputIndex?.value ?? 0;
|
|
396
|
+
}
|
|
397
|
+
get outputName() {
|
|
398
|
+
return this.props.outputName?.value ?? "";
|
|
399
|
+
}
|
|
400
|
+
get dataType() {
|
|
401
|
+
const value = this.props.dataType?.value;
|
|
402
|
+
return typeof value === "string" && isCoreType(value) ? value : "any";
|
|
403
|
+
}
|
|
404
|
+
update() {
|
|
405
|
+
const input = this.inputs[0];
|
|
406
|
+
if (input) {
|
|
407
|
+
if (this.isPreviewValue(input.value)) {
|
|
408
|
+
this.preview = input.value;
|
|
409
|
+
} else {
|
|
410
|
+
this.preview = null;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
// src/nodes/core/nodes/RandomNode.ts
|
|
417
|
+
var RandomNode = class extends Node {
|
|
418
|
+
constructor(id, graph) {
|
|
419
|
+
super(id, "Random", graph);
|
|
420
|
+
}
|
|
421
|
+
setup() {
|
|
422
|
+
const seed = this.in("seed", 0, { type: "int" });
|
|
423
|
+
const sample = this.in("sample", 0, { type: "int" });
|
|
424
|
+
const value = this.out("value");
|
|
425
|
+
const update = () => value.setValue(randomFromSeed(seed.value, sample.value));
|
|
426
|
+
seed.onChange = update;
|
|
427
|
+
sample.onChange = update;
|
|
428
|
+
this.onUpdate = update;
|
|
429
|
+
this.onReady = update;
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
// src/nodes/core/nodes/RemapNode.ts
|
|
434
|
+
var RemapNode = class extends Node {
|
|
435
|
+
constructor(id, graph) {
|
|
436
|
+
super(id, "Remap", graph);
|
|
437
|
+
}
|
|
438
|
+
setup() {
|
|
439
|
+
const value = this.in("value", 0, { type: "float" });
|
|
440
|
+
const inMin = this.in("inMin", 0, { type: "float" });
|
|
441
|
+
const inMax = this.in("inMax", 1, { type: "float" });
|
|
442
|
+
const outMin = this.in("outMin", 0, { type: "float" });
|
|
443
|
+
const outMax = this.in("outMax", 1, { type: "float" });
|
|
444
|
+
const result = this.out("result");
|
|
445
|
+
this.addParm("clamp", { value: false, type: "boolean", displayName: "Clamp" });
|
|
446
|
+
const update = () => result.setValue(remap(
|
|
447
|
+
value.value,
|
|
448
|
+
inMin.value,
|
|
449
|
+
inMax.value,
|
|
450
|
+
outMin.value,
|
|
451
|
+
outMax.value,
|
|
452
|
+
this.props.clamp.value
|
|
453
|
+
));
|
|
454
|
+
for (const input of [value, inMin, inMax, outMin, outMax]) input.onChange = update;
|
|
455
|
+
this.watchProp("clamp", update);
|
|
456
|
+
this.onUpdate = update;
|
|
457
|
+
this.onReady = update;
|
|
458
|
+
}
|
|
459
|
+
};
|
|
460
|
+
|
|
461
|
+
// src/nodes/core/nodes/SelectNode.ts
|
|
462
|
+
var SelectNode = class extends Node {
|
|
463
|
+
constructor(id, graph) {
|
|
464
|
+
super(id, "Select", graph);
|
|
465
|
+
}
|
|
466
|
+
setup() {
|
|
467
|
+
this.arrayInput = this.in("array", [], { type: "array" });
|
|
468
|
+
this.itemOutput = this.out("item", "param");
|
|
469
|
+
this.countOutput = this.out("count", "param");
|
|
470
|
+
this.addParm("index", {
|
|
471
|
+
value: 0,
|
|
472
|
+
type: "int",
|
|
473
|
+
params: { min: 0, max: 0, step: 1 },
|
|
474
|
+
displayName: "Index"
|
|
475
|
+
});
|
|
476
|
+
this.addParm("wrap", {
|
|
477
|
+
value: true,
|
|
478
|
+
type: "boolean",
|
|
479
|
+
displayName: "Wrap Index"
|
|
480
|
+
});
|
|
481
|
+
this.watchProp("index", () => this.update());
|
|
482
|
+
this.watchProp("wrap", () => this.update());
|
|
483
|
+
this.onUpdate = () => this.update();
|
|
484
|
+
this.onReady = () => this.update();
|
|
485
|
+
}
|
|
486
|
+
update() {
|
|
487
|
+
const array = this.arrayInput.value;
|
|
488
|
+
if (!Array.isArray(array) || array.length === 0) {
|
|
489
|
+
this.itemOutput.setValue(null);
|
|
490
|
+
this.countOutput.setValue(0);
|
|
491
|
+
this.updatePropParams("index", { max: 0 });
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
this.updatePropParams("index", { max: array.length - 1 });
|
|
495
|
+
let index = this.props.index?.value ?? 0;
|
|
496
|
+
const wrap = this.props.wrap?.value ?? true;
|
|
497
|
+
if (wrap && array.length > 0) {
|
|
498
|
+
index = (index % array.length + array.length) % array.length;
|
|
499
|
+
} else {
|
|
500
|
+
index = Math.max(0, Math.min(index, array.length - 1));
|
|
501
|
+
}
|
|
502
|
+
const item = array[index];
|
|
503
|
+
this.itemOutput.setValue(item);
|
|
504
|
+
this.countOutput.setValue(array.length);
|
|
505
|
+
if (item instanceof HTMLCanvasElement || item instanceof HTMLImageElement) {
|
|
506
|
+
this.preview = item;
|
|
507
|
+
} else {
|
|
508
|
+
this.preview = null;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
};
|
|
512
|
+
|
|
513
|
+
// src/nodes/core/nodes/NullNode.ts
|
|
514
|
+
var NullNode = class extends Node {
|
|
515
|
+
constructor(id, graph) {
|
|
516
|
+
super(id, "Null", graph);
|
|
517
|
+
}
|
|
518
|
+
setup() {
|
|
519
|
+
const input = this.in("input", null, { type: "any" });
|
|
520
|
+
const output = this.out("output");
|
|
521
|
+
const update = () => output.setValue(input.value);
|
|
522
|
+
input.onChange = update;
|
|
523
|
+
this.onUpdate = update;
|
|
524
|
+
this.onReady = update;
|
|
525
|
+
}
|
|
526
|
+
};
|
|
527
|
+
|
|
528
|
+
// src/nodes/image/surface.ts
|
|
529
|
+
var globals = () => globalThis;
|
|
530
|
+
function hasPixels(value) {
|
|
531
|
+
if (typeof value !== "object" || value === null) return false;
|
|
532
|
+
const candidate = value;
|
|
533
|
+
if (typeof candidate.width !== "number" || typeof candidate.height !== "number") return false;
|
|
534
|
+
return typeof candidate.getContext === "function" || "src" in candidate || typeof candidate.close === "function";
|
|
535
|
+
}
|
|
536
|
+
var MissingRenderSurfaceError = class extends Error {
|
|
537
|
+
constructor(kind) {
|
|
538
|
+
super(
|
|
539
|
+
`Cascade has no ${kind} in this environment. Install the optional '@napi-rs/canvas' renderer before cooking a graph that draws.`
|
|
540
|
+
);
|
|
541
|
+
this.name = "MissingRenderSurfaceError";
|
|
542
|
+
}
|
|
543
|
+
};
|
|
544
|
+
function provider() {
|
|
545
|
+
const host = globals();
|
|
546
|
+
if (typeof host.document?.createElement === "function") return domProvider;
|
|
547
|
+
if (typeof host.OffscreenCanvas === "function") return offscreenProvider;
|
|
548
|
+
return null;
|
|
549
|
+
}
|
|
550
|
+
function createSurface(width, height) {
|
|
551
|
+
const current = provider();
|
|
552
|
+
if (!current) throw new MissingRenderSurfaceError("drawing surface");
|
|
553
|
+
return current.createSurface(width, height);
|
|
554
|
+
}
|
|
555
|
+
function bytesOf(source) {
|
|
556
|
+
return source instanceof Uint8Array ? source : new Uint8Array(source);
|
|
557
|
+
}
|
|
558
|
+
async function decodeViaBitmap(source) {
|
|
559
|
+
const host = globals();
|
|
560
|
+
if (typeof host.createImageBitmap !== "function" || typeof source === "string") return null;
|
|
561
|
+
const input = source instanceof Uint8Array || source instanceof ArrayBuffer ? typeof host.Blob === "function" ? new host.Blob([bytesOf(source)]) : bytesOf(source) : source;
|
|
562
|
+
return host.createImageBitmap(input);
|
|
563
|
+
}
|
|
564
|
+
async function decodeViaImage(source) {
|
|
565
|
+
const host = globals();
|
|
566
|
+
if (typeof host.Image !== "function") throw new MissingRenderSurfaceError("image decoder");
|
|
567
|
+
const image = new host.Image();
|
|
568
|
+
if (typeof source === "string") {
|
|
569
|
+
if (!/^(data:|blob:)/.test(source)) image.crossOrigin = "anonymous";
|
|
570
|
+
image.src = source;
|
|
571
|
+
} else if (source instanceof Uint8Array || source instanceof ArrayBuffer) {
|
|
572
|
+
image.src = bytesOf(source);
|
|
573
|
+
} else {
|
|
574
|
+
image.src = new Uint8Array(await source.arrayBuffer());
|
|
575
|
+
}
|
|
576
|
+
await image.decode();
|
|
577
|
+
if (!image.width || !image.height) throw new Error("cascade: could not decode image data");
|
|
578
|
+
return image;
|
|
579
|
+
}
|
|
580
|
+
async function decode(source) {
|
|
581
|
+
if (typeof source !== "string") {
|
|
582
|
+
const bitmap = await decodeViaBitmap(source);
|
|
583
|
+
if (bitmap) return bitmap;
|
|
584
|
+
}
|
|
585
|
+
return decodeViaImage(source);
|
|
586
|
+
}
|
|
587
|
+
var domProvider = {
|
|
588
|
+
name: "DOM canvas",
|
|
589
|
+
createSurface(width, height) {
|
|
590
|
+
const surface = globals().document.createElement("canvas");
|
|
591
|
+
surface.width = width;
|
|
592
|
+
surface.height = height;
|
|
593
|
+
return surface;
|
|
594
|
+
},
|
|
595
|
+
decodeImage: decode
|
|
596
|
+
};
|
|
597
|
+
var offscreenProvider = {
|
|
598
|
+
name: "OffscreenCanvas",
|
|
599
|
+
createSurface(width, height) {
|
|
600
|
+
const Offscreen = globals().OffscreenCanvas;
|
|
601
|
+
return new Offscreen(width, height);
|
|
602
|
+
},
|
|
603
|
+
decodeImage: decode
|
|
604
|
+
};
|
|
605
|
+
|
|
606
|
+
// src/nodes/core/nodes/FreezeNode.ts
|
|
607
|
+
function previewWanted() {
|
|
608
|
+
return typeof document !== "undefined";
|
|
609
|
+
}
|
|
610
|
+
var FreezeNode = class extends Node {
|
|
611
|
+
constructor(id, graph) {
|
|
612
|
+
super(id, "Freeze", graph);
|
|
613
|
+
this.frozenValue = null;
|
|
614
|
+
this.hasCaptured = false;
|
|
615
|
+
}
|
|
616
|
+
setup() {
|
|
617
|
+
this.input = this.in("input", null, { type: "any" });
|
|
618
|
+
this.output = this.out("output", "param");
|
|
619
|
+
this.addParm("frozen", {
|
|
620
|
+
value: false,
|
|
621
|
+
type: "boolean",
|
|
622
|
+
displayName: "Frozen"
|
|
623
|
+
});
|
|
624
|
+
this.addAction("capture", {
|
|
625
|
+
label: "Capture",
|
|
626
|
+
icon: "Camera",
|
|
627
|
+
callback: () => this.capture()
|
|
628
|
+
});
|
|
629
|
+
this.addAction("clear", {
|
|
630
|
+
label: "Clear",
|
|
631
|
+
icon: "Trash2",
|
|
632
|
+
callback: () => this.clear()
|
|
633
|
+
});
|
|
634
|
+
this.watchProp("frozen", () => this.update());
|
|
635
|
+
this.onUpdate = () => this.update();
|
|
636
|
+
this.onReady = () => this.update();
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* Capture the current input value
|
|
640
|
+
*/
|
|
641
|
+
capture() {
|
|
642
|
+
this.frozenValue = this.deepClone(this.input.value);
|
|
643
|
+
this.hasCaptured = true;
|
|
644
|
+
this.setParm("frozen", true);
|
|
645
|
+
this.update();
|
|
646
|
+
}
|
|
647
|
+
/**
|
|
648
|
+
* Clear the frozen value
|
|
649
|
+
*/
|
|
650
|
+
clear() {
|
|
651
|
+
this.frozenValue = null;
|
|
652
|
+
this.hasCaptured = false;
|
|
653
|
+
this.setParm("frozen", false);
|
|
654
|
+
this.update();
|
|
655
|
+
}
|
|
656
|
+
/**
|
|
657
|
+
* Deep clone a value if possible
|
|
658
|
+
*/
|
|
659
|
+
deepClone(value) {
|
|
660
|
+
if (value === null || value === void 0) {
|
|
661
|
+
return value;
|
|
662
|
+
}
|
|
663
|
+
if (hasPixels(value)) {
|
|
664
|
+
const source = value;
|
|
665
|
+
const width = source.naturalWidth || source.width;
|
|
666
|
+
const height = source.naturalHeight || source.height;
|
|
667
|
+
const canvas = createSurface(width, height);
|
|
668
|
+
const ctx = canvas.getContext("2d");
|
|
669
|
+
ctx?.drawImage(value, 0, 0);
|
|
670
|
+
return canvas;
|
|
671
|
+
}
|
|
672
|
+
if (Array.isArray(value)) {
|
|
673
|
+
return value.map((item) => this.deepClone(item));
|
|
674
|
+
}
|
|
675
|
+
if (typeof value === "object") {
|
|
676
|
+
try {
|
|
677
|
+
return JSON.parse(JSON.stringify(value));
|
|
678
|
+
} catch {
|
|
679
|
+
return value;
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
return value;
|
|
683
|
+
}
|
|
684
|
+
update() {
|
|
685
|
+
const isFrozen = this.props.frozen?.value ?? false;
|
|
686
|
+
if (isFrozen && this.hasCaptured) {
|
|
687
|
+
this.output.setValue(this.frozenValue);
|
|
688
|
+
if (previewWanted() && hasPixels(this.frozenValue)) {
|
|
689
|
+
this.preview = this.frozenValue;
|
|
690
|
+
}
|
|
691
|
+
} else {
|
|
692
|
+
this.output.setValue(this.input.value);
|
|
693
|
+
if (previewWanted() && hasPixels(this.input.value)) {
|
|
694
|
+
this.preview = this.input.value;
|
|
695
|
+
} else {
|
|
696
|
+
this.preview = null;
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
/**
|
|
701
|
+
* Serialize with frozen state
|
|
702
|
+
*/
|
|
703
|
+
serialize() {
|
|
704
|
+
return {
|
|
705
|
+
hasCaptured: this.hasCaptured
|
|
706
|
+
};
|
|
707
|
+
}
|
|
708
|
+
/**
|
|
709
|
+
* Deserialize and restore frozen state
|
|
710
|
+
*/
|
|
711
|
+
deserialize(data) {
|
|
712
|
+
this.hasCaptured = data.hasCaptured === true;
|
|
713
|
+
}
|
|
714
|
+
};
|
|
715
|
+
|
|
716
|
+
// src/nodes/core/classes.ts
|
|
717
|
+
var coreNodeClasses = {
|
|
718
|
+
"Switch": SwitchNode,
|
|
719
|
+
"Merge": MergeNode,
|
|
720
|
+
"Subnet": SubnetNode,
|
|
721
|
+
"Input": InputNode,
|
|
722
|
+
"Output": OutputNode,
|
|
723
|
+
"Random": RandomNode,
|
|
724
|
+
"Remap": RemapNode,
|
|
725
|
+
"Select": SelectNode,
|
|
726
|
+
"Null": NullNode,
|
|
727
|
+
"Freeze": FreezeNode
|
|
728
|
+
};
|
|
729
|
+
|
|
730
|
+
// src/nodes/registerStandardNodes.ts
|
|
731
|
+
var registered = false;
|
|
732
|
+
function registerStandardNodes() {
|
|
733
|
+
if (registered) return;
|
|
734
|
+
registerNodeClasses("core", coreNodeClasses);
|
|
735
|
+
registered = true;
|
|
736
|
+
}
|
|
737
|
+
function standardNodesRegistered() {
|
|
738
|
+
return registered;
|
|
739
|
+
}
|
|
740
|
+
export {
|
|
741
|
+
registerStandardNodes,
|
|
742
|
+
standardNodesRegistered
|
|
743
|
+
};
|
|
744
|
+
//# sourceMappingURL=registerStandardNodes-BXJCB6E4.js.map
|