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