@plait/core 0.55.0 → 0.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/board/board.component.d.ts +2 -0
  2. package/core/element/element-ref.d.ts +5 -0
  3. package/core/element/plugin-element.d.ts +9 -6
  4. package/esm2022/board/board.component.mjs +10 -5
  5. package/esm2022/core/element/element-ref.mjs +2 -0
  6. package/esm2022/core/element/plugin-element.mjs +16 -7
  7. package/esm2022/core/list-render.mjs +4 -3
  8. package/esm2022/interfaces/board.mjs +1 -1
  9. package/esm2022/interfaces/element.mjs +5 -2
  10. package/esm2022/plugins/create-board.mjs +2 -2
  11. package/esm2022/plugins/with-hotkey.mjs +2 -2
  12. package/esm2022/plugins/with-moving.mjs +88 -10
  13. package/esm2022/plugins/with-related-fragment.mjs +20 -13
  14. package/esm2022/public-api.mjs +3 -2
  15. package/esm2022/services/context.service.mjs +30 -0
  16. package/esm2022/utils/angle.mjs +24 -1
  17. package/esm2022/utils/common.mjs +5 -3
  18. package/esm2022/utils/dom/common.mjs +1 -21
  19. package/esm2022/utils/fragment.mjs +10 -8
  20. package/esm2022/utils/group.mjs +25 -22
  21. package/esm2022/utils/math.mjs +36 -1
  22. package/esm2022/utils/selected-element.mjs +3 -2
  23. package/esm2022/utils/selection.mjs +2 -3
  24. package/esm2022/utils/weak-maps.mjs +2 -1
  25. package/esm2022/utils/z-index.mjs +2 -2
  26. package/fesm2022/plait-core.mjs +235 -80
  27. package/fesm2022/plait-core.mjs.map +1 -1
  28. package/interfaces/board.d.ts +1 -1
  29. package/interfaces/element.d.ts +6 -4
  30. package/package.json +1 -1
  31. package/plugins/with-moving.d.ts +3 -1
  32. package/public-api.d.ts +2 -1
  33. package/services/{image-context.service.d.ts → context.service.d.ts} +3 -0
  34. package/utils/angle.d.ts +2 -0
  35. package/utils/dom/common.d.ts +1 -2
  36. package/utils/fragment.d.ts +2 -2
  37. package/utils/group.d.ts +5 -5
  38. package/utils/math.d.ts +1 -0
  39. package/utils/weak-maps.d.ts +2 -0
  40. package/esm2022/services/image-context.service.mjs +0 -22
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { IterableDiffers, inject, ViewContainerRef, Directive, Input, Injectable, EventEmitter, ElementRef, Component, ChangeDetectionStrategy, Output, HostBinding, ViewChild, ContentChildren } from '@angular/core';
2
+ import { IterableDiffers, inject, ViewContainerRef, ChangeDetectorRef, Directive, Input, Injectable, EventEmitter, ElementRef, Component, ChangeDetectionStrategy, Output, HostBinding, ViewChild, ContentChildren } from '@angular/core';
3
3
  import rough from 'roughjs/bin/rough';
4
4
  import { timer, Subject, fromEvent } from 'rxjs';
5
5
  import { takeUntil, filter, tap } from 'rxjs/operators';
@@ -30,6 +30,7 @@ const BOARD_TO_IS_SELECTION_MOVING = new WeakMap();
30
30
  const BOARD_TO_TEMPORARY_ELEMENTS = new WeakMap();
31
31
  const BOARD_TO_MOVING_ELEMENT = new WeakMap();
32
32
  const PATH_REFS = new WeakMap();
33
+ const ELEMENT_TO_REF = new WeakMap();
33
34
 
34
35
  var PlaitPointerType;
