@babsey/code-graph 0.0.8 → 0.0.9

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.
@@ -1,1833 +1 @@
1
- (function(global, factory) {
2
- typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("baklavajs"), require("mustache"), require("vue"), require("toposort"), require("uuid"), require("@vueuse/core")) : typeof define === "function" && define.amd ? define(["exports", "baklavajs", "mustache", "vue", "toposort", "uuid", "@vueuse/core"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global["@babsey/code-graph"] = {}, global.baklavajs, global.mustache, global.Vue, global.toposort, global.uuid, global["@vueuse/core"]));
3
- })(this, (function(exports2, baklavajs, mustache, vue, toposort, uuid, core) {
4
- "use strict";
5
- class AbstractCodeNode extends baklavajs.AbstractNode {
6
- state;
7
- code;
8
- isCodeNode = true;
9
- inputs = {};
10
- outputs = {};
11
- constructor() {
12
- super();
13
- this.initializeIo();
14
- this.width = 400;
15
- this.twoColumn = true;
16
- this.state = vue.reactive({
17
- codeTemplate: "{{ &outputs.code }}",
18
- hidden: false,
19
- integrated: false,
20
- modules: [],
21
- script: "",
22
- variableName: ""
23
- });
24
- }
25
- get codeTemplate() {
26
- return this.state.codeTemplate;
27
- }
28
- get idx() {
29
- return this.code?.codeNodes.filter((node) => !node.state.integrated).indexOf(this) ?? -1;
30
- }
31
- get idxByVariableNames() {
32
- return this.code?.getNodesBySameVariableNames(this.state.variableName).indexOf(this) ?? -1;
33
- }
34
- get script() {
35
- return this.state.script;
36
- }
37
- get shortId() {
38
- return this.id.slice(0, 6);
39
- }
40
- get variableName() {
41
- return this.state.variableName ? this.state.variableName + (this.idxByVariableNames + 1) : "";
42
- }
43
- /**
44
- * Get connected nodes to the node.
45
- * @param type inputs or outputs
46
- * @returns code node instances
47
- */
48
- getConnectedNodes(type) {
49
- let nodeIds = [];
50
- if (type !== "inputs") {
51
- const targets = this.graph?.connections.filter((c) => c.from.name !== "_node").filter((c) => c.from.nodeId === this.id).map((c) => c.to.nodeId);
52
- if (targets) nodeIds = nodeIds.concat(targets);
53
- }
54
- if (type !== "outputs") {
55
- const sources = this.graph?.connections.filter((c) => c.from.name !== "_node").filter((c) => c.to.nodeId === this.id).map((c) => c.from.nodeId);
56
- if (sources) nodeIds = nodeIds.concat(sources);
57
- }
58
- if (!nodeIds || nodeIds.length == 0) return [];
59
- return nodeIds.map((nodeId) => this.graph?.findNodeById(nodeId));
60
- }
61
- registerCode(code) {
62
- this.code = code;
63
- }
64
- /**
65
- * Render code of this node.
66
- */
67
- renderCode() {
68
- const inputs = {};
69
- Object.keys(this.inputs).forEach((intfKey) => {
70
- if (intfKey === "_node") return;
71
- const intf = this.inputs[intfKey];
72
- const value = intf.isString ? `'${intf.value}'` : intf.value;
73
- if (intf && intf.state) inputs[intfKey] = intf.state.script.length > 0 ? intf.state.script : value;
74
- });
75
- const outputs = {};
76
- Object.keys(this.outputs).forEach((intfKey) => {
77
- if (intfKey === "_node") return;
78
- const intf = this.outputs[intfKey];
79
- const value = intf.isString ? `'${intf.value}'` : intf.value;
80
- if (intf && intf.state) outputs[intfKey] = value;
81
- });
82
- this.state.script = mustache.render(this.state.codeTemplate, { inputs, outputs });
83
- if (this.outputs.code) this.outputs.code.state.script = this.state.script;
84
- }
85
- updateOutputVariableName() {
86
- if (this.outputs.code) this.outputs.code.name = this.variableName;
87
- }
88
- }
89
- class CodeNode extends AbstractCodeNode {
90
- /**
91
- * The default implementation does nothing.
92
- * Overwrite this method to do calculation.
93
- * @param inputs Values of all input interfaces
94
- * @param globalValues Set of values passed to every node by the engine plugin
95
- * @return Values for output interfaces
96
- */
97
- calculate;
98
- load(state) {
99
- super.load(state);
100
- loadNodeState(this.graph, state);
101
- }
102
- save() {
103
- const state = super.save();
104
- saveNodeState(this.graph, state);
105
- return state;
106
- }
107
- updateModules(modules) {
108
- if (modules) {
109
- this.state.modules = modules;
110
- } else if (this.type.includes(".")) {
111
- const modules2 = this.type.split(".");
112
- this.state.modules.push(modules2.slice(0, modules2.length - 1).join("."));
113
- }
114
- }
115
- }
116
- const loadNodeState = (graph, nodeState) => {
117
- if (!graph) return;
118
- const node = graph.findNodeById(nodeState.id);
119
- if (!node || node.subgraph) return;
120
- const codeNode = node;
121
- if (codeNode.state) {
122
- codeNode.state.integrated = nodeState.integrated;
123
- codeNode.state.modules = nodeState.modules;
124
- codeNode.state.props = nodeState.props;
125
- }
126
- Object.entries(nodeState.inputs).forEach(([inputKey, inputItem]) => {
127
- if (inputKey === "_node") return;
128
- if (codeNode.inputs[inputKey]) codeNode.inputs[inputKey].hidden = inputItem.hidden;
129
- });
130
- Object.entries(nodeState.outputs).forEach(([outputKey, outputItem]) => {
131
- if (outputKey === "_node") return;
132
- if (codeNode.outputs[outputKey]) codeNode.outputs[outputKey].hidden = outputItem.hidden;
133
- });
134
- };
135
- const saveNodeState = (graph, nodeState) => {
136
- if (!graph) return;
137
- const node = graph.findNodeById(nodeState.id);
138
- if (!node || node.subgraph) return;
139
- const codeNode = node;
140
- if (codeNode.state) {
141
- nodeState.integrated = codeNode.state.integrated;
142
- nodeState.modules = codeNode.state.modules;
143
- }
144
- Object.entries(nodeState.inputs).forEach(([inputKey, inputItem]) => {
145
- if (inputKey === "_node") return;
146
- if (codeNode.inputs[inputKey]) inputItem.hidden = codeNode.inputs[inputKey].hidden;
147
- });
148
- Object.entries(nodeState.outputs).forEach(([outputKey, outputItem]) => {
149
- if (outputKey === "_node") return;
150
- if (codeNode.outputs[outputKey]) outputItem.hidden = codeNode.outputs[outputKey].hidden;
151
- });
152
- };
153
- new baklavajs.NodeInterfaceType("boolean");
154
- new baklavajs.NodeInterfaceType("dict");
155
- new baklavajs.NodeInterfaceType("list");
156
- const nodeType = new baklavajs.NodeInterfaceType("node");
157
- const numberType = new baklavajs.NodeInterfaceType("number");
158
- const stringType = new baklavajs.NodeInterfaceType("string");
159
- const _hoisted_1$f = ["title"];
160
- const _sfc_main$g = /* @__PURE__ */ vue.defineComponent({
161
- __name: "CodeNodeInterface",
162
- props: {
163
- intf: {}
164
- },
165
- setup(__props) {
166
- return (_ctx, _cache) => {
167
- return vue.openBlock(), vue.createElementBlock("div", {
168
- title: _ctx.intf.state?.script
169
- }, vue.toDisplayString(_ctx.intf.name), 9, _hoisted_1$f);
170
- };
171
- }
172
- });
173
- class CodeNodeInterface extends baklavajs.NodeInterface {
174
- optional = false;
175
- code;
176
- state;
177
- constructor(name, value) {
178
- super(name, value);
179
- this.setComponent(vue.markRaw(_sfc_main$g));
180
- this.state = vue.reactive({
181
- script: ""
182
- });
183
- }
184
- get shortId() {
185
- return this.id.slice(0, 6);
186
- }
187
- // override get value(): T {
188
- // return super.value
189
- // }
190
- // override set value(value: T) {
191
- // super.value = value;
192
- // if (this.name !== '_node') this.setHidden(false);
193
- // }
194
- }
195
- class ButtonInterface extends CodeNodeInterface {
196
- component = vue.markRaw(baklavajs.ButtonInterfaceComponent);
197
- callback;
198
- constructor(name, callback) {
199
- super(name, void 0);
200
- this.callback = callback;
201
- this.setPort(false);
202
- }
203
- }
204
- class CheckboxInterface extends CodeNodeInterface {
205
- component = vue.markRaw(baklavajs.CheckboxInterfaceComponent);
206
- }
207
- class BaseNumericInterface extends CodeNodeInterface {
208
- min;
209
- max;
210
- constructor(name, value, min, max) {
211
- super(name, value);
212
- this.min = min;
213
- this.max = max;
214
- }
215
- validate(v) {
216
- return (this.min === void 0 || v >= this.min) && (this.max === void 0 || v <= this.max);
217
- }
218
- }
219
- class IntegerInterface extends BaseNumericInterface {
220
- component = vue.markRaw(baklavajs.IntegerInterfaceComponent);
221
- validate(v) {
222
- return Number.isInteger(v) && super.validate(v);
223
- }
224
- }
225
- class CodeInputInterface extends CodeNodeInterface {
226
- isCodeInput = true;
227
- constructor(name = "", value) {
228
- super(name, value);
229
- this.setComponent(vue.markRaw(_sfc_main$g));
230
- }
231
- }
232
- class CodeOutputInterface extends CodeNodeInterface {
233
- isCodeOutput = true;
234
- constructor(name = "", value = "") {
235
- super(name, value);
236
- this.setComponent(vue.markRaw(_sfc_main$g));
237
- }
238
- get script() {
239
- return this.state.script;
240
- }
241
- get value() {
242
- return super.value;
243
- }
244
- set value(value) {
245
- super.value = value;
246
- this.state.script = this.name.length > 0 ? this.name : this.value;
247
- }
248
- }
249
- class NumberInterface extends BaseNumericInterface {
250
- component = vue.markRaw(baklavajs.NumberInterfaceComponent);
251
- }
252
- class SelectInterface extends CodeNodeInterface {
253
- component = vue.markRaw(baklavajs.SelectInterfaceComponent);
254
- items;
255
- constructor(name, value, items) {
256
- super(name, value);
257
- this.items = items;
258
- }
259
- }
260
- class SliderInterface extends BaseNumericInterface {
261
- component = vue.markRaw(baklavajs.SliderInterfaceComponent);
262
- min;
263
- max;
264
- constructor(name, value, min, max) {
265
- super(name, value, min, max);
266
- this.min = min;
267
- this.max = max;
268
- }
269
- }
270
- class TextInterface extends CodeNodeInterface {
271
- component = vue.markRaw(baklavajs.TextInputInterfaceComponent);
272
- constructor(name, value) {
273
- super(name, value);
274
- this.setPort(false);
275
- }
276
- }
277
- class TextInputInterface extends CodeNodeInterface {
278
- isString = true;
279
- component = vue.markRaw(baklavajs.TextInputInterfaceComponent);
280
- }
281
- class TextareaInputInterface extends CodeNodeInterface {
282
- component = vue.markRaw(baklavajs.TextareaInputInterfaceComponent);
283
- }
284
- function defineCodeNode(definition) {
285
- return class extends CodeNode {
286
- type = definition.type;
287
- inputs = {};
288
- outputs = {};
289
- constructor() {
290
- super();
291
- this._title = definition.title ?? definition.type;
292
- this.updateModules(definition.modules);
293
- if (definition.codeTemplate) this.state.codeTemplate = definition.codeTemplate(this);
294
- if (definition.variableName) this.state.variableName = definition.variableName;
295
- this.addInput(
296
- "_node",
297
- new CodeNodeInterface("", []).use(baklavajs.setType, nodeType).use(baklavajs.allowMultipleConnections).setHidden(true)
298
- );
299
- this.addOutput(
300
- "_node",
301
- new CodeNodeInterface("", []).use(baklavajs.setType, nodeType).use(baklavajs.allowMultipleConnections).setHidden(true)
302
- );
303
- this.executeFactory("input", definition.inputs);
304
- this.executeFactory("output", definition.outputs);
305
- definition.onCreate?.call(this);
306
- }
307
- calculate = definition.calculate ? (inputs, globalValues) => ({
308
- ...definition.calculate.call(this, inputs, globalValues),
309
- _node: null
310
- }) : void 0;
311
- onPlaced() {
312
- definition.onPlaced?.call(this);
313
- }
314
- onDestroy() {
315
- definition.onDestroy?.call(this);
316
- }
317
- onCodeUpdate() {
318
- definition.onCodeUpdate?.call(this);
319
- }
320
- executeFactory(type, factory) {
321
- Object.keys(factory || {}).forEach((k) => {
322
- const intf = factory[k]();
323
- if (type === "input") {
324
- this.addInput(k, intf);
325
- } else {
326
- this.addOutput(k, intf);
327
- }
328
- });
329
- }
330
- };
331
- }
332
- class DynamicCodeNode extends CodeNode {
333
- /**
334
- * The default implementation does nothing.
335
- * Overwrite this method to do calculation.
336
- * @param inputs Values of all input interfaces
337
- * @param globalValues Set of values passed to every node by the engine plugin
338
- * @return Values for output interfaces
339
- */
340
- calculate;
341
- }
342
- function defineDynamicCodeNode(definition) {
343
- return class extends DynamicCodeNode {
344
- type = definition.type;
345
- inputs = {};
346
- outputs = {};
347
- calculate;
348
- preventUpdate = false;
349
- staticInputKeys = Object.keys(definition.inputs ?? {});
350
- staticOutputKeys = Object.keys(definition.outputs ?? {});
351
- constructor() {
352
- super();
353
- this._title = definition.title ?? definition.type;
354
- this.updateModules(definition.modules);
355
- if (definition.codeTemplate) this.state.codeTemplate = definition.codeTemplate(this);
356
- if (definition.variableName) this.state.variableName = definition.variableName;
357
- this.addInput(
358
- "_node",
359
- new CodeNodeInterface("", []).use(baklavajs.setType, nodeType).use(baklavajs.allowMultipleConnections).setHidden(true)
360
- );
361
- this.addOutput(
362
- "_node",
363
- new CodeNodeInterface("", []).use(baklavajs.setType, nodeType).use(baklavajs.allowMultipleConnections).setHidden(true)
364
- );
365
- this.staticInputKeys.push("_node");
366
- this.staticOutputKeys.push("_node");
367
- this.executeFactory("input", definition.inputs);
368
- this.executeFactory("output", definition.outputs);
369
- if (definition.calculate) {
370
- this.calculate = (inputs, globalValues) => ({
371
- ...definition.calculate?.call(this, inputs, globalValues),
372
- _node: null
373
- });
374
- }
375
- definition.onCreate?.call(this);
376
- }
377
- onPlaced() {
378
- this.events.update.subscribe(this, (data) => {
379
- if (!data) return;
380
- if (data.type === "input" && this.staticInputKeys.includes(data.name) || data.type === "output" && this.staticOutputKeys.includes(data.name)) {
381
- this.onUpdate();
382
- }
383
- });
384
- this.onUpdate();
385
- definition.onPlaced?.call(this);
386
- }
387
- onDestroy() {
388
- definition.onDestroy?.call(this);
389
- }
390
- onCodeUpdate() {
391
- definition.onCodeUpdate?.call(this);
392
- }
393
- load(state) {
394
- this.preventUpdate = true;
395
- this.hooks.beforeLoad.execute(state);
396
- this.id = state.id;
397
- this.title = state.title;
398
- for (const k of this.staticInputKeys) {
399
- this.inputs[k].load(state.inputs[k]);
400
- this.inputs[k].nodeId = this.id;
401
- if (k === "_node") continue;
402
- this.inputs[k].hidden = state.inputs[k].hidden;
403
- }
404
- for (const k of this.staticOutputKeys) {
405
- this.outputs[k].load(state.outputs[k]);
406
- this.outputs[k].nodeId = this.id;
407
- if (k === "_node") continue;
408
- this.outputs[k].hidden = state.outputs[k].hidden;
409
- }
410
- this.preventUpdate = false;
411
- this.onUpdate();
412
- this.preventUpdate = true;
413
- for (const k of Object.keys(state.inputs)) {
414
- if (this.staticInputKeys.includes(k)) continue;
415
- if (!this.inputs[k]) {
416
- const value = state.inputs[k].value;
417
- let inputInterface;
418
- if (typeof value == "number") {
419
- inputInterface = new baklavajs.IntegerInterface(k, value).use(baklavajs.setType, numberType);
420
- } else {
421
- inputInterface = new baklavajs.TextInputInterface(k, JSON.stringify(value)).use(baklavajs.setType, stringType);
422
- }
423
- inputInterface.use(baklavajs.displayInSidebar, true);
424
- this.addInput(k, inputInterface);
425
- }
426
- if (this.inputs[k]) {
427
- this.inputs[k].load(state.inputs[k]);
428
- this.inputs[k].nodeId = this.id;
429
- }
430
- }
431
- for (const k of Object.keys(state.outputs)) {
432
- if (this.staticOutputKeys.includes(k)) continue;
433
- if (!this.outputs[k]) {
434
- const outputInterface = new CodeOutputInterface(k);
435
- this.addOutput(k, outputInterface);
436
- }
437
- if (this.outputs[k]) {
438
- this.outputs[k].load(state.outputs[k]);
439
- this.outputs[k].nodeId = this.id;
440
- }
441
- }
442
- loadNodeState(this.graph, state);
443
- this.preventUpdate = false;
444
- this.events.loaded.emit(this);
445
- }
446
- onUpdate() {
447
- if (this.preventUpdate) return;
448
- if (this.graph) this.graph.activeTransactions++;
449
- const inputValues = this.getStaticValues(this.staticInputKeys, this.inputs);
450
- const outputValues = this.getStaticValues(this.staticOutputKeys, this.outputs);
451
- const result = definition.onUpdate.call(this, inputValues, outputValues);
452
- this.updateInterfaces("input", result.inputs ?? {}, result.forceUpdateInputs ?? []);
453
- this.updateInterfaces("output", result.outputs ?? {}, result.forceUpdateOutputs ?? []);
454
- if (this.graph) this.graph.activeTransactions--;
455
- }
456
- getStaticValues(keys, interfaces) {
457
- const values = {};
458
- for (const k of keys) {
459
- values[k] = interfaces[k].value;
460
- }
461
- return values;
462
- }
463
- updateInterfaces(type, newInterfaces, forceUpdates) {
464
- const staticKeys = type === "input" ? this.staticInputKeys : this.staticOutputKeys;
465
- const currentInterfaces = type === "input" ? this.inputs : this.outputs;
466
- for (const k of Object.keys(currentInterfaces)) {
467
- if (staticKeys.includes(k) || newInterfaces[k] && !forceUpdates.includes(k)) continue;
468
- if (type === "input") {
469
- this.removeInput(k);
470
- } else {
471
- this.removeOutput(k);
472
- }
473
- }
474
- for (const k of Object.keys(newInterfaces)) {
475
- if (currentInterfaces[k]) continue;
476
- const intf = newInterfaces[k]();
477
- if (type === "input") {
478
- this.addInput(k, intf);
479
- } else {
480
- this.addOutput(k, intf);
481
- }
482
- }
483
- }
484
- executeFactory(type, factory) {
485
- Object.keys(factory || {}).forEach((k) => {
486
- const intf = factory[k]();
487
- if (type === "input") {
488
- this.addInput(k, intf);
489
- } else {
490
- this.addOutput(k, intf);
491
- }
492
- });
493
- }
494
- };
495
- }
496
- class Code {
497
- _id;
498
- _viewModel;
499
- _state;
500
- constructor(viewModel) {
501
- this._id = uuid.v4();
502
- this._viewModel = viewModel;
503
- this._state = vue.reactive({
504
- autosort: false,
505
- modules: {},
506
- script: "",
507
- token: null,
508
- template: ""
509
- });
510
- }
511
- get codeNodes() {
512
- return getCodeNodes(this.graph);
513
- }
514
- get connections() {
515
- return this.graph.connections;
516
- }
517
- set connections(values) {
518
- this.graph._connections = values;
519
- }
520
- get graph() {
521
- return this.viewModel.displayedGraph;
522
- }
523
- get id() {
524
- return this._id;
525
- }
526
- get modules() {
527
- let categories = [];
528
- this.codeNodes.filter((node) => node.state.modules?.length > 0).forEach((node) => {
529
- categories = categories.concat(node.state.modules);
530
- });
531
- if (!categories) return [];
532
- categories.sort();
533
- return Array.from(new Set(categories.map((category) => this.viewModel.state.modules[category])));
534
- }
535
- get nodeIds() {
536
- return this.codeNodes.map((node) => node.id);
537
- }
538
- get nodes() {
539
- return this.graph.nodes;
540
- }
541
- set nodes(values) {
542
- this.graph._nodes = values;
543
- }
544
- get scriptedCodeNodes() {
545
- return getCodeNodes(this.graph).filter(
546
- (codeNode) => codeNode.state?.script.length > 0
547
- );
548
- }
549
- get shortId() {
550
- return this.id.slice(0, 6);
551
- }
552
- get state() {
553
- return this._state;
554
- }
555
- get viewModel() {
556
- return this._viewModel;
557
- }
558
- get visibleNodes() {
559
- return this.codeNodes.filter((node) => !node.state?.hidden);
560
- }
561
- /**
562
- * Add code node to graph.
563
- * @param node code node
564
- * @param props optional
565
- */
566
- addNode(node, props) {
567
- if (!node.code) node.code = this;
568
- if (props) node.state.props = props;
569
- return this.graph.addNode(node);
570
- }
571
- /**
572
- * Add code node at coordinates.
573
- * @param node code node
574
- * @param position position
575
- * @param props optional
576
- * @returns code node
577
- */
578
- addNodeAtCoordinates = (node, position = { x: 0, y: 0 }, props) => {
579
- this.addNode(node, props);
580
- if (node.position) node.position = position;
581
- return node;
582
- };
583
- /**
584
- * Add connection of code nodes
585
- * @param from code node interface
586
- * @param to code node interface
587
- */
588
- addConnection(from, to) {
589
- if (from.name !== "_node") from.hidden = false;
590
- if (to.name !== "_node") to.hidden = false;
591
- this.graph.addConnection(from, to);
592
- }
593
- /**
594
- * Clear code graph.
595
- */
596
- clear() {
597
- this.nodes = [];
598
- this.connections = [];
599
- }
600
- findNodeById(id) {
601
- return this.graph.findNodeById(id);
602
- }
603
- findNodeByType(nodeType2) {
604
- return this.codeNodes.find((codeNode) => codeNode.type === nodeType2);
605
- }
606
- getNodesBySameType(type) {
607
- return this.codeNodes.filter((codeNode) => codeNode.type === type);
608
- }
609
- getNodesBySameVariableNames(variableName) {
610
- return this.codeNodes.filter(
611
- (codeNode) => codeNode.state.variableName === variableName
612
- );
613
- }
614
- /**
615
- * Check whether the graph has this connection.
616
- * @param from node interface
617
- * @param to node interface
618
- * @returns boolean
619
- */
620
- hasConnection(from, to) {
621
- return this.connections.some(
622
- (connection) => connection.from.id === from.id && connection.to.id === to.id
623
- );
624
- }
625
- /**
626
- * Load template from the file.
627
- */
628
- loadTemplate(resolve) {
629
- resolve.then((template) => {
630
- this._state.template = template.default ?? "";
631
- });
632
- }
633
- onCodeUpdate() {
634
- this.codeNodes.forEach((codeNode) => codeNode.onCodeUpdate());
635
- }
636
- /**
637
- * Remove connection from the graph
638
- * @param connection connection between code nodes
639
- */
640
- removeConnection(connection) {
641
- this.graph.removeConnection(connection);
642
- }
643
- /**
644
- * Remove node from the graph.
645
- * @param codeNode code node
646
- */
647
- removeNode(codeNode) {
648
- this.graph.removeNode(codeNode);
649
- }
650
- /**
651
- * Render node codes.
652
- */
653
- renderNodeCodes() {
654
- if (this.codeNodes.length === 0) return;
655
- this.codeNodes.forEach((node) => node.renderCode());
656
- }
657
- /**
658
- * Render code.
659
- */
660
- renderCode() {
661
- this.state.script = mustache.render(this.state.template || "", this);
662
- }
663
- /**
664
- * Save code graph.
665
- * @returns graph state
666
- */
667
- save() {
668
- if (this.state.autosort) this.sortNodes();
669
- const editorState = this.viewModel.editor.save();
670
- editorState.graph.id = this.id;
671
- this.saveNodeStates(editorState.graph.nodes);
672
- return JSON.parse(JSON.stringify(editorState));
673
- }
674
- /**
675
- * Save node states.
676
- * @param nodeStates a list of node state.
677
- */
678
- saveNodeStates(nodeStates) {
679
- nodeStates.forEach((nodeState, nodeIdx) => {
680
- const node = this.nodes[nodeIdx];
681
- Object.entries(nodeState.inputs).forEach(([inputKey]) => {
682
- if (nodeState.inputs && node.inputs[inputKey]) nodeState.inputs[inputKey].hidden = node.inputs[inputKey].hidden;
683
- });
684
- Object.entries(nodeState.outputs).forEach(([outputKey]) => {
685
- if (nodeState.outputs && node.outputs[outputKey])
686
- nodeState.outputs[outputKey].hidden = node.outputs[outputKey].hidden;
687
- });
688
- });
689
- }
690
- /**
691
- * Sort code nodes.
692
- */
693
- sortNodes() {
694
- if (this.nodes.length === 0 || this.connections.length === 0) return;
695
- try {
696
- const edges = this.connections.map((connection) => [
697
- connection.to.nodeId,
698
- connection.from.nodeId
699
- ]);
700
- let nodeIds = [...this.nodeIds];
701
- nodeIds.reverse();
702
- nodeIds = toposort.array(nodeIds, edges);
703
- nodeIds.reverse();
704
- const unconnected = this.graph.nodes.map((node) => node.id).filter((nodeId) => !nodeIds.includes(nodeId));
705
- nodeIds = nodeIds.concat(unconnected);
706
- const nodes = nodeIds.map((nodeId) => this.findNodeById(nodeId));
707
- if (nodes) this.nodes = nodes;
708
- } catch {
709
- console.warn("Failed to sort nodes.");
710
- }
711
- }
712
- updateOutputVariableNames() {
713
- this.codeNodes.forEach((codeNode) => codeNode.updateOutputVariableName());
714
- }
715
- }
716
- const getCodeNodes = (graph) => {
717
- let nodes = [];
718
- graph.nodes.forEach((node) => {
719
- if (node.subgraph) {
720
- nodes = nodes.concat(getCodeNodes(node.subgraph));
721
- } else if (node.isCodeNode) {
722
- nodes.push(node);
723
- }
724
- });
725
- return nodes;
726
- };
727
- const getPositionAtColumn = (col = 0, offset = 100) => {
728
- const width = 350;
729
- const padding = 70;
730
- return {
731
- x: col * (width + padding),
732
- y: offset
733
- };
734
- };
735
- const getPositionBeforeNode = (node) => {
736
- const position = { ...node.position };
737
- position.x -= 400;
738
- position.y += 50;
739
- return position;
740
- };
741
- const transferCodeScript = (graph) => {
742
- const { calculationOrder, connectionsFromNode } = baklavajs.sortTopologically(graph);
743
- calculationOrder.forEach((node) => {
744
- if (!node.isCodeNode) return;
745
- const codeNode = node;
746
- if (connectionsFromNode.has(codeNode)) {
747
- connectionsFromNode.get(codeNode).forEach((c) => {
748
- if (c.to.state && c.from.script) c.to.state.script = c.from.script;
749
- });
750
- }
751
- });
752
- };
753
- const _hoisted_1$e = ["id"];
754
- const _hoisted_2$5 = { class: "align-middle" };
755
- const _sfc_main$f = /* @__PURE__ */ vue.defineComponent({
756
- __name: "CodeGraphNodeInterface",
757
- props: {
758
- node: {},
759
- intf: {}
760
- },
761
- setup(__props) {
762
- const props = __props;
763
- const { viewModel } = baklavajs.useViewModel();
764
- const { hoveredOver, temporaryConnection } = baklavajs.useTemporaryConnection();
765
- const el = vue.ref(null);
766
- const isConnected = vue.computed(() => props.intf.connectionCount > 0);
767
- const classes = vue.computed(() => ({
768
- "--connected": isConnected.value
769
- }));
770
- const startHover = () => {
771
- hoveredOver(props.intf);
772
- };
773
- const endHover = () => {
774
- hoveredOver(void 0);
775
- };
776
- const onRender = () => {
777
- if (el.value) {
778
- viewModel.value.hooks.renderInterface.execute({ intf: props.intf, el: el.value });
779
- }
780
- };
781
- vue.onMounted(onRender);
782
- vue.onUpdated(onRender);
783
- return (_ctx, _cache) => {
784
- return vue.openBlock(), vue.createElementBlock("div", {
785
- id: _ctx.intf.id,
786
- ref_key: "el",
787
- ref: el,
788
- class: vue.normalizeClass(["baklava-node-interface", classes.value])
789
- }, [
790
- _ctx.intf.port ? (vue.openBlock(), vue.createElementBlock("div", {
791
- key: 0,
792
- class: vue.normalizeClass(["__port", { "--selected": vue.unref(temporaryConnection)?.from === _ctx.intf }]),
793
- onPointerover: startHover,
794
- onPointerout: endHover
795
- }, null, 34)) : vue.createCommentVNode("", true),
796
- vue.createElementVNode("span", _hoisted_2$5, [
797
- vue.renderSlot(_ctx.$slots, "default")
798
- ])
799
- ], 10, _hoisted_1$e);
800
- };
801
- }
802
- });
803
- const _export_sfc = (sfc, props) => {
804
- const target = sfc.__vccOpts || sfc;
805
- for (const [key, val] of props) {
806
- target[key] = val;
807
- }
808
- return target;
809
- };
810
- const _sfc_main$e = {};
811
- const _hoisted_1$d = {
812
- xmlns: "http://www.w3.org/2000/svg",
813
- width: "24",
814
- height: "24",
815
- viewBox: "0 0 24 24",
816
- fill: "currentColor",
817
- class: "baklava-icon icon icon-tabler icons-tabler-filled icon-tabler-layout-sidebar-left-collapse"
818
- };
819
- function _sfc_render$9(_ctx, _cache) {
820
- return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1$d, [..._cache[0] || (_cache[0] = [
821
- vue.createElementVNode("path", {
822
- stroke: "none",
823
- d: "M0 0h24v24H0z",
824
- fill: "none"
825
- }, null, -1),
826
- vue.createElementVNode("path", { d: "M18 3a3 3 0 0 1 2.995 2.824l.005 .176v12a3 3 0 0 1 -2.824 2.995l-.176 .005h-12a3 3 0 0 1 -2.995 -2.824l-.005 -.176v-12a3 3 0 0 1 2.824 -2.995l.176 -.005h12zm0 2h-9v14h9a1 1 0 0 0 .993 -.883l.007 -.117v-12a1 1 0 0 0 -.883 -.993l-.117 -.007zm-2.293 4.293a1 1 0 0 1 .083 1.32l-.083 .094l-1.292 1.293l1.292 1.293a1 1 0 0 1 .083 1.32l-.083 .094a1 1 0 0 1 -1.32 .083l-.094 -.083l-2 -2a1 1 0 0 1 -.083 -1.32l.083 -.094l2 -2a1 1 0 0 1 1.414 0z" }, null, -1)
827
- ])]);
828
- }
829
- const LayoutSidebarLeftCollapse = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["render", _sfc_render$9]]);
830
- const _sfc_main$d = {};
831
- const _hoisted_1$c = {
832
- xmlns: "http://www.w3.org/2000/svg",
833
- width: "24",
834
- height: "24",
835
- viewBox: "0 0 24 24",
836
- fill: "currentColor",
837
- class: "baklava-icon icon icon-tabler icons-tabler-filled icon-tabler-layout-sidebar-left-expand"
838
- };
839
- function _sfc_render$8(_ctx, _cache) {
840
- return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1$c, [..._cache[0] || (_cache[0] = [
841
- vue.createElementVNode("path", {
842
- stroke: "none",
843
- d: "M0 0h24v24H0z",
844
- fill: "none"
845
- }, null, -1),
846
- vue.createElementVNode("path", { d: "M18 3a3 3 0 0 1 2.995 2.824l.005 .176v12a3 3 0 0 1 -2.824 2.995l-.176 .005h-12a3 3 0 0 1 -2.995 -2.824l-.005 -.176v-12a3 3 0 0 1 2.824 -2.995l.176 -.005h12zm0 2h-9v14h9a1 1 0 0 0 .993 -.883l.007 -.117v-12a1 1 0 0 0 -.883 -.993l-.117 -.007zm-4.387 4.21l.094 .083l2 2a1 1 0 0 1 .083 1.32l-.083 .094l-2 2a1 1 0 0 1 -1.497 -1.32l.083 -.094l1.292 -1.293l-1.292 -1.293a1 1 0 0 1 -.083 -1.32l.083 -.094a1 1 0 0 1 1.32 -.083z" }, null, -1)
847
- ])]);
848
- }
849
- const LayoutSidebarLeftExpand = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["render", _sfc_render$8]]);
850
- const _sfc_main$c = {};
851
- const _hoisted_1$b = {
852
- xmlns: "http://www.w3.org/2000/svg",
853
- width: "24",
854
- height: "24",
855
- viewBox: "0 0 24 24",
856
- fill: "currentColor",
857
- class: "balkava-icon icon icon-tabler icons-tabler-filled icon-tabler-layout-sidebar-right"
858
- };
859
- function _sfc_render$7(_ctx, _cache) {
860
- return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1$b, [..._cache[0] || (_cache[0] = [
861
- vue.createElementVNode("path", {
862
- stroke: "none",
863
- d: "M0 0h24v24H0z",
864
- fill: "none"
865
- }, null, -1),
866
- vue.createElementVNode("path", { d: "M6 21a3 3 0 0 1 -3 -3v-12a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v12a3 3 0 0 1 -3 3zm8 -16h-8a1 1 0 0 0 -1 1v12a1 1 0 0 0 1 1h8z" }, null, -1)
867
- ])]);
868
- }
869
- const LayoutSidebarRight = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["render", _sfc_render$7]]);
870
- const _sfc_main$b = {};
871
- const _hoisted_1$a = {
872
- xmlns: "http://www.w3.org/2000/svg",
873
- width: "24",
874
- height: "24",
875
- viewBox: "0 0 24 24",
876
- fill: "currentColor",
877
- class: "baklava-icon icon icon-tabler icons-tabler-filled icon-tabler-layout-sidebar-right-collapse"
878
- };
879
- function _sfc_render$6(_ctx, _cache) {
880
- return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1$a, [..._cache[0] || (_cache[0] = [
881
- vue.createElementVNode("path", {
882
- stroke: "none",
883
- d: "M0 0h24v24H0z",
884
- fill: "none"
885
- }, null, -1),
886
- vue.createElementVNode("path", { d: "M18 3a3 3 0 0 1 2.995 2.824l.005 .176v12a3 3 0 0 1 -2.824 2.995l-.176 .005h-12a3 3 0 0 1 -2.995 -2.824l-.005 -.176v-12a3 3 0 0 1 2.824 -2.995l.176 -.005h12zm-3 2h-9a1 1 0 0 0 -.993 .883l-.007 .117v12a1 1 0 0 0 .883 .993l.117 .007h9v-14zm-5.387 4.21l.094 .083l2 2a1 1 0 0 1 .083 1.32l-.083 .094l-2 2a1 1 0 0 1 -1.497 -1.32l.083 -.094l1.292 -1.293l-1.292 -1.293a1 1 0 0 1 -.083 -1.32l.083 -.094a1 1 0 0 1 1.32 -.083z" }, null, -1)
887
- ])]);
888
- }
889
- const LayoutSidebarRightCollapse = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["render", _sfc_render$6]]);
890
- const _sfc_main$a = {};
891
- const _hoisted_1$9 = {
892
- xmlns: "http://www.w3.org/2000/svg",
893
- width: "24",
894
- height: "24",
895
- viewBox: "0 0 24 24",
896
- fill: "currentColor",
897
- class: "baklava-icon icon icon-tabler icons-tabler-filled icon-tabler-layout-sidebar-right-expand"
898
- };
899
- function _sfc_render$5(_ctx, _cache) {
900
- return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1$9, [..._cache[0] || (_cache[0] = [
901
- vue.createElementVNode("path", {
902
- stroke: "none",
903
- d: "M0 0h24v24H0z",
904
- fill: "none"
905
- }, null, -1),
906
- vue.createElementVNode("path", { d: "M18 3a3 3 0 0 1 2.995 2.824l.005 .176v12a3 3 0 0 1 -2.824 2.995l-.176 .005h-12a3 3 0 0 1 -2.995 -2.824l-.005 -.176v-12a3 3 0 0 1 2.824 -2.995l.176 -.005h12zm-3 2h-9a1 1 0 0 0 -.993 .883l-.007 .117v12a1 1 0 0 0 .883 .993l.117 .007h9v-14zm-3.293 4.293a1 1 0 0 1 .083 1.32l-.083 .094l-1.292 1.293l1.292 1.293a1 1 0 0 1 .083 1.32l-.083 .094a1 1 0 0 1 -1.32 .083l-.094 -.083l-2 -2a1 1 0 0 1 -.083 -1.32l.083 -.094l2 -2a1 1 0 0 1 1.414 0z" }, null, -1)
907
- ])]);
908
- }
909
- const LayoutSidebarRightExpand = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["render", _sfc_render$5]]);
910
- const _sfc_main$9 = {};
911
- const _hoisted_1$8 = {
912
- xmlns: "http://www.w3.org/2000/svg",
913
- class: "baklava-icon",
914
- width: "24",
915
- height: "24",
916
- viewBox: "0 0 24 24",
917
- fill: "none",
918
- stroke: "currentColor",
919
- "stroke-width": "2",
920
- "stroke-linecap": "round",
921
- "stroke-linejoin": "round"
922
- };
923
- function _sfc_render$4(_ctx, _cache) {
924
- return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1$8, [..._cache[0] || (_cache[0] = [
925
- vue.createStaticVNode('<path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M5 2h5v4h-5z"></path><path d="M15 10h5v4h-5z"></path><path d="M5 18h5v4h-5z"></path><path d="M5 10h5v4h-5z"></path><path d="M10 12h5"></path><path d="M7.5 6v4"></path><path d="M7.5 14v4"></path>', 8)
926
- ])]);
927
- }
928
- const Schema = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["render", _sfc_render$4]]);
929
- const _sfc_main$8 = {};
930
- const _hoisted_1$7 = {
931
- xmlns: "http://www.w3.org/2000/svg",
932
- class: "baklava-icon",
933
- width: "24",
934
- height: "24",
935
- viewBox: "0 0 24 24",
936
- fill: "none",
937
- stroke: "currentColor",
938
- "stroke-width": "2",
939
- "stroke-linecap": "round",
940
- "stroke-linejoin": "round"
941
- };
942
- function _sfc_render$3(_ctx, _cache) {
943
- return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1$7, [..._cache[0] || (_cache[0] = [
944
- vue.createStaticVNode('<path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M6 2h4v4m-4 0h-1v-1"></path><path d="M15 11v-1h5v4h-2"></path><path d="M5 18h5v4h-5z"></path><path d="M5 10h5v4h-5z"></path><path d="M10 12h2"></path><path d="M7.5 7.5v2.5"></path><path d="M7.5 14v4"></path><path d="M3 3l18 18"></path>', 9)
945
- ])]);
946
- }
947
- const SchemaOff = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$3]]);
948
- const _sfc_main$7 = {};
949
- const _hoisted_1$6 = {
950
- xmlns: "http://www.w3.org/2000/svg",
951
- class: "baklava-icon",
952
- width: "24",
953
- height: "24",
954
- viewBox: "0 0 24 24",
955
- fill: "none",
956
- stroke: "currentColor",
957
- "stroke-width": "2",
958
- "stroke-linecap": "round",
959
- "stroke-linejoin": "round"
960
- };
961
- function _sfc_render$2(_ctx, _cache) {
962
- return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1$6, [..._cache[0] || (_cache[0] = [
963
- vue.createStaticVNode('<path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M3 3l18 18"></path><path d="M4 7h3m4 0h9"></path><path d="M10 11l0 6"></path><path d="M14 14l0 3"></path><path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l.077 -.923"></path><path d="M18.384 14.373l.616 -7.373"></path><path d="M9 5v-1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3"></path>', 8)
964
- ])]);
965
- }
966
- const TrashOff = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["render", _sfc_render$2]]);
967
- const _sfc_main$6 = {};
968
- const _hoisted_1$5 = {
969
- xmlns: "http://www.w3.org/2000/svg",
970
- class: "baklava-icon",
971
- width: "16",
972
- height: "16",
973
- viewBox: "0 0 24 24",
974
- "stroke-width": "2",
975
- stroke: "currentColor",
976
- fill: "none",
977
- "stroke-linecap": "round",
978
- "stroke-linejoin": "round"
979
- };
980
- function _sfc_render$1(_ctx, _cache) {
981
- return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1$5, [..._cache[0] || (_cache[0] = [
982
- vue.createElementVNode("path", {
983
- stroke: "none",
984
- d: "M0 0h24v24H0z",
985
- fill: "none"
986
- }, null, -1),
987
- vue.createElementVNode("circle", {
988
- cx: "12",
989
- cy: "12",
990
- r: "1"
991
- }, null, -1),
992
- vue.createElementVNode("circle", {
993
- cx: "12",
994
- cy: "19",
995
- r: "1"
996
- }, null, -1),
997
- vue.createElementVNode("circle", {
998
- cx: "12",
999
- cy: "5",
1000
- r: "1"
1001
- }, null, -1)
1002
- ])]);
1003
- }
1004
- const VerticalDots = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["render", _sfc_render$1]]);
1005
- const _hoisted_1$4 = ["id", "data-node-type"];
1006
- const _hoisted_2$4 = {
1007
- class: "__title-label",
1008
- style: { "flex-grow": "1" }
1009
- };
1010
- const _hoisted_3$2 = { key: 0 };
1011
- const _hoisted_4$1 = {
1012
- class: "__menu",
1013
- style: { "display": "flex" }
1014
- };
1015
- const _hoisted_5 = { class: "__outputs" };
1016
- const _hoisted_6 = { key: 0 };
1017
- const _hoisted_7 = ["id", "title"];
1018
- const _hoisted_8 = { class: "__inputs" };
1019
- const _hoisted_9 = { key: 0 };
1020
- const _hoisted_10 = ["id", "title"];
1021
- const _sfc_main$5 = /* @__PURE__ */ vue.defineComponent({
1022
- __name: "CodeGraphNode",
1023
- props: {
1024
- node: {},
1025
- selected: { type: Boolean, default: false },
1026
- dragging: { type: Boolean }
1027
- },
1028
- emits: ["select", "start-drag", "update"],
1029
- setup(__props, { emit: __emit }) {
1030
- const ContextMenu = baklavajs.Components.ContextMenu;
1031
- const NodeInterface = baklavajs.Components.NodeInterface;
1032
- const props = __props;
1033
- const node = vue.computed(() => props.node);
1034
- const emit = __emit;
1035
- const { viewModel } = baklavajs.useViewModel();
1036
- const { graph, switchGraph } = baklavajs.useGraph();
1037
- const el = vue.ref(null);
1038
- const renaming = vue.ref(false);
1039
- const tempName = vue.ref("");
1040
- const renameInputEl = vue.ref(null);
1041
- const isResizing = vue.ref(false);
1042
- let resizeStartWidth = 0;
1043
- let resizeStartMouseX = 0;
1044
- const showContextMenu = vue.ref(false);
1045
- const contextMenuItems = vue.computed(() => {
1046
- const items = [
1047
- { value: "edit", label: "Edit" },
1048
- { value: "rename", label: "Rename" },
1049
- { value: "delete", label: "Delete" }
1050
- ];
1051
- if (props.node.type.startsWith(baklavajs.GRAPH_NODE_TYPE_PREFIX)) {
1052
- items.push({ value: "editSubgraph", label: "Edit Subgraph" });
1053
- }
1054
- return items;
1055
- });
1056
- const classes = vue.computed(() => ({
1057
- "--selected": props.selected,
1058
- "--dragging": props.dragging,
1059
- "--two-column": !!props.node.twoColumn,
1060
- "--hidden": node.value.state?.hidden
1061
- }));
1062
- const classesContent = vue.computed(() => ({
1063
- "--reverse-y": props.node.reverseY ?? viewModel.value.settings.nodes.reverseY
1064
- }));
1065
- const styles = vue.computed(() => ({
1066
- "top": `${props.node.position?.y ?? 0}px`,
1067
- "left": `${props.node.position?.x ?? 0}px`,
1068
- "--width": `${props.node.width ?? viewModel.value.settings.nodes.defaultWidth}px`
1069
- }));
1070
- const displayedInputs = vue.computed(() => Object.values(props.node.inputs).filter((ni) => !ni.hidden));
1071
- const displayedOutputs = vue.computed(() => Object.values(props.node.outputs).filter((ni) => !ni.hidden));
1072
- const select = () => {
1073
- emit("select");
1074
- };
1075
- const startDrag = (ev) => {
1076
- if (!props.selected) {
1077
- select();
1078
- }
1079
- emit("start-drag", ev);
1080
- };
1081
- const openContextMenu = () => {
1082
- showContextMenu.value = true;
1083
- };
1084
- const closeSidebar = () => {
1085
- const sidebar = viewModel.value.displayedGraph.sidebar;
1086
- sidebar.nodeId = "";
1087
- sidebar.visible = false;
1088
- };
1089
- const openSidebar = () => {
1090
- const sidebar = viewModel.value.displayedGraph.sidebar;
1091
- sidebar.nodeId = props.node.id;
1092
- sidebar.visible = true;
1093
- };
1094
- const updateSidebar = () => {
1095
- const sidebar = viewModel.value.displayedGraph.sidebar;
1096
- sidebar.nodeId = props.node.id;
1097
- };
1098
- const onContextMenuClick = async (action) => {
1099
- switch (action) {
1100
- case "edit":
1101
- openSidebar();
1102
- break;
1103
- case "delete":
1104
- graph.value.removeNode(props.node);
1105
- break;
1106
- case "rename":
1107
- tempName.value = props.node.title;
1108
- renaming.value = true;
1109
- await vue.nextTick();
1110
- renameInputEl.value?.focus();
1111
- break;
1112
- case "editSubgraph":
1113
- switchGraph(props.node.template);
1114
- break;
1115
- }
1116
- };
1117
- const doneRenaming = () => {
1118
- props.node.title = tempName.value;
1119
- renaming.value = false;
1120
- };
1121
- const onRender = () => {
1122
- if (el.value) {
1123
- viewModel.value.hooks.renderNode.execute({ node: props.node, el: el.value });
1124
- }
1125
- };
1126
- const startResize = (ev) => {
1127
- isResizing.value = true;
1128
- resizeStartWidth = props.node.width;
1129
- resizeStartMouseX = ev.clientX;
1130
- ev.preventDefault();
1131
- };
1132
- const doResize = (ev) => {
1133
- if (!isResizing.value) return;
1134
- const deltaX = ev.clientX - resizeStartMouseX;
1135
- const newWidth = resizeStartWidth + deltaX / graph.value.scaling;
1136
- const minWidth = viewModel.value.settings.nodes.minWidth;
1137
- const maxWidth = viewModel.value.settings.nodes.maxWidth;
1138
- props.node.width = Math.max(minWidth, Math.min(maxWidth, newWidth));
1139
- };
1140
- const stopResize = () => {
1141
- isResizing.value = false;
1142
- };
1143
- vue.onMounted(() => {
1144
- onRender();
1145
- window.addEventListener("mousemove", doResize);
1146
- window.addEventListener("mouseup", stopResize);
1147
- });
1148
- vue.onUpdated(onRender);
1149
- vue.onBeforeUnmount(() => {
1150
- window.removeEventListener("mousemove", doResize);
1151
- window.removeEventListener("mouseup", stopResize);
1152
- });
1153
- return (_ctx, _cache) => {
1154
- return vue.openBlock(), vue.createElementBlock("div", {
1155
- id: node.value.id,
1156
- ref_key: "el",
1157
- ref: el,
1158
- class: vue.normalizeClass([classes.value, "baklava-node"]),
1159
- "data-node-type": node.value.type,
1160
- style: vue.normalizeStyle(styles.value),
1161
- onPointerdown: select
1162
- }, [
1163
- vue.unref(viewModel).settings.nodes.resizable ? (vue.openBlock(), vue.createElementBlock("div", {
1164
- key: 0,
1165
- class: "__resize-handle",
1166
- onMousedown: startResize
1167
- }, null, 32)) : vue.createCommentVNode("", true),
1168
- vue.createElementVNode("div", {
1169
- class: "__title",
1170
- onPointerdown: vue.withModifiers(startDrag, ["self", "stop"]),
1171
- onContextmenu: vue.withModifiers(openContextMenu, ["prevent"])
1172
- }, [
1173
- node.value.inputs._node ? (vue.openBlock(), vue.createBlock(_sfc_main$f, {
1174
- key: 0,
1175
- node: node.value,
1176
- intf: node.value.inputs._node,
1177
- class: "--input",
1178
- "data-interface-type": "node",
1179
- style: { "flex-grow": "0" }
1180
- }, null, 8, ["node", "intf"])) : vue.createCommentVNode("", true),
1181
- !renaming.value ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 1 }, [
1182
- vue.createElementVNode("div", _hoisted_2$4, [
1183
- node.value.idx > -1 ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_3$2, vue.toDisplayString(node.value.idx + 1) + " - ", 1)) : vue.createCommentVNode("", true),
1184
- vue.createTextVNode(vue.toDisplayString(node.value.title) + " (" + vue.toDisplayString(node.value.shortId) + ") ", 1)
1185
- ]),
1186
- vue.createElementVNode("div", _hoisted_4$1, [
1187
- !node.value.subgraph ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 0 }, [
1188
- !vue.unref(viewModel).displayedGraph.sidebar.visible && vue.unref(viewModel).displayedGraph.sidebar.nodeId !== node.value.id ? (vue.openBlock(), vue.createBlock(vue.unref(LayoutSidebarRightExpand), {
1189
- key: 0,
1190
- class: "--clickable mx-1",
1191
- onClick: openSidebar
1192
- })) : vue.unref(viewModel).displayedGraph.sidebar.visible && vue.unref(viewModel).displayedGraph.sidebar.nodeId !== node.value.id ? (vue.openBlock(), vue.createBlock(vue.unref(LayoutSidebarRight), {
1193
- key: 1,
1194
- class: "--clickable mx-1",
1195
- onClick: updateSidebar
1196
- })) : (vue.openBlock(), vue.createBlock(vue.unref(LayoutSidebarRightCollapse), {
1197
- key: 2,
1198
- class: "--clickable mx-1",
1199
- onClick: closeSidebar
1200
- }))
1201
- ], 64)) : vue.createCommentVNode("", true),
1202
- vue.createVNode(vue.unref(VerticalDots), {
1203
- class: "--clickable mx-1",
1204
- onClick: openContextMenu
1205
- }),
1206
- vue.createVNode(vue.unref(ContextMenu), {
1207
- modelValue: showContextMenu.value,
1208
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => showContextMenu.value = $event),
1209
- x: 0,
1210
- y: 0,
1211
- items: contextMenuItems.value,
1212
- onClick: onContextMenuClick
1213
- }, null, 8, ["modelValue", "items"])
1214
- ])
1215
- ], 64)) : vue.withDirectives((vue.openBlock(), vue.createElementBlock("input", {
1216
- key: 2,
1217
- ref_key: "renameInputEl",
1218
- ref: renameInputEl,
1219
- "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => tempName.value = $event),
1220
- class: "baklava-input",
1221
- placeholder: "Node Name",
1222
- style: { "flex-grow": "1" },
1223
- type: "text",
1224
- onBlur: doneRenaming,
1225
- onKeydown: vue.withKeys(doneRenaming, ["enter"])
1226
- }, null, 544)), [
1227
- [vue.vModelText, tempName.value]
1228
- ]),
1229
- node.value.outputs._node ? (vue.openBlock(), vue.createBlock(_sfc_main$f, {
1230
- key: 3,
1231
- node: node.value,
1232
- intf: node.value.outputs._node,
1233
- class: "--output",
1234
- "data-interface-type": "node"
1235
- }, null, 8, ["node", "intf"])) : vue.createCommentVNode("", true)
1236
- ], 32),
1237
- vue.createElementVNode("div", {
1238
- class: vue.normalizeClass(["__content", classesContent.value]),
1239
- onKeydown: _cache[2] || (_cache[2] = vue.withKeys(vue.withModifiers(() => {
1240
- }, ["stop"]), ["delete"])),
1241
- onContextmenu: _cache[3] || (_cache[3] = vue.withModifiers(() => {
1242
- }, ["prevent"]))
1243
- }, [
1244
- vue.createElementVNode("div", _hoisted_5, [
1245
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(displayedOutputs.value, (output) => {
1246
- return vue.openBlock(), vue.createElementBlock(vue.Fragment, {
1247
- key: output.id
1248
- }, [
1249
- node.value.state?.hidden ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_6, [
1250
- output.port ? (vue.openBlock(), vue.createElementBlock("div", {
1251
- key: 0,
1252
- id: output.id,
1253
- title: output.name,
1254
- class: "baklava-node-interface --output --connected"
1255
- }, [..._cache[4] || (_cache[4] = [
1256
- vue.createElementVNode("div", { class: "__port" }, null, -1)
1257
- ])], 8, _hoisted_7)) : vue.createCommentVNode("", true)
1258
- ])) : vue.renderSlot(_ctx.$slots, "nodeInterface", {
1259
- key: 1,
1260
- type: "output",
1261
- node: node.value,
1262
- intf: output
1263
- }, () => [
1264
- vue.createVNode(vue.unref(NodeInterface), {
1265
- node: node.value,
1266
- intf: output
1267
- }, null, 8, ["node", "intf"])
1268
- ])
1269
- ], 64);
1270
- }), 128))
1271
- ]),
1272
- vue.createElementVNode("div", _hoisted_8, [
1273
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(displayedInputs.value, (input) => {
1274
- return vue.openBlock(), vue.createElementBlock(vue.Fragment, {
1275
- key: input.id
1276
- }, [
1277
- node.value.state?.hidden ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_9, [
1278
- input.port ? (vue.openBlock(), vue.createElementBlock("div", {
1279
- key: 0,
1280
- id: input.id,
1281
- title: input.name,
1282
- class: "baklava-node-interface --input --connected"
1283
- }, [..._cache[5] || (_cache[5] = [
1284
- vue.createElementVNode("div", { class: "__port" }, null, -1)
1285
- ])], 8, _hoisted_10)) : vue.createCommentVNode("", true)
1286
- ])) : vue.renderSlot(_ctx.$slots, "nodeInterface", {
1287
- key: 1,
1288
- node: node.value,
1289
- intf: input,
1290
- type: "input"
1291
- }, () => [
1292
- vue.createVNode(vue.unref(NodeInterface), {
1293
- node: node.value,
1294
- intf: input,
1295
- title: input.name
1296
- }, null, 8, ["node", "intf", "title"])
1297
- ])
1298
- ], 64);
1299
- }), 128))
1300
- ])
1301
- ], 34)
1302
- ], 46, _hoisted_1$4);
1303
- };
1304
- }
1305
- });
1306
- const _hoisted_1$3 = ["title"];
1307
- const _hoisted_2$3 = {
1308
- key: 0,
1309
- class: "__label"
1310
- };
1311
- const _sfc_main$4 = /* @__PURE__ */ vue.defineComponent({
1312
- __name: "Checkbox",
1313
- props: {
1314
- modelValue: { type: Boolean },
1315
- inversed: { type: Boolean },
1316
- name: {}
1317
- },
1318
- emits: ["update:modelValue"],
1319
- setup(__props, { emit: __emit }) {
1320
- const emit = __emit;
1321
- return (_ctx, _cache) => {
1322
- return vue.openBlock(), vue.createElementBlock("div", {
1323
- class: vue.normalizeClass(["baklava-checkbox", { "--checked": _ctx.inversed ? !_ctx.modelValue : _ctx.modelValue }]),
1324
- title: _ctx.name,
1325
- onClick: _cache[0] || (_cache[0] = ($event) => emit("update:modelValue", !_ctx.modelValue))
1326
- }, [
1327
- _cache[1] || (_cache[1] = vue.createElementVNode("div", { class: "__checkmark-container" }, [
1328
- vue.createElementVNode("svg", {
1329
- xmlns: "http://www.w3.org/2000/svg",
1330
- width: "18",
1331
- height: "18",
1332
- viewBox: "0 0 18 18"
1333
- }, [
1334
- vue.createElementVNode("path", {
1335
- class: "__checkmark",
1336
- d: "M 6 5 L 6 10 L 16 10",
1337
- transform: "rotate(-45 10 10)"
1338
- })
1339
- ])
1340
- ], -1)),
1341
- _ctx.name ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$3, vue.toDisplayString(_ctx.name), 1)) : vue.createCommentVNode("", true)
1342
- ], 10, _hoisted_1$3);
1343
- };
1344
- }
1345
- });
1346
- const _hoisted_1$2 = { class: "__header" };
1347
- const _hoisted_2$2 = { class: "__node-name" };
1348
- const _hoisted_3$1 = { style: { "display": "flex" } };
1349
- const _hoisted_4 = {
1350
- key: 1,
1351
- class: "__interface"
1352
- };
1353
- const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
1354
- __name: "CodeGraphSidebar",
1355
- setup(__props) {
1356
- const { viewModel } = baklavajs.useViewModel();
1357
- const { graph } = baklavajs.useGraph();
1358
- const el = vue.ref(null);
1359
- const width = vue.toRef(viewModel.value.settings.sidebar, "width");
1360
- const resizable = vue.computed(() => viewModel.value.settings.sidebar.resizable);
1361
- let resizeStartWidth = 0;
1362
- let resizeStartMouseX = 0;
1363
- const node = vue.computed(() => {
1364
- const id = graph.value.sidebar.nodeId;
1365
- return graph.value.nodes.find((x) => x.id === id);
1366
- });
1367
- const codeNode = vue.computed(() => node.value);
1368
- const styles = vue.computed(() => ({
1369
- width: `${width.value}px`
1370
- }));
1371
- const displayedInterfaces = vue.computed(() => {
1372
- if (!node.value) return [];
1373
- const allIntfs = [...Object.values(node.value.inputs), ...Object.values(node.value.outputs)];
1374
- return allIntfs.filter((intf) => intf.displayInSidebar && intf.component);
1375
- });
1376
- const close = () => {
1377
- graph.value.sidebar.visible = false;
1378
- };
1379
- const doneRenaming = () => {
1380
- node.value?.events.update.emit(null);
1381
- };
1382
- const startResize = (event) => {
1383
- resizeStartWidth = width.value;
1384
- resizeStartMouseX = event.clientX;
1385
- window.addEventListener("mousemove", onMouseMove);
1386
- window.addEventListener(
1387
- "mouseup",
1388
- () => {
1389
- window.removeEventListener("mousemove", onMouseMove);
1390
- },
1391
- { once: true }
1392
- );
1393
- };
1394
- const onMouseMove = (event) => {
1395
- const maxwidth = el.value?.parentElement?.getBoundingClientRect().width ?? 500;
1396
- const deltaX = event.clientX - resizeStartMouseX;
1397
- let newWidth = resizeStartWidth - deltaX;
1398
- if (newWidth < 300) {
1399
- newWidth = 300;
1400
- } else if (newWidth > 0.9 * maxwidth) {
1401
- newWidth = 0.9 * maxwidth;
1402
- }
1403
- width.value = newWidth;
1404
- };
1405
- return (_ctx, _cache) => {
1406
- return vue.openBlock(), vue.createElementBlock("div", {
1407
- ref_key: "el",
1408
- ref: el,
1409
- class: vue.normalizeClass(["baklava-sidebar", { "--open": vue.unref(graph).sidebar.visible }]),
1410
- style: vue.normalizeStyle(styles.value)
1411
- }, [
1412
- resizable.value ? (vue.openBlock(), vue.createElementBlock("div", {
1413
- key: 0,
1414
- class: "__resizer",
1415
- onMousedown: startResize
1416
- }, null, 32)) : vue.createCommentVNode("", true),
1417
- vue.createElementVNode("div", _hoisted_1$2, [
1418
- vue.createElementVNode("button", {
1419
- tabindex: "-1",
1420
- class: "__close",
1421
- onClick: close
1422
- }, "×"),
1423
- vue.createElementVNode("div", _hoisted_2$2, [
1424
- vue.createElementVNode("b", null, vue.toDisplayString(node.value ? node.value.title : ""), 1)
1425
- ])
1426
- ]),
1427
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(displayedInterfaces.value, (intf) => {
1428
- return vue.openBlock(), vue.createElementBlock("div", {
1429
- key: intf.id,
1430
- class: "__interface"
1431
- }, [
1432
- vue.createElementVNode("div", _hoisted_3$1, [
1433
- vue.createVNode(_sfc_main$4, {
1434
- modelValue: intf.hidden,
1435
- "onUpdate:modelValue": [
1436
- ($event) => intf.hidden = $event,
1437
- _cache[0] || (_cache[0] = () => node.value?.events.update.emit(null))
1438
- ],
1439
- inversed: "",
1440
- style: { "margin-right": "8px" }
1441
- }, null, 8, ["modelValue", "onUpdate:modelValue"]),
1442
- (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(intf.component), {
1443
- modelValue: intf.value,
1444
- "onUpdate:modelValue": ($event) => intf.value = $event,
1445
- node: node.value,
1446
- intf,
1447
- style: { "width": "100%" }
1448
- }, null, 8, ["modelValue", "onUpdate:modelValue", "node", "intf"]))
1449
- ])
1450
- ]);
1451
- }), 128)),
1452
- codeNode.value && codeNode.value.state ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_4, [
1453
- _cache[2] || (_cache[2] = vue.createElementVNode("label", null, "Variable name", -1)),
1454
- vue.withDirectives(vue.createElementVNode("input", {
1455
- "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => codeNode.value.state.variableName = $event),
1456
- type: "text",
1457
- class: "baklava-input",
1458
- title: "Variable name",
1459
- onBlur: doneRenaming,
1460
- onKeydown: vue.withKeys(doneRenaming, ["enter"])
1461
- }, null, 544), [
1462
- [vue.vModelText, codeNode.value.state.variableName]
1463
- ])
1464
- ])) : vue.createCommentVNode("", true)
1465
- ], 6);
1466
- };
1467
- }
1468
- });
1469
- const _sfc_main$2 = vue.defineComponent({
1470
- props: {
1471
- type: {
1472
- type: String,
1473
- required: true
1474
- },
1475
- title: {
1476
- type: String,
1477
- required: true
1478
- }
1479
- },
1480
- setup(props) {
1481
- const { viewModel } = baklavajs.useViewModel();
1482
- const { switchGraph } = baklavajs.useGraph();
1483
- const showContextMenu = vue.ref(false);
1484
- const hasContextMenu = vue.computed(() => props.type.startsWith(baklavajs.GRAPH_NODE_TYPE_PREFIX));
1485
- const contextMenuItems = [
1486
- { label: "Edit Subgraph", value: "editSubgraph" },
1487
- { label: "Delete Subgraph", value: "deleteSubgraph" }
1488
- ];
1489
- const openContextMenu = () => {
1490
- showContextMenu.value = true;
1491
- };
1492
- const onContextMenuClick = (action) => {
1493
- const graphTemplateId = props.type.substring(baklavajs.GRAPH_NODE_TYPE_PREFIX.length);
1494
- const graphTemplate = viewModel.value.editor.graphTemplates.find((gt) => gt.id === graphTemplateId);
1495
- if (!graphTemplate) {
1496
- return;
1497
- }
1498
- switch (action) {
1499
- case "editSubgraph":
1500
- switchGraph(graphTemplate);
1501
- break;
1502
- case "deleteSubgraph":
1503
- viewModel.value.editor.removeGraphTemplate(graphTemplate);
1504
- break;
1505
- }
1506
- };
1507
- return { showContextMenu, hasContextMenu, contextMenuItems, openContextMenu, onContextMenuClick };
1508
- }
1509
- });
1510
- const _hoisted_1$1 = ["data-node-type"];
1511
- const _hoisted_2$1 = { class: "__title" };
1512
- const _hoisted_3 = { class: "__title-label" };
1513
- function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
1514
- return vue.openBlock(), vue.createElementBlock("div", {
1515
- class: "baklava-node --palette",
1516
- "data-node-type": _ctx.type
1517
- }, [
1518
- vue.createElementVNode("div", _hoisted_2$1, [
1519
- vue.createElementVNode("div", _hoisted_3, vue.toDisplayString(_ctx.title), 1)
1520
- ])
1521
- ], 8, _hoisted_1$1);
1522
- }
1523
- const PaletteEntry = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["render", _sfc_render]]);
1524
- const _hoisted_1 = {
1525
- class: "baklava-node --palette",
1526
- style: { "margin-top": "-20px", "margin-bottom": "30px" }
1527
- };
1528
- const _hoisted_2 = { key: 0 };
1529
- const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
1530
- __name: "CodeNodePalette",
1531
- setup(__props) {
1532
- const { viewModel } = baklavajs.useViewModel();
1533
- const { x: mouseX, y: mouseY } = core.usePointer();
1534
- const { transform } = baklavajs.useTransform();
1535
- const categories = baklavajs.useNodeCategories(viewModel);
1536
- const editorEl = vue.inject("editorEl");
1537
- const searchQuery = vue.ref("");
1538
- const draggedNode = vue.ref(null);
1539
- const filterCategoryBySearch = (categories2) => {
1540
- if (searchQuery.value) {
1541
- return categories2.filter(
1542
- (c) => Object.values(c.nodeTypes).some(
1543
- (nodeType2) => nodeType2.title.toLowerCase().includes(searchQuery.value?.toLowerCase())
1544
- )
1545
- );
1546
- }
1547
- return categories2;
1548
- };
1549
- const filterNodesBySearch = (nodeTypes) => {
1550
- if (searchQuery.value) {
1551
- return Object.values(nodeTypes).filter(
1552
- (nt) => nt.title.toLowerCase().includes(searchQuery.value?.toLowerCase())
1553
- );
1554
- }
1555
- return Object.values(nodeTypes);
1556
- };
1557
- const draggedNodeStyles = vue.computed(() => {
1558
- if (!draggedNode.value || !editorEl?.value) return {};
1559
- const { left, top } = editorEl.value.getBoundingClientRect();
1560
- return {
1561
- top: `${mouseY.value - top}px`,
1562
- left: `${mouseX.value - left}px`
1563
- };
1564
- });
1565
- const onDragStart = (type, nodeInformation) => {
1566
- draggedNode.value = {
1567
- type,
1568
- nodeInformation
1569
- };
1570
- const onDragEnd = () => {
1571
- const instance = vue.reactive(new nodeInformation.type());
1572
- viewModel.value.displayedGraph.addNode(instance);
1573
- const rect = editorEl.value.getBoundingClientRect();
1574
- const [x, y] = transform(mouseX.value - rect.left, mouseY.value - rect.top);
1575
- instance.position.x = x;
1576
- instance.position.y = y;
1577
- draggedNode.value = null;
1578
- document.removeEventListener("pointerup", onDragEnd);
1579
- };
1580
- document.addEventListener("pointerup", onDragEnd);
1581
- };
1582
- return (_ctx, _cache) => {
1583
- return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [
1584
- vue.createElementVNode("div", {
1585
- class: vue.normalizeClass(["baklava-node-palette", { "--open": vue.unref(viewModel).settings.palette.enabled }]),
1586
- onContextmenu: _cache[1] || (_cache[1] = vue.withModifiers(() => {
1587
- }, ["stop", "prevent"]))
1588
- }, [
1589
- vue.createElementVNode("div", _hoisted_1, [
1590
- vue.withDirectives(vue.createElementVNode("input", {
1591
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => searchQuery.value = $event),
1592
- type: "text",
1593
- class: "baklava-input",
1594
- title: "Filter node types"
1595
- }, null, 512), [
1596
- [vue.vModelText, searchQuery.value]
1597
- ])
1598
- ]),
1599
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(filterCategoryBySearch(vue.unref(categories)), (c) => {
1600
- return vue.openBlock(), vue.createElementBlock("section", {
1601
- key: c.name
1602
- }, [
1603
- c.name !== "default" ? (vue.openBlock(), vue.createElementBlock("h3", _hoisted_2, vue.toDisplayString(c.name), 1)) : vue.createCommentVNode("", true),
1604
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(filterNodesBySearch(c.nodeTypes), (ni, nt) => {
1605
- return vue.openBlock(), vue.createBlock(PaletteEntry, {
1606
- key: nt,
1607
- type: nt,
1608
- title: ni.title,
1609
- onPointerdown: ($event) => onDragStart(nt, ni)
1610
- }, null, 8, ["type", "title", "onPointerdown"]);
1611
- }), 128))
1612
- ]);
1613
- }), 128))
1614
- ], 34),
1615
- vue.createVNode(vue.Transition, { name: "fade" }, {
1616
- default: vue.withCtx(() => [
1617
- draggedNode.value ? (vue.openBlock(), vue.createElementBlock("div", {
1618
- key: 0,
1619
- class: "baklava-dragged-node",
1620
- style: vue.normalizeStyle(draggedNodeStyles.value)
1621
- }, [
1622
- vue.createVNode(PaletteEntry, {
1623
- type: draggedNode.value.type,
1624
- title: draggedNode.value.nodeInformation.title
1625
- }, null, 8, ["type", "title"])
1626
- ], 4)) : vue.createCommentVNode("", true)
1627
- ]),
1628
- _: 1
1629
- })
1630
- ], 64);
1631
- };
1632
- }
1633
- });
1634
- const _sfc_main = /* @__PURE__ */ vue.defineComponent({
1635
- __name: "CodeGraphEditor",
1636
- props: {
1637
- viewModel: {}
1638
- },
1639
- setup(__props) {
1640
- const props = __props;
1641
- const viewModel = vue.toRef(props, "viewModel");
1642
- const onUpdate = (node) => node.events.update.emit(null);
1643
- vue.onMounted(() => {
1644
- viewModel.value.subscribe();
1645
- viewModel.value.engine.start();
1646
- });
1647
- vue.onUnmounted(() => {
1648
- viewModel.value.unsubscribe();
1649
- viewModel.value.engine.stop();
1650
- });
1651
- return (_ctx, _cache) => {
1652
- return vue.openBlock(), vue.createBlock(vue.unref(baklavajs.BaklavaEditor), { "view-model": viewModel.value }, {
1653
- palette: vue.withCtx(() => [
1654
- vue.createVNode(_sfc_main$1)
1655
- ]),
1656
- node: vue.withCtx((nodeProps) => [
1657
- vue.createVNode(_sfc_main$5, vue.mergeProps(nodeProps, {
1658
- onUpdate: ($event) => onUpdate(nodeProps.node)
1659
- }), null, 16, ["onUpdate"])
1660
- ]),
1661
- sidebar: vue.withCtx((nodeProps) => [
1662
- vue.createVNode(_sfc_main$3, vue.normalizeProps(vue.guardReactiveProps(nodeProps)), null, 16)
1663
- ]),
1664
- _: 1
1665
- }, 8, ["view-model"]);
1666
- };
1667
- }
1668
- });
1669
- const addToolbarCommands = (viewModel) => {
1670
- const TOGGLE_PALETTE_COMMAND = "TOGGLE_PALETTE";
1671
- viewModel.commandHandler.registerCommand(TOGGLE_PALETTE_COMMAND, {
1672
- execute: () => viewModel.settings.palette.enabled = !viewModel.settings.palette.enabled,
1673
- canExecute: () => true
1674
- });
1675
- const CLEAR_ALL_COMMAND = "CLEAR_ALL";
1676
- viewModel.commandHandler.registerCommand(CLEAR_ALL_COMMAND, {
1677
- execute: () => viewModel.displayedGraph.nodes.forEach((node) => viewModel.displayedGraph.removeNode(node)),
1678
- canExecute: () => viewModel.displayedGraph.nodes.length > 0
1679
- });
1680
- const TOGGLE_MINIMAP_COMMAND = "TOGGLE_MINIMAP";
1681
- viewModel.commandHandler.registerCommand(TOGGLE_MINIMAP_COMMAND, {
1682
- execute: () => viewModel.settings.enableMinimap = !viewModel.settings.enableMinimap,
1683
- canExecute: () => viewModel.displayedGraph.nodes.length > 1
1684
- });
1685
- viewModel.settings.toolbar.commands = [
1686
- {
1687
- command: TOGGLE_PALETTE_COMMAND,
1688
- title: "Toggle palette",
1689
- // Tooltip text
1690
- icon: vue.computed(() => viewModel.settings.palette.enabled ? LayoutSidebarLeftCollapse : LayoutSidebarLeftExpand)
1691
- },
1692
- ...baklavajs.DEFAULT_TOOLBAR_COMMANDS,
1693
- {
1694
- command: CLEAR_ALL_COMMAND,
1695
- title: "Clear all",
1696
- // Tooltip text
1697
- icon: TrashOff
1698
- },
1699
- {
1700
- command: TOGGLE_MINIMAP_COMMAND,
1701
- title: "Toggle minimap",
1702
- // Tooltip text
1703
- icon: vue.computed(() => viewModel.settings.enableMinimap ? SchemaOff : Schema)
1704
- }
1705
- ];
1706
- };
1707
- const DEFAULT_SETTINGS = {
1708
- enableMinimap: false,
1709
- toolbar: {
1710
- enabled: true
1711
- },
1712
- palette: {
1713
- enabled: true
1714
- },
1715
- sidebar: {
1716
- enabled: true,
1717
- resizable: true,
1718
- width: 350
1719
- },
1720
- displayValueOnHover: false
1721
- };
1722
- function useCodeGraph(props) {
1723
- const viewModel = baklavajs.useBaklava(props?.existingEditor);
1724
- viewModel.code = props?.code ? new props.code(viewModel) : new Code(viewModel);
1725
- addToolbarCommands(viewModel);
1726
- const settings = {};
1727
- Object.keys(DEFAULT_SETTINGS).forEach((K) => {
1728
- settings[K] = typeof DEFAULT_SETTINGS[K] === "object" ? { ...viewModel.settings[K], ...DEFAULT_SETTINGS[K] } : DEFAULT_SETTINGS[K];
1729
- });
1730
- viewModel.settings = vue.reactive({ ...viewModel.settings, ...settings });
1731
- viewModel.settings.nodes.defaultWidth = 350;
1732
- viewModel.state = vue.reactive({
1733
- modules: {},
1734
- token: null
1735
- });
1736
- viewModel.engine = new baklavajs.DependencyEngine(viewModel.editor);
1737
- viewModel.subscribe = () => {
1738
- if (viewModel.state.token) viewModel.unsubscribe();
1739
- const token = Symbol();
1740
- viewModel.displayedGraph.events.addNode.subscribe(token, (node) => node.code = viewModel.code);
1741
- viewModel.engine.events.beforeRun.subscribe(token, () => {
1742
- viewModel.engine.pause();
1743
- if (viewModel.code) {
1744
- viewModel.code.onCodeUpdate();
1745
- viewModel.code.sortNodes();
1746
- viewModel.code.updateOutputVariableNames();
1747
- }
1748
- viewModel.engine.resume();
1749
- });
1750
- viewModel.engine.events.afterRun.subscribe(token, (result) => {
1751
- viewModel.engine.pause();
1752
- baklavajs.applyResult(result, viewModel.editor);
1753
- transferCodeScript(viewModel.displayedGraph);
1754
- if (viewModel.code) {
1755
- viewModel.code.renderNodeCodes();
1756
- viewModel.code.renderCode();
1757
- }
1758
- viewModel.engine.resume();
1759
- });
1760
- viewModel.state.token = token;
1761
- };
1762
- viewModel.unsubscribe = () => {
1763
- if (!viewModel.state.token) return;
1764
- const token = viewModel.state.token;
1765
- viewModel.displayedGraph.events.addNode.unsubscribe(token);
1766
- viewModel.engine.events.beforeRun.unsubscribe(token);
1767
- viewModel.engine.events.afterRun.unsubscribe(token);
1768
- viewModel.state.token = null;
1769
- };
1770
- return viewModel;
1771
- }
1772
- Object.defineProperty(exports2, "ButtonInterfaceComponent", {
1773
- enumerable: true,
1774
- get: () => baklavajs.ButtonInterfaceComponent
1775
- });
1776
- Object.defineProperty(exports2, "CheckboxInterfaceComponent", {
1777
- enumerable: true,
1778
- get: () => baklavajs.CheckboxInterfaceComponent
1779
- });
1780
- Object.defineProperty(exports2, "IntegerInterfaceComponent", {
1781
- enumerable: true,
1782
- get: () => baklavajs.IntegerInterfaceComponent
1783
- });
1784
- Object.defineProperty(exports2, "NumberInterfaceComponent", {
1785
- enumerable: true,
1786
- get: () => baklavajs.NumberInterfaceComponent
1787
- });
1788
- Object.defineProperty(exports2, "SelectInterfaceComponent", {
1789
- enumerable: true,
1790
- get: () => baklavajs.SelectInterfaceComponent
1791
- });
1792
- Object.defineProperty(exports2, "SliderInterfaceComponent", {
1793
- enumerable: true,
1794
- get: () => baklavajs.SliderInterfaceComponent
1795
- });
1796
- Object.defineProperty(exports2, "TextInputInterfaceComponent", {
1797
- enumerable: true,
1798
- get: () => baklavajs.TextInputInterfaceComponent
1799
- });
1800
- Object.defineProperty(exports2, "TextareaInputInterfaceComponent", {
1801
- enumerable: true,
1802
- get: () => baklavajs.TextareaInputInterfaceComponent
1803
- });
1804
- exports2.AbstractCodeNode = AbstractCodeNode;
1805
- exports2.ButtonInterface = ButtonInterface;
1806
- exports2.CheckboxInterface = CheckboxInterface;
1807
- exports2.Code = Code;
1808
- exports2.CodeGraphEditor = _sfc_main;
1809
- exports2.CodeInputInterface = CodeInputInterface;
1810
- exports2.CodeNode = CodeNode;
1811
- exports2.CodeNodeInterface = CodeNodeInterface;
1812
- exports2.CodeOutputInterface = CodeOutputInterface;
1813
- exports2.DEFAULT_SETTINGS = DEFAULT_SETTINGS;
1814
- exports2.DynamicCodeNode = DynamicCodeNode;
1815
- exports2.IntegerInterface = IntegerInterface;
1816
- exports2.NumberInterface = NumberInterface;
1817
- exports2.SelectInterface = SelectInterface;
1818
- exports2.SliderInterface = SliderInterface;
1819
- exports2.TextInputInterface = TextInputInterface;
1820
- exports2.TextInterface = TextInterface;
1821
- exports2.TextareaInputInterface = TextareaInputInterface;
1822
- exports2.addToolbarCommands = addToolbarCommands;
1823
- exports2.defineCodeNode = defineCodeNode;
1824
- exports2.defineDynamicCodeNode = defineDynamicCodeNode;
1825
- exports2.getCodeNodes = getCodeNodes;
1826
- exports2.getPositionAtColumn = getPositionAtColumn;
1827
- exports2.getPositionBeforeNode = getPositionBeforeNode;
1828
- exports2.loadNodeState = loadNodeState;
1829
- exports2.saveNodeState = saveNodeState;
1830
- exports2.transferCodeScript = transferCodeScript;
1831
- exports2.useCodeGraph = useCodeGraph;
1832
- Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
1833
- }));
1
+ (function(l,i){typeof exports=="object"&&typeof module<"u"?i(exports,require("baklavajs"),require("mustache"),require("vue"),require("toposort"),require("uuid"),require("@vueuse/core")):typeof define=="function"&&define.amd?define(["exports","baklavajs","mustache","vue","toposort","uuid","@vueuse/core"],i):(l=typeof globalThis<"u"?globalThis:l||self,i(l["@babsey/code-graph"]={},l.baklavajs,l.mustache,l.Vue,l.toposort,l.uuid,l["@vueuse/core"]))})(this,(function(l,i,v,e,Z,j,ee){"use strict";class R extends i.AbstractNode{state;code;isCodeNode=!0;inputs={};outputs={};constructor(){super(),this.initializeIo(),this.width=400,this.twoColumn=!0,this.state=e.reactive({codeTemplate:"{{ &outputs.code }}",hidden:!1,integrated:!1,modules:[],script:"",variableName:""})}get codeTemplate(){return this.state.codeTemplate}get idx(){return this.code?.codeNodes.filter(t=>!t.state.integrated).indexOf(this)??-1}get idxByVariableNames(){return this.code?.getNodesBySameVariableNames(this.state.variableName).indexOf(this)??-1}get script(){return this.state.script}get shortId(){return this.id.slice(0,6)}get variableName(){return this.state.variableName?this.state.variableName+(this.idxByVariableNames+1):""}getConnectedNodes(t){let n=[];if(t!=="inputs"){const o=this.graph?.connections.filter(s=>s.from.name!=="_node").filter(s=>s.from.nodeId===this.id).map(s=>s.to.nodeId);o&&(n=n.concat(o))}if(t!=="outputs"){const o=this.graph?.connections.filter(s=>s.from.name!=="_node").filter(s=>s.to.nodeId===this.id).map(s=>s.from.nodeId);o&&(n=n.concat(o))}return!n||n.length==0?[]:n.map(o=>this.graph?.findNodeById(o))}registerCode(t){this.code=t}renderCode(){const t={};Object.keys(this.inputs).forEach(o=>{if(o==="_node")return;const s=this.inputs[o],r=s.isString?`'${s.value}'`:s.value;s&&s.state&&(t[o]=s.state.script.length>0?s.state.script:r)});const n={};Object.keys(this.outputs).forEach(o=>{if(o==="_node")return;const s=this.outputs[o],r=s.isString?`'${s.value}'`:s.value;s&&s.state&&(n[o]=r)}),this.state.script=v.render(this.state.codeTemplate,{inputs:t,outputs:n}),this.outputs.code&&(this.outputs.code.state.script=this.state.script)}updateOutputVariableName(){this.outputs.code&&(this.outputs.code.name=this.variableName)}}class O extends R{calculate;load(t){super.load(t),S(this.graph,t)}save(){const t=super.save();return L(this.graph,t),t}updateModules(t){if(t)this.state.modules=t;else if(this.type.includes(".")){const n=this.type.split(".");this.state.modules.push(n.slice(0,n.length-1).join("."))}}}const S=(a,t)=>{if(!a)return;const n=a.findNodeById(t.id);if(!n||n.subgraph)return;const o=n;o.state&&(o.state.integrated=t.integrated,o.state.modules=t.modules,o.state.props=t.props),Object.entries(t.inputs).forEach(([s,r])=>{s!=="_node"&&o.inputs[s]&&(o.inputs[s].hidden=r.hidden)}),Object.entries(t.outputs).forEach(([s,r])=>{s!=="_node"&&o.outputs[s]&&(o.outputs[s].hidden=r.hidden)})},L=(a,t)=>{if(!a)return;const n=a.findNodeById(t.id);if(!n||n.subgraph)return;const o=n;o.state&&(t.integrated=o.state.integrated,t.modules=o.state.modules),Object.entries(t.inputs).forEach(([s,r])=>{s!=="_node"&&o.inputs[s]&&(r.hidden=o.inputs[s].hidden)}),Object.entries(t.outputs).forEach(([s,r])=>{s!=="_node"&&o.outputs[s]&&(r.hidden=o.outputs[s].hidden)})};new i.NodeInterfaceType("boolean"),new i.NodeInterfaceType("dict"),new i.NodeInterfaceType("list");const M=new i.NodeInterfaceType("node"),te=new i.NodeInterfaceType("number"),ne=new i.NodeInterfaceType("string"),oe=["title"],$=e.defineComponent({__name:"CodeNodeInterface",props:{intf:{}},setup(a){return(t,n)=>(e.openBlock(),e.createElementBlock("div",{title:t.intf.state?.script},e.toDisplayString(t.intf.name),9,oe))}});class C extends i.NodeInterface{optional=!1;code;state;constructor(t,n){super(t,n),this.setComponent(e.markRaw($)),this.state=e.reactive({script:""})}get shortId(){return this.id.slice(0,6)}}class se extends C{component=e.markRaw(i.ButtonInterfaceComponent);callback;constructor(t,n){super(t,void 0),this.callback=n,this.setPort(!1)}}class ae extends C{component=e.markRaw(i.CheckboxInterfaceComponent)}class z extends C{min;max;constructor(t,n,o,s){super(t,n),this.min=o,this.max=s}validate(t){return(this.min===void 0||t>=this.min)&&(this.max===void 0||t<=this.max)}}class re extends z{component=e.markRaw(i.IntegerInterfaceComponent);validate(t){return Number.isInteger(t)&&super.validate(t)}}class ie extends C{isCodeInput=!0;constructor(t="",n){super(t,n),this.setComponent(e.markRaw($))}}class P extends C{isCodeOutput=!0;constructor(t="",n=""){super(t,n),this.setComponent(e.markRaw($))}get script(){return this.state.script}get value(){return super.value}set value(t){super.value=t,this.state.script=this.name.length>0?this.name:this.value}}class le extends z{component=e.markRaw(i.NumberInterfaceComponent)}class de extends C{component=e.markRaw(i.SelectInterfaceComponent);items;constructor(t,n,o){super(t,n),this.items=o}}class ce extends z{component=e.markRaw(i.SliderInterfaceComponent);min;max;constructor(t,n,o,s){super(t,n,o,s),this.min=o,this.max=s}}class pe extends C{component=e.markRaw(i.TextInputInterfaceComponent);constructor(t,n){super(t,n),this.setPort(!1)}}class ue extends C{isString=!0;component=e.markRaw(i.TextInputInterfaceComponent)}class he extends C{component=e.markRaw(i.TextareaInputInterfaceComponent)}function me(a){return class extends O{type=a.type;inputs={};outputs={};constructor(){super(),this._title=a.title??a.type,this.updateModules(a.modules),a.codeTemplate&&(this.state.codeTemplate=a.codeTemplate(this)),a.variableName&&(this.state.variableName=a.variableName),this.addInput("_node",new C("",[]).use(i.setType,M).use(i.allowMultipleConnections).setHidden(!0)),this.addOutput("_node",new C("",[]).use(i.setType,M).use(i.allowMultipleConnections).setHidden(!0)),this.executeFactory("input",a.inputs),this.executeFactory("output",a.outputs),a.onCreate?.call(this)}calculate=a.calculate?(t,n)=>({...a.calculate.call(this,t,n),_node:null}):void 0;onPlaced(){a.onPlaced?.call(this)}onDestroy(){a.onDestroy?.call(this)}onCodeUpdate(){a.onCodeUpdate?.call(this)}executeFactory(t,n){Object.keys(n||{}).forEach(o=>{const s=n[o]();t==="input"?this.addInput(o,s):this.addOutput(o,s)})}}}class G extends O{calculate}function fe(a){return class extends G{type=a.type;inputs={};outputs={};calculate;preventUpdate=!1;staticInputKeys=Object.keys(a.inputs??{});staticOutputKeys=Object.keys(a.outputs??{});constructor(){super(),this._title=a.title??a.type,this.updateModules(a.modules),a.codeTemplate&&(this.state.codeTemplate=a.codeTemplate(this)),a.variableName&&(this.state.variableName=a.variableName),this.addInput("_node",new C("",[]).use(i.setType,M).use(i.allowMultipleConnections).setHidden(!0)),this.addOutput("_node",new C("",[]).use(i.setType,M).use(i.allowMultipleConnections).setHidden(!0)),this.staticInputKeys.push("_node"),this.staticOutputKeys.push("_node"),this.executeFactory("input",a.inputs),this.executeFactory("output",a.outputs),a.calculate&&(this.calculate=(t,n)=>({...a.calculate?.call(this,t,n),_node:null})),a.onCreate?.call(this)}onPlaced(){this.events.update.subscribe(this,t=>{t&&(t.type==="input"&&this.staticInputKeys.includes(t.name)||t.type==="output"&&this.staticOutputKeys.includes(t.name))&&this.onUpdate()}),this.onUpdate(),a.onPlaced?.call(this)}onDestroy(){a.onDestroy?.call(this)}onCodeUpdate(){a.onCodeUpdate?.call(this)}load(t){this.preventUpdate=!0,this.hooks.beforeLoad.execute(t),this.id=t.id,this.title=t.title;for(const n of this.staticInputKeys)this.inputs[n].load(t.inputs[n]),this.inputs[n].nodeId=this.id,n!=="_node"&&(this.inputs[n].hidden=t.inputs[n].hidden);for(const n of this.staticOutputKeys)this.outputs[n].load(t.outputs[n]),this.outputs[n].nodeId=this.id,n!=="_node"&&(this.outputs[n].hidden=t.outputs[n].hidden);this.preventUpdate=!1,this.onUpdate(),this.preventUpdate=!0;for(const n of Object.keys(t.inputs))if(!this.staticInputKeys.includes(n)){if(!this.inputs[n]){const o=t.inputs[n].value;let s;typeof o=="number"?s=new i.IntegerInterface(n,o).use(i.setType,te):s=new i.TextInputInterface(n,JSON.stringify(o)).use(i.setType,ne),s.use(i.displayInSidebar,!0),this.addInput(n,s)}this.inputs[n]&&(this.inputs[n].load(t.inputs[n]),this.inputs[n].nodeId=this.id)}for(const n of Object.keys(t.outputs))if(!this.staticOutputKeys.includes(n)){if(!this.outputs[n]){const o=new P(n);this.addOutput(n,o)}this.outputs[n]&&(this.outputs[n].load(t.outputs[n]),this.outputs[n].nodeId=this.id)}S(this.graph,t),this.preventUpdate=!1,this.events.loaded.emit(this)}onUpdate(){if(this.preventUpdate)return;this.graph&&this.graph.activeTransactions++;const t=this.getStaticValues(this.staticInputKeys,this.inputs),n=this.getStaticValues(this.staticOutputKeys,this.outputs),o=a.onUpdate.call(this,t,n);this.updateInterfaces("input",o.inputs??{},o.forceUpdateInputs??[]),this.updateInterfaces("output",o.outputs??{},o.forceUpdateOutputs??[]),this.graph&&this.graph.activeTransactions--}getStaticValues(t,n){const o={};for(const s of t)o[s]=n[s].value;return o}updateInterfaces(t,n,o){const s=t==="input"?this.staticInputKeys:this.staticOutputKeys,r=t==="input"?this.inputs:this.outputs;for(const c of Object.keys(r))s.includes(c)||n[c]&&!o.includes(c)||(t==="input"?this.removeInput(c):this.removeOutput(c));for(const c of Object.keys(n)){if(r[c])continue;const d=n[c]();t==="input"?this.addInput(c,d):this.addOutput(c,d)}}executeFactory(t,n){Object.keys(n||{}).forEach(o=>{const s=n[o]();t==="input"?this.addInput(o,s):this.addOutput(o,s)})}}}class D{_id;_viewModel;_state;constructor(t){this._id=j.v4(),this._viewModel=t,this._state=e.reactive({autosort:!1,modules:{},script:"",token:null,template:""})}get codeNodes(){return T(this.graph)}get connections(){return this.graph.connections}set connections(t){this.graph._connections=t}get graph(){return this.viewModel.displayedGraph}get id(){return this._id}get modules(){let t=[];return this.codeNodes.filter(n=>n.state.modules?.length>0).forEach(n=>{t=t.concat(n.state.modules)}),t?(t.sort(),Array.from(new Set(t.map(n=>this.viewModel.state.modules[n])))):[]}get nodeIds(){return this.codeNodes.map(t=>t.id)}get nodes(){return this.graph.nodes}set nodes(t){this.graph._nodes=t}get scriptedCodeNodes(){return T(this.graph).filter(t=>t.state?.script.length>0)}get shortId(){return this.id.slice(0,6)}get state(){return this._state}get viewModel(){return this._viewModel}get visibleNodes(){return this.codeNodes.filter(t=>!t.state?.hidden)}addNode(t,n){return t.code||(t.code=this),n&&(t.state.props=n),this.graph.addNode(t)}addNodeAtCoordinates=(t,n={x:0,y:0},o)=>(this.addNode(t,o),t.position&&(t.position=n),t);addConnection(t,n){t.name!=="_node"&&(t.hidden=!1),n.name!=="_node"&&(n.hidden=!1),this.graph.addConnection(t,n)}clear(){this.nodes=[],this.connections=[]}findNodeById(t){return this.graph.findNodeById(t)}findNodeByType(t){return this.codeNodes.find(n=>n.type===t)}getNodesBySameType(t){return this.codeNodes.filter(n=>n.type===t)}getNodesBySameVariableNames(t){return this.codeNodes.filter(n=>n.state.variableName===t)}hasConnection(t,n){return this.connections.some(o=>o.from.id===t.id&&o.to.id===n.id)}loadTemplate(t){t.then(n=>{this._state.template=n.default??""})}onCodeUpdate(){this.codeNodes.forEach(t=>t.onCodeUpdate())}removeConnection(t){this.graph.removeConnection(t)}removeNode(t){this.graph.removeNode(t)}renderNodeCodes(){this.codeNodes.length!==0&&this.codeNodes.forEach(t=>t.renderCode())}renderCode(){this.state.script=v.render(this.state.template||"",this)}save(){this.state.autosort&&this.sortNodes();const t=this.viewModel.editor.save();return t.graph.id=this.id,this.saveNodeStates(t.graph.nodes),JSON.parse(JSON.stringify(t))}saveNodeStates(t){t.forEach((n,o)=>{const s=this.nodes[o];Object.entries(n.inputs).forEach(([r])=>{n.inputs&&s.inputs[r]&&(n.inputs[r].hidden=s.inputs[r].hidden)}),Object.entries(n.outputs).forEach(([r])=>{n.outputs&&s.outputs[r]&&(n.outputs[r].hidden=s.outputs[r].hidden)})})}sortNodes(){if(!(this.nodes.length===0||this.connections.length===0))try{const t=this.connections.map(r=>[r.to.nodeId,r.from.nodeId]);let n=[...this.nodeIds];n.reverse(),n=Z.array(n,t),n.reverse();const o=this.graph.nodes.map(r=>r.id).filter(r=>!n.includes(r));n=n.concat(o);const s=n.map(r=>this.findNodeById(r));s&&(this.nodes=s)}catch{console.warn("Failed to sort nodes.")}}updateOutputVariableNames(){this.codeNodes.forEach(t=>t.updateOutputVariableName())}}const T=a=>{let t=[];return a.nodes.forEach(n=>{n.subgraph?t=t.concat(T(n.subgraph)):n.isCodeNode&&t.push(n)}),t},ge=(a=0,t=100)=>({x:a*420,y:t}),ye=a=>{const t={...a.position};return t.x-=400,t.y+=50,t},U=a=>{const{calculationOrder:t,connectionsFromNode:n}=i.sortTopologically(a);t.forEach(o=>{if(!o.isCodeNode)return;const s=o;n.has(s)&&n.get(s).forEach(r=>{r.to.state&&r.from.script&&(r.to.state.script=r.from.script)})})},_e=["id"],Ne={class:"align-middle"},A=e.defineComponent({__name:"CodeGraphNodeInterface",props:{node:{},intf:{}},setup(a){const t=a,{viewModel:n}=i.useViewModel(),{hoveredOver:o,temporaryConnection:s}=i.useTemporaryConnection(),r=e.ref(null),c=e.computed(()=>t.intf.connectionCount>0),d=e.computed(()=>({"--connected":c.value})),h=()=>{o(t.intf)},E=()=>{o(void 0)},b=()=>{r.value&&n.value.hooks.renderInterface.execute({intf:t.intf,el:r.value})};return e.onMounted(b),e.onUpdated(b),(k,x)=>(e.openBlock(),e.createElementBlock("div",{id:k.intf.id,ref_key:"el",ref:r,class:e.normalizeClass(["baklava-node-interface",d.value])},[k.intf.port?(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass(["__port",{"--selected":e.unref(s)?.from===k.intf}]),onPointerover:h,onPointerout:E},null,34)):e.createCommentVNode("",!0),e.createElementVNode("span",Ne,[e.renderSlot(k.$slots,"default")])],10,_e))}}),B=(a,t)=>{const n=a.__vccOpts||a;for(const[o,s]of t)n[o]=s;return n},Ce={},be={xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24",fill:"currentColor",class:"baklava-icon icon icon-tabler icons-tabler-filled icon-tabler-layout-sidebar-left-collapse"};function ke(a,t){return e.openBlock(),e.createElementBlock("svg",be,[...t[0]||(t[0]=[e.createElementVNode("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"},null,-1),e.createElementVNode("path",{d:"M18 3a3 3 0 0 1 2.995 2.824l.005 .176v12a3 3 0 0 1 -2.824 2.995l-.176 .005h-12a3 3 0 0 1 -2.995 -2.824l-.005 -.176v-12a3 3 0 0 1 2.824 -2.995l.176 -.005h12zm0 2h-9v14h9a1 1 0 0 0 .993 -.883l.007 -.117v-12a1 1 0 0 0 -.883 -.993l-.117 -.007zm-2.293 4.293a1 1 0 0 1 .083 1.32l-.083 .094l-1.292 1.293l1.292 1.293a1 1 0 0 1 .083 1.32l-.083 .094a1 1 0 0 1 -1.32 .083l-.094 -.083l-2 -2a1 1 0 0 1 -.083 -1.32l.083 -.094l2 -2a1 1 0 0 1 1.414 0z"},null,-1)])])}const we=B(Ce,[["render",ke]]),Ie={},Ee={xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24",fill:"currentColor",class:"baklava-icon icon icon-tabler icons-tabler-filled icon-tabler-layout-sidebar-left-expand"};function Be(a,t){return e.openBlock(),e.createElementBlock("svg",Ee,[...t[0]||(t[0]=[e.createElementVNode("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"},null,-1),e.createElementVNode("path",{d:"M18 3a3 3 0 0 1 2.995 2.824l.005 .176v12a3 3 0 0 1 -2.824 2.995l-.176 .005h-12a3 3 0 0 1 -2.995 -2.824l-.005 -.176v-12a3 3 0 0 1 2.824 -2.995l.176 -.005h12zm0 2h-9v14h9a1 1 0 0 0 .993 -.883l.007 -.117v-12a1 1 0 0 0 -.883 -.993l-.117 -.007zm-4.387 4.21l.094 .083l2 2a1 1 0 0 1 .083 1.32l-.083 .094l-2 2a1 1 0 0 1 -1.497 -1.32l.083 -.094l1.292 -1.293l-1.292 -1.293a1 1 0 0 1 -.083 -1.32l.083 -.094a1 1 0 0 1 1.32 -.083z"},null,-1)])])}const xe=B(Ie,[["render",Be]]),Ve={},Me={xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24",fill:"currentColor",class:"balkava-icon icon icon-tabler icons-tabler-filled icon-tabler-layout-sidebar-right"};function Te(a,t){return e.openBlock(),e.createElementBlock("svg",Me,[...t[0]||(t[0]=[e.createElementVNode("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"},null,-1),e.createElementVNode("path",{d:"M6 21a3 3 0 0 1 -3 -3v-12a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v12a3 3 0 0 1 -3 3zm8 -16h-8a1 1 0 0 0 -1 1v12a1 1 0 0 0 1 1h8z"},null,-1)])])}const Oe=B(Ve,[["render",Te]]),Se={},$e={xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24",fill:"currentColor",class:"baklava-icon icon icon-tabler icons-tabler-filled icon-tabler-layout-sidebar-right-collapse"};function ze(a,t){return e.openBlock(),e.createElementBlock("svg",$e,[...t[0]||(t[0]=[e.createElementVNode("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"},null,-1),e.createElementVNode("path",{d:"M18 3a3 3 0 0 1 2.995 2.824l.005 .176v12a3 3 0 0 1 -2.824 2.995l-.176 .005h-12a3 3 0 0 1 -2.995 -2.824l-.005 -.176v-12a3 3 0 0 1 2.824 -2.995l.176 -.005h12zm-3 2h-9a1 1 0 0 0 -.993 .883l-.007 .117v12a1 1 0 0 0 .883 .993l.117 .007h9v-14zm-5.387 4.21l.094 .083l2 2a1 1 0 0 1 .083 1.32l-.083 .094l-2 2a1 1 0 0 1 -1.497 -1.32l.083 -.094l1.292 -1.293l-1.292 -1.293a1 1 0 0 1 -.083 -1.32l.083 -.094a1 1 0 0 1 1.32 -.083z"},null,-1)])])}const ve=B(Se,[["render",ze]]),Re={},Le={xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24",fill:"currentColor",class:"baklava-icon icon icon-tabler icons-tabler-filled icon-tabler-layout-sidebar-right-expand"};function Pe(a,t){return e.openBlock(),e.createElementBlock("svg",Le,[...t[0]||(t[0]=[e.createElementVNode("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"},null,-1),e.createElementVNode("path",{d:"M18 3a3 3 0 0 1 2.995 2.824l.005 .176v12a3 3 0 0 1 -2.824 2.995l-.176 .005h-12a3 3 0 0 1 -2.995 -2.824l-.005 -.176v-12a3 3 0 0 1 2.824 -2.995l.176 -.005h12zm-3 2h-9a1 1 0 0 0 -.993 .883l-.007 .117v12a1 1 0 0 0 .883 .993l.117 .007h9v-14zm-3.293 4.293a1 1 0 0 1 .083 1.32l-.083 .094l-1.292 1.293l1.292 1.293a1 1 0 0 1 .083 1.32l-.083 .094a1 1 0 0 1 -1.32 .083l-.094 -.083l-2 -2a1 1 0 0 1 -.083 -1.32l.083 -.094l2 -2a1 1 0 0 1 1.414 0z"},null,-1)])])}const Ge=B(Re,[["render",Pe]]),De={},Ue={xmlns:"http://www.w3.org/2000/svg",class:"baklava-icon",width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"};function Ae(a,t){return e.openBlock(),e.createElementBlock("svg",Ue,[...t[0]||(t[0]=[e.createStaticVNode('<path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M5 2h5v4h-5z"></path><path d="M15 10h5v4h-5z"></path><path d="M5 18h5v4h-5z"></path><path d="M5 10h5v4h-5z"></path><path d="M10 12h5"></path><path d="M7.5 6v4"></path><path d="M7.5 14v4"></path>',8)])])}const Fe=B(De,[["render",Ae]]),He={},We={xmlns:"http://www.w3.org/2000/svg",class:"baklava-icon",width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"};function Xe(a,t){return e.openBlock(),e.createElementBlock("svg",We,[...t[0]||(t[0]=[e.createStaticVNode('<path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M6 2h4v4m-4 0h-1v-1"></path><path d="M15 11v-1h5v4h-2"></path><path d="M5 18h5v4h-5z"></path><path d="M5 10h5v4h-5z"></path><path d="M10 12h2"></path><path d="M7.5 7.5v2.5"></path><path d="M7.5 14v4"></path><path d="M3 3l18 18"></path>',9)])])}const qe=B(He,[["render",Xe]]),Ye={},Je={xmlns:"http://www.w3.org/2000/svg",class:"baklava-icon",width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"};function Ke(a,t){return e.openBlock(),e.createElementBlock("svg",Je,[...t[0]||(t[0]=[e.createStaticVNode('<path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M3 3l18 18"></path><path d="M4 7h3m4 0h9"></path><path d="M10 11l0 6"></path><path d="M14 14l0 3"></path><path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l.077 -.923"></path><path d="M18.384 14.373l.616 -7.373"></path><path d="M9 5v-1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3"></path>',8)])])}const Qe=B(Ye,[["render",Ke]]),Ze={},je={xmlns:"http://www.w3.org/2000/svg",class:"baklava-icon",width:"16",height:"16",viewBox:"0 0 24 24","stroke-width":"2",stroke:"currentColor",fill:"none","stroke-linecap":"round","stroke-linejoin":"round"};function et(a,t){return e.openBlock(),e.createElementBlock("svg",je,[...t[0]||(t[0]=[e.createElementVNode("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"},null,-1),e.createElementVNode("circle",{cx:"12",cy:"12",r:"1"},null,-1),e.createElementVNode("circle",{cx:"12",cy:"19",r:"1"},null,-1),e.createElementVNode("circle",{cx:"12",cy:"5",r:"1"},null,-1)])])}const tt=B(Ze,[["render",et]]),nt=["id","data-node-type"],ot={class:"__title-label",style:{"flex-grow":"1"}},st={key:0},at={class:"__menu",style:{display:"flex"}},rt={class:"__outputs"},it={key:0},lt=["id","title"],dt={class:"__inputs"},ct={key:0},pt=["id","title"],ut=e.defineComponent({__name:"CodeGraphNode",props:{node:{},selected:{type:Boolean,default:!1},dragging:{type:Boolean}},emits:["select","start-drag","update"],setup(a,{emit:t}){const n=i.Components.ContextMenu,o=i.Components.NodeInterface,s=a,r=e.computed(()=>s.node),c=t,{viewModel:d}=i.useViewModel(),{graph:h,switchGraph:E}=i.useGraph(),b=e.ref(null),k=e.ref(!1),x=e.ref(""),_=e.ref(null),f=e.ref(!1);let g=0,y=0;const u=e.ref(!1),N=e.computed(()=>{const p=[{value:"edit",label:"Edit"},{value:"rename",label:"Rename"},{value:"delete",label:"Delete"}];return s.node.type.startsWith(i.GRAPH_NODE_TYPE_PREFIX)&&p.push({value:"editSubgraph",label:"Edit Subgraph"}),p}),I=e.computed(()=>({"--selected":s.selected,"--dragging":s.dragging,"--two-column":!!s.node.twoColumn,"--hidden":r.value.state?.hidden})),Ot=e.computed(()=>({"--reverse-y":s.node.reverseY??d.value.settings.nodes.reverseY})),St=e.computed(()=>({top:`${s.node.position?.y??0}px`,left:`${s.node.position?.x??0}px`,"--width":`${s.node.width??d.value.settings.nodes.defaultWidth}px`})),$t=e.computed(()=>Object.values(s.node.inputs).filter(p=>!p.hidden)),zt=e.computed(()=>Object.values(s.node.outputs).filter(p=>!p.hidden)),W=()=>{c("select")},vt=p=>{s.selected||W(),c("start-drag",p)},X=()=>{u.value=!0},Rt=()=>{const p=d.value.displayedGraph.sidebar;p.nodeId="",p.visible=!1},q=()=>{const p=d.value.displayedGraph.sidebar;p.nodeId=s.node.id,p.visible=!0},Lt=()=>{const p=d.value.displayedGraph.sidebar;p.nodeId=s.node.id},Pt=async p=>{switch(p){case"edit":q();break;case"delete":h.value.removeNode(s.node);break;case"rename":x.value=s.node.title,k.value=!0,await e.nextTick(),_.value?.focus();break;case"editSubgraph":E(s.node.template);break}},Y=()=>{s.node.title=x.value,k.value=!1},J=()=>{b.value&&d.value.hooks.renderNode.execute({node:s.node,el:b.value})},Gt=p=>{f.value=!0,g=s.node.width,y=p.clientX,p.preventDefault()},K=p=>{if(!f.value)return;const w=p.clientX-y,m=g+w/h.value.scaling,Dt=d.value.settings.nodes.minWidth,Ut=d.value.settings.nodes.maxWidth;s.node.width=Math.max(Dt,Math.min(Ut,m))},Q=()=>{f.value=!1};return e.onMounted(()=>{J(),window.addEventListener("mousemove",K),window.addEventListener("mouseup",Q)}),e.onUpdated(J),e.onBeforeUnmount(()=>{window.removeEventListener("mousemove",K),window.removeEventListener("mouseup",Q)}),(p,w)=>(e.openBlock(),e.createElementBlock("div",{id:r.value.id,ref_key:"el",ref:b,class:e.normalizeClass([I.value,"baklava-node"]),"data-node-type":r.value.type,style:e.normalizeStyle(St.value),onPointerdown:W},[e.unref(d).settings.nodes.resizable?(e.openBlock(),e.createElementBlock("div",{key:0,class:"__resize-handle",onMousedown:Gt},null,32)):e.createCommentVNode("",!0),e.createElementVNode("div",{class:"__title",onPointerdown:e.withModifiers(vt,["self","stop"]),onContextmenu:e.withModifiers(X,["prevent"])},[r.value.inputs._node?(e.openBlock(),e.createBlock(A,{key:0,node:r.value,intf:r.value.inputs._node,class:"--input","data-interface-type":"node",style:{"flex-grow":"0"}},null,8,["node","intf"])):e.createCommentVNode("",!0),k.value?e.withDirectives((e.openBlock(),e.createElementBlock("input",{key:2,ref_key:"renameInputEl",ref:_,"onUpdate:modelValue":w[1]||(w[1]=m=>x.value=m),class:"baklava-input",placeholder:"Node Name",style:{"flex-grow":"1"},type:"text",onBlur:Y,onKeydown:e.withKeys(Y,["enter"])},null,544)),[[e.vModelText,x.value]]):(e.openBlock(),e.createElementBlock(e.Fragment,{key:1},[e.createElementVNode("div",ot,[r.value.idx>-1?(e.openBlock(),e.createElementBlock("span",st,e.toDisplayString(r.value.idx+1)+" - ",1)):e.createCommentVNode("",!0),e.createTextVNode(e.toDisplayString(r.value.title)+" ("+e.toDisplayString(r.value.shortId)+") ",1)]),e.createElementVNode("div",at,[r.value.subgraph?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[!e.unref(d).displayedGraph.sidebar.visible&&e.unref(d).displayedGraph.sidebar.nodeId!==r.value.id?(e.openBlock(),e.createBlock(e.unref(Ge),{key:0,class:"--clickable mx-1",onClick:q})):e.unref(d).displayedGraph.sidebar.visible&&e.unref(d).displayedGraph.sidebar.nodeId!==r.value.id?(e.openBlock(),e.createBlock(e.unref(Oe),{key:1,class:"--clickable mx-1",onClick:Lt})):(e.openBlock(),e.createBlock(e.unref(ve),{key:2,class:"--clickable mx-1",onClick:Rt}))],64)),e.createVNode(e.unref(tt),{class:"--clickable mx-1",onClick:X}),e.createVNode(e.unref(n),{modelValue:u.value,"onUpdate:modelValue":w[0]||(w[0]=m=>u.value=m),x:0,y:0,items:N.value,onClick:Pt},null,8,["modelValue","items"])])],64)),r.value.outputs._node?(e.openBlock(),e.createBlock(A,{key:3,node:r.value,intf:r.value.outputs._node,class:"--output","data-interface-type":"node"},null,8,["node","intf"])):e.createCommentVNode("",!0)],32),e.createElementVNode("div",{class:e.normalizeClass(["__content",Ot.value]),onKeydown:w[2]||(w[2]=e.withKeys(e.withModifiers(()=>{},["stop"]),["delete"])),onContextmenu:w[3]||(w[3]=e.withModifiers(()=>{},["prevent"]))},[e.createElementVNode("div",rt,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(zt.value,m=>(e.openBlock(),e.createElementBlock(e.Fragment,{key:m.id},[r.value.state?.hidden?(e.openBlock(),e.createElementBlock("div",it,[m.port?(e.openBlock(),e.createElementBlock("div",{key:0,id:m.id,title:m.name,class:"baklava-node-interface --output --connected"},[...w[4]||(w[4]=[e.createElementVNode("div",{class:"__port"},null,-1)])],8,lt)):e.createCommentVNode("",!0)])):e.renderSlot(p.$slots,"nodeInterface",{key:1,type:"output",node:r.value,intf:m},()=>[e.createVNode(e.unref(o),{node:r.value,intf:m},null,8,["node","intf"])])],64))),128))]),e.createElementVNode("div",dt,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList($t.value,m=>(e.openBlock(),e.createElementBlock(e.Fragment,{key:m.id},[r.value.state?.hidden?(e.openBlock(),e.createElementBlock("div",ct,[m.port?(e.openBlock(),e.createElementBlock("div",{key:0,id:m.id,title:m.name,class:"baklava-node-interface --input --connected"},[...w[5]||(w[5]=[e.createElementVNode("div",{class:"__port"},null,-1)])],8,pt)):e.createCommentVNode("",!0)])):e.renderSlot(p.$slots,"nodeInterface",{key:1,node:r.value,intf:m,type:"input"},()=>[e.createVNode(e.unref(o),{node:r.value,intf:m,title:m.name},null,8,["node","intf","title"])])],64))),128))])],34)],46,nt))}}),ht=["title"],mt={key:0,class:"__label"},ft=e.defineComponent({__name:"Checkbox",props:{modelValue:{type:Boolean},inversed:{type:Boolean},name:{}},emits:["update:modelValue"],setup(a,{emit:t}){const n=t;return(o,s)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(["baklava-checkbox",{"--checked":o.inversed?!o.modelValue:o.modelValue}]),title:o.name,onClick:s[0]||(s[0]=r=>n("update:modelValue",!o.modelValue))},[s[1]||(s[1]=e.createElementVNode("div",{class:"__checkmark-container"},[e.createElementVNode("svg",{xmlns:"http://www.w3.org/2000/svg",width:"18",height:"18",viewBox:"0 0 18 18"},[e.createElementVNode("path",{class:"__checkmark",d:"M 6 5 L 6 10 L 16 10",transform:"rotate(-45 10 10)"})])],-1)),o.name?(e.openBlock(),e.createElementBlock("div",mt,e.toDisplayString(o.name),1)):e.createCommentVNode("",!0)],10,ht))}}),gt={class:"__header"},yt={class:"__node-name"},_t={style:{display:"flex"}},Nt={key:1,class:"__interface"},Ct=e.defineComponent({__name:"CodeGraphSidebar",setup(a){const{viewModel:t}=i.useViewModel(),{graph:n}=i.useGraph(),o=e.ref(null),s=e.toRef(t.value.settings.sidebar,"width"),r=e.computed(()=>t.value.settings.sidebar.resizable);let c=0,d=0;const h=e.computed(()=>{const y=n.value.sidebar.nodeId;return n.value.nodes.find(u=>u.id===y)}),E=e.computed(()=>h.value),b=e.computed(()=>({width:`${s.value}px`})),k=e.computed(()=>h.value?[...Object.values(h.value.inputs),...Object.values(h.value.outputs)].filter(u=>u.displayInSidebar&&u.component):[]),x=()=>{n.value.sidebar.visible=!1},_=()=>{h.value?.events.update.emit(null)},f=y=>{c=s.value,d=y.clientX,window.addEventListener("mousemove",g),window.addEventListener("mouseup",()=>{window.removeEventListener("mousemove",g)},{once:!0})},g=y=>{const u=o.value?.parentElement?.getBoundingClientRect().width??500,N=y.clientX-d;let I=c-N;I<300?I=300:I>.9*u&&(I=.9*u),s.value=I};return(y,u)=>(e.openBlock(),e.createElementBlock("div",{ref_key:"el",ref:o,class:e.normalizeClass(["baklava-sidebar",{"--open":e.unref(n).sidebar.visible}]),style:e.normalizeStyle(b.value)},[r.value?(e.openBlock(),e.createElementBlock("div",{key:0,class:"__resizer",onMousedown:f},null,32)):e.createCommentVNode("",!0),e.createElementVNode("div",gt,[e.createElementVNode("button",{tabindex:"-1",class:"__close",onClick:x},"×"),e.createElementVNode("div",yt,[e.createElementVNode("b",null,e.toDisplayString(h.value?h.value.title:""),1)])]),(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(k.value,N=>(e.openBlock(),e.createElementBlock("div",{key:N.id,class:"__interface"},[e.createElementVNode("div",_t,[e.createVNode(ft,{modelValue:N.hidden,"onUpdate:modelValue":[I=>N.hidden=I,u[0]||(u[0]=()=>h.value?.events.update.emit(null))],inversed:"",style:{"margin-right":"8px"}},null,8,["modelValue","onUpdate:modelValue"]),(e.openBlock(),e.createBlock(e.resolveDynamicComponent(N.component),{modelValue:N.value,"onUpdate:modelValue":I=>N.value=I,node:h.value,intf:N,style:{width:"100%"}},null,8,["modelValue","onUpdate:modelValue","node","intf"]))])]))),128)),E.value&&E.value.state?(e.openBlock(),e.createElementBlock("div",Nt,[u[2]||(u[2]=e.createElementVNode("label",null,"Variable name",-1)),e.withDirectives(e.createElementVNode("input",{"onUpdate:modelValue":u[1]||(u[1]=N=>E.value.state.variableName=N),type:"text",class:"baklava-input",title:"Variable name",onBlur:_,onKeydown:e.withKeys(_,["enter"])},null,544),[[e.vModelText,E.value.state.variableName]])])):e.createCommentVNode("",!0)],6))}}),bt=e.defineComponent({props:{type:{type:String,required:!0},title:{type:String,required:!0}},setup(a){const{viewModel:t}=i.useViewModel(),{switchGraph:n}=i.useGraph(),o=e.ref(!1),s=e.computed(()=>a.type.startsWith(i.GRAPH_NODE_TYPE_PREFIX));return{showContextMenu:o,hasContextMenu:s,contextMenuItems:[{label:"Edit Subgraph",value:"editSubgraph"},{label:"Delete Subgraph",value:"deleteSubgraph"}],openContextMenu:()=>{o.value=!0},onContextMenuClick:h=>{const E=a.type.substring(i.GRAPH_NODE_TYPE_PREFIX.length),b=t.value.editor.graphTemplates.find(k=>k.id===E);if(b)switch(h){case"editSubgraph":n(b);break;case"deleteSubgraph":t.value.editor.removeGraphTemplate(b);break}}}}}),kt=["data-node-type"],wt={class:"__title"},It={class:"__title-label"};function Et(a,t,n,o,s,r){return e.openBlock(),e.createElementBlock("div",{class:"baklava-node --palette","data-node-type":a.type},[e.createElementVNode("div",wt,[e.createElementVNode("div",It,e.toDisplayString(a.title),1)])],8,kt)}const F=B(bt,[["render",Et]]),Bt={class:"baklava-node --palette",style:{"margin-top":"-20px","margin-bottom":"30px"}},xt={key:0},Vt=e.defineComponent({__name:"CodeNodePalette",setup(a){const{viewModel:t}=i.useViewModel(),{x:n,y:o}=ee.usePointer(),{transform:s}=i.useTransform(),r=i.useNodeCategories(t),c=e.inject("editorEl"),d=e.ref(""),h=e.ref(null),E=_=>d.value?_.filter(f=>Object.values(f.nodeTypes).some(g=>g.title.toLowerCase().includes(d.value?.toLowerCase()))):_,b=_=>d.value?Object.values(_).filter(f=>f.title.toLowerCase().includes(d.value?.toLowerCase())):Object.values(_),k=e.computed(()=>{if(!h.value||!c?.value)return{};const{left:_,top:f}=c.value.getBoundingClientRect();return{top:`${o.value-f}px`,left:`${n.value-_}px`}}),x=(_,f)=>{h.value={type:_,nodeInformation:f};const g=()=>{const y=e.reactive(new f.type);t.value.displayedGraph.addNode(y);const u=c.value.getBoundingClientRect(),[N,I]=s(n.value-u.left,o.value-u.top);y.position.x=N,y.position.y=I,h.value=null,document.removeEventListener("pointerup",g)};document.addEventListener("pointerup",g)};return(_,f)=>(e.openBlock(),e.createElementBlock(e.Fragment,null,[e.createElementVNode("div",{class:e.normalizeClass(["baklava-node-palette",{"--open":e.unref(t).settings.palette.enabled}]),onContextmenu:f[1]||(f[1]=e.withModifiers(()=>{},["stop","prevent"]))},[e.createElementVNode("div",Bt,[e.withDirectives(e.createElementVNode("input",{"onUpdate:modelValue":f[0]||(f[0]=g=>d.value=g),type:"text",class:"baklava-input",title:"Filter node types"},null,512),[[e.vModelText,d.value]])]),(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(E(e.unref(r)),g=>(e.openBlock(),e.createElementBlock("section",{key:g.name},[g.name!=="default"?(e.openBlock(),e.createElementBlock("h3",xt,e.toDisplayString(g.name),1)):e.createCommentVNode("",!0),(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(b(g.nodeTypes),(y,u)=>(e.openBlock(),e.createBlock(F,{key:u,type:u,title:y.title,onPointerdown:N=>x(u,y)},null,8,["type","title","onPointerdown"]))),128))]))),128))],34),e.createVNode(e.Transition,{name:"fade"},{default:e.withCtx(()=>[h.value?(e.openBlock(),e.createElementBlock("div",{key:0,class:"baklava-dragged-node",style:e.normalizeStyle(k.value)},[e.createVNode(F,{type:h.value.type,title:h.value.nodeInformation.title},null,8,["type","title"])],4)):e.createCommentVNode("",!0)]),_:1})],64))}}),Mt=e.defineComponent({__name:"CodeGraphEditor",props:{viewModel:{}},setup(a){const t=a,n=e.toRef(t,"viewModel"),o=s=>s.events.update.emit(null);return e.onMounted(()=>{n.value.subscribe(),n.value.engine.start()}),e.onUnmounted(()=>{n.value.unsubscribe(),n.value.engine.stop()}),(s,r)=>(e.openBlock(),e.createBlock(e.unref(i.BaklavaEditor),{"view-model":n.value},{palette:e.withCtx(()=>[e.createVNode(Vt)]),node:e.withCtx(c=>[e.createVNode(ut,e.mergeProps(c,{onUpdate:d=>o(c.node)}),null,16,["onUpdate"])]),sidebar:e.withCtx(c=>[e.createVNode(Ct,e.normalizeProps(e.guardReactiveProps(c)),null,16)]),_:1},8,["view-model"]))}}),H=a=>{const t="TOGGLE_PALETTE";a.commandHandler.registerCommand(t,{execute:()=>a.settings.palette.enabled=!a.settings.palette.enabled,canExecute:()=>!0});const n="CLEAR_ALL";a.commandHandler.registerCommand(n,{execute:()=>a.displayedGraph.nodes.forEach(s=>a.displayedGraph.removeNode(s)),canExecute:()=>a.displayedGraph.nodes.length>0});const o="TOGGLE_MINIMAP";a.commandHandler.registerCommand(o,{execute:()=>a.settings.enableMinimap=!a.settings.enableMinimap,canExecute:()=>a.displayedGraph.nodes.length>1}),a.settings.toolbar.commands=[{command:t,title:"Toggle palette",icon:e.computed(()=>a.settings.palette.enabled?we:xe)},...i.DEFAULT_TOOLBAR_COMMANDS,{command:n,title:"Clear all",icon:Qe},{command:o,title:"Toggle minimap",icon:e.computed(()=>a.settings.enableMinimap?qe:Fe)}]},V={enableMinimap:!1,toolbar:{enabled:!0},palette:{enabled:!0},sidebar:{enabled:!0,resizable:!0,width:350},displayValueOnHover:!1};function Tt(a){const t=i.useBaklava(a?.existingEditor);t.code=a?.code?new a.code(t):new D(t),H(t);const n={};return Object.keys(V).forEach(o=>{n[o]=typeof V[o]=="object"?{...t.settings[o],...V[o]}:V[o]}),t.settings=e.reactive({...t.settings,...n}),t.settings.nodes.defaultWidth=350,t.state=e.reactive({modules:{},token:null}),t.engine=new i.DependencyEngine(t.editor),t.subscribe=()=>{t.state.token&&t.unsubscribe();const o=Symbol();t.displayedGraph.events.addNode.subscribe(o,s=>s.code=t.code),t.engine.events.beforeRun.subscribe(o,()=>{t.engine.pause(),t.code&&(t.code.onCodeUpdate(),t.code.sortNodes(),t.code.updateOutputVariableNames()),t.engine.resume()}),t.engine.events.afterRun.subscribe(o,s=>{t.engine.pause(),i.applyResult(s,t.editor),U(t.displayedGraph),t.code&&(t.code.renderNodeCodes(),t.code.renderCode()),t.engine.resume()}),t.state.token=o},t.unsubscribe=()=>{if(!t.state.token)return;const o=t.state.token;t.displayedGraph.events.addNode.unsubscribe(o),t.engine.events.beforeRun.unsubscribe(o),t.engine.events.afterRun.unsubscribe(o),t.state.token=null},t}Object.defineProperty(l,"ButtonInterfaceComponent",{enumerable:!0,get:()=>i.ButtonInterfaceComponent}),Object.defineProperty(l,"CheckboxInterfaceComponent",{enumerable:!0,get:()=>i.CheckboxInterfaceComponent}),Object.defineProperty(l,"IntegerInterfaceComponent",{enumerable:!0,get:()=>i.IntegerInterfaceComponent}),Object.defineProperty(l,"NumberInterfaceComponent",{enumerable:!0,get:()=>i.NumberInterfaceComponent}),Object.defineProperty(l,"SelectInterfaceComponent",{enumerable:!0,get:()=>i.SelectInterfaceComponent}),Object.defineProperty(l,"SliderInterfaceComponent",{enumerable:!0,get:()=>i.SliderInterfaceComponent}),Object.defineProperty(l,"TextInputInterfaceComponent",{enumerable:!0,get:()=>i.TextInputInterfaceComponent}),Object.defineProperty(l,"TextareaInputInterfaceComponent",{enumerable:!0,get:()=>i.TextareaInputInterfaceComponent}),l.AbstractCodeNode=R,l.ButtonInterface=se,l.CheckboxInterface=ae,l.Code=D,l.CodeGraphEditor=Mt,l.CodeInputInterface=ie,l.CodeNode=O,l.CodeNodeInterface=C,l.CodeOutputInterface=P,l.DEFAULT_SETTINGS=V,l.DynamicCodeNode=G,l.IntegerInterface=re,l.NumberInterface=le,l.SelectInterface=de,l.SliderInterface=ce,l.TextInputInterface=ue,l.TextInterface=pe,l.TextareaInputInterface=he,l.addToolbarCommands=H,l.defineCodeNode=me,l.defineDynamicCodeNode=fe,l.getCodeNodes=T,l.getPositionAtColumn=ge,l.getPositionBeforeNode=ye,l.loadNodeState=S,l.saveNodeState=L,l.transferCodeScript=U,l.useCodeGraph=Tt,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})}));