@blueking/flow-canvas 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -1,231 +1,233 @@
1
- import { ref as L, computed as H, onScopeDispose as Ue, defineComponent as ce, onBeforeUnmount as Re, createElementBlock as N, openBlock as I, normalizeStyle as Ie, createElementVNode as R, createVNode as Ve, createCommentVNode as F, normalizeClass as Q, Transition as We, withCtx as $e, withModifiers as Ze, createTextVNode as Oe, renderSlot as me, onMounted as Je, watch as ge, createBlock as Ce, Fragment as de, renderList as Ee, toDisplayString as he, unref as et, resolveDynamicComponent as tt, inject as ot } from "vue";
2
- import { Graph as nt } from "@antv/x6";
3
- import { register as st } from "@antv/x6-vue-shape";
4
- function mo() {
1
+ import { ref as O, computed as j, onScopeDispose as Ye, defineComponent as le, h as Ae, watch as fe, onBeforeUnmount as Se, createElementBlock as A, openBlock as N, normalizeStyle as ve, createElementVNode as G, createVNode as Ze, createCommentVNode as V, normalizeClass as te, Transition as Qe, withCtx as $e, withModifiers as nt, createTextVNode as Pe, renderSlot as we, onMounted as Je, createBlock as ye, Fragment as he, renderList as xe, toDisplayString as ce, unref as re, reactive as st, resolveDynamicComponent as it, Teleport as rt, nextTick as Te, inject as at, createApp as lt } from "vue";
2
+ import { Graph as dt } from "@antv/x6";
3
+ import { register as ct } from "@antv/x6-vue-shape";
4
+ import { Selection as ut } from "@antv/x6-plugin-selection";
5
+ import { MiniMap as ft } from "@antv/x6-plugin-minimap";
6
+ function rn() {
5
7
  return {
6
8
  version: "1.0",
7
9
  nodes: {},
8
10
  edges: {}
9
11
  };
10
12
  }
11
- class Y extends Error {
13
+ class ae extends Error {
12
14
  constructor(e) {
13
15
  super(e), this.name = "CanvasConstraintError";
14
16
  }
15
17
  }
16
- class it extends Error {
18
+ class pt extends Error {
17
19
  constructor(e) {
18
20
  super(e), this.name = "CanvasSchemaError";
19
21
  }
20
22
  }
21
- function Me(s, e, t) {
23
+ function _e(n, e, t) {
22
24
  if (e.length === 0) {
23
25
  if (t === void 0) return;
24
26
  if (typeof t != "object" || t === null || Array.isArray(t))
25
27
  throw new Error("Root value of payload/extensions/meta must be an object or undefined");
26
28
  return t;
27
29
  }
28
- const o = s ? { ...s } : {};
29
- let n = o;
30
+ const s = n ? { ...n } : {};
31
+ let o = s;
30
32
  for (let r = 0; r < e.length - 1; r++) {
31
- const l = e[r], a = n[l];
32
- a && typeof a == "object" && !Array.isArray(a) ? n[l] = { ...a } : n[l] = {}, n = n[l];
33
+ const l = e[r], a = o[l];
34
+ a && typeof a == "object" && !Array.isArray(a) ? o[l] = { ...a } : o[l] = {}, o = o[l];
33
35
  }
34
36
  const i = e[e.length - 1];
35
- return t === void 0 ? delete n[i] : n[i] = t, o;
37
+ return t === void 0 ? delete o[i] : o[i] = t, s;
36
38
  }
37
- function Te(s, e) {
39
+ function Re(n, e) {
38
40
  switch (e.type) {
39
41
  case "node.add":
40
- return rt(s, e.node);
42
+ return gt(n, e.node);
41
43
  case "node.move":
42
- return at(s, e.nodeId, e.position);
44
+ return ht(n, e.nodeId, e.position);
43
45
  case "node.remove":
44
- return lt(s, e.nodeId);
46
+ return vt(n, e.nodeId);
45
47
  case "node.update":
46
- return dt(s, e.nodeId, e.patch);
48
+ return yt(n, e.nodeId, e.patch);
47
49
  case "node.set-payload":
48
- return ct(s, e.nodeId, e.path, e.value);
50
+ return mt(n, e.nodeId, e.path, e.value);
49
51
  case "node.set-extensions":
50
- return ut(s, e.nodeId, e.path, e.value);
52
+ return bt(n, e.nodeId, e.path, e.value);
51
53
  case "edge.add":
52
- return ft(s, e.edge);
54
+ return wt(n, e.edge);
53
55
  case "edge.remove":
54
- return pt(s, e.edgeId);
56
+ return xt(n, e.edgeId);
55
57
  case "edge.reconnect":
56
- return gt(s, e.edgeId, e.source, e.target);
58
+ return Ct(n, e.edgeId, e.source, e.target);
57
59
  case "edge.update":
58
- return ht(s, e.edgeId, e.patch);
60
+ return Et(n, e.edgeId, e.patch);
59
61
  case "edge.set-payload":
60
- return vt(s, e.edgeId, e.path, e.value);
62
+ return kt(n, e.edgeId, e.path, e.value);
61
63
  case "edge.label.update":
62
- return yt(s, e.edgeId, e.labelId, e.patch);
64
+ return It(n, e.edgeId, e.labelId, e.patch);
63
65
  case "model.set-meta":
64
- return mt(s, e.path, e.value);
66
+ return St(n, e.path, e.value);
65
67
  default:
66
- throw new Y(`Unknown command type: ${e.type}`);
68
+ throw new ae(`Unknown command type: ${e.type}`);
67
69
  }
68
70
  }
69
- function be(s, e) {
70
- const t = s.nodes[e];
71
- if (!t) throw new Y(`Node "${e}" does not exist`);
71
+ function Ce(n, e) {
72
+ const t = n.nodes[e];
73
+ if (!t) throw new ae(`Node "${e}" does not exist`);
72
74
  return t;
73
75
  }
74
- function we(s, e) {
75
- const t = s.edges[e];
76
- if (!t) throw new Y(`Edge "${e}" does not exist`);
76
+ function Ee(n, e) {
77
+ const t = n.edges[e];
78
+ if (!t) throw new ae(`Edge "${e}" does not exist`);
77
79
  return t;
78
80
  }
79
- function ve(s, e, t) {
80
- const o = s.nodes[e.nodeId];
81
- if (!o)
82
- throw new Y(`${t} node "${e.nodeId}" does not exist`);
83
- if (e.portId && o.ports && !o.ports.some((i) => i.id === e.portId))
84
- throw new Y(`${t} port "${e.portId}" not found on node "${e.nodeId}"`);
85
- }
86
- function Ne(s, e, t) {
87
- return { ...s, nodes: { ...s.nodes, [e]: t } };
88
- }
89
- function Se(s, e, t) {
90
- return { ...s, edges: { ...s.edges, [e]: t } };
91
- }
92
- function rt(s, e) {
93
- if (s.nodes[e.id])
94
- throw new Y(`Node id "${e.id}" already exists`);
95
- return { ...s, nodes: { ...s.nodes, [e.id]: e } };
96
- }
97
- function at(s, e, t) {
98
- const o = be(s, e);
99
- return Ne(s, e, { ...o, position: t });
100
- }
101
- function lt(s, e) {
102
- be(s, e);
103
- const { [e]: t, ...o } = s.nodes, n = {};
104
- for (const [i, r] of Object.entries(s.edges))
105
- r.source.nodeId !== e && r.target.nodeId !== e && (n[i] = r);
106
- return { ...s, nodes: o, edges: n };
107
- }
108
- function dt(s, e, t) {
109
- const o = be(s, e);
110
- return Ne(s, e, { ...o, ...t, id: o.id });
111
- }
112
- function ct(s, e, t, o) {
113
- const n = be(s, e), i = Me(n.payload, t, o);
114
- return Ne(s, e, { ...n, payload: i });
115
- }
116
- function ut(s, e, t, o) {
117
- const n = be(s, e), i = Me(n.extensions, t, o);
118
- return Ne(s, e, { ...n, extensions: i });
119
- }
120
- function ft(s, e) {
121
- if (s.edges[e.id])
122
- throw new Y(`Edge id "${e.id}" already exists`);
123
- if (ve(s, e.source, "Source"), ve(s, e.target, "Target"), e.labels) {
81
+ function me(n, e, t) {
82
+ const s = n.nodes[e.nodeId];
83
+ if (!s)
84
+ throw new ae(`${t} node "${e.nodeId}" does not exist`);
85
+ if (e.portId && s.ports && !s.ports.some((i) => i.id === e.portId))
86
+ throw new ae(`${t} port "${e.portId}" not found on node "${e.nodeId}"`);
87
+ }
88
+ function Ne(n, e, t) {
89
+ return { ...n, nodes: { ...n.nodes, [e]: t } };
90
+ }
91
+ function Me(n, e, t) {
92
+ return { ...n, edges: { ...n.edges, [e]: t } };
93
+ }
94
+ function gt(n, e) {
95
+ if (n.nodes[e.id])
96
+ throw new ae(`Node id "${e.id}" already exists`);
97
+ return { ...n, nodes: { ...n.nodes, [e.id]: e } };
98
+ }
99
+ function ht(n, e, t) {
100
+ const s = Ce(n, e);
101
+ return Ne(n, e, { ...s, position: t });
102
+ }
103
+ function vt(n, e) {
104
+ Ce(n, e);
105
+ const { [e]: t, ...s } = n.nodes, o = {};
106
+ for (const [i, r] of Object.entries(n.edges))
107
+ r.source.nodeId !== e && r.target.nodeId !== e && (o[i] = r);
108
+ return { ...n, nodes: s, edges: o };
109
+ }
110
+ function yt(n, e, t) {
111
+ const s = Ce(n, e);
112
+ return Ne(n, e, { ...s, ...t, id: s.id });
113
+ }
114
+ function mt(n, e, t, s) {
115
+ const o = Ce(n, e), i = _e(o.payload, t, s);
116
+ return Ne(n, e, { ...o, payload: i });
117
+ }
118
+ function bt(n, e, t, s) {
119
+ const o = Ce(n, e), i = _e(o.extensions, t, s);
120
+ return Ne(n, e, { ...o, extensions: i });
121
+ }
122
+ function wt(n, e) {
123
+ if (n.edges[e.id])
124
+ throw new ae(`Edge id "${e.id}" already exists`);
125
+ if (me(n, e.source, "Source"), me(n, e.target, "Target"), e.labels) {
124
126
  const t = /* @__PURE__ */ new Set();
125
- for (const o of e.labels) {
126
- if (t.has(o.id))
127
- throw new Y(`Duplicate label id "${o.id}" in edge "${e.id}"`);
128
- t.add(o.id);
127
+ for (const s of e.labels) {
128
+ if (t.has(s.id))
129
+ throw new ae(`Duplicate label id "${s.id}" in edge "${e.id}"`);
130
+ t.add(s.id);
129
131
  }
130
132
  }
131
- return { ...s, edges: { ...s.edges, [e.id]: e } };
133
+ return { ...n, edges: { ...n.edges, [e.id]: e } };
132
134
  }
133
- function pt(s, e) {
134
- we(s, e);
135
- const { [e]: t, ...o } = s.edges;
136
- return { ...s, edges: o };
135
+ function xt(n, e) {
136
+ Ee(n, e);
137
+ const { [e]: t, ...s } = n.edges;
138
+ return { ...n, edges: s };
137
139
  }
138
- function gt(s, e, t, o) {
139
- const n = we(s, e), i = t ?? n.source, r = o ?? n.target;
140
- return ve(s, i, "Source"), ve(s, r, "Target"), Se(s, e, { ...n, source: i, target: r });
140
+ function Ct(n, e, t, s) {
141
+ const o = Ee(n, e), i = t ?? o.source, r = s ?? o.target;
142
+ return me(n, i, "Source"), me(n, r, "Target"), Me(n, e, { ...o, source: i, target: r });
141
143
  }
142
- function ht(s, e, t) {
143
- const o = we(s, e), n = { ...o, ...t, id: o.id };
144
- return t.source && ve(s, n.source, "Source"), t.target && ve(s, n.target, "Target"), Se(s, e, n);
144
+ function Et(n, e, t) {
145
+ const s = Ee(n, e), o = { ...s, ...t, id: s.id };
146
+ return t.source && me(n, o.source, "Source"), t.target && me(n, o.target, "Target"), Me(n, e, o);
145
147
  }
146
- function vt(s, e, t, o) {
147
- const n = we(s, e), i = Me(n.payload, t, o);
148
- return Se(s, e, { ...n, payload: i });
148
+ function kt(n, e, t, s) {
149
+ const o = Ee(n, e), i = _e(o.payload, t, s);
150
+ return Me(n, e, { ...o, payload: i });
149
151
  }
150
- function yt(s, e, t, o) {
151
- const n = we(s, e);
152
- if (!n.labels)
153
- throw new Y(`Edge "${e}" has no labels`);
154
- const i = n.labels.findIndex((l) => l.id === t);
152
+ function It(n, e, t, s) {
153
+ const o = Ee(n, e);
154
+ if (!o.labels)
155
+ throw new ae(`Edge "${e}" has no labels`);
156
+ const i = o.labels.findIndex((l) => l.id === t);
155
157
  if (i === -1)
156
- throw new Y(`Label "${t}" not found in edge "${e}"`);
157
- const r = [...n.labels];
158
- return r[i] = { ...r[i], ...o, id: t }, Se(s, e, { ...n, labels: r });
158
+ throw new ae(`Label "${t}" not found in edge "${e}"`);
159
+ const r = [...o.labels];
160
+ return r[i] = { ...r[i], ...s, id: t }, Me(n, e, { ...o, labels: r });
159
161
  }
160
- function mt(s, e, t) {
161
- const o = Me(s.meta, e, t);
162
- return { ...s, meta: o };
162
+ function St(n, e, t) {
163
+ const s = _e(n.meta, e, t);
164
+ return { ...n, meta: s };
163
165
  }
164
- function bt(s, e) {
165
- const t = e?.maxHistorySize ?? 100, o = L(s), n = [], i = [], r = L(!1), l = L(!1);
166
+ function _t(n, e) {
167
+ const t = e?.maxHistorySize ?? 100, s = O(n), o = [], i = [], r = O(!1), l = O(!1);
166
168
  function a() {
167
- r.value = n.length > 0, l.value = i.length > 0;
168
- }
169
- function f(k) {
170
- const w = o.value;
171
- let x = w;
172
- for (const A of k.commands)
173
- x = Te(x, A);
174
- return n.push({ snapshot: w, envelope: k }), n.length > t && n.shift(), i.length = 0, o.value = x, a(), x;
175
- }
176
- function d() {
177
- const k = n.pop();
178
- return k ? (i.push({ snapshot: o.value, envelope: k.envelope }), o.value = k.snapshot, a(), k.snapshot) : null;
179
- }
180
- function b() {
181
- const k = i.pop();
182
- if (!k) return null;
183
- n.push({ snapshot: o.value, envelope: k.envelope });
184
- let w = o.value;
185
- for (const x of k.envelope.commands)
186
- w = Te(w, x);
187
- return o.value = w, a(), w;
188
- }
189
- function m() {
190
- n.length = 0, i.length = 0, a();
169
+ r.value = o.length > 0, l.value = i.length > 0;
170
+ }
171
+ function p(C) {
172
+ const M = s.value;
173
+ let D = M;
174
+ for (const L of C.commands)
175
+ D = Re(D, L);
176
+ return o.push({ snapshot: M, envelope: C }), o.length > t && o.shift(), i.length = 0, s.value = D, a(), D;
177
+ }
178
+ function c() {
179
+ const C = o.pop();
180
+ return C ? (i.push({ snapshot: s.value, envelope: C.envelope }), s.value = C.snapshot, a(), C.snapshot) : null;
191
181
  }
192
182
  function g() {
193
- return o.value;
183
+ const C = i.pop();
184
+ if (!C) return null;
185
+ o.push({ snapshot: s.value, envelope: C.envelope });
186
+ let M = s.value;
187
+ for (const D of C.envelope.commands)
188
+ M = Re(M, D);
189
+ return s.value = M, a(), M;
194
190
  }
195
- function S(k) {
196
- o.value = k, m();
191
+ function u() {
192
+ o.length = 0, i.length = 0, a();
193
+ }
194
+ function y() {
195
+ return s.value;
196
+ }
197
+ function v(C) {
198
+ s.value = C, u();
197
199
  }
198
200
  return {
199
- currentFlowModel: o,
200
- execute: f,
201
- undo: d,
202
- redo: b,
201
+ currentFlowModel: s,
202
+ execute: p,
203
+ undo: c,
204
+ redo: g,
203
205
  canUndo: r,
204
206
  canRedo: l,
205
207
  get undoStack() {
206
- return n.map((k) => k.envelope);
208
+ return o.map((C) => C.envelope);
207
209
  },
208
210
  get redoStack() {
209
- return i.map((k) => k.envelope);
211
+ return i.map((C) => C.envelope);
210
212
  },
211
- clear: m,
212
- createSnapshot: g,
213
- replaceFlowModel: S
213
+ clear: u,
214
+ createSnapshot: y,
215
+ replaceFlowModel: v
214
216
  };
215
217
  }
216
- function wt(s) {
217
- return s !== null && typeof s == "object" && s.rejected === !0;
218
+ function Nt(n) {
219
+ return n !== null && typeof n == "object" && n.rejected === !0;
218
220
  }
219
- class xt {
221
+ class Mt {
220
222
  plugins = [];
221
223
  editorContext = null;
222
224
  runtimeCtx = null;
223
225
  /** 每次 attachRuntime 递增,detachRuntime 时旧 generation 的异步调用自动作废 */
224
226
  runtimeVersion = 0;
225
227
  install(e, t) {
226
- this.plugins = [...e].sort((o, n) => (o.priority ?? 100) - (n.priority ?? 100)), this.editorContext = t;
227
- for (const o of this.plugins)
228
- o.install?.(t);
228
+ this.plugins = [...e].sort((s, o) => (s.priority ?? 100) - (o.priority ?? 100)), this.editorContext = t;
229
+ for (const s of this.plugins)
230
+ s.install?.(t);
229
231
  }
230
232
  /**
231
233
  * 挂载运行时上下文并调用各插件的 attachRuntime。
@@ -235,9 +237,9 @@ class xt {
235
237
  attachRuntime(e) {
236
238
  const t = ++this.runtimeVersion;
237
239
  this.runtimeCtx = e;
238
- const o = this.createSafeRuntimeContext(e, t);
239
- for (const n of this.plugins)
240
- n.attachRuntime?.(o);
240
+ const s = this.createSafeRuntimeContext(e, t);
241
+ for (const o of this.plugins)
242
+ o.attachRuntime?.(s);
241
243
  }
242
244
  /** 按安装的逆序 detach,保证后安装的插件先释放运行时资源 */
243
245
  detachRuntime() {
@@ -250,16 +252,16 @@ class xt {
250
252
  * 如果在 await 期间 detachRuntime 已执行,代理会将 graph 操作变为 no-op。
251
253
  */
252
254
  createSafeRuntimeContext(e, t) {
253
- const o = this, n = new Proxy(e.graph, {
255
+ const s = this, o = new Proxy(e.graph, {
254
256
  get(i, r, l) {
255
257
  const a = Reflect.get(i, r, l);
256
- return r === "use" && typeof a == "function" ? function(...d) {
257
- if (o.runtimeVersion === t)
258
- return a.apply(i, d);
258
+ return r === "use" && typeof a == "function" ? function(...c) {
259
+ if (s.runtimeVersion === t)
260
+ return a.apply(i, c);
259
261
  } : a;
260
262
  }
261
263
  });
262
- return { ...e, graph: n };
264
+ return { ...e, graph: o };
263
265
  }
264
266
  dispose() {
265
267
  for (const e of [...this.plugins].reverse())
@@ -269,35 +271,35 @@ class xt {
269
271
  transformCommand(e) {
270
272
  if (!this.editorContext) return { envelope: e };
271
273
  let t = e;
272
- for (const o of this.plugins) {
273
- if (!o.transformCommand) continue;
274
- const n = this.createPreview(t), i = o.transformCommand(t, n, this.editorContext);
274
+ for (const s of this.plugins) {
275
+ if (!s.transformCommand) continue;
276
+ const o = this.createPreview(t), i = s.transformCommand(t, o, this.editorContext);
275
277
  if (i === null)
276
278
  return {
277
279
  rejected: !0,
278
280
  error: {
279
281
  code: "plugin_rejected",
280
282
  reason: "",
281
- source: o.name
283
+ source: s.name
282
284
  }
283
285
  };
284
- if (wt(i))
286
+ if (Nt(i))
285
287
  return {
286
288
  rejected: !0,
287
289
  error: {
288
290
  code: i.code ?? "plugin_rejected",
289
291
  reason: i.reason,
290
- source: o.name
292
+ source: s.name
291
293
  }
292
294
  };
293
295
  t = i;
294
296
  }
295
297
  return { envelope: t };
296
298
  }
297
- afterCommand(e, t, o) {
299
+ afterCommand(e, t, s) {
298
300
  if (this.editorContext)
299
- for (const n of this.plugins)
300
- n.afterCommand?.(e, t, o, this.editorContext);
301
+ for (const o of this.plugins)
302
+ o.afterCommand?.(e, t, s, this.editorContext);
301
303
  }
302
304
  dispatchUiEvent(e) {
303
305
  if (this.runtimeCtx)
@@ -319,9 +321,9 @@ class xt {
319
321
  collectContextMenuItems(e) {
320
322
  if (!this.runtimeCtx) return [];
321
323
  const t = [];
322
- for (const o of this.plugins) {
323
- const n = o.onBlankContextMenu?.(e, this.runtimeCtx);
324
- n && t.push(...n);
324
+ for (const s of this.plugins) {
325
+ const o = s.onBlankContextMenu?.(e, this.runtimeCtx);
326
+ o && t.push(...o);
325
327
  }
326
328
  return t;
327
329
  }
@@ -330,20 +332,20 @@ class xt {
330
332
  if (!this.editorContext) return [];
331
333
  const e = /* @__PURE__ */ new Map();
332
334
  for (const t of this.plugins) {
333
- const o = t.provideToolbarItems?.(this.editorContext);
334
- if (o)
335
- for (const n of o)
336
- e.set(n.id, n);
335
+ const s = t.provideToolbarItems?.(this.editorContext);
336
+ if (s)
337
+ for (const o of s)
338
+ e.set(o.id, o);
337
339
  }
338
- return [...e.values()].sort((t, o) => (t.order ?? 0) - (o.order ?? 0));
340
+ return [...e.values()].sort((t, s) => (t.order ?? 0) - (s.order ?? 0));
339
341
  }
340
342
  /** 合并所有插件对某节点的装饰(className / borderColor / badge),后注册覆盖先注册 */
341
343
  collectNodeDecorations(e) {
342
344
  if (!this.editorContext) return;
343
345
  let t;
344
- for (const o of this.plugins) {
345
- const n = o.decorateNode?.(e, this.editorContext);
346
- n && (t = t ? { ...t, ...n } : n);
346
+ for (const s of this.plugins) {
347
+ const o = s.decorateNode?.(e, this.editorContext);
348
+ o && (t = t ? { ...t, ...o } : o);
347
349
  }
348
350
  return t;
349
351
  }
@@ -351,9 +353,9 @@ class xt {
351
353
  collectEdgeDecorations(e) {
352
354
  if (!this.editorContext) return;
353
355
  let t;
354
- for (const o of this.plugins) {
355
- const n = o.decorateEdge?.(e, this.editorContext);
356
- n && (t = t ? { ...t, ...n } : n);
356
+ for (const s of this.plugins) {
357
+ const o = s.decorateEdge?.(e, this.editorContext);
358
+ o && (t = t ? { ...t, ...o } : o);
357
359
  }
358
360
  return t;
359
361
  }
@@ -361,8 +363,8 @@ class xt {
361
363
  if (!this.runtimeCtx) return {};
362
364
  const e = {};
363
365
  for (const t of this.plugins) {
364
- const o = t.extendApi?.(this.runtimeCtx.api, this.runtimeCtx);
365
- o && Object.assign(e, o);
366
+ const s = t.extendApi?.(this.runtimeCtx.api, this.runtimeCtx);
367
+ s && Object.assign(e, s);
366
368
  }
367
369
  return e;
368
370
  }
@@ -370,144 +372,156 @@ class xt {
370
372
  createPreview(e) {
371
373
  const t = this.editorContext;
372
374
  return {
373
- previewFlowModel(o) {
374
- const n = o ?? e.commands;
375
+ previewFlowModel(s) {
376
+ const o = s ?? e.commands;
375
377
  let i = t.flowModel.value;
376
- for (const r of n)
377
- i = Te(i, r);
378
+ for (const r of o)
379
+ i = Re(i, r);
378
380
  return i;
379
381
  }
380
382
  };
381
383
  }
382
384
  }
383
- function bo(s) {
384
- const { schema: e, plugins: t = [], historyOptions: o } = s, n = { version: "1.0", ...s.initialFlowModel }, i = bt(n, o), r = L(s.mode ?? "edit"), l = L(!1), a = L(null), f = L([]), d = {}, b = new xt();
385
- function m(w, x, A, U = "user:toolbar") {
386
- const O = {
385
+ let Dt = 0;
386
+ function Z() {
387
+ const n = Date.now().toString(36), e = Math.random().toString(36).substring(2, 8);
388
+ return `${n}-${e}-${++Dt}`;
389
+ }
390
+ const Oe = () => Z();
391
+ function an(n) {
392
+ const { schema: e, plugins: t = [], historyOptions: s } = n, o = n.idGenerator ?? Oe, i = { version: "1.0", ...n.initialFlowModel }, r = _t(i, s), l = O(n.mode ?? "edit"), a = O(!1), p = O(null), c = O([]), g = {}, u = new Mt();
393
+ function y(D, L, H, K = "user:toolbar") {
394
+ const $ = {
387
395
  id: `history-${Date.now()}`,
388
- source: U,
389
- label: w,
396
+ source: K,
397
+ label: D,
390
398
  timestamp: Date.now(),
391
399
  commands: []
392
400
  };
393
- b.afterCommand(O, x, A), f.value = b.collectToolbarItems(), s.onCommandResult?.({
401
+ u.afterCommand($, L, H), c.value = u.collectToolbarItems(), n.onCommandResult?.({
394
402
  status: "applied",
395
- envelope: O,
396
- flowModel: A
397
- }), s.onFlowModelChange?.({
398
- flowModel: A,
399
- prevFlowModel: x,
400
- envelope: O,
401
- source: U
403
+ envelope: $,
404
+ flowModel: H
405
+ }), n.onFlowModelChange?.({
406
+ flowModel: H,
407
+ prevFlowModel: L,
408
+ envelope: $,
409
+ source: K
402
410
  });
403
411
  }
404
- const g = {
405
- execute: i.execute,
412
+ const v = {
413
+ execute: r.execute,
406
414
  undo() {
407
- const w = i.currentFlowModel.value, x = i.undo();
408
- return x && m("撤销", w, x), x;
415
+ const D = r.currentFlowModel.value, L = r.undo();
416
+ return L && y("撤销", D, L), L;
409
417
  },
410
418
  redo() {
411
- const w = i.currentFlowModel.value, x = i.redo();
412
- return x && m("重做", w, x), x;
419
+ const D = r.currentFlowModel.value, L = r.redo();
420
+ return L && y("重做", D, L), L;
413
421
  },
414
422
  get canUndo() {
415
- return i.canUndo;
423
+ return r.canUndo;
416
424
  },
417
425
  get canRedo() {
418
- return i.canRedo;
426
+ return r.canRedo;
419
427
  },
420
428
  get undoStack() {
421
- return i.undoStack;
429
+ return r.undoStack;
422
430
  },
423
431
  get redoStack() {
424
- return i.redoStack;
432
+ return r.redoStack;
425
433
  },
426
- clear: i.clear,
427
- createSnapshot: i.createSnapshot,
428
- replaceFlowModel(w) {
429
- const x = i.currentFlowModel.value;
430
- i.replaceFlowModel(w), m("替换 FlowModel", x, w, "system:replace");
431
- }
432
- }, S = {
433
- flowModel: H(() => i.currentFlowModel.value),
434
- history: g,
434
+ clear: r.clear,
435
+ createSnapshot: r.createSnapshot,
436
+ replaceFlowModel(D) {
437
+ const L = r.currentFlowModel.value;
438
+ r.replaceFlowModel(D), y("替换 FlowModel", L, D, "system:replace");
439
+ }
440
+ }, C = {
441
+ flowModel: j(() => r.currentFlowModel.value),
442
+ history: v,
435
443
  schema: e,
436
- mode: r,
437
- executeCommand: k,
438
- replaceFlowModel(w) {
439
- g.replaceFlowModel(w);
444
+ mode: l,
445
+ idGenerator: o,
446
+ executeCommand: M,
447
+ replaceFlowModel(D) {
448
+ v.replaceFlowModel(D);
440
449
  },
441
- setMode(w) {
442
- r.value = w;
450
+ setMode(D) {
451
+ l.value = D;
443
452
  },
444
- selectionMode: l,
445
- setSelectionMode(w) {
446
- l.value = w;
453
+ selectionMode: a,
454
+ setSelectionMode(D) {
455
+ a.value = D;
447
456
  },
448
- api: a,
449
- toolbarItems: f,
450
- extendedApi: d,
451
- _pluginManager: b
457
+ api: p,
458
+ toolbarItems: c,
459
+ extendedApi: g,
460
+ _pluginManager: u,
461
+ _emitUiEvent: (D) => {
462
+ u.dispatchUiEvent(D);
463
+ }
452
464
  };
453
- b.install(t, {
454
- flowModel: S.flowModel,
455
- history: g,
465
+ u.install(t, {
466
+ flowModel: C.flowModel,
467
+ history: v,
456
468
  schema: e,
457
- mode: r,
458
- executeCommand: k
459
- }), f.value = b.collectToolbarItems(), Ue(() => {
460
- b.dispose();
469
+ mode: l,
470
+ idGenerator: o,
471
+ executeCommand: M
472
+ }), c.value = u.collectToolbarItems(), Ye(() => {
473
+ u.dispose();
461
474
  });
462
- function k(w) {
463
- const x = b.transformCommand(w);
464
- if ("rejected" in x) {
465
- const O = {
475
+ function M(D) {
476
+ const L = u.transformCommand(D);
477
+ if ("rejected" in L) {
478
+ const $ = {
466
479
  status: "rejected",
467
- envelope: w,
468
- error: x.error
480
+ envelope: D,
481
+ error: L.error
469
482
  };
470
- return s.onCommandResult?.(O), O;
483
+ return n.onCommandResult?.($), $;
471
484
  }
472
- const A = x.envelope, U = i.currentFlowModel.value;
485
+ const H = L.envelope, K = r.currentFlowModel.value;
473
486
  try {
474
- const O = i.execute(A), K = {
487
+ const $ = r.execute(H), W = {
475
488
  status: "applied",
476
- envelope: A,
477
- flowModel: O
489
+ envelope: H,
490
+ flowModel: $
478
491
  };
479
- return b.afterCommand(A, U, O), f.value = b.collectToolbarItems(), s.onCommandResult?.(K), s.onFlowModelChange?.({
480
- flowModel: O,
481
- prevFlowModel: U,
482
- envelope: A,
483
- source: A.source
484
- }), K;
485
- } catch (O) {
486
- if (O instanceof Y) {
487
- const K = {
492
+ return u.afterCommand(H, K, $), c.value = u.collectToolbarItems(), n.onCommandResult?.(W), n.onFlowModelChange?.({
493
+ flowModel: $,
494
+ prevFlowModel: K,
495
+ envelope: H,
496
+ source: H.source
497
+ }), W;
498
+ } catch ($) {
499
+ if ($ instanceof ae) {
500
+ const W = {
488
501
  status: "invalid",
489
- envelope: A,
502
+ envelope: H,
490
503
  error: {
491
504
  code: "constraint_violated",
492
- reason: O.message,
505
+ reason: $.message,
493
506
  source: "engine"
494
507
  }
495
508
  };
496
- return s.onCommandResult?.(K), K;
509
+ return n.onCommandResult?.(W), W;
497
510
  }
498
- throw O;
511
+ throw $;
499
512
  }
500
513
  }
501
- return S;
514
+ return C;
502
515
  }
503
- const kt = ["top", "right", "bottom", "left"];
504
- function Qe() {
505
- return kt.map((s) => ({ id: s, group: s }));
516
+ const At = ["top", "right", "bottom", "left"];
517
+ function et() {
518
+ return At.map((n) => ({ id: n, group: n }));
506
519
  }
507
- function Be(s, e) {
508
- return e?.(s) ?? s.ports ?? Qe();
520
+ function Be(n, e) {
521
+ return e?.(n) ?? n.ports ?? et();
509
522
  }
510
- class Ct {
523
+ const De = -1, Pt = "flow-canvas-node-ring-target", He = "flow-canvas-node-ring-target--decorated", Ge = "flow-canvas-node-ring-target--pulse", Tt = "linear-gradient(135deg, #cadcfa 0%, #cee0ff 100%)";
524
+ class Rt {
511
525
  graph;
512
526
  schema;
513
527
  shapeRegistry;
@@ -532,15 +546,15 @@ class Ct {
532
546
  /** x6EdgeConfig 中 attrs.line 的基线值,清理时恢复而非删除 */
533
547
  edgeDefaultAttrs = /* @__PURE__ */ new Map();
534
548
  lastModel = null;
535
- constructor(e, t, o, n, i, r) {
536
- this.graph = e, this.schema = t, this.shapeRegistry = o, this.resolveNodeDecoration = n, this.resolveEdgeDecoration = i, this.resolveCanvasContext = r;
549
+ constructor(e, t, s, o, i, r) {
550
+ this.graph = e, this.schema = t, this.shapeRegistry = s, this.resolveNodeDecoration = o, this.resolveEdgeDecoration = i, this.resolveCanvasContext = r;
537
551
  }
538
552
  syncFlowModel(e) {
539
553
  if (!this.syncing) {
540
554
  this.syncing = !0, this.lastModel = e;
541
555
  try {
542
- const t = this.resolveNodes(e), o = this.resolveEdges(e);
543
- this.syncNodes(t), this.syncEdges(o, e);
556
+ const t = this.resolveNodes(e), s = this.resolveEdges(e);
557
+ this.syncNodes(t), this.syncEdges(s, e);
544
558
  } finally {
545
559
  this.syncing = !1;
546
560
  }
@@ -554,35 +568,48 @@ class Ct {
554
568
  * 仅在节点首次创建时调用一次。
555
569
  */
556
570
  saveNodeDefaultAttrs(e, t) {
557
- const n = t.x6CellConfig?.attrs?.body;
558
- if (!n) return;
571
+ const o = t.x6CellConfig?.attrs?.body;
572
+ if (!o) return;
559
573
  const i = {};
560
574
  let r = !1;
561
- n.stroke !== void 0 && (i.stroke = n.stroke, r = !0), n.strokeWidth !== void 0 && (i.strokeWidth = n.strokeWidth, r = !0), r && this.nodeDefaultAttrs.set(e, i);
575
+ o.stroke !== void 0 && (i.stroke = o.stroke, r = !0), o.strokeWidth !== void 0 && (i.strokeWidth = o.strokeWidth, r = !0), r && this.nodeDefaultAttrs.set(e, i);
562
576
  }
563
577
  /**
564
578
  * 从 x6EdgeConfig.attrs.line 中提取基线描边,用于管理层清理时恢复。
565
579
  */
566
580
  saveEdgeDefaultAttrs(e, t) {
567
- const n = t?.x6EdgeConfig?.attrs?.line;
568
- if (!n) return;
581
+ const o = t?.x6EdgeConfig?.attrs?.line;
582
+ if (!o) return;
569
583
  const i = {};
570
584
  let r = !1;
571
- n.stroke !== void 0 && (i.stroke = n.stroke, r = !0), n.strokeWidth !== void 0 && (i.strokeWidth = n.strokeWidth, r = !0), n.strokeDasharray !== void 0 && (i.strokeDasharray = n.strokeDasharray, r = !0), r && this.edgeDefaultAttrs.set(e, i);
585
+ o.stroke !== void 0 && (i.stroke = o.stroke, r = !0), o.strokeWidth !== void 0 && (i.strokeWidth = o.strokeWidth, r = !0), o.strokeDasharray !== void 0 && (i.strokeDasharray = o.strokeDasharray, r = !0), r && this.edgeDefaultAttrs.set(e, i);
572
586
  }
573
- /** 恢复节点 attr 到基线值;无基线时移除。 */
574
- restoreNodeAttr(e, t, o) {
575
- const n = this.nodeDefaultAttrs.get(e.id)?.[o];
576
- n !== void 0 ? e.setAttrByPath(t, n) : e.removeAttrByPath(t);
587
+ /**
588
+ * 恢复节点 attr 到基线值;无基线时设为安全默认值。
589
+ * 不使用 removeAttrByPath,因为对 Vue Shape 节点执行 remove 会触发 X6
590
+ * 完整的 cell view 重渲染,可能导致 foreignObject 尺寸被瞬间重置,
591
+ * 使得内部 Vue 组件 (width/height: 100%) 折叠后无法恢复。
592
+ */
593
+ restoreNodeAttr(e, t, s) {
594
+ const o = this.nodeDefaultAttrs.get(e.id)?.[s];
595
+ if (o !== void 0)
596
+ e.setAttrByPath(t, o);
597
+ else {
598
+ const i = s === "stroke" ? "none" : 0;
599
+ e.setAttrByPath(t, i);
600
+ }
577
601
  }
578
602
  /** 恢复边 attr 到基线值;无基线时移除。 */
579
- restoreEdgeAttr(e, t, o) {
580
- const n = this.edgeDefaultAttrs.get(e.id)?.[o];
581
- n !== void 0 ? e.setAttrByPath(t, n) : e.removeAttrByPath(t);
603
+ restoreEdgeAttr(e, t, s) {
604
+ const o = this.edgeDefaultAttrs.get(e.id)?.[s];
605
+ o !== void 0 ? e.setAttrByPath(t, o) : e.removeAttrByPath(t);
606
+ }
607
+ getNodeRingTarget(e) {
608
+ return e ? e.querySelector(".flow-canvas-highlight-target") ?? e.querySelector(".flow-canvas-node-surface > :first-child") : null;
582
609
  }
583
610
  /** 让正式边接管交互式预览边时,恢复 schema 定义的端点 marker。 */
584
- syncEdgeMarker(e, t, o) {
585
- const i = t?.x6EdgeConfig?.attrs?.line?.[o], r = `line/${o}`;
611
+ syncEdgeMarker(e, t, s) {
612
+ const i = t?.x6EdgeConfig?.attrs?.line?.[s], r = `line/${s}`;
586
613
  e.removeAttrByPath(r), i !== void 0 && e.setAttrByPath(r, i);
587
614
  }
588
615
  dispose() {
@@ -590,59 +617,64 @@ class Ct {
590
617
  }
591
618
  resolveNodes(e) {
592
619
  const t = /* @__PURE__ */ new Map();
593
- for (const [o, n] of Object.entries(e.nodes)) {
594
- const i = this.schema.nodeTypes[n.type];
620
+ for (const [s, o] of Object.entries(e.nodes)) {
621
+ const i = this.schema.nodeTypes[o.type];
595
622
  if (!i)
596
- throw new it(
597
- `Unknown node type "${n.type}" for node "${o}". Registered types: [${Object.keys(this.schema.nodeTypes).join(", ")}]. Register the type in CanvasSchema.nodeTypes before using it in a FlowModel.`
623
+ throw new pt(
624
+ `Unknown node type "${o.type}" for node "${s}". Registered types: [${Object.keys(this.schema.nodeTypes).join(", ")}]. Register the type in CanvasSchema.nodeTypes before using it in a FlowModel.`
598
625
  );
599
- const r = this.shapeRegistry.registerNodeType(n.type, i.component), l = i.getSize(n), a = Be(n, i.getPorts);
600
- t.set(o, { model: n, definition: i, shapeName: r, size: l, ports: a });
626
+ const r = this.shapeRegistry.registerNodeType(o.type, i.component), l = i.getSize(o), a = Be(o, i.getPorts);
627
+ t.set(s, { model: o, definition: i, shapeName: r, size: l, ports: a });
601
628
  }
602
629
  return t;
603
630
  }
604
631
  resolveEdges(e) {
605
632
  const t = /* @__PURE__ */ new Map();
606
- for (const [o, n] of Object.entries(e.edges)) {
607
- const i = n.type ?? this.schema.defaultEdgeType ?? "default", r = this.schema.edgeTypes?.[i];
608
- t.set(o, { model: n, definition: r });
633
+ for (const [s, o] of Object.entries(e.edges)) {
634
+ const i = o.type ?? this.schema.defaultEdgeType ?? "default", r = this.schema.edgeTypes?.[i];
635
+ t.set(s, { model: o, definition: r });
609
636
  }
610
637
  return t;
611
638
  }
612
639
  syncNodes(e) {
613
640
  const t = new Set(e.keys());
614
- for (const o of this.knownNodeIds)
615
- if (!t.has(o)) {
616
- const n = this.graph.getCellById(o);
617
- n && this.graph.removeCell(n), this.knownNodeIds.delete(o), this.defaultHighlightedNodeIds.delete(o), this.prevNodeDecorationClasses.delete(o), this.prevNodeDecorationColors.delete(o), this.nodeDefaultAttrs.delete(o);
641
+ for (const s of this.knownNodeIds)
642
+ if (!t.has(s)) {
643
+ const o = this.graph.getCellById(s);
644
+ o && this.graph.removeCell(o), this.knownNodeIds.delete(s), this.defaultHighlightedNodeIds.delete(s), this.prevNodeDecorationClasses.delete(s), this.prevNodeDecorationColors.delete(s), this.nodeDefaultAttrs.delete(s);
618
645
  }
619
- for (const [o, n] of e) {
620
- const i = this.graph.getCellById(o);
621
- i ? this.updateExistingNode(i, n) : this.addNewNode(o, n);
646
+ for (const [s, o] of e) {
647
+ const i = this.graph.getCellById(s);
648
+ i ? this.updateExistingNode(i, o) : this.addNewNode(s, o);
622
649
  }
623
650
  }
624
651
  updateExistingNode(e, t) {
625
- const { model: o, size: n, ports: i, definition: r } = t, l = e.getPosition();
626
- (l.x !== o.position.x || l.y !== o.position.y) && e.setPosition(o.position.x, o.position.y);
627
- const a = e.getSize();
628
- (a.width !== n.width || a.height !== n.height) && e.setSize(n.width, n.height, { silent: !0 }), this.syncNodePorts(e, i), e.setData({ ...o }), this.applyNodeBehavior(e, o, r), this.applyNodeHighlightAndDecoration(e, o);
652
+ const { model: s, size: o, ports: i, definition: r } = t;
653
+ if (e.getData()?.type !== s.type) {
654
+ this.graph.removeCell(e), this.addNewNode(e.id, t);
655
+ return;
656
+ }
657
+ const a = e.getPosition();
658
+ (a.x !== s.position.x || a.y !== s.position.y) && e.setPosition(s.position.x, s.position.y);
659
+ const p = e.getSize();
660
+ (p.width !== o.width || p.height !== o.height) && e.setSize(o.width, o.height, { silent: !0 }), this.syncNodePorts(e, i), e.setData({ ...s }), this.applyNodeBehavior(e, s, r), this.applyNodeHighlightAndDecoration(e, s);
629
661
  }
630
662
  syncNodePorts(e, t) {
631
- const o = e.getPorts(), n = new Set(t.map((r) => r.id)), i = new Set(o.map((r) => r.id));
632
- for (const r of o)
633
- r.id && !n.has(r.id) && e.removePort(r.id);
663
+ const s = e.getPorts(), o = new Set(t.map((r) => r.id)), i = new Set(s.map((r) => r.id));
664
+ for (const r of s)
665
+ r.id && !o.has(r.id) && e.removePort(r.id);
634
666
  for (const r of t)
635
667
  i.has(r.id) || e.addPort({ id: r.id, group: r.group, ...r.x6PortConfig });
636
668
  }
637
669
  addNewNode(e, t) {
638
- const { model: o, shapeName: n, size: i, ports: r, definition: l } = t, a = {
639
- id: o.id,
640
- shape: n,
641
- x: o.position.x,
642
- y: o.position.y,
670
+ const { model: s, shapeName: o, size: i, ports: r, definition: l } = t, a = {
671
+ id: s.id,
672
+ shape: o,
673
+ x: s.position.x,
674
+ y: s.position.y,
643
675
  width: i.width,
644
676
  height: i.height,
645
- data: { ...o },
677
+ data: { ...s },
646
678
  ports: {
647
679
  groups: {
648
680
  top: {
@@ -670,51 +702,54 @@ class Ct {
670
702
  }
671
703
  }
672
704
  },
673
- items: r.map((d) => ({ id: d.id, group: d.group, ...d.x6PortConfig }))
705
+ items: r.map((c) => ({ id: c.id, group: c.group, ...c.x6PortConfig }))
674
706
  },
675
707
  ...l.x6CellConfig
676
708
  };
677
709
  this.graph.addNode(a), this.knownNodeIds.add(e), this.saveNodeDefaultAttrs(e, l);
678
- const f = this.graph.getCellById(e);
679
- f && (this.applyNodeBehavior(f, o, l), this.applyNodeHighlightAndDecoration(f, o));
710
+ const p = this.graph.getCellById(e);
711
+ p && (this.applyNodeBehavior(p, s, l), this.applyNodeHighlightAndDecoration(p, s));
680
712
  }
681
713
  /**
682
714
  * 将 schema 定义的 getBehavior 映射到 X6 节点属性。
683
715
  * NodeBehaviorConfig 的每个字段都映射到 X6 Cell 对应能力:
684
716
  * - draggable → 是否可拖拽移动
685
717
  * - selectable → 是否可被选中(注意:X6 Selection 插件也有全局控制)
686
- * - connectable → ports 的 magnet 属性,控制是否可从该节点发起连线
718
+ * - connectable / targetable → ports 的 magnet 属性
719
+ * true → 可发起,也可作为目标
720
+ * 'passive' → 不可发起,但仍可作为目标(如结束节点)
721
+ * false → 不可发起,也不可作为目标
687
722
  * - showPorts → ports 的可见性
688
723
  * - deletable → 存入 cell data,由删除操作(插件/快捷键)自行读取判断
689
724
  */
690
- applyNodeBehavior(e, t, o) {
691
- if (!o.getBehavior) return;
692
- const n = this.resolveCanvasContext?.();
693
- if (!n) return;
694
- const i = o.getBehavior(t, n);
725
+ applyNodeBehavior(e, t, s) {
726
+ if (!s.getBehavior) return;
727
+ const o = this.resolveCanvasContext?.();
728
+ if (!o) return;
729
+ const i = s.getBehavior(t, o);
695
730
  if (i.draggable !== void 0 && e.setProp("draggable", i.draggable, { silent: !0 }), i.connectable !== void 0) {
696
- const l = i.connectable;
731
+ const l = i.connectable ? !0 : i.targetable === !1 ? !1 : "passive";
697
732
  for (const a of e.getPorts())
698
733
  e.setPortProp(a.id, "attrs/circle/magnet", l, { silent: !0 });
699
734
  }
700
735
  if (i.showPorts !== void 0) {
701
736
  const l = i.showPorts;
702
737
  for (const a of e.getPorts())
703
- e.setPortProp(a.id, "attrs/circle/style/visibility", l ? "visible" : "hidden", { silent: !0 });
738
+ e.setPortProp(a.id, "attrs/circle/visibility", l ? "visible" : "hidden", { silent: !0 });
704
739
  }
705
740
  const r = e.getData() ?? {};
706
741
  i.deletable !== void 0 && r._deletable !== i.deletable && e.setData({ ...r, _deletable: i.deletable }, { silent: !0 }), i.selectable !== void 0 && r._selectable !== i.selectable && e.setData({ ...e.getData(), _selectable: i.selectable }, { silent: !0 });
707
742
  }
708
743
  syncEdges(e, t) {
709
- const o = new Set(e.keys());
710
- for (const n of this.knownEdgeIds)
711
- if (!o.has(n)) {
712
- const i = this.graph.getCellById(n);
713
- i && this.graph.removeCell(i), this.knownEdgeIds.delete(n), this.defaultHighlightedEdgeIds.delete(n), this.prevEdgeDecorationClasses.delete(n), this.prevEdgeDecorationColors.delete(n), this.prevEdgeStyleIds.delete(n), this.edgeDefaultAttrs.delete(n);
744
+ const s = new Set(e.keys());
745
+ for (const o of this.knownEdgeIds)
746
+ if (!s.has(o)) {
747
+ const i = this.graph.getCellById(o);
748
+ i && this.graph.removeCell(i), this.knownEdgeIds.delete(o), this.defaultHighlightedEdgeIds.delete(o), this.prevEdgeDecorationClasses.delete(o), this.prevEdgeDecorationColors.delete(o), this.prevEdgeStyleIds.delete(o), this.edgeDefaultAttrs.delete(o);
714
749
  }
715
- for (const [n, i] of e) {
716
- const r = this.graph.getCellById(n), { model: l, definition: a } = i;
717
- r ? (this.updateExistingEdge(r, l, a, t), this.knownEdgeIds.has(n) || (this.knownEdgeIds.add(n), this.saveEdgeDefaultAttrs(n, a))) : this.addNewEdge(n, l, a);
750
+ for (const [o, i] of e) {
751
+ const r = this.graph.getCellById(o), { model: l, definition: a } = i;
752
+ r ? (this.updateExistingEdge(r, l, a, t), this.knownEdgeIds.has(o) || (this.knownEdgeIds.add(o), this.saveEdgeDefaultAttrs(o, a))) : this.addNewEdge(o, l, a);
718
753
  }
719
754
  }
720
755
  /**
@@ -722,45 +757,45 @@ class Ct {
722
757
  * X6 Edge.getSource() 返回 { cell, port } 格式,与 FlowEdgeModel 的 { nodeId, portId } 不同,
723
758
  * 需要用 (currentSource as any).cell 来比较。
724
759
  */
725
- updateExistingEdge(e, t, o, n) {
760
+ updateExistingEdge(e, t, s, o) {
726
761
  const i = e.getSource(), r = e.getTarget();
727
- if ((i.cell !== t.source.nodeId || i.port !== t.source.portId) && e.setSource({ cell: t.source.nodeId, port: t.source.portId }), (r.cell !== t.target.nodeId || r.port !== t.target.portId) && e.setTarget({ cell: t.target.nodeId, port: t.target.portId }), o?.router) {
728
- const l = typeof o.router == "string" ? { name: o.router } : o.router;
762
+ if ((i.cell !== t.source.nodeId || i.port !== t.source.portId) && e.setSource({ cell: t.source.nodeId, port: t.source.portId }), (r.cell !== t.target.nodeId || r.port !== t.target.portId) && e.setTarget({ cell: t.target.nodeId, port: t.target.portId }), s?.router) {
763
+ const l = typeof s.router == "string" ? { name: s.router } : s.router;
729
764
  e.setRouter(l);
730
765
  }
731
- if (o?.connector) {
732
- const l = typeof o.connector == "string" ? { name: o.connector } : o.connector;
766
+ if (s?.connector) {
767
+ const l = typeof s.connector == "string" ? { name: s.connector } : s.connector;
733
768
  e.setConnector(l);
734
769
  }
735
- this.syncEdgeMarker(e, o, "sourceMarker"), this.syncEdgeMarker(e, o, "targetMarker"), this.syncEdgeLabels(e, t), e.setData({ ...t }, { silent: !0 }), this.applyEdgeStyleAndDecoration(e, t, o);
770
+ this.syncEdgeMarker(e, s, "sourceMarker"), this.syncEdgeMarker(e, s, "targetMarker"), this.syncEdgeLabels(e, t), e.getZIndex() !== De && e.setZIndex(De), e.setData({ ...t }, { silent: !0 }), this.applyEdgeStyleAndDecoration(e, t, s);
736
771
  }
737
772
  syncEdgeLabels(e, t) {
738
773
  if (!t.labels?.length) {
739
774
  e.getLabels().length > 0 && e.setLabels([]);
740
775
  return;
741
776
  }
742
- const o = t.labels.map((n) => ({
777
+ const s = t.labels.map((o) => ({
743
778
  attrs: {
744
- label: { text: n.text ?? "" }
779
+ label: { text: o.text ?? "" }
745
780
  },
746
- position: n.position != null ? { distance: n.position } : void 0
781
+ position: o.position != null ? { distance: o.position } : void 0
747
782
  }));
748
- e.setLabels(o);
783
+ e.setLabels(s);
749
784
  }
750
- addNewEdge(e, t, o) {
751
- const n = {
785
+ addNewEdge(e, t, s) {
786
+ const o = {
752
787
  id: t.id,
753
788
  source: { cell: t.source.nodeId, port: t.source.portId },
754
789
  target: { cell: t.target.nodeId, port: t.target.portId },
755
790
  data: { ...t },
756
- zIndex: -1
791
+ zIndex: De
757
792
  };
758
- o?.router && (n.router = typeof o.router == "string" ? { name: o.router } : o.router), o?.connector && (n.connector = typeof o.connector == "string" ? { name: o.connector } : o.connector), o?.x6EdgeConfig && Object.assign(n, o.x6EdgeConfig), t.labels?.length && (n.labels = t.labels.map((r) => ({
793
+ s?.router && (o.router = typeof s.router == "string" ? { name: s.router } : s.router), s?.connector && (o.connector = typeof s.connector == "string" ? { name: s.connector } : s.connector), s?.x6EdgeConfig && Object.assign(o, s.x6EdgeConfig), t.labels?.length && (o.labels = t.labels.map((r) => ({
759
794
  attrs: { label: { text: r.text ?? "" } },
760
795
  position: r.position != null ? { distance: r.position } : void 0
761
- }))), this.graph.addEdge(n), this.knownEdgeIds.add(e), this.saveEdgeDefaultAttrs(e, o);
796
+ }))), this.graph.addEdge(o), this.knownEdgeIds.add(e), this.saveEdgeDefaultAttrs(e, s);
762
797
  const i = this.graph.getCellById(e);
763
- i && this.applyEdgeStyleAndDecoration(i, t, o);
798
+ i && this.applyEdgeStyleAndDecoration(i, t, s);
764
799
  }
765
800
  /**
766
801
  * 外部通知选区、高亮或 hover 变化时,重算所有边的视觉样式。
@@ -770,10 +805,10 @@ class Ct {
770
805
  refreshEdgeStyles() {
771
806
  if (this.lastModel)
772
807
  for (const [e, t] of Object.entries(this.lastModel.edges)) {
773
- const o = this.graph.getCellById(e);
774
- if (!o?.isEdge()) continue;
775
- const n = t.type ?? this.schema.defaultEdgeType ?? "default", i = this.schema.edgeTypes?.[n];
776
- this.applyEdgeStyleAndDecoration(o, t, i);
808
+ const s = this.graph.getCellById(e);
809
+ if (!s?.isEdge()) continue;
810
+ const o = t.type ?? this.schema.defaultEdgeType ?? "default", i = this.schema.edgeTypes?.[o];
811
+ this.applyEdgeStyleAndDecoration(s, t, i);
777
812
  }
778
813
  }
779
814
  /**
@@ -782,26 +817,30 @@ class Ct {
782
817
  refreshNodeHighlights() {
783
818
  if (this.lastModel)
784
819
  for (const [e, t] of Object.entries(this.lastModel.nodes)) {
785
- const o = this.graph.getCellById(e);
786
- o?.isNode() && this.applyNodeHighlightAndDecoration(o, t);
820
+ const s = this.graph.getCellById(e);
821
+ s?.isNode() && this.applyNodeHighlightAndDecoration(s, t);
787
822
  }
788
823
  }
789
824
  /**
790
825
  * 单节点的高亮 + 装饰统一管道。
791
826
  * 所有路径(FlowModel 同步更新/新增节点/显式刷新高亮)必须走此方法。
792
827
  *
793
- * body/stroke 的分层优先级(低 → 高):
828
+ * 可见高亮的分层优先级(低 → 高):
794
829
  * 1. 默认高亮 (#3a84ff) — 节点在 highlightedNodeIds 中时兜底
795
830
  * 2. 插件装饰 (decorateNode().borderColor) — 始终覆盖高亮
796
831
  *
797
832
  * 最终值 = decorationColor ?? highlightColor ?? (清除)。
798
- * 只在"曾经设过 现在无值"时执行 removeAttrByPath,避免误删 X6 原始样式。
833
+ * Vue Shape 节点,真正可见的 ring 通过节点高亮目标元素的独立装饰态 / 脉冲态 / 选中态 class 呈现;
834
+ * body/stroke 仅作为普通 SVG shape 的兜底同步。
799
835
  */
800
836
  applyNodeHighlightAndDecoration(e, t) {
801
- const o = this.highlightedNodeIds.has(e.id), n = this.resolveNodeDecoration?.(t), i = this.prevNodeDecorationClasses.get(e.id);
802
- i && (this.graph.findViewByCell(e)?.container?.classList.remove(i), this.prevNodeDecorationClasses.delete(e.id)), n?.className && (this.graph.findViewByCell(e)?.container?.classList.add(n.className), this.prevNodeDecorationClasses.set(e.id, n.className));
803
- const r = n?.borderColor, a = r ?? (o ? "#3a84ff" : void 0), f = this.prevNodeDecorationColors.has(e.id) || this.defaultHighlightedNodeIds.has(e.id);
804
- a ? (e.setAttrByPath("body/stroke", a), e.setAttrByPath("body/strokeWidth", 2)) : f && (this.restoreNodeAttr(e, "body/stroke", "stroke"), this.restoreNodeAttr(e, "body/strokeWidth", "strokeWidth")), r ? this.prevNodeDecorationColors.add(e.id) : this.prevNodeDecorationColors.delete(e.id), o && !r ? this.defaultHighlightedNodeIds.add(e.id) : this.defaultHighlightedNodeIds.delete(e.id);
837
+ const s = this.highlightedNodeIds.has(e.id), o = this.resolveNodeDecoration?.(t), i = this.graph.findViewByCell(e)?.container, r = this.getNodeRingTarget(i), l = this.prevNodeDecorationClasses.get(e.id);
838
+ l && (i?.classList.remove(l), this.prevNodeDecorationClasses.delete(e.id)), o?.className && (i?.classList.add(o.className), this.prevNodeDecorationClasses.set(e.id, o.className));
839
+ const a = o?.borderColor, c = a ?? (s ? "#3a84ff" : void 0), g = this.prevNodeDecorationColors.has(e.id) || this.defaultHighlightedNodeIds.has(e.id);
840
+ c ? (e.setAttrByPath("body/stroke", c), e.setAttrByPath("body/strokeWidth", 2)) : g && (this.restoreNodeAttr(e, "body/stroke", "stroke"), this.restoreNodeAttr(e, "body/strokeWidth", "strokeWidth")), r && (r.classList.add(Pt), a ? (r.classList.add(He), r.style.setProperty("--flow-canvas-node-decoration-ring-background", a), r.style.setProperty("--flow-canvas-node-decoration-ring-opacity", "0.95")) : (r.classList.remove(He), r.style.removeProperty("--flow-canvas-node-decoration-ring-background"), r.style.removeProperty("--flow-canvas-node-decoration-ring-opacity")), s ? (r.classList.add(Ge), r.style.setProperty(
841
+ "--flow-canvas-node-pulse-ring-background",
842
+ a ?? Tt
843
+ ), r.style.setProperty("--flow-canvas-node-pulse-ring-opacity", "0.95")) : (r.classList.remove(Ge), r.style.removeProperty("--flow-canvas-node-pulse-ring-background"), r.style.removeProperty("--flow-canvas-node-pulse-ring-opacity"))), a ? this.prevNodeDecorationColors.add(e.id) : this.prevNodeDecorationColors.delete(e.id), s && !a ? this.defaultHighlightedNodeIds.add(e.id) : this.defaultHighlightedNodeIds.delete(e.id);
805
844
  }
806
845
  setHoveredEdge(e) {
807
846
  this.hoveredEdgeId = e;
@@ -823,51 +862,54 @@ class Ct {
823
862
  * strokeWidth / strokeDasharray 仅由 schema style() 控制,不受装饰影响。
824
863
  * 最终值 = decorationStroke ?? styleStroke ?? defaultHighlightStroke ?? (清除)。
825
864
  */
826
- applyEdgeStyleAndDecoration(e, t, o) {
827
- const n = this.highlightedEdgeIds.has(e.id), i = this.resolveEdgeDecoration?.(t), r = this.prevEdgeDecorationClasses.get(e.id);
865
+ applyEdgeStyleAndDecoration(e, t, s) {
866
+ const o = this.highlightedEdgeIds.has(e.id), i = this.resolveEdgeDecoration?.(t), r = this.prevEdgeDecorationClasses.get(e.id);
828
867
  r && (this.graph.findViewByCell(e)?.container?.classList.remove(r), this.prevEdgeDecorationClasses.delete(e.id)), i?.className && (this.graph.findViewByCell(e)?.container?.classList.add(i.className), this.prevEdgeDecorationClasses.set(e.id, i.className));
829
- let l, a, f;
830
- if (o?.style) {
831
- const S = this.graph.isSelected?.(e) ?? !1, k = this.hoveredEdgeId === e.id, w = o.style(t, { selected: S, highlighted: n, hovered: k });
832
- l = w.stroke, a = w.strokeWidth, f = w.strokeDasharray;
868
+ let l, a, p;
869
+ if (s?.style) {
870
+ const v = this.graph.isSelected?.(e) ?? !1, C = this.hoveredEdgeId === e.id, M = s.style(t, { selected: v, highlighted: o, hovered: C });
871
+ l = M.stroke, a = M.strokeWidth, p = M.strokeDasharray;
833
872
  }
834
- const d = !o?.style && n ? "#3a84ff" : void 0, b = i?.strokeColor, m = b ?? l ?? d, g = !!o?.style || this.prevEdgeDecorationColors.has(e.id) || this.defaultHighlightedEdgeIds.has(e.id) || this.prevEdgeStyleIds.has(e.id);
835
- m ? e.setAttrByPath("line/stroke", m) : g && this.restoreEdgeAttr(e, "line/stroke", "stroke"), o?.style ? (this.prevEdgeStyleIds.add(e.id), a ? e.setAttrByPath("line/strokeWidth", a) : this.restoreEdgeAttr(e, "line/strokeWidth", "strokeWidth"), f ? e.setAttrByPath("line/strokeDasharray", f) : this.restoreEdgeAttr(e, "line/strokeDasharray", "strokeDasharray")) : this.prevEdgeStyleIds.has(e.id) && (this.restoreEdgeAttr(e, "line/strokeWidth", "strokeWidth"), this.restoreEdgeAttr(e, "line/strokeDasharray", "strokeDasharray"), this.prevEdgeStyleIds.delete(e.id)), b ? this.prevEdgeDecorationColors.add(e.id) : this.prevEdgeDecorationColors.delete(e.id), d ? this.defaultHighlightedEdgeIds.add(e.id) : this.defaultHighlightedEdgeIds.delete(e.id);
873
+ const c = !s?.style && o ? "#3a84ff" : void 0, g = i?.strokeColor, u = g ?? l ?? c, y = !!s?.style || this.prevEdgeDecorationColors.has(e.id) || this.defaultHighlightedEdgeIds.has(e.id) || this.prevEdgeStyleIds.has(e.id);
874
+ u ? e.setAttrByPath("line/stroke", u) : y && this.restoreEdgeAttr(e, "line/stroke", "stroke"), s?.style ? (this.prevEdgeStyleIds.add(e.id), a ? e.setAttrByPath("line/strokeWidth", a) : this.restoreEdgeAttr(e, "line/strokeWidth", "strokeWidth"), p ? e.setAttrByPath("line/strokeDasharray", p) : this.restoreEdgeAttr(e, "line/strokeDasharray", "strokeDasharray")) : this.prevEdgeStyleIds.has(e.id) && (this.restoreEdgeAttr(e, "line/strokeWidth", "strokeWidth"), this.restoreEdgeAttr(e, "line/strokeDasharray", "strokeDasharray"), this.prevEdgeStyleIds.delete(e.id)), g ? this.prevEdgeDecorationColors.add(e.id) : this.prevEdgeDecorationColors.delete(e.id), c ? this.defaultHighlightedEdgeIds.add(e.id) : this.defaultHighlightedEdgeIds.delete(e.id);
836
875
  }
837
876
  }
838
- let Et = 0;
839
- function $() {
840
- const s = Date.now().toString(36), e = Math.random().toString(36).substring(2, 8);
841
- return `${s}-${e}-${++Et}`;
842
- }
843
- class It {
844
- instanceId = $();
877
+ class Lt {
878
+ instanceId = Z();
845
879
  registeredShapes = /* @__PURE__ */ new Map();
880
+ wrappedComponents = /* @__PURE__ */ new Map();
846
881
  getShapeName(e) {
847
882
  let t = this.registeredShapes.get(e);
848
883
  return t || (t = `flow-node-${this.instanceId}-${e}`, this.registeredShapes.set(e, t)), t;
849
884
  }
850
885
  registerNodeType(e, t) {
851
- const o = this.getShapeName(e);
852
- return st({
853
- shape: o,
854
- component: t,
886
+ const s = this.getShapeName(e);
887
+ let o = this.wrappedComponents.get(e);
888
+ return o || (o = le({
889
+ name: `FlowCanvasNodeShape${e.replace(/(^|[-_])(\w)/g, (i, r, l) => l.toUpperCase())}`,
890
+ setup() {
891
+ return () => Ae("div", { class: "flow-canvas-node-surface" }, [Ae(t)]);
892
+ }
893
+ }), this.wrappedComponents.set(e, o)), ct({
894
+ shape: s,
895
+ component: o,
855
896
  width: 100,
856
897
  height: 40
857
- }), o;
898
+ }), s;
858
899
  }
859
900
  dispose() {
860
- this.registeredShapes.clear();
901
+ this.registeredShapes.clear(), this.wrappedComponents.clear();
861
902
  }
862
903
  }
863
- class Mt {
904
+ class $t {
864
905
  graph;
865
906
  onUiEvent;
866
907
  onCommand;
867
908
  flowModelRef;
909
+ idGenerator;
868
910
  disposers = [];
869
- constructor(e, t, o, n) {
870
- this.graph = e, this.onUiEvent = t, this.onCommand = o, this.flowModelRef = n, this.bindEvents();
911
+ constructor(e, t, s, o, i) {
912
+ this.graph = e, this.onUiEvent = t, this.onCommand = s, this.flowModelRef = o, this.idGenerator = i ?? Oe, this.bindEvents();
871
913
  }
872
914
  dispose() {
873
915
  for (const e of this.disposers) e();
@@ -885,13 +927,13 @@ class Mt {
885
927
  position: { x: t.clientX, y: t.clientY }
886
928
  });
887
929
  }), this.on("edge:click", ({ edge: e, e: t }) => {
888
- const n = t.target?.closest?.(".x6-edge-label");
889
- if (n) {
890
- const r = e.getData?.()?.labels ?? [], l = n.parentElement?.querySelectorAll(".x6-edge-label"), a = l ? Array.from(l).indexOf(n) : 0, f = r[Math.max(0, a)];
930
+ const o = t.target?.closest?.(".x6-edge-label");
931
+ if (o) {
932
+ const r = e.getData?.()?.labels ?? [], l = o.parentElement?.querySelectorAll(".x6-edge-label"), a = l ? Array.from(l).indexOf(o) : 0, p = r[Math.max(0, a)];
891
933
  this.onUiEvent({
892
934
  type: "edge.label.click",
893
935
  edgeId: e.id,
894
- labelId: f?.id ?? `label-${a}`
936
+ labelId: p?.id ?? `label-${a}`
895
937
  });
896
938
  return;
897
939
  }
@@ -907,18 +949,18 @@ class Mt {
907
949
  }), this.on("node:moved", ({ node: e }) => {
908
950
  const t = e.getPosition();
909
951
  this.onCommand({
910
- id: $(),
952
+ id: Z(),
911
953
  source: "user:drag",
912
954
  label: "移动节点",
913
955
  timestamp: Date.now(),
914
956
  commands: [{ type: "node.move", nodeId: e.id, position: { x: t.x, y: t.y } }]
915
957
  });
916
958
  }), this.on("edge:connected", ({ edge: e, isNew: t }) => {
917
- const o = e.getSourceCell(), n = e.getTargetCell();
918
- if (!o || !n) return;
959
+ const s = e.getSourceCell(), o = e.getTargetCell();
960
+ if (!s || !o) return;
919
961
  const i = e.getSourcePortId(), r = e.getTargetPortId(), l = e.id in this.flowModelRef.value.edges;
920
- t && !l ? this.onCommand({
921
- id: $(),
962
+ t && !l ? (this.graph.removeCell(e), this.onCommand({
963
+ id: Z(),
922
964
  source: "user:drag",
923
965
  label: "连线",
924
966
  timestamp: Date.now(),
@@ -926,14 +968,14 @@ class Mt {
926
968
  {
927
969
  type: "edge.add",
928
970
  edge: {
929
- id: e.id,
930
- source: { nodeId: o.id, portId: i ?? void 0 },
931
- target: { nodeId: n.id, portId: r ?? void 0 }
971
+ id: this.idGenerator("edge"),
972
+ source: { nodeId: s.id, portId: i ?? void 0 },
973
+ target: { nodeId: o.id, portId: r ?? void 0 }
932
974
  }
933
975
  }
934
976
  ]
935
- }) : this.onCommand({
936
- id: $(),
977
+ })) : this.onCommand({
978
+ id: Z(),
937
979
  source: "user:drag",
938
980
  label: "重连",
939
981
  timestamp: Date.now(),
@@ -941,28 +983,28 @@ class Mt {
941
983
  {
942
984
  type: "edge.reconnect",
943
985
  edgeId: e.id,
944
- source: { nodeId: o.id, portId: i ?? void 0 },
945
- target: { nodeId: n.id, portId: r ?? void 0 }
986
+ source: { nodeId: s.id, portId: i ?? void 0 },
987
+ target: { nodeId: o.id, portId: r ?? void 0 }
946
988
  }
947
989
  ]
948
990
  });
949
991
  }), this.on("edge:change:labels", ({ edge: e, current: t }) => {
950
- const n = e.getData?.()?.labels ?? [];
951
- if (!n.length || !t?.length) return;
992
+ const o = e.getData?.()?.labels ?? [];
993
+ if (!o.length || !t?.length) return;
952
994
  const i = [];
953
- for (let r = 0; r < Math.min(n.length, t.length); r++) {
954
- const l = t[r], a = n[r];
995
+ for (let r = 0; r < Math.min(o.length, t.length); r++) {
996
+ const l = t[r], a = o[r];
955
997
  if (!a?.id) continue;
956
- const f = typeof l.position == "object" ? l.position?.distance : l.position;
957
- f != null && i.push({
998
+ const p = typeof l.position == "object" ? l.position?.distance : l.position;
999
+ p != null && i.push({
958
1000
  type: "edge.label.update",
959
1001
  edgeId: e.id,
960
1002
  labelId: a.id,
961
- patch: { position: f }
1003
+ patch: { position: p }
962
1004
  });
963
1005
  }
964
1006
  i.length && this.onCommand({
965
- id: $(),
1007
+ id: Z(),
966
1008
  source: "user:drag",
967
1009
  label: "拖动标签",
968
1010
  timestamp: Date.now(),
@@ -974,120 +1016,155 @@ class Mt {
974
1016
  this.graph.on(e, t), this.disposers.push(() => this.graph.off(e, t));
975
1017
  }
976
1018
  }
977
- function Nt(s) {
1019
+ function Ot(n) {
978
1020
  function e(t) {
979
- const o = s.getCellById(t);
980
- if (!o || !o.isNode()) return null;
981
- const n = o, i = n.getPosition(), r = n.getSize(), l = { x: i.x, y: i.y, width: r.width, height: r.height }, a = s.localToGraph(l);
1021
+ const s = n.getCellById(t);
1022
+ if (!s || !s.isNode()) return null;
1023
+ const o = s, i = o.getPosition(), r = o.getSize(), l = { x: i.x, y: i.y, width: r.width, height: r.height }, a = n.localToGraph(l);
982
1024
  return new DOMRect(a.x, a.y, a.width, a.height);
983
1025
  }
984
1026
  return {
985
1027
  getNodeScreenRect: e
986
1028
  };
987
1029
  }
988
- const St = 100;
989
- function Dt({
990
- graph: s,
1030
+ function tt(n) {
1031
+ return {
1032
+ nodeIds: n.filter((e) => e.isNode()).map((e) => e.id),
1033
+ edgeIds: n.filter((e) => e.isEdge()).map((e) => e.id)
1034
+ };
1035
+ }
1036
+ function Bt(n, e) {
1037
+ const t = [
1038
+ ...e.nodeIds.map((i) => n.getCellById(i)),
1039
+ ...e.edgeIds.map((i) => n.getCellById(i))
1040
+ ].filter((i) => !!i);
1041
+ if (t.length === 0) return null;
1042
+ const s = n.getCellsBBox(t);
1043
+ if (!s) return null;
1044
+ const o = n.localToGraph(s);
1045
+ return new DOMRect(o.x, o.y, o.width, o.height);
1046
+ }
1047
+ function ot(n, e, t) {
1048
+ const s = n.nodeIds.filter((r) => {
1049
+ const l = e.nodes[r];
1050
+ if (!l) return !1;
1051
+ const a = t(l);
1052
+ return a.deletable !== !1 && a.deleteDisabled !== !0;
1053
+ }), o = new Set(s), i = n.edgeIds.filter((r) => {
1054
+ const l = e.edges[r];
1055
+ return l ? !o.has(l.source.nodeId) && !o.has(l.target.nodeId) : !1;
1056
+ });
1057
+ return { nodeIds: s, edgeIds: i };
1058
+ }
1059
+ function Ht(n) {
1060
+ return [
1061
+ ...n.edgeIds.map((e) => ({ type: "edge.remove", edgeId: e })),
1062
+ ...n.nodeIds.map((e) => ({ type: "node.remove", nodeId: e }))
1063
+ ];
1064
+ }
1065
+ const Gt = 100;
1066
+ function qt({
1067
+ graph: n,
991
1068
  overlayManager: e,
992
1069
  executeCommand: t,
993
- schema: o,
994
- flowModel: n,
995
- defaultInsertGap: i,
996
- getContextMenuItems: r,
997
- onHighlightChange: l,
998
- resolveNodeShape: a
1070
+ schema: s,
1071
+ flowModel: o,
1072
+ getNodeBehavior: i,
1073
+ idGenerator: r,
1074
+ defaultInsertGap: l,
1075
+ getContextMenuItems: a,
1076
+ onHighlightChange: p,
1077
+ resolveNodeShape: c
999
1078
  }) {
1000
- let f = [], d = [], b = null, m = !1, g = null, S = !1;
1001
- async function k() {
1002
- if (m) return b;
1003
- m = !0;
1079
+ const g = r ?? Oe;
1080
+ let u = [], y = [], v = null, C = !1, M = null;
1081
+ async function D() {
1082
+ if (C) return v;
1083
+ C = !0;
1004
1084
  try {
1005
- const p = await import("@antv/x6-plugin-dnd"), c = p.Dnd ?? p.default;
1006
- return c ? (b = new c({
1007
- target: s,
1085
+ const h = await import("@antv/x6-plugin-dnd"), d = h.Dnd ?? h.default;
1086
+ return d ? (v = new d({
1087
+ target: n,
1008
1088
  scaled: !0,
1009
1089
  animation: !0,
1010
- getDragNode: (C) => C.clone(),
1011
- getDropNode: (C) => C.clone()
1012
- }), b) : null;
1090
+ getDragNode: (f) => f.clone(),
1091
+ getDropNode: (f) => f.clone()
1092
+ }), v) : null;
1013
1093
  } catch {
1014
1094
  return console.warn("[flow-canvas] @antv/x6-plugin-dnd not available, add it to your dependencies"), null;
1015
1095
  }
1016
1096
  }
1017
- async function w() {
1018
- if (!S) {
1019
- S = !0;
1020
- try {
1021
- const p = await import("@antv/x6-plugin-export"), c = p.Export ?? p.default;
1022
- c && s.use(new c());
1023
- } catch {
1024
- console.warn("[flow-canvas] @antv/x6-plugin-export not available, add it to your dependencies");
1025
- }
1026
- }
1097
+ function L() {
1098
+ return new Promise((h) => {
1099
+ requestAnimationFrame(() => requestAnimationFrame(() => h()));
1100
+ });
1027
1101
  }
1028
- const x = ({ node: p }) => {
1029
- const c = p.getData?.();
1030
- if (!c?._dndSessionId || c._dndSessionId !== g) return;
1031
- g = null;
1032
- const C = p.getPosition();
1033
- s.removeNode(p.id);
1034
- const { _dndSessionId: z, ..._ } = c, j = _.id || $();
1102
+ const H = ({ node: h }) => {
1103
+ const d = h.getData?.();
1104
+ if (!d?._dndSessionId || d._dndSessionId !== M) return;
1105
+ M = null;
1106
+ const f = h.getPosition();
1107
+ n.removeNode(h.id);
1108
+ const { _dndSessionId: I, ...S } = d, w = S.id || g("node");
1035
1109
  t({
1036
- id: $(),
1110
+ id: Z(),
1037
1111
  source: "user:drag",
1038
1112
  label: "拖入节点",
1039
1113
  timestamp: Date.now(),
1040
1114
  commands: [
1041
1115
  {
1042
1116
  type: "node.add",
1043
- node: { ..._, id: j, position: { x: C.x, y: C.y } }
1117
+ node: { ...S, id: w, position: { x: f.x, y: f.y } }
1044
1118
  }
1045
1119
  ]
1046
1120
  });
1047
1121
  };
1048
- s.on("node:added", x);
1049
- function A(p) {
1050
- const c = o.nodeTypes[p.type];
1051
- return Be(p, c?.getPorts);
1122
+ n.on("node:added", H);
1123
+ function K(h) {
1124
+ const d = s.nodeTypes[h.type];
1125
+ return Be(h, d?.getPorts);
1052
1126
  }
1053
- function U(p, c, C, z, _) {
1054
- switch (p) {
1127
+ function $(h) {
1128
+ return h ?? tt(n.getSelectedCells?.() ?? []);
1129
+ }
1130
+ function W(h, d, f, I, S) {
1131
+ switch (h) {
1055
1132
  case "left":
1056
1133
  return {
1057
- x: c.position.x - _ - z.width,
1058
- y: c.position.y + (C.height - z.height) / 2
1134
+ x: d.position.x - S - I.width,
1135
+ y: d.position.y + (f.height - I.height) / 2
1059
1136
  };
1060
1137
  case "top":
1061
1138
  return {
1062
- x: c.position.x + (C.width - z.width) / 2,
1063
- y: c.position.y - _ - z.height
1139
+ x: d.position.x + (f.width - I.width) / 2,
1140
+ y: d.position.y - S - I.height
1064
1141
  };
1065
1142
  case "bottom":
1066
1143
  return {
1067
- x: c.position.x + (C.width - z.width) / 2,
1068
- y: c.position.y + C.height + _
1144
+ x: d.position.x + (f.width - I.width) / 2,
1145
+ y: d.position.y + f.height + S
1069
1146
  };
1070
1147
  default:
1071
1148
  return {
1072
- x: c.position.x + C.width + _,
1073
- y: c.position.y + (C.height - z.height) / 2
1149
+ x: d.position.x + f.width + S,
1150
+ y: d.position.y + (f.height - I.height) / 2
1074
1151
  };
1075
1152
  }
1076
1153
  }
1077
- function O(p, c, C) {
1078
- switch (p) {
1154
+ function F(h, d, f) {
1155
+ switch (h) {
1079
1156
  case "left":
1080
- return { x: -(c.width + C), y: 0 };
1157
+ return { x: -(d.width + f), y: 0 };
1081
1158
  case "top":
1082
- return { x: 0, y: -(c.height + C) };
1159
+ return { x: 0, y: -(d.height + f) };
1083
1160
  case "bottom":
1084
- return { x: 0, y: c.height + C };
1161
+ return { x: 0, y: d.height + f };
1085
1162
  default:
1086
- return { x: c.width + C, y: 0 };
1163
+ return { x: d.width + f, y: 0 };
1087
1164
  }
1088
1165
  }
1089
- function K(p) {
1090
- switch (p) {
1166
+ function k(h) {
1167
+ switch (h) {
1091
1168
  case "left":
1092
1169
  return "right";
1093
1170
  case "top":
@@ -1098,281 +1175,316 @@ function Dt({
1098
1175
  return "left";
1099
1176
  }
1100
1177
  }
1101
- return {
1178
+ const B = {
1102
1179
  zoomIn() {
1103
- s.zoom(0.1);
1180
+ n.zoom(0.1);
1104
1181
  },
1105
1182
  zoomOut() {
1106
- s.zoom(-0.1);
1183
+ n.zoom(-0.1);
1107
1184
  },
1108
- zoomTo(p) {
1109
- s.zoomTo(p);
1185
+ zoomTo(h) {
1186
+ n.zoomTo(h);
1110
1187
  },
1111
1188
  zoomToFit() {
1112
- s.zoomToFit({ padding: 40, maxScale: 1.5 });
1189
+ n.zoomToFit({ padding: 40, maxScale: 1.5 });
1113
1190
  },
1114
1191
  getZoom() {
1115
- return s.zoom();
1192
+ return n.zoom();
1116
1193
  },
1117
1194
  centerContent() {
1118
- s.centerContent();
1195
+ n.centerContent();
1119
1196
  },
1120
1197
  scrollToOrigin() {
1121
- s.translate(0, 0);
1198
+ n.translate(0, 0);
1122
1199
  },
1123
- scrollToNode(p) {
1124
- const c = s.getCellById(p);
1125
- c && s.centerCell(c);
1200
+ scrollToNode(h) {
1201
+ const d = n.getCellById(h);
1202
+ d && n.centerCell(d);
1126
1203
  },
1127
1204
  getSelection() {
1128
- const p = s.getSelectedCells?.() ?? [];
1129
- return {
1130
- nodeIds: p.filter((c) => c.isNode()).map((c) => c.id),
1131
- edgeIds: p.filter((c) => c.isEdge()).map((c) => c.id)
1132
- };
1205
+ return $();
1206
+ },
1207
+ getSelectionBounds(h) {
1208
+ return Bt(n, $(h));
1133
1209
  },
1134
- selectNodes(p) {
1135
- const c = p.map((C) => s.getCellById(C)).filter(Boolean);
1136
- s.select?.(c);
1210
+ selectNodes(h) {
1211
+ const d = h.map((f) => n.getCellById(f)).filter(Boolean);
1212
+ n.select?.(d);
1137
1213
  },
1138
- selectEdges(p) {
1139
- const c = p.map((C) => s.getCellById(C)).filter(Boolean);
1140
- s.select?.(c);
1214
+ selectEdges(h) {
1215
+ const d = h.map((f) => n.getCellById(f)).filter(Boolean);
1216
+ n.select?.(d);
1141
1217
  },
1142
1218
  clearSelection() {
1143
- const p = s.getSelectedCells?.();
1144
- p?.length && s.unselect?.(p);
1219
+ const h = n.getSelectedCells?.();
1220
+ h?.length && n.unselect?.(h);
1145
1221
  },
1146
- registerDndSource(p, c) {
1147
- const C = async (z) => {
1148
- const _ = await k();
1149
- if (!_) return;
1150
- const j = $();
1151
- g = j;
1152
- const G = c(), q = a?.(G.type), X = s.createNode({
1153
- width: q?.width ?? 154,
1154
- height: q?.height ?? 54,
1155
- shape: q?.shapeName ?? "rect",
1156
- data: { ...G, _dndSessionId: j }
1222
+ deleteSelection(h) {
1223
+ const d = $(h?.selection), f = ot(d, o.value, i ?? (() => ({}))), I = Ht(f);
1224
+ if (I.length === 0) return null;
1225
+ const S = t({
1226
+ id: Z(),
1227
+ source: h?.source ?? "user:toolbar",
1228
+ label: h?.label ?? "删除选中",
1229
+ timestamp: Date.now(),
1230
+ commands: I
1231
+ });
1232
+ return S.status === "applied" && h?.clearSelectionAfterApply !== !1 && B.clearSelection(), S;
1233
+ },
1234
+ registerDndSource(h, d) {
1235
+ const f = async (I) => {
1236
+ const S = await D();
1237
+ if (!S) return;
1238
+ const w = Z();
1239
+ M = w;
1240
+ const U = d(), oe = c?.(U.type), E = n.createNode({
1241
+ width: oe?.width ?? 154,
1242
+ height: oe?.height ?? 54,
1243
+ shape: oe?.shapeName ?? "rect",
1244
+ data: { ...U, _dndSessionId: w }
1157
1245
  });
1158
- _.start(X, z);
1246
+ S.start(E, I);
1159
1247
  };
1160
- return p.addEventListener("mousedown", C), () => {
1161
- p.removeEventListener("mousedown", C);
1248
+ return h.addEventListener("mousedown", f), () => {
1249
+ h.removeEventListener("mousedown", f);
1162
1250
  };
1163
1251
  },
1164
1252
  /**
1165
1253
  * 通过编程方式发起连线:直接命中真实 port 元素,
1166
1254
  * 复用 X6 原生的连线拖拽流程与 connecting.createEdge 配置。
1167
1255
  */
1168
- startConnection(p, c) {
1169
- const C = s.getCellById(p);
1170
- if (!C?.isNode()) return;
1171
- const z = C, _ = s.findViewByCell(z);
1172
- if (!_) return;
1173
- const j = _.findPortElem(c, "circle") ?? _.findPortElem(c);
1174
- if (!j) return;
1175
- const q = (j.matches?.("[magnet]") ? j : j.querySelector?.("[magnet]")) ?? j, X = q.getBoundingClientRect(), ye = X.left + X.width / 2, se = X.top + X.height / 2, ae = new MouseEvent("mousedown", {
1176
- clientX: ye,
1177
- clientY: se,
1256
+ startConnection(h, d) {
1257
+ const f = n.getCellById(h);
1258
+ if (!f?.isNode()) return;
1259
+ const I = f, S = n.findViewByCell(I);
1260
+ if (!S) return;
1261
+ const w = S.findPortElem(d, "circle") ?? S.findPortElem(d);
1262
+ if (!w) return;
1263
+ const oe = (w.matches?.("[magnet]") ? w : w.querySelector?.("[magnet]")) ?? w, E = oe.getBoundingClientRect(), T = E.left + E.width / 2, m = E.top + E.height / 2, P = new MouseEvent("mousedown", {
1264
+ clientX: T,
1265
+ clientY: m,
1178
1266
  button: 0,
1179
1267
  buttons: 1,
1180
1268
  bubbles: !0,
1181
1269
  cancelable: !0
1182
1270
  });
1183
- q.dispatchEvent(ae);
1271
+ oe.dispatchEvent(P);
1184
1272
  },
1185
- async exportAsImage(p) {
1186
- await w();
1187
- const c = s;
1188
- return typeof c.toPNG != "function" ? (console.warn("[flow-canvas] exportAsImage requires @antv/x6-plugin-export, add it to your dependencies"), new Blob()) : new Promise((C) => {
1189
- c.toPNG(
1190
- (z) => {
1191
- fetch(z).then((_) => _.blob()).then(C).catch(() => C(new Blob()));
1192
- },
1193
- {
1194
- backgroundColor: p?.backgroundColor ?? "#ffffff",
1195
- padding: p?.padding ?? 20,
1196
- quality: p?.quality,
1197
- copyStyles: !0
1273
+ async exportAsImage(h) {
1274
+ const { domToBlob: d } = await import("modern-screenshot"), f = h?.padding ?? 20, I = h?.backgroundColor ?? n.options.background?.color ?? "#ffffff", S = n.zoom(), w = n.translate(), U = n.getContentBBox(), oe = U.width / S, E = U.height / S;
1275
+ if (oe === 0 || E === 0)
1276
+ return new Blob();
1277
+ const T = (U.x - w.tx) / S, m = (U.y - w.ty) / S, P = Math.ceil(oe + f * 2), z = Math.ceil(E + f * 2), Y = document.createElement("div");
1278
+ Y.style.cssText = "position:fixed;left:-99999px;top:0;pointer-events:none;";
1279
+ const X = n.container.cloneNode(!0);
1280
+ X.style.width = `${P}px`, X.style.height = `${z}px`, X.style.overflow = "visible";
1281
+ const ne = X.querySelector("svg");
1282
+ ne && (ne.setAttribute("width", String(P)), ne.setAttribute("height", String(z)), ne.style.width = `${P}px`, ne.style.height = `${z}px`), X.querySelector(".x6-graph-svg-viewport")?.setAttribute("transform", `matrix(1,0,0,1,${-T + f},${-m + f})`), Y.appendChild(X), document.body.appendChild(Y);
1283
+ try {
1284
+ return await L(), await d(X, {
1285
+ width: P,
1286
+ height: z,
1287
+ backgroundColor: I,
1288
+ scale: h?.scale ?? window.devicePixelRatio,
1289
+ filter: (de) => {
1290
+ if (de instanceof Element) {
1291
+ const se = de.getAttribute("class") ?? "";
1292
+ if (se.includes("x6-widget-selection") || se.includes("x6-widget-transform") || se.includes("x6-graph-grid") || se.includes("x6-graph-background"))
1293
+ return !1;
1294
+ }
1295
+ return !0;
1198
1296
  }
1199
- );
1200
- });
1201
- },
1202
- async exportAsSVG() {
1203
- await w();
1204
- const p = s;
1205
- return typeof p.toSVG != "function" ? (console.warn("[flow-canvas] exportAsSVG requires @antv/x6-plugin-export, add it to your dependencies"), "") : new Promise((c) => {
1206
- p.toSVG((C) => c(C));
1207
- });
1297
+ });
1298
+ } catch (de) {
1299
+ return console.warn("[flow-canvas] Export failed:", de), new Blob();
1300
+ } finally {
1301
+ Y.remove();
1302
+ }
1208
1303
  },
1209
- highlightNodes(p) {
1210
- f = p, l?.(f, d);
1304
+ highlightNodes(h) {
1305
+ u = h, p?.(u, y);
1211
1306
  },
1212
- highlightEdges(p) {
1213
- d = p, l?.(f, d);
1307
+ highlightEdges(h) {
1308
+ y = h, p?.(u, y);
1214
1309
  },
1215
1310
  clearHighlight() {
1216
- f = [], d = [], l?.([], []);
1311
+ u = [], y = [], p?.([], []);
1217
1312
  },
1218
1313
  overlay: e,
1219
- getContextMenuItems(p) {
1220
- return r?.(p) ?? [];
1314
+ getContextMenuItems(h) {
1315
+ return a?.(h) ?? [];
1221
1316
  },
1222
- insertNodeToRight(p, c, C) {
1223
- const z = n.value, _ = z.nodes[p];
1224
- if (!_)
1317
+ insertNodeToRight(h, d, f) {
1318
+ const I = o.value, S = I.nodes[h];
1319
+ if (!S)
1225
1320
  return {
1226
1321
  status: "invalid",
1227
1322
  envelope: { id: "", source: "user:toolbar", timestamp: Date.now(), commands: [] },
1228
- error: { code: "constraint_violated", reason: `Source node "${p}" not found`, source: "api" }
1323
+ error: { code: "constraint_violated", reason: `Source node "${h}" not found`, source: "api" }
1229
1324
  };
1230
- const j = C?.gap ?? i ?? St, G = C?.direction ?? "right", q = o.nodeTypes[_.type], X = o.nodeTypes[c.type], ye = q?.getSize(_) ?? { width: 154, height: 54 }, se = X?.getSize({ ...c, position: { x: 0, y: 0 } }) ?? {
1325
+ const w = f?.gap ?? l ?? Gt, U = f?.direction ?? "right", oe = s.nodeTypes[S.type], E = s.nodeTypes[d.type], T = oe?.getSize(S) ?? { width: 154, height: 54 }, m = E?.getSize({ ...d, position: { x: 0, y: 0 } }) ?? {
1231
1326
  width: 154,
1232
1327
  height: 54
1233
- }, ae = U(G, _, ye, se, j), ie = c.id || $(), xe = { ...c, id: ie, position: ae }, J = [{ type: "node.add", node: xe }], ke = O(G, se, j), ee = { x: ae.x, y: ae.y, width: se.width, height: se.height };
1234
- for (const [le, V] of Object.entries(z.nodes)) {
1235
- if (le === p || le === ie) continue;
1236
- const fe = o.nodeTypes[V.type]?.getSize(V) ?? { width: 154, height: 54 }, oe = ee.x < V.position.x + fe.width && ee.x + ee.width > V.position.x, pe = ee.y < V.position.y + fe.height && ee.y + ee.height > V.position.y;
1237
- oe && pe && J.push({
1328
+ }, P = W(U, S, T, m, w), z = d.id || g("node"), Y = { ...d, id: z, position: P }, X = [{ type: "node.add", node: Y }], ne = F(U, m, w), Q = { x: P.x, y: P.y, width: m.width, height: m.height };
1329
+ for (const [se, x] of Object.entries(I.nodes)) {
1330
+ if (se === h || se === z) continue;
1331
+ const _ = s.nodeTypes[x.type]?.getSize(x) ?? { width: 154, height: 54 }, q = Q.x < x.position.x + _.width && Q.x + Q.width > x.position.x, J = Q.y < x.position.y + _.height && Q.y + Q.height > x.position.y;
1332
+ q && J && X.push({
1238
1333
  type: "node.move",
1239
- nodeId: le,
1240
- position: { x: V.position.x + ke.x, y: V.position.y + ke.y }
1334
+ nodeId: se,
1335
+ position: { x: x.position.x + ne.x, y: x.position.y + ne.y }
1241
1336
  });
1242
1337
  }
1243
- if (C?.autoWireEdges) {
1244
- const le = A(_), V = A(xe), te = G, fe = K(G), oe = le.find((h) => h.group === te), pe = V.find((h) => h.group === fe), Pe = V.find((h) => h.group === te), v = oe ? Object.values(z.edges).find(
1245
- (h) => h.source.nodeId === p && h.source.portId === oe.id
1246
- ) : Object.values(z.edges).find((h) => h.source.nodeId === p);
1247
- if (v) {
1248
- const h = v.target;
1249
- J.push({ type: "edge.remove", edgeId: v.id }), J.push({
1338
+ if (f?.autoWireEdges) {
1339
+ const se = K(S), x = K(Y), b = U, _ = k(U), q = se.find((ee) => ee.group === b), J = x.find((ee) => ee.group === _), ue = x.find((ee) => ee.group === b), ie = q ? Object.values(I.edges).find(
1340
+ (ee) => ee.source.nodeId === h && ee.source.portId === q.id
1341
+ ) : Object.values(I.edges).find((ee) => ee.source.nodeId === h);
1342
+ if (ie) {
1343
+ const ee = ie.target;
1344
+ X.push({ type: "edge.remove", edgeId: ie.id }), X.push({
1250
1345
  type: "edge.add",
1251
1346
  edge: {
1252
- id: $(),
1253
- source: { nodeId: p, portId: oe?.id },
1254
- target: { nodeId: ie, portId: pe?.id }
1347
+ id: g("edge"),
1348
+ source: { nodeId: h, portId: q?.id },
1349
+ target: { nodeId: z, portId: J?.id }
1255
1350
  }
1256
- }), J.push({
1351
+ }), X.push({
1257
1352
  type: "edge.add",
1258
1353
  edge: {
1259
- id: $(),
1260
- source: { nodeId: ie, portId: Pe?.id },
1261
- target: h
1354
+ id: g("edge"),
1355
+ source: { nodeId: z, portId: ue?.id },
1356
+ target: ee
1262
1357
  }
1263
1358
  });
1264
1359
  } else
1265
- J.push({
1360
+ X.push({
1266
1361
  type: "edge.add",
1267
1362
  edge: {
1268
- id: $(),
1269
- source: { nodeId: p, portId: oe?.id },
1270
- target: { nodeId: ie, portId: pe?.id }
1363
+ id: g("edge"),
1364
+ source: { nodeId: h, portId: q?.id },
1365
+ target: { nodeId: z, portId: J?.id }
1271
1366
  }
1272
1367
  });
1273
1368
  }
1274
- const De = {
1275
- id: $(),
1276
- source: C?.source ?? "user:toolbar",
1277
- label: C?.label ?? "插入节点",
1369
+ const de = {
1370
+ id: Z(),
1371
+ source: f?.source ?? "user:toolbar",
1372
+ label: f?.label ?? "插入节点",
1278
1373
  timestamp: Date.now(),
1279
- commands: J
1374
+ commands: X
1280
1375
  };
1281
- return t(De);
1376
+ return t(de);
1282
1377
  },
1283
- onGraphEvent(p, c) {
1284
- return s.on(p, c), () => s.off(p, c);
1378
+ onGraphEvent(h, d) {
1379
+ return n.on(h, d), () => n.off(h, d);
1285
1380
  },
1286
1381
  unsafeGetGraph() {
1287
- return s;
1382
+ return n;
1288
1383
  }
1289
1384
  };
1385
+ return B;
1290
1386
  }
1291
- function Pt() {
1292
- const s = L(null), e = L(!1);
1293
- let t = null, o = !1;
1294
- function n(d) {
1295
- t && (clearTimeout(t), t = null), s.value = d;
1387
+ function Ut() {
1388
+ const n = O(null), e = O(!1);
1389
+ let t = null, s = !1;
1390
+ function o(g) {
1391
+ t && (clearTimeout(t), t = null), n.value = g;
1296
1392
  }
1297
- function i(d = 100) {
1298
- o || (t && clearTimeout(t), t = setTimeout(() => {
1299
- s.value = null, t = null;
1300
- }, d));
1393
+ function i(g = 100) {
1394
+ s || (t && clearTimeout(t), t = setTimeout(() => {
1395
+ n.value = null, t = null;
1396
+ }, g));
1301
1397
  }
1302
1398
  function r() {
1303
- o = !0, t && (clearTimeout(t), t = null);
1399
+ s = !0, t && (clearTimeout(t), t = null);
1304
1400
  }
1305
- function l(d = 100) {
1306
- o = !1, i(d);
1401
+ function l(g = 100) {
1402
+ s = !1, i(g);
1307
1403
  }
1308
1404
  function a() {
1309
1405
  t && (clearTimeout(t), t = null);
1310
1406
  }
1311
- function f() {
1407
+ function p() {
1408
+ a(), s = !1, n.value = null;
1409
+ }
1410
+ function c() {
1312
1411
  t && clearTimeout(t);
1313
1412
  }
1314
- return { hoveredNodeId: s, isDraggingNode: e, enter: n, leave: i, enterOverlay: r, leaveOverlay: l, cancelLeave: a, cleanup: f };
1413
+ return { hoveredNodeId: n, isDraggingNode: e, enter: o, leave: i, enterOverlay: r, leaveOverlay: l, cancelLeave: a, reset: p, cleanup: c };
1315
1414
  }
1316
- const ze = 10;
1317
- function je(s, e) {
1318
- const t = s.getTotalLength();
1415
+ const qe = 10, Ie = 12;
1416
+ function Ue(n, e) {
1417
+ const t = n.getTotalLength();
1319
1418
  if (t === 0) return { ...e, length: 0, totalLength: 0 };
1320
- let o = s.getPointAtLength(0), n = 1 / 0;
1419
+ let s = n.getPointAtLength(0), o = 1 / 0;
1321
1420
  const i = 50, r = t / i;
1322
1421
  let l = 0;
1323
- for (let b = 0; b <= i; b++) {
1324
- const m = b * r, g = s.getPointAtLength(m), S = (g.x - e.x) ** 2 + (g.y - e.y) ** 2;
1325
- S < n && (n = S, o = g, l = m);
1422
+ for (let g = 0; g <= i; g++) {
1423
+ const u = g * r, y = n.getPointAtLength(u), v = (y.x - e.x) ** 2 + (y.y - e.y) ** 2;
1424
+ v < o && (o = v, s = y, l = u);
1326
1425
  }
1327
- const a = Math.max(0, l - r), f = Math.min(t, l + r), d = (f - a) / 20;
1328
- for (let b = a; b <= f; b += d) {
1329
- const m = s.getPointAtLength(b), g = (m.x - e.x) ** 2 + (m.y - e.y) ** 2;
1330
- g < n && (n = g, o = m, l = b);
1426
+ const a = Math.max(0, l - r), p = Math.min(t, l + r), c = (p - a) / 20;
1427
+ for (let g = a; g <= p; g += c) {
1428
+ const u = n.getPointAtLength(g), y = (u.x - e.x) ** 2 + (u.y - e.y) ** 2;
1429
+ y < o && (o = y, s = u, l = g);
1331
1430
  }
1332
- return { x: o.x, y: o.y, length: l, totalLength: t };
1431
+ return { x: s.x, y: s.y, length: l, totalLength: t };
1333
1432
  }
1334
- function Ge(s, e) {
1335
- return s < ze || s > e - ze;
1433
+ function ze(n, e) {
1434
+ return n < qe || n > e - qe;
1336
1435
  }
1337
- function He() {
1338
- const s = "http://www.w3.org/2000/svg", e = document.createElementNS(s, "g");
1436
+ function Fe(n, e, t) {
1437
+ const s = n.querySelectorAll(".x6-edge-label");
1438
+ for (const o of s) {
1439
+ const i = o.getBoundingClientRect();
1440
+ if (e >= i.left - Ie && e <= i.right + Ie && t >= i.top - Ie && t <= i.bottom + Ie)
1441
+ return !0;
1442
+ }
1443
+ return !1;
1444
+ }
1445
+ function je() {
1446
+ const n = "http://www.w3.org/2000/svg", e = document.createElementNS(n, "g");
1339
1447
  e.setAttribute("class", "flow-canvas-edge-delete-tool"), e.style.cursor = "pointer";
1340
- const t = document.createElementNS(s, "rect");
1448
+ const t = document.createElementNS(n, "rect");
1341
1449
  t.setAttribute("width", "20"), t.setAttribute("height", "20"), t.setAttribute("x", "-10"), t.setAttribute("y", "-10"), t.setAttribute("rx", "4"), t.setAttribute("ry", "4"), t.setAttribute("fill", "#3a84ff"), e.appendChild(t);
1342
- const o = document.createElementNS(s, "text");
1343
- return o.setAttribute("font-family", "flow-canvas"), o.setAttribute("font-size", "16"), o.setAttribute("fill", "#ffffff"), o.setAttribute("text-anchor", "middle"), o.setAttribute("dominant-baseline", "central"), o.textContent = "", e.appendChild(o), e;
1450
+ const s = document.createElementNS(n, "text");
1451
+ return s.setAttribute("font-family", "flow-canvas"), s.setAttribute("font-size", "16"), s.setAttribute("fill", "#ffffff"), s.setAttribute("text-anchor", "middle"), s.setAttribute("dominant-baseline", "central"), s.textContent = "", e.appendChild(s), e;
1344
1452
  }
1345
- function _t(s) {
1453
+ function zt(n) {
1346
1454
  let e = null, t = null;
1347
- function o(l, a) {
1348
- i(), t = l;
1349
- const f = s.getCellById(l);
1350
- if (!f?.isEdge()) return;
1351
- const d = s.findViewByCell(f);
1352
- if (!d) return;
1353
- const b = d.container.querySelector("path");
1354
- if (!b) return;
1355
- const m = s.clientToLocal(a.clientX, a.clientY), g = je(b, m);
1356
- if (Ge(g.length, g.totalLength)) return;
1357
- const S = He();
1358
- S.setAttribute("transform", `translate(${g.x}, ${g.y})`), d.container.appendChild(S), e = S;
1359
- }
1360
- function n(l) {
1455
+ function s(l, a) {
1456
+ if (i(), t = l, a.target?.closest?.(".x6-edge-label")) return;
1457
+ const c = n.getCellById(l);
1458
+ if (!c?.isEdge()) return;
1459
+ const g = n.findViewByCell(c);
1460
+ if (!g) return;
1461
+ const u = g.container.querySelector("path");
1462
+ if (!u) return;
1463
+ const y = n.clientToLocal(a.clientX, a.clientY), v = Ue(u, y);
1464
+ if (ze(v.length, v.totalLength) || Fe(g.container, a.clientX, a.clientY)) return;
1465
+ const C = je();
1466
+ C.setAttribute("transform", `translate(${v.x}, ${v.y})`), g.container.appendChild(C), e = C;
1467
+ }
1468
+ function o(l) {
1361
1469
  if (!t) return;
1362
- const a = s.getCellById(t);
1363
- if (!a?.isEdge()) return;
1364
- const f = s.findViewByCell(a);
1365
- if (!f) return;
1366
- const d = f.container.querySelector("path");
1367
- if (!d) return;
1368
- const b = s.clientToLocal(l.clientX, l.clientY), m = je(d, b);
1369
- if (Ge(m.length, m.totalLength))
1470
+ if (l.target?.closest?.(".x6-edge-label")) {
1471
+ e && e.setAttribute("display", "none");
1472
+ return;
1473
+ }
1474
+ const p = n.getCellById(t);
1475
+ if (!p?.isEdge()) return;
1476
+ const c = n.findViewByCell(p);
1477
+ if (!c) return;
1478
+ const g = c.container.querySelector("path");
1479
+ if (!g) return;
1480
+ const u = n.clientToLocal(l.clientX, l.clientY), y = Ue(g, u);
1481
+ if (ze(y.length, y.totalLength) || Fe(c.container, l.clientX, l.clientY))
1370
1482
  e && e.setAttribute("display", "none");
1371
1483
  else if (e)
1372
- e.removeAttribute("display"), e.setAttribute("transform", `translate(${m.x}, ${m.y})`);
1484
+ e.removeAttribute("display"), e.setAttribute("transform", `translate(${y.x}, ${y.y})`);
1373
1485
  else {
1374
- const g = He();
1375
- g.setAttribute("transform", `translate(${m.x}, ${m.y})`), f.container.appendChild(g), e = g;
1486
+ const v = je();
1487
+ v.setAttribute("transform", `translate(${y.x}, ${y.y})`), c.container.appendChild(v), e = v;
1376
1488
  }
1377
1489
  }
1378
1490
  function i() {
@@ -1381,48 +1493,357 @@ function _t(s) {
1381
1493
  function r(l) {
1382
1494
  l === t && (e = null, t = null);
1383
1495
  }
1384
- return { show: o, move: n, remove: i, handleEdgeRemoved: r };
1496
+ return { show: s, move: o, remove: i, handleEdgeRemoved: r };
1385
1497
  }
1386
- function At(s) {
1498
+ function Ft(n) {
1387
1499
  let e = null, t = 0;
1388
- function o(d) {
1389
- const b = d ? "visible" : "hidden";
1390
- for (const m of s.getNodes())
1391
- for (const g of m.getPorts())
1392
- m.setPortProp(g.id, "attrs/circle/visibility", b);
1500
+ function s(c) {
1501
+ const g = c ? "visible" : "hidden";
1502
+ for (const u of n.getNodes())
1503
+ for (const y of u.getPorts())
1504
+ u.setPortProp(y.id, "attrs/circle/visibility", g);
1393
1505
  }
1394
- function n(d) {
1506
+ function o(c) {
1395
1507
  if (!e)
1396
- for (const b of d.getPorts())
1397
- d.setPortProp(b.id, "attrs/circle/visibility", "visible");
1508
+ for (const g of c.getPorts())
1509
+ c.setPortProp(g.id, "attrs/circle/visibility", "visible");
1398
1510
  }
1399
- function i(d) {
1511
+ function i(c) {
1400
1512
  if (!e)
1401
- for (const b of d.getPorts())
1402
- d.setPortProp(b.id, "attrs/circle/visibility", "hidden");
1403
- }
1404
- function r(d) {
1405
- d.getTargetCell() || (e = d.id, o(!0));
1513
+ for (const g of c.getPorts())
1514
+ c.setPortProp(g.id, "attrs/circle/visibility", "hidden");
1515
+ }
1516
+ function r(c, g) {
1517
+ if (!c.getTargetCell())
1518
+ if (e = c.id, g?.size)
1519
+ for (const u of n.getNodes()) {
1520
+ const y = g.has(u.id) ? "hidden" : "visible";
1521
+ for (const v of u.getPorts())
1522
+ u.setPortProp(v.id, "attrs/circle/visibility", y);
1523
+ }
1524
+ else
1525
+ s(!0);
1406
1526
  }
1407
1527
  function l() {
1408
- e = null, o(!1), t = Date.now() + 300;
1528
+ e = null, s(!1), t = Date.now() + 300;
1409
1529
  }
1410
- function a(d) {
1411
- d === e && (e = null, o(!1));
1530
+ function a(c) {
1531
+ c === e && (e = null, s(!1));
1412
1532
  }
1413
- function f() {
1533
+ function p() {
1414
1534
  return !e && Date.now() >= t;
1415
1535
  }
1416
1536
  return {
1417
- showNodePorts: n,
1537
+ showNodePorts: o,
1418
1538
  hideNodePorts: i,
1419
1539
  handleEdgeAdded: r,
1420
1540
  handleEdgeConnected: l,
1421
1541
  handleEdgeRemoved: a,
1422
- canShowEdgeTool: f
1542
+ canShowEdgeTool: p
1543
+ };
1544
+ }
1545
+ function We(n) {
1546
+ return n === "top" || n === "right" || n === "bottom" || n === "left";
1547
+ }
1548
+ function jt(n) {
1549
+ const { editor: e, nodeHover: t, isSelectionModeActive: s, viewportVersion: o, getNodeBehavior: i, getInsertGap: r } = n, { isDraggingNode: l } = n, a = O(null), p = O(!1);
1550
+ let c = null, g = null, u = null;
1551
+ const y = j(() => ({
1552
+ enabled: !0,
1553
+ portGroup: "right",
1554
+ ...n.quickAddProp.value
1555
+ }));
1556
+ function v() {
1557
+ c && (clearTimeout(c), c = null);
1558
+ }
1559
+ function C() {
1560
+ c && clearTimeout(c), c = setTimeout(() => {
1561
+ a.value = null, c = null;
1562
+ }, 150);
1563
+ }
1564
+ function M(E) {
1565
+ return p.value ? !0 : (v(), B(E) ? (a.value = E, !0) : (a.value = null, !1));
1566
+ }
1567
+ function D() {
1568
+ v(), t.enterOverlay();
1569
+ }
1570
+ function L() {
1571
+ C(), t.leaveOverlay();
1572
+ }
1573
+ function H(E) {
1574
+ const T = e.schema.nodeTypes[E.type];
1575
+ return Be(E, T?.getPorts);
1576
+ }
1577
+ function K(E, T) {
1578
+ const m = y.value.getPort?.(E, T);
1579
+ if (!m) return null;
1580
+ const P = typeof m == "string" ? m : m.id;
1581
+ return T.find((z) => z.id === P) ?? null;
1582
+ }
1583
+ function $(E, T) {
1584
+ const m = e.api.value?.overlay.getNodeScreenRect(E);
1585
+ if (!m) return null;
1586
+ switch (T) {
1587
+ case "top":
1588
+ return { x: m.x + m.width / 2, y: m.y };
1589
+ case "bottom":
1590
+ return { x: m.x + m.width / 2, y: m.y + m.height };
1591
+ case "left":
1592
+ return { x: m.x, y: m.y + m.height / 2 };
1593
+ case "right":
1594
+ return { x: m.x + m.width, y: m.y + m.height / 2 };
1595
+ default:
1596
+ return null;
1597
+ }
1598
+ }
1599
+ function W(E, T, m) {
1600
+ if (!g) return $(E, m);
1601
+ const P = g.getCellById(E);
1602
+ if (P?.isNode()) {
1603
+ const z = P, Y = g.findViewByCell(z), X = Y?.findPortElem(T, "circle") ?? Y?.findPortElem(T);
1604
+ if (X) {
1605
+ const ne = g.container.getBoundingClientRect(), Q = X.getBoundingClientRect();
1606
+ return {
1607
+ x: Q.left - ne.left + Q.width / 2,
1608
+ y: Q.top - ne.top + Q.height / 2
1609
+ };
1610
+ }
1611
+ }
1612
+ return $(E, m);
1613
+ }
1614
+ function F(E) {
1615
+ const T = H(E), m = K(E, T) ?? T.find((z) => z.group === y.value.portGroup) ?? null;
1616
+ if (!m) return null;
1617
+ const P = W(E.id, m.id, m.group);
1618
+ return P ? { portId: m.id, portGroup: m.group, portPosition: P } : null;
1619
+ }
1620
+ function k(E) {
1621
+ const T = F(E), m = y.value.insertDirection;
1622
+ if (typeof m == "function") {
1623
+ const P = m(E, T ? { id: T.portId, group: T.portGroup } : null);
1624
+ if (P) return P;
1625
+ } else if (m)
1626
+ return m;
1627
+ return T && We(T.portGroup) ? T.portGroup : We(y.value.portGroup) ? y.value.portGroup : "right";
1628
+ }
1629
+ function B(E) {
1630
+ if (!y.value.enabled || e.mode.value !== "edit") return !1;
1631
+ const m = e.flowModel.value.nodes[E];
1632
+ return !m || i(m).quickAddEnabled === !1 ? !1 : !!F(m);
1633
+ }
1634
+ const h = j(() => {
1635
+ if (o.value, !y.value.enabled) return null;
1636
+ const E = a.value;
1637
+ if (!E || l.value || !e.api.value || e.mode.value !== "edit" || s.value)
1638
+ return null;
1639
+ const m = e.flowModel.value.nodes[E];
1640
+ if (!m) return null;
1641
+ const P = i(m);
1642
+ if (P.quickAddEnabled === !1) return null;
1643
+ const z = F(m);
1644
+ return z ? { node: m, ...z, behavior: P } : null;
1645
+ });
1646
+ function d(E) {
1647
+ p.value = !0, h.value && e._emitUiEvent({ type: "node.quick-add", nodeId: E, position: h.value.portPosition });
1648
+ }
1649
+ function f() {
1650
+ p.value = !1;
1651
+ }
1652
+ function I(E) {
1653
+ const T = e.api.value;
1654
+ if (!T) return;
1655
+ const m = e.flowModel.value.nodes[E];
1656
+ if (!m) return;
1657
+ const P = F(m);
1658
+ P && T.startConnection(E, P.portId);
1659
+ }
1660
+ function S(E, T) {
1661
+ const m = e.api.value;
1662
+ if (!m) return;
1663
+ const P = T.id || e.idGenerator("node"), z = { ...T, id: P }, Y = e.flowModel.value.nodes[E];
1664
+ if (!Y) return;
1665
+ m.insertNodeToRight(E, z, {
1666
+ autoWireEdges: !0,
1667
+ direction: k(Y),
1668
+ gap: r(),
1669
+ source: "user:quick-add",
1670
+ label: "快捷插入节点"
1671
+ }).status === "applied" && e._emitUiEvent({ type: "node.action.quick-insert", sourceNodeId: E, newNodeId: P }), n.closePopover();
1672
+ }
1673
+ function w(E) {
1674
+ if (!g) return;
1675
+ const T = g.getCellById(E);
1676
+ if (!T?.isNode()) return;
1677
+ const m = T, P = e.flowModel.value.nodes[E];
1678
+ if (!P) return;
1679
+ const z = F(P);
1680
+ let Y = !0;
1681
+ i(P).hidePortForQuickAdd === !1 && (Y = !1);
1682
+ const ne = Y && !l.value && !!z && B(E);
1683
+ for (const Q of m.getPorts()) {
1684
+ const de = ne && Q.id === z?.portId ? "hidden" : "visible";
1685
+ m.setPortProp(Q.id, "attrs/circle/visibility", de);
1686
+ }
1687
+ }
1688
+ function U(E, T) {
1689
+ u?.(), g = E, u = fe(
1690
+ [a, l],
1691
+ ([m], [P]) => {
1692
+ if (P && P !== m) {
1693
+ const z = E.getCellById(P);
1694
+ z?.isNode() && T(z);
1695
+ }
1696
+ m && w(m);
1697
+ },
1698
+ { flush: "sync" }
1699
+ );
1700
+ }
1701
+ fe(h, (E) => {
1702
+ E || (p.value = !1);
1703
+ });
1704
+ function oe() {
1705
+ c && clearTimeout(c), u?.(), u = null, g = null;
1706
+ }
1707
+ return {
1708
+ quickAddNodeId: a,
1709
+ quickAddPopoverOpen: p,
1710
+ mergedConfig: y,
1711
+ data: h,
1712
+ enter: M,
1713
+ leave: C,
1714
+ cancelLeave: v,
1715
+ handleOverlayEnter: D,
1716
+ handleOverlayLeave: L,
1717
+ handleOpen: d,
1718
+ handleClose: f,
1719
+ handleStartDrag: I,
1720
+ handleInsert: S,
1721
+ isActiveForNode: B,
1722
+ syncNodePorts: w,
1723
+ attachRuntime: U,
1724
+ cleanup: oe
1725
+ };
1726
+ }
1727
+ function Wt(n) {
1728
+ function e(o) {
1729
+ return {
1730
+ id: n.idGenerator("node"),
1731
+ type: o.type,
1732
+ label: o.label,
1733
+ ports: o.ports ? JSON.parse(JSON.stringify(o.ports)) : void 0,
1734
+ payload: o.payload ? JSON.parse(JSON.stringify(o.payload)) : void 0,
1735
+ extensions: o.extensions ? JSON.parse(JSON.stringify(o.extensions)) : void 0
1736
+ };
1737
+ }
1738
+ function t(o, i, r) {
1739
+ const l = n.api.value;
1740
+ switch (o) {
1741
+ case "delete":
1742
+ return n.executeCommand({
1743
+ id: Z(),
1744
+ source: "user:toolbar",
1745
+ label: "删除节点",
1746
+ timestamp: Date.now(),
1747
+ commands: [{ type: "node.remove", nodeId: i }]
1748
+ }), n._emitUiEvent({ type: "node.action.delete", nodeId: i }), !0;
1749
+ case "copy": {
1750
+ if (!l) break;
1751
+ const a = n.flowModel.value.nodes[i];
1752
+ if (!a) break;
1753
+ const p = e(a);
1754
+ l.insertNodeToRight(i, p, {
1755
+ autoWireEdges: !1,
1756
+ gap: r,
1757
+ label: "复制节点"
1758
+ }), n._emitUiEvent({ type: "node.action.copy", sourceNodeId: i, newNodeId: p.id });
1759
+ break;
1760
+ }
1761
+ case "copy-insert": {
1762
+ if (!l) break;
1763
+ const a = n.flowModel.value.nodes[i];
1764
+ if (!a) break;
1765
+ const p = e(a);
1766
+ l.insertNodeToRight(i, p, {
1767
+ autoWireEdges: !0,
1768
+ gap: r,
1769
+ label: "复制并插入节点"
1770
+ }), n._emitUiEvent({ type: "node.action.copy-insert", sourceNodeId: i, newNodeId: p.id });
1771
+ break;
1772
+ }
1773
+ case "disconnect": {
1774
+ const a = n.flowModel.value, p = Object.entries(a.edges).filter(([, c]) => {
1775
+ const g = c;
1776
+ return g.source.nodeId === i || g.target.nodeId === i;
1777
+ }).map(([c]) => c);
1778
+ if (p.length === 0) break;
1779
+ n.executeCommand({
1780
+ id: Z(),
1781
+ source: "user:toolbar",
1782
+ label: "断开连线",
1783
+ timestamp: Date.now(),
1784
+ commands: p.map((c) => ({ type: "edge.remove", edgeId: c }))
1785
+ }), n._emitUiEvent({ type: "node.action.disconnect", nodeId: i, edgeIds: p });
1786
+ break;
1787
+ }
1788
+ case "debug": {
1789
+ n._emitUiEvent({ type: "node.action.debug", nodeId: i });
1790
+ break;
1791
+ }
1792
+ }
1793
+ return !1;
1794
+ }
1795
+ function s(o) {
1796
+ n.api.value?.deleteSelection({
1797
+ selection: o,
1798
+ source: "user:toolbar",
1799
+ label: "批量删除选中"
1800
+ });
1801
+ }
1802
+ return { handleNodeAction: t, deleteSelection: s };
1803
+ }
1804
+ function Vt() {
1805
+ return {
1806
+ refX: 0,
1807
+ children: [
1808
+ {
1809
+ tagName: "path",
1810
+ d: "M -16 -5 L -8 0 L -16 5 Z",
1811
+ transform: "rotate(0)"
1812
+ },
1813
+ {
1814
+ tagName: "circle",
1815
+ cx: 0,
1816
+ cy: 0,
1817
+ r: 8,
1818
+ fill: "#3a84ff",
1819
+ stroke: "#3a84ff",
1820
+ transform: "rotate(0)"
1821
+ }
1822
+ ]
1423
1823
  };
1424
1824
  }
1425
- const Tt = { class: "flow-canvas-node-actions__bar" }, Rt = /* @__PURE__ */ ce({
1825
+ function Xt(n, e) {
1826
+ const t = e.defaultEdgeType ?? "default", s = e.edgeTypes?.[t], o = {
1827
+ zIndex: -1,
1828
+ attrs: {
1829
+ line: {
1830
+ stroke: "#abb5cc",
1831
+ strokeWidth: 2,
1832
+ targetMarker: { name: "block", width: 8, height: 8 }
1833
+ }
1834
+ }
1835
+ };
1836
+ s?.router && (o.router = typeof s.router == "string" ? { name: s.router } : s.router), s?.connector && (o.connector = typeof s.connector == "string" ? { name: s.connector } : s.connector), s?.x6EdgeConfig && Object.assign(o, s.x6EdgeConfig);
1837
+ const i = o.attrs ?? {}, r = i.line ?? {};
1838
+ return o.attrs = {
1839
+ ...i,
1840
+ line: {
1841
+ ...r,
1842
+ targetMarker: Vt()
1843
+ }
1844
+ }, n.createEdge(o);
1845
+ }
1846
+ const Kt = { class: "flow-canvas-node-actions__bar" }, Yt = /* @__PURE__ */ le({
1426
1847
  __name: "node-actions-toolbar",
1427
1848
  props: {
1428
1849
  node: {},
@@ -1432,15 +1853,15 @@ const Tt = { class: "flow-canvas-node-actions__bar" }, Rt = /* @__PURE__ */ ce({
1432
1853
  actionsOffset: {}
1433
1854
  },
1434
1855
  emits: ["action"],
1435
- setup(s, { emit: e }) {
1436
- const t = s, o = H(() => {
1437
- const b = t.actionsOffset?.x ?? 0, m = t.actionsOffset?.y ?? 0, g = b !== 0 || m !== 0;
1856
+ setup(n, { emit: e }) {
1857
+ const t = n, s = j(() => {
1858
+ const g = t.actionsOffset?.x ?? 0, u = t.actionsOffset?.y ?? 0, y = g !== 0 || u !== 0;
1438
1859
  return {
1439
1860
  left: `${t.position.x}px`,
1440
1861
  top: `${t.position.y}px`,
1441
- transform: g ? `translate(${b}px, ${m}px)` : "translateX(-100%)"
1862
+ transform: y ? `translate(${g}px, ${u}px)` : "translateX(-100%)"
1442
1863
  };
1443
- }), n = e, i = H(() => ({
1864
+ }), o = e, i = j(() => ({
1444
1865
  debug: {
1445
1866
  visible: t.config.showDebug && t.behavior.debuggable !== !1,
1446
1867
  disabled: t.behavior.debugDisabled === !0
@@ -1461,238 +1882,236 @@ const Tt = { class: "flow-canvas-node-actions__bar" }, Rt = /* @__PURE__ */ ce({
1461
1882
  visible: t.config.showDisconnect && t.behavior.disconnectable !== !1,
1462
1883
  disabled: t.behavior.disconnectDisabled === !0
1463
1884
  }
1464
- })), r = H(() => i.value.copy.visible || i.value.copyInsert.visible || i.value.disconnect.visible), l = L(!1);
1885
+ })), r = j(() => i.value.copy.visible || i.value.copyInsert.visible || i.value.disconnect.visible), l = O(!1);
1465
1886
  let a = null;
1466
- function f() {
1887
+ function p() {
1467
1888
  a && (clearTimeout(a), a = null), l.value = !0;
1468
1889
  }
1469
- function d() {
1890
+ function c() {
1470
1891
  a = setTimeout(() => {
1471
1892
  l.value = !1, a = null;
1472
1893
  }, 100);
1473
1894
  }
1474
- return Re(() => {
1895
+ return Se(() => {
1475
1896
  a && clearTimeout(a);
1476
- }), (b, m) => (I(), N("div", {
1897
+ }), (g, u) => (N(), A("div", {
1477
1898
  class: "flow-canvas-node-actions",
1478
- style: Ie(o.value)
1899
+ style: ve(s.value)
1479
1900
  }, [
1480
- R("div", Tt, [
1481
- i.value.debug.visible ? (I(), N("i", {
1901
+ G("div", Kt, [
1902
+ i.value.debug.visible ? (N(), A("i", {
1482
1903
  key: 0,
1483
- class: Q(["flow-canvas-icon canvas-debug flow-canvas-node-actions__icon", { "is-disabled": i.value.debug.disabled }]),
1484
- onClick: m[0] || (m[0] = (g) => !i.value.debug.disabled && n("action", "debug", s.node.id))
1485
- }, null, 2)) : F("", !0),
1486
- i.value.delete.visible ? (I(), N("i", {
1904
+ class: te(["flow-canvas-icon canvas-debug flow-canvas-node-actions__icon", { "is-disabled": i.value.debug.disabled }]),
1905
+ onClick: u[0] || (u[0] = (y) => !i.value.debug.disabled && o("action", "debug", n.node.id))
1906
+ }, null, 2)) : V("", !0),
1907
+ i.value.delete.visible ? (N(), A("i", {
1487
1908
  key: 1,
1488
- class: Q(["flow-canvas-icon canvas-shanchu flow-canvas-node-actions__icon", { "is-disabled": i.value.delete.disabled }]),
1489
- onClick: m[1] || (m[1] = (g) => !i.value.delete.disabled && n("action", "delete", s.node.id))
1490
- }, null, 2)) : F("", !0),
1491
- r.value ? (I(), N("div", {
1909
+ class: te(["flow-canvas-icon canvas-shanchu flow-canvas-node-actions__icon", { "is-disabled": i.value.delete.disabled }]),
1910
+ onClick: u[1] || (u[1] = (y) => !i.value.delete.disabled && o("action", "delete", n.node.id))
1911
+ }, null, 2)) : V("", !0),
1912
+ r.value ? (N(), A("div", {
1492
1913
  key: 2,
1493
1914
  class: "flow-canvas-node-actions__more-wrapper",
1494
- onMouseenter: f,
1495
- onMouseleave: d
1496
- }, [...m[5] || (m[5] = [
1497
- R("i", { class: "flow-canvas-icon canvas-gengduo flow-canvas-node-actions__icon" }, null, -1)
1498
- ])], 32)) : F("", !0)
1915
+ onMouseenter: p,
1916
+ onMouseleave: c
1917
+ }, [...u[5] || (u[5] = [
1918
+ G("i", { class: "flow-canvas-icon canvas-gengduo flow-canvas-node-actions__icon" }, null, -1)
1919
+ ])], 32)) : V("", !0)
1499
1920
  ]),
1500
- Ve(We, { name: "flow-canvas-fade" }, {
1921
+ Ze(Qe, { name: "flow-canvas-fade" }, {
1501
1922
  default: $e(() => [
1502
- l.value && r.value ? (I(), N("div", {
1923
+ l.value && r.value ? (N(), A("div", {
1503
1924
  key: 0,
1504
1925
  class: "flow-canvas-node-actions__dropdown",
1505
- onMouseenter: f,
1506
- onMouseleave: d
1926
+ onMouseenter: p,
1927
+ onMouseleave: c
1507
1928
  }, [
1508
- i.value.copy.visible ? (I(), N("div", {
1929
+ i.value.copy.visible ? (N(), A("div", {
1509
1930
  key: 0,
1510
- class: Q(["flow-canvas-node-actions__dropdown-item", { "is-disabled": i.value.copy.disabled }]),
1511
- onClick: m[2] || (m[2] = (g) => !i.value.copy.disabled && n("action", "copy", s.node.id))
1512
- }, [...m[6] || (m[6] = [
1513
- R("i", { class: "flow-canvas-icon canvas-copy-fuzhi-2" }, null, -1),
1514
- R("span", null, "复制", -1)
1515
- ])], 2)) : F("", !0),
1516
- i.value.copyInsert.visible ? (I(), N("div", {
1931
+ class: te(["flow-canvas-node-actions__dropdown-item", { "is-disabled": i.value.copy.disabled }]),
1932
+ onClick: u[2] || (u[2] = (y) => !i.value.copy.disabled && o("action", "copy", n.node.id))
1933
+ }, [...u[6] || (u[6] = [
1934
+ G("i", { class: "flow-canvas-icon canvas-copy-fuzhi-2" }, null, -1),
1935
+ G("span", null, "复制", -1)
1936
+ ])], 2)) : V("", !0),
1937
+ i.value.copyInsert.visible ? (N(), A("div", {
1517
1938
  key: 1,
1518
- class: Q(["flow-canvas-node-actions__dropdown-item", { "is-disabled": i.value.copyInsert.disabled }]),
1519
- onClick: m[3] || (m[3] = (g) => !i.value.copyInsert.disabled && n("action", "copy-insert", s.node.id))
1520
- }, [...m[7] || (m[7] = [
1521
- R("i", { class: "flow-canvas-icon canvas-fuzhibingcharu" }, null, -1),
1522
- R("span", null, "复制并插入", -1)
1523
- ])], 2)) : F("", !0),
1524
- i.value.disconnect.visible ? (I(), N("div", {
1939
+ class: te(["flow-canvas-node-actions__dropdown-item", { "is-disabled": i.value.copyInsert.disabled }]),
1940
+ onClick: u[3] || (u[3] = (y) => !i.value.copyInsert.disabled && o("action", "copy-insert", n.node.id))
1941
+ }, [...u[7] || (u[7] = [
1942
+ G("i", { class: "flow-canvas-icon canvas-fuzhibingcharu" }, null, -1),
1943
+ G("span", null, "复制并插入", -1)
1944
+ ])], 2)) : V("", !0),
1945
+ i.value.disconnect.visible ? (N(), A("div", {
1525
1946
  key: 2,
1526
- class: Q(["flow-canvas-node-actions__dropdown-item", { "is-disabled": i.value.disconnect.disabled }]),
1527
- onClick: m[4] || (m[4] = (g) => !i.value.disconnect.disabled && n("action", "disconnect", s.node.id))
1528
- }, [...m[8] || (m[8] = [
1529
- R("i", { class: "flow-canvas-icon canvas-unlock-jiebang" }, null, -1),
1530
- R("span", null, "断开连线", -1)
1531
- ])], 2)) : F("", !0)
1532
- ], 32)) : F("", !0)
1947
+ class: te(["flow-canvas-node-actions__dropdown-item", { "is-disabled": i.value.disconnect.disabled }]),
1948
+ onClick: u[4] || (u[4] = (y) => !i.value.disconnect.disabled && o("action", "disconnect", n.node.id))
1949
+ }, [...u[8] || (u[8] = [
1950
+ G("i", { class: "flow-canvas-icon canvas-unlock-jiebang" }, null, -1),
1951
+ G("span", null, "断开连线", -1)
1952
+ ])], 2)) : V("", !0)
1953
+ ], 32)) : V("", !0)
1533
1954
  ]),
1534
1955
  _: 1
1535
1956
  })
1536
1957
  ], 4));
1537
1958
  }
1538
- }), ue = (s, e) => {
1539
- const t = s.__vccOpts || s;
1540
- for (const [o, n] of e)
1541
- t[o] = n;
1959
+ }), pe = (n, e) => {
1960
+ const t = n.__vccOpts || n;
1961
+ for (const [s, o] of e)
1962
+ t[s] = o;
1542
1963
  return t;
1543
- }, $t = /* @__PURE__ */ ue(Rt, [["__scopeId", "data-v-3b39dab5"]]), Bt = {
1964
+ }, Zt = /* @__PURE__ */ pe(Yt, [["__scopeId", "data-v-3b39dab5"]]), Qt = {
1544
1965
  key: 0,
1545
1966
  class: "flow-canvas-quick-add__tooltip"
1546
- }, Lt = 5, Ot = /* @__PURE__ */ ce({
1967
+ }, Jt = 5, eo = /* @__PURE__ */ le({
1547
1968
  __name: "node-quick-add-popover",
1548
1969
  props: {
1549
1970
  node: {},
1550
- portPosition: {},
1551
- tooltipText: {}
1971
+ portPosition: {}
1552
1972
  },
1553
1973
  emits: ["open", "close", "start-drag", "mouseenter", "mouseleave"],
1554
- setup(s, { expose: e, emit: t }) {
1555
- const o = s, n = t, i = L(), r = L(), l = L(!1), a = L(!1);
1556
- let f = null, d = !1, b = null;
1557
- function m(p) {
1558
- p.preventDefault(), p.stopPropagation(), f = { x: p.clientX, y: p.clientY }, d = !1, document.addEventListener("mousemove", g), document.addEventListener("mouseup", S);
1974
+ setup(n, { expose: e, emit: t }) {
1975
+ const s = n, o = t, i = O(), r = O(), l = O(!1), a = O(!1);
1976
+ let p = null, c = !1, g = null;
1977
+ function u(F) {
1978
+ F.preventDefault(), F.stopPropagation(), p = { x: F.clientX, y: F.clientY }, c = !1, document.addEventListener("mousemove", y), document.addEventListener("mouseup", v);
1559
1979
  }
1560
- function g(p) {
1561
- if (!f) return;
1562
- const c = p.clientX - f.x, C = p.clientY - f.y;
1563
- Math.sqrt(c * c + C * C) >= Lt && (d = !0, k(), n("start-drag", o.node.id));
1980
+ function y(F) {
1981
+ if (!p) return;
1982
+ const k = F.clientX - p.x, B = F.clientY - p.y;
1983
+ Math.sqrt(k * k + B * B) >= Jt && (c = !0, C(), o("start-drag", s.node.id));
1564
1984
  }
1565
- function S() {
1566
- k(), d || w(), f = null, d = !1;
1985
+ function v() {
1986
+ C(), c || M(), p = null, c = !1;
1567
1987
  }
1568
- function k() {
1569
- document.removeEventListener("mousemove", g), document.removeEventListener("mouseup", S);
1988
+ function C() {
1989
+ document.removeEventListener("mousemove", y), document.removeEventListener("mouseup", v);
1570
1990
  }
1571
- function w() {
1572
- a.value ? A() : x();
1991
+ function M() {
1992
+ a.value ? L() : D();
1573
1993
  }
1574
- function x() {
1575
- a.value = !0, n("open", o.node.id), requestAnimationFrame(() => {
1576
- document.addEventListener("mousedown", U);
1994
+ function D() {
1995
+ a.value = !0, o("open", s.node.id), requestAnimationFrame(() => {
1996
+ document.addEventListener("mousedown", H);
1577
1997
  });
1578
1998
  }
1579
- function A() {
1580
- a.value = !1, n("close"), document.removeEventListener("mousedown", U);
1999
+ function L() {
2000
+ a.value = !1, o("close"), document.removeEventListener("mousedown", H);
1581
2001
  }
1582
- function U(p) {
1583
- const c = p.target;
1584
- i.value?.contains(c) || r.value?.contains(c) || A();
1585
- }
1586
- function O() {
1587
- a.value || n("mouseleave");
2002
+ function H(F) {
2003
+ const k = F.target;
2004
+ i.value?.contains(k) || r.value?.contains(k) || L();
1588
2005
  }
1589
2006
  function K() {
1590
- b && (clearTimeout(b), b = null), n("mouseenter");
2007
+ a.value || o("mouseleave");
2008
+ }
2009
+ function $() {
2010
+ g && (clearTimeout(g), g = null), o("mouseenter");
1591
2011
  }
1592
- function Z() {
1593
- b = setTimeout(() => {
1594
- A(), n("mouseleave"), b = null;
2012
+ function W() {
2013
+ g = setTimeout(() => {
2014
+ L(), o("mouseleave"), g = null;
1595
2015
  }, 150);
1596
2016
  }
1597
- return Re(() => {
1598
- k(), b && clearTimeout(b), document.removeEventListener("mousedown", U);
1599
- }), e({ closePopover: A }), (p, c) => (I(), N("div", {
2017
+ return Se(() => {
2018
+ C(), g && clearTimeout(g), document.removeEventListener("mousedown", H);
2019
+ }), e({ closePopover: L }), (F, k) => (N(), A("div", {
1600
2020
  class: "flow-canvas-quick-add",
1601
- style: Ie({ left: `${s.portPosition.x}px`, top: `${s.portPosition.y}px` }),
1602
- onMouseenter: c[2] || (c[2] = (C) => n("mouseenter")),
1603
- onMouseleave: O,
1604
- onClick: c[3] || (c[3] = Ze(() => {
2021
+ style: ve({ left: `${n.portPosition.x}px`, top: `${n.portPosition.y}px` }),
2022
+ onMouseenter: k[2] || (k[2] = (B) => o("mouseenter")),
2023
+ onMouseleave: K,
2024
+ onClick: k[3] || (k[3] = nt(() => {
1605
2025
  }, ["stop"]))
1606
2026
  }, [
1607
- R("div", {
2027
+ G("div", {
1608
2028
  ref_key: "btnRef",
1609
2029
  ref: i,
1610
- class: Q(["flow-canvas-quick-add__btn", { "is-hovered": l.value, "is-active": a.value }]),
1611
- onMouseenter: c[0] || (c[0] = (C) => l.value = !0),
1612
- onMouseleave: c[1] || (c[1] = (C) => l.value = !1),
1613
- onMousedown: m
1614
- }, [...c[4] || (c[4] = [
1615
- R("i", { class: "flow-canvas-icon canvas-zoom-add" }, null, -1)
2030
+ class: te(["flow-canvas-quick-add__btn", { "is-hovered": l.value, "is-active": a.value }]),
2031
+ onMouseenter: k[0] || (k[0] = (B) => l.value = !0),
2032
+ onMouseleave: k[1] || (k[1] = (B) => l.value = !1),
2033
+ onMousedown: u
2034
+ }, [...k[4] || (k[4] = [
2035
+ G("i", { class: "flow-canvas-icon canvas-zoom-add" }, null, -1)
1616
2036
  ])], 34),
1617
- l.value && !a.value ? (I(), N("div", Bt, [...c[5] || (c[5] = [
1618
- R("div", null, [
1619
- R("b", null, "点击"),
1620
- Oe(" 添加节点")
2037
+ l.value && !a.value ? (N(), A("div", Qt, [...k[5] || (k[5] = [
2038
+ G("div", null, [
2039
+ G("b", null, "点击"),
2040
+ Pe(" 添加节点")
1621
2041
  ], -1),
1622
- R("div", null, [
1623
- R("b", null, "拖拽"),
1624
- Oe(" 连接节点")
2042
+ G("div", null, [
2043
+ G("b", null, "拖拽"),
2044
+ Pe(" 连接节点")
1625
2045
  ], -1)
1626
- ])])) : F("", !0),
1627
- Ve(We, { name: "flow-canvas-fade" }, {
2046
+ ])])) : V("", !0),
2047
+ Ze(Qe, { name: "flow-canvas-fade" }, {
1628
2048
  default: $e(() => [
1629
- a.value ? (I(), N("div", {
2049
+ a.value ? (N(), A("div", {
1630
2050
  key: 0,
1631
2051
  ref_key: "popoverRef",
1632
2052
  ref: r,
1633
2053
  class: "flow-canvas-quick-add__popover",
1634
- onMouseenter: K,
1635
- onMouseleave: Z
2054
+ onMouseenter: $,
2055
+ onMouseleave: W
1636
2056
  }, [
1637
- me(p.$slots, "default", {}, () => [
1638
- c[6] || (c[6] = R("div", { class: "flow-canvas-quick-add__default-content" }, "节点快捷操作面板", -1))
2057
+ we(F.$slots, "default", {}, () => [
2058
+ k[6] || (k[6] = G("div", { class: "flow-canvas-quick-add__default-content" }, "节点快捷操作面板", -1))
1639
2059
  ], !0)
1640
- ], 544)) : F("", !0)
2060
+ ], 544)) : V("", !0)
1641
2061
  ]),
1642
2062
  _: 3
1643
2063
  })
1644
2064
  ], 36));
1645
2065
  }
1646
- }), zt = /* @__PURE__ */ ue(Ot, [["__scopeId", "data-v-deb5af25"]]), jt = { class: "flow-canvas-runtime-core__overlay" }, Gt = /* @__PURE__ */ ce({
2066
+ }), to = /* @__PURE__ */ pe(eo, [["__scopeId", "data-v-336cc3b4"]]), oo = { class: "flow-canvas-selection-actions__bar" }, no = /* @__PURE__ */ le({
2067
+ __name: "selection-actions-toolbar",
2068
+ props: {
2069
+ position: {},
2070
+ canDelete: { type: Boolean }
2071
+ },
2072
+ emits: ["action"],
2073
+ setup(n, { emit: e }) {
2074
+ const t = n, s = e, o = j(() => ({
2075
+ left: `${t.position.x}px`,
2076
+ top: `${t.position.y}px`,
2077
+ transform: "translateX(-100%)"
2078
+ }));
2079
+ return (i, r) => (N(), A("div", {
2080
+ class: "flow-canvas-selection-actions",
2081
+ style: ve(o.value)
2082
+ }, [
2083
+ G("div", oo, [
2084
+ G("i", {
2085
+ class: te(["flow-canvas-icon canvas-shanchu flow-canvas-selection-actions__icon", { "is-disabled": !n.canDelete }]),
2086
+ onClick: r[0] || (r[0] = (l) => n.canDelete && s("action", "delete"))
2087
+ }, null, 2)
2088
+ ])
2089
+ ], 4));
2090
+ }
2091
+ }), so = /* @__PURE__ */ pe(no, [["__scopeId", "data-v-25eb8b79"]]), io = { class: "flow-canvas-runtime-core__overlay" }, ro = /* @__PURE__ */ le({
1647
2092
  __name: "canvas-runtime-core",
1648
2093
  props: {
1649
2094
  editor: {},
1650
2095
  graphOptions: {},
1651
2096
  nodeActions: {},
1652
- quickAdd: {}
2097
+ quickAdd: {},
2098
+ getConnectionExcludedNodeIds: { type: Function }
1653
2099
  },
1654
2100
  emits: ["ui-event"],
1655
- setup(s, { emit: e }) {
1656
- const t = s, o = e, n = L(), i = L();
1657
- let r, l, a, f;
1658
- const d = Pt(), { hoveredNodeId: b, isDraggingNode: m } = d, g = d.enterOverlay, S = () => d.leaveOverlay(), k = L(null);
1659
- let w = null;
1660
- function x(v) {
1661
- return U(), J(v) ? (k.value = v, !0) : (k.value = null, !1);
1662
- }
1663
- function A() {
1664
- w && clearTimeout(w), w = setTimeout(() => {
1665
- k.value = null, w = null;
1666
- }, 150);
1667
- }
1668
- function U() {
1669
- w && (clearTimeout(w), w = null);
1670
- }
1671
- function O() {
1672
- U(), d.enterOverlay();
1673
- }
1674
- function K() {
1675
- A(), d.leaveOverlay();
2101
+ setup(n, { emit: e }) {
2102
+ const t = n, s = e, o = O(), i = O();
2103
+ let r, l, a, p, c = null, g = null, u = null, y = null;
2104
+ const v = Ut(), { hoveredNodeId: C, isDraggingNode: M } = v, D = v.enterOverlay, L = () => v.leaveOverlay(), H = O(0), K = O({ nodeIds: [], edgeIds: [] });
2105
+ function $(x) {
2106
+ const b = t.editor.api.value;
2107
+ return b ? t.editor.schema.nodeTypes[x.type]?.getBehavior?.(x, {
2108
+ api: b,
2109
+ flowModel: t.editor.flowModel.value,
2110
+ history: t.editor.history,
2111
+ mode: t.editor.mode.value
2112
+ }) ?? {} : {};
1676
2113
  }
1677
- let Z = null, p = null, c = null;
1678
- const C = L(0), z = H(
1679
- () => {
1680
- if (C.value, !t.editor.api.value) return [];
1681
- const v = t.editor.flowModel.value, h = t.editor.api.value.overlay, u = [];
1682
- for (const [E, D] of Object.entries(v.nodes)) {
1683
- const P = t.editor._pluginManager.collectNodeDecorations(D);
1684
- if (!P?.badge) continue;
1685
- const T = h.getNodeScreenRect(E);
1686
- T && u.push({
1687
- nodeId: E,
1688
- x: T.x + T.width - 4,
1689
- y: T.y - 8,
1690
- badge: P.badge
1691
- });
1692
- }
1693
- return u;
1694
- }
1695
- ), _ = H(() => ({
2114
+ const W = j(() => t.editor.mode.value === "edit" && t.editor.selectionMode.value), F = j(() => ({
1696
2115
  showDebug: !1,
1697
2116
  showDelete: !0,
1698
2117
  showCopy: !0,
@@ -1700,291 +2119,188 @@ const Tt = { class: "flow-canvas-node-actions__bar" }, Rt = /* @__PURE__ */ ce({
1700
2119
  showDisconnect: !0,
1701
2120
  insertGap: 100,
1702
2121
  ...t.nodeActions
1703
- })), j = H(() => {
1704
- C.value;
1705
- const v = b.value;
1706
- if (!v || m.value || !t.editor.api.value || t.editor.mode.value !== "edit") return null;
1707
- const h = t.editor.flowModel.value, u = h.nodes[v];
1708
- if (!u) return null;
1709
- const E = t.editor.api.value.overlay.getNodeScreenRect(v);
1710
- if (!E) return null;
1711
- const P = t.editor.schema.nodeTypes[u.type]?.getBehavior?.(u, {
1712
- api: t.editor.api.value,
1713
- flowModel: h,
1714
- history: t.editor.history,
1715
- mode: t.editor.mode.value
1716
- }) ?? {};
1717
- return P.showActions === !1 ? null : {
1718
- node: u,
1719
- position: { x: E.x + E.width, y: E.y + E.height + 4 },
1720
- behavior: P
2122
+ })), k = j(
2123
+ () => {
2124
+ if (H.value, !t.editor.api.value) return [];
2125
+ const x = t.editor.flowModel.value, b = t.editor.api.value.overlay, _ = [];
2126
+ for (const [q, J] of Object.entries(x.nodes)) {
2127
+ const ue = t.editor._pluginManager.collectNodeDecorations(J);
2128
+ if (!ue?.badge) continue;
2129
+ const ie = b.getNodeScreenRect(q);
2130
+ ie && _.push({
2131
+ nodeId: q,
2132
+ x: ie.x + ie.width - 4,
2133
+ y: ie.y - 8,
2134
+ badge: ue.badge
2135
+ });
2136
+ }
2137
+ return _;
2138
+ }
2139
+ ), B = j(() => {
2140
+ H.value;
2141
+ const x = C.value;
2142
+ if (!x || M.value || !t.editor.api.value || t.editor.mode.value !== "edit" || W.value)
2143
+ return null;
2144
+ const _ = t.editor.flowModel.value.nodes[x];
2145
+ if (!_) return null;
2146
+ const q = t.editor.api.value.overlay.getNodeScreenRect(x);
2147
+ if (!q) return null;
2148
+ const J = $(_);
2149
+ return J.showActions === !1 ? null : {
2150
+ node: _,
2151
+ position: { x: q.x + q.width, y: q.y + q.height + 4 },
2152
+ behavior: J
1721
2153
  };
1722
- }), G = H(() => ({
1723
- enabled: !0,
1724
- tooltipText: "",
1725
- portGroup: "right",
1726
- ...t.quickAdd
1727
- })), q = H(() => {
1728
- if (C.value, !G.value.enabled) return null;
1729
- const v = k.value;
1730
- if (!v || m.value || !t.editor.api.value || t.editor.mode.value !== "edit") return null;
1731
- const h = t.editor.flowModel.value, u = h.nodes[v];
1732
- if (!u) return null;
1733
- const D = t.editor.schema.nodeTypes[u.type]?.getBehavior?.(u, {
1734
- api: t.editor.api.value,
1735
- flowModel: h,
1736
- history: t.editor.history,
1737
- mode: t.editor.mode.value
1738
- }) ?? {};
1739
- if (D.quickAddEnabled === !1) return null;
1740
- const P = te(u);
1741
- return P ? {
1742
- node: u,
1743
- portId: P.portId,
1744
- portGroup: P.portGroup,
1745
- portPosition: P.portPosition,
1746
- behavior: D
1747
- } : null;
1748
- }), X = L();
1749
- function ye(v) {
1750
- const h = q.value;
1751
- h && o("ui-event", {
1752
- type: "node.quick-add",
1753
- nodeId: v,
1754
- position: h.portPosition
1755
- });
1756
- }
1757
- function se(v) {
1758
- const h = t.editor.api.value;
1759
- if (!h) return;
1760
- const E = t.editor.flowModel.value.nodes[v];
1761
- if (!E) return;
1762
- const D = te(E);
1763
- D && h.startConnection(v, D.portId);
1764
- }
1765
- function ae(v, h) {
1766
- const u = t.editor.api.value;
1767
- if (!u) return;
1768
- const E = h.id || $(), D = { ...h, id: E }, P = t.editor.flowModel.value.nodes[v];
1769
- if (!P) return;
1770
- u.insertNodeToRight(v, D, {
1771
- autoWireEdges: !0,
1772
- direction: fe(P),
1773
- gap: _.value.insertGap,
1774
- source: "user:quick-add",
1775
- label: "快捷插入节点"
1776
- }).status === "applied" && o("ui-event", { type: "node.action.quick-insert", sourceNodeId: v, newNodeId: E }), X.value?.closePopover();
1777
- }
1778
- function ie(v) {
2154
+ }), h = j(() => {
2155
+ if (H.value, !t.editor.api.value || t.editor.mode.value !== "edit") return null;
2156
+ const x = K.value;
2157
+ if (x.nodeIds.length + x.edgeIds.length <= 1) return null;
2158
+ const b = t.editor.api.value.getSelectionBounds(x);
2159
+ if (!b) return null;
2160
+ const _ = ot(x, t.editor.flowModel.value, $);
1779
2161
  return {
1780
- id: $(),
1781
- type: v.type,
1782
- label: v.label,
1783
- ports: v.ports ? JSON.parse(JSON.stringify(v.ports)) : void 0,
1784
- payload: v.payload ? JSON.parse(JSON.stringify(v.payload)) : void 0,
1785
- extensions: v.extensions ? JSON.parse(JSON.stringify(v.extensions)) : void 0
2162
+ position: { x: b.x + b.width, y: b.y + b.height + 4 },
2163
+ canDelete: _.nodeIds.length > 0 || _.edgeIds.length > 0
2164
+ };
2165
+ }), d = O(), f = jt({
2166
+ editor: t.editor,
2167
+ quickAddProp: j(() => t.quickAdd),
2168
+ isDraggingNode: M,
2169
+ nodeHover: v,
2170
+ isSelectionModeActive: W,
2171
+ viewportVersion: H,
2172
+ getNodeBehavior: $,
2173
+ getInsertGap: () => F.value.insertGap,
2174
+ closePopover: () => d.value?.closePopover()
2175
+ }), I = f.data, S = f.handleOpen, w = f.handleClose, U = f.handleStartDrag, oe = f.handleOverlayEnter, E = f.handleOverlayLeave, T = f.handleInsert, m = Wt(t.editor);
2176
+ function P(x, b) {
2177
+ m.handleNodeAction(
2178
+ x,
2179
+ b,
2180
+ F.value.insertGap
2181
+ ) && (C.value = null);
2182
+ }
2183
+ function z(x) {
2184
+ x === "delete" && m.deleteSelection(K.value);
2185
+ }
2186
+ function Y(x) {
2187
+ if (t.editor.mode.value !== "edit") return;
2188
+ t.editor._pluginManager.dispatchKeyboardShortcut(x) && (x.preventDefault(), x.stopPropagation());
2189
+ }
2190
+ function X(x, b) {
2191
+ const _ = r, q = (J) => {
2192
+ const ue = _.isRubberbandEnabled?.() ?? !1;
2193
+ ue && _.disableRubberband?.(), J ? r.enablePanning() : r.disablePanning(), ue && _.enableRubberband?.();
1786
2194
  };
2195
+ x ? (_.enableSelection?.(), b ? (v.reset(), f.quickAddNodeId.value = null, f.quickAddPopoverOpen.value = !1, c?.remove(), q(!1), _.enableRubberband?.()) : (_.disableRubberband?.(), q(!0))) : (_.disableRubberband?.(), q(!0), _.disableSelection?.());
1787
2196
  }
1788
- function xe(v, h) {
1789
- const u = t.editor, E = u.api.value;
1790
- switch (v) {
1791
- case "delete": {
1792
- u.executeCommand({
1793
- id: $(),
1794
- source: "user:toolbar",
1795
- label: "删除节点",
1796
- timestamp: Date.now(),
1797
- commands: [{ type: "node.remove", nodeId: h }]
1798
- }), o("ui-event", { type: "node.action.delete", nodeId: h }), b.value = null;
1799
- break;
1800
- }
1801
- case "copy": {
1802
- if (!E) break;
1803
- const D = u.flowModel.value.nodes[h];
1804
- if (!D) break;
1805
- const P = ie(D);
1806
- E.insertNodeToRight(h, P, {
1807
- autoWireEdges: !1,
1808
- gap: _.value.insertGap,
1809
- label: "复制节点"
1810
- }), o("ui-event", { type: "node.action.copy", sourceNodeId: h, newNodeId: P.id });
1811
- break;
1812
- }
1813
- case "copy-insert": {
1814
- if (!E) break;
1815
- const D = u.flowModel.value.nodes[h];
1816
- if (!D) break;
1817
- const P = ie(D);
1818
- E.insertNodeToRight(h, P, {
1819
- autoWireEdges: !0,
1820
- gap: _.value.insertGap,
1821
- label: "复制并插入节点"
1822
- }), o("ui-event", { type: "node.action.copy-insert", sourceNodeId: h, newNodeId: P.id });
1823
- break;
1824
- }
1825
- case "disconnect": {
1826
- const D = u.flowModel.value, P = Object.entries(D.edges).filter(([, T]) => {
1827
- const W = T;
1828
- return W.source.nodeId === h || W.target.nodeId === h;
1829
- }).map(([T]) => T);
1830
- if (P.length === 0) break;
1831
- u.executeCommand({
1832
- id: $(),
1833
- source: "user:toolbar",
1834
- label: "断开连线",
1835
- timestamp: Date.now(),
1836
- commands: P.map((T) => ({ type: "edge.remove", edgeId: T }))
1837
- }), o("ui-event", { type: "node.action.disconnect", nodeId: h, edgeIds: P });
1838
- break;
2197
+ function ne(x) {
2198
+ r.on("node:move", ({ node: b }) => {
2199
+ M.value = !0;
2200
+ const _ = t.editor.flowModel.value.nodes[b.id];
2201
+ _ && $(_).bringToFrontOnDrag === !1 || b.toFront?.();
2202
+ }), r.on("node:moved", () => {
2203
+ M.value = !1;
2204
+ }), r.on("node:mouseenter", ({ node: b }) => {
2205
+ if (W.value) {
2206
+ C.value = null, f.quickAddNodeId.value = null, x.hideNodePorts(b);
2207
+ return;
1839
2208
  }
1840
- case "debug": {
1841
- o("ui-event", { type: "node.action.debug", nodeId: h });
1842
- break;
2209
+ v.enter(b.id);
2210
+ const _ = t.editor.flowModel.value.nodes[b.id];
2211
+ if (_ && $(_).showPorts === !1) {
2212
+ f.mergedConfig.value.enabled && f.enter(b.id);
2213
+ return;
1843
2214
  }
1844
- }
1845
- }
1846
- function J(v) {
1847
- if (!G.value.enabled || t.editor.mode.value !== "edit") return !1;
1848
- const h = t.editor.flowModel.value, u = h.nodes[v];
1849
- return !u || (t.editor.schema.nodeTypes[u.type]?.getBehavior?.(u, {
1850
- api: t.editor.api.value,
1851
- flowModel: h,
1852
- history: t.editor.history,
1853
- mode: t.editor.mode.value
1854
- }) ?? {}).quickAddEnabled === !1 ? !1 : !!te(u);
1855
- }
1856
- function ke(v) {
1857
- const h = t.editor.schema.nodeTypes[v.type];
1858
- return Be(v, h?.getPorts);
1859
- }
1860
- function ee(v) {
1861
- return v === "top" || v === "right" || v === "bottom" || v === "left";
1862
- }
1863
- function De(v, h) {
1864
- const u = G.value.getPort?.(v, h);
1865
- if (!u) return null;
1866
- const E = typeof u == "string" ? u : u.id;
1867
- return h.find((D) => D.id === E) ?? null;
1868
- }
1869
- function le(v, h) {
1870
- const u = t.editor.api.value?.overlay.getNodeScreenRect(v);
1871
- if (!u) return null;
1872
- switch (h) {
1873
- case "top":
1874
- return { x: u.x + u.width / 2, y: u.y };
1875
- case "bottom":
1876
- return { x: u.x + u.width / 2, y: u.y + u.height };
1877
- case "left":
1878
- return { x: u.x, y: u.y + u.height / 2 };
1879
- case "right":
1880
- return { x: u.x + u.width, y: u.y + u.height / 2 };
1881
- default:
1882
- return null;
1883
- }
1884
- }
1885
- function V(v, h, u) {
1886
- const E = r.getCellById(v);
1887
- if (E?.isNode()) {
1888
- const D = E, P = r.findViewByCell(D), T = P?.findPortElem(h, "circle") ?? P?.findPortElem(h);
1889
- if (T) {
1890
- const W = r.container.getBoundingClientRect(), re = T.getBoundingClientRect();
1891
- return {
1892
- x: re.left - W.left + re.width / 2,
1893
- y: re.top - W.top + re.height / 2
1894
- };
2215
+ f.mergedConfig.value.enabled && f.enter(b.id) || x.showNodePorts(b);
2216
+ }), r.on("node:mouseleave", ({ node: b }) => {
2217
+ if (W.value) {
2218
+ x.hideNodePorts(b);
2219
+ return;
1895
2220
  }
1896
- }
1897
- return le(v, u);
1898
- }
1899
- function te(v) {
1900
- const h = ke(v), u = De(v, h) ?? h.find((D) => D.group === G.value.portGroup) ?? null;
1901
- if (!u) return null;
1902
- const E = V(v.id, u.id, u.group);
1903
- return E ? {
1904
- portId: u.id,
1905
- portGroup: u.group,
1906
- portPosition: E
1907
- } : null;
1908
- }
1909
- function fe(v) {
1910
- const h = te(v), u = G.value.insertDirection;
1911
- if (typeof u == "function") {
1912
- const E = u(
1913
- v,
1914
- h ? { id: h.portId, group: h.portGroup } : null
1915
- );
1916
- if (E) return E;
1917
- } else if (u)
1918
- return u;
1919
- return h && ee(h.portGroup) ? h.portGroup : ee(G.value.portGroup) ? G.value.portGroup : "right";
1920
- }
1921
- function oe(v) {
1922
- if (t.editor.mode.value !== "edit") return;
1923
- t.editor._pluginManager.dispatchKeyboardShortcut(v) && (v.preventDefault(), v.stopPropagation());
1924
- }
1925
- function pe() {
1926
- return {
1927
- refX: 0,
1928
- children: [
1929
- {
1930
- tagName: "path",
1931
- d: "M -16 -5 L -8 0 L -16 5 Z",
1932
- transform: "rotate(0)"
1933
- },
1934
- {
1935
- tagName: "circle",
1936
- cx: 0,
1937
- cy: 0,
1938
- r: 8,
1939
- fill: "#3a84ff",
1940
- stroke: "#3a84ff",
1941
- transform: "rotate(0)"
1942
- }
1943
- ]
1944
- };
2221
+ const _ = t.editor.flowModel.value.nodes[b.id];
2222
+ let q = 100;
2223
+ _ && $(_).actionsOffset && (q = 300), v.leave(q), f.mergedConfig.value.enabled ? f.quickAddNodeId.value === b.id && !f.quickAddPopoverOpen.value ? f.leave() : f.quickAddNodeId.value !== b.id && x.hideNodePorts(b) : x.hideNodePorts(b);
2224
+ });
1945
2225
  }
1946
- function Pe(v) {
1947
- const h = t.editor.schema.defaultEdgeType ?? "default", u = t.editor.schema.edgeTypes?.[h], E = {
1948
- zIndex: -1,
1949
- attrs: {
1950
- line: {
1951
- stroke: "#abb5cc",
1952
- strokeWidth: 2,
1953
- targetMarker: { name: "block", width: 8, height: 8 }
2226
+ function Q(x) {
2227
+ r.on("edge:added", ({ edge: b }) => {
2228
+ let _;
2229
+ if (t.getConnectionExcludedNodeIds && !b.getTargetCell()) {
2230
+ const q = b.getSourceCell();
2231
+ if (q) {
2232
+ const J = t.getConnectionExcludedNodeIds(q.id);
2233
+ _ = J instanceof Set ? J : new Set(J);
1954
2234
  }
1955
2235
  }
1956
- };
1957
- u?.router && (E.router = typeof u.router == "string" ? { name: u.router } : u.router), u?.connector && (E.connector = typeof u.connector == "string" ? { name: u.connector } : u.connector), u?.x6EdgeConfig && Object.assign(E, u.x6EdgeConfig);
1958
- const D = E.attrs ?? {}, P = D.line ?? {};
1959
- return E.attrs = {
1960
- ...D,
1961
- line: {
1962
- ...P,
1963
- targetMarker: pe()
2236
+ x.handleEdgeAdded(b, _);
2237
+ }), r.on("edge:connected", () => {
2238
+ x.handleEdgeConnected();
2239
+ }), r.on("edge:removed", ({ edge: b }) => {
2240
+ x.handleEdgeRemoved(b.id), c.handleEdgeRemoved(b.id);
2241
+ }), r.on("edge:mouseenter", ({ edge: b, e: _ }) => {
2242
+ l.setHoveredEdge(b.id), l.refreshEdgeStyles(), t.editor.mode.value === "edit" && !W.value && x.canShowEdgeTool() && c.show(b.id, _);
2243
+ }), r.on("edge:mouseleave", () => {
2244
+ l.setHoveredEdge(null), l.refreshEdgeStyles(), c.remove();
2245
+ }), r.on("edge:click", ({ edge: b, e: _ }) => {
2246
+ _.target?.closest?.(".flow-canvas-edge-delete-tool") && t.editor.mode.value === "edit" && (c.remove(), t.editor.executeCommand({
2247
+ id: Z(),
2248
+ source: "user:toolbar",
2249
+ label: "删除连线",
2250
+ timestamp: Date.now(),
2251
+ commands: [{ type: "edge.remove", edgeId: b.id }]
2252
+ }));
2253
+ }), g = (b) => c.move(b), r.container.addEventListener("mousemove", g);
2254
+ }
2255
+ function de() {
2256
+ u = (x) => {
2257
+ if (!C.value && !f.quickAddNodeId.value) return;
2258
+ const b = x.target;
2259
+ if (b?.closest?.(".x6-node") || b?.closest?.(".flow-canvas-node-actions") || b?.closest?.(".flow-canvas-quick-add")) {
2260
+ v.cancelLeave(), f.cancelLeave();
2261
+ return;
1964
2262
  }
1965
- }, v.createEdge(E);
2263
+ v.leave(180), f.quickAddPopoverOpen.value || f.leave();
2264
+ }, o.value?.addEventListener("mousemove", u), y = () => {
2265
+ v.reset(), f.quickAddPopoverOpen.value || (f.quickAddNodeId.value = null);
2266
+ }, o.value?.addEventListener("mouseleave", y), o.value?.addEventListener("keydown", Y);
2267
+ }
2268
+ function se() {
2269
+ fe(
2270
+ () => t.editor.flowModel.value,
2271
+ (x) => l.syncFlowModel(x)
2272
+ ), fe(
2273
+ [() => t.editor.mode.value, () => t.editor.selectionMode.value],
2274
+ ([x, b]) => {
2275
+ X(x === "edit", b);
2276
+ },
2277
+ { immediate: !0 }
2278
+ );
1966
2279
  }
1967
2280
  return Je(() => {
1968
2281
  if (!i.value) return;
1969
- const v = /* @__PURE__ */ new Set(["model", "container"]), h = {};
2282
+ const x = /* @__PURE__ */ new Set(["model", "container"]), b = {};
1970
2283
  if (t.graphOptions)
1971
- for (const [y, M] of Object.entries(t.graphOptions)) {
1972
- if (v.has(y)) {
1973
- console.warn(`[flow-canvas] graphOptions.${y} is managed by the engine and will be ignored`);
2284
+ for (const [R, ge] of Object.entries(t.graphOptions)) {
2285
+ if (x.has(R)) {
2286
+ console.warn(`[flow-canvas] graphOptions.${R} is managed by the engine and will be ignored`);
1974
2287
  continue;
1975
2288
  }
1976
- h[y] = M;
2289
+ b[R] = ge;
1977
2290
  }
1978
- r = new nt({
2291
+ r = new dt({
1979
2292
  container: i.value,
1980
2293
  autoResize: !0,
1981
2294
  background: { color: "#edf2fc" },
1982
2295
  grid: { visible: !0, size: 20, type: "dot" },
2296
+ highlighting: {
2297
+ magnetAdsorbed: { name: "className", args: { className: "flow-canvas-magnet-adsorbed" } }
2298
+ },
1983
2299
  panning: { enabled: !0 },
1984
2300
  mousewheel: { enabled: !0, modifiers: ["ctrl", "meta"] },
1985
2301
  interacting: {
1986
- nodeMovable(y) {
1987
- return y.cell.getProp("draggable") !== !1;
2302
+ nodeMovable(R) {
2303
+ return R.cell.getProp("draggable") !== !1;
1988
2304
  }
1989
2305
  },
1990
2306
  connecting: {
@@ -1998,16 +2314,16 @@ const Tt = { class: "flow-canvas-node-actions__bar" }, Rt = /* @__PURE__ */ ce({
1998
2314
  connectionPoint: "anchor",
1999
2315
  snap: { radius: 30 },
2000
2316
  createEdge() {
2001
- return Pe(this);
2317
+ return Xt(this, t.editor.schema);
2002
2318
  }
2003
2319
  },
2004
- ...h
2005
- }), a = new It(), l = new Ct(
2320
+ ...b
2321
+ }), a = new Lt(), l = new Rt(
2006
2322
  r,
2007
2323
  t.editor.schema,
2008
2324
  a,
2009
- (y) => t.editor._pluginManager.collectNodeDecorations(y),
2010
- (y) => t.editor._pluginManager.collectEdgeDecorations(y),
2325
+ (R) => t.editor._pluginManager.collectNodeDecorations(R),
2326
+ (R) => t.editor._pluginManager.collectEdgeDecorations(R),
2011
2327
  () => t.editor.api.value ? {
2012
2328
  api: t.editor.api.value,
2013
2329
  flowModel: t.editor.flowModel.value,
@@ -2015,263 +2331,194 @@ const Tt = { class: "flow-canvas-node-actions__bar" }, Rt = /* @__PURE__ */ ce({
2015
2331
  mode: t.editor.mode.value
2016
2332
  } : null
2017
2333
  );
2018
- const u = Nt(r), E = Dt({
2334
+ const _ = Ot(r), q = qt({
2019
2335
  graph: r,
2020
- overlayManager: u,
2021
- executeCommand: (y) => t.editor.executeCommand(y),
2336
+ overlayManager: _,
2337
+ executeCommand: (R) => t.editor.executeCommand(R),
2022
2338
  schema: t.editor.schema,
2023
2339
  flowModel: t.editor.flowModel,
2340
+ getNodeBehavior: $,
2341
+ idGenerator: t.editor.idGenerator,
2024
2342
  defaultInsertGap: t.nodeActions?.insertGap,
2025
- getContextMenuItems: (y) => t.editor._pluginManager.collectContextMenuItems(y),
2026
- onHighlightChange: (y, M) => {
2027
- l.setHighlightedNodes(y), l.setHighlightedEdges(M), l.refreshNodeHighlights(), l.refreshEdgeStyles();
2343
+ getContextMenuItems: (R) => t.editor._pluginManager.collectContextMenuItems(R),
2344
+ onHighlightChange: (R, ge) => {
2345
+ l.setHighlightedNodes(R), l.setHighlightedEdges(ge), l.refreshNodeHighlights(), l.refreshEdgeStyles();
2028
2346
  },
2029
- resolveNodeShape: (y) => {
2030
- const M = t.editor.schema.nodeTypes[y];
2031
- if (!M) return null;
2032
- const B = a.registerNodeType(y, M.component), ne = M.getSize({ id: "", type: y, position: { x: 0, y: 0 } });
2033
- return { shapeName: B, width: ne.width, height: ne.height };
2347
+ resolveNodeShape: (R) => {
2348
+ const ge = t.editor.schema.nodeTypes[R];
2349
+ if (!ge) return null;
2350
+ const ke = a.registerNodeType(R, ge.component), be = ge.getSize({ id: "", type: R, position: { x: 0, y: 0 } });
2351
+ return { shapeName: ke, width: be.width, height: be.height };
2034
2352
  }
2035
2353
  });
2036
- t.editor.api.value = E;
2037
- const D = {
2354
+ t.editor.api.value = q;
2355
+ const J = {
2038
2356
  flowModel: t.editor.flowModel,
2039
2357
  history: t.editor.history,
2040
2358
  schema: t.editor.schema,
2041
2359
  mode: t.editor.mode,
2360
+ idGenerator: t.editor.idGenerator,
2042
2361
  executeCommand: t.editor.executeCommand,
2043
- api: E,
2044
- overlay: u,
2362
+ selectionMode: t.editor.selectionMode,
2363
+ api: q,
2364
+ overlay: _,
2045
2365
  graph: r
2046
2366
  };
2047
- t.editor._pluginManager.attachRuntime(D);
2048
- const P = t.editor._pluginManager.collectExtendedApi();
2049
- Object.assign(t.editor.extendedApi, P), f = new Mt(
2367
+ t.editor._pluginManager.attachRuntime(J);
2368
+ const ue = t.editor._pluginManager.collectExtendedApi();
2369
+ Object.assign(t.editor.extendedApi, ue), t.editor._emitUiEvent = (R) => {
2370
+ t.editor._pluginManager.dispatchUiEvent(R), s("ui-event", R);
2371
+ }, p = new $t(
2050
2372
  r,
2051
- (y) => {
2052
- (y.type === "node.click" || y.type === "node.dblclick" || y.type === "node.contextmenu") && d.enter(y.nodeId), t.editor._pluginManager.dispatchUiEvent(y), o("ui-event", y);
2373
+ (R) => {
2374
+ (R.type === "node.click" || R.type === "node.dblclick" || R.type === "node.contextmenu") && v.enter(R.nodeId), t.editor._emitUiEvent(R);
2053
2375
  },
2054
- (y) => {
2376
+ (R) => {
2055
2377
  if (l.isSyncing) return;
2056
- if (t.editor.executeCommand(y).status !== "applied") {
2057
- for (const B of y.commands)
2058
- if (B.type === "edge.add") {
2059
- const ne = r.getCellById(B.edge.id);
2060
- ne && r.removeCell(ne);
2378
+ if (t.editor.executeCommand(R).status !== "applied") {
2379
+ for (const ke of R.commands)
2380
+ if (ke.type === "edge.add") {
2381
+ const be = r.getCellById(ke.edge.id);
2382
+ be && r.removeCell(be);
2061
2383
  }
2062
2384
  }
2063
2385
  },
2064
- t.editor.flowModel
2065
- ), Z = _t(r);
2066
- const T = At(r), W = r, re = (y) => {
2067
- const M = W.isRubberbandEnabled?.() ?? !1;
2068
- M && W.disableRubberband?.(), y ? r.enablePanning() : r.disablePanning(), M && W.enableRubberband?.();
2069
- }, _e = () => {
2070
- C.value++;
2071
- };
2072
- r.on("translate", _e), r.on("scale", _e), r.on("resize", _e), r.on("node:move", () => {
2073
- m.value = !0;
2074
- }), r.on("node:moved", () => {
2075
- m.value = !1;
2076
- }), r.on("node:mouseenter", ({ node: y }) => {
2077
- d.enter(y.id), G.value.enabled && x(y.id) || T.showNodePorts(y);
2078
- }), r.on("node:mouseleave", ({ node: y }) => {
2079
- const M = t.editor.flowModel.value.nodes[y.id];
2080
- let B = 100;
2081
- M && t.editor.api.value && t.editor.schema.nodeTypes[M.type]?.getBehavior?.(M, {
2082
- api: t.editor.api.value,
2083
- flowModel: t.editor.flowModel.value,
2084
- history: t.editor.history,
2085
- mode: t.editor.mode.value
2086
- })?.actionsOffset && (B = 300), d.leave(B), G.value.enabled && k.value === y.id ? A() : T.hideNodePorts(y);
2087
- });
2088
- function Xe(y) {
2089
- const M = r.getCellById(y);
2090
- if (!M?.isNode()) return;
2091
- const B = M, ne = t.editor.flowModel.value.nodes[y];
2092
- if (!ne) return;
2093
- const Ae = te(ne), Ke = !m.value && !!Ae && J(y);
2094
- for (const Le of B.getPorts()) {
2095
- const Ye = Ke && Le.id === Ae?.portId ? "hidden" : "visible";
2096
- B.setPortProp(Le.id, "attrs/circle/visibility", Ye);
2097
- }
2098
- }
2099
- ge(
2100
- [k, m],
2101
- ([y], [M]) => {
2102
- if (M && M !== y) {
2103
- const B = r.getCellById(M);
2104
- B?.isNode() && T.hideNodePorts(B);
2105
- }
2106
- y && Xe(y);
2107
- },
2108
- { flush: "sync" }
2109
- ), r.on("edge:added", ({ edge: y }) => {
2110
- T.handleEdgeAdded(y);
2111
- }), r.on("edge:connected", () => {
2112
- T.handleEdgeConnected();
2113
- }), r.on("edge:removed", ({ edge: y }) => {
2114
- T.handleEdgeRemoved(y.id), Z.handleEdgeRemoved(y.id);
2115
- }), r.on("selection:changed", () => {
2116
- const y = r.getSelectedCells?.() ?? [], M = {
2117
- nodeIds: y.filter((B) => B.isNode()).map((B) => B.id),
2118
- edgeIds: y.filter((B) => B.isEdge()).map((B) => B.id)
2119
- };
2120
- t.editor._pluginManager.dispatchSelectionChange(M), o("ui-event", {
2386
+ t.editor.flowModel,
2387
+ t.editor.idGenerator
2388
+ ), c = zt(r);
2389
+ const ie = Ft(r);
2390
+ f.attachRuntime(r, (R) => ie.hideNodePorts(R)), ne(ie), Q(ie), r.on("selection:changed", () => {
2391
+ const R = tt(r.getSelectedCells?.() ?? []);
2392
+ K.value = R, t.editor._pluginManager.dispatchSelectionChange(R), s("ui-event", {
2121
2393
  type: "selection.change",
2122
- nodeIds: M.nodeIds,
2123
- edgeIds: M.edgeIds
2124
- }), l.refreshEdgeStyles();
2125
- }), r.on("edge:mouseenter", ({ edge: y, e: M }) => {
2126
- l.setHoveredEdge(y.id), l.refreshEdgeStyles(), t.editor.mode.value === "edit" && T.canShowEdgeTool() && Z.show(y.id, M);
2127
- }), p = (y) => Z.move(y), r.container.addEventListener("mousemove", p), r.on("edge:mouseleave", () => {
2128
- l.setHoveredEdge(null), l.refreshEdgeStyles(), Z.remove();
2129
- }), r.on("edge:click", ({ edge: y, e: M }) => {
2130
- M.target?.closest?.(".flow-canvas-edge-delete-tool") && t.editor.mode.value === "edit" && (Z.remove(), t.editor.executeCommand({
2131
- id: $(),
2132
- source: "user:toolbar",
2133
- label: "删除连线",
2134
- timestamp: Date.now(),
2135
- commands: [{ type: "edge.remove", edgeId: y.id }]
2136
- }));
2137
- }), n.value?.addEventListener("keydown", oe), l.syncFlowModel(t.editor.flowModel.value), ge(
2138
- () => t.editor.flowModel.value,
2139
- (y) => l.syncFlowModel(y)
2140
- ), ge(
2141
- () => t.editor.selectionMode.value,
2142
- (y) => {
2143
- if (c?.(), c = null, y) {
2144
- re(!1), W.enableRubberband?.();
2145
- const M = () => {
2146
- r.container.removeEventListener("mouseup", M), c = null, setTimeout(() => {
2147
- t.editor.selectionMode.value && t.editor.setSelectionMode(!1);
2148
- }, 50);
2149
- };
2150
- r.container.addEventListener("mouseup", M), c = () => r.container.removeEventListener("mouseup", M);
2151
- } else
2152
- W.disableRubberband?.(), re(!0);
2153
- }
2154
- ), ge(
2155
- () => t.editor.mode.value,
2156
- (y) => {
2157
- const M = y === "edit";
2158
- re(!0), M ? W.enableSelection?.() : W.disableSelection?.();
2159
- }
2160
- );
2161
- }), Re(() => {
2162
- d.cleanup(), w && clearTimeout(w), Z?.remove(), c?.(), p && r?.container?.removeEventListener("mousemove", p), n.value?.removeEventListener("keydown", oe), t.editor._pluginManager.detachRuntime(), t.editor.api.value = null;
2163
- for (const v of Object.keys(t.editor.extendedApi))
2164
- delete t.editor.extendedApi[v];
2165
- f?.dispose(), l?.dispose(), a?.dispose(), r?.dispose();
2166
- }), (v, h) => (I(), N("div", {
2394
+ nodeIds: R.nodeIds,
2395
+ edgeIds: R.edgeIds
2396
+ }), l.refreshNodeHighlights(), l.refreshEdgeStyles();
2397
+ });
2398
+ const ee = () => {
2399
+ H.value++;
2400
+ };
2401
+ r.on("translate", ee), r.on("scale", ee), r.on("resize", ee), de(), l.syncFlowModel(t.editor.flowModel.value), se();
2402
+ }), Se(() => {
2403
+ v.cleanup(), f.cleanup(), c?.remove(), g && r?.container?.removeEventListener("mousemove", g), u && o.value?.removeEventListener("mousemove", u), y && o.value?.removeEventListener("mouseleave", y), o.value?.removeEventListener("keydown", Y), t.editor._pluginManager.detachRuntime(), t.editor.api.value = null;
2404
+ for (const x of Object.keys(t.editor.extendedApi))
2405
+ delete t.editor.extendedApi[x];
2406
+ p?.dispose(), l?.dispose(), a?.dispose(), r?.dispose();
2407
+ }), (x, b) => (N(), A("div", {
2167
2408
  ref_key: "rootRef",
2168
- ref: n,
2169
- class: "flow-canvas-runtime-core",
2409
+ ref: o,
2410
+ class: te(["flow-canvas-runtime-core", { "flow-canvas-runtime-core--selection-mode": W.value }]),
2170
2411
  tabindex: "0"
2171
2412
  }, [
2172
- R("div", {
2413
+ G("div", {
2173
2414
  ref_key: "containerRef",
2174
2415
  ref: i,
2175
2416
  class: "flow-canvas-runtime-core__graph"
2176
2417
  }, null, 512),
2177
- R("div", jt, [
2178
- (I(!0), N(de, null, Ee(z.value, (u) => (I(), N("div", {
2179
- key: `badge-${u.nodeId}`,
2418
+ G("div", io, [
2419
+ (N(!0), A(he, null, xe(k.value, (_) => (N(), A("div", {
2420
+ key: `badge-${_.nodeId}`,
2180
2421
  class: "flow-canvas-runtime-core__badge",
2181
- style: Ie({ left: `${u.x}px`, top: `${u.y}px`, backgroundColor: u.badge.color })
2182
- }, he(u.badge.text), 5))), 128)),
2183
- q.value ? (I(), Ce(zt, {
2422
+ style: ve({ left: `${_.x}px`, top: `${_.y}px`, backgroundColor: _.badge.color })
2423
+ }, ce(_.badge.text), 5))), 128)),
2424
+ re(I) ? (N(), ye(to, {
2184
2425
  key: 0,
2185
2426
  ref_key: "quickAddPopoverRef",
2186
- ref: X,
2187
- node: q.value.node,
2188
- "port-position": q.value.portPosition,
2189
- "tooltip-text": G.value.tooltipText,
2190
- onOpen: ye,
2191
- onStartDrag: se,
2192
- onMouseenter: O,
2193
- onMouseleave: K
2427
+ ref: d,
2428
+ node: re(I).node,
2429
+ "port-position": re(I).portPosition,
2430
+ onOpen: re(S),
2431
+ onClose: re(w),
2432
+ onStartDrag: re(U),
2433
+ onMouseenter: re(oe),
2434
+ onMouseleave: re(E)
2194
2435
  }, {
2195
2436
  default: $e(() => [
2196
- me(v.$slots, "quick-add-panel", {
2197
- node: q.value.node,
2198
- api: s.editor.api.value,
2199
- insertNodeToRight: (u) => ae(q.value.node.id, u),
2200
- closePopover: () => X.value?.closePopover()
2437
+ we(x.$slots, "quick-add-panel", {
2438
+ node: re(I).node,
2439
+ api: n.editor.api.value,
2440
+ insertNodeToRight: (_) => re(T)(re(I).node.id, _),
2441
+ closePopover: () => d.value?.closePopover()
2201
2442
  }, void 0, !0)
2202
2443
  ]),
2203
2444
  _: 3
2204
- }, 8, ["node", "port-position", "tooltip-text"])) : F("", !0),
2205
- j.value ? (I(), Ce($t, {
2445
+ }, 8, ["node", "port-position", "onOpen", "onClose", "onStartDrag", "onMouseenter", "onMouseleave"])) : V("", !0),
2446
+ B.value ? (N(), ye(Zt, {
2206
2447
  key: 1,
2207
- node: j.value.node,
2208
- position: j.value.position,
2209
- config: _.value,
2210
- behavior: j.value.behavior,
2211
- "actions-offset": j.value.behavior.actionsOffset,
2212
- onAction: xe,
2213
- onMouseenter: et(g),
2214
- onMouseleave: S
2215
- }, null, 8, ["node", "position", "config", "behavior", "actions-offset", "onMouseenter"])) : F("", !0)
2448
+ node: B.value.node,
2449
+ position: B.value.position,
2450
+ config: F.value,
2451
+ behavior: B.value.behavior,
2452
+ "actions-offset": B.value.behavior.actionsOffset,
2453
+ onAction: P,
2454
+ onMouseenter: re(D),
2455
+ onMouseleave: L
2456
+ }, null, 8, ["node", "position", "config", "behavior", "actions-offset", "onMouseenter"])) : V("", !0),
2457
+ h.value ? (N(), ye(so, {
2458
+ key: 2,
2459
+ position: h.value.position,
2460
+ "can-delete": h.value.canDelete,
2461
+ onAction: z
2462
+ }, null, 8, ["position", "can-delete"])) : V("", !0)
2216
2463
  ])
2217
- ], 512));
2464
+ ], 2));
2218
2465
  }
2219
- }), wo = /* @__PURE__ */ ue(Gt, [["__scopeId", "data-v-7e8e2569"]]), Ht = { class: "flow-canvas-node-palette" }, Ft = ["data-node-type"], qt = { class: "flow-canvas-node-palette__item-label" }, Ut = /* @__PURE__ */ ce({
2466
+ }), ln = /* @__PURE__ */ pe(ro, [["__scopeId", "data-v-84f96992"]]), ao = { class: "flow-canvas-node-palette" }, lo = ["data-node-type"], co = { class: "flow-canvas-node-palette__item-label" }, uo = /* @__PURE__ */ le({
2220
2467
  __name: "canvas-node-palette",
2221
2468
  props: {
2222
2469
  editor: {},
2223
2470
  items: {}
2224
2471
  },
2225
- setup(s) {
2226
- const e = s, t = L(), o = H(() => e.items ? e.items : Object.keys(e.editor.schema.nodeTypes).map((n) => ({
2227
- type: n,
2228
- label: n.charAt(0).toUpperCase() + n.slice(1)
2472
+ setup(n) {
2473
+ const e = n, t = O(), s = j(() => e.items ? e.items : Object.keys(e.editor.schema.nodeTypes).map((o) => ({
2474
+ type: o,
2475
+ label: o.charAt(0).toUpperCase() + o.slice(1)
2229
2476
  })));
2230
- return ge(
2231
- [() => e.editor.api.value, o, t],
2232
- ([n, i, r], l, a) => {
2233
- if (!n || !r) return;
2234
- const f = [];
2235
- for (const d of i) {
2236
- const b = r.querySelector(`[data-node-type="${d.type}"]`);
2237
- if (!b) continue;
2238
- const m = n.registerDndSource(b, () => ({
2239
- id: $(),
2240
- type: d.type,
2241
- label: d.label,
2477
+ return fe(
2478
+ [() => e.editor.api.value, s, t],
2479
+ ([o, i, r], l, a) => {
2480
+ if (!o || !r) return;
2481
+ const p = [];
2482
+ for (const c of i) {
2483
+ const g = r.querySelector(`[data-node-type="${c.type}"]`);
2484
+ if (!g) continue;
2485
+ const u = o.registerDndSource(g, () => ({
2486
+ id: Z(),
2487
+ type: c.type,
2488
+ label: c.label,
2242
2489
  position: { x: 0, y: 0 }
2243
2490
  }));
2244
- f.push(m);
2491
+ p.push(u);
2245
2492
  }
2246
2493
  a(() => {
2247
- for (const d of f) d();
2494
+ for (const c of p) c();
2248
2495
  });
2249
2496
  },
2250
2497
  { flush: "post" }
2251
- ), (n, i) => (I(), N("div", Ht, [
2252
- R("div", {
2498
+ ), (o, i) => (N(), A("div", ao, [
2499
+ G("div", {
2253
2500
  ref_key: "listRef",
2254
2501
  ref: t,
2255
2502
  class: "flow-canvas-node-palette__list"
2256
2503
  }, [
2257
- (I(!0), N(de, null, Ee(o.value, (r) => (I(), N("div", {
2504
+ (N(!0), A(he, null, xe(s.value, (r) => (N(), A("div", {
2258
2505
  key: r.type,
2259
2506
  class: "flow-canvas-node-palette__item",
2260
2507
  "data-node-type": r.type
2261
2508
  }, [
2262
- r.icon ? (I(), N("i", {
2509
+ r.icon ? (N(), A("i", {
2263
2510
  key: 0,
2264
- class: Q([r.icon, "flow-canvas-node-palette__item-icon"])
2265
- }, null, 2)) : F("", !0),
2266
- R("span", qt, he(r.label), 1)
2267
- ], 8, Ft))), 128))
2511
+ class: te([r.icon, "flow-canvas-node-palette__item-icon"])
2512
+ }, null, 2)) : V("", !0),
2513
+ G("span", co, ce(r.label), 1)
2514
+ ], 8, lo))), 128))
2268
2515
  ], 512)
2269
2516
  ]));
2270
2517
  }
2271
- }), Vt = /* @__PURE__ */ ue(Ut, [["__scopeId", "data-v-300314b7"]]), Wt = { class: "flow-canvas-layout" }, Qt = { class: "flow-canvas-layout__main" }, Xt = { class: "flow-canvas-layout__content" }, Kt = {
2518
+ }), fo = /* @__PURE__ */ pe(uo, [["__scopeId", "data-v-300314b7"]]), po = { class: "flow-canvas-layout" }, go = { class: "flow-canvas-layout__main" }, ho = { class: "flow-canvas-layout__content" }, vo = {
2272
2519
  key: 0,
2273
2520
  class: "flow-canvas-layout__footer"
2274
- }, Yt = /* @__PURE__ */ ce({
2521
+ }, yo = /* @__PURE__ */ le({
2275
2522
  __name: "canvas-layout",
2276
2523
  props: {
2277
2524
  sidebarCollapsed: { type: Boolean, default: !1 },
@@ -2282,37 +2529,34 @@ const Tt = { class: "flow-canvas-node-actions__bar" }, Rt = /* @__PURE__ */ ce({
2282
2529
  paletteItems: { default: void 0 }
2283
2530
  },
2284
2531
  emits: ["update:sidebarCollapsed"],
2285
- setup(s) {
2286
- return (e, t) => (I(), N("div", Wt, [
2287
- !s.hideSidebar && (e.$slots.sidebar || s.editor) ? (I(), N("aside", {
2532
+ setup(n) {
2533
+ return (e, t) => (N(), A("div", po, [
2534
+ !n.hideSidebar && (e.$slots.sidebar || n.editor) ? (N(), A("aside", {
2288
2535
  key: 0,
2289
- class: Q(["flow-canvas-layout__sidebar", { "is-collapsed": s.sidebarCollapsed }]),
2290
- style: Ie({ width: s.sidebarCollapsed ? "0px" : `${s.sidebarWidth}px` })
2536
+ class: te(["flow-canvas-layout__sidebar", { "is-collapsed": n.sidebarCollapsed }]),
2537
+ style: ve({ width: n.sidebarCollapsed ? "0px" : `${n.sidebarWidth}px` })
2291
2538
  }, [
2292
- me(e.$slots, "sidebar", {}, () => [
2293
- s.editor ? (I(), Ce(Vt, {
2539
+ we(e.$slots, "sidebar", {}, () => [
2540
+ n.editor ? (N(), ye(fo, {
2294
2541
  key: 0,
2295
- editor: s.editor,
2296
- items: s.paletteItems
2297
- }, null, 8, ["editor", "items"])) : F("", !0)
2542
+ editor: n.editor,
2543
+ items: n.paletteItems
2544
+ }, null, 8, ["editor", "items"])) : V("", !0)
2298
2545
  ], !0)
2299
- ], 6)) : F("", !0),
2300
- R("div", Qt, [
2301
- R("div", Xt, [
2302
- me(e.$slots, "default", {}, void 0, !0)
2546
+ ], 6)) : V("", !0),
2547
+ G("div", go, [
2548
+ G("div", ho, [
2549
+ we(e.$slots, "default", {}, void 0, !0)
2303
2550
  ]),
2304
- !s.hideFooter && e.$slots.footer ? (I(), N("div", Kt, [
2305
- me(e.$slots, "footer", {}, void 0, !0)
2306
- ])) : F("", !0)
2551
+ !n.hideFooter && e.$slots.footer ? (N(), A("div", vo, [
2552
+ we(e.$slots, "footer", {}, void 0, !0)
2553
+ ])) : V("", !0)
2307
2554
  ])
2308
2555
  ]));
2309
2556
  }
2310
- }), xo = /* @__PURE__ */ ue(Yt, [["__scopeId", "data-v-26f35b6b"]]), Zt = ["undo", "redo"];
2311
- function Jt(s) {
2312
- const e = new Set(s?.include), t = /* @__PURE__ */ new Set([
2313
- ...Zt.filter((a) => !e.has(a)),
2314
- ...s?.exclude ?? []
2315
- ]), o = [
2557
+ }), dn = /* @__PURE__ */ pe(yo, [["__scopeId", "data-v-26f35b6b"]]), mo = ["undo", "redo"];
2558
+ function bo(n) {
2559
+ const e = new Set(n?.include), t = new Set(mo.filter((a) => !e.has(a))), s = [
2316
2560
  {
2317
2561
  id: "undo",
2318
2562
  type: "undo",
@@ -2329,7 +2573,7 @@ function Jt(s) {
2329
2573
  description: "重做",
2330
2574
  order: 11
2331
2575
  }
2332
- ], n = [
2576
+ ], o = [
2333
2577
  {
2334
2578
  id: "select",
2335
2579
  type: "select",
@@ -2346,22 +2590,6 @@ function Jt(s) {
2346
2590
  description: "自动排版",
2347
2591
  order: 21
2348
2592
  },
2349
- {
2350
- id: "search",
2351
- type: "search",
2352
- group: "tools",
2353
- icon: "flow-canvas-icon canvas-search",
2354
- description: "搜索节点",
2355
- order: 22
2356
- },
2357
- {
2358
- id: "minimap",
2359
- type: "minimap",
2360
- group: "tools",
2361
- icon: "flow-canvas-icon canvas-map",
2362
- description: "缩略图",
2363
- order: 23
2364
- },
2365
2593
  {
2366
2594
  id: "export",
2367
2595
  type: "export",
@@ -2398,147 +2626,235 @@ function Jt(s) {
2398
2626
  order: 40
2399
2627
  }
2400
2628
  ];
2401
- return [...[...o, ...n].filter(
2629
+ return [...[...s, ...o].filter(
2402
2630
  (a) => !t.has(a.type)
2403
2631
  ), ...i, ...r];
2404
2632
  }
2405
- const eo = { class: "flow-canvas-toolbar" }, to = {
2633
+ const wo = { class: "flow-canvas-toolbar" }, xo = {
2406
2634
  key: 0,
2407
2635
  class: "flow-canvas-toolbar__separator"
2408
- }, oo = { class: "flow-canvas-toolbar__group" }, no = {
2636
+ }, Co = { class: "flow-canvas-toolbar__group" }, Eo = {
2409
2637
  key: 0,
2410
2638
  class: "flow-canvas-toolbar__zoom-display"
2411
- }, so = ["data-description", "disabled", "onClick"], io = ["textContent"], ro = /* @__PURE__ */ ce({
2639
+ }, ko = ["data-toolbar-id", "data-toolbar-type", "disabled", "onClick", "onMouseenter"], Io = ["textContent"], So = /* @__PURE__ */ le({
2412
2640
  __name: "canvas-toolbar",
2413
2641
  props: {
2414
2642
  items: {},
2415
2643
  exclude: {},
2416
2644
  editor: {}
2417
2645
  },
2418
- setup(s) {
2419
- const e = s, t = H(() => e.items ? e.items : Jt({ exclude: e.exclude })), o = L(1);
2420
- let n = null;
2421
- ge(
2422
- () => e.editor.api.value,
2423
- (g) => {
2424
- n?.(), n = null, g && (o.value = g.getZoom(), n = g.onGraphEvent("scale", () => {
2425
- o.value = g.getZoom();
2646
+ setup(n) {
2647
+ const e = /* @__PURE__ */ new Set([
2648
+ "undo",
2649
+ "redo",
2650
+ "select",
2651
+ "auto-layout",
2652
+ "search",
2653
+ "minimap",
2654
+ "export"
2655
+ ]), t = /* @__PURE__ */ new Set(["select", "search", "minimap"]);
2656
+ function s(d) {
2657
+ return d.id.startsWith("plugin:") || d.type === "custom";
2658
+ }
2659
+ function o(d) {
2660
+ return d !== "custom" && t.has(d);
2661
+ }
2662
+ const i = n, r = j(() => {
2663
+ if (i.items) return i.items;
2664
+ const d = bo(), f = i.editor.toolbarItems.value, I = new Set(i.exclude ?? []), S = /* @__PURE__ */ new Map();
2665
+ for (const w of d)
2666
+ S.set(w.id, w);
2667
+ for (const w of f) {
2668
+ const U = S.get(w.id);
2669
+ U ? S.set(w.id, { ...U, ...w, order: U.order, group: U.group }) : s(w) && S.set(w.id, w);
2670
+ }
2671
+ return [...S.values()].filter((w) => w.type === "custom" || !e.has(w.type) ? !0 : !I.has(w.type)).sort((w, U) => (w.order ?? 0) - (U.order ?? 0));
2672
+ }), l = O(1), a = O(null), p = O(null), c = O(!1);
2673
+ let g = null;
2674
+ fe(
2675
+ () => i.editor.api.value,
2676
+ (d) => {
2677
+ g?.(), g = null, d && (l.value = d.getZoom(), g = d.onGraphEvent("scale", () => {
2678
+ l.value = d.getZoom();
2426
2679
  }));
2427
2680
  },
2428
2681
  { immediate: !0 }
2429
- ), Ue(() => {
2430
- n?.();
2682
+ );
2683
+ const u = st({ visible: !1, text: "", x: 0, y: 0 });
2684
+ function y(d, f) {
2685
+ if (!f.description) return;
2686
+ const S = d.currentTarget.getBoundingClientRect();
2687
+ u.text = f.description, u.visible = !0, Te(() => {
2688
+ const w = a.value?.offsetWidth ?? 0, U = a.value?.offsetHeight ?? 0;
2689
+ u.x = S.left + S.width / 2 - w / 2, u.y = S.top - U - 6;
2690
+ });
2691
+ }
2692
+ function v() {
2693
+ u.visible = !1, a.value = null;
2694
+ }
2695
+ Ye(() => {
2696
+ g?.();
2431
2697
  });
2432
- const i = H(() => `${Math.round(o.value * 100)}%`), r = H(() => e.editor.api.value ? {
2433
- api: e.editor.api.value,
2434
- flowModel: e.editor.flowModel.value,
2435
- history: e.editor.history,
2436
- mode: e.editor.mode.value
2698
+ const C = j(() => `${Math.round(l.value * 100)}%`), M = j(() => i.editor.api.value ? {
2699
+ api: i.editor.api.value,
2700
+ flowModel: i.editor.flowModel.value,
2701
+ history: i.editor.history,
2702
+ mode: i.editor.mode.value
2437
2703
  } : null);
2438
- function l(g) {
2439
- return g.visible === !1 ? !1 : typeof g.visible == "function" ? r.value ? g.visible(r.value) : !1 : !0;
2704
+ function D(d) {
2705
+ return d.visible === !1 ? !1 : typeof d.visible == "function" ? M.value ? d.visible(M.value) : !1 : !0;
2706
+ }
2707
+ function L(d) {
2708
+ return typeof d.active == "function" ? M.value ? d.active(M.value) : !1 : d.active !== void 0 ? d.active : d.type === "select" ? i.editor.selectionMode.value : !1;
2709
+ }
2710
+ const H = j(() => {
2711
+ const d = B.value.filter(
2712
+ (I) => o(I.type) && L(I)
2713
+ );
2714
+ if (d.length === 0) return null;
2715
+ const f = p.value;
2716
+ return f && d.some((I) => I.type === f) ? f : d[0]?.type ?? null;
2717
+ });
2718
+ function K(d) {
2719
+ return o(d.type) ? H.value === d.type : L(d);
2440
2720
  }
2441
- function a(g) {
2442
- return g.type === "select" ? e.editor.selectionMode.value : !1;
2721
+ function $(d) {
2722
+ return !M.value || d.disabled === !0 ? !0 : typeof d.disabled == "function" ? d.disabled(M.value) : d.type === "undo" ? !i.editor.history.canUndo.value : d.type === "redo" ? !i.editor.history.canRedo.value : d.type === "export" ? c.value : !1;
2443
2723
  }
2444
- function f(g) {
2445
- return !r.value || g.disabled === !0 ? !0 : typeof g.disabled == "function" ? g.disabled(r.value) : g.type === "undo" ? !e.editor.history.canUndo.value : g.type === "redo" ? !e.editor.history.canRedo.value : !1;
2724
+ function W(d) {
2725
+ if (!(!M.value || !o(d.type) || !L(d))) {
2726
+ if (d.type === "select") {
2727
+ i.editor.setSelectionMode(!1);
2728
+ return;
2729
+ }
2730
+ d.onClick?.(M.value);
2731
+ }
2732
+ }
2733
+ function F(d) {
2734
+ if (o(d.type))
2735
+ for (const f of B.value)
2736
+ !o(f.type) || f.id === d.id || W(f);
2446
2737
  }
2447
- function d(g) {
2448
- if (!r.value || f(g)) return;
2449
- if (g.onClick) {
2450
- g.onClick(r.value);
2738
+ function k(d) {
2739
+ if (!M.value || $(d)) return;
2740
+ if (o(d.type) && (p.value = d.type, F(d)), d.onClick) {
2741
+ d.onClick(M.value);
2451
2742
  return;
2452
2743
  }
2453
- const { api: S } = r.value;
2454
- switch (g.type) {
2744
+ const { api: f } = M.value;
2745
+ switch (d.type) {
2455
2746
  case "undo":
2456
- e.editor.history.undo();
2747
+ i.editor.history.undo();
2457
2748
  break;
2458
2749
  case "redo":
2459
- e.editor.history.redo();
2750
+ i.editor.history.redo();
2460
2751
  break;
2461
2752
  case "zoom-in":
2462
- S.zoomIn(), o.value = S.getZoom();
2753
+ f.zoomIn(), l.value = f.getZoom();
2463
2754
  break;
2464
2755
  case "zoom-out":
2465
- S.zoomOut(), o.value = S.getZoom();
2756
+ f.zoomOut(), l.value = f.getZoom();
2466
2757
  break;
2467
2758
  case "fit":
2468
- S.zoomToFit();
2759
+ f.zoomToFit();
2469
2760
  break;
2470
2761
  case "reset":
2471
- S.zoomTo(1), S.scrollToOrigin(), o.value = 1;
2762
+ f.zoomTo(1), f.scrollToOrigin(), l.value = 1;
2472
2763
  break;
2473
2764
  case "export":
2474
- S.exportAsImage().then((k) => {
2475
- const w = URL.createObjectURL(k), x = document.createElement("a");
2476
- x.href = w, x.download = "canvas-export.png", x.click(), URL.revokeObjectURL(w);
2477
- }).catch((k) => {
2478
- console.warn("[flow-canvas] Export failed:", k);
2765
+ if (c.value) break;
2766
+ c.value = !0, f.exportAsImage().then((I) => {
2767
+ const S = URL.createObjectURL(I), w = document.createElement("a");
2768
+ w.href = S, w.download = "canvas-export.png", w.click(), URL.revokeObjectURL(S);
2769
+ }).catch((I) => {
2770
+ console.warn("[flow-canvas] Export failed:", I);
2771
+ }).finally(() => {
2772
+ c.value = !1;
2479
2773
  });
2480
2774
  break;
2481
2775
  case "select":
2482
- e.editor.setSelectionMode(!e.editor.selectionMode.value);
2776
+ i.editor.setSelectionMode(!i.editor.selectionMode.value);
2483
2777
  break;
2484
- case "search":
2485
2778
  case "auto-layout":
2779
+ i.editor._emitUiEvent({ type: "toolbar.auto-layout" });
2780
+ break;
2781
+ case "search":
2486
2782
  case "minimap":
2487
- console.warn(`[flow-canvas] "${g.type}" toolbar item has no built-in handler. Provide an onClick callback.`);
2783
+ console.warn(`[flow-canvas] "${d.type}" toolbar item has no built-in handler. Provide an onClick callback.`);
2488
2784
  break;
2489
2785
  default:
2490
- g.type !== "custom" && console.warn(`[flow-canvas] No default handler for toolbar type "${g.type}". Provide an onClick handler.`);
2786
+ d.type !== "custom" && console.warn(`[flow-canvas] No default handler for toolbar type "${d.type}". Provide an onClick handler.`);
2491
2787
  break;
2492
2788
  }
2493
2789
  }
2494
- const b = H(() => t.value.filter(l)), m = H(() => {
2495
- const g = /* @__PURE__ */ new Map(), S = [];
2496
- for (const k of b.value) {
2497
- const w = k.group ?? "default";
2498
- g.has(w) || (g.set(w, []), S.push(w)), g.get(w).push(k);
2790
+ const B = j(() => r.value.filter(D)), h = j(() => {
2791
+ const d = /* @__PURE__ */ new Map(), f = [];
2792
+ for (const I of B.value) {
2793
+ const S = I.group ?? "default";
2794
+ d.has(S) || (d.set(S, []), f.push(S)), d.get(S).push(I);
2499
2795
  }
2500
- return S.map((k) => ({ name: k, items: g.get(k) })).filter((k) => k.items.length > 0);
2796
+ return f.map((I) => ({ name: I, items: d.get(I) })).filter((I) => I.items.length > 0);
2501
2797
  });
2502
- return (g, S) => (I(), N("div", eo, [
2503
- (I(!0), N(de, null, Ee(m.value, (k, w) => (I(), N(de, {
2504
- key: k.name
2798
+ return (d, f) => (N(), A("div", wo, [
2799
+ (N(!0), A(he, null, xe(h.value, (I, S) => (N(), A(he, {
2800
+ key: I.name
2505
2801
  }, [
2506
- w > 0 ? (I(), N("div", to)) : F("", !0),
2507
- R("div", oo, [
2508
- (I(!0), N(de, null, Ee(k.items, (x) => (I(), N(de, {
2509
- key: x.id
2802
+ S > 0 ? (N(), A("div", xo)) : V("", !0),
2803
+ G("div", Co, [
2804
+ (N(!0), A(he, null, xe(I.items, (w) => (N(), A(he, {
2805
+ key: w.id
2510
2806
  }, [
2511
- x.type === "zoom-display" ? (I(), N("span", no, he(i.value), 1)) : (I(), N("button", {
2807
+ w.type === "zoom-display" ? (N(), A("span", Eo, ce(C.value), 1)) : (N(), A("button", {
2512
2808
  key: 1,
2513
- class: Q(["flow-canvas-toolbar__btn", { "is-disabled": f(x), "is-active": a(x) }]),
2514
- "data-description": x.description,
2515
- disabled: f(x),
2516
- onClick: (A) => d(x)
2809
+ type: "button",
2810
+ class: te(["flow-canvas-toolbar__btn", {
2811
+ "is-disabled": $(w),
2812
+ "is-active": K(w),
2813
+ "is-exporting": w.type === "export" && c.value
2814
+ }]),
2815
+ "data-toolbar-id": w.id,
2816
+ "data-toolbar-type": w.type,
2817
+ disabled: $(w),
2818
+ onClick: (U) => k(w),
2819
+ onMouseenter: (U) => y(U, w),
2820
+ onMouseleave: v
2517
2821
  }, [
2518
- x.component ? (I(), Ce(tt(x.component), { key: 0 })) : x.icon ? (I(), N("i", {
2822
+ w.component ? (N(), ye(it(w.component), { key: 0 })) : w.icon ? (N(), A("i", {
2519
2823
  key: 1,
2520
- class: Q(x.icon)
2521
- }, null, 2)) : (I(), N("span", {
2824
+ class: te(w.icon)
2825
+ }, null, 2)) : (N(), A("span", {
2522
2826
  key: 2,
2523
2827
  class: "flow-canvas-toolbar__text",
2524
- textContent: he(x.text ?? x.description ?? x.id)
2525
- }, null, 8, io))
2526
- ], 10, so))
2828
+ textContent: ce(w.text ?? w.description ?? w.id)
2829
+ }, null, 8, Io))
2830
+ ], 42, ko))
2527
2831
  ], 64))), 128))
2528
2832
  ])
2529
- ], 64))), 128))
2833
+ ], 64))), 128)),
2834
+ (N(), ye(rt, { to: "body" }, [
2835
+ u.visible ? (N(), A("div", {
2836
+ key: 0,
2837
+ ref_key: "tooltipRef",
2838
+ ref: a,
2839
+ class: "flow-canvas-toolbar-tooltip",
2840
+ style: ve({ left: `${u.x}px`, top: `${u.y}px` })
2841
+ }, [
2842
+ Pe(ce(u.text) + " ", 1),
2843
+ f[0] || (f[0] = G("div", { class: "flow-canvas-toolbar-tooltip__arrow" }, null, -1))
2844
+ ], 4)) : V("", !0)
2845
+ ]))
2530
2846
  ]));
2531
2847
  }
2532
- }), ko = /* @__PURE__ */ ue(ro, [["__scopeId", "data-v-51b5c98a"]]), ao = { class: "flow-canvas-default-node__ep-label" }, lo = {
2848
+ }), cn = /* @__PURE__ */ pe(So, [["__scopeId", "data-v-77d4afbb"]]), _o = { class: "flow-canvas-default-node__ep-label" }, No = {
2533
2849
  key: 1,
2534
- class: "flow-canvas-default-node__diamond"
2535
- }, co = {
2850
+ class: "flow-canvas-default-node__diamond flow-canvas-highlight-target"
2851
+ }, Mo = {
2536
2852
  key: 2,
2537
2853
  class: "flow-canvas-default-node__task-label"
2538
- }, uo = /* @__PURE__ */ ce({
2854
+ }, Do = /* @__PURE__ */ le({
2539
2855
  __name: "default-node",
2540
- setup(s) {
2541
- const t = ot("getNode")?.(), o = H(() => t?.getData?.() ?? null), n = H(() => o.value?.label || o.value?.type || ""), i = {
2856
+ setup(n) {
2857
+ const t = at("getNode")?.(), s = j(() => t?.getData?.() ?? null), o = j(() => s.value?.label || s.value?.type || ""), i = {
2542
2858
  start: "canvas-kaishi",
2543
2859
  end: "canvas-stop",
2544
2860
  "parallel-gateway": "canvas-bingxingwangguan",
@@ -2550,28 +2866,28 @@ const eo = { class: "flow-canvas-toolbar" }, to = {
2550
2866
  "branch-gateway",
2551
2867
  "converge-gateway",
2552
2868
  "conditional-parallel-gateway"
2553
- ]), a = H(() => {
2554
- const d = o.value?.type ?? "";
2555
- return r.has(d) ? "endpoint" : l.has(d) ? "gateway" : "task";
2556
- }), f = H(() => i[o.value?.type ?? ""] ?? "");
2557
- return (d, b) => (I(), N("div", {
2558
- class: Q(["flow-canvas-default-node", `is-${a.value}`])
2869
+ ]), a = j(() => {
2870
+ const c = s.value?.type ?? "";
2871
+ return r.has(c) ? "endpoint" : l.has(c) ? "gateway" : "task";
2872
+ }), p = j(() => i[s.value?.type ?? ""] ?? "");
2873
+ return (c, g) => (N(), A("div", {
2874
+ class: te(["flow-canvas-default-node", [`is-${a.value}`, { "flow-canvas-highlight-target": a.value !== "gateway" }]])
2559
2875
  }, [
2560
- a.value === "endpoint" ? (I(), N(de, { key: 0 }, [
2561
- f.value ? (I(), N("i", {
2876
+ a.value === "endpoint" ? (N(), A(he, { key: 0 }, [
2877
+ p.value ? (N(), A("i", {
2562
2878
  key: 0,
2563
- class: Q([["flow-canvas-icon", f.value], "flow-canvas-default-node__ep-icon"])
2564
- }, null, 2)) : F("", !0),
2565
- R("span", ao, he(n.value), 1)
2566
- ], 64)) : a.value === "gateway" ? (I(), N("div", lo, [
2567
- f.value ? (I(), N("i", {
2879
+ class: te([["flow-canvas-icon", p.value], "flow-canvas-default-node__ep-icon"])
2880
+ }, null, 2)) : V("", !0),
2881
+ G("span", _o, ce(o.value), 1)
2882
+ ], 64)) : a.value === "gateway" ? (N(), A("div", No, [
2883
+ p.value ? (N(), A("i", {
2568
2884
  key: 0,
2569
- class: Q([["flow-canvas-icon", f.value], "flow-canvas-default-node__gw-icon"])
2570
- }, null, 2)) : F("", !0)
2571
- ])) : (I(), N("span", co, he(n.value), 1))
2885
+ class: te([["flow-canvas-icon", p.value], "flow-canvas-default-node__gw-icon"])
2886
+ }, null, 2)) : V("", !0)
2887
+ ])) : (N(), A("span", Mo, ce(o.value), 1))
2572
2888
  ], 2));
2573
2889
  }
2574
- }), fo = /* @__PURE__ */ ue(uo, [["__scopeId", "data-v-c88cdae7"]]), po = {
2890
+ }), Ao = /* @__PURE__ */ pe(Do, [["__scopeId", "data-v-f0e24a9f"]]), Po = {
2575
2891
  start: { label: "开始", icon: "flow-canvas-icon canvas-kaishi", width: 88, height: 40 },
2576
2892
  end: { label: "结束", icon: "flow-canvas-icon canvas-stop", width: 88, height: 40 },
2577
2893
  empty: { label: "空节点", icon: "flow-canvas-icon canvas-jiedi", width: 240, height: 48 },
@@ -2584,11 +2900,11 @@ const eo = { class: "flow-canvas-toolbar" }, to = {
2584
2900
  width: 64,
2585
2901
  height: 64
2586
2902
  }
2587
- }, Fe = (s, e) => ({
2903
+ }, Ve = (n, e) => ({
2588
2904
  stroke: e.hovered ? "#3a84ff" : "#abb5cc",
2589
2905
  strokeWidth: 2
2590
2906
  });
2591
- function qe() {
2907
+ function Xe() {
2592
2908
  return {
2593
2909
  attrs: {
2594
2910
  line: {
@@ -2599,67 +2915,67 @@ function qe() {
2599
2915
  }
2600
2916
  };
2601
2917
  }
2602
- function go() {
2918
+ function To() {
2603
2919
  return {
2604
2920
  manhattan: {
2605
2921
  router: { name: "manhattan", args: { padding: 10, maxDirectionChange: 90 } },
2606
2922
  connector: { name: "rounded", args: { radius: 8 } },
2607
- style: Fe,
2608
- x6EdgeConfig: qe()
2923
+ style: Ve,
2924
+ x6EdgeConfig: Xe()
2609
2925
  },
2610
2926
  bezier: {
2611
2927
  connector: { name: "smooth" },
2612
- style: Fe,
2613
- x6EdgeConfig: qe()
2928
+ style: Ve,
2929
+ x6EdgeConfig: Xe()
2614
2930
  }
2615
2931
  };
2616
2932
  }
2617
- function Co(s) {
2618
- const e = s?.nodeTypes ?? po, t = {}, o = [];
2933
+ function un(n) {
2934
+ const e = n?.nodeTypes ?? Po, t = {}, s = [];
2619
2935
  for (const [r, l] of Object.entries(e)) {
2620
- const a = l.width ?? 150, f = l.height ?? 50;
2936
+ const a = l.width ?? 150, p = l.height ?? 50;
2621
2937
  t[r] = {
2622
- component: fo,
2623
- getSize: () => ({ width: a, height: f }),
2624
- getPorts: () => Qe()
2625
- }, o.push({
2938
+ component: Ao,
2939
+ getSize: () => ({ width: a, height: p }),
2940
+ getPorts: () => et()
2941
+ }, s.push({
2626
2942
  type: r,
2627
2943
  label: l.label ?? r,
2628
2944
  icon: l.icon
2629
2945
  });
2630
2946
  }
2631
- const n = {
2632
- ...go(),
2633
- ...s?.edgeTypes
2634
- }, i = s?.defaultEdgeType ?? "manhattan";
2947
+ const o = {
2948
+ ...To(),
2949
+ ...n?.edgeTypes
2950
+ }, i = n?.defaultEdgeType ?? "manhattan";
2635
2951
  return {
2636
- schema: { nodeTypes: t, defaultEdgeType: i, edgeTypes: n },
2637
- paletteItems: o
2952
+ schema: { nodeTypes: t, defaultEdgeType: i, edgeTypes: o },
2953
+ paletteItems: s
2638
2954
  };
2639
2955
  }
2640
- function Eo(s) {
2956
+ function fn(n) {
2641
2957
  return {
2642
2958
  name: "connection-validator",
2643
2959
  priority: 10,
2644
- transformCommand(e, t, o) {
2645
- for (const n of e.commands) {
2646
- if (n.type !== "edge.add" && n.type !== "edge.reconnect") continue;
2647
- const i = o.flowModel.value, r = n.type === "edge.add" ? n.edge.source.nodeId : n.source?.nodeId, l = n.type === "edge.add" ? n.edge.target.nodeId : n.target?.nodeId;
2960
+ transformCommand(e, t, s) {
2961
+ for (const o of e.commands) {
2962
+ if (o.type !== "edge.add" && o.type !== "edge.reconnect") continue;
2963
+ const i = s.flowModel.value, r = o.type === "edge.add" ? o.edge.source.nodeId : o.source?.nodeId, l = o.type === "edge.add" ? o.edge.target.nodeId : o.target?.nodeId;
2648
2964
  if (!r || !l) continue;
2649
- const a = i.nodes[r], f = i.nodes[l];
2650
- if (!a || !f) continue;
2651
- const d = n.type === "edge.add" ? n.edge.source.portId : n.source?.portId, b = n.type === "edge.add" ? n.edge.target.portId : n.target?.portId, m = d ? a.ports?.find((x) => x.id === d) : void 0, g = b ? f.ports?.find((x) => x.id === b) : void 0, S = n.type === "edge.reconnect" ? n.edgeId : void 0, k = Object.values(i.edges).filter((x) => x.id !== S), w = s({
2965
+ const a = i.nodes[r], p = i.nodes[l];
2966
+ if (!a || !p) continue;
2967
+ const c = o.type === "edge.add" ? o.edge.source.portId : o.source?.portId, g = o.type === "edge.add" ? o.edge.target.portId : o.target?.portId, u = c ? a.ports?.find((D) => D.id === c) : void 0, y = g ? p.ports?.find((D) => D.id === g) : void 0, v = o.type === "edge.reconnect" ? o.edgeId : void 0, C = Object.values(i.edges).filter((D) => D.id !== v), M = n({
2652
2968
  flowModel: i,
2653
2969
  sourceNode: a,
2654
- targetNode: f,
2655
- sourcePort: m,
2656
- targetPort: g,
2657
- existingEdges: k
2970
+ targetNode: p,
2971
+ sourcePort: u,
2972
+ targetPort: y,
2973
+ existingEdges: C
2658
2974
  });
2659
- if (!w.valid)
2975
+ if (!M.valid)
2660
2976
  return {
2661
2977
  rejected: !0,
2662
- reason: w.reason ?? "Connection validation failed",
2978
+ reason: M.reason ?? "Connection validation failed",
2663
2979
  code: "validation_failed"
2664
2980
  };
2665
2981
  }
@@ -2667,113 +2983,433 @@ function Eo(s) {
2667
2983
  }
2668
2984
  };
2669
2985
  }
2670
- function Io(s) {
2671
- const { rubberband: e = !0, multiple: t = !0, movable: o = !0 } = s ?? {};
2986
+ function pn(n) {
2987
+ const { rubberband: e = !0, multiple: t = !0, movable: s = !0 } = n ?? {};
2672
2988
  return {
2673
2989
  name: "selection",
2674
2990
  priority: 90,
2675
- async attachRuntime(n) {
2676
- const { Selection: i } = await import("@antv/x6-plugin-selection");
2677
- n.graph.use(
2678
- new i({
2991
+ attachRuntime(o) {
2992
+ o.graph.use(
2993
+ new ut({
2679
2994
  enabled: !0,
2680
2995
  rubberband: e,
2681
2996
  multiple: t,
2682
- movable: o,
2997
+ movable: s,
2998
+ pointerEvents: "none",
2683
2999
  showNodeSelectionBox: !0,
2684
- filter: (r) => !(r.isNode() && (!n.graph.isRubberbandEnabled?.() || (r.getData?.() ?? {})._selectable === !1))
3000
+ filter: (i) => !(i.isNode() && (i.getData?.() ?? {})._selectable === !1)
2685
3001
  })
2686
3002
  );
2687
3003
  }
2688
3004
  };
2689
3005
  }
2690
- function Mo(s) {
2691
- const { tolerance: e = 10, color: t = "#3a84ff" } = s ?? {};
2692
- let o = null;
3006
+ function gn(n) {
3007
+ const { tolerance: e = 10, color: t = "#3a84ff" } = n ?? {};
3008
+ let s = null;
2693
3009
  return {
2694
3010
  name: "snapline",
2695
3011
  priority: 90,
2696
- async attachRuntime(n) {
3012
+ async attachRuntime(o) {
2697
3013
  const { Snapline: i } = await import("@antv/x6-plugin-snapline");
2698
- n.graph.use(
3014
+ o.graph.use(
2699
3015
  new i({
2700
3016
  enabled: !0,
2701
3017
  tolerance: e,
2702
3018
  className: "flow-canvas-snapline"
2703
3019
  })
2704
- ), o = document.createElement("style"), o.textContent = `.flow-canvas-snapline line { stroke: ${t} !important; }`, document.head.appendChild(o);
3020
+ ), s = document.createElement("style"), s.textContent = `.flow-canvas-snapline line { stroke: ${t} !important; }`, document.head.appendChild(s);
3021
+ },
3022
+ detachRuntime() {
3023
+ s?.remove(), s = null;
3024
+ }
3025
+ };
3026
+ }
3027
+ const Ro = { class: "flow-canvas-search-popover__input" }, Lo = ["value", "placeholder"], $o = ["onMouseenter", "onClick"], Oo = { class: "flow-canvas-search-popover__item-label" }, Bo = {
3028
+ key: 0,
3029
+ class: "flow-canvas-search-popover__item-subtitle"
3030
+ }, Ho = {
3031
+ key: 1,
3032
+ class: "flow-canvas-search-popover__empty"
3033
+ }, Go = /* @__PURE__ */ le({
3034
+ __name: "search-popover",
3035
+ props: {
3036
+ open: { type: Boolean },
3037
+ position: {},
3038
+ query: {},
3039
+ results: {},
3040
+ placeholder: { default: "搜索节点名称" },
3041
+ emptyText: { default: "暂无匹配节点" },
3042
+ isAnchorTarget: { type: Function, default: void 0 }
3043
+ },
3044
+ emits: ["update:query", "select", "close"],
3045
+ setup(n, { emit: e }) {
3046
+ const t = n, s = e, o = O(null), i = O(null), r = O(-1);
3047
+ fe(
3048
+ () => t.open,
3049
+ (v) => {
3050
+ v && (r.value = -1, Te(() => {
3051
+ o.value?.focus(), o.value?.select();
3052
+ }));
3053
+ }
3054
+ ), fe(
3055
+ () => t.query,
3056
+ () => {
3057
+ r.value = -1;
3058
+ }
3059
+ ), fe(
3060
+ () => t.results.length,
3061
+ (v) => {
3062
+ if (!v) {
3063
+ r.value = -1;
3064
+ return;
3065
+ }
3066
+ r.value >= v && (r.value = -1);
3067
+ }
3068
+ );
3069
+ function l(v) {
3070
+ s("update:query", v.target.value);
3071
+ }
3072
+ function a(v) {
3073
+ r.value = v;
3074
+ }
3075
+ function p() {
3076
+ r.value = -1;
3077
+ }
3078
+ function c() {
3079
+ s("update:query", ""), Te(() => {
3080
+ o.value?.focus();
3081
+ });
3082
+ }
3083
+ function g() {
3084
+ const v = t.results[r.value] ?? t.results[0];
3085
+ v && s("select", v.id);
3086
+ }
3087
+ function u(v) {
3088
+ if (v.key === "Escape") {
3089
+ v.preventDefault(), s("close");
3090
+ return;
3091
+ }
3092
+ if (v.key === "ArrowDown") {
3093
+ if (v.preventDefault(), !t.results.length) return;
3094
+ r.value = r.value < t.results.length - 1 ? r.value + 1 : 0;
3095
+ return;
3096
+ }
3097
+ if (v.key === "ArrowUp") {
3098
+ if (v.preventDefault(), !t.results.length) return;
3099
+ r.value = r.value > 0 ? r.value - 1 : t.results.length - 1;
3100
+ return;
3101
+ }
3102
+ v.key === "Enter" && (v.preventDefault(), g());
3103
+ }
3104
+ function y(v) {
3105
+ if (!t.open) return;
3106
+ const C = v.target;
3107
+ C && i.value?.contains(C) || t.isAnchorTarget?.(v.target) || s("close");
3108
+ }
3109
+ return Je(() => {
3110
+ document.addEventListener("mousedown", y);
3111
+ }), Se(() => {
3112
+ document.removeEventListener("mousedown", y);
3113
+ }), (v, C) => n.open ? (N(), A("div", {
3114
+ key: 0,
3115
+ ref_key: "panelRef",
3116
+ ref: i,
3117
+ class: "flow-canvas-search-popover",
3118
+ style: ve({ left: `${n.position.x}px`, top: `${n.position.y}px`, width: `${n.position.width}px` })
3119
+ }, [
3120
+ G("div", Ro, [
3121
+ C[1] || (C[1] = G("i", { class: "flow-canvas-icon canvas-search" }, null, -1)),
3122
+ G("input", {
3123
+ ref_key: "inputRef",
3124
+ ref: o,
3125
+ value: n.query,
3126
+ placeholder: n.placeholder,
3127
+ onInput: l,
3128
+ onKeydown: u
3129
+ }, null, 40, Lo),
3130
+ n.query ? (N(), A("button", {
3131
+ key: 0,
3132
+ type: "button",
3133
+ class: "flow-canvas-search-popover__clear",
3134
+ "aria-label": "清空搜索",
3135
+ onClick: c
3136
+ }, [...C[0] || (C[0] = [
3137
+ G("i", { class: "flow-canvas-icon canvas-close-circle-shape" }, null, -1)
3138
+ ])])) : V("", !0)
3139
+ ]),
3140
+ n.results.length ? (N(), A("div", {
3141
+ key: 0,
3142
+ class: "flow-canvas-search-popover__list",
3143
+ onMouseleave: p
3144
+ }, [
3145
+ (N(!0), A(he, null, xe(n.results, (M, D) => (N(), A("button", {
3146
+ key: M.id,
3147
+ type: "button",
3148
+ class: te(["flow-canvas-search-popover__item", { "is-active": D === r.value }]),
3149
+ onMouseenter: (L) => a(D),
3150
+ onClick: (L) => s("select", M.id)
3151
+ }, [
3152
+ G("span", Oo, ce(M.label), 1),
3153
+ M.subtitle ? (N(), A("span", Bo, ce(M.subtitle), 1)) : V("", !0)
3154
+ ], 42, $o))), 128))
3155
+ ], 32)) : (N(), A("div", Ho, ce(n.emptyText), 1))
3156
+ ], 4)) : V("", !0);
3157
+ }
3158
+ }), qo = /* @__PURE__ */ pe(Go, [["__scopeId", "data-v-c80f6b26"]]), Ke = 282, Uo = 4, zo = 300, Fo = 360, Le = 100, jo = Fo * 4 - Le;
3159
+ function Wo(n) {
3160
+ return n !== null;
3161
+ }
3162
+ function Vo(n) {
3163
+ const e = /* @__PURE__ */ new Set();
3164
+ return n.map((t) => t?.trim()).filter((t) => !!t).filter((t) => {
3165
+ const s = t.toLowerCase();
3166
+ return e.has(s) ? !1 : (e.add(s), !0);
3167
+ });
3168
+ }
3169
+ function Xo(n, e) {
3170
+ const t = Math.max(8, window.innerWidth - e - 8);
3171
+ return Math.min(Math.max(8, n), t);
3172
+ }
3173
+ function Ko(n, e) {
3174
+ const t = e?.getNodeMeta?.(n);
3175
+ if (t === null) return null;
3176
+ const s = t?.label?.trim() || n.label?.trim() || n.id, o = t?.subtitle?.trim() || void 0, i = Vo(t?.keywords ?? [n.label, o]);
3177
+ return i.length ? {
3178
+ id: n.id,
3179
+ label: s,
3180
+ subtitle: o,
3181
+ keywords: i
3182
+ } : null;
3183
+ }
3184
+ function hn(n) {
3185
+ let e = null, t = null, s = null, o = null, i = null, r = [];
3186
+ const l = O(!1), a = O(""), p = O({ x: 0, y: 0, width: Ke }), c = j(() => e ? Object.values(e.flowModel.value.nodes).map((k) => Ko(k, n)).filter(Wo) : []), g = j(() => {
3187
+ const k = a.value.trim().toLowerCase(), B = Math.max(1, n?.maxResults ?? zo);
3188
+ return k ? c.value.filter((h) => h.keywords.some((d) => d.toLowerCase().includes(k))).slice(0, B) : c.value.slice(0, B);
3189
+ });
3190
+ function u() {
3191
+ return s?.querySelector('.flow-canvas-toolbar__btn[data-toolbar-type="search"]');
3192
+ }
3193
+ function y() {
3194
+ return u()?.closest(".flow-canvas-toolbar");
3195
+ }
3196
+ function v() {
3197
+ const k = y(), B = s?.getBoundingClientRect(), h = k?.getBoundingClientRect() ?? B;
3198
+ if (!h) return;
3199
+ const d = Math.max(Ke, Math.round(h.width));
3200
+ p.value = {
3201
+ x: Xo(h.left, d),
3202
+ y: h.bottom + Uo,
3203
+ width: d
3204
+ };
3205
+ }
3206
+ function C() {
3207
+ r.forEach((k) => clearTimeout(k)), r = [], t?.api.clearHighlight();
3208
+ }
3209
+ function M(k) {
3210
+ C();
3211
+ const B = setTimeout(() => {
3212
+ t?.api.highlightNodes([k]);
3213
+ }, Le), h = setTimeout(() => {
3214
+ t?.api.clearHighlight(), r = [];
3215
+ }, Le + jo);
3216
+ r.push(B, h);
3217
+ }
3218
+ function D(k) {
3219
+ t && (t.api.scrollToNode(k), M(k));
3220
+ }
3221
+ function L() {
3222
+ t && (l.value = !0, v(), requestAnimationFrame(() => v()));
3223
+ }
3224
+ function H() {
3225
+ l.value = !1, a.value = "";
3226
+ }
3227
+ function K() {
3228
+ if (l.value) {
3229
+ H();
3230
+ return;
3231
+ }
3232
+ L();
3233
+ }
3234
+ function $(k) {
3235
+ const B = u();
3236
+ return !!(B && k instanceof Node && B.contains(k));
3237
+ }
3238
+ function W() {
3239
+ l.value && v();
3240
+ }
3241
+ const F = le({
3242
+ name: "FlowCanvasSearchHost",
3243
+ setup() {
3244
+ return () => Ae(qo, {
3245
+ open: l.value,
3246
+ position: p.value,
3247
+ query: a.value,
3248
+ results: g.value,
3249
+ placeholder: n?.placeholder ?? "搜索节点名称",
3250
+ emptyText: n?.emptyText ?? "暂无匹配节点",
3251
+ isAnchorTarget: $,
3252
+ "onUpdate:query": (k) => {
3253
+ a.value = k;
3254
+ },
3255
+ onSelect: D,
3256
+ onClose: H
3257
+ });
3258
+ }
3259
+ });
3260
+ return {
3261
+ name: "search",
3262
+ priority: 90,
3263
+ install(k) {
3264
+ e = k;
3265
+ },
3266
+ attachRuntime(k) {
3267
+ t = k, s = k.graph.container.closest(".flow-canvas-layout__content") ?? k.graph.container.parentElement, o = document.createElement("div"), o.className = "flow-canvas-search-host", document.body.append(o), i = lt(F), i.mount(o), window.addEventListener("resize", W), window.addEventListener("scroll", W, !0);
2705
3268
  },
2706
3269
  detachRuntime() {
2707
- o?.remove(), o = null;
3270
+ H(), C(), window.removeEventListener("resize", W), window.removeEventListener("scroll", W, !0), i?.unmount(), i = null, o?.remove(), o = null, s = null, t = null;
3271
+ },
3272
+ dispose() {
3273
+ H(), C(), e = null;
3274
+ },
3275
+ provideToolbarItems() {
3276
+ return [
3277
+ {
3278
+ id: "plugin:search",
3279
+ type: "search",
3280
+ icon: "flow-canvas-icon canvas-search",
3281
+ description: "搜索节点",
3282
+ group: "tools",
3283
+ order: 22,
3284
+ active: () => l.value,
3285
+ onClick: K
3286
+ }
3287
+ ];
2708
3288
  }
2709
3289
  };
2710
3290
  }
2711
- function No(s) {
3291
+ const Yo = 52, Zo = 16, Qo = 40;
3292
+ function Jo(n) {
3293
+ const e = document.createElement("div");
3294
+ e.className = "flow-canvas-minimap", n.floating !== !1 && e.classList.add("flow-canvas-minimap--floating");
3295
+ const t = document.createElement("div");
3296
+ t.className = "flow-canvas-minimap__host", e.append(t), Object.assign(e.style, {
3297
+ width: `${n.width}px`,
3298
+ height: `${n.height}px`
3299
+ }), n.floating !== !1 && Object.assign(e.style, {
3300
+ top: `${Yo}px`,
3301
+ left: `${Zo}px`
3302
+ });
3303
+ let s = null, o = n.defaultOpen ?? !1, i = null;
3304
+ function r() {
3305
+ !n.onClickOutside || i || (i = (u) => {
3306
+ const y = u.target;
3307
+ y && e.contains(y) || u.target?.closest('[data-toolbar-type="minimap"]') || n.onClickOutside();
3308
+ }, document.addEventListener("mousedown", i));
3309
+ }
3310
+ function l() {
3311
+ i && (document.removeEventListener("mousedown", i), i = null);
3312
+ }
3313
+ function a() {
3314
+ s || (s = new ft({
3315
+ container: t,
3316
+ width: n.width,
3317
+ height: n.height,
3318
+ padding: n.contentPadding ?? Qo,
3319
+ scalable: !1
3320
+ }), n.sourceGraph.use(s));
3321
+ }
3322
+ function p(u) {
3323
+ o = u, e.style.display = o ? "" : "none", o ? (a(), r()) : l();
3324
+ }
3325
+ function c() {
3326
+ p(o), n.mountTarget.appendChild(e);
3327
+ }
3328
+ function g() {
3329
+ l(), s?.dispose(), s = null, e.remove();
3330
+ }
3331
+ return c(), {
3332
+ element: e,
3333
+ isOpen: () => o,
3334
+ setOpen: p,
3335
+ toggle() {
3336
+ const u = !o;
3337
+ return p(u), u;
3338
+ },
3339
+ destroy: g
3340
+ };
3341
+ }
3342
+ function vn(n) {
2712
3343
  let e = null;
3344
+ const t = O(!1);
3345
+ function s(i) {
3346
+ e?.setOpen(i), t.value = i;
3347
+ }
3348
+ function o() {
3349
+ e && (t.value = e.toggle());
3350
+ }
2713
3351
  return {
2714
3352
  name: "minimap",
2715
3353
  priority: 90,
2716
- async attachRuntime(t) {
2717
- if (!s?.container) return;
2718
- e = s.container;
2719
- const { MiniMap: o } = await import("@antv/x6-plugin-minimap");
2720
- t.graph.use(
2721
- new o({
2722
- container: s.container,
2723
- width: s.width ?? 200,
2724
- height: s.height ?? 160
2725
- })
2726
- );
3354
+ attachRuntime(i) {
3355
+ const r = n?.width ?? 334, l = n?.height ?? 180, a = n?.container ?? i.graph.container.closest(".flow-canvas-layout__content") ?? i.graph.container.parentElement;
3356
+ a && (e = Jo({
3357
+ sourceGraph: i.graph,
3358
+ mountTarget: a,
3359
+ width: r,
3360
+ height: l,
3361
+ floating: !n?.container,
3362
+ defaultOpen: !1,
3363
+ onClickOutside: () => s(!1)
3364
+ }), s(!1));
2727
3365
  },
2728
3366
  detachRuntime() {
2729
- e = null;
3367
+ e?.destroy(), e = null, t.value = !1;
2730
3368
  },
2731
3369
  provideToolbarItems() {
2732
3370
  return [
2733
3371
  {
2734
- id: "minimap",
3372
+ id: "plugin:minimap",
2735
3373
  type: "minimap",
2736
- tooltip: "小地图",
2737
- order: 100,
2738
- visible: !!s?.container,
2739
- onClick() {
2740
- if (!e) return;
2741
- const t = e.style.display === "none";
2742
- e.style.display = t ? "" : "none";
2743
- }
3374
+ icon: "flow-canvas-icon canvas-map",
3375
+ description: "缩略图",
3376
+ group: "tools",
3377
+ order: 23,
3378
+ active: () => t.value,
3379
+ onClick: o
2744
3380
  }
2745
3381
  ];
2746
3382
  }
2747
3383
  };
2748
3384
  }
2749
- function So() {
2750
- let s = null, e = 0;
3385
+ function yn() {
3386
+ let n = null, e = 0;
2751
3387
  return {
2752
3388
  name: "clipboard",
2753
3389
  priority: 90,
2754
- onKeyboardShortcut(t, o) {
2755
- const n = t.metaKey || t.ctrlKey;
2756
- if (n && t.key === "c") {
2757
- const i = o.graph.getSelectedCells?.() ?? [];
3390
+ onKeyboardShortcut(t, s) {
3391
+ const o = t.metaKey || t.ctrlKey;
3392
+ if (o && t.key === "c") {
3393
+ const i = s.graph.getSelectedCells?.() ?? [];
2758
3394
  if (!i.length) return !1;
2759
- const r = o.flowModel.value, l = new Set(i.filter((d) => d.isNode()).map((d) => d.id)), a = [...l].map((d) => r.nodes[d]).filter(Boolean);
3395
+ const r = s.flowModel.value, l = new Set(i.filter((c) => c.isNode()).map((c) => c.id)), a = [...l].map((c) => r.nodes[c]).filter(Boolean);
2760
3396
  if (!a.length) return !1;
2761
- const f = Object.values(r.edges).filter(
2762
- (d) => l.has(d.source.nodeId) && l.has(d.target.nodeId)
3397
+ const p = Object.values(r.edges).filter(
3398
+ (c) => l.has(c.source.nodeId) && l.has(c.target.nodeId)
2763
3399
  );
2764
- return s = { nodes: a, edges: f }, e = 0, !0;
3400
+ return n = { nodes: a, edges: p }, e = 0, !0;
2765
3401
  }
2766
- if (n && t.key === "v") {
2767
- if (!s?.nodes.length) return !1;
3402
+ if (o && t.key === "v") {
3403
+ if (!n?.nodes.length) return !1;
2768
3404
  e++;
2769
3405
  const i = e * 30, r = /* @__PURE__ */ new Map(), l = [];
2770
- for (const a of s.nodes) {
2771
- const f = `${a.id}_cp${$().slice(0, 6)}`;
2772
- r.set(a.id, f), l.push({
3406
+ for (const a of n.nodes) {
3407
+ const p = `${a.id}_cp${Z().slice(0, 6)}`;
3408
+ r.set(a.id, p), l.push({
2773
3409
  type: "node.add",
2774
3410
  node: {
2775
3411
  ...a,
2776
- id: f,
3412
+ id: p,
2777
3413
  position: {
2778
3414
  x: a.position.x + i,
2779
3415
  y: a.position.y + i
@@ -2783,22 +3419,22 @@ function So() {
2783
3419
  }
2784
3420
  });
2785
3421
  }
2786
- for (const a of s.edges) {
2787
- const f = r.get(a.source.nodeId), d = r.get(a.target.nodeId);
2788
- !f || !d || l.push({
3422
+ for (const a of n.edges) {
3423
+ const p = r.get(a.source.nodeId), c = r.get(a.target.nodeId);
3424
+ !p || !c || l.push({
2789
3425
  type: "edge.add",
2790
3426
  edge: {
2791
3427
  ...a,
2792
- id: `${a.id}_cp${$().slice(0, 6)}`,
2793
- source: { ...a.source, nodeId: f },
2794
- target: { ...a.target, nodeId: d },
2795
- labels: a.labels?.map((b) => ({ ...b, id: `${b.id}_cp${$().slice(0, 6)}` })),
3428
+ id: `${a.id}_cp${Z().slice(0, 6)}`,
3429
+ source: { ...a.source, nodeId: p },
3430
+ target: { ...a.target, nodeId: c },
3431
+ labels: a.labels?.map((g) => ({ ...g, id: `${g.id}_cp${Z().slice(0, 6)}` })),
2796
3432
  payload: a.payload ? { ...a.payload } : {}
2797
3433
  }
2798
3434
  });
2799
3435
  }
2800
- return l.length && o.executeCommand({
2801
- id: $(),
3436
+ return l.length && s.executeCommand({
3437
+ id: Z(),
2802
3438
  source: "user:keyboard",
2803
3439
  label: "粘贴",
2804
3440
  timestamp: Date.now(),
@@ -2810,26 +3446,27 @@ function So() {
2810
3446
  };
2811
3447
  }
2812
3448
  export {
2813
- Y as CanvasConstraintError,
2814
- xo as CanvasLayout,
2815
- Vt as CanvasNodePalette,
2816
- wo as CanvasRuntime,
2817
- it as CanvasSchemaError,
2818
- ko as CanvasToolbar,
2819
- fo as DefaultNode,
2820
- $t as NodeActionsToolbar,
2821
- zt as NodeQuickAddPopover,
2822
- Te as applyCanvasCommand,
2823
- So as clipboardPlugin,
2824
- Eo as connectionValidatorPlugin,
2825
- go as createBuiltinEdgeTypes,
2826
- bt as createCanvasHistory,
2827
- Co as createDefaultSchema,
2828
- Jt as createDefaultToolbarItems,
2829
- mo as createEmptyFlowModel,
2830
- $ as generateId,
2831
- No as minimapPlugin,
2832
- Io as selectionPlugin,
2833
- Mo as snaplinePlugin,
2834
- bo as useCanvasEditor
3449
+ ae as CanvasConstraintError,
3450
+ dn as CanvasLayout,
3451
+ fo as CanvasNodePalette,
3452
+ ln as CanvasRuntime,
3453
+ pt as CanvasSchemaError,
3454
+ cn as CanvasToolbar,
3455
+ Ao as DefaultNode,
3456
+ Zt as NodeActionsToolbar,
3457
+ to as NodeQuickAddPopover,
3458
+ Re as applyCanvasCommand,
3459
+ yn as clipboardPlugin,
3460
+ fn as connectionValidatorPlugin,
3461
+ To as createBuiltinEdgeTypes,
3462
+ _t as createCanvasHistory,
3463
+ un as createDefaultSchema,
3464
+ bo as createDefaultToolbarItems,
3465
+ rn as createEmptyFlowModel,
3466
+ Z as generateId,
3467
+ vn as minimapPlugin,
3468
+ hn as searchPlugin,
3469
+ pn as selectionPlugin,
3470
+ gn as snaplinePlugin,
3471
+ an as useCanvasEditor
2835
3472
  };