35
36
  (function (PlaitPointerType) {
@@ -278,7 +279,7 @@ const getHitElementByPoint = (board, point, match = () => true) => {
278
279
  if (hitElement) {
279
280
  return;
280
281
  }
281
- if (PlaitBoard.isBoard(node) || !match(node)) {
282
+ if (PlaitBoard.isBoard(node) || !match(node) || !PlaitElement.hasMounted(node)) {
282
283
  return;
283
284
  }
284
285
  if (board.isHit(node, point)) {
@@ -544,26 +545,6 @@ function createRect(rectangle, options) {
544
545
  const setStrokeLinecap = (g, value) => {
545
546
  g.setAttribute('stroke-linecap', value);
546
547
  };
547
- const setAngleForG = (g, centerPoint, angle) => {
548
- if (angle === 0) {
549
- g.removeAttribute('transform');
550
- return;
551
- }
552
- var centerX = centerPoint[0];
553
- var centerY = centerPoint[1];
554
- let cosTheta = Math.cos(angle);
555
- let sinTheta = Math.sin(angle);
556
- let transformMatrix = [
557
- cosTheta,
558
- sinTheta,
559
- -sinTheta,
560
- cosTheta,
561
- centerX * (1 - cosTheta) + centerY * sinTheta,
562
- centerY * (1 - cosTheta) - centerX * sinTheta
563
- ];
564
- let matrix = 'matrix(' + transformMatrix.join(',') + ')';
565
- g.setAttribute('transform', `${matrix}`);
566
- };
567
548
  const setPathStrokeLinecap = (g, value) => {
568
549
  g.querySelectorAll('path').forEach(path => {
569
550
  path.setAttribute('stroke-linecap', value);
@@ -681,7 +662,8 @@ class ListRender {
681
662
  newComponentRefs.push(componentRef);
682
663
  newContexts.push(context);
683
664
  }
684
- if (record.item === this.children[0]) {
665
+ // item might has been changed, so need to compare the id
666
+ if (record.item === this.children[0] || record.item.id === this.children[0]?.id) {
685
667
  currentIndexForFirstElement = record.currentIndex;
686
668
  }
687
669
  });
@@ -731,7 +713,7 @@ const trackBy = (index, element) => {
731
713
  return element.id;
732
714
  };
733
715
  const createPluginComponent = (componentType, context, viewContainerRef, childrenContext) => {
734
- const componentRef = viewContainerRef.createComponent(componentType);
716
+ const componentRef = viewContainerRef.createComponent(componentType, { injector: viewContainerRef.injector });
735
717
  const instance = componentRef.instance;
736
718
  instance.context = context;
737
719
  componentRef.changeDetectorRef.detectChanges();
@@ -847,6 +829,7 @@ class PlaitPluginElementComponent {
847
829
  const containerG = this.getContainerG();
848
830
  NODE_TO_G.set(this.element, elementG);
849
831
  NODE_TO_CONTAINER_G.set(this.element, containerG);
832
+ ELEMENT_TO_REF.set(this.element, this.ref);
850
833
  this.updateListRender();
851
834
  this.cdr.markForCheck();
852
835
  if (hasOnContextChanged(this)) {
@@ -865,6 +848,7 @@ class PlaitPluginElementComponent {
865
848
  }
866
849
  NODE_TO_G.set(this.element, this._g);
867
850
  NODE_TO_CONTAINER_G.set(this.element, this._containerG);
851
+ ELEMENT_TO_REF.set(this.element, this.ref);
868
852
  }
869
853
  }
870
854
  get context() {
@@ -885,9 +869,10 @@ class PlaitPluginElementComponent {
885
869
  getElementG() {
886
870
  return this._g;
887
871
  }
888
- constructor(cdr) {
889
- this.cdr = cdr;
872
+ constructor(ref) {
873
+ this.ref = ref;
890
874
  this.viewContainerRef = inject(ViewContainerRef);
875
+ this.cdr = inject(ChangeDetectorRef);
891
876
  this.initialized = false;
892
877
  }
893
878
  ngOnInit() {
@@ -915,6 +900,9 @@ class PlaitPluginElementComponent {
915
900
  }
916
901
  }
917
902
  }
903
+ getRef() {
904
+ return this.ref;
905
+ }
918
906
  updateListRender() {
919
907
  if (this.hasChildren) {
920
908
  if (!this.listRender) {
@@ -950,15 +938,18 @@ class PlaitPluginElementComponent {
950
938
  if (NODE_TO_CONTAINER_G.get(this.element) === this._containerG) {
951
939
  NODE_TO_CONTAINER_G.delete(this.element);
952
940
  }
941
+ if (ELEMENT_TO_REF.get(this.element) === this.ref) {
942
+ ELEMENT_TO_REF.set(this.element, this.ref);
943
+ }
953
944
  removeSelectedElement(this.board, this.element);
954
945
  this.getContainerG().remove();
955
946
  }
956
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: PlaitPluginElementComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive }); }
947
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: PlaitPluginElementComponent, deps: "invalid", target: i0.ɵɵFactoryTarget.Directive }); }
957
948
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.2.4", type: PlaitPluginElementComponent, inputs: { context: "context" }, ngImport: i0 }); }
958
949
  }
959
950
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: PlaitPluginElementComponent, decorators: [{
960
951
  type: Directive
961
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { context: [{
952
+ }], ctorParameters: () => [{ type: undefined }], propDecorators: { context: [{
962
953
  type: Input
963
954
  }] } });
964
955
  const ELEMENT_TO_COMPONENT = new WeakMap();
@@ -1051,6 +1042,41 @@ function getNearestPointBetweenPointAndSegments(point, points, isClose = true) {
1051
1042
  }
1052
1043
  return result;
1053
1044
  }
1045
+ function getNearestPointBetweenPointAndEllipse(point, center, rx, ry, rotation = 0) {
1046
+ const rectangleClient = {
1047
+ x: center[0] - rx,
1048
+ y: center[1] - ry,
1049
+ height: ry * 2,
1050
+ width: rx * 2
1051
+ };
1052
+ // https://stackoverflow.com/a/46007540/232122
1053
+ const px = Math.abs(point[0] - rectangleClient.x - rectangleClient.width / 2);
1054
+ const py = Math.abs(point[1] - rectangleClient.y - rectangleClient.height / 2);
1055
+ let tx = 0.707;
1056
+ let ty = 0.707;
1057
+ const a = Math.abs(rectangleClient.width) / 2;
1058
+ const b = Math.abs(rectangleClient.height) / 2;
1059
+ [0, 1, 2, 3].forEach(x => {
1060
+ const xx = a * tx;
1061
+ const yy = b * ty;
1062
+ const ex = ((a * a - b * b) * tx ** 3) / a;
1063
+ const ey = ((b * b - a * a) * ty ** 3) / b;
1064
+ const rx = xx - ex;
1065
+ const ry = yy - ey;
1066
+ const qx = px - ex;
1067
+ const qy = py - ey;
1068
+ const r = Math.hypot(ry, rx);
1069
+ const q = Math.hypot(qy, qx);
1070
+ tx = Math.min(1, Math.max(0, ((qx * r) / q + ex) / a));
1071
+ ty = Math.min(1, Math.max(0, ((qy * r) / q + ey) / b));
1072
+ const t = Math.hypot(ty, tx);
1073
+ tx /= t;
1074
+ ty /= t;
1075
+ });
1076
+ const signX = point[0] > center[0] ? 1 : -1;
1077
+ const signY = point[1] > center[1] ? 1 : -1;
1078
+ return [center[0] + a * tx * signX, center[1] + b * ty * signY];
1079
+ }
1054
1080
  function rotate(x1, y1, x2, y2, angle) {
1055
1081
  // 𝑎′𝑥=(𝑎𝑥−𝑐𝑥)cos𝜃−(𝑎𝑦−𝑐𝑦)sin𝜃+𝑐𝑥
1056
1082
  // 𝑎′𝑦=(𝑎𝑥−𝑐𝑥)sin𝜃+(𝑎𝑦−𝑐𝑦)cos𝜃+𝑐𝑦.
@@ -2361,9 +2387,11 @@ const debounce = (func, wait, options) => {
2361
2387
  };
2362
2388
  const getElementsIndices = (board, elements) => {
2363
2389
  sortElements(board, elements);
2364
- return elements.map(item => {
2390
+ return elements
2391
+ .map(item => {
2365
2392
  return board.children.map(item => item.id).indexOf(item.id);
2366
- });
2393
+ })
2394
+ .filter(item => item >= 0);
2367
2395
  };
2368
2396
  const getHighestIndexOfElement = (board, elements) => {
2369
2397
  const indices = getElementsIndices(board, elements);
@@ -3172,7 +3200,7 @@ const toContiguousGroups = (board, array) => {
3172
3200
  return true;
3173
3201
  });
3174
3202
  let isPartialSelectGroupElement = false;
3175
- if (previousElement.groupId || (currentElement.groupId && previousElement.groupId !== currentElement.groupId)) {
3203
+ if (previousElement?.groupId || (currentElement?.groupId && previousElement?.groupId !== currentElement?.groupId)) {
3176
3204
  let isPartialSelectPreviousGroup = false;
3177
3205
  let isPartialSelectCurrentElement = false;
3178
3206
  if (previousElement.groupId) {
@@ -3422,6 +3450,29 @@ const getAngleBetweenPoints = (startPoint, endPoint, centerPoint) => {
3422
3450
  const endAngle = (5 * Math.PI) / 2 + Math.atan2(endPoint[1] - centerPoint[1], endPoint[0] - centerPoint[0]);
3423
3451
  return normalizeAngle(endAngle - startAngle);
3424
3452
  };
3453
+ const getAngleByElement = (element) => {
3454
+ return element?.angle;
3455
+ };
3456
+ const setAngleForG = (g, centerPoint, angle) => {
3457
+ if (angle === 0) {
3458
+ g.removeAttribute('transform');
3459
+ return;
3460
+ }
3461
+ var centerX = centerPoint[0];
3462
+ var centerY = centerPoint[1];
3463
+ let cosTheta = Math.cos(angle);
3464
+ let sinTheta = Math.sin(angle);
3465
+ let transformMatrix = [
3466
+ cosTheta,
3467
+ sinTheta,
3468
+ -sinTheta,
3469
+ cosTheta,
3470
+ centerX * (1 - cosTheta) + centerY * sinTheta,
3471
+ centerY * (1 - cosTheta) - centerX * sinTheta
3472
+ ];
3473
+ let matrix = 'matrix(' + transformMatrix.join(',') + ')';
3474
+ g.setAttribute('transform', `${matrix}`);
3475
+ };
3425
3476
 
3426
3477
  function isSelectionMoving(board) {
3427
3478
  return !!BOARD_TO_IS_SELECTION_MOVING.get(board);
@@ -3589,14 +3640,14 @@ const getRectangleByGroup = (board, group, recursion) => {
3589
3640
  const elementsInGroup = getAllElementsInGroup(board, group, recursion);
3590
3641
  return getRectangleByElements(board, elementsInGroup, false);
3591
3642
  };
3592
- const getGroupByElement = (board, element, recursion, source) => {
3593
- const group = (source || board.children).find(item => item.id === element?.groupId);
3643
+ const getGroupByElement = (board, element, recursion, originElements) => {
3644
+ const group = (originElements || board.children).find(item => item.id === element?.groupId);
3594
3645
  if (!group) {
3595
3646
  return recursion ? [] : null;
3596
3647
  }
3597
3648
  if (recursion) {
3598
3649
  const groups = [group];
3599
- const grandGroups = getGroupByElement(board, group, recursion, source);
3650
+ const grandGroups = getGroupByElement(board, group, recursion, originElements);
3600
3651
  if (grandGroups.length) {
3601
3652
  groups.push(...grandGroups);
3602
3653
  }
@@ -3623,14 +3674,14 @@ const getElementsInGroupByElement = (board, element) => {
3623
3674
  }
3624
3675
  };
3625
3676
  const isSelectedElementOrGroup = (board, element, elements) => {
3626
- const selectedElements = elements || getSelectedElements(board);
3677
+ const selectedElements = elements?.length ? elements : getSelectedElements(board);
3627
3678
  if (PlaitGroupElement.isGroup(element)) {
3628
3679
  return isSelectedAllElementsInGroup(board, element, elements);
3629
3680
  }
3630
3681
  return selectedElements.map(item => item.id).includes(element.id);
3631
3682
  };
3632
3683
  const isSelectedAllElementsInGroup = (board, group, elements) => {
3633
- const selectedElements = elements || getSelectedElements(board);
3684
+ const selectedElements = elements?.length ? elements : getSelectedElements(board);
3634
3685
  const elementsInGroup = getElementsInGroup(board, group, true);
3635
3686
  return elementsInGroup.every(item => selectedElements.map(element => element.id).includes(item.id));
3636
3687
  };
@@ -3643,8 +3694,8 @@ const filterSelectedGroups = (board, groups, elements) => {
3643
3694
  });
3644
3695
  return selectedGroups;
3645
3696
  };
3646
- const getSelectedGroups = (board, elements) => {
3647
- const highestSelectedGroups = getHighestSelectedGroups(board, elements);
3697
+ const getSelectedGroups = (board, elements, originElements) => {
3698
+ const highestSelectedGroups = getHighestSelectedGroups(board, elements, originElements);
3648
3699
  const groups = [];
3649
3700
  highestSelectedGroups.forEach(item => {
3650
3701
  groups.push(item);
@@ -3653,20 +3704,20 @@ const getSelectedGroups = (board, elements) => {
3653
3704
  });
3654
3705
  return groups;
3655
3706
  };
3656
- const getHighestSelectedGroup = (board, element, elements) => {
3657
- const hitElementGroups = getGroupByElement(board, element, true, elements);
3707
+ const getHighestSelectedGroup = (board, element, elements, originElements) => {
3708
+ const hitElementGroups = getGroupByElement(board, element, true, originElements);
3658
3709
  const selectedGroups = filterSelectedGroups(board, hitElementGroups, elements);
3659
3710
  if (selectedGroups.length) {
3660
3711
  return selectedGroups[selectedGroups.length - 1];
3661
3712
  }
3662
3713
  return null;
3663
3714
  };
3664
- const getHighestSelectedGroups = (board, elements) => {
3715
+ const getHighestSelectedGroups = (board, elements, originElements) => {
3665
3716
  let result = [];
3666
- const selectedElements = elements || getSelectedElements(board);
3717
+ const selectedElements = elements?.length ? elements : getSelectedElements(board);
3667
3718
  selectedElements.forEach(item => {
3668
3719
  if (item.groupId) {
3669
- const group = getHighestSelectedGroup(board, item, elements);
3720
+ const group = getHighestSelectedGroup(board, item, elements, originElements);
3670
3721
  if (group && !result.includes(group)) {
3671
3722
  result.push(group);
3672
3723
  }
@@ -3676,7 +3727,7 @@ const getHighestSelectedGroups = (board, elements) => {
3676
3727
  };
3677
3728
  const getSelectedIsolatedElements = (board, elements) => {
3678
3729
  let result = [];
3679
- const selectedElements = elements || getSelectedElements(board);
3730
+ const selectedElements = elements?.length ? elements : getSelectedElements(board);
3680
3731
  selectedElements
3681
3732
  .filter(item => !PlaitGroupElement.isGroup(item))
3682
3733
  .forEach(item => {
@@ -3700,12 +3751,15 @@ const getHighestSelectedElements = (board, elements) => {
3700
3751
  return [...getHighestSelectedGroups(board, elements), ...getSelectedIsolatedElements(board, elements)];
3701
3752
  };
3702
3753
  const createGroupRectangleG = (board, elements) => {
3703
- const selectedElements = getSelectedElements(board);
3704
- const groupRectangleG = createG();
3754
+ const selectedElementIds = getSelectedElements(board).map(item => item.id);
3755
+ let groupRectangleG = null;
3705
3756
  const isMoving = isSelectionMoving(board);
3706
3757
  elements.forEach(item => {
3707
- const isRender = (!selectedElements.includes(item) && !isMoving) || isMoving;
3758
+ const isRender = (!selectedElementIds.includes(item.id) && !isMoving) || isMoving;
3708
3759
  if (item.groupId && isRender) {
3760
+ if (!groupRectangleG) {
3761
+ groupRectangleG = createG();
3762
+ }
3709
3763
  const elements = getElementsInGroupByElement(board, item);
3710
3764
  const rectangle = getRectangleByElements(board, elements, false);
3711
3765
  const rectangleG = drawRectangle(board, rectangle, {
@@ -3748,9 +3802,9 @@ const canAddGroup = (board, elements) => {
3748
3802
  }
3749
3803
  return false;
3750
3804
  };
3751
- const canRemoveGroup = (board, elements) => {
3752
- const selectedGroups = getHighestSelectedGroups(board, elements);
3753
- const selectedElements = elements || getSelectedElements(board);
3805
+ const canRemoveGroup = (board, elements, originElements) => {
3806
+ const selectedGroups = getHighestSelectedGroups(board, elements, originElements);
3807
+ const selectedElements = elements?.length ? elements : getSelectedElements(board);
3754
3808
  return selectedElements.length > 0 && selectedGroups.length > 0;
3755
3809
  };
3756
3810
  const getEditingGroup = (board, element) => {
@@ -3788,15 +3842,17 @@ const setFragment = (board, type, clipboardData) => {
3788
3842
  const clipboardContext = board.buildFragment(null, rectangle, type);
3789
3843
  clipboardContext && setClipboardData(clipboardData, clipboardContext);
3790
3844
  };
3791
- const duplicateElements = (board, elements) => {
3792
- const selectedElements = elements || getSelectedElements(board);
3793
- const rectangle = getRectangleByElements(board, selectedElements, false);
3794
- const clipboardContext = board.buildFragment(null, rectangle, 'copy');
3795
- clipboardContext &&
3845
+ const duplicateElements = (board, elements, point) => {
3846
+ const targetElements = elements?.length ? elements : getSelectedElements(board);
3847
+ const targetRectangle = getRectangleByElements(board, targetElements, false);
3848
+ const clipboardContext = board.buildFragment(null, targetRectangle, 'copy', targetElements);
3849
+ const stringifiedContext = clipboardContext && JSON.stringify(clipboardContext);
3850
+ const clonedContext = stringifiedContext && JSON.parse(stringifiedContext);
3851
+ clonedContext &&
3796
3852
  board.insertFragment({
3797
- ...clipboardContext,
3853
+ ...clonedContext,
3798
3854
  text: undefined
3799
- }, [rectangle.x + rectangle.width / 2, rectangle.y + rectangle.height / 2]);
3855
+ }, point || [targetRectangle.x + targetRectangle.width / 2, targetRectangle.y + targetRectangle.height / 2]);
3800
3856
  };
3801
3857
 
3802
3858
  const SNAP_TOLERANCE = 2;
@@ -4016,6 +4072,9 @@ const PlaitElement = {
4016
4072
  getComponent(value) {
4017
4073
  return ELEMENT_TO_COMPONENT.get(value);
4018
4074
  },
4075
+ getElementRef(value) {
4076
+ return ELEMENT_TO_REF.get(value);
4077
+ },
4019
4078
  getElementG(value) {
4020
4079
  const g = NODE_TO_G.get(value);
4021
4080
  if (!g) {
@@ -4482,7 +4541,7 @@ function createBoard(children, options) {
4482
4541
  globalKeyDown: (event) => { },
4483
4542
  keyUp: (event) => { },
4484
4543
  dblClick: (event) => { },
4485
- buildFragment: (clipboardContext) => clipboardContext,
4544
+ buildFragment: (clipboardContext, rectangle, type, originData) => clipboardContext,
4486
4545
  insertFragment: () => { },
4487
4546
  deleteFragment: (elements) => {
4488
4547
  CoreTransforms.removeElements(board, elements);
@@ -5103,7 +5162,7 @@ function isVerticalCross(rectangle, other) {
5103
5162
  }
5104
5163
 
5105
5164
  function withMoving(board) {
5106
- const { pointerDown, pointerMove, globalPointerUp, globalPointerMove } = board;
5165
+ const { pointerDown, pointerMove, globalPointerUp, globalPointerMove, globalKeyDown, keyUp } = board;
5107
5166
  let offsetX = 0;
5108
5167
  let offsetY = 0;
5109
5168
  let isPreventDefault = false;
@@ -5114,6 +5173,31 @@ function withMoving(board) {
5114
5173
  let selectedTargetElements = null;
5115
5174
  let hitTargetElement = undefined;
5116
5175
  let isHitSelectedTarget = undefined;
5176
+ let pendingNodesG = null;
5177
+ board.globalKeyDown = (event) => {
5178
+ if (!PlaitBoard.isReadonly(board)) {
5179
+ if (isKeyHotkey('option', event)) {
5180
+ event.preventDefault();
5181
+ if (startPoint && activeElements.length && !PlaitBoard.hasBeenTextEditing(board)) {
5182
+ pendingNodesG = drawPendingNodesG(board, activeElements, offsetX, offsetY);
5183
+ pendingNodesG && PlaitBoard.getElementActiveHost(board).append(pendingNodesG);
5184
+ }
5185
+ }
5186
+ }
5187
+ globalKeyDown(event);
5188
+ };
5189
+ board.keyUp = (event) => {
5190
+ if (!PlaitBoard.isReadonly(board)) {
5191
+ if (event.altKey && pendingNodesG && startPoint && activeElements.length && !PlaitBoard.hasBeenTextEditing(board)) {
5192
+ event.preventDefault();
5193
+ const currentElements = updatePoints(board, activeElements, offsetX, offsetY);
5194
+ PlaitBoard.getBoardContainer(board).classList.add('element-moving');
5195
+ cacheMovingElements(board, currentElements);
5196
+ }
5197
+ }
5198
+ pendingNodesG?.remove();
5199
+ keyUp(event);
5200
+ };
5117
5201
  board.pointerDown = (event) => {
5118
5202
  if (PlaitBoard.isReadonly(board) ||
5119
5203
  !PlaitBoard.isPointer(board, PlaitPointerType.selection) ||
@@ -5159,6 +5243,7 @@ function withMoving(board) {
5159
5243
  isPreventDefault = true;
5160
5244
  }
5161
5245
  snapG?.remove();
5246
+ pendingNodesG?.remove();
5162
5247
  const endPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
5163
5248
  offsetX = endPoint[0] - startPoint[0];
5164
5249
  offsetY = endPoint[1] - startPoint[1];
@@ -5187,9 +5272,15 @@ function withMoving(board) {
5187
5272
  snapG.classList.add(ACTIVE_MOVING_CLASS_NAME);
5188
5273
  PlaitBoard.getElementActiveHost(board).append(snapG);
5189
5274
  handleTouchTarget(board);
5190
- const currentElements = updatePoints(board, activeElements, offsetX, offsetY);
5191
- PlaitBoard.getBoardContainer(board).classList.add('element-moving');
5192
- cacheMovingElements(board, currentElements);
5275
+ if (event.altKey) {
5276
+ pendingNodesG = drawPendingNodesG(board, activeElements, offsetX, offsetY);
5277
+ pendingNodesG && PlaitBoard.getElementActiveHost(board).append(pendingNodesG);
5278
+ }
5279
+ else {
5280
+ const currentElements = updatePoints(board, activeElements, offsetX, offsetY);
5281
+ PlaitBoard.getBoardContainer(board).classList.add('element-moving');
5282
+ cacheMovingElements(board, currentElements);
5283
+ }
5193
5284
  });
5194
5285
  }
5195
5286
  }
@@ -5209,6 +5300,11 @@ function withMoving(board) {
5209
5300
  globalPointerMove(event);
5210
5301
  };
5211
5302
  board.globalPointerUp = event => {
5303
+ if (event.altKey && activeElements.length) {
5304
+ const validElements = getValidElements(board, activeElements);
5305
+ const rectangle = getRectangleByElements(board, validElements, false);
5306
+ duplicateElements(board, validElements, [rectangle.x + offsetX, rectangle.y + offsetY]);
5307
+ }
5212
5308
  isPreventDefault = false;
5213
5309
  hitTargetElement = undefined;
5214
5310
  selectedTargetElements = null;
@@ -5221,6 +5317,7 @@ function withMoving(board) {
5221
5317
  };
5222
5318
  function cancelMove(board) {
5223
5319
  snapG?.remove();
5320
+ pendingNodesG?.remove();
5224
5321
  startPoint = null;
5225
5322
  activeElementsRectangle = null;
5226
5323
  offsetX = 0;
@@ -5284,8 +5381,12 @@ function getSelectedTargetElements(board) {
5284
5381
  targetElements.push(...relatedElements);
5285
5382
  return targetElements;
5286
5383
  }
5287
- function updatePoints(board, targetElements, offsetX, offsetY) {
5288
- const validElements = targetElements.filter(element => !PlaitGroupElement.isGroup(element) && board.children.findIndex(item => item.id === element.id) > -1);
5384
+ function getValidElements(board, activeElements) {
5385
+ const validElements = [...activeElements].filter(element => !PlaitGroupElement.isGroup(element) && board.children.findIndex(item => item.id === element.id) > -1);
5386
+ return validElements;
5387
+ }
5388
+ function updatePoints(board, activeElements, offsetX, offsetY) {
5389
+ const validElements = getValidElements(board, activeElements);
5289
5390
  const currentElements = validElements.map(element => {
5290
5391
  const points = element.points || [];
5291
5392
  const newPoints = points.map(p => [p[0] + offsetX, p[1] + offsetY]);
@@ -5298,6 +5399,41 @@ function updatePoints(board, targetElements, offsetX, offsetY) {
5298
5399
  });
5299
5400
  return currentElements;
5300
5401
  }
5402
+ function drawPendingNodesG(board, activeElements, offsetX, offsetY) {
5403
+ let pendingNodesG = null;
5404
+ const elements = [];
5405
+ const validElements = getValidElements(board, activeElements);
5406
+ validElements.forEach(element => {
5407
+ depthFirstRecursion(element, node => {
5408
+ elements.push(node);
5409
+ }, () => true);
5410
+ });
5411
+ elements.forEach(item => {
5412
+ let rectangle = board.getRectangle(item);
5413
+ if (rectangle) {
5414
+ rectangle = {
5415
+ x: rectangle.x + offsetX,
5416
+ y: rectangle.y + offsetY,
5417
+ width: rectangle.width,
5418
+ height: rectangle.height
5419
+ };
5420
+ const movingG = drawRectangle(board, rectangle, {
5421
+ stroke: SELECTION_BORDER_COLOR,
5422
+ strokeWidth: 1,
5423
+ fill: SELECTION_FILL_COLOR,
5424
+ fillStyle: 'solid'
5425
+ });
5426
+ if (!pendingNodesG) {
5427
+ pendingNodesG = createG();
5428
+ pendingNodesG.classList.add(ACTIVE_MOVING_CLASS_NAME);
5429
+ }
5430
+ const angle = getAngleByElement(item);
5431
+ angle && setAngleForG(movingG, RectangleClient.getCenterPoint(rectangle), angle);
5432
+ pendingNodesG.append(movingG);
5433
+ }
5434
+ });
5435
+ return pendingNodesG;
5436
+ }
5301
5437
 
5302
5438
  const withOptions = (board) => {
5303
5439
  const pluginOptions = new Map();
@@ -5430,7 +5566,7 @@ const withHotkey = (board) => {
5430
5566
  if (!PlaitBoard.isReadonly(board) && selectedElements.length > 0) {
5431
5567
  if (isKeyHotkey('mod+d', event)) {
5432
5568
  event.preventDefault();
5433
- duplicateElements(board, selectedElements);
5569
+ duplicateElements(board);
5434
5570
  return;
5435
5571
  }
5436
5572
  }
@@ -5475,6 +5611,7 @@ const withHotkey = (board) => {
5475
5611
 
5476
5612
  class PlaitContextService {
5477
5613
  constructor() {
5614
+ this._stable = new Subject();
5478
5615
  this.uploadingFiles = [];
5479
5616
  }
5480
5617
  getUploadingFile(url) {
@@ -5486,6 +5623,12 @@ class PlaitContextService {
5486
5623
  removeUploadingFile(fileEntry) {
5487
5624
  this.uploadingFiles = this.uploadingFiles.filter(file => file.url !== fileEntry.url);
5488
5625
  }
5626
+ onStable() {
5627
+ return this._stable.asObservable();
5628
+ }
5629
+ nextStable() {
5630
+ this._stable.next('');
5631
+ }
5489
5632
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: PlaitContextService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5490
5633
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: PlaitContextService }); }
5491
5634
  }
@@ -5495,19 +5638,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImpor
5495
5638
 
5496
5639
  function withRelatedFragment(board) {
5497
5640
  const { buildFragment } = board;
5498
- board.buildFragment = (clipboardContext, rectangle, type) => {
5499
- const relatedFragment = board.getRelatedFragment([]);
5500
- if (!clipboardContext) {
5501
- clipboardContext = createClipboardContext(WritableClipboardType.elements, relatedFragment, '');
5502
- }
5503
- else {
5504
- clipboardContext = addClipboardContext(clipboardContext, {
5505
- text: '',
5506
- type: WritableClipboardType.elements,
5507
- elements: relatedFragment
5508
- });
5641
+ board.buildFragment = (clipboardContext, rectangle, type, originData) => {
5642
+ let relatedFragment = board.getRelatedFragment(originData || []);
5643
+ if (relatedFragment) {
5644
+ if (originData?.length) {
5645
+ relatedFragment = relatedFragment.filter(item => !originData.map(element => element.id).includes(item.id));
5646
+ }
5647
+ if (relatedFragment.length) {
5648
+ if (!clipboardContext) {
5649
+ clipboardContext = createClipboardContext(WritableClipboardType.elements, relatedFragment, '');
5650
+ }
5651
+ else {
5652
+ clipboardContext = addClipboardContext(clipboardContext, {
5653
+ text: '',
5654
+ type: WritableClipboardType.elements,
5655
+ elements: relatedFragment
5656
+ });
5657
+ }
5658
+ }
5509
5659
  }
5510
- return buildFragment(clipboardContext, rectangle, type);
5660
+ return buildFragment(clipboardContext, rectangle, type, originData);
5511
5661
  };
5512
5662
  return board;
5513
5663
  }
@@ -5557,6 +5707,7 @@ class PlaitBoardComponent {
5557
5707
  this.plaitPlugins = [];
5558
5708
  this.plaitChange = new EventEmitter();
5559
5709
  this.plaitBoardInitialized = new EventEmitter();
5710
+ this.contextService = inject(PlaitContextService);
5560
5711
  this.trackBy = (index, element) => {
5561
5712
  return element.id;
5562
5713
  };
@@ -5620,10 +5771,13 @@ class PlaitBoardComponent {
5620
5771
  if (this.hasInitialized) {
5621
5772
  const valueChange = changes['plaitValue'];
5622
5773
  const options = changes['plaitOptions'];
5623
- if (valueChange)
5774
+ if (valueChange) {
5624
5775
  this.board.children = valueChange.currentValue;
5625
- if (options)
5776
+ this.updateListRender();
5777
+ }
5778
+ if (options) {
5626
5779
  this.board.options = options.currentValue;
5780
+ }
5627
5781
  this.cdr.markForCheck();
5628
5782
  }
5629
5783
  }
@@ -5760,6 +5914,7 @@ class PlaitBoardComponent {
5760
5914
  }
5761
5915
  updateListRender() {
5762
5916
  this.listRender.update(this.board.children, this.initializeChildrenContext());
5917
+ this.contextService.nextStable();
5763
5918
  }
5764
5919
  initializeChildrenContext() {
5765
5920
  return {
@@ -6182,5 +6337,5 @@ const isDebug = (key) => {
6182
6337
  * Generated bundle index. Do not edit.
6183
6338
  */
6184
6339
 
6185
- export { A, ACTIVE_MOVING_CLASS_NAME, ACTIVE_STROKE_WIDTH, ALT, APOSTROPHE, ATTACHED_ELEMENT_CLASS_NAME, AT_SIGN, B, BACKSLASH, BACKSPACE, BOARD_TO_AFTER_CHANGE, BOARD_TO_COMPONENT, BOARD_TO_ELEMENT_HOST, BOARD_TO_HOST, BOARD_TO_IS_SELECTION_MOVING, BOARD_TO_MOVING_ELEMENT, BOARD_TO_MOVING_POINT, BOARD_TO_MOVING_POINT_IN_BOARD, BOARD_TO_ON_CHANGE, BOARD_TO_ROUGH_SVG, BOARD_TO_SELECTED_ELEMENT, BOARD_TO_TEMPORARY_ELEMENTS, BOARD_TO_TOUCH_REF, BOARD_TO_VIEWPORT_ORIGINATION, BoardTransforms, C, CAPS_LOCK, CLOSE_SQUARE_BRACKET, COMMA, CONTEXT_MENU, CONTROL, ColorfulThemeColor, CoreTransforms, CursorClass, D, DASH, DELETE, DOWN_ARROW, DarkThemeColor, DebugGenerator, DefaultThemeColor, Direction, E, EIGHT, ELEMENT_TO_COMPONENT, END, ENTER, EQUALS, ESCAPE, F, F1, F10, F11, F12, F2, F3, F4, F5, F6, F7, F8, F9, FF_EQUALS, FF_MINUS, FF_MUTE, FF_SEMICOLON, FF_VOLUME_DOWN, FF_VOLUME_UP, FIRST_MEDIA, FIVE, FLUSHING, FOUR, G, H, HIT_DISTANCE_BUFFER, HOME, HOST_CLASS_NAME, I, INSERT, IS_APPLE, IS_BOARD_ALIVE, IS_BOARD_CACHE, IS_CHROME, IS_CHROME_LEGACY, IS_DRAGGING, IS_EDGE_LEGACY, IS_FIREFOX, IS_IOS, IS_MAC, IS_SAFARI, IS_TEXT_EDITABLE, J, K, L, LAST_MEDIA, LEFT_ARROW, M, MAC_ENTER, MAC_META, MAC_WK_CMD_LEFT, MAC_WK_CMD_RIGHT, MAX_RADIUS, MERGING, META, MUTE, N, NINE, NODE_TO_CONTAINER_G, NODE_TO_G, NODE_TO_INDEX, NODE_TO_PARENT, NS, NUMPAD_DIVIDE, NUMPAD_EIGHT, NUMPAD_FIVE, NUMPAD_FOUR, NUMPAD_MINUS, NUMPAD_MULTIPLY, NUMPAD_NINE, NUMPAD_ONE, NUMPAD_PERIOD, NUMPAD_PLUS, NUMPAD_SEVEN, NUMPAD_SIX, NUMPAD_THREE, NUMPAD_TWO, NUMPAD_ZERO, NUM_CENTER, NUM_LOCK, O, ONE, OPEN_SQUARE_BRACKET, P, PAGE_DOWN, PAGE_UP, PATH_REFS, PAUSE, PERIOD, PLUS_SIGN, POINTER_BUTTON, PRESS_AND_MOVE_BUFFER, PRINT_SCREEN, Path, PlaitBoard, PlaitBoardComponent, PlaitContextService, PlaitElement, PlaitGroupElement, PlaitHistoryBoard, PlaitIslandBaseComponent, PlaitIslandPopoverBaseComponent, PlaitNode, PlaitOperation, PlaitPluginElementComponent, PlaitPluginKey, PlaitPointerType, Point, Q, QUESTION_MARK, R, RESIZE_CURSORS, RESIZE_HANDLE_CLASS_NAME, RIGHT_ARROW, ROTATE_HANDLE_CLASS_NAME, RectangleClient, ResizeCursorClass, RetroThemeColor, RgbaToHEX, S, SAVING, SCROLL_BAR_WIDTH, SCROLL_LOCK, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, SELECTION_RECTANGLE_CLASS_NAME, SEMICOLON, SEVEN, SHIFT, SINGLE_QUOTE, SIX, SLASH, SNAPPING_STROKE_WIDTH, SNAP_TOLERANCE, SPACE, Selection, SoftThemeColor, StarryThemeColor, T, TAB, THREE, TILDE, TWO, ThemeColorMode, ThemeColors, Transforms, U, UP_ARROW, V, VOLUME_DOWN, VOLUME_UP, Viewport, W, WritableClipboardType, X, Y, Z, ZERO, addClipboardContext, addSelectedElement, approximately, arrowPoints, buildPlaitHtml, cacheMovingElements, cacheSelectedElements, cacheSelectedElementsWithGroup, cacheSelectedElementsWithGroupOnShift, calcNewViewBox, canAddGroup, canRemoveGroup, canSetZIndex, catmullRomFitting, clampZoomLevel, clearNodeWeakMap, clearSelectedElement, clearSelectionMoving, clearViewportOrigination, createClipboardContext, createDebugGenerator, createFakeEvent, createForeignObject, createG, createGroup, createGroupRectangleG, createKeyboardEvent, createMask, createModModifierKeys, createMouseEvent, createPath, createPointerEvent, createRect, createSVG, createTestingBoard, createText, createTouchEvent, debounce, degreesToRadians, deleteFragment, deleteTemporaryElements, depthFirstRecursion, distanceBetweenPointAndPoint, distanceBetweenPointAndRectangle, distanceBetweenPointAndSegment, distanceBetweenPointAndSegments, downloadImage, drawArrow, drawBezierPath, drawCircle, drawDashedLines, drawEntireActiveRectangleG, drawLine, drawLinearPath, drawPointSnapLines, drawRectangle, drawRoundRectangle, drawSolidLines, duplicateElements, fakeNodeWeakMap, filterSelectedGroups, findElements, findIndex, findLastIndex, getAllElementsInGroup, getAllMoveOptions, getAngleBetweenPoints, getBarPoint, getBoardRectangle, getClipboardData, getClipboardFromHtml, getCrossingPointsBetweenEllipseAndSegment, getDataTransferClipboard, getDataTransferClipboardText, getEditingGroup, getElementById, getElementHostBBox, getElementsInGroup, getElementsInGroupByElement, getElementsIndices, getEllipseTangentSlope, getGroupByElement, getHighestGroup, getHighestIndexOfElement, getHighestSelectedElements, getHighestSelectedGroup, getHighestSelectedGroups, getHitElementByPoint, getHitElementsBySelection, getHitSelectedElements, getIsRecursionFunc, getMinPointDelta, getMovingElements, getNearestDelta, getNearestPointBetweenPointAndSegment, getNearestPointBetweenPointAndSegments, getNearestPointRectangle, getOffsetAfterRotate, getOneMoveOptions, getProbablySupportsClipboardRead, getProbablySupportsClipboardWrite, getProbablySupportsClipboardWriteText, getRealScrollBarWidth, getRectangleByAngle, getRectangleByElements, getRectangleByGroup, getRotatedBoundingRectangle, getSelectedElements, getSelectedGroups, getSelectedIsolatedElements, getSelectedIsolatedElementsCanAddToGroup, getSelectedTargetElements, getSelectionAngle, getSnapRectangles, getTemporaryElements, getTemporaryRef, getTripleAxis, getVectorFromPointAndSlope, getViewBox, getViewBoxCenterPoint, getViewportContainerRect, getViewportOrigination, handleTouchTarget, hasBeforeContextChange, hasInputOrTextareaTarget, hasOnBoardChange, hasOnContextChanged, hasSameAngle, hasSelectedElementsInSameGroup, hasValidAngle, hotkeys, idCreator, initializeViewBox, initializeViewportContainer, initializeViewportOffset, inverse, isAxisChangedByAngle, isContextmenu, isDOMElement, isDOMNode, isDebug, isDragging, isFromScrolling, isFromViewportChange, isHandleSelection, isInPlaitBoard, isIndicesContinuous, isLineHitLine, isMainPointer, isMovingElements, isNullOrUndefined, isPointInEllipse, isPointInPolygon, isPointInRoundRectangle, isPolylineHitRectangle, isPreventTouchMove, isSecondaryPointer, isSelectedAllElementsInGroup, isSelectedElement, isSelectedElementOrGroup, isSelectionMoving, isSetSelectionOperation, isSetViewportOperation, isSnapPoint, moveElementsToNewPath, moveElementsToNewPathAfterAddGroup, nonGroupInHighestSelectedElements, normalizeAngle, normalizePoint, preventTouchMove, radiansToDegrees, removeMovingElements, removeSelectedElement, rotate, rotateAntiPointsByElement, rotateElements, rotatePoints, rotatePointsByElement, rotatedDataPoints, scrollToRectangle, setAngleForG, setClipboardData, setDataTransferClipboard, setDataTransferClipboardText, setDragging, setFragment, setIsFromScrolling, setIsFromViewportChange, setPathStrokeLinecap, setSVGViewBox, setSelectedElementsWithGroup, setSelectionMoving, setStrokeLinecap, shouldClear, shouldMerge, shouldSave, sortElements, stripHtml, temporaryDisableSelection, throttleRAF, toDomPrecision, toFixed, toHostPoint, toHostPointFromViewBoxPoint, toImage, toScreenPointFromHostPoint, toViewBoxPoint, toViewBoxPoints, uniqueById, updateForeignObject, updateForeignObjectWidth, updatePoints, updateViewportByScrolling, updateViewportContainerScroll, updateViewportOffset, updateViewportOrigination, withArrowMoving, withMoving, withOptions, withSelection };
6340
+ export { A, ACTIVE_MOVING_CLASS_NAME, ACTIVE_STROKE_WIDTH, ALT, APOSTROPHE, ATTACHED_ELEMENT_CLASS_NAME, AT_SIGN, B, BACKSLASH, BACKSPACE, BOARD_TO_AFTER_CHANGE, BOARD_TO_COMPONENT, BOARD_TO_ELEMENT_HOST, BOARD_TO_HOST, BOARD_TO_IS_SELECTION_MOVING, BOARD_TO_MOVING_ELEMENT, BOARD_TO_MOVING_POINT, BOARD_TO_MOVING_POINT_IN_BOARD, BOARD_TO_ON_CHANGE, BOARD_TO_ROUGH_SVG, BOARD_TO_SELECTED_ELEMENT, BOARD_TO_TEMPORARY_ELEMENTS, BOARD_TO_TOUCH_REF, BOARD_TO_VIEWPORT_ORIGINATION, BoardTransforms, C, CAPS_LOCK, CLOSE_SQUARE_BRACKET, COMMA, CONTEXT_MENU, CONTROL, ColorfulThemeColor, CoreTransforms, CursorClass, D, DASH, DELETE, DOWN_ARROW, DarkThemeColor, DebugGenerator, DefaultThemeColor, Direction, E, EIGHT, ELEMENT_TO_COMPONENT, ELEMENT_TO_REF, END, ENTER, EQUALS, ESCAPE, F, F1, F10, F11, F12, F2, F3, F4, F5, F6, F7, F8, F9, FF_EQUALS, FF_MINUS, FF_MUTE, FF_SEMICOLON, FF_VOLUME_DOWN, FF_VOLUME_UP, FIRST_MEDIA, FIVE, FLUSHING, FOUR, G, H, HIT_DISTANCE_BUFFER, HOME, HOST_CLASS_NAME, I, INSERT, IS_APPLE, IS_BOARD_ALIVE, IS_BOARD_CACHE, IS_CHROME, IS_CHROME_LEGACY, IS_DRAGGING, IS_EDGE_LEGACY, IS_FIREFOX, IS_IOS, IS_MAC, IS_SAFARI, IS_TEXT_EDITABLE, J, K, L, LAST_MEDIA, LEFT_ARROW, M, MAC_ENTER, MAC_META, MAC_WK_CMD_LEFT, MAC_WK_CMD_RIGHT, MAX_RADIUS, MERGING, META, MUTE, N, NINE, NODE_TO_CONTAINER_G, NODE_TO_G, NODE_TO_INDEX, NODE_TO_PARENT, NS, NUMPAD_DIVIDE, NUMPAD_EIGHT, NUMPAD_FIVE, NUMPAD_FOUR, NUMPAD_MINUS, NUMPAD_MULTIPLY, NUMPAD_NINE, NUMPAD_ONE, NUMPAD_PERIOD, NUMPAD_PLUS, NUMPAD_SEVEN, NUMPAD_SIX, NUMPAD_THREE, NUMPAD_TWO, NUMPAD_ZERO, NUM_CENTER, NUM_LOCK, O, ONE, OPEN_SQUARE_BRACKET, P, PAGE_DOWN, PAGE_UP, PATH_REFS, PAUSE, PERIOD, PLUS_SIGN, POINTER_BUTTON, PRESS_AND_MOVE_BUFFER, PRINT_SCREEN, Path, PlaitBoard, PlaitBoardComponent, PlaitContextService, PlaitElement, PlaitGroupElement, PlaitHistoryBoard, PlaitIslandBaseComponent, PlaitIslandPopoverBaseComponent, PlaitNode, PlaitOperation, PlaitPluginElementComponent, PlaitPluginKey, PlaitPointerType, Point, Q, QUESTION_MARK, R, RESIZE_CURSORS, RESIZE_HANDLE_CLASS_NAME, RIGHT_ARROW, ROTATE_HANDLE_CLASS_NAME, RectangleClient, ResizeCursorClass, RetroThemeColor, RgbaToHEX, S, SAVING, SCROLL_BAR_WIDTH, SCROLL_LOCK, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, SELECTION_RECTANGLE_CLASS_NAME, SEMICOLON, SEVEN, SHIFT, SINGLE_QUOTE, SIX, SLASH, SNAPPING_STROKE_WIDTH, SNAP_TOLERANCE, SPACE, Selection, SoftThemeColor, StarryThemeColor, T, TAB, THREE, TILDE, TWO, ThemeColorMode, ThemeColors, Transforms, U, UP_ARROW, V, VOLUME_DOWN, VOLUME_UP, Viewport, W, WritableClipboardType, X, Y, Z, ZERO, addClipboardContext, addSelectedElement, approximately, arrowPoints, buildPlaitHtml, cacheMovingElements, cacheSelectedElements, cacheSelectedElementsWithGroup, cacheSelectedElementsWithGroupOnShift, calcNewViewBox, canAddGroup, canRemoveGroup, canSetZIndex, catmullRomFitting, clampZoomLevel, clearNodeWeakMap, clearSelectedElement, clearSelectionMoving, clearViewportOrigination, createClipboardContext, createDebugGenerator, createFakeEvent, createForeignObject, createG, createGroup, createGroupRectangleG, createKeyboardEvent, createMask, createModModifierKeys, createMouseEvent, createPath, createPointerEvent, createRect, createSVG, createTestingBoard, createText, createTouchEvent, debounce, degreesToRadians, deleteFragment, deleteTemporaryElements, depthFirstRecursion, distanceBetweenPointAndPoint, distanceBetweenPointAndRectangle, distanceBetweenPointAndSegment, distanceBetweenPointAndSegments, downloadImage, drawArrow, drawBezierPath, drawCircle, drawDashedLines, drawEntireActiveRectangleG, drawLine, drawLinearPath, drawPendingNodesG, drawPointSnapLines, drawRectangle, drawRoundRectangle, drawSolidLines, duplicateElements, fakeNodeWeakMap, filterSelectedGroups, findElements, findIndex, findLastIndex, getAllElementsInGroup, getAllMoveOptions, getAngleBetweenPoints, getAngleByElement, getBarPoint, getBoardRectangle, getClipboardData, getClipboardFromHtml, getCrossingPointsBetweenEllipseAndSegment, getDataTransferClipboard, getDataTransferClipboardText, getEditingGroup, getElementById, getElementHostBBox, getElementsInGroup, getElementsInGroupByElement, getElementsIndices, getEllipseTangentSlope, getGroupByElement, getHighestGroup, getHighestIndexOfElement, getHighestSelectedElements, getHighestSelectedGroup, getHighestSelectedGroups, getHitElementByPoint, getHitElementsBySelection, getHitSelectedElements, getIsRecursionFunc, getMinPointDelta, getMovingElements, getNearestDelta, getNearestPointBetweenPointAndEllipse, getNearestPointBetweenPointAndSegment, getNearestPointBetweenPointAndSegments, getNearestPointRectangle, getOffsetAfterRotate, getOneMoveOptions, getProbablySupportsClipboardRead, getProbablySupportsClipboardWrite, getProbablySupportsClipboardWriteText, getRealScrollBarWidth, getRectangleByAngle, getRectangleByElements, getRectangleByGroup, getRotatedBoundingRectangle, getSelectedElements, getSelectedGroups, getSelectedIsolatedElements, getSelectedIsolatedElementsCanAddToGroup, getSelectedTargetElements, getSelectionAngle, getSnapRectangles, getTemporaryElements, getTemporaryRef, getTripleAxis, getValidElements, getVectorFromPointAndSlope, getViewBox, getViewBoxCenterPoint, getViewportContainerRect, getViewportOrigination, handleTouchTarget, hasBeforeContextChange, hasInputOrTextareaTarget, hasOnBoardChange, hasOnContextChanged, hasSameAngle, hasSelectedElementsInSameGroup, hasValidAngle, hotkeys, idCreator, initializeViewBox, initializeViewportContainer, initializeViewportOffset, inverse, isAxisChangedByAngle, isContextmenu, isDOMElement, isDOMNode, isDebug, isDragging, isFromScrolling, isFromViewportChange, isHandleSelection, isInPlaitBoard, isIndicesContinuous, isLineHitLine, isMainPointer, isMovingElements, isNullOrUndefined, isPointInEllipse, isPointInPolygon, isPointInRoundRectangle, isPolylineHitRectangle, isPreventTouchMove, isSecondaryPointer, isSelectedAllElementsInGroup, isSelectedElement, isSelectedElementOrGroup, isSelectionMoving, isSetSelectionOperation, isSetViewportOperation, isSnapPoint, moveElementsToNewPath, moveElementsToNewPathAfterAddGroup, nonGroupInHighestSelectedElements, normalizeAngle, normalizePoint, preventTouchMove, radiansToDegrees, removeMovingElements, removeSelectedElement, rotate, rotateAntiPointsByElement, rotateElements, rotatePoints, rotatePointsByElement, rotatedDataPoints, scrollToRectangle, setAngleForG, setClipboardData, setDataTransferClipboard, setDataTransferClipboardText, setDragging, setFragment, setIsFromScrolling, setIsFromViewportChange, setPathStrokeLinecap, setSVGViewBox, setSelectedElementsWithGroup, setSelectionMoving, setStrokeLinecap, shouldClear, shouldMerge, shouldSave, sortElements, stripHtml, temporaryDisableSelection, throttleRAF, toDomPrecision, toFixed, toHostPoint, toHostPointFromViewBoxPoint, toImage, toScreenPointFromHostPoint, toViewBoxPoint, toViewBoxPoints, uniqueById, updateForeignObject, updateForeignObjectWidth, updatePoints, updateViewportByScrolling, updateViewportContainerScroll, updateViewportOffset, updateViewportOrigination, withArrowMoving, withMoving, withOptions, withSelection };
6186
6341
  //# sourceMappingURL=plait-core.mjs.map