@flowgram.ai/renderer 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,2941 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var __decorateClass = (decorators, target, key, kind) => {
30
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
31
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
32
+ if (decorator = decorators[i])
33
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
34
+ if (kind && result) __defProp(target, key, result);
35
+ return result;
36
+ };
37
+
38
+ // src/index.ts
39
+ var src_exports = {};
40
+ __export(src_exports, {
41
+ FlowContextMenuLayer: () => FlowContextMenuLayer,
42
+ FlowDebugLayer: () => FlowDebugLayer,
43
+ FlowDragEntity: () => FlowDragEntity,
44
+ FlowDragLayer: () => FlowDragLayer,
45
+ FlowLabelsLayer: () => FlowLabelsLayer,
46
+ FlowLinesLayer: () => FlowLinesLayer,
47
+ FlowNodesContentLayer: () => FlowNodesContentLayer,
48
+ FlowNodesTransformLayer: () => FlowNodesTransformLayer,
49
+ FlowRendererCommandCategory: () => FlowRendererCommandCategory,
50
+ FlowRendererComponentType: () => FlowRendererComponentType,
51
+ FlowRendererContainerModule: () => FlowRendererContainerModule,
52
+ FlowRendererContribution: () => FlowRendererContribution,
53
+ FlowRendererKey: () => FlowRendererKey,
54
+ FlowRendererRegistry: () => FlowRendererRegistry,
55
+ FlowScrollBarLayer: () => FlowScrollBarLayer,
56
+ FlowScrollLimitLayer: () => FlowScrollLimitLayer,
57
+ FlowSelectConfigEntity: () => FlowSelectConfigEntity,
58
+ FlowSelectorBoundsLayer: () => FlowSelectorBoundsLayer,
59
+ FlowSelectorBoxLayer: () => FlowSelectorBoxLayer,
60
+ FlowTextKey: () => FlowTextKey,
61
+ MARK_ACTIVATED_ARROW_ID: () => MARK_ACTIVATED_ARROW_ID,
62
+ MARK_ARROW_ID: () => MARK_ARROW_ID,
63
+ ScrollBarEvents: () => ScrollBarEvents,
64
+ SelectorBoxConfigEntity: () => SelectorBoxConfigEntity,
65
+ useBaseColor: () => useBaseColor
66
+ });
67
+ module.exports = __toCommonJS(src_exports);
68
+
69
+ // src/entities/flow-drag-entity.tsx
70
+ var import_document3 = require("@flowgram.ai/document");
71
+ var import_core2 = require("@flowgram.ai/core");
72
+ var import_utils = require("@flowgram.ai/utils");
73
+
74
+ // src/components/utils.tsx
75
+ var import_document2 = require("@flowgram.ai/document");
76
+
77
+ // src/hooks/use-base-color.ts
78
+ var import_document = require("@flowgram.ai/document");
79
+ var import_core = require("@flowgram.ai/core");
80
+ var BASE_DEFAULT_COLOR = "#BBBFC4";
81
+ var BASE_DEFAULT_ACTIVATED_COLOR = "#82A7FC";
82
+ function useBaseColor() {
83
+ const options = (0, import_core.useService)(import_document.FlowDocumentOptions);
84
+ return {
85
+ baseColor: options.constants?.[import_document.ConstantKeys.BASE_COLOR] || BASE_DEFAULT_COLOR,
86
+ baseActivatedColor: options.constants?.[import_document.ConstantKeys.BASE_ACTIVATED_COLOR] || BASE_DEFAULT_ACTIVATED_COLOR
87
+ };
88
+ }
89
+
90
+ // src/components/utils.tsx
91
+ var DEFAULT_LINE_ATTRS = {
92
+ stroke: BASE_DEFAULT_COLOR,
93
+ fill: "transparent",
94
+ strokeLinecap: "round",
95
+ strokeLinejoin: "round"
96
+ };
97
+ var DEFAULT_RADIUS = 16;
98
+ var DEFAULT_LABEL_ACTIVATE_HEIGHT = 32;
99
+ function getHorizontalVertices(line, xRadius = 16, yRadius = 20) {
100
+ const { from, to, type } = line || {};
101
+ const deltaY = Math.abs(to.y - from.y);
102
+ const deltaX = Math.abs(to.x - from.x);
103
+ const radiusXCount = deltaX / xRadius;
104
+ const radiusYCount = deltaY / yRadius;
105
+ let res = [];
106
+ if (radiusXCount < 1) {
107
+ return [];
108
+ }
109
+ switch (type) {
110
+ case import_document2.FlowTransitionLineEnum.DIVERGE_LINE:
111
+ case import_document2.FlowTransitionLineEnum.DRAGGING_LINE:
112
+ if (radiusXCount <= 1) {
113
+ return [
114
+ {
115
+ x: to.x,
116
+ y: from.y,
117
+ radiusX: deltaX
118
+ }
119
+ ];
120
+ }
121
+ res = [
122
+ {
123
+ x: from.x + yRadius,
124
+ y: from.y
125
+ },
126
+ {
127
+ x: from.x + yRadius,
128
+ y: to.y
129
+ }
130
+ ];
131
+ if (radiusXCount < 2) {
132
+ const firstRadius = deltaX - yRadius;
133
+ res = [
134
+ {
135
+ x: from.x + firstRadius,
136
+ y: from.y,
137
+ // 第一个圆角收缩 y 半径
138
+ radiusX: firstRadius
139
+ },
140
+ {
141
+ x: from.x + firstRadius,
142
+ y: to.y
143
+ }
144
+ ];
145
+ }
146
+ if (radiusYCount < 2) {
147
+ res[0].moveY = deltaY / 2;
148
+ res[1].moveY = deltaY / 2;
149
+ }
150
+ return res;
151
+ case import_document2.FlowTransitionLineEnum.MERGE_LINE:
152
+ if (radiusXCount < 2) {
153
+ return [
154
+ {
155
+ x: to.x,
156
+ y: from.y
157
+ }
158
+ ];
159
+ }
160
+ res = [
161
+ {
162
+ x: to.x - yRadius,
163
+ y: from.y
164
+ },
165
+ {
166
+ x: to.x - yRadius,
167
+ y: to.y
168
+ }
169
+ ];
170
+ if (radiusYCount < 2) {
171
+ res[0].moveY = deltaY / 2;
172
+ res[1].moveY = deltaY / 2;
173
+ }
174
+ return res;
175
+ default:
176
+ break;
177
+ }
178
+ return [];
179
+ }
180
+ function getVertices(line, xRadius = 16, yRadius = 20) {
181
+ const { from, to, type } = line || {};
182
+ const deltaY = Math.abs(to.y - from.y);
183
+ const deltaX = Math.abs(to.x - from.x);
184
+ const radiusYCount = deltaY / yRadius;
185
+ const radiusXCount = deltaX / xRadius;
186
+ let res = [];
187
+ if (radiusYCount < 1) {
188
+ return [];
189
+ }
190
+ switch (type) {
191
+ case import_document2.FlowTransitionLineEnum.DIVERGE_LINE:
192
+ case import_document2.FlowTransitionLineEnum.DRAGGING_LINE:
193
+ if (radiusYCount <= 1) {
194
+ return [
195
+ {
196
+ x: to.x,
197
+ y: from.y,
198
+ radiusY: deltaY
199
+ }
200
+ ];
201
+ }
202
+ res = [
203
+ {
204
+ x: from.x,
205
+ y: from.y + yRadius
206
+ },
207
+ {
208
+ x: to.x,
209
+ y: from.y + yRadius
210
+ }
211
+ ];
212
+ if (radiusYCount < 2) {
213
+ const firstRadius = deltaY - yRadius;
214
+ res = [
215
+ {
216
+ x: from.x,
217
+ y: from.y + firstRadius,
218
+ // 第一个圆角收缩 y 半径
219
+ radiusY: firstRadius
220
+ },
221
+ {
222
+ x: to.x,
223
+ y: from.y + firstRadius
224
+ }
225
+ ];
226
+ }
227
+ if (radiusXCount < 2) {
228
+ res[0].moveX = deltaX / 2;
229
+ res[1].moveX = deltaX / 2;
230
+ }
231
+ return res;
232
+ case import_document2.FlowTransitionLineEnum.MERGE_LINE:
233
+ if (radiusYCount < 2) {
234
+ return [
235
+ {
236
+ x: from.x,
237
+ y: to.y
238
+ }
239
+ ];
240
+ }
241
+ res = [
242
+ {
243
+ x: from.x,
244
+ y: to.y - yRadius
245
+ },
246
+ {
247
+ x: to.x,
248
+ y: to.y - yRadius
249
+ }
250
+ ];
251
+ if (radiusXCount < 2) {
252
+ res[0].moveX = deltaX / 2;
253
+ res[1].moveX = deltaX / 2;
254
+ }
255
+ return res;
256
+ default:
257
+ break;
258
+ }
259
+ return [];
260
+ }
261
+ function getTransitionLabelHoverWidth(data) {
262
+ const { isVertical } = data.entity;
263
+ if (isVertical) {
264
+ const nextWidth = data.entity.next?.firstChild && !data.entity.next.isInlineBlocks ? data.entity.next.firstChild.getData(import_document2.FlowNodeTransformData).size.width : data.entity.next?.getData(import_document2.FlowNodeTransformData).size.width;
265
+ const maxWidth = Math.max(
266
+ data.entity.getData(import_document2.FlowNodeTransformData)?.size.width ?? import_document2.DEFAULT_SPACING[import_document2.DefaultSpacingKey.HOVER_AREA_WIDTH],
267
+ nextWidth || 0
268
+ );
269
+ return maxWidth;
270
+ }
271
+ if (data.transform.next) {
272
+ return data.transform.next.inputPoint.x - data.transform.outputPoint.x;
273
+ }
274
+ return DEFAULT_LABEL_ACTIVATE_HEIGHT;
275
+ }
276
+ function getTransitionLabelHoverHeight(data) {
277
+ const { isVertical } = data.entity;
278
+ if (isVertical) {
279
+ if (data.transform.next) {
280
+ return data.transform.next.inputPoint.y - data.transform.outputPoint.y;
281
+ }
282
+ return DEFAULT_LABEL_ACTIVATE_HEIGHT;
283
+ }
284
+ const nextHeight = data.entity.next?.firstChild && !data.entity.next.isInlineBlocks ? data.entity.next.firstChild.getData(import_document2.FlowNodeTransformData).size.height : data.entity.next?.getData(import_document2.FlowNodeTransformData).size.height;
285
+ const maxHeight = Math.max(
286
+ data.entity.getData(import_document2.FlowNodeTransformData)?.size.height || 280,
287
+ nextHeight || 0
288
+ );
289
+ return maxHeight;
290
+ }
291
+
292
+ // src/entities/flow-drag-entity.tsx
293
+ var BRANCH_HOVER_HEIGHT = 64;
294
+ var SCROLL_DELTA = 4;
295
+ var SCROLL_INTERVAL = 20;
296
+ var SCROLL_BOUNDING = 20;
297
+ var EDITOR_LEFT_BAR_WIDTH = 60;
298
+ var FlowDragEntity = class extends import_core2.ConfigEntity {
299
+ constructor(conf) {
300
+ super(conf);
301
+ this.containerX = 0;
302
+ this.containerY = 0;
303
+ this.playgroundConfigEntity = this.entityManager.getEntity(
304
+ import_core2.PlaygroundConfigEntity,
305
+ true
306
+ );
307
+ }
308
+ get hasScroll() {
309
+ return Boolean(this._scrollXInterval || this._scrollYInterval);
310
+ }
311
+ isCollision(transition, rect, isBranch) {
312
+ const scale = this.playgroundConfigEntity.finalScale || 0;
313
+ if (isBranch) {
314
+ return this.isBranchCollision(transition, rect, scale);
315
+ }
316
+ return this.isNodeCollision(transition, rect, scale);
317
+ }
318
+ // 检测节点维度碰撞方法
319
+ isNodeCollision(transition, rect, scale) {
320
+ const { labels } = transition;
321
+ const { isVertical } = transition.entity;
322
+ const hasCollision = labels.some((label) => {
323
+ if (!label || ![
324
+ import_document3.FlowTransitionLabelEnum.ADDER_LABEL,
325
+ import_document3.FlowTransitionLabelEnum.COLLAPSE_ADDER_LABEL
326
+ ].includes(label.type)) {
327
+ return false;
328
+ }
329
+ const hoverWidth = isVertical ? transition.transform.bounds.width : DEFAULT_LABEL_ACTIVATE_HEIGHT;
330
+ const hoverHeight = isVertical ? DEFAULT_LABEL_ACTIVATE_HEIGHT : transition.transform.bounds.height;
331
+ const labelRect = new import_utils.Rectangle(
332
+ (label.offset.x - hoverWidth / 2) * scale,
333
+ (label.offset.y - hoverHeight / 2) * scale,
334
+ hoverWidth * scale,
335
+ hoverHeight * scale
336
+ );
337
+ return import_utils.Rectangle.intersects(labelRect, rect);
338
+ });
339
+ return {
340
+ hasCollision,
341
+ // 节点不关心 offsetType
342
+ labelOffsetType: void 0
343
+ };
344
+ }
345
+ // 检测分支维度碰撞
346
+ isBranchCollision(transition, rect, scale) {
347
+ const { labels } = transition;
348
+ const { isVertical } = transition.entity;
349
+ let labelOffsetType = import_document3.LABEL_SIDE_TYPE.NORMAL_BRANCH;
350
+ const hasCollision = labels.some((label) => {
351
+ if (!label || label.type !== import_document3.FlowTransitionLabelEnum.BRANCH_DRAGGING_LABEL) {
352
+ return false;
353
+ }
354
+ const hoverHeight = isVertical ? BRANCH_HOVER_HEIGHT : label.width || 0;
355
+ const hoverWidth = isVertical ? label.width || 0 : BRANCH_HOVER_HEIGHT;
356
+ const labelRect = new import_utils.Rectangle(
357
+ (label.offset.x - hoverWidth / 2) * scale,
358
+ (label.offset.y - hoverHeight / 2) * scale,
359
+ hoverWidth * scale,
360
+ hoverHeight * scale
361
+ );
362
+ const collision = import_utils.Rectangle.intersects(labelRect, rect);
363
+ if (collision) {
364
+ labelOffsetType = label.props.side;
365
+ }
366
+ return collision;
367
+ });
368
+ return {
369
+ hasCollision,
370
+ labelOffsetType
371
+ };
372
+ }
373
+ _startScrollX(origin, added) {
374
+ if (this._scrollXInterval) {
375
+ return;
376
+ }
377
+ const interval = window.setInterval(() => {
378
+ const current = this._scrollXInterval;
379
+ if (!current) return;
380
+ const scrollX = current.origin = added ? current.origin + SCROLL_DELTA : current.origin - SCROLL_DELTA;
381
+ this.playgroundConfigEntity.updateConfig({
382
+ scrollX
383
+ });
384
+ const playgroundConfig = this.playgroundConfigEntity.config;
385
+ if (playgroundConfig?.scrollX === scrollX) {
386
+ if (added) {
387
+ this.containerX += SCROLL_DELTA;
388
+ } else {
389
+ this.containerX -= SCROLL_DELTA;
390
+ }
391
+ this.setDomStyle();
392
+ }
393
+ }, SCROLL_INTERVAL);
394
+ this._scrollXInterval = { interval, origin };
395
+ }
396
+ _stopScrollX() {
397
+ if (this._scrollXInterval) {
398
+ clearInterval(this._scrollXInterval.interval);
399
+ this._scrollXInterval = void 0;
400
+ }
401
+ }
402
+ _startScrollY(origin, added) {
403
+ if (this._scrollYInterval) {
404
+ return;
405
+ }
406
+ const interval = window.setInterval(() => {
407
+ const current = this._scrollYInterval;
408
+ if (!current) return;
409
+ const scrollY = current.origin = added ? current.origin + SCROLL_DELTA : current.origin - SCROLL_DELTA;
410
+ this.playgroundConfigEntity.updateConfig({
411
+ scrollY
412
+ });
413
+ const playgroundConfig = this.playgroundConfigEntity.config;
414
+ if (playgroundConfig?.scrollY === scrollY) {
415
+ if (added) {
416
+ this.containerY += SCROLL_DELTA;
417
+ } else {
418
+ this.containerY -= SCROLL_DELTA;
419
+ }
420
+ this.setDomStyle();
421
+ }
422
+ }, SCROLL_INTERVAL);
423
+ this._scrollYInterval = { interval, origin };
424
+ }
425
+ _stopScrollY() {
426
+ if (this._scrollYInterval) {
427
+ clearInterval(this._scrollYInterval.interval);
428
+ this._scrollYInterval = void 0;
429
+ }
430
+ }
431
+ stopAllScroll() {
432
+ this._stopScrollX();
433
+ this._stopScrollY();
434
+ }
435
+ setDomStyle() {
436
+ this.containerDom.style.left = `${this.containerX}px`;
437
+ this.containerDom.style.top = `${this.containerY}px`;
438
+ }
439
+ scrollDirection(e, containerDom, x, y) {
440
+ const playgroundConfig = this.playgroundConfigEntity.config;
441
+ const currentScrollX = playgroundConfig.scrollX;
442
+ const currentScrollY = playgroundConfig.scrollY;
443
+ this.containerDom = containerDom;
444
+ this.containerX = x;
445
+ this.containerY = y;
446
+ const mouseToBottom = playgroundConfig.height + playgroundConfig.clientY - e.clientY;
447
+ if (mouseToBottom < SCROLL_BOUNDING) {
448
+ this._startScrollY(currentScrollY, true);
449
+ return 1 /* BOTTOM */;
450
+ }
451
+ const mouseToTop = e.clientY - playgroundConfig.clientY;
452
+ if (mouseToTop < SCROLL_BOUNDING) {
453
+ this._startScrollY(currentScrollY, false);
454
+ return 0 /* TOP */;
455
+ }
456
+ this._stopScrollY();
457
+ const mouseToRight = playgroundConfig.width + playgroundConfig.clientX - e.clientX;
458
+ if (mouseToRight < SCROLL_BOUNDING) {
459
+ this._startScrollX(currentScrollX, true);
460
+ return 3 /* RIGHT */;
461
+ }
462
+ const mouseToLeft = e.clientX - playgroundConfig.clientX;
463
+ if (mouseToLeft < SCROLL_BOUNDING + EDITOR_LEFT_BAR_WIDTH) {
464
+ this._startScrollX(currentScrollX, false);
465
+ return 2 /* LEFT */;
466
+ }
467
+ this._stopScrollX();
468
+ return void 0;
469
+ }
470
+ dispose() {
471
+ this.toDispose.dispose();
472
+ }
473
+ };
474
+ FlowDragEntity.type = "FlowDragEntity";
475
+
476
+ // src/entities/flow-select-config-entity.tsx
477
+ var import_document4 = require("@flowgram.ai/document");
478
+ var import_core3 = require("@flowgram.ai/core");
479
+ var import_utils3 = require("@flowgram.ai/utils");
480
+
481
+ // src/utils/find-selected-nodes.ts
482
+ var import_lodash = require("lodash");
483
+ function getNodePath(node) {
484
+ const path = [node];
485
+ node = node.parent;
486
+ while (node) {
487
+ path.push(node);
488
+ node = node.parent;
489
+ }
490
+ return path.reverse();
491
+ }
492
+ function findRealEntity(entity) {
493
+ while (entity.originParent) {
494
+ entity = entity.originParent;
495
+ }
496
+ return entity;
497
+ }
498
+ function findSelectedNodes(nodes) {
499
+ if (nodes.length === 0) return [];
500
+ const nodePathList = nodes.map((n) => getNodePath(n));
501
+ const minLength = Math.min(...nodePathList.map((n) => n.length));
502
+ let index = 0;
503
+ let selectedItems = [];
504
+ while (index < minLength) {
505
+ selectedItems = (0, import_lodash.uniq)(nodePathList.map((p) => p[index]));
506
+ if (selectedItems.length > 1) {
507
+ break;
508
+ }
509
+ index += 1;
510
+ }
511
+ return (0, import_lodash.uniq)(selectedItems.map((item) => findRealEntity(item)));
512
+ }
513
+
514
+ // src/entities/flow-select-config-entity.tsx
515
+ var BOUNDS_PADDING_DEFAULT = 10;
516
+ var FlowSelectConfigEntity = class extends import_core3.ConfigEntity {
517
+ constructor() {
518
+ super(...arguments);
519
+ this.boundsPadding = BOUNDS_PADDING_DEFAULT;
520
+ }
521
+ getDefaultConfig() {
522
+ return {
523
+ selectedNodes: []
524
+ };
525
+ }
526
+ get selectedNodes() {
527
+ return this.config.selectedNodes;
528
+ }
529
+ /**
530
+ * 选中节点
531
+ * @param nodes
532
+ */
533
+ set selectedNodes(nodes) {
534
+ nodes = findSelectedNodes(nodes);
535
+ if (nodes.length !== this.config.selectedNodes.length || nodes.some((n) => !this.config.selectedNodes.includes(n))) {
536
+ this.config.selectedNodes.forEach((oldNode) => {
537
+ if (!nodes.includes(oldNode)) {
538
+ oldNode.getData(import_document4.FlowNodeRenderData).activated = false;
539
+ }
540
+ });
541
+ nodes.forEach((node) => {
542
+ node.getData(import_document4.FlowNodeRenderData).activated = true;
543
+ });
544
+ if (import_utils3.Compare.isArrayShallowChanged(this.config.selectedNodes, nodes)) {
545
+ this.updateConfig({
546
+ selectedNodes: nodes
547
+ });
548
+ }
549
+ }
550
+ }
551
+ /**
552
+ * 清除选中节点
553
+ */
554
+ clearSelectedNodes() {
555
+ if (this.config.selectedNodes.length === 0) return;
556
+ this.config.selectedNodes.forEach((node) => {
557
+ node.getData(import_document4.FlowNodeRenderData).activated = false;
558
+ });
559
+ this.updateConfig({
560
+ selectedNodes: []
561
+ });
562
+ }
563
+ /**
564
+ * 通过选择框选中节点
565
+ * @param rect
566
+ * @param transforms
567
+ */
568
+ selectFromBounds(rect, transforms) {
569
+ const selectedNodes = [];
570
+ transforms.forEach((transform) => {
571
+ if (import_utils3.Rectangle.intersects(rect, transform.bounds)) {
572
+ if (transform.entity.originParent) {
573
+ selectedNodes.push(transform.entity.originParent);
574
+ } else {
575
+ selectedNodes.push(transform.entity);
576
+ }
577
+ }
578
+ });
579
+ this.selectedNodes = selectedNodes;
580
+ }
581
+ /**
582
+ * 获取选中节点外围的最大边框
583
+ */
584
+ getSelectedBounds() {
585
+ const nodes = this.selectedNodes;
586
+ if (nodes.length === 0) {
587
+ return import_utils3.Rectangle.EMPTY;
588
+ }
589
+ return import_utils3.Rectangle.enlarge(nodes.map((n) => n.getData(import_document4.FlowNodeTransformData).bounds)).pad(
590
+ this.boundsPadding
591
+ );
592
+ }
593
+ };
594
+ FlowSelectConfigEntity.type = "FlowSelectConfigEntity";
595
+
596
+ // src/entities/selector-box-config-entity.ts
597
+ var import_core4 = require("@flowgram.ai/core");
598
+ var import_utils4 = require("@flowgram.ai/utils");
599
+ var SelectorBoxConfigEntity = class extends import_core4.ConfigEntity {
600
+ get dragInfo() {
601
+ return this.config;
602
+ }
603
+ setDragInfo(info) {
604
+ this.updateConfig(info);
605
+ }
606
+ get disabled() {
607
+ return this.config && !!this.config.disabled;
608
+ }
609
+ set disabled(disabled) {
610
+ this.updateConfig({
611
+ disabled
612
+ });
613
+ }
614
+ get isStart() {
615
+ return this.dragInfo.isStart;
616
+ }
617
+ get isMoving() {
618
+ return this.dragInfo.isMoving;
619
+ }
620
+ get position() {
621
+ const { dragInfo } = this;
622
+ return {
623
+ x: dragInfo.startPos.x < dragInfo.endPos.x ? dragInfo.startPos.x : dragInfo.endPos.x,
624
+ y: dragInfo.startPos.y < dragInfo.endPos.y ? dragInfo.startPos.y : dragInfo.endPos.y
625
+ };
626
+ }
627
+ get size() {
628
+ const { dragInfo } = this;
629
+ return {
630
+ width: Math.abs(dragInfo.startPos.x - dragInfo.endPos.x),
631
+ height: Math.abs(dragInfo.startPos.y - dragInfo.endPos.y)
632
+ };
633
+ }
634
+ get collapsed() {
635
+ const { size } = this;
636
+ return size.width === 0 && size.height === 0;
637
+ }
638
+ collapse() {
639
+ this.setDragInfo({
640
+ ...this.dragInfo,
641
+ isMoving: false,
642
+ isStart: false
643
+ });
644
+ }
645
+ toRectangle(scale) {
646
+ const { position, size } = this;
647
+ return new import_utils4.Rectangle(
648
+ position.x / scale,
649
+ position.y / scale,
650
+ size.width / scale,
651
+ size.height / scale
652
+ );
653
+ }
654
+ };
655
+ SelectorBoxConfigEntity.type = "SelectorBoxConfigEntity";
656
+
657
+ // src/layers/flow-nodes-transform-layer.tsx
658
+ var import_inversify2 = require("inversify");
659
+ var import_utils6 = require("@flowgram.ai/utils");
660
+ var import_document5 = require("@flowgram.ai/document");
661
+ var import_core5 = require("@flowgram.ai/core");
662
+
663
+ // src/flow-renderer-resize-observer.ts
664
+ var import_inversify = require("inversify");
665
+ var import_utils5 = require("@flowgram.ai/utils");
666
+
667
+ // src/utils/element.ts
668
+ var import_lodash2 = require("lodash");
669
+ var isHidden = (dom) => {
670
+ const style = window.getComputedStyle(dom);
671
+ return (0, import_lodash2.isNil)(dom?.offsetParent) || style?.display === "none";
672
+ };
673
+ var isRectInit = (rect) => {
674
+ if (!rect) {
675
+ return false;
676
+ }
677
+ if (rect.bottom === 0 && rect.height === 0 && rect.left === 0 && rect.right === 0 && rect.top === 0 && rect.width === 0 && rect.x === 0 && rect.y === 0) {
678
+ return false;
679
+ }
680
+ return true;
681
+ };
682
+
683
+ // src/flow-renderer-resize-observer.ts
684
+ var FlowRendererResizeObserver = class {
685
+ /**
686
+ * 监听元素 size,并同步到 transform
687
+ * @param el
688
+ * @param transform
689
+ */
690
+ observe(el, transform) {
691
+ const observer = new ResizeObserver((entries) => {
692
+ window.requestAnimationFrame(() => {
693
+ if (!Array.isArray(entries) || !entries.length) {
694
+ return;
695
+ }
696
+ const entry = entries[0];
697
+ const { contentRect, target } = entry;
698
+ const isContentRectInit = isRectInit(contentRect);
699
+ const isLeaveDOMTree = !target.parentNode;
700
+ const isHiddenElement = isHidden(target.parentNode);
701
+ if (isContentRectInit && !isLeaveDOMTree && !isHiddenElement) {
702
+ transform.size = {
703
+ width: Math.round(contentRect.width * 10) / 10,
704
+ height: Math.round(contentRect.height * 10) / 10
705
+ };
706
+ }
707
+ });
708
+ });
709
+ observer.observe(el);
710
+ return import_utils5.Disposable.create(() => {
711
+ observer.unobserve(el);
712
+ });
713
+ }
714
+ };
715
+ FlowRendererResizeObserver = __decorateClass([
716
+ (0, import_inversify.injectable)()
717
+ ], FlowRendererResizeObserver);
718
+
719
+ // src/layers/flow-nodes-transform-layer.tsx
720
+ var FlowNodesTransformLayer = class extends import_core5.Layer {
721
+ constructor() {
722
+ super(...arguments);
723
+ this.node = import_utils6.domUtils.createDivWithClass("gedit-flow-nodes-layer");
724
+ // onViewportChange() {
725
+ // this.throttleUpdate()
726
+ // }
727
+ // throttleUpdate = throttle(() => {
728
+ // this.renderCache.getFromCache().forEach((cache) => cache.updateBounds())
729
+ // }, 100)
730
+ this.renderCache = import_utils6.Cache.create(
731
+ (transform) => {
732
+ const { renderState } = transform;
733
+ const { node } = renderState;
734
+ const { entity } = transform;
735
+ node.id = entity.id;
736
+ let resizeDispose;
737
+ const append = () => {
738
+ if (resizeDispose) return;
739
+ this.renderElement.appendChild(node);
740
+ resizeDispose = this.resizeObserver.observe(node, transform);
741
+ };
742
+ const dispose = () => {
743
+ if (!resizeDispose) return;
744
+ if (node.parentElement) {
745
+ this.renderElement.removeChild(node);
746
+ }
747
+ resizeDispose.dispose();
748
+ resizeDispose = void 0;
749
+ };
750
+ append();
751
+ return {
752
+ dispose,
753
+ updateBounds: () => {
754
+ const { bounds } = transform;
755
+ if (node.style.left !== `${bounds.x}px` || node.style.top !== `${bounds.y}px`) {
756
+ node.style.left = `${bounds.x}px`;
757
+ node.style.top = `${bounds.y}px`;
758
+ }
759
+ }
760
+ };
761
+ }
762
+ );
763
+ }
764
+ get transformVisibles() {
765
+ return this.document.getRenderDatas(import_document5.FlowNodeTransformData, false);
766
+ }
767
+ /**
768
+ * 监听缩放,目前采用整体缩放
769
+ * @param scale
770
+ */
771
+ onZoom(scale) {
772
+ this.node.style.transform = `scale(${scale})`;
773
+ }
774
+ dispose() {
775
+ this.renderCache.dispose();
776
+ super.dispose();
777
+ }
778
+ onReady() {
779
+ this.node.style.zIndex = "10";
780
+ }
781
+ get visibeBounds() {
782
+ return this.transformVisibles.map((transform) => transform.bounds);
783
+ }
784
+ /**
785
+ * 更新节点的 bounds 数据
786
+ */
787
+ updateNodesBounds() {
788
+ this.renderCache.getMoreByItems(this.transformVisibles).forEach((render) => render.updateBounds());
789
+ }
790
+ autorun() {
791
+ if (this.documentTransformer.loading) return;
792
+ this.documentTransformer.refresh();
793
+ this.updateNodesBounds();
794
+ }
795
+ get renderElement() {
796
+ if (typeof this.options.renderElement === "function") {
797
+ const element = this.options.renderElement();
798
+ if (element) {
799
+ return element;
800
+ }
801
+ } else if (typeof this.options.renderElement !== "undefined") {
802
+ return this.options.renderElement;
803
+ }
804
+ return this.node;
805
+ }
806
+ };
807
+ __decorateClass([
808
+ (0, import_inversify2.inject)(import_document5.FlowDocument)
809
+ ], FlowNodesTransformLayer.prototype, "document", 2);
810
+ __decorateClass([
811
+ (0, import_inversify2.inject)(FlowRendererResizeObserver)
812
+ ], FlowNodesTransformLayer.prototype, "resizeObserver", 2);
813
+ __decorateClass([
814
+ (0, import_core5.observeEntity)(import_document5.FlowDocumentTransformerEntity)
815
+ ], FlowNodesTransformLayer.prototype, "documentTransformer", 2);
816
+ __decorateClass([
817
+ (0, import_core5.observeEntityDatas)(import_document5.FlowNodeEntity, import_document5.FlowNodeTransformData)
818
+ ], FlowNodesTransformLayer.prototype, "_transforms", 2);
819
+ FlowNodesTransformLayer = __decorateClass([
820
+ (0, import_inversify2.injectable)()
821
+ ], FlowNodesTransformLayer);
822
+
823
+ // src/layers/flow-nodes-content-layer.tsx
824
+ var import_react_dom = __toESM(require("react-dom"));
825
+ var import_react = __toESM(require("react"));
826
+ var import_inversify4 = require("inversify");
827
+ var import_utils7 = require("@flowgram.ai/utils");
828
+ var import_document6 = require("@flowgram.ai/document");
829
+ var import_core7 = require("@flowgram.ai/core");
830
+
831
+ // src/flow-renderer-registry.ts
832
+ var import_inversify3 = require("inversify");
833
+ var import_i18n = require("@flowgram.ai/i18n");
834
+ var import_core6 = require("@flowgram.ai/core");
835
+
836
+ // src/flow-renderer-contribution.ts
837
+ var FlowRendererContribution = Symbol("FlowRendererContribution");
838
+
839
+ // src/flow-renderer-registry.ts
840
+ var FlowRendererComponentType = /* @__PURE__ */ ((FlowRendererComponentType2) => {
841
+ FlowRendererComponentType2[FlowRendererComponentType2["REACT"] = 0] = "REACT";
842
+ FlowRendererComponentType2[FlowRendererComponentType2["DOM"] = 1] = "DOM";
843
+ FlowRendererComponentType2[FlowRendererComponentType2["TEXT"] = 2] = "TEXT";
844
+ return FlowRendererComponentType2;
845
+ })(FlowRendererComponentType || {});
846
+ var FlowRendererKey = /* @__PURE__ */ ((FlowRendererKey2) => {
847
+ FlowRendererKey2["NODE_RENDER"] = "node-render";
848
+ FlowRendererKey2["ADDER"] = "adder";
849
+ FlowRendererKey2["COLLAPSE"] = "collapse";
850
+ FlowRendererKey2["BRANCH_ADDER"] = "branch-adder";
851
+ FlowRendererKey2["TRY_CATCH_COLLAPSE"] = "try-catch-collapse";
852
+ FlowRendererKey2["DRAG_NODE"] = "drag-node";
853
+ FlowRendererKey2["DRAGGABLE_ADDER"] = "draggable-adder";
854
+ FlowRendererKey2["DRAG_HIGHLIGHT_ADDER"] = "drag-highlight-adder";
855
+ FlowRendererKey2["DRAG_BRANCH_HIGHLIGHT_ADDER"] = "drag-branch-highlight-adder";
856
+ FlowRendererKey2["SELECTOR_BOX_POPOVER"] = "selector-box-popover";
857
+ FlowRendererKey2["CONTEXT_MENU_POPOVER"] = "context-menu-popover";
858
+ FlowRendererKey2["SUB_CANVAS"] = "sub-canvas";
859
+ FlowRendererKey2["MARKER_ARROW"] = "marker-arrow";
860
+ FlowRendererKey2["MARKER_ACTIVATE_ARROW"] = "marker-active-arrow";
861
+ return FlowRendererKey2;
862
+ })(FlowRendererKey || {});
863
+ var FlowTextKey = /* @__PURE__ */ ((FlowTextKey2) => {
864
+ FlowTextKey2["LOOP_END_TEXT"] = "loop-end-text";
865
+ FlowTextKey2["LOOP_TRAVERSE_TEXT"] = "loop-traverse-text";
866
+ FlowTextKey2["LOOP_WHILE_TEXT"] = "loop-while-text";
867
+ FlowTextKey2["TRY_START_TEXT"] = "try-start-text";
868
+ FlowTextKey2["TRY_END_TEXT"] = "try-end-text";
869
+ FlowTextKey2["CATCH_TEXT"] = "catch-text";
870
+ return FlowTextKey2;
871
+ })(FlowTextKey || {});
872
+ var FlowRendererCommandCategory = /* @__PURE__ */ ((FlowRendererCommandCategory2) => {
873
+ FlowRendererCommandCategory2["SELECTOR_BOX"] = "SELECTOR_BOX";
874
+ return FlowRendererCommandCategory2;
875
+ })(FlowRendererCommandCategory || {});
876
+ var FlowRendererRegistry = class {
877
+ constructor() {
878
+ this.componentsMap = /* @__PURE__ */ new Map();
879
+ this.textMap = /* @__PURE__ */ new Map();
880
+ this.contribs = [];
881
+ }
882
+ init() {
883
+ this.contribs.forEach((contrib) => contrib.registerRenderer?.(this));
884
+ }
885
+ /**
886
+ * 注册 组件数据
887
+ */
888
+ registerRendererComponents(renderKey, comp) {
889
+ this.componentsMap.set(renderKey, comp);
890
+ }
891
+ registerReactComponent(renderKey, renderer) {
892
+ this.componentsMap.set(renderKey, {
893
+ type: 0 /* REACT */,
894
+ renderer
895
+ });
896
+ }
897
+ /**
898
+ * 注册文案
899
+ */
900
+ registerText(configs) {
901
+ Object.entries(configs).forEach(([key, value]) => {
902
+ this.textMap.set(key, value);
903
+ });
904
+ }
905
+ getText(textKey) {
906
+ return import_i18n.I18n.t(textKey, { disableReturnKey: true }) || this.textMap.get(textKey);
907
+ }
908
+ /**
909
+ * TODO: support memo
910
+ */
911
+ getRendererComponent(renderKey) {
912
+ const comp = this.componentsMap.get(renderKey);
913
+ if (!comp) {
914
+ throw new Error(`Unknown render key ${renderKey}`);
915
+ }
916
+ return comp;
917
+ }
918
+ tryToGetRendererComponent(renderKey) {
919
+ return this.componentsMap.get(renderKey);
920
+ }
921
+ /**
922
+ * 注册画布层
923
+ */
924
+ registerLayers(...layerRegistries) {
925
+ layerRegistries.forEach((layer) => this.pipeline.registerLayer(layer));
926
+ }
927
+ /**
928
+ * 根据配置注册画布
929
+ * @param layerRegistry
930
+ * @param options
931
+ */
932
+ registerLayer(layerRegistry, options) {
933
+ this.pipeline.registerLayer(layerRegistry, options);
934
+ }
935
+ };
936
+ __decorateClass([
937
+ (0, import_inversify3.multiInject)(FlowRendererContribution),
938
+ (0, import_inversify3.optional)()
939
+ ], FlowRendererRegistry.prototype, "contribs", 2);
940
+ __decorateClass([
941
+ (0, import_inversify3.inject)(import_core6.PipelineRegistry)
942
+ ], FlowRendererRegistry.prototype, "pipeline", 2);
943
+ FlowRendererRegistry = __decorateClass([
944
+ (0, import_inversify3.injectable)()
945
+ ], FlowRendererRegistry);
946
+
947
+ // src/layers/flow-nodes-content-layer.tsx
948
+ var FlowNodesContentLayer = class extends import_core7.Layer {
949
+ constructor() {
950
+ super(...arguments);
951
+ this.renderMemoCache = /* @__PURE__ */ new WeakMap();
952
+ this.node = import_utils7.domUtils.createDivWithClass("gedit-flow-nodes-layer");
953
+ this.reactPortals = import_utils7.Cache.create(
954
+ (data) => {
955
+ const { node, entity } = data;
956
+ const { config } = this;
957
+ const PortalRenderer = this.getPortalRenderer(data);
958
+ function Portal() {
959
+ import_react.default.useEffect(() => {
960
+ if (node.clientWidth && node.clientHeight) {
961
+ const transform = entity.getData(import_document6.FlowNodeTransformData);
962
+ if (transform)
963
+ transform.size = {
964
+ width: node.clientWidth,
965
+ height: node.clientHeight
966
+ };
967
+ }
968
+ }, []);
969
+ return import_react_dom.default.createPortal(
970
+ /* @__PURE__ */ import_react.default.createElement(import_core7.PlaygroundEntityContext.Provider, { value: entity }, /* @__PURE__ */ import_react.default.createElement(
971
+ PortalRenderer,
972
+ {
973
+ node: entity,
974
+ version: data?.version,
975
+ activated: data?.activated,
976
+ readonly: config.readonly,
977
+ disabled: config.disabled
978
+ }
979
+ )),
980
+ node
981
+ );
982
+ }
983
+ return {
984
+ id: node.id || entity.id,
985
+ dispose: () => {
986
+ },
987
+ Portal
988
+ };
989
+ }
990
+ );
991
+ }
992
+ get renderStatesVisible() {
993
+ return this.document.getRenderDatas(import_document6.FlowNodeRenderData, false);
994
+ }
995
+ getPortalRenderer(data) {
996
+ const meta = data.entity.getNodeMeta();
997
+ const renderer = this.rendererRegistry.getRendererComponent(
998
+ meta.renderKey || "node-render" /* NODE_RENDER */
999
+ );
1000
+ const reactRenderer = renderer.renderer;
1001
+ let memoCache = this.renderMemoCache.get(reactRenderer);
1002
+ if (!memoCache) {
1003
+ memoCache = import_react.default.memo(reactRenderer);
1004
+ this.renderMemoCache.set(reactRenderer, memoCache);
1005
+ }
1006
+ return memoCache;
1007
+ }
1008
+ /**
1009
+ * 监听缩放,目前采用整体缩放
1010
+ * @param scale
1011
+ */
1012
+ onZoom(scale) {
1013
+ this.node.style.transform = `scale(${scale})`;
1014
+ }
1015
+ dispose() {
1016
+ this.reactPortals.dispose();
1017
+ super.dispose();
1018
+ }
1019
+ onReady() {
1020
+ this.node.style.zIndex = "10";
1021
+ }
1022
+ /**
1023
+ * 监听readonly和 disabled 状态 并刷新layer, 并刷新节点
1024
+ */
1025
+ onReadonlyOrDisabledChange() {
1026
+ this.render();
1027
+ }
1028
+ getPortals() {
1029
+ return this.reactPortals.getMoreByItems(this.renderStatesVisible);
1030
+ }
1031
+ render() {
1032
+ if (this.documentTransformer.loading) return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null);
1033
+ this.documentTransformer.refresh();
1034
+ return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, this.getPortals().map((portal) => /* @__PURE__ */ import_react.default.createElement(portal.Portal, { key: portal.id })));
1035
+ }
1036
+ };
1037
+ __decorateClass([
1038
+ (0, import_inversify4.inject)(import_document6.FlowDocument)
1039
+ ], FlowNodesContentLayer.prototype, "document", 2);
1040
+ __decorateClass([
1041
+ (0, import_inversify4.inject)(FlowRendererRegistry)
1042
+ ], FlowNodesContentLayer.prototype, "rendererRegistry", 2);
1043
+ __decorateClass([
1044
+ (0, import_core7.observeEntity)(import_document6.FlowDocumentTransformerEntity)
1045
+ ], FlowNodesContentLayer.prototype, "documentTransformer", 2);
1046
+ __decorateClass([
1047
+ (0, import_core7.observeEntityDatas)(import_document6.FlowNodeEntity, import_document6.FlowNodeRenderData)
1048
+ ], FlowNodesContentLayer.prototype, "_renderStates", 2);
1049
+ FlowNodesContentLayer = __decorateClass([
1050
+ (0, import_inversify4.injectable)()
1051
+ ], FlowNodesContentLayer);
1052
+
1053
+ // src/layers/flow-lines-layer.tsx
1054
+ var import_react8 = __toESM(require("react"));
1055
+ var import_lodash4 = require("lodash");
1056
+ var import_inversify5 = require("inversify");
1057
+ var import_utils12 = require("@flowgram.ai/utils");
1058
+ var import_document9 = require("@flowgram.ai/document");
1059
+ var import_core8 = require("@flowgram.ai/core");
1060
+
1061
+ // src/components/MarkerArrow.tsx
1062
+ var import_react2 = __toESM(require("react"));
1063
+ var MARK_ARROW_ID = "line-marker-arrow";
1064
+ var MARK_ARROW_URL = `url(#${MARK_ARROW_ID})`;
1065
+ function MarkerArrow() {
1066
+ const { baseColor } = useBaseColor();
1067
+ return /* @__PURE__ */ import_react2.default.createElement("marker", { id: MARK_ARROW_ID, markerWidth: "11", markerHeight: "14", refX: "10", refY: "7", orient: "auto" }, /* @__PURE__ */ import_react2.default.createElement(
1068
+ "path",
1069
+ {
1070
+ d: "M9.6 5.2C10.8 6.1 10.8 7.9 9.6 8.8L3.6 13.3C2.11672 14.4125 0 13.3541 0 11.5L0 2.5C0 0.645898 2.11672 -0.412461 3.6 0.7L9.6 5.2Z",
1071
+ fill: baseColor
1072
+ }
1073
+ ));
1074
+ }
1075
+ var MarkerArrow_default = MarkerArrow;
1076
+
1077
+ // src/components/MarkerActivatedArrow.tsx
1078
+ var import_react3 = __toESM(require("react"));
1079
+ var MARK_ACTIVATED_ARROW_ID = "line-marker-arrow-activated";
1080
+ var MARK_ACTIVATED_ARROW_URL = `url(#${MARK_ACTIVATED_ARROW_ID})`;
1081
+ function MarkerActivatedArrow() {
1082
+ const { baseActivatedColor } = useBaseColor();
1083
+ return /* @__PURE__ */ import_react3.default.createElement(
1084
+ "marker",
1085
+ {
1086
+ id: MARK_ACTIVATED_ARROW_ID,
1087
+ markerWidth: "11",
1088
+ markerHeight: "14",
1089
+ refX: "10",
1090
+ refY: "7",
1091
+ orient: "auto"
1092
+ },
1093
+ /* @__PURE__ */ import_react3.default.createElement(
1094
+ "path",
1095
+ {
1096
+ d: "M9.6 5.2C10.8 6.1 10.8 7.9 9.6 8.8L3.6 13.3C2.11672 14.4125 0 13.3541 0 11.5L0 2.5C0 0.645898 2.11672 -0.412461 3.6 0.7L9.6 5.2Z",
1097
+ fill: baseActivatedColor
1098
+ }
1099
+ )
1100
+ );
1101
+ }
1102
+ var MarkerActivatedArrow_default = MarkerActivatedArrow;
1103
+
1104
+ // src/components/LinesRenderer.tsx
1105
+ var import_react7 = __toESM(require("react"));
1106
+ var import_utils11 = require("@flowgram.ai/utils");
1107
+ var import_document7 = require("@flowgram.ai/document");
1108
+ var import_document8 = require("@flowgram.ai/document");
1109
+
1110
+ // src/components/StraightLine.tsx
1111
+ var import_react4 = __toESM(require("react"));
1112
+ function StraightLine(props) {
1113
+ const { from, to, activated, style } = props;
1114
+ const { baseColor, baseActivatedColor } = useBaseColor();
1115
+ return /* @__PURE__ */ import_react4.default.createElement(
1116
+ "path",
1117
+ {
1118
+ d: `M ${from.x} ${from.y} L ${to.x} ${to.y}`,
1119
+ ...DEFAULT_LINE_ATTRS,
1120
+ stroke: activated ? baseActivatedColor : baseColor,
1121
+ style
1122
+ }
1123
+ );
1124
+ }
1125
+ var StraightLine_default = StraightLine;
1126
+
1127
+ // src/components/RoundedTurningLine.tsx
1128
+ var import_react5 = __toESM(require("react"));
1129
+ var import_lodash3 = require("lodash");
1130
+ var import_utils9 = require("@flowgram.ai/utils");
1131
+ function RoundedTurningLine(props) {
1132
+ const { vertices, radius = DEFAULT_RADIUS, hide, xRadius, yRadius, ...line } = props;
1133
+ const { from, to, arrow, activated, style } = line || {};
1134
+ const { baseActivatedColor, baseColor } = useBaseColor();
1135
+ const realVertices = vertices || (props.isHorizontal ? getHorizontalVertices(line, xRadius, yRadius) : getVertices(line, xRadius, yRadius));
1136
+ const middleStr = (0, import_react5.useMemo)(
1137
+ () => realVertices.map((point, idx) => {
1138
+ const prev = realVertices[idx - 1] || from;
1139
+ const next = realVertices[idx + 1] || to;
1140
+ const prevDelta = { x: Math.abs(prev.x - point.x), y: Math.abs(prev.y - point.y) };
1141
+ const nextDelta = { x: Math.abs(next.x - point.x), y: Math.abs(next.y - point.y) };
1142
+ const isRightAngleX = prevDelta.x === 0 && nextDelta.y === 0;
1143
+ const isRightAngleY = prevDelta.y === 0 && nextDelta.x === 0;
1144
+ const isRightAngle = isRightAngleX || isRightAngleY;
1145
+ if (!isRightAngle) {
1146
+ console.error(`vertex ${point.x},${point.y} is not right angle`);
1147
+ }
1148
+ const inPoint = new import_utils9.Point().copyFrom(point);
1149
+ const outPoint = new import_utils9.Point().copyFrom(point);
1150
+ const radiusX = (0, import_lodash3.isNil)(point.radiusX) ? radius : point.radiusX;
1151
+ const radiusY = (0, import_lodash3.isNil)(point.radiusY) ? radius : point.radiusY;
1152
+ let rx = radiusX;
1153
+ let ry = radiusY;
1154
+ if (isRightAngleX) {
1155
+ ry = Math.min(prevDelta.y, radiusY);
1156
+ const moveY = (0, import_lodash3.isNil)(point.moveY) ? ry : point.moveY;
1157
+ inPoint.y += from.y < point.y ? -moveY : +moveY;
1158
+ rx = Math.min(nextDelta.x, radiusX);
1159
+ const moveX = (0, import_lodash3.isNil)(point.moveX) ? rx : point.moveX;
1160
+ outPoint.x += to.x < point.x ? -moveX : +moveX;
1161
+ }
1162
+ if (isRightAngleY) {
1163
+ rx = Math.min(prevDelta.x, radiusX);
1164
+ const moveX = (0, import_lodash3.isNil)(point.moveX) ? rx : point.moveX;
1165
+ inPoint.x += from.x < point.x ? -moveX : +moveX;
1166
+ ry = Math.min(nextDelta.y, radiusY);
1167
+ const moveY = (0, import_lodash3.isNil)(point.moveY) ? ry : point.moveY;
1168
+ outPoint.y += to.y < point.y ? -moveY : +moveY;
1169
+ }
1170
+ const crossProduct = (point.x - inPoint.x) * (outPoint.y - inPoint.y) - (point.y - inPoint.y) * (outPoint.x - inPoint.x);
1171
+ const isClockWise = crossProduct > 0;
1172
+ return `L ${inPoint.x} ${inPoint.y} A ${rx} ${ry} 0 0 ${isClockWise ? 1 : 0} ${outPoint.x} ${outPoint.y}`;
1173
+ }).join(" "),
1174
+ [realVertices]
1175
+ );
1176
+ if (hide) {
1177
+ return null;
1178
+ }
1179
+ const pathStr = `M ${from.x} ${from.y} ${middleStr} L ${to.x} ${to.y}`;
1180
+ return /* @__PURE__ */ import_react5.default.createElement(
1181
+ "path",
1182
+ {
1183
+ d: pathStr,
1184
+ ...DEFAULT_LINE_ATTRS,
1185
+ stroke: activated ? baseActivatedColor : baseColor,
1186
+ ...arrow ? {
1187
+ markerEnd: activated ? MARK_ACTIVATED_ARROW_URL : MARK_ARROW_URL
1188
+ } : {},
1189
+ style
1190
+ }
1191
+ );
1192
+ }
1193
+ var RoundedTurningLine_default = RoundedTurningLine;
1194
+
1195
+ // src/components/CustomLine.tsx
1196
+ var import_react6 = __toESM(require("react"));
1197
+ function CustomLine(props) {
1198
+ const { renderKey, rendererRegistry, ...line } = props;
1199
+ if (!renderKey) {
1200
+ return /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null);
1201
+ }
1202
+ const renderer = rendererRegistry.getRendererComponent(renderKey);
1203
+ if (!renderer) {
1204
+ return /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null);
1205
+ }
1206
+ const Component = renderer.renderer;
1207
+ return /* @__PURE__ */ import_react6.default.createElement(Component, { ...line });
1208
+ }
1209
+ var CustomLine_default = CustomLine;
1210
+
1211
+ // src/components/LinesRenderer.tsx
1212
+ function createLines(props) {
1213
+ const { data, rendererRegistry, linesSave, dragService } = props;
1214
+ const { lines, entity } = data || {};
1215
+ const xRadius = (0, import_document8.getDefaultSpacing)(entity, import_document7.DefaultSpacingKey.ROUNDED_LINE_X_RADIUS);
1216
+ const yRadius = (0, import_document8.getDefaultSpacing)(entity, import_document7.DefaultSpacingKey.ROUNDED_LINE_Y_RADIUS);
1217
+ const renderLine = (line, index) => {
1218
+ const { renderData } = data;
1219
+ const { isVertical } = data.entity;
1220
+ const { lineActivated } = renderData || {};
1221
+ const draggingLineHide = line.type === import_document7.FlowTransitionLineEnum.DRAGGING_LINE && !dragService.isDroppableBranch(data.entity, line.side);
1222
+ const draggingLineActivated = line.type === import_document7.FlowTransitionLineEnum.DRAGGING_LINE && data.entity?.id === dragService.dropNodeId && line.side === dragService.labelSide;
1223
+ switch (line.type) {
1224
+ case import_document7.FlowTransitionLineEnum.STRAIGHT_LINE:
1225
+ return /* @__PURE__ */ import_react7.default.createElement(StraightLine_default, { key: `${data.entity.id}${index}`, activated: lineActivated, ...line });
1226
+ case import_document7.FlowTransitionLineEnum.DIVERGE_LINE:
1227
+ case import_document7.FlowTransitionLineEnum.DRAGGING_LINE:
1228
+ case import_document7.FlowTransitionLineEnum.MERGE_LINE:
1229
+ case import_document7.FlowTransitionLineEnum.ROUNDED_LINE:
1230
+ return /* @__PURE__ */ import_react7.default.createElement(
1231
+ RoundedTurningLine_default,
1232
+ {
1233
+ key: `${data.entity.id}${index}`,
1234
+ isHorizontal: !isVertical,
1235
+ activated: lineActivated || draggingLineActivated,
1236
+ ...line,
1237
+ xRadius,
1238
+ yRadius,
1239
+ hide: draggingLineHide
1240
+ }
1241
+ );
1242
+ case import_document7.FlowTransitionLineEnum.CUSTOM_LINE:
1243
+ return /* @__PURE__ */ import_react7.default.createElement(
1244
+ CustomLine_default,
1245
+ {
1246
+ key: `${data.entity.id}${index}`,
1247
+ ...line,
1248
+ rendererRegistry
1249
+ }
1250
+ );
1251
+ default:
1252
+ break;
1253
+ }
1254
+ return void 0;
1255
+ };
1256
+ lines.forEach((line, index) => {
1257
+ const bounds = import_utils11.Rectangle.createRectangleWithTwoPoints(line.from, line.to).pad(10);
1258
+ if (props.isViewportVisible(bounds)) {
1259
+ const jsxEl = renderLine(line, index);
1260
+ if (jsxEl) linesSave.push(jsxEl);
1261
+ }
1262
+ });
1263
+ }
1264
+
1265
+ // src/layers/flow-lines-layer.tsx
1266
+ var FlowLinesLayer = class extends import_core8.Layer {
1267
+ constructor() {
1268
+ super(...arguments);
1269
+ this.node = import_utils12.domUtils.createDivWithClass("gedit-flow-lines-layer");
1270
+ /**
1271
+ * 可视区域变化
1272
+ */
1273
+ this.onViewportChange = (0, import_lodash4.throttle)(() => {
1274
+ this.render();
1275
+ }, 100);
1276
+ }
1277
+ get transitions() {
1278
+ return this.document.getRenderDatas(import_document9.FlowNodeTransitionData);
1279
+ }
1280
+ onZoom() {
1281
+ const svgContainer = this.node.querySelector("svg.flow-lines-container");
1282
+ svgContainer?.setAttribute?.("viewBox", this.viewBox);
1283
+ }
1284
+ onReady() {
1285
+ this.node.style.zIndex = "1";
1286
+ }
1287
+ get viewBox() {
1288
+ const ratio = 1e3 / this.config.finalScale;
1289
+ return `0 0 ${ratio} ${ratio}`;
1290
+ }
1291
+ render() {
1292
+ const allLines = [];
1293
+ const isViewportVisible = this.config.isViewportVisible.bind(this.config);
1294
+ if (this.documentTransformer.loading) return /* @__PURE__ */ import_react8.default.createElement(import_react8.default.Fragment, null);
1295
+ this.documentTransformer.refresh();
1296
+ this.transitions.forEach((transition) => {
1297
+ createLines({
1298
+ data: transition,
1299
+ rendererRegistry: this.rendererRegistry,
1300
+ isViewportVisible,
1301
+ linesSave: allLines,
1302
+ dragService: this.dragService
1303
+ });
1304
+ });
1305
+ const { activateLines = [], normalLines = [] } = (0, import_lodash4.groupBy)(
1306
+ allLines,
1307
+ (line) => line.props.activated ? "activateLines" : "normalLines"
1308
+ );
1309
+ const resultLines = [...normalLines, ...activateLines];
1310
+ const arrowRenderer = this.rendererRegistry.tryToGetRendererComponent(
1311
+ "marker-arrow" /* MARKER_ARROW */
1312
+ );
1313
+ const activateArrowRenderer = this.rendererRegistry.tryToGetRendererComponent(
1314
+ "marker-active-arrow" /* MARKER_ACTIVATE_ARROW */
1315
+ );
1316
+ const arrow = arrowRenderer ? import_react8.default.createElement(arrowRenderer.renderer) : null;
1317
+ const activateArrow = activateArrowRenderer ? import_react8.default.createElement(activateArrowRenderer.renderer) : null;
1318
+ return /* @__PURE__ */ import_react8.default.createElement(
1319
+ "svg",
1320
+ {
1321
+ className: "flow-lines-container",
1322
+ width: "1000",
1323
+ height: "1000",
1324
+ overflow: "visible",
1325
+ viewBox: this.viewBox,
1326
+ xmlns: "http://www.w3.org/2000/svg"
1327
+ },
1328
+ /* @__PURE__ */ import_react8.default.createElement("defs", null, arrowRenderer ? arrow : /* @__PURE__ */ import_react8.default.createElement(MarkerArrow_default, null), activateArrow ? activateArrow : /* @__PURE__ */ import_react8.default.createElement(MarkerActivatedArrow_default, null)),
1329
+ resultLines
1330
+ );
1331
+ }
1332
+ };
1333
+ __decorateClass([
1334
+ (0, import_inversify5.inject)(import_document9.FlowDocument)
1335
+ ], FlowLinesLayer.prototype, "document", 2);
1336
+ __decorateClass([
1337
+ (0, import_inversify5.inject)(import_document9.FlowDragService)
1338
+ ], FlowLinesLayer.prototype, "dragService", 2);
1339
+ __decorateClass([
1340
+ (0, import_inversify5.inject)(FlowRendererRegistry)
1341
+ ], FlowLinesLayer.prototype, "rendererRegistry", 2);
1342
+ __decorateClass([
1343
+ (0, import_core8.observeEntity)(import_document9.FlowDocumentTransformerEntity)
1344
+ ], FlowLinesLayer.prototype, "documentTransformer", 2);
1345
+ __decorateClass([
1346
+ (0, import_core8.observeEntity)(import_document9.FlowRendererStateEntity)
1347
+ ], FlowLinesLayer.prototype, "flowRenderState", 2);
1348
+ __decorateClass([
1349
+ (0, import_core8.observeEntityDatas)(import_document9.FlowNodeEntity, import_document9.FlowNodeTransitionData)
1350
+ ], FlowLinesLayer.prototype, "_transitions", 2);
1351
+ FlowLinesLayer = __decorateClass([
1352
+ (0, import_inversify5.injectable)()
1353
+ ], FlowLinesLayer);
1354
+
1355
+ // src/layers/flow-labels-layer.tsx
1356
+ var import_react14 = __toESM(require("react"));
1357
+ var import_lodash5 = require("lodash");
1358
+ var import_inversify6 = require("inversify");
1359
+ var import_utils16 = require("@flowgram.ai/utils");
1360
+ var import_document15 = require("@flowgram.ai/document");
1361
+ var import_core11 = require("@flowgram.ai/core");
1362
+
1363
+ // src/components/LabelsRenderer.tsx
1364
+ var import_react13 = __toESM(require("react"));
1365
+ var import_utils15 = require("@flowgram.ai/utils");
1366
+ var import_document14 = require("@flowgram.ai/document");
1367
+
1368
+ // src/components/CollapseAdder.tsx
1369
+ var import_react11 = __toESM(require("react"));
1370
+ var import_document12 = require("@flowgram.ai/document");
1371
+
1372
+ // src/components/Collapse.tsx
1373
+ var import_react9 = __toESM(require("react"));
1374
+ var import_document10 = require("@flowgram.ai/document");
1375
+ function Collapse(props) {
1376
+ const {
1377
+ data,
1378
+ rendererRegistry,
1379
+ forceVisible,
1380
+ hoverHeight = getTransitionLabelHoverHeight(data),
1381
+ hoverWidth = getTransitionLabelHoverWidth(data),
1382
+ wrapperStyle,
1383
+ ...restProps
1384
+ } = props;
1385
+ const { activateNode } = restProps;
1386
+ const [hoverActivated, setHoverActivated] = (0, import_react9.useState)(false);
1387
+ const activateData = activateNode?.getData(import_document10.FlowNodeRenderData);
1388
+ const handleMouseEnter = (0, import_react9.useCallback)(() => {
1389
+ setHoverActivated(true);
1390
+ activateData?.toggleMouseEnter();
1391
+ }, []);
1392
+ const handleMouseLeave = (0, import_react9.useCallback)(() => {
1393
+ setHoverActivated(false);
1394
+ activateData?.toggleMouseLeave();
1395
+ }, []);
1396
+ const collapseOpener = rendererRegistry.getRendererComponent("collapse" /* COLLAPSE */);
1397
+ const node = data.entity;
1398
+ const child = import_react9.default.createElement(
1399
+ collapseOpener.renderer,
1400
+ {
1401
+ node,
1402
+ collapseNode: node,
1403
+ ...restProps,
1404
+ hoverActivated
1405
+ }
1406
+ );
1407
+ const isChildVisible = data.collapsed || activateData?.hovered || hoverActivated || forceVisible;
1408
+ return /* @__PURE__ */ import_react9.default.createElement(
1409
+ "div",
1410
+ {
1411
+ className: "flow-canvas-collapse",
1412
+ onMouseEnter: handleMouseEnter,
1413
+ onMouseLeave: handleMouseLeave,
1414
+ style: {
1415
+ width: hoverWidth,
1416
+ height: hoverHeight,
1417
+ display: "flex",
1418
+ justifyContent: "center",
1419
+ alignItems: "center",
1420
+ ...wrapperStyle
1421
+ }
1422
+ },
1423
+ isChildVisible ? child : null
1424
+ );
1425
+ }
1426
+
1427
+ // src/components/Adder.tsx
1428
+ var import_react10 = __toESM(require("react"));
1429
+ var import_document11 = require("@flowgram.ai/document");
1430
+ var import_core9 = require("@flowgram.ai/core");
1431
+ var getFlowRenderKey = (node, { dragService }) => {
1432
+ if (dragService && dragService.dragging && dragService.isDroppableNode(node)) {
1433
+ if (dragService.dropNodeId === node.id) {
1434
+ return "drag-highlight-adder" /* DRAG_HIGHLIGHT_ADDER */;
1435
+ }
1436
+ return "draggable-adder" /* DRAGGABLE_ADDER */;
1437
+ }
1438
+ return "adder" /* ADDER */;
1439
+ };
1440
+ function Adder(props) {
1441
+ const {
1442
+ data,
1443
+ rendererRegistry,
1444
+ hoverHeight = getTransitionLabelHoverHeight(data),
1445
+ hoverWidth = getTransitionLabelHoverWidth(data),
1446
+ ...restProps
1447
+ } = props;
1448
+ const [hoverActivated, setHoverActivated] = (0, import_react10.useState)(false);
1449
+ const handleMouseEnter = (0, import_react10.useCallback)(() => setHoverActivated(true), []);
1450
+ const handleMouseLeave = (0, import_react10.useCallback)(() => setHoverActivated(false), []);
1451
+ const node = data.entity;
1452
+ const dragService = (0, import_core9.useService)(import_document11.FlowDragService);
1453
+ const flowRenderKey = getFlowRenderKey(node, { dragService });
1454
+ const adder = rendererRegistry.getRendererComponent(flowRenderKey);
1455
+ const from = node;
1456
+ const to = data.entity.document.renderTree.getOriginInfo(node).next;
1457
+ const renderTo = node.next;
1458
+ const child = import_react10.default.createElement(
1459
+ adder.renderer,
1460
+ {
1461
+ node,
1462
+ from,
1463
+ to,
1464
+ renderTo,
1465
+ hoverActivated,
1466
+ setHoverActivated,
1467
+ hoverWidth,
1468
+ hoverHeight,
1469
+ ...restProps
1470
+ }
1471
+ );
1472
+ return (
1473
+ // eslint-disable-next-line react/jsx-filename-extension
1474
+ /* @__PURE__ */ import_react10.default.createElement(
1475
+ "div",
1476
+ {
1477
+ className: "flow-canvas-adder",
1478
+ "data-testid": "sdk.flowcanvas.line.adder",
1479
+ "data-from": from.id,
1480
+ "data-to": to?.id ?? "",
1481
+ onMouseEnter: handleMouseEnter,
1482
+ onMouseLeave: handleMouseLeave,
1483
+ style: {
1484
+ width: hoverWidth,
1485
+ height: hoverHeight,
1486
+ display: "flex",
1487
+ justifyContent: "center",
1488
+ alignItems: "center"
1489
+ }
1490
+ },
1491
+ child
1492
+ )
1493
+ );
1494
+ }
1495
+
1496
+ // src/components/CollapseAdder.tsx
1497
+ function CollapseAdder(props) {
1498
+ const { data, rendererRegistry, ...restProps } = props;
1499
+ const { activateNode } = restProps;
1500
+ const [hoverActivated, setHoverActivated] = (0, import_react11.useState)(false);
1501
+ const activateData = activateNode?.getData(import_document12.FlowNodeRenderData);
1502
+ const handleMouseEnter = (0, import_react11.useCallback)(() => {
1503
+ setHoverActivated(true);
1504
+ }, []);
1505
+ const handleMouseLeave = (0, import_react11.useCallback)(() => {
1506
+ setHoverActivated(false);
1507
+ }, []);
1508
+ const isVertical = activateNode?.isVertical;
1509
+ const activated = activateData?.hovered || hoverActivated;
1510
+ if (isVertical) {
1511
+ return /* @__PURE__ */ import_react11.default.createElement(
1512
+ "div",
1513
+ {
1514
+ className: "flow-canvas-collapse-adder",
1515
+ onMouseEnter: handleMouseEnter,
1516
+ onMouseLeave: handleMouseLeave
1517
+ },
1518
+ (activated || data.collapsed) && /* @__PURE__ */ import_react11.default.createElement(
1519
+ Collapse,
1520
+ {
1521
+ forceVisible: true,
1522
+ ...props,
1523
+ wrapperStyle: {
1524
+ alignItems: "flex-end"
1525
+ },
1526
+ hoverHeight: 20
1527
+ }
1528
+ ),
1529
+ !data.collapsed && /* @__PURE__ */ import_react11.default.createElement(Adder, { ...props, hoverHeight: activated ? 20 : 40, hoverActivated: activated })
1530
+ );
1531
+ }
1532
+ return /* @__PURE__ */ import_react11.default.createElement(
1533
+ "div",
1534
+ {
1535
+ className: "flow-canvas-collapse-adder",
1536
+ onMouseEnter: handleMouseEnter,
1537
+ onMouseLeave: handleMouseLeave,
1538
+ style: {
1539
+ display: data.collapsed ? "block" : "flex"
1540
+ }
1541
+ },
1542
+ (activated || data.collapsed) && /* @__PURE__ */ import_react11.default.createElement(
1543
+ Collapse,
1544
+ {
1545
+ forceVisible: true,
1546
+ ...props,
1547
+ wrapperStyle: {
1548
+ justifyContent: "flex-end"
1549
+ },
1550
+ hoverWidth: 20
1551
+ }
1552
+ ),
1553
+ !data.collapsed && /* @__PURE__ */ import_react11.default.createElement(Adder, { ...props, hoverWidth: activated ? 20 : 40, hoverActivated: activated })
1554
+ );
1555
+ }
1556
+
1557
+ // src/components/BranchDraggableRenderer.tsx
1558
+ var import_react12 = __toESM(require("react"));
1559
+ var import_document13 = require("@flowgram.ai/document");
1560
+ var import_core10 = require("@flowgram.ai/core");
1561
+ var getFlowRenderKey2 = (node, { dragService, side }) => {
1562
+ if (dragService.isDragBranch && side && dragService.labelSide === side && dragService.isDroppableBranch(node, side)) {
1563
+ if (dragService.dropNodeId === node.id) {
1564
+ return "drag-branch-highlight-adder" /* DRAG_BRANCH_HIGHLIGHT_ADDER */;
1565
+ }
1566
+ return "draggable-adder" /* DRAGGABLE_ADDER */;
1567
+ }
1568
+ return "";
1569
+ };
1570
+ function BranchDraggableRenderer(props) {
1571
+ const { data, rendererRegistry, side, ...restProps } = props;
1572
+ const node = data.entity;
1573
+ const dragService = (0, import_core10.useService)(import_document13.FlowDragService);
1574
+ const flowRenderKey = getFlowRenderKey2(node, { side, dragService });
1575
+ if (!flowRenderKey) {
1576
+ return null;
1577
+ }
1578
+ const adder = rendererRegistry.getRendererComponent(flowRenderKey);
1579
+ const from = node;
1580
+ const to = data.entity.document.renderTree.getOriginInfo(node).next;
1581
+ const renderTo = node.next;
1582
+ const child = import_react12.default.createElement(
1583
+ adder.renderer,
1584
+ {
1585
+ node,
1586
+ from,
1587
+ to,
1588
+ renderTo,
1589
+ ...restProps
1590
+ }
1591
+ );
1592
+ return /* @__PURE__ */ import_react12.default.createElement("div", { className: "flow-canvas-branch-draggable-adder" }, child);
1593
+ }
1594
+
1595
+ // src/components/LabelsRenderer.tsx
1596
+ var TEXT_LABEL_STYLE = {
1597
+ fontSize: 12,
1598
+ color: "#8F959E",
1599
+ textAlign: "center",
1600
+ whiteSpace: "nowrap",
1601
+ backgroundColor: "var(--g-editor-background)",
1602
+ lineHeight: "20px"
1603
+ };
1604
+ var LABEL_MAX_WIDTH = 150;
1605
+ var LABEL_MAX_HEIGHT = 60;
1606
+ function getLabelBounds(offset) {
1607
+ return new import_utils15.Rectangle(
1608
+ offset.x - LABEL_MAX_WIDTH / 2,
1609
+ offset.y - LABEL_MAX_HEIGHT / 2,
1610
+ LABEL_MAX_WIDTH,
1611
+ LABEL_MAX_HEIGHT
1612
+ );
1613
+ }
1614
+ function createLabels(labelProps) {
1615
+ const { data, rendererRegistry, labelsSave, getLabelColor } = labelProps;
1616
+ const { labels, renderData } = data || {};
1617
+ const { activated } = renderData || {};
1618
+ const renderLabel = (label, index) => {
1619
+ const { offset, renderKey, props, rotate, type } = label || {};
1620
+ const offsetX = offset.x;
1621
+ const offsetY = offset.y;
1622
+ let child = null;
1623
+ switch (type) {
1624
+ case import_document14.FlowTransitionLabelEnum.BRANCH_DRAGGING_LABEL:
1625
+ child = /* @__PURE__ */ import_react13.default.createElement(BranchDraggableRenderer, { rendererRegistry, data, ...props });
1626
+ break;
1627
+ case import_document14.FlowTransitionLabelEnum.ADDER_LABEL:
1628
+ child = /* @__PURE__ */ import_react13.default.createElement(Adder, { rendererRegistry, data, ...props });
1629
+ break;
1630
+ case import_document14.FlowTransitionLabelEnum.COLLAPSE_LABEL:
1631
+ child = /* @__PURE__ */ import_react13.default.createElement(Collapse, { rendererRegistry, data, ...props });
1632
+ break;
1633
+ case import_document14.FlowTransitionLabelEnum.COLLAPSE_ADDER_LABEL:
1634
+ child = /* @__PURE__ */ import_react13.default.createElement(CollapseAdder, { rendererRegistry, data, ...props });
1635
+ break;
1636
+ case import_document14.FlowTransitionLabelEnum.TEXT_LABEL:
1637
+ if (!renderKey) {
1638
+ return null;
1639
+ }
1640
+ const text = rendererRegistry.getText(renderKey) || renderKey;
1641
+ child = /* @__PURE__ */ import_react13.default.createElement(
1642
+ "div",
1643
+ {
1644
+ style: {
1645
+ ...TEXT_LABEL_STYLE,
1646
+ ...props?.style,
1647
+ color: getLabelColor(activated),
1648
+ transform: rotate ? `rotate(${rotate})` : void 0
1649
+ }
1650
+ },
1651
+ text
1652
+ );
1653
+ break;
1654
+ case import_document14.FlowTransitionLabelEnum.CUSTOM_LABEL:
1655
+ if (!renderKey) {
1656
+ return null;
1657
+ }
1658
+ try {
1659
+ const renderer = rendererRegistry.getRendererComponent(renderKey);
1660
+ child = import_react13.default.createElement(
1661
+ renderer.renderer,
1662
+ {
1663
+ node: data.entity,
1664
+ ...props
1665
+ }
1666
+ );
1667
+ } catch (err) {
1668
+ console.error(err);
1669
+ child = renderKey;
1670
+ }
1671
+ break;
1672
+ default:
1673
+ break;
1674
+ }
1675
+ return /* @__PURE__ */ import_react13.default.createElement(
1676
+ "div",
1677
+ {
1678
+ key: `${data.entity.id}${index}`,
1679
+ style: {
1680
+ position: "absolute",
1681
+ left: offsetX,
1682
+ top: offsetY,
1683
+ transform: "translate(-50%, -50%)"
1684
+ }
1685
+ },
1686
+ child
1687
+ );
1688
+ };
1689
+ labels.forEach((label, index) => {
1690
+ if (labelProps.isViewportVisible(getLabelBounds(label.offset))) {
1691
+ labelsSave.push(renderLabel(label, index));
1692
+ }
1693
+ });
1694
+ }
1695
+
1696
+ // src/layers/flow-labels-layer.tsx
1697
+ var FlowLabelsLayer = class extends import_core11.Layer {
1698
+ constructor() {
1699
+ super(...arguments);
1700
+ this.node = import_utils16.domUtils.createDivWithClass("gedit-flow-labels-layer");
1701
+ /**
1702
+ * 可视区域变化
1703
+ */
1704
+ this.onViewportChange = (0, import_lodash5.throttle)(() => {
1705
+ this.render();
1706
+ }, 100);
1707
+ }
1708
+ get transitions() {
1709
+ return this.document.getRenderDatas(import_document15.FlowNodeTransitionData);
1710
+ }
1711
+ /**
1712
+ * 监听缩放,目前采用整体缩放
1713
+ * @param scale
1714
+ */
1715
+ onZoom(scale) {
1716
+ this.node.style.transform = `scale(${scale})`;
1717
+ }
1718
+ onReady() {
1719
+ this.node.style.zIndex = "9";
1720
+ }
1721
+ /**
1722
+ * 监听readonly和 disabled 状态 并刷新layer, 并刷新
1723
+ */
1724
+ onReadonlyOrDisabledChange() {
1725
+ this.render();
1726
+ }
1727
+ render() {
1728
+ const labels = [];
1729
+ if (this.documentTransformer?.loading) return /* @__PURE__ */ import_react14.default.createElement(import_react14.default.Fragment, null);
1730
+ this.documentTransformer?.refresh?.();
1731
+ const { baseActivatedColor, baseColor } = useBaseColor();
1732
+ const isViewportVisible = this.config.isViewportVisible.bind(this.config);
1733
+ this.transitions.forEach((transition) => {
1734
+ createLabels({
1735
+ data: transition,
1736
+ rendererRegistry: this.rendererRegistry,
1737
+ isViewportVisible,
1738
+ labelsSave: labels,
1739
+ getLabelColor: (activated) => activated ? baseActivatedColor : baseColor
1740
+ });
1741
+ });
1742
+ return /* @__PURE__ */ import_react14.default.createElement(import_react14.default.Fragment, null, labels);
1743
+ }
1744
+ };
1745
+ __decorateClass([
1746
+ (0, import_inversify6.inject)(import_document15.FlowDocument)
1747
+ ], FlowLabelsLayer.prototype, "document", 2);
1748
+ __decorateClass([
1749
+ (0, import_inversify6.inject)(FlowRendererRegistry)
1750
+ ], FlowLabelsLayer.prototype, "rendererRegistry", 2);
1751
+ __decorateClass([
1752
+ (0, import_core11.observeEntity)(import_document15.FlowDocumentTransformerEntity)
1753
+ ], FlowLabelsLayer.prototype, "documentTransformer", 2);
1754
+ __decorateClass([
1755
+ (0, import_core11.observeEntity)(import_document15.FlowRendererStateEntity)
1756
+ ], FlowLabelsLayer.prototype, "flowRenderState", 2);
1757
+ __decorateClass([
1758
+ (0, import_core11.observeEntityDatas)(import_document15.FlowNodeEntity, import_document15.FlowNodeTransitionData)
1759
+ ], FlowLabelsLayer.prototype, "_transitions", 2);
1760
+ FlowLabelsLayer = __decorateClass([
1761
+ (0, import_inversify6.injectable)()
1762
+ ], FlowLabelsLayer);
1763
+
1764
+ // src/layers/flow-debug-layer.tsx
1765
+ var import_inversify7 = require("inversify");
1766
+ var import_utils18 = require("@flowgram.ai/utils");
1767
+ var import_document16 = require("@flowgram.ai/document");
1768
+ var import_core12 = require("@flowgram.ai/core");
1769
+
1770
+ // src/utils/scroll-limit.ts
1771
+ var import_utils17 = require("@flowgram.ai/utils");
1772
+ var SCROLL_LIMIT_PADDING = -120;
1773
+ function getScrollViewport(scrollData, config) {
1774
+ const scale = config.finalScale;
1775
+ return new import_utils17.Rectangle(
1776
+ scrollData.scrollX / scale,
1777
+ scrollData.scrollY / scale,
1778
+ config.config.width / scale,
1779
+ config.config.height / scale
1780
+ ).pad(SCROLL_LIMIT_PADDING / scale, SCROLL_LIMIT_PADDING / scale);
1781
+ }
1782
+ function scrollLimit(scroll, boundsList, config, initScroll) {
1783
+ scroll = { ...scroll };
1784
+ const configData = config.config;
1785
+ const oldScroll = { scrollX: configData.scrollX, scrollY: configData.scrollY };
1786
+ if (boundsList.length === 0 || configData.width === 0 || configData.height === 0) return scroll;
1787
+ const viewport = getScrollViewport(scroll, config);
1788
+ const isVisible = boundsList.find((bounds) => import_utils17.Rectangle.isViewportVisible(bounds, viewport));
1789
+ if (!isVisible) {
1790
+ const oldViewport = getScrollViewport(oldScroll, config);
1791
+ const isOldVisible = boundsList.find(
1792
+ (bounds) => import_utils17.Rectangle.isViewportVisible(bounds, oldViewport)
1793
+ );
1794
+ if (!isOldVisible) {
1795
+ return initScroll();
1796
+ }
1797
+ return oldScroll;
1798
+ }
1799
+ return scroll;
1800
+ }
1801
+
1802
+ // src/utils/scroll-bar-events.tsx
1803
+ var ScrollBarEvents = Symbol("ScrollBarEvents");
1804
+
1805
+ // src/layers/flow-debug-layer.tsx
1806
+ var rgbTimes = 0;
1807
+ function randomColor(percent) {
1808
+ const max = Math.min(percent / 10 * 255, 255);
1809
+ rgbTimes += 1;
1810
+ const rgb = rgbTimes % 3;
1811
+ const random = () => Math.floor(Math.random() * max);
1812
+ return `rgb(${rgb === 0 ? random() : 0}, ${rgb === 1 ? random() : 0}, ${rgb === 2 ? random() : 0})`;
1813
+ }
1814
+ var FlowDebugLayer = class extends import_core12.Layer {
1815
+ constructor() {
1816
+ super(...arguments);
1817
+ this.node = document.createElement("div");
1818
+ this.viewport = import_utils18.domUtils.createDivWithClass("gedit-flow-debug-bounds");
1819
+ this.boundsNodes = import_utils18.domUtils.createDivWithClass("gedit-flow-debug-bounds");
1820
+ this.pointsNodes = import_utils18.domUtils.createDivWithClass("gedit-flow-debug-points");
1821
+ this.versionNodes = import_utils18.domUtils.createDivWithClass("gedit-flow-debug-versions gedit-hidden");
1822
+ /**
1823
+ * ?debug=xxxx, 则返回 xxxx
1824
+ */
1825
+ this.filterKey = window.location.search.match(/debug=([^&]+)/)?.[1] || "";
1826
+ this.originLine = document.createElement("div");
1827
+ this.domCache = /* @__PURE__ */ new WeakMap();
1828
+ }
1829
+ get transforms() {
1830
+ return this.document.getRenderDatas(import_document16.FlowNodeTransformData);
1831
+ }
1832
+ onReady() {
1833
+ this.node.style.zIndex = "20";
1834
+ import_utils18.domUtils.setStyle(this.originLine, {
1835
+ position: "absolute",
1836
+ width: 1,
1837
+ height: "100%",
1838
+ left: this.pipelineNode.style.left,
1839
+ top: 0,
1840
+ borderLeft: "1px dashed rgba(255, 0, 0, 0.5)"
1841
+ });
1842
+ this.pipelineNode.parentElement.appendChild(this.originLine);
1843
+ this.node.appendChild(this.viewport);
1844
+ this.node.appendChild(this.versionNodes);
1845
+ this.node.appendChild(this.boundsNodes);
1846
+ this.node.appendChild(this.pointsNodes);
1847
+ this.renderScrollViewportBounds();
1848
+ }
1849
+ onScroll() {
1850
+ this.originLine.style.left = this.pipelineNode.style.left;
1851
+ this.renderScrollViewportBounds();
1852
+ }
1853
+ onResize() {
1854
+ this.renderScrollViewportBounds();
1855
+ }
1856
+ onZoom(scale) {
1857
+ this.node.style.transform = `scale(${scale})`;
1858
+ this.renderScrollViewportBounds();
1859
+ }
1860
+ createBounds(transform, color, depth) {
1861
+ if (this.filterKey && transform.key.indexOf(this.filterKey) === -1) return;
1862
+ let cache = this.domCache.get(transform);
1863
+ const { bounds, inputPoint, outputPoint } = transform;
1864
+ if (!cache) {
1865
+ const bbox = import_utils18.domUtils.createDivWithClass("");
1866
+ const input = import_utils18.domUtils.createDivWithClass("");
1867
+ const output = import_utils18.domUtils.createDivWithClass("");
1868
+ const version = import_utils18.domUtils.createDivWithClass("");
1869
+ bbox.title = transform.key;
1870
+ input.title = transform.key + "(input)";
1871
+ output.title = transform.key + "(output)";
1872
+ version.title = transform.key;
1873
+ this.boundsNodes.appendChild(bbox);
1874
+ this.pointsNodes.appendChild(input);
1875
+ this.pointsNodes.appendChild(output);
1876
+ this.versionNodes.appendChild(version);
1877
+ transform.onDispose(() => {
1878
+ bbox.remove();
1879
+ input.remove();
1880
+ output.remove();
1881
+ });
1882
+ cache = { bbox, input, output, version, color };
1883
+ this.domCache.set(transform, cache);
1884
+ }
1885
+ import_utils18.domUtils.setStyle(cache.version, {
1886
+ position: "absolute",
1887
+ marginLeft: "-9px",
1888
+ marginTop: "-10px",
1889
+ borderRadius: 12,
1890
+ background: "#f54a45",
1891
+ padding: 4,
1892
+ color: "navajowhite",
1893
+ display: transform.renderState.hidden ? "none" : "block",
1894
+ zIndex: depth + 1e3,
1895
+ left: bounds.center.x,
1896
+ top: bounds.center.y
1897
+ });
1898
+ cache.version.innerHTML = transform.version.toString();
1899
+ import_utils18.domUtils.setStyle(cache.input, {
1900
+ position: "absolute",
1901
+ width: 10,
1902
+ height: 10,
1903
+ marginLeft: -5,
1904
+ marginTop: -5,
1905
+ borderRadius: 5,
1906
+ left: inputPoint.x,
1907
+ top: inputPoint.y,
1908
+ opacity: 0.4,
1909
+ zIndex: depth,
1910
+ backgroundColor: cache.color,
1911
+ whiteSpace: "nowrap",
1912
+ overflow: "visible"
1913
+ });
1914
+ cache.input.innerHTML = `${inputPoint.x},${inputPoint.y}`;
1915
+ import_utils18.domUtils.setStyle(cache.output, {
1916
+ position: "absolute",
1917
+ width: 10,
1918
+ height: 10,
1919
+ marginLeft: -5,
1920
+ marginTop: -5,
1921
+ borderRadius: 5,
1922
+ left: outputPoint.x,
1923
+ top: outputPoint.y,
1924
+ opacity: 0.4,
1925
+ zIndex: depth,
1926
+ backgroundColor: cache.color,
1927
+ whiteSpace: "nowrap",
1928
+ overflow: "visible"
1929
+ });
1930
+ cache.output.innerHTML = `${outputPoint.x},${outputPoint.y}`;
1931
+ import_utils18.domUtils.setStyle(cache.bbox, {
1932
+ position: "absolute",
1933
+ width: bounds.width,
1934
+ height: bounds.height,
1935
+ left: bounds.left,
1936
+ top: bounds.top,
1937
+ opacity: `${depth / 30}`,
1938
+ backgroundColor: cache.color
1939
+ });
1940
+ }
1941
+ /**
1942
+ * 显示 viewport 可滚动区域
1943
+ */
1944
+ renderScrollViewportBounds() {
1945
+ const viewportBounds = getScrollViewport(
1946
+ {
1947
+ scrollX: this.config.config.scrollX,
1948
+ scrollY: this.config.config.scrollY
1949
+ },
1950
+ this.config
1951
+ );
1952
+ import_utils18.domUtils.setStyle(this.viewport, {
1953
+ position: "absolute",
1954
+ width: viewportBounds.width - 2,
1955
+ height: viewportBounds.height - 2,
1956
+ left: viewportBounds.left + 1,
1957
+ top: viewportBounds.top + 1,
1958
+ border: "1px solid rgba(200, 200, 255, 0.5)"
1959
+ });
1960
+ }
1961
+ autorun() {
1962
+ if (this.documentTransformer.loading) return;
1963
+ this.documentTransformer.refresh();
1964
+ let color = randomColor(0);
1965
+ this.document.traverse((entity, depth) => {
1966
+ const transform = entity.getData(import_document16.FlowNodeTransformData);
1967
+ color = randomColor(depth);
1968
+ this.createBounds(transform, color, depth);
1969
+ });
1970
+ this.renderScrollViewportBounds();
1971
+ }
1972
+ };
1973
+ __decorateClass([
1974
+ (0, import_inversify7.inject)(import_document16.FlowDocument)
1975
+ ], FlowDebugLayer.prototype, "document", 2);
1976
+ __decorateClass([
1977
+ (0, import_core12.observeEntity)(import_document16.FlowDocumentTransformerEntity)
1978
+ ], FlowDebugLayer.prototype, "documentTransformer", 2);
1979
+ __decorateClass([
1980
+ (0, import_core12.observeEntityDatas)(import_document16.FlowNodeEntity, import_document16.FlowNodeTransformData)
1981
+ ], FlowDebugLayer.prototype, "_transforms", 2);
1982
+ FlowDebugLayer = __decorateClass([
1983
+ (0, import_inversify7.injectable)()
1984
+ ], FlowDebugLayer);
1985
+
1986
+ // src/layers/flow-scroll-bar-layer.tsx
1987
+ var import_inversify8 = require("inversify");
1988
+ var import_document17 = require("@flowgram.ai/document");
1989
+ var import_core13 = require("@flowgram.ai/core");
1990
+ var import_utils20 = require("@flowgram.ai/utils");
1991
+ var BORDER_WIDTH = 2;
1992
+ var BLOCK_OFFSET = 11;
1993
+ var SCROLL_BAR_WIDTH = "7px";
1994
+ var FlowScrollBarLayer = class extends import_core13.Layer {
1995
+ constructor() {
1996
+ super(...arguments);
1997
+ // @observeEntity(FlowDocumentTransformerEntity) readonly documentTransformer: FlowDocumentTransformerEntity
1998
+ // 右滚动区域
1999
+ this.rightScrollBar = import_utils20.domUtils.createDivWithClass("gedit-playground-scroll-right");
2000
+ // 右滚动条
2001
+ this.rightScrollBarBlock = import_utils20.domUtils.createDivWithClass("gedit-playground-scroll-right-block");
2002
+ // 底滚动区域
2003
+ this.bottomScrollBar = import_utils20.domUtils.createDivWithClass("gedit-playground-scroll-bottom");
2004
+ // 底滚动条
2005
+ this.bottomScrollBarBlock = import_utils20.domUtils.createDivWithClass(
2006
+ "gedit-playground-scroll-bottom-block"
2007
+ );
2008
+ // 总滚动距离
2009
+ this.sum = 0;
2010
+ // 初始 x 轴滚动距离
2011
+ this.initialScrollX = 0;
2012
+ // 初始 y 轴滚动距离
2013
+ this.initialScrollY = 0;
2014
+ this.bottomGrabDragger = new import_core13.PlaygroundDrag({
2015
+ onDragStart: (e) => {
2016
+ this.config.updateCursor("grabbing");
2017
+ this.sum = 0;
2018
+ this.initialScrollX = this.config.getViewport().x;
2019
+ this.onBoardingToast();
2020
+ },
2021
+ onDrag: (e) => {
2022
+ this.sum += e.movingDelta.x;
2023
+ this.playgroundConfigEntity.scroll(
2024
+ {
2025
+ scrollX: (this.initialScrollX + this.sum * this.viewportFullWidth / (this.clientViewportWidth - this.scrollBottomWidth)) * this.scale
2026
+ },
2027
+ false
2028
+ );
2029
+ },
2030
+ onDragEnd: (e) => {
2031
+ this.config.updateCursor("default");
2032
+ }
2033
+ });
2034
+ this.rightGrabDragger = new import_core13.PlaygroundDrag({
2035
+ onDragStart: (e) => {
2036
+ this.config.updateCursor("grabbing");
2037
+ this.sum = 0;
2038
+ this.initialScrollY = this.config.getViewport().y;
2039
+ this.onBoardingToast();
2040
+ },
2041
+ onDrag: (e) => {
2042
+ this.sum += e.movingDelta.y;
2043
+ this.playgroundConfigEntity.scroll(
2044
+ {
2045
+ scrollY: (this.initialScrollY + this.sum * this.viewportFullHeight / (this.clientViewportHeight - this.scrollRightHeight)) * this.scale
2046
+ },
2047
+ false
2048
+ );
2049
+ },
2050
+ onDragEnd: (e) => {
2051
+ this.config.updateCursor("default");
2052
+ }
2053
+ });
2054
+ }
2055
+ // 浏览器视图宽度
2056
+ get clientViewportWidth() {
2057
+ return this.viewportWidth * this.scale - BLOCK_OFFSET;
2058
+ }
2059
+ // 浏览器视图高度
2060
+ get clientViewportHeight() {
2061
+ return this.viewportHeight * this.scale - BLOCK_OFFSET;
2062
+ }
2063
+ // 视图的完整宽度
2064
+ get viewportFullWidth() {
2065
+ return this.mostLeft - this.mostRight;
2066
+ }
2067
+ // 视图的完整高度
2068
+ get viewportFullHeight() {
2069
+ return this.mostTop - this.mostBottom;
2070
+ }
2071
+ // 视图的可移动宽度
2072
+ get viewportMoveWidth() {
2073
+ return this.mostLeft - this.mostRight + this.width;
2074
+ }
2075
+ // 视图的可移动高度
2076
+ get viewportMoveHeight() {
2077
+ return this.mostTop - this.mostBottom + this.height;
2078
+ }
2079
+ getToLeft(scrollX) {
2080
+ return (scrollX - this.mostRight) / this.viewportMoveWidth * this.clientViewportWidth;
2081
+ }
2082
+ getToTop(scrollY) {
2083
+ return (scrollY - this.mostBottom) / this.viewportMoveHeight * this.clientViewportHeight;
2084
+ }
2085
+ clickRightScrollBar(e) {
2086
+ e.preventDefault();
2087
+ e.stopPropagation();
2088
+ const ratio = 1 - (e?.y || 0) / this.clientViewportHeight;
2089
+ const scrollY = (this.mostTop - this.viewportFullHeight * ratio) * this.scale;
2090
+ this.playgroundConfigEntity.scroll(
2091
+ {
2092
+ scrollY
2093
+ },
2094
+ false
2095
+ );
2096
+ }
2097
+ clickBottomScrollBar(e) {
2098
+ e.preventDefault();
2099
+ e.stopPropagation();
2100
+ const ratio = 1 - (e?.x || 0) / this.clientViewportWidth;
2101
+ const scrollX = (this.mostLeft - this.viewportFullWidth * ratio) * this.scale;
2102
+ this.playgroundConfigEntity.scroll(
2103
+ {
2104
+ scrollX
2105
+ },
2106
+ false
2107
+ );
2108
+ }
2109
+ onBoardingToast() {
2110
+ this.events?.dragStart();
2111
+ }
2112
+ changeScrollBarVisibility(scrollBar, status) {
2113
+ const addClassName = status === "show" /* Show */ ? "gedit-playground-scroll-show" : "gedit-playground-scroll-hidden";
2114
+ const delClassName = status === "show" /* Show */ ? "gedit-playground-scroll-hidden" : "gedit-playground-scroll-show";
2115
+ import_utils20.domUtils.addClass(scrollBar, addClassName);
2116
+ import_utils20.domUtils.delClass(scrollBar, delClassName);
2117
+ }
2118
+ onReady() {
2119
+ if (!this.options.getBounds) {
2120
+ this.options = {
2121
+ getBounds: () => {
2122
+ const document2 = this.flowDocument;
2123
+ if (!document2) return import_utils20.Rectangle.EMPTY;
2124
+ document2.transformer.refresh();
2125
+ return document2.root.getData(import_document17.FlowNodeTransformData).bounds;
2126
+ },
2127
+ showScrollBars: "whenScrolling"
2128
+ };
2129
+ }
2130
+ this.pipelineNode.parentNode.appendChild(this.rightScrollBar);
2131
+ this.pipelineNode.parentNode.appendChild(this.rightScrollBarBlock);
2132
+ this.pipelineNode.parentNode.appendChild(this.bottomScrollBar);
2133
+ this.pipelineNode.parentNode.appendChild(this.bottomScrollBarBlock);
2134
+ this.rightScrollBar.onclick = this.clickRightScrollBar.bind(this);
2135
+ this.bottomScrollBar.onclick = this.clickBottomScrollBar.bind(this);
2136
+ if (this.options.showScrollBars === "whenScrolling") {
2137
+ this.rightScrollBar.addEventListener("mouseenter", (e) => {
2138
+ this.changeScrollBarVisibility(this.rightScrollBarBlock, "show" /* Show */);
2139
+ });
2140
+ this.rightScrollBar.addEventListener("mouseleave", (e) => {
2141
+ this.changeScrollBarVisibility(this.rightScrollBarBlock, "hidden" /* Hidden */);
2142
+ });
2143
+ this.bottomScrollBar.addEventListener("mouseenter", (e) => {
2144
+ this.changeScrollBarVisibility(this.bottomScrollBarBlock, "show" /* Show */);
2145
+ });
2146
+ this.bottomScrollBar.addEventListener("mouseleave", (e) => {
2147
+ this.changeScrollBarVisibility(this.bottomScrollBarBlock, "hidden" /* Hidden */);
2148
+ });
2149
+ }
2150
+ this.bottomScrollBarBlock.addEventListener("mousedown", (e) => {
2151
+ this.bottomGrabDragger.start(e.clientX, e.clientY);
2152
+ e.stopPropagation();
2153
+ });
2154
+ this.rightScrollBarBlock.addEventListener("mousedown", (e) => {
2155
+ this.rightGrabDragger.start(e.clientX, e.clientY);
2156
+ e.stopPropagation();
2157
+ });
2158
+ }
2159
+ autorun() {
2160
+ if (this.hideTimeout) {
2161
+ clearTimeout(this.hideTimeout);
2162
+ }
2163
+ const viewportBounds = getScrollViewport(
2164
+ {
2165
+ scrollX: this.config.config.scrollX,
2166
+ scrollY: this.config.config.scrollY
2167
+ },
2168
+ this.config
2169
+ );
2170
+ const viewport = this.config.getViewport();
2171
+ this.viewportWidth = viewport.width;
2172
+ this.viewportHeight = viewport.height;
2173
+ const rootBounds = this.options.getBounds();
2174
+ this.width = rootBounds?.width || 0;
2175
+ this.height = rootBounds?.height || 0;
2176
+ const paddingLeftRight = (this.viewportWidth - viewportBounds.width) / 2 - BORDER_WIDTH;
2177
+ const paddingTopBottom = (this.viewportHeight - viewportBounds.height) / 2 - BORDER_WIDTH;
2178
+ const canvasTotalWidth = this.width + viewportBounds.width;
2179
+ const canvasTotalHeight = this.height + viewportBounds.height;
2180
+ const initialOffsetX = rootBounds.x;
2181
+ const initialOffsetY = rootBounds.y;
2182
+ this.mostLeft = this.width + initialOffsetX - paddingLeftRight;
2183
+ this.mostRight = this.mostLeft - canvasTotalWidth;
2184
+ this.mostTop = this.height + initialOffsetY - paddingTopBottom;
2185
+ this.mostBottom = this.mostTop - canvasTotalHeight;
2186
+ this.scale = this.config.finalScale;
2187
+ const calcViewportWidth = this.clientViewportWidth;
2188
+ const calcViewportHeight = this.clientViewportHeight;
2189
+ this.scrollBottomWidth = calcViewportWidth - calcViewportWidth * (this.mostLeft - this.mostRight) / this.viewportMoveWidth;
2190
+ this.scrollRightHeight = calcViewportHeight - calcViewportHeight * (this.mostTop - this.mostBottom) / this.viewportMoveHeight;
2191
+ const bottomBarToLeft = this.getToLeft(viewport.x);
2192
+ const rightBarToTop = this.getToTop(viewport.y);
2193
+ import_utils20.domUtils.setStyle(this.rightScrollBarBlock, {
2194
+ right: 2,
2195
+ top: rightBarToTop,
2196
+ background: "#1F2329",
2197
+ zIndex: 10,
2198
+ height: this.scrollRightHeight,
2199
+ width: SCROLL_BAR_WIDTH
2200
+ });
2201
+ import_utils20.domUtils.setStyle(this.bottomScrollBarBlock, {
2202
+ left: bottomBarToLeft,
2203
+ bottom: 2,
2204
+ background: "#1F2329",
2205
+ zIndex: 10,
2206
+ height: SCROLL_BAR_WIDTH,
2207
+ width: this.scrollBottomWidth
2208
+ });
2209
+ this.changeScrollBarVisibility(this.rightScrollBarBlock, "show" /* Show */);
2210
+ this.changeScrollBarVisibility(this.bottomScrollBarBlock, "show" /* Show */);
2211
+ if (this.options.showScrollBars === "whenScrolling") {
2212
+ this.hideTimeout = window.setTimeout(() => {
2213
+ this.changeScrollBarVisibility(this.rightScrollBarBlock, "hidden" /* Hidden */);
2214
+ this.changeScrollBarVisibility(this.bottomScrollBarBlock, "hidden" /* Hidden */);
2215
+ this.hideTimeout = void 0;
2216
+ }, 1e3);
2217
+ }
2218
+ }
2219
+ };
2220
+ __decorateClass([
2221
+ (0, import_inversify8.optional)(),
2222
+ (0, import_inversify8.inject)(ScrollBarEvents)
2223
+ ], FlowScrollBarLayer.prototype, "events", 2);
2224
+ __decorateClass([
2225
+ (0, import_inversify8.inject)(import_document17.FlowDocument),
2226
+ (0, import_inversify8.optional)()
2227
+ ], FlowScrollBarLayer.prototype, "flowDocument", 2);
2228
+ __decorateClass([
2229
+ (0, import_core13.observeEntity)(import_core13.PlaygroundConfigEntity)
2230
+ ], FlowScrollBarLayer.prototype, "playgroundConfigEntity", 2);
2231
+ FlowScrollBarLayer = __decorateClass([
2232
+ (0, import_inversify8.injectable)()
2233
+ ], FlowScrollBarLayer);
2234
+
2235
+ // src/layers/flow-drag-layer.tsx
2236
+ var import_react15 = __toESM(require("react"));
2237
+ var import_inversify9 = require("inversify");
2238
+ var import_utils22 = require("@flowgram.ai/utils");
2239
+ var import_document18 = require("@flowgram.ai/document");
2240
+ var import_core14 = require("@flowgram.ai/core");
2241
+ var import_core15 = require("@flowgram.ai/core");
2242
+ var DRAG_OFFSET = 10;
2243
+ var DEFAULT_DRAG_OFFSET_X = 8;
2244
+ var DEFAULT_DRAG_OFFSET_Y = 8;
2245
+ var FlowDragLayer = class extends import_core14.Layer {
2246
+ constructor() {
2247
+ super(...arguments);
2248
+ this.dragOffset = {
2249
+ x: DEFAULT_DRAG_OFFSET_X,
2250
+ y: DEFAULT_DRAG_OFFSET_Y
2251
+ };
2252
+ this.containerRef = import_react15.default.createRef();
2253
+ this.draggingNodeMask = document.createElement("div");
2254
+ this._dragger = new import_core15.PlaygroundDrag({
2255
+ onDrag: (e) => {
2256
+ this.handleMouseMove(e);
2257
+ },
2258
+ onDragEnd: () => {
2259
+ this.handleMouseUp();
2260
+ },
2261
+ stopGlobalEventNames: ["contextmenu"]
2262
+ });
2263
+ }
2264
+ get transitions() {
2265
+ const result = [];
2266
+ this.document.traverse((entity) => {
2267
+ result.push(entity.getData(import_document18.FlowNodeTransitionData));
2268
+ });
2269
+ return result;
2270
+ }
2271
+ get dragStartEntity() {
2272
+ return this.flowRenderStateEntity.getDragStartEntity();
2273
+ }
2274
+ set dragStartEntity(entity) {
2275
+ this.flowRenderStateEntity.setDragStartEntity(entity);
2276
+ }
2277
+ get dragEntities() {
2278
+ return this.flowRenderStateEntity.getDragEntities();
2279
+ }
2280
+ set dragEntities(entities) {
2281
+ this.flowRenderStateEntity.setDragEntities(entities);
2282
+ }
2283
+ isGrab() {
2284
+ const currentState = this.editorStateConfig.getCurrentState();
2285
+ return currentState === import_core14.EditorState.STATE_GRAB;
2286
+ }
2287
+ setDraggingStatus(status) {
2288
+ if (this.service.nodeDragIdsWithChildren.length) {
2289
+ this.service.nodeDragIdsWithChildren.forEach((_id) => {
2290
+ const node = this.entityManager.getEntityById(_id);
2291
+ const data = node?.getData(import_document18.FlowNodeRenderData);
2292
+ data.dragging = status;
2293
+ });
2294
+ }
2295
+ }
2296
+ dragEnable(e) {
2297
+ return Math.abs(e.clientX - this.initialPosition.x) > DRAG_OFFSET || Math.abs(e.clientY - this.initialPosition.y) > DRAG_OFFSET;
2298
+ }
2299
+ handleMouseMove(event) {
2300
+ if (this.dragStartEntity && this.dragEnable(event)) {
2301
+ this.setDraggingStatus(true);
2302
+ const scale = this.playgroundConfigEntity.finalScale;
2303
+ if (this.containerRef.current) {
2304
+ const dragNode = this.containerRef.current.children?.[0];
2305
+ const dragBlockX = event.clientX - (this.pipelineNode.offsetLeft || 0) - this.playgroundConfigEntity.config.clientX - (dragNode.clientWidth - this.dragOffset.x) * scale;
2306
+ const dragBlockY = event.clientY - (this.pipelineNode.offsetTop || 0) - this.playgroundConfigEntity.config.clientY - (dragNode.clientHeight - this.dragOffset.y) * scale;
2307
+ const isBranch = this.service.isDragBranch;
2308
+ const draggingRect = new import_utils22.Rectangle(
2309
+ dragBlockX,
2310
+ dragBlockY,
2311
+ dragNode.clientWidth * scale,
2312
+ dragNode.clientHeight * scale
2313
+ );
2314
+ let side;
2315
+ const collisionTransition = this.transitions.find((transition) => {
2316
+ if (transition?.entity?.parent?.collapsed) {
2317
+ return false;
2318
+ }
2319
+ const { hasCollision, labelOffsetType } = this.flowDragConfigEntity.isCollision(
2320
+ transition,
2321
+ draggingRect,
2322
+ isBranch
2323
+ );
2324
+ side = labelOffsetType;
2325
+ return hasCollision;
2326
+ });
2327
+ if (collisionTransition && (isBranch ? this.service.isDroppableBranch(collisionTransition.entity, side) : this.service.isDroppableNode(collisionTransition.entity)) && (!this.options.canDrop || this.options.canDrop({
2328
+ dragNodes: this.dragEntities,
2329
+ dropNode: collisionTransition.entity,
2330
+ isBranch
2331
+ }))) {
2332
+ this.flowRenderStateEntity.setNodeDroppingId(collisionTransition.entity.id);
2333
+ } else {
2334
+ this.flowRenderStateEntity.setNodeDroppingId("");
2335
+ }
2336
+ this.flowRenderStateEntity.setDragLabelSide(side);
2337
+ this.containerRef.current.style.visibility = "visible";
2338
+ this.pipelineNode.parentElement.appendChild(this.draggingNodeMask);
2339
+ this.containerRef.current.style.left = `${dragBlockX}px`;
2340
+ this.containerRef.current.style.top = `${dragBlockY}px`;
2341
+ this.containerRef.current.style.transformOrigin = "top left";
2342
+ this.containerRef.current.style.transform = `scale(${scale})`;
2343
+ this.flowDragConfigEntity.scrollDirection(
2344
+ event,
2345
+ this.containerRef.current,
2346
+ dragBlockX,
2347
+ dragBlockY
2348
+ );
2349
+ }
2350
+ }
2351
+ }
2352
+ handleMouseUp() {
2353
+ this.setDraggingStatus(false);
2354
+ if (this.dragStartEntity) {
2355
+ const activatedNodeId = this.service.dropNodeId;
2356
+ if (activatedNodeId) {
2357
+ if (this.service.isDragBranch) {
2358
+ this.service.dropBranch();
2359
+ } else {
2360
+ this.service.dropNode();
2361
+ this.selectConfigEntity.clearSelectedNodes();
2362
+ }
2363
+ }
2364
+ this.flowRenderStateEntity.setNodeDroppingId("");
2365
+ this.flowRenderStateEntity.setDragLabelSide();
2366
+ this.dragStartEntity = void 0;
2367
+ this.dragEntities = [];
2368
+ this.flowDragConfigEntity.stopAllScroll();
2369
+ }
2370
+ if (this.containerRef.current) {
2371
+ this.containerRef.current.style.visibility = "hidden";
2372
+ if (this.pipelineNode.parentElement.contains(this.draggingNodeMask)) {
2373
+ this.pipelineNode.parentElement.removeChild(this.draggingNodeMask);
2374
+ }
2375
+ }
2376
+ }
2377
+ /**
2378
+ * 开始拖拽事件
2379
+ * @param e
2380
+ */
2381
+ async startDrag(e, {
2382
+ dragStartEntity: startEntityFromProps,
2383
+ dragEntities
2384
+ }, options) {
2385
+ if (this.isGrab() || this.config.disabled || this.config.readonly) {
2386
+ return;
2387
+ }
2388
+ this.dragOffset.x = options?.dragOffsetX || DEFAULT_DRAG_OFFSET_X;
2389
+ this.dragOffset.y = options?.dragOffsetY || DEFAULT_DRAG_OFFSET_Y;
2390
+ const isIcon = startEntityFromProps.flowNodeType === import_document18.FlowNodeBaseType.BLOCK_ICON;
2391
+ const isOrderIcon = startEntityFromProps.flowNodeType === import_document18.FlowNodeBaseType.BLOCK_ORDER_ICON;
2392
+ const dragStartEntity = isIcon || isOrderIcon ? startEntityFromProps.parent : startEntityFromProps;
2393
+ if (!dragStartEntity.getData(import_document18.FlowNodeRenderData).draggable) {
2394
+ return;
2395
+ }
2396
+ this.initialPosition = {
2397
+ x: e.clientX,
2398
+ y: e.clientY
2399
+ };
2400
+ this.dragStartEntity = dragStartEntity;
2401
+ this.dragEntities = dragEntities || [this.dragStartEntity];
2402
+ return this._dragger.start(e.clientX, e.clientY);
2403
+ }
2404
+ onReady() {
2405
+ this.draggingNodeMask.style.width = "100%";
2406
+ this.draggingNodeMask.style.height = "100%";
2407
+ this.draggingNodeMask.style.position = "absolute";
2408
+ this.draggingNodeMask.classList.add("dragging-node");
2409
+ this.draggingNodeMask.style.zIndex = "99";
2410
+ this.draggingNodeMask.style.cursor = "pointer";
2411
+ this.dragNodeComp = this.rendererRegistry.getRendererComponent("drag-node" /* DRAG_NODE */);
2412
+ if (this.options.onDrop) {
2413
+ this.toDispose.push(this.service.onDrop(this.options.onDrop));
2414
+ }
2415
+ }
2416
+ render() {
2417
+ const DragComp = this.dragNodeComp.renderer;
2418
+ return /* @__PURE__ */ import_react15.default.createElement(
2419
+ "div",
2420
+ {
2421
+ ref: this.containerRef,
2422
+ style: { position: "absolute", zIndex: 99999, visibility: "hidden" },
2423
+ onMouseEnter: (e) => e.stopPropagation()
2424
+ },
2425
+ /* @__PURE__ */ import_react15.default.createElement(DragComp, { dragStart: this.dragStartEntity, dragNodes: this.dragEntities })
2426
+ );
2427
+ }
2428
+ };
2429
+ __decorateClass([
2430
+ (0, import_inversify9.inject)(import_document18.FlowDocument)
2431
+ ], FlowDragLayer.prototype, "document", 2);
2432
+ __decorateClass([
2433
+ (0, import_inversify9.inject)(import_document18.FlowDragService)
2434
+ ], FlowDragLayer.prototype, "service", 2);
2435
+ __decorateClass([
2436
+ (0, import_core14.observeEntityDatas)(import_document18.FlowNodeEntity, import_document18.FlowNodeTransformData)
2437
+ ], FlowDragLayer.prototype, "transforms", 2);
2438
+ __decorateClass([
2439
+ (0, import_core14.observeEntity)(import_core14.EditorStateConfigEntity)
2440
+ ], FlowDragLayer.prototype, "editorStateConfig", 2);
2441
+ __decorateClass([
2442
+ (0, import_core14.observeEntity)(import_core14.PlaygroundConfigEntity)
2443
+ ], FlowDragLayer.prototype, "playgroundConfigEntity", 2);
2444
+ __decorateClass([
2445
+ (0, import_core14.observeEntity)(FlowDragEntity)
2446
+ ], FlowDragLayer.prototype, "flowDragConfigEntity", 2);
2447
+ __decorateClass([
2448
+ (0, import_core14.observeEntity)(import_document18.FlowRendererStateEntity)
2449
+ ], FlowDragLayer.prototype, "flowRenderStateEntity", 2);
2450
+ __decorateClass([
2451
+ (0, import_core14.observeEntity)(FlowSelectConfigEntity)
2452
+ ], FlowDragLayer.prototype, "selectConfigEntity", 2);
2453
+ __decorateClass([
2454
+ (0, import_inversify9.inject)(FlowRendererRegistry)
2455
+ ], FlowDragLayer.prototype, "rendererRegistry", 2);
2456
+ FlowDragLayer = __decorateClass([
2457
+ (0, import_inversify9.injectable)()
2458
+ ], FlowDragLayer);
2459
+
2460
+ // src/layers/flow-selector-box-layer.tsx
2461
+ var import_inversify10 = require("inversify");
2462
+ var import_utils23 = require("@flowgram.ai/utils");
2463
+ var import_document19 = require("@flowgram.ai/document");
2464
+ var import_core16 = require("@flowgram.ai/core");
2465
+ var FlowSelectorBoxLayer = class extends import_core16.Layer {
2466
+ constructor() {
2467
+ super(...arguments);
2468
+ this.node = import_utils23.domUtils.createDivWithClass("gedit-selector-box-layer");
2469
+ /**
2470
+ * 选择框
2471
+ */
2472
+ this.selectorBox = this.createDOMCache("gedit-selector-box");
2473
+ /**
2474
+ * 用于遮挡鼠标,避免触发 hover
2475
+ */
2476
+ this.selectorBoxBlock = this.createDOMCache("gedit-selector-box-block");
2477
+ /**
2478
+ * 拖动选择框
2479
+ */
2480
+ this.selectboxDragger = new import_core16.PlaygroundDrag({
2481
+ onDragStart: (e) => {
2482
+ this.selectConfigEntity.clearSelectedNodes();
2483
+ const mousePos = this.playgroundConfigEntity.getPosFromMouseEvent(e);
2484
+ this.transformVisibles = this.flowDocument.getRenderDatas(import_document19.FlowNodeTransformData, false).filter((transform) => {
2485
+ const { entity } = transform;
2486
+ if (entity.originParent) {
2487
+ return this.nodeSelectable(entity, mousePos) && this.nodeSelectable(entity.originParent, mousePos);
2488
+ }
2489
+ return this.nodeSelectable(entity, mousePos);
2490
+ });
2491
+ this.selectorBoxConfigEntity.setDragInfo(e);
2492
+ this.updateSelectorBox(this.selectorBoxConfigEntity);
2493
+ },
2494
+ onDrag: (e) => {
2495
+ this.selectorBoxConfigEntity.setDragInfo(e);
2496
+ this.selectConfigEntity.selectFromBounds(
2497
+ this.selectorBoxConfigEntity.toRectangle(this.playgroundConfigEntity.finalScale),
2498
+ this.transformVisibles
2499
+ );
2500
+ this.updateSelectorBox(this.selectorBoxConfigEntity);
2501
+ },
2502
+ onDragEnd: (e) => {
2503
+ this.selectorBoxConfigEntity.setDragInfo(e);
2504
+ this.transformVisibles.length = 0;
2505
+ this.updateSelectorBox(this.selectorBoxConfigEntity);
2506
+ }
2507
+ });
2508
+ }
2509
+ onReady() {
2510
+ if (!this.options.canSelect) {
2511
+ this.options.canSelect = (e) => {
2512
+ const target = e.target;
2513
+ return target === this.pipelineNode || target === this.playgroundNode;
2514
+ };
2515
+ }
2516
+ this.toDispose.pushAll([
2517
+ this.selectConfigEntity.onConfigChanged(() => {
2518
+ this.selectionService.selection = this.selectConfigEntity.selectedNodes;
2519
+ }),
2520
+ this.selectionService.onSelectionChanged(() => {
2521
+ const selectedNodes = this.selectionService.selection.filter(
2522
+ (entity) => entity instanceof import_document19.FlowNodeEntity
2523
+ );
2524
+ this.selectConfigEntity.selectedNodes = selectedNodes;
2525
+ })
2526
+ ]);
2527
+ this.listenPlaygroundEvent(
2528
+ "mousedown",
2529
+ (e) => {
2530
+ if (!this.isEnabled()) return;
2531
+ if (this.options.canSelect && !this.options.canSelect(e, this.selectorBoxConfigEntity)) {
2532
+ return;
2533
+ }
2534
+ const currentState = this.editorStateConfig.getCurrentState();
2535
+ if (currentState === import_core16.EditorState.STATE_MOUSE_FRIENDLY_SELECT) {
2536
+ this.selectConfigEntity.clearSelectedNodes();
2537
+ }
2538
+ this.selectboxDragger.start(e.clientX, e.clientY, this.config);
2539
+ return true;
2540
+ },
2541
+ import_core16.PipelineLayerPriority.BASE_LAYER
2542
+ );
2543
+ }
2544
+ isEnabled() {
2545
+ const currentState = this.editorStateConfig.getCurrentState();
2546
+ const isMouseFriendly = currentState === import_core16.EditorState.STATE_MOUSE_FRIENDLY_SELECT;
2547
+ return !this.config.disabled && !this.config.readonly && // 鼠标友好模式下,需要按下 shift 启动框选
2548
+ (isMouseFriendly && this.editorStateConfig.isPressingShift || currentState === import_core16.EditorState.STATE_SELECT) && !this.selectorBoxConfigEntity.disabled;
2549
+ }
2550
+ /**
2551
+ * Destroy
2552
+ */
2553
+ dispose() {
2554
+ this.selectorBox.dispose();
2555
+ this.selectorBoxBlock.dispose();
2556
+ super.dispose();
2557
+ }
2558
+ updateSelectorBox(selector) {
2559
+ const node = this.selectorBox.get();
2560
+ const block = this.selectorBoxBlock.get();
2561
+ if (!this.isEnabled() && selector.isMoving) {
2562
+ this.selectorBoxConfigEntity.collapse();
2563
+ }
2564
+ if (!this.isEnabled() || !selector.isMoving) {
2565
+ node.setStyle({
2566
+ display: "none"
2567
+ });
2568
+ block.setStyle({
2569
+ display: "none"
2570
+ });
2571
+ } else {
2572
+ node.setStyle({
2573
+ display: "block",
2574
+ left: selector.position.x,
2575
+ top: selector.position.y,
2576
+ width: selector.size.width,
2577
+ height: selector.size.height
2578
+ });
2579
+ block.setStyle({
2580
+ display: "block",
2581
+ left: selector.position.x - 10,
2582
+ top: selector.position.y - 10,
2583
+ width: selector.size.width + 20,
2584
+ height: selector.size.height + 20
2585
+ });
2586
+ }
2587
+ }
2588
+ nodeSelectable(node, mousePos) {
2589
+ const selectable = node.getNodeMeta().selectable;
2590
+ if (typeof selectable === "function") {
2591
+ return selectable(node, mousePos);
2592
+ } else {
2593
+ return selectable;
2594
+ }
2595
+ }
2596
+ // autorun(): void {
2597
+ // this.updateSelectorBox(this.selectorBoxConfigEntity);
2598
+ // }
2599
+ };
2600
+ __decorateClass([
2601
+ (0, import_inversify10.inject)(import_document19.FlowDocument)
2602
+ ], FlowSelectorBoxLayer.prototype, "flowDocument", 2);
2603
+ __decorateClass([
2604
+ (0, import_inversify10.inject)(import_core16.ContextMenuService)
2605
+ ], FlowSelectorBoxLayer.prototype, "contextMenuService", 2);
2606
+ __decorateClass([
2607
+ (0, import_core16.observeEntity)(import_core16.PlaygroundConfigEntity)
2608
+ ], FlowSelectorBoxLayer.prototype, "playgroundConfigEntity", 2);
2609
+ __decorateClass([
2610
+ (0, import_inversify10.inject)(import_core16.SelectionService)
2611
+ ], FlowSelectorBoxLayer.prototype, "selectionService", 2);
2612
+ __decorateClass([
2613
+ (0, import_core16.observeEntity)(SelectorBoxConfigEntity)
2614
+ ], FlowSelectorBoxLayer.prototype, "selectorBoxConfigEntity", 2);
2615
+ __decorateClass([
2616
+ (0, import_core16.observeEntity)(FlowSelectConfigEntity)
2617
+ ], FlowSelectorBoxLayer.prototype, "selectConfigEntity", 2);
2618
+ __decorateClass([
2619
+ (0, import_core16.observeEntity)(import_core16.EditorStateConfigEntity)
2620
+ ], FlowSelectorBoxLayer.prototype, "editorStateConfig", 2);
2621
+ FlowSelectorBoxLayer = __decorateClass([
2622
+ (0, import_inversify10.injectable)()
2623
+ ], FlowSelectorBoxLayer);
2624
+
2625
+ // src/layers/flow-selector-bounds-layer.tsx
2626
+ var import_react16 = __toESM(require("react"));
2627
+ var import_inversify11 = require("inversify");
2628
+ var import_document20 = require("@flowgram.ai/document");
2629
+ var import_core17 = require("@flowgram.ai/core");
2630
+ var import_utils24 = require("@flowgram.ai/utils");
2631
+ var FlowSelectorBoundsLayer = class extends import_core17.Layer {
2632
+ constructor() {
2633
+ super(...arguments);
2634
+ this.node = import_utils24.domUtils.createDivWithClass("gedit-selector-bounds-layer");
2635
+ this.selectBoundsBackground = import_utils24.domUtils.createDivWithClass("gedit-selector-bounds-background");
2636
+ }
2637
+ onReady() {
2638
+ this.node.style.zIndex = "20";
2639
+ const { firstChild } = this.pipelineNode;
2640
+ if (this.options.boundsPadding !== void 0) {
2641
+ this.flowSelectConfigEntity.boundsPadding = this.options.boundsPadding;
2642
+ }
2643
+ if (this.options.backgroundClassName) {
2644
+ this.selectBoundsBackground.classList.add(this.options.backgroundClassName);
2645
+ }
2646
+ const selectorBoundsLayer = import_utils24.domUtils.createDivWithClass("gedit-playground-layer");
2647
+ selectorBoundsLayer.appendChild(this.selectBoundsBackground);
2648
+ this.pipelineNode.insertBefore(selectorBoundsLayer, firstChild);
2649
+ }
2650
+ onZoom(scale) {
2651
+ this.node.style.transform = `scale(${scale})`;
2652
+ this.selectBoundsBackground.parentElement.style.transform = `scale(${scale})`;
2653
+ }
2654
+ onViewportChange() {
2655
+ this.render();
2656
+ }
2657
+ isEnabled() {
2658
+ const currentState = this.editorStateConfig.getCurrentState();
2659
+ return currentState === import_core17.EditorState.STATE_SELECT;
2660
+ }
2661
+ // /**
2662
+ // * 渲染工具栏
2663
+ // */
2664
+ // renderCommandMenus(): JSX.Element[] {
2665
+ // return this.commandRegistry.commands
2666
+ // .filter(cmd => cmd.category === FlowRendererCommandCategory.SELECTOR_BOX)
2667
+ // .map(cmd => {
2668
+ // const CommandRenderer = this.rendererRegistry.getRendererComponent(
2669
+ // (cmd.icon as string) || cmd.id,
2670
+ // )?.renderer;
2671
+ //
2672
+ // return (
2673
+ // // eslint-disable-next-line react/jsx-filename-extension
2674
+ // <CommandRenderer
2675
+ // key={cmd.id}
2676
+ // disabled={!this.commandRegistry.isEnabled(cmd.id)}
2677
+ // command={cmd}
2678
+ // onClick={(e: any) => this.commandRegistry.executeCommand(cmd.id, e)}
2679
+ // />
2680
+ // );
2681
+ // })
2682
+ // .filter(c => c);
2683
+ // }
2684
+ render() {
2685
+ const {
2686
+ ignoreOneSelect,
2687
+ SelectorBoxPopover: SelectorBoxPopoverFromOpts,
2688
+ disableBackground,
2689
+ CustomBoundsRenderer
2690
+ } = this.options;
2691
+ const bounds = this.flowSelectConfigEntity.getSelectedBounds();
2692
+ const selectedNodes = this.flowSelectConfigEntity.selectedNodes;
2693
+ const bg = this.selectBoundsBackground;
2694
+ const isDragging = !this.selectorBoxConfigEntity.isStart;
2695
+ if (bounds.width === 0 || bounds.height === 0 || // 选中单个的时候不显示
2696
+ ignoreOneSelect && selectedNodes.length === 1 && // 选中的节点不包含多个子节点
2697
+ selectedNodes[0].childrenLength <= 1) {
2698
+ import_utils24.domUtils.setStyle(bg, {
2699
+ display: "none"
2700
+ });
2701
+ return /* @__PURE__ */ import_react16.default.createElement(import_react16.default.Fragment, null);
2702
+ }
2703
+ if (CustomBoundsRenderer) {
2704
+ return /* @__PURE__ */ import_react16.default.createElement(
2705
+ CustomBoundsRenderer,
2706
+ {
2707
+ bounds,
2708
+ config: this.config,
2709
+ flowSelectConfig: this.flowSelectConfigEntity,
2710
+ commandRegistry: this.commandRegistry
2711
+ }
2712
+ );
2713
+ }
2714
+ const style = {
2715
+ display: "block",
2716
+ left: bounds.left,
2717
+ top: bounds.top,
2718
+ width: bounds.width,
2719
+ height: bounds.height
2720
+ };
2721
+ if (!disableBackground) {
2722
+ import_utils24.domUtils.setStyle(bg, style);
2723
+ }
2724
+ let foregroundClassName = "gedit-selector-bounds-foreground";
2725
+ if (this.options.foregroundClassName) {
2726
+ foregroundClassName += " " + this.options.foregroundClassName;
2727
+ }
2728
+ const SelectorBoxPopover = SelectorBoxPopoverFromOpts || this.rendererRegistry.tryToGetRendererComponent("selector-box-popover" /* SELECTOR_BOX_POPOVER */)?.renderer;
2729
+ if (!isDragging || !SelectorBoxPopover)
2730
+ return /* @__PURE__ */ import_react16.default.createElement("div", { className: foregroundClassName, style });
2731
+ return /* @__PURE__ */ import_react16.default.createElement(
2732
+ SelectorBoxPopover,
2733
+ {
2734
+ bounds,
2735
+ config: this.config,
2736
+ flowSelectConfig: this.flowSelectConfigEntity,
2737
+ commandRegistry: this.commandRegistry
2738
+ },
2739
+ /* @__PURE__ */ import_react16.default.createElement("div", { className: foregroundClassName, style })
2740
+ );
2741
+ }
2742
+ };
2743
+ __decorateClass([
2744
+ (0, import_inversify11.inject)(FlowRendererRegistry)
2745
+ ], FlowSelectorBoundsLayer.prototype, "rendererRegistry", 2);
2746
+ __decorateClass([
2747
+ (0, import_inversify11.inject)(import_core17.CommandRegistry)
2748
+ ], FlowSelectorBoundsLayer.prototype, "commandRegistry", 2);
2749
+ __decorateClass([
2750
+ (0, import_core17.observeEntity)(FlowSelectConfigEntity)
2751
+ ], FlowSelectorBoundsLayer.prototype, "flowSelectConfigEntity", 2);
2752
+ __decorateClass([
2753
+ (0, import_core17.observeEntity)(import_core17.EditorStateConfigEntity)
2754
+ ], FlowSelectorBoundsLayer.prototype, "editorStateConfig", 2);
2755
+ __decorateClass([
2756
+ (0, import_core17.observeEntity)(SelectorBoxConfigEntity)
2757
+ ], FlowSelectorBoundsLayer.prototype, "selectorBoxConfigEntity", 2);
2758
+ __decorateClass([
2759
+ (0, import_core17.observeEntityDatas)(import_document20.FlowNodeEntity, import_document20.FlowNodeRenderData)
2760
+ ], FlowSelectorBoundsLayer.prototype, "renderStates", 2);
2761
+ __decorateClass([
2762
+ (0, import_core17.observeEntityDatas)(import_document20.FlowNodeEntity, import_document20.FlowNodeTransformData)
2763
+ ], FlowSelectorBoundsLayer.prototype, "_transforms", 2);
2764
+ FlowSelectorBoundsLayer = __decorateClass([
2765
+ (0, import_inversify11.injectable)()
2766
+ ], FlowSelectorBoundsLayer);
2767
+
2768
+ // src/layers/flow-context-menu-layer.tsx
2769
+ var import_react17 = __toESM(require("react"));
2770
+ var import_inversify12 = require("inversify");
2771
+ var import_core18 = require("@flowgram.ai/core");
2772
+ var import_utils25 = require("@flowgram.ai/utils");
2773
+ var FlowContextMenuLayer = class extends import_core18.Layer {
2774
+ constructor() {
2775
+ super(...arguments);
2776
+ this.node = import_utils25.domUtils.createDivWithClass("gedit-context-menu-layer");
2777
+ this.nodeRef = import_react17.default.createRef();
2778
+ }
2779
+ isEnabled() {
2780
+ const currentState = this.editorStateConfig.getCurrentState();
2781
+ return !this.config.disabled && !this.config.readonly && currentState === import_core18.EditorState.STATE_SELECT && !this.selectorBoxConfigEntity.disabled;
2782
+ }
2783
+ onReady() {
2784
+ this.node.style.zIndex = "30";
2785
+ this.node.style.display = "block";
2786
+ this.toDispose.pushAll([
2787
+ this.listenPlaygroundEvent(
2788
+ "contextmenu",
2789
+ (e) => {
2790
+ if (!this.isEnabled()) return;
2791
+ this.contextMenuService.rightPanelVisible = true;
2792
+ const bounds = this.flowSelectConfigEntity.getSelectedBounds();
2793
+ if (bounds.width === 0 || bounds.height === 0) {
2794
+ return;
2795
+ }
2796
+ e.stopPropagation();
2797
+ e.preventDefault();
2798
+ this.nodeRef.current?.setVisible(true);
2799
+ const dragBlockX = e.clientX - (this.pipelineNode.offsetLeft || 0) - this.playgroundConfigEntity.config.clientX;
2800
+ const dragBlockY = e.clientY - (this.pipelineNode.offsetTop || 0) - this.playgroundConfigEntity.config.clientY;
2801
+ this.node.style.left = `${dragBlockX}px`;
2802
+ this.node.style.top = `${dragBlockY}px`;
2803
+ },
2804
+ import_core18.PipelineLayerPriority.BASE_LAYER
2805
+ ),
2806
+ this.listenPlaygroundEvent("mousedown", () => {
2807
+ this.nodeRef.current?.setVisible(false);
2808
+ this.contextMenuService.rightPanelVisible = false;
2809
+ })
2810
+ ]);
2811
+ }
2812
+ onScroll() {
2813
+ this.nodeRef.current?.setVisible(false);
2814
+ }
2815
+ onZoom() {
2816
+ this.nodeRef.current?.setVisible(false);
2817
+ }
2818
+ /**
2819
+ * Destroy
2820
+ */
2821
+ dispose() {
2822
+ super.dispose();
2823
+ }
2824
+ /**
2825
+ * 渲染工具栏
2826
+ */
2827
+ renderCommandMenus() {
2828
+ return this.commandRegistry.commands.filter((cmd) => cmd.category === "SELECTOR_BOX" /* SELECTOR_BOX */).map((cmd) => {
2829
+ const CommandRenderer = this.rendererRegistry.getRendererComponent(
2830
+ cmd.icon || cmd.id
2831
+ )?.renderer;
2832
+ return /* @__PURE__ */ import_react17.default.createElement(
2833
+ CommandRenderer,
2834
+ {
2835
+ key: cmd.id,
2836
+ command: cmd,
2837
+ isContextMenu: true,
2838
+ disabled: !this.commandRegistry.isEnabled(cmd.id),
2839
+ onClick: (e) => this.commandRegistry.executeCommand(cmd.id, e)
2840
+ }
2841
+ );
2842
+ }).filter((c) => c);
2843
+ }
2844
+ render() {
2845
+ const SelectorBoxPopover = this.rendererRegistry.getRendererComponent(
2846
+ "context-menu-popover" /* CONTEXT_MENU_POPOVER */
2847
+ ).renderer;
2848
+ return /* @__PURE__ */ import_react17.default.createElement(SelectorBoxPopover, { ref: this.nodeRef, content: this.renderCommandMenus() });
2849
+ }
2850
+ };
2851
+ __decorateClass([
2852
+ (0, import_inversify12.inject)(import_core18.CommandRegistry)
2853
+ ], FlowContextMenuLayer.prototype, "commandRegistry", 2);
2854
+ __decorateClass([
2855
+ (0, import_inversify12.inject)(FlowRendererRegistry)
2856
+ ], FlowContextMenuLayer.prototype, "rendererRegistry", 2);
2857
+ __decorateClass([
2858
+ (0, import_inversify12.inject)(import_core18.ContextMenuService)
2859
+ ], FlowContextMenuLayer.prototype, "contextMenuService", 2);
2860
+ __decorateClass([
2861
+ (0, import_core18.observeEntity)(FlowSelectConfigEntity)
2862
+ ], FlowContextMenuLayer.prototype, "flowSelectConfigEntity", 2);
2863
+ __decorateClass([
2864
+ (0, import_inversify12.inject)(import_core18.SelectionService)
2865
+ ], FlowContextMenuLayer.prototype, "selectionService", 2);
2866
+ __decorateClass([
2867
+ (0, import_core18.observeEntity)(import_core18.PlaygroundConfigEntity)
2868
+ ], FlowContextMenuLayer.prototype, "playgroundConfigEntity", 2);
2869
+ __decorateClass([
2870
+ (0, import_core18.observeEntity)(import_core18.EditorStateConfigEntity)
2871
+ ], FlowContextMenuLayer.prototype, "editorStateConfig", 2);
2872
+ __decorateClass([
2873
+ (0, import_core18.observeEntity)(SelectorBoxConfigEntity)
2874
+ ], FlowContextMenuLayer.prototype, "selectorBoxConfigEntity", 2);
2875
+ FlowContextMenuLayer = __decorateClass([
2876
+ (0, import_inversify12.injectable)()
2877
+ ], FlowContextMenuLayer);
2878
+
2879
+ // src/layers/flow-scroll-limit-layer.tsx
2880
+ var import_inversify13 = require("inversify");
2881
+ var import_document21 = require("@flowgram.ai/document");
2882
+ var import_core19 = require("@flowgram.ai/core");
2883
+ var FlowScrollLimitLayer = class extends import_core19.Layer {
2884
+ getInitScroll() {
2885
+ return this.document.layout.getInitScroll(this.pipelineNode.getBoundingClientRect());
2886
+ }
2887
+ onReady() {
2888
+ const initScroll = () => this.getInitScroll();
2889
+ this.config.updateConfig(initScroll());
2890
+ this.config.addScrollLimit(
2891
+ (scroll) => scrollLimit(
2892
+ scroll,
2893
+ [this.document.root.getData(import_document21.FlowNodeTransformData).bounds],
2894
+ this.config,
2895
+ initScroll
2896
+ )
2897
+ );
2898
+ }
2899
+ };
2900
+ __decorateClass([
2901
+ (0, import_inversify13.inject)(import_document21.FlowDocument)
2902
+ ], FlowScrollLimitLayer.prototype, "document", 2);
2903
+ FlowScrollLimitLayer = __decorateClass([
2904
+ (0, import_inversify13.injectable)()
2905
+ ], FlowScrollLimitLayer);
2906
+
2907
+ // src/flow-renderer-container-module.ts
2908
+ var import_inversify14 = require("inversify");
2909
+ var FlowRendererContainerModule = new import_inversify14.ContainerModule((bind) => {
2910
+ bind(FlowRendererRegistry).toSelf().inSingletonScope();
2911
+ bind(FlowRendererResizeObserver).toSelf().inSingletonScope();
2912
+ });
2913
+ // Annotate the CommonJS export names for ESM import in node:
2914
+ 0 && (module.exports = {
2915
+ FlowContextMenuLayer,
2916
+ FlowDebugLayer,
2917
+ FlowDragEntity,
2918
+ FlowDragLayer,
2919
+ FlowLabelsLayer,
2920
+ FlowLinesLayer,
2921
+ FlowNodesContentLayer,
2922
+ FlowNodesTransformLayer,
2923
+ FlowRendererCommandCategory,
2924
+ FlowRendererComponentType,
2925
+ FlowRendererContainerModule,
2926
+ FlowRendererContribution,
2927
+ FlowRendererKey,
2928
+ FlowRendererRegistry,
2929
+ FlowScrollBarLayer,
2930
+ FlowScrollLimitLayer,
2931
+ FlowSelectConfigEntity,
2932
+ FlowSelectorBoundsLayer,
2933
+ FlowSelectorBoxLayer,
2934
+ FlowTextKey,
2935
+ MARK_ACTIVATED_ARROW_ID,
2936
+ MARK_ARROW_ID,
2937
+ ScrollBarEvents,
2938
+ SelectorBoxConfigEntity,
2939
+ useBaseColor
2940
+ });
2941
+ //# sourceMappingURL=index.js.map