@excalidraw/element 0.18.0-b7aac689a → 0.18.0-b9d27d3

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 (53) hide show
  1. package/dist/dev/index.js +913 -578
  2. package/dist/dev/index.js.map +4 -4
  3. package/dist/prod/index.js +14 -14
  4. package/dist/types/common/src/constants.d.ts +13 -3
  5. package/dist/types/element/src/Scene.d.ts +6 -2
  6. package/dist/types/element/src/align.d.ts +2 -1
  7. package/dist/types/element/src/bounds.d.ts +1 -1
  8. package/dist/types/element/src/delta.d.ts +16 -4
  9. package/dist/types/element/src/distribute.d.ts +2 -1
  10. package/dist/types/element/src/groups.d.ts +1 -0
  11. package/dist/types/element/src/index.d.ts +1 -0
  12. package/dist/types/element/src/linearElementEditor.d.ts +2 -1
  13. package/dist/types/element/src/positionElementsOnGrid.d.ts +2 -0
  14. package/dist/types/element/src/store.d.ts +6 -1
  15. package/dist/types/element/src/textElement.d.ts +1 -1
  16. package/dist/types/excalidraw/actions/actionAddToLibrary.d.ts +0 -3
  17. package/dist/types/excalidraw/actions/actionBoundText.d.ts +0 -2
  18. package/dist/types/excalidraw/actions/actionCanvas.d.ts +15 -14
  19. package/dist/types/excalidraw/actions/actionClipboard.d.ts +3 -8
  20. package/dist/types/excalidraw/actions/actionCropEditor.d.ts +0 -1
  21. package/dist/types/excalidraw/actions/actionDeleteSelected.d.ts +3 -6
  22. package/dist/types/excalidraw/actions/actionElementLink.d.ts +0 -1
  23. package/dist/types/excalidraw/actions/actionElementLock.d.ts +0 -2
  24. package/dist/types/excalidraw/actions/actionEmbeddable.d.ts +0 -1
  25. package/dist/types/excalidraw/actions/actionExport.d.ts +0 -9
  26. package/dist/types/excalidraw/actions/actionFinalize.d.ts +2 -3
  27. package/dist/types/excalidraw/actions/actionFrame.d.ts +0 -4
  28. package/dist/types/excalidraw/actions/actionGroup.d.ts +0 -2
  29. package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +33 -3
  30. package/dist/types/excalidraw/actions/actionLink.d.ts +0 -1
  31. package/dist/types/excalidraw/actions/actionMenu.d.ts +0 -3
  32. package/dist/types/excalidraw/actions/actionNavigate.d.ts +0 -2
  33. package/dist/types/excalidraw/actions/actionProperties.d.ts +0 -15
  34. package/dist/types/excalidraw/actions/actionSelectAll.d.ts +0 -1
  35. package/dist/types/excalidraw/actions/actionStyles.d.ts +0 -1
  36. package/dist/types/excalidraw/actions/actionToggleGridMode.d.ts +0 -1
  37. package/dist/types/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +0 -1
  38. package/dist/types/excalidraw/actions/actionToggleSearchMenu.d.ts +0 -1
  39. package/dist/types/excalidraw/actions/actionToggleStats.d.ts +0 -1
  40. package/dist/types/excalidraw/actions/actionToggleViewMode.d.ts +0 -1
  41. package/dist/types/excalidraw/actions/actionToggleZenMode.d.ts +0 -1
  42. package/dist/types/excalidraw/clipboard.d.ts +62 -1
  43. package/dist/types/excalidraw/components/Actions.d.ts +0 -4
  44. package/dist/types/excalidraw/components/App.d.ts +11 -8
  45. package/dist/types/excalidraw/components/Ellipsify.d.ts +4 -0
  46. package/dist/types/excalidraw/components/shapes.d.ts +129 -1
  47. package/dist/types/excalidraw/data/blob.d.ts +1 -5
  48. package/dist/types/excalidraw/data/reconcile.d.ts +1 -0
  49. package/dist/types/excalidraw/data/restore.d.ts +6 -1
  50. package/dist/types/excalidraw/index.d.ts +2 -1
  51. package/dist/types/excalidraw/renderer/staticScene.d.ts +4 -1
  52. package/dist/types/excalidraw/types.d.ts +7 -4
  53. package/package.json +3 -3
package/dist/dev/index.js CHANGED
@@ -2269,9 +2269,9 @@ import {
2269
2269
  degreesToRadians,
2270
2270
  lineSegment as lineSegment5,
2271
2271
  pointDistance as pointDistance7,
2272
- pointFrom as pointFrom12,
2272
+ pointFrom as pointFrom13,
2273
2273
  pointFromArray as pointFromArray3,
2274
- pointRotateRads as pointRotateRads10
2274
+ pointRotateRads as pointRotateRads11
2275
2275
  } from "@excalidraw/math";
2276
2276
 
2277
2277
  // ../utils/src/shape.ts
@@ -2448,9 +2448,9 @@ var getClosedCurveShape = (element, roughShape, startingPoint = pointFrom(0, 0),
2448
2448
  // src/shape.ts
2449
2449
  init_define_import_meta_env();
2450
2450
  import {
2451
- pointFrom as pointFrom11,
2451
+ pointFrom as pointFrom12,
2452
2452
  pointDistance as pointDistance6,
2453
- pointRotateRads as pointRotateRads9
2453
+ pointRotateRads as pointRotateRads10
2454
2454
  } from "@excalidraw/math";
2455
2455
  import {
2456
2456
  ROUGHNESS,
@@ -3103,8 +3103,8 @@ var getFlipAdjustedCropPosition = (element, natural = false) => {
3103
3103
  init_define_import_meta_env();
3104
3104
  import {
3105
3105
  pointCenter as pointCenter2,
3106
- pointFrom as pointFrom8,
3107
- pointRotateRads as pointRotateRads7,
3106
+ pointFrom as pointFrom9,
3107
+ pointRotateRads as pointRotateRads8,
3108
3108
  pointsEqual as pointsEqual6,
3109
3109
  pointDistance as pointDistance5,
3110
3110
  vectorFromPoint as vectorFromPoint7,
@@ -3138,8 +3138,8 @@ import {
3138
3138
  } from "@excalidraw/common";
3139
3139
  import {
3140
3140
  lineSegment as lineSegment4,
3141
- pointFrom as pointFrom7,
3142
- pointRotateRads as pointRotateRads6,
3141
+ pointFrom as pointFrom8,
3142
+ pointRotateRads as pointRotateRads7,
3143
3143
  vectorFromPoint as vectorFromPoint6,
3144
3144
  pointDistanceSq,
3145
3145
  clamp as clamp3,
@@ -3161,9 +3161,9 @@ import {
3161
3161
  isPointWithinBounds,
3162
3162
  lineSegment as lineSegment3,
3163
3163
  lineSegmentIntersectionPoints,
3164
- pointFrom as pointFrom4,
3164
+ pointFrom as pointFrom5,
3165
3165
  pointFromVector as pointFromVector3,
3166
- pointRotateRads as pointRotateRads4,
3166
+ pointRotateRads as pointRotateRads5,
3167
3167
  pointsEqual as pointsEqual2,
3168
3168
  vectorFromPoint as vectorFromPoint3,
3169
3169
  vectorNormalize as vectorNormalize2,
@@ -3711,6 +3711,7 @@ import {
3711
3711
  isProdEnv,
3712
3712
  invariant as invariant2
3713
3713
  } from "@excalidraw/common";
3714
+ import { pointFrom as pointFrom4, pointRotateRads as pointRotateRads3 } from "@excalidraw/math";
3714
3715
 
3715
3716
  // src/containerCache.ts
3716
3717
  init_define_import_meta_env();
@@ -4390,6 +4391,22 @@ var computeBoundTextPosition = (container, boundTextElement, elementsMap) => {
4390
4391
  } else {
4391
4392
  x = containerCoords.x + (maxContainerWidth / 2 - boundTextElement.width / 2);
4392
4393
  }
4394
+ const angle = container.angle ?? 0;
4395
+ if (angle !== 0) {
4396
+ const contentCenter = pointFrom4(
4397
+ containerCoords.x + maxContainerWidth / 2,
4398
+ containerCoords.y + maxContainerHeight / 2
4399
+ );
4400
+ const textCenter = pointFrom4(
4401
+ x + boundTextElement.width / 2,
4402
+ y + boundTextElement.height / 2
4403
+ );
4404
+ const [rx, ry] = pointRotateRads3(textCenter, contentCenter, angle);
4405
+ return {
4406
+ x: rx - boundTextElement.width / 2,
4407
+ y: ry - boundTextElement.height / 2
4408
+ };
4409
+ }
4393
4410
  return { x, y };
4394
4411
  };
4395
4412
  var getBoundTextElementId = (container) => {
@@ -4573,7 +4590,7 @@ init_define_import_meta_env();
4573
4590
  import {
4574
4591
  curvePointDistance,
4575
4592
  distanceToLineSegment,
4576
- pointRotateRads as pointRotateRads3
4593
+ pointRotateRads as pointRotateRads4
4577
4594
  } from "@excalidraw/math";
4578
4595
  import { ellipse as ellipse2, ellipseDistanceFromPoint } from "@excalidraw/math/ellipse";
4579
4596
  var distanceToElement = (element, elementsMap, p) => {
@@ -4599,7 +4616,7 @@ var distanceToElement = (element, elementsMap, p) => {
4599
4616
  };
4600
4617
  var distanceToRectanguloidElement = (element, elementsMap, p) => {
4601
4618
  const center = elementCenterPoint(element, elementsMap);
4602
- const rotatedPoint = pointRotateRads3(p, center, -element.angle);
4619
+ const rotatedPoint = pointRotateRads4(p, center, -element.angle);
4603
4620
  const [sides, corners] = deconstructRectanguloidElement(element);
4604
4621
  return Math.min(
4605
4622
  ...sides.map((s) => distanceToLineSegment(rotatedPoint, s)),
@@ -4608,7 +4625,7 @@ var distanceToRectanguloidElement = (element, elementsMap, p) => {
4608
4625
  };
4609
4626
  var distanceToDiamondElement = (element, elementsMap, p) => {
4610
4627
  const center = elementCenterPoint(element, elementsMap);
4611
- const rotatedPoint = pointRotateRads3(p, center, -element.angle);
4628
+ const rotatedPoint = pointRotateRads4(p, center, -element.angle);
4612
4629
  const [sides, curves] = deconstructDiamondElement(element);
4613
4630
  return Math.min(
4614
4631
  ...sides.map((s) => distanceToLineSegment(rotatedPoint, s)),
@@ -4619,7 +4636,7 @@ var distanceToEllipseElement = (element, elementsMap, p) => {
4619
4636
  const center = elementCenterPoint(element, elementsMap);
4620
4637
  return ellipseDistanceFromPoint(
4621
4638
  // Instead of rotating the ellipse, rotate the point to the inverse angle
4622
- pointRotateRads3(p, center, -element.angle),
4639
+ pointRotateRads4(p, center, -element.angle),
4623
4640
  ellipse2(center, element.width / 2, element.height / 2)
4624
4641
  );
4625
4642
  };
@@ -4653,22 +4670,22 @@ var hitElementItself = ({
4653
4670
  frameNameBound = null
4654
4671
  }) => {
4655
4672
  const hitFrameName = frameNameBound ? isPointWithinBounds(
4656
- pointFrom4(frameNameBound.x - threshold, frameNameBound.y - threshold),
4673
+ pointFrom5(frameNameBound.x - threshold, frameNameBound.y - threshold),
4657
4674
  point,
4658
- pointFrom4(
4675
+ pointFrom5(
4659
4676
  frameNameBound.x + frameNameBound.width + threshold,
4660
4677
  frameNameBound.y + frameNameBound.height + threshold
4661
4678
  )
4662
4679
  ) : false;
4663
4680
  const bounds = getElementBounds(element, elementsMap, true);
4664
4681
  const hitBounds = isPointWithinBounds(
4665
- pointFrom4(bounds[0] - threshold, bounds[1] - threshold),
4666
- pointRotateRads4(
4682
+ pointFrom5(bounds[0] - threshold, bounds[1] - threshold),
4683
+ pointRotateRads5(
4667
4684
  point,
4668
4685
  getCenterForBounds(bounds),
4669
4686
  -element.angle
4670
4687
  ),
4671
- pointFrom4(bounds[2] + threshold, bounds[3] + threshold)
4688
+ pointFrom5(bounds[2] + threshold, bounds[3] + threshold)
4672
4689
  );
4673
4690
  if (!hitBounds && !hitFrameName) {
4674
4691
  return false;
@@ -4686,7 +4703,7 @@ var hitElementBoundingBox = (point, element, elementsMap, tolerance = 0) => {
4686
4703
  y1 -= tolerance;
4687
4704
  x2 += tolerance;
4688
4705
  y2 += tolerance;
4689
- return isPointWithinBounds(pointFrom4(x1, y1), point, pointFrom4(x2, y2));
4706
+ return isPointWithinBounds(pointFrom5(x1, y1), point, pointFrom5(x2, y2));
4690
4707
  };
4691
4708
  var hitElementBoundingBoxOnly = (hitArgs, elementsMap) => !hitElementItself(hitArgs) && // bound text is considered part of the element (even if it's outside the bounding box)
4692
4709
  !hitElementBoundText(hitArgs.point, hitArgs.element, elementsMap) && hitElementBoundingBox(hitArgs.point, hitArgs.element, elementsMap);
@@ -4770,7 +4787,7 @@ var curveIntersections = (curves, segment, intersections, center, angle, onlyFir
4770
4787
  const hits = curveIntersectLineSegment(c, segment);
4771
4788
  if (hits.length > 0) {
4772
4789
  for (const j of hits) {
4773
- intersections.push(pointRotateRads4(j, center, angle));
4790
+ intersections.push(pointRotateRads5(j, center, angle));
4774
4791
  }
4775
4792
  if (onlyFirst) {
4776
4793
  return intersections;
@@ -4783,7 +4800,7 @@ var lineIntersections = (lines, segment, intersections, center, angle, onlyFirst
4783
4800
  for (const l2 of lines) {
4784
4801
  const intersection = lineSegmentIntersectionPoints(l2, segment);
4785
4802
  if (intersection) {
4786
- intersections.push(pointRotateRads4(intersection, center, angle));
4803
+ intersections.push(pointRotateRads5(intersection, center, angle));
4787
4804
  if (onlyFirst) {
4788
4805
  return intersections;
4789
4806
  }
@@ -4826,12 +4843,12 @@ var intersectLinearOrFreeDrawWithLineSegment = (element, segment, onlyFirst = fa
4826
4843
  };
4827
4844
  var intersectRectanguloidWithLineSegment = (element, elementsMap, segment, offset = 0, onlyFirst = false) => {
4828
4845
  const center = elementCenterPoint(element, elementsMap);
4829
- const rotatedA = pointRotateRads4(
4846
+ const rotatedA = pointRotateRads5(
4830
4847
  segment[0],
4831
4848
  center,
4832
4849
  -element.angle
4833
4850
  );
4834
- const rotatedB = pointRotateRads4(
4851
+ const rotatedB = pointRotateRads5(
4835
4852
  segment[1],
4836
4853
  center,
4837
4854
  -element.angle
@@ -4862,8 +4879,8 @@ var intersectRectanguloidWithLineSegment = (element, elementsMap, segment, offse
4862
4879
  };
4863
4880
  var intersectDiamondWithLineSegment = (element, elementsMap, l2, offset = 0, onlyFirst = false) => {
4864
4881
  const center = elementCenterPoint(element, elementsMap);
4865
- const rotatedA = pointRotateRads4(l2[0], center, -element.angle);
4866
- const rotatedB = pointRotateRads4(l2[1], center, -element.angle);
4882
+ const rotatedA = pointRotateRads5(l2[0], center, -element.angle);
4883
+ const rotatedB = pointRotateRads5(l2[1], center, -element.angle);
4867
4884
  const rotatedIntersector = lineSegment3(rotatedA, rotatedB);
4868
4885
  const [sides, corners] = deconstructDiamondElement(element, offset);
4869
4886
  const intersections = [];
@@ -4890,12 +4907,12 @@ var intersectDiamondWithLineSegment = (element, elementsMap, l2, offset = 0, onl
4890
4907
  };
4891
4908
  var intersectEllipseWithLineSegment = (element, elementsMap, l2, offset = 0) => {
4892
4909
  const center = elementCenterPoint(element, elementsMap);
4893
- const rotatedA = pointRotateRads4(l2[0], center, -element.angle);
4894
- const rotatedB = pointRotateRads4(l2[1], center, -element.angle);
4910
+ const rotatedA = pointRotateRads5(l2[0], center, -element.angle);
4911
+ const rotatedB = pointRotateRads5(l2[1], center, -element.angle);
4895
4912
  return ellipseSegmentInterceptPoints(
4896
4913
  ellipse3(center, element.width / 2 + offset, element.height / 2 + offset),
4897
4914
  lineSegment3(rotatedA, rotatedB)
4898
- ).map((p) => pointRotateRads4(p, center, element.angle));
4915
+ ).map((p) => pointRotateRads5(p, center, element.angle));
4899
4916
  };
4900
4917
  var isPointOnElementOutline = (point, element, elementsMap, tolerance = 1) => distanceToElement(element, elementsMap, point) <= tolerance;
4901
4918
  var isPointInElement = (point, element, elementsMap) => {
@@ -4903,10 +4920,10 @@ var isPointInElement = (point, element, elementsMap) => {
4903
4920
  return false;
4904
4921
  }
4905
4922
  const [x1, y1, x2, y2] = getElementBounds(element, elementsMap);
4906
- if (!isPointWithinBounds(pointFrom4(x1, y1), point, pointFrom4(x2, y2))) {
4923
+ if (!isPointWithinBounds(pointFrom5(x1, y1), point, pointFrom5(x2, y2))) {
4907
4924
  return false;
4908
4925
  }
4909
- const center = pointFrom4((x1 + x2) / 2, (y1 + y2) / 2);
4926
+ const center = pointFrom5((x1 + x2) / 2, (y1 + y2) / 2);
4910
4927
  const otherPoint = pointFromVector3(
4911
4928
  vectorScale3(
4912
4929
  vectorNormalize2(vectorFromPoint3(point, center, 0.1)),
@@ -4927,9 +4944,9 @@ var isPointInElement = (point, element, elementsMap) => {
4927
4944
  init_define_import_meta_env();
4928
4945
  import { invariant as invariant3, isDevEnv as isDevEnv2, isTestEnv as isTestEnv3 } from "@excalidraw/common";
4929
4946
  import {
4930
- pointFrom as pointFrom5,
4947
+ pointFrom as pointFrom6,
4931
4948
  pointFromVector as pointFromVector4,
4932
- pointRotateRads as pointRotateRads5,
4949
+ pointRotateRads as pointRotateRads6,
4933
4950
  pointScaleFromOrigin,
4934
4951
  pointsEqual as pointsEqual3,
4935
4952
  triangleIncludesPoint,
@@ -4975,8 +4992,8 @@ var headingForPointFromDiamondElement = (element, aabb, point) => {
4975
4992
  const top = pointFromVector4(
4976
4993
  vectorScale4(
4977
4994
  vectorFromPoint4(
4978
- pointRotateRads5(
4979
- pointFrom5(element.x + element.width / 2, element.y),
4995
+ pointRotateRads6(
4996
+ pointFrom6(element.x + element.width / 2, element.y),
4980
4997
  midPoint,
4981
4998
  element.angle
4982
4999
  ),
@@ -4989,8 +5006,8 @@ var headingForPointFromDiamondElement = (element, aabb, point) => {
4989
5006
  const right = pointFromVector4(
4990
5007
  vectorScale4(
4991
5008
  vectorFromPoint4(
4992
- pointRotateRads5(
4993
- pointFrom5(
5009
+ pointRotateRads6(
5010
+ pointFrom6(
4994
5011
  element.x + element.width,
4995
5012
  element.y + element.height / 2
4996
5013
  ),
@@ -5006,8 +5023,8 @@ var headingForPointFromDiamondElement = (element, aabb, point) => {
5006
5023
  const bottom = pointFromVector4(
5007
5024
  vectorScale4(
5008
5025
  vectorFromPoint4(
5009
- pointRotateRads5(
5010
- pointFrom5(
5026
+ pointRotateRads6(
5027
+ pointFrom6(
5011
5028
  element.x + element.width / 2,
5012
5029
  element.y + element.height
5013
5030
  ),
@@ -5023,8 +5040,8 @@ var headingForPointFromDiamondElement = (element, aabb, point) => {
5023
5040
  const left = pointFromVector4(
5024
5041
  vectorScale4(
5025
5042
  vectorFromPoint4(
5026
- pointRotateRads5(
5027
- pointFrom5(element.x, element.y + element.height / 2),
5043
+ pointRotateRads6(
5044
+ pointFrom6(element.x, element.y + element.height / 2),
5028
5045
  midPoint,
5029
5046
  element.angle
5030
5047
  ),
@@ -5090,22 +5107,22 @@ var headingForPointFromElement = (element, aabb, p) => {
5090
5107
  return headingForPointFromDiamondElement(element, aabb, p);
5091
5108
  }
5092
5109
  const topLeft = pointScaleFromOrigin(
5093
- pointFrom5(aabb[0], aabb[1]),
5110
+ pointFrom6(aabb[0], aabb[1]),
5094
5111
  midPoint,
5095
5112
  SEARCH_CONE_MULTIPLIER
5096
5113
  );
5097
5114
  const topRight = pointScaleFromOrigin(
5098
- pointFrom5(aabb[2], aabb[1]),
5115
+ pointFrom6(aabb[2], aabb[1]),
5099
5116
  midPoint,
5100
5117
  SEARCH_CONE_MULTIPLIER
5101
5118
  );
5102
5119
  const bottomLeft = pointScaleFromOrigin(
5103
- pointFrom5(aabb[0], aabb[3]),
5120
+ pointFrom6(aabb[0], aabb[3]),
5104
5121
  midPoint,
5105
5122
  SEARCH_CONE_MULTIPLIER
5106
5123
  );
5107
5124
  const bottomRight = pointScaleFromOrigin(
5108
- pointFrom5(aabb[2], aabb[3]),
5125
+ pointFrom6(aabb[2], aabb[3]),
5109
5126
  midPoint,
5110
5127
  SEARCH_CONE_MULTIPLIER
5111
5128
  );
@@ -5138,7 +5155,7 @@ init_define_import_meta_env();
5138
5155
  import {
5139
5156
  clamp as clamp2,
5140
5157
  pointDistance as pointDistance3,
5141
- pointFrom as pointFrom6,
5158
+ pointFrom as pointFrom7,
5142
5159
  pointScaleFromOrigin as pointScaleFromOrigin2,
5143
5160
  pointsEqual as pointsEqual4,
5144
5161
  pointTranslate,
@@ -5162,7 +5179,7 @@ var handleSegmentRenormalization = (arrow, elementsMap) => {
5162
5179
  const nextFixedSegments = arrow.fixedSegments ? arrow.fixedSegments.slice() : null;
5163
5180
  if (nextFixedSegments) {
5164
5181
  const _nextPoints = [];
5165
- arrow.points.map((p) => pointFrom6(arrow.x + p[0], arrow.y + p[1])).forEach((p, i, points) => {
5182
+ arrow.points.map((p) => pointFrom7(arrow.x + p[0], arrow.y + p[1])).forEach((p, i, points) => {
5166
5183
  if (i < 2) {
5167
5184
  return _nextPoints.push(p);
5168
5185
  }
@@ -5180,7 +5197,7 @@ var handleSegmentRenormalization = (arrow, elementsMap) => {
5180
5197
  ) ?? -1;
5181
5198
  const segmentIdx = nextFixedSegments?.findIndex((segment) => segment.index === i) ?? -1;
5182
5199
  if (segmentIdx !== -1) {
5183
- nextFixedSegments[segmentIdx].start = pointFrom6(
5200
+ nextFixedSegments[segmentIdx].start = pointFrom7(
5184
5201
  points[i - 2][0] - arrow.x,
5185
5202
  points[i - 2][1] - arrow.y
5186
5203
  );
@@ -5222,7 +5239,7 @@ var handleSegmentRenormalization = (arrow, elementsMap) => {
5222
5239
  });
5223
5240
  const isHorizontal = headingForPointIsHorizontal(p, points[i - 1]);
5224
5241
  return nextPoints.push(
5225
- pointFrom6(
5242
+ pointFrom7(
5226
5243
  !isHorizontal ? points[i - 2][0] : p[0],
5227
5244
  isHorizontal ? points[i - 2][1] : p[1]
5228
5245
  )
@@ -5243,7 +5260,7 @@ var handleSegmentRenormalization = (arrow, elementsMap) => {
5243
5260
  arrow,
5244
5261
  elementsMap,
5245
5262
  nextPoints.map(
5246
- (p) => pointFrom6(p[0] - arrow.x, p[1] - arrow.y)
5263
+ (p) => pointFrom7(p[0] - arrow.x, p[1] - arrow.y)
5247
5264
  )
5248
5265
  )
5249
5266
  ) ?? []
@@ -5312,8 +5329,8 @@ var handleSegmentRelease = (arrow, fixedSegments, elementsMap) => {
5312
5329
  },
5313
5330
  elementsMap,
5314
5331
  [
5315
- pointFrom6(0, 0),
5316
- pointFrom6(
5332
+ pointFrom7(0, 0),
5333
+ pointFrom7(
5317
5334
  arrow.x + (nextSegment?.start[0] ?? arrow.points[arrow.points.length - 1][0]) - x,
5318
5335
  arrow.y + (nextSegment?.start[1] ?? arrow.points[arrow.points.length - 1][1]) - y
5319
5336
  )
@@ -5338,11 +5355,16 @@ var handleSegmentRelease = (arrow, fixedSegments, elementsMap) => {
5338
5355
  null,
5339
5356
  null
5340
5357
  );
5358
+ if (!restoredPoints || restoredPoints.length < 2) {
5359
+ throw new Error(
5360
+ "Property 'points' is required in the update returned by normalizeArrowElementUpdate()"
5361
+ );
5362
+ }
5341
5363
  const nextPoints = [];
5342
5364
  if (prevSegment) {
5343
5365
  for (let i = 0; i < prevSegment.index; i++) {
5344
5366
  nextPoints.push(
5345
- pointFrom6(
5367
+ pointFrom7(
5346
5368
  arrow.x + arrow.points[i][0],
5347
5369
  arrow.y + arrow.points[i][1]
5348
5370
  )
@@ -5351,7 +5373,7 @@ var handleSegmentRelease = (arrow, fixedSegments, elementsMap) => {
5351
5373
  }
5352
5374
  restoredPoints.forEach((p) => {
5353
5375
  nextPoints.push(
5354
- pointFrom6(
5376
+ pointFrom7(
5355
5377
  arrow.x + (prevSegment ? prevSegment.end[0] : 0) + p[0],
5356
5378
  arrow.y + (prevSegment ? prevSegment.end[1] : 0) + p[1]
5357
5379
  )
@@ -5360,7 +5382,7 @@ var handleSegmentRelease = (arrow, fixedSegments, elementsMap) => {
5360
5382
  if (nextSegment) {
5361
5383
  for (let i = nextSegment.index; i < arrow.points.length; i++) {
5362
5384
  nextPoints.push(
5363
- pointFrom6(
5385
+ pointFrom7(
5364
5386
  arrow.x + arrow.points[i][0],
5365
5387
  arrow.y + arrow.points[i][1]
5366
5388
  )
@@ -5431,7 +5453,7 @@ var handleSegmentMove = (arrow, fixedSegments, startHeading, endHeading, hovered
5431
5453
  const startIsHorizontal = headingIsHorizontal(startHeading);
5432
5454
  const startIsPositive = startIsHorizontal ? compareHeading(startHeading, HEADING_RIGHT) : compareHeading(startHeading, HEADING_DOWN);
5433
5455
  const padding = startIsPositive ? segmentIsTooShort ? segmentLength / 2 : BASE_PADDING : segmentIsTooShort ? -segmentLength / 2 : -BASE_PADDING;
5434
- fixedSegments[activelyModifiedSegmentIdx].start = pointFrom6(
5456
+ fixedSegments[activelyModifiedSegmentIdx].start = pointFrom7(
5435
5457
  fixedSegments[activelyModifiedSegmentIdx].start[0] + (startIsHorizontal ? padding : 0),
5436
5458
  fixedSegments[activelyModifiedSegmentIdx].start[1] + (!startIsHorizontal ? padding : 0)
5437
5459
  );
@@ -5440,24 +5462,24 @@ var handleSegmentMove = (arrow, fixedSegments, startHeading, endHeading, hovered
5440
5462
  const endIsHorizontal = headingIsHorizontal(endHeading);
5441
5463
  const endIsPositive = endIsHorizontal ? compareHeading(endHeading, HEADING_RIGHT) : compareHeading(endHeading, HEADING_DOWN);
5442
5464
  const padding = endIsPositive ? segmentIsTooShort ? segmentLength / 2 : BASE_PADDING : segmentIsTooShort ? -segmentLength / 2 : -BASE_PADDING;
5443
- fixedSegments[activelyModifiedSegmentIdx].end = pointFrom6(
5465
+ fixedSegments[activelyModifiedSegmentIdx].end = pointFrom7(
5444
5466
  fixedSegments[activelyModifiedSegmentIdx].end[0] + (endIsHorizontal ? padding : 0),
5445
5467
  fixedSegments[activelyModifiedSegmentIdx].end[1] + (!endIsHorizontal ? padding : 0)
5446
5468
  );
5447
5469
  }
5448
5470
  const nextFixedSegments = fixedSegments.map((segment) => ({
5449
5471
  ...segment,
5450
- start: pointFrom6(
5472
+ start: pointFrom7(
5451
5473
  arrow.x + segment.start[0],
5452
5474
  arrow.y + segment.start[1]
5453
5475
  ),
5454
- end: pointFrom6(
5476
+ end: pointFrom7(
5455
5477
  arrow.x + segment.end[0],
5456
5478
  arrow.y + segment.end[1]
5457
5479
  )
5458
5480
  }));
5459
5481
  const newPoints = arrow.points.map(
5460
- (p, i) => pointFrom6(arrow.x + p[0], arrow.y + p[1])
5482
+ (p, i) => pointFrom7(arrow.x + p[0], arrow.y + p[1])
5461
5483
  );
5462
5484
  const startIdx = nextFixedSegments[activelyModifiedSegmentIdx].index - 1;
5463
5485
  const endIdx = nextFixedSegments[activelyModifiedSegmentIdx].index;
@@ -5503,14 +5525,14 @@ var handleSegmentMove = (arrow, fixedSegments, startHeading, endHeading, hovered
5503
5525
  if (firstSegmentIdx === -1 && startIdx === 0) {
5504
5526
  const startIsHorizontal = hoveredStartElement ? headingIsHorizontal(startHeading) : headingForPointIsHorizontal(newPoints[1], newPoints[0]);
5505
5527
  newPoints.unshift(
5506
- pointFrom6(
5528
+ pointFrom7(
5507
5529
  startIsHorizontal ? start[0] : arrow.x + arrow.points[0][0],
5508
5530
  !startIsHorizontal ? start[1] : arrow.y + arrow.points[0][1]
5509
5531
  )
5510
5532
  );
5511
5533
  if (hoveredStartElement) {
5512
5534
  newPoints.unshift(
5513
- pointFrom6(
5535
+ pointFrom7(
5514
5536
  arrow.x + arrow.points[0][0],
5515
5537
  arrow.y + arrow.points[0][1]
5516
5538
  )
@@ -5523,14 +5545,14 @@ var handleSegmentMove = (arrow, fixedSegments, startHeading, endHeading, hovered
5523
5545
  if (lastSegmentIdx === -1 && endIdx === arrow.points.length - 1) {
5524
5546
  const endIsHorizontal = headingIsHorizontal(endHeading);
5525
5547
  newPoints.push(
5526
- pointFrom6(
5548
+ pointFrom7(
5527
5549
  endIsHorizontal ? end[0] : arrow.x + arrow.points[arrow.points.length - 1][0],
5528
5550
  !endIsHorizontal ? end[1] : arrow.y + arrow.points[arrow.points.length - 1][1]
5529
5551
  )
5530
5552
  );
5531
5553
  if (hoveredEndElement) {
5532
5554
  newPoints.push(
5533
- pointFrom6(
5555
+ pointFrom7(
5534
5556
  arrow.x + arrow.points[arrow.points.length - 1][0],
5535
5557
  arrow.y + arrow.points[arrow.points.length - 1][1]
5536
5558
  )
@@ -5541,11 +5563,11 @@ var handleSegmentMove = (arrow, fixedSegments, startHeading, endHeading, hovered
5541
5563
  newPoints,
5542
5564
  nextFixedSegments.map((segment) => ({
5543
5565
  ...segment,
5544
- start: pointFrom6(
5566
+ start: pointFrom7(
5545
5567
  segment.start[0] - arrow.x,
5546
5568
  segment.start[1] - arrow.y
5547
5569
  ),
5548
- end: pointFrom6(
5570
+ end: pointFrom7(
5549
5571
  segment.end[0] - arrow.x,
5550
5572
  segment.end[1] - arrow.y
5551
5573
  )
@@ -5560,18 +5582,18 @@ var handleEndpointDrag = (arrow, updatedPoints, fixedSegments, startHeading, end
5560
5582
  let startIsSpecial = arrow.startIsSpecial ?? null;
5561
5583
  let endIsSpecial = arrow.endIsSpecial ?? null;
5562
5584
  const globalUpdatedPoints = updatedPoints.map(
5563
- (p, i) => i === 0 ? pointFrom6(arrow.x + p[0], arrow.y + p[1]) : i === updatedPoints.length - 1 ? pointFrom6(arrow.x + p[0], arrow.y + p[1]) : pointFrom6(
5585
+ (p, i) => i === 0 ? pointFrom7(arrow.x + p[0], arrow.y + p[1]) : i === updatedPoints.length - 1 ? pointFrom7(arrow.x + p[0], arrow.y + p[1]) : pointFrom7(
5564
5586
  arrow.x + arrow.points[i][0],
5565
5587
  arrow.y + arrow.points[i][1]
5566
5588
  )
5567
5589
  );
5568
5590
  const nextFixedSegments = fixedSegments.map((segment) => ({
5569
5591
  ...segment,
5570
- start: pointFrom6(
5592
+ start: pointFrom7(
5571
5593
  arrow.x + (segment.start[0] - updatedPoints[0][0]),
5572
5594
  arrow.y + (segment.start[1] - updatedPoints[0][1])
5573
5595
  ),
5574
- end: pointFrom6(
5596
+ end: pointFrom7(
5575
5597
  arrow.x + (segment.end[0] - updatedPoints[0][0]),
5576
5598
  arrow.y + (segment.end[1] - updatedPoints[0][1])
5577
5599
  )
@@ -5583,8 +5605,13 @@ var handleEndpointDrag = (arrow, updatedPoints, fixedSegments, startHeading, end
5583
5605
  newPoints.push(globalUpdatedPoints[newPoints.length + offset]);
5584
5606
  }
5585
5607
  {
5586
- const secondPoint = globalUpdatedPoints[startIsSpecial ? 2 : 1];
5587
- const thirdPoint = globalUpdatedPoints[startIsSpecial ? 3 : 2];
5608
+ const secondPoint = globalUpdatedPoints.at(startIsSpecial ? 2 : 1);
5609
+ const thirdPoint = globalUpdatedPoints.at(startIsSpecial ? 3 : 2);
5610
+ if (!secondPoint || !thirdPoint) {
5611
+ throw new Error(
5612
+ `Second and third points must exist when handling endpoint drag (${startIsSpecial})`
5613
+ );
5614
+ }
5588
5615
  const startIsHorizontal = headingIsHorizontal(startHeading);
5589
5616
  const secondIsHorizontal = headingIsHorizontal(
5590
5617
  vectorToHeading(vectorFromPoint5(secondPoint, thirdPoint))
@@ -5592,13 +5619,13 @@ var handleEndpointDrag = (arrow, updatedPoints, fixedSegments, startHeading, end
5592
5619
  if (hoveredStartElement && startIsHorizontal === secondIsHorizontal) {
5593
5620
  const positive = startIsHorizontal ? compareHeading(startHeading, HEADING_RIGHT) : compareHeading(startHeading, HEADING_DOWN);
5594
5621
  newPoints.unshift(
5595
- pointFrom6(
5622
+ pointFrom7(
5596
5623
  !secondIsHorizontal ? thirdPoint[0] : startGlobalPoint[0] + (positive ? BASE_PADDING : -BASE_PADDING),
5597
5624
  secondIsHorizontal ? thirdPoint[1] : startGlobalPoint[1] + (positive ? BASE_PADDING : -BASE_PADDING)
5598
5625
  )
5599
5626
  );
5600
5627
  newPoints.unshift(
5601
- pointFrom6(
5628
+ pointFrom7(
5602
5629
  startIsHorizontal ? startGlobalPoint[0] + (positive ? BASE_PADDING : -BASE_PADDING) : startGlobalPoint[0],
5603
5630
  !startIsHorizontal ? startGlobalPoint[1] + (positive ? BASE_PADDING : -BASE_PADDING) : startGlobalPoint[1]
5604
5631
  )
@@ -5613,7 +5640,7 @@ var handleEndpointDrag = (arrow, updatedPoints, fixedSegments, startHeading, end
5613
5640
  }
5614
5641
  } else {
5615
5642
  newPoints.unshift(
5616
- pointFrom6(
5643
+ pointFrom7(
5617
5644
  !secondIsHorizontal ? secondPoint[0] : startGlobalPoint[0],
5618
5645
  secondIsHorizontal ? secondPoint[1] : startGlobalPoint[1]
5619
5646
  )
@@ -5630,8 +5657,17 @@ var handleEndpointDrag = (arrow, updatedPoints, fixedSegments, startHeading, end
5630
5657
  newPoints.unshift(startGlobalPoint);
5631
5658
  }
5632
5659
  {
5633
- const secondToLastPoint = globalUpdatedPoints[globalUpdatedPoints.length - (endIsSpecial ? 3 : 2)];
5634
- const thirdToLastPoint = globalUpdatedPoints[globalUpdatedPoints.length - (endIsSpecial ? 4 : 3)];
5660
+ const secondToLastPoint = globalUpdatedPoints.at(
5661
+ globalUpdatedPoints.length - (endIsSpecial ? 3 : 2)
5662
+ );
5663
+ const thirdToLastPoint = globalUpdatedPoints.at(
5664
+ globalUpdatedPoints.length - (endIsSpecial ? 4 : 3)
5665
+ );
5666
+ if (!secondToLastPoint || !thirdToLastPoint) {
5667
+ throw new Error(
5668
+ `Second and third to last points must exist when handling endpoint drag (${endIsSpecial})`
5669
+ );
5670
+ }
5635
5671
  const endIsHorizontal = headingIsHorizontal(endHeading);
5636
5672
  const secondIsHorizontal = headingForPointIsHorizontal(
5637
5673
  thirdToLastPoint,
@@ -5640,13 +5676,13 @@ var handleEndpointDrag = (arrow, updatedPoints, fixedSegments, startHeading, end
5640
5676
  if (hoveredEndElement && endIsHorizontal === secondIsHorizontal) {
5641
5677
  const positive = endIsHorizontal ? compareHeading(endHeading, HEADING_RIGHT) : compareHeading(endHeading, HEADING_DOWN);
5642
5678
  newPoints.push(
5643
- pointFrom6(
5679
+ pointFrom7(
5644
5680
  !secondIsHorizontal ? thirdToLastPoint[0] : endGlobalPoint[0] + (positive ? BASE_PADDING : -BASE_PADDING),
5645
5681
  secondIsHorizontal ? thirdToLastPoint[1] : endGlobalPoint[1] + (positive ? BASE_PADDING : -BASE_PADDING)
5646
5682
  )
5647
5683
  );
5648
5684
  newPoints.push(
5649
- pointFrom6(
5685
+ pointFrom7(
5650
5686
  endIsHorizontal ? endGlobalPoint[0] + (positive ? BASE_PADDING : -BASE_PADDING) : endGlobalPoint[0],
5651
5687
  !endIsHorizontal ? endGlobalPoint[1] + (positive ? BASE_PADDING : -BASE_PADDING) : endGlobalPoint[1]
5652
5688
  )
@@ -5656,7 +5692,7 @@ var handleEndpointDrag = (arrow, updatedPoints, fixedSegments, startHeading, end
5656
5692
  }
5657
5693
  } else {
5658
5694
  newPoints.push(
5659
- pointFrom6(
5695
+ pointFrom7(
5660
5696
  !secondIsHorizontal ? secondToLastPoint[0] : endGlobalPoint[0],
5661
5697
  secondIsHorizontal ? secondToLastPoint[1] : endGlobalPoint[1]
5662
5698
  )
@@ -5675,11 +5711,11 @@ var handleEndpointDrag = (arrow, updatedPoints, fixedSegments, startHeading, end
5675
5711
  end: newPoints[index]
5676
5712
  })).map((segment) => ({
5677
5713
  ...segment,
5678
- start: pointFrom6(
5714
+ start: pointFrom7(
5679
5715
  segment.start[0] - startGlobalPoint[0],
5680
5716
  segment.start[1] - startGlobalPoint[1]
5681
5717
  ),
5682
- end: pointFrom6(
5718
+ end: pointFrom7(
5683
5719
  segment.end[0] - startGlobalPoint[0],
5684
5720
  segment.end[1] - startGlobalPoint[1]
5685
5721
  )
@@ -5741,7 +5777,7 @@ var updateElbowArrowPoints = (arrow, elementsMap, updates, options) => {
5741
5777
  if (startBinding && !startElement && areUpdatedPointsValid || endBinding && !endElement && areUpdatedPointsValid || elementsMap.size === 0 && areUpdatedPointsValid || Object.keys(restOfTheUpdates).length === 0 && (startElement?.id !== startBinding?.elementId || endElement?.id !== endBinding?.elementId)) {
5742
5778
  return normalizeArrowElementUpdate(
5743
5779
  updatedPoints.map(
5744
- (p) => pointFrom6(arrow.x + p[0], arrow.y + p[1])
5780
+ (p) => pointFrom7(arrow.x + p[0], arrow.y + p[1])
5745
5781
  ),
5746
5782
  arrow.fixedSegments,
5747
5783
  arrow.startIsSpecial,
@@ -5773,7 +5809,7 @@ var updateElbowArrowPoints = (arrow, elementsMap, updates, options) => {
5773
5809
  if (elementsMap.size === 0 && areUpdatedPointsValid) {
5774
5810
  return normalizeArrowElementUpdate(
5775
5811
  updatedPoints.map(
5776
- (p) => pointFrom6(arrow.x + p[0], arrow.y + p[1])
5812
+ (p) => pointFrom7(arrow.x + p[0], arrow.y + p[1])
5777
5813
  ),
5778
5814
  arrow.fixedSegments,
5779
5815
  arrow.startIsSpecial,
@@ -5786,7 +5822,7 @@ var updateElbowArrowPoints = (arrow, elementsMap, updates, options) => {
5786
5822
  if (updates.startBinding === arrow.startBinding && updates.endBinding === arrow.endBinding && (updates.points ?? []).every(
5787
5823
  (p, i) => pointsEqual4(
5788
5824
  p,
5789
- arrow.points[i] ?? pointFrom6(Infinity, Infinity)
5825
+ arrow.points[i] ?? pointFrom7(Infinity, Infinity)
5790
5826
  )
5791
5827
  ) && areUpdatedPointsValid) {
5792
5828
  return {};
@@ -6280,13 +6316,13 @@ var calculateGrid = (aabbs, start, startHeading, end, endHeading, common) => {
6280
6316
  var getDonglePosition = (bounds, heading, p) => {
6281
6317
  switch (heading) {
6282
6318
  case HEADING_UP:
6283
- return pointFrom6(p[0], bounds[1]);
6319
+ return pointFrom7(p[0], bounds[1]);
6284
6320
  case HEADING_RIGHT:
6285
- return pointFrom6(bounds[2], p[1]);
6321
+ return pointFrom7(bounds[2], p[1]);
6286
6322
  case HEADING_DOWN:
6287
- return pointFrom6(p[0], bounds[3]);
6323
+ return pointFrom7(p[0], bounds[3]);
6288
6324
  }
6289
- return pointFrom6(bounds[0], p[1]);
6325
+ return pointFrom7(bounds[0], p[1]);
6290
6326
  };
6291
6327
  var estimateSegmentCount = (start, end, startHeading, endHeading) => {
6292
6328
  if (endHeading === HEADING_RIGHT) {
@@ -6454,7 +6490,7 @@ var normalizeArrowElementUpdate = (global2, nextFixedSegments, startIsSpecial, e
6454
6490
  );
6455
6491
  }
6456
6492
  points = points.map(
6457
- ([x, y]) => pointFrom6(clamp2(x, -1e6, 1e6), clamp2(y, -1e6, 1e6))
6493
+ ([x, y]) => pointFrom7(clamp2(x, -1e6, 1e6), clamp2(y, -1e6, 1e6))
6458
6494
  );
6459
6495
  return {
6460
6496
  points,
@@ -7192,7 +7228,7 @@ var bindPointToSnapToElementOutline = (arrow, bindableElement, startOrEnd, eleme
7192
7228
  }
7193
7229
  const aabb = aabbForElement(bindableElement, elementsMap);
7194
7230
  const localP = arrow.points[startOrEnd === "start" ? 0 : arrow.points.length - 1];
7195
- const globalP = pointFrom7(
7231
+ const globalP = pointFrom8(
7196
7232
  arrow.x + localP[0],
7197
7233
  arrow.y + localP[1]
7198
7234
  );
@@ -7200,8 +7236,8 @@ var bindPointToSnapToElementOutline = (arrow, bindableElement, startOrEnd, eleme
7200
7236
  const elbowed = isElbowArrow(arrow);
7201
7237
  const center = getCenterForBounds(aabb);
7202
7238
  const adjacentPointIdx = startOrEnd === "start" ? 1 : arrow.points.length - 2;
7203
- const adjacentPoint = pointRotateRads6(
7204
- pointFrom7(
7239
+ const adjacentPoint = pointRotateRads7(
7240
+ pointFrom8(
7205
7241
  arrow.x + arrow.points[adjacentPointIdx][0],
7206
7242
  arrow.y + arrow.points[adjacentPointIdx][1]
7207
7243
  ),
@@ -7214,7 +7250,7 @@ var bindPointToSnapToElementOutline = (arrow, bindableElement, startOrEnd, eleme
7214
7250
  headingForPointFromElement(bindableElement, aabb, globalP)
7215
7251
  );
7216
7252
  const snapPoint = snapToMid(bindableElement, elementsMap, edgePoint);
7217
- const otherPoint = pointFrom7(
7253
+ const otherPoint = pointFrom8(
7218
7254
  isHorizontal ? center[0] : snapPoint[0],
7219
7255
  !isHorizontal ? center[1] : snapPoint[1]
7220
7256
  );
@@ -7261,24 +7297,24 @@ var bindPointToSnapToElementOutline = (arrow, bindableElement, startOrEnd, eleme
7261
7297
  };
7262
7298
  var avoidRectangularCorner = (element, elementsMap, p) => {
7263
7299
  const center = elementCenterPoint(element, elementsMap);
7264
- const nonRotatedPoint = pointRotateRads6(p, center, -element.angle);
7300
+ const nonRotatedPoint = pointRotateRads7(p, center, -element.angle);
7265
7301
  if (nonRotatedPoint[0] < element.x && nonRotatedPoint[1] < element.y) {
7266
7302
  if (nonRotatedPoint[1] - element.y > -FIXED_BINDING_DISTANCE) {
7267
- return pointRotateRads6(
7268
- pointFrom7(element.x - FIXED_BINDING_DISTANCE, element.y),
7303
+ return pointRotateRads7(
7304
+ pointFrom8(element.x - FIXED_BINDING_DISTANCE, element.y),
7269
7305
  center,
7270
7306
  element.angle
7271
7307
  );
7272
7308
  }
7273
- return pointRotateRads6(
7274
- pointFrom7(element.x, element.y - FIXED_BINDING_DISTANCE),
7309
+ return pointRotateRads7(
7310
+ pointFrom8(element.x, element.y - FIXED_BINDING_DISTANCE),
7275
7311
  center,
7276
7312
  element.angle
7277
7313
  );
7278
7314
  } else if (nonRotatedPoint[0] < element.x && nonRotatedPoint[1] > element.y + element.height) {
7279
7315
  if (nonRotatedPoint[0] - element.x > -FIXED_BINDING_DISTANCE) {
7280
- return pointRotateRads6(
7281
- pointFrom7(
7316
+ return pointRotateRads7(
7317
+ pointFrom8(
7282
7318
  element.x,
7283
7319
  element.y + element.height + FIXED_BINDING_DISTANCE
7284
7320
  ),
@@ -7286,15 +7322,15 @@ var avoidRectangularCorner = (element, elementsMap, p) => {
7286
7322
  element.angle
7287
7323
  );
7288
7324
  }
7289
- return pointRotateRads6(
7290
- pointFrom7(element.x - FIXED_BINDING_DISTANCE, element.y + element.height),
7325
+ return pointRotateRads7(
7326
+ pointFrom8(element.x - FIXED_BINDING_DISTANCE, element.y + element.height),
7291
7327
  center,
7292
7328
  element.angle
7293
7329
  );
7294
7330
  } else if (nonRotatedPoint[0] > element.x + element.width && nonRotatedPoint[1] > element.y + element.height) {
7295
7331
  if (nonRotatedPoint[0] - element.x < element.width + FIXED_BINDING_DISTANCE) {
7296
- return pointRotateRads6(
7297
- pointFrom7(
7332
+ return pointRotateRads7(
7333
+ pointFrom8(
7298
7334
  element.x + element.width,
7299
7335
  element.y + element.height + FIXED_BINDING_DISTANCE
7300
7336
  ),
@@ -7302,8 +7338,8 @@ var avoidRectangularCorner = (element, elementsMap, p) => {
7302
7338
  element.angle
7303
7339
  );
7304
7340
  }
7305
- return pointRotateRads6(
7306
- pointFrom7(
7341
+ return pointRotateRads7(
7342
+ pointFrom8(
7307
7343
  element.x + element.width + FIXED_BINDING_DISTANCE,
7308
7344
  element.y + element.height
7309
7345
  ),
@@ -7312,8 +7348,8 @@ var avoidRectangularCorner = (element, elementsMap, p) => {
7312
7348
  );
7313
7349
  } else if (nonRotatedPoint[0] > element.x + element.width && nonRotatedPoint[1] < element.y) {
7314
7350
  if (nonRotatedPoint[0] - element.x < element.width + FIXED_BINDING_DISTANCE) {
7315
- return pointRotateRads6(
7316
- pointFrom7(
7351
+ return pointRotateRads7(
7352
+ pointFrom8(
7317
7353
  element.x + element.width,
7318
7354
  element.y - FIXED_BINDING_DISTANCE
7319
7355
  ),
@@ -7321,8 +7357,8 @@ var avoidRectangularCorner = (element, elementsMap, p) => {
7321
7357
  element.angle
7322
7358
  );
7323
7359
  }
7324
- return pointRotateRads6(
7325
- pointFrom7(element.x + element.width + FIXED_BINDING_DISTANCE, element.y),
7360
+ return pointRotateRads7(
7361
+ pointFrom8(element.x + element.width + FIXED_BINDING_DISTANCE, element.y),
7326
7362
  center,
7327
7363
  element.angle
7328
7364
  );
@@ -7332,62 +7368,62 @@ var avoidRectangularCorner = (element, elementsMap, p) => {
7332
7368
  var snapToMid = (element, elementsMap, p, tolerance = 0.05) => {
7333
7369
  const { x, y, width, height, angle } = element;
7334
7370
  const center = elementCenterPoint(element, elementsMap, -0.1, -0.1);
7335
- const nonRotated = pointRotateRads6(p, center, -angle);
7371
+ const nonRotated = pointRotateRads7(p, center, -angle);
7336
7372
  const verticalThreshold = clamp3(tolerance * height, 5, 80);
7337
7373
  const horizontalThreshold = clamp3(tolerance * width, 5, 80);
7338
7374
  if (nonRotated[0] <= x + width / 2 && nonRotated[1] > center[1] - verticalThreshold && nonRotated[1] < center[1] + verticalThreshold) {
7339
- return pointRotateRads6(
7340
- pointFrom7(x - FIXED_BINDING_DISTANCE, center[1]),
7375
+ return pointRotateRads7(
7376
+ pointFrom8(x - FIXED_BINDING_DISTANCE, center[1]),
7341
7377
  center,
7342
7378
  angle
7343
7379
  );
7344
7380
  } else if (nonRotated[1] <= y + height / 2 && nonRotated[0] > center[0] - horizontalThreshold && nonRotated[0] < center[0] + horizontalThreshold) {
7345
- return pointRotateRads6(
7346
- pointFrom7(center[0], y - FIXED_BINDING_DISTANCE),
7381
+ return pointRotateRads7(
7382
+ pointFrom8(center[0], y - FIXED_BINDING_DISTANCE),
7347
7383
  center,
7348
7384
  angle
7349
7385
  );
7350
7386
  } else if (nonRotated[0] >= x + width / 2 && nonRotated[1] > center[1] - verticalThreshold && nonRotated[1] < center[1] + verticalThreshold) {
7351
- return pointRotateRads6(
7352
- pointFrom7(x + width + FIXED_BINDING_DISTANCE, center[1]),
7387
+ return pointRotateRads7(
7388
+ pointFrom8(x + width + FIXED_BINDING_DISTANCE, center[1]),
7353
7389
  center,
7354
7390
  angle
7355
7391
  );
7356
7392
  } else if (nonRotated[1] >= y + height / 2 && nonRotated[0] > center[0] - horizontalThreshold && nonRotated[0] < center[0] + horizontalThreshold) {
7357
- return pointRotateRads6(
7358
- pointFrom7(center[0], y + height + FIXED_BINDING_DISTANCE),
7393
+ return pointRotateRads7(
7394
+ pointFrom8(center[0], y + height + FIXED_BINDING_DISTANCE),
7359
7395
  center,
7360
7396
  angle
7361
7397
  );
7362
7398
  } else if (element.type === "diamond") {
7363
7399
  const distance3 = FIXED_BINDING_DISTANCE;
7364
- const topLeft = pointFrom7(
7400
+ const topLeft = pointFrom8(
7365
7401
  x + width / 4 - distance3,
7366
7402
  y + height / 4 - distance3
7367
7403
  );
7368
- const topRight = pointFrom7(
7404
+ const topRight = pointFrom8(
7369
7405
  x + 3 * width / 4 + distance3,
7370
7406
  y + height / 4 - distance3
7371
7407
  );
7372
- const bottomLeft = pointFrom7(
7408
+ const bottomLeft = pointFrom8(
7373
7409
  x + width / 4 - distance3,
7374
7410
  y + 3 * height / 4 + distance3
7375
7411
  );
7376
- const bottomRight = pointFrom7(
7412
+ const bottomRight = pointFrom8(
7377
7413
  x + 3 * width / 4 + distance3,
7378
7414
  y + 3 * height / 4 + distance3
7379
7415
  );
7380
7416
  if (pointDistance4(topLeft, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {
7381
- return pointRotateRads6(topLeft, center, angle);
7417
+ return pointRotateRads7(topLeft, center, angle);
7382
7418
  }
7383
7419
  if (pointDistance4(topRight, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {
7384
- return pointRotateRads6(topRight, center, angle);
7420
+ return pointRotateRads7(topRight, center, angle);
7385
7421
  }
7386
7422
  if (pointDistance4(bottomLeft, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {
7387
- return pointRotateRads6(bottomLeft, center, angle);
7423
+ return pointRotateRads7(bottomLeft, center, angle);
7388
7424
  }
7389
7425
  if (pointDistance4(bottomRight, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {
7390
- return pointRotateRads6(bottomRight, center, angle);
7426
+ return pointRotateRads7(bottomRight, center, angle);
7391
7427
  }
7392
7428
  }
7393
7429
  return p;
@@ -7407,11 +7443,11 @@ var updateBoundPoint = (linearElement, startOrEnd, binding, bindableElement, ele
7407
7443
  elementsMap
7408
7444
  ).fixedPoint;
7409
7445
  const globalMidPoint = elementCenterPoint(bindableElement, elementsMap);
7410
- const global2 = pointFrom7(
7446
+ const global2 = pointFrom8(
7411
7447
  bindableElement.x + fixedPoint[0] * bindableElement.width,
7412
7448
  bindableElement.y + fixedPoint[1] * bindableElement.height
7413
7449
  );
7414
- const rotatedGlobal = pointRotateRads6(
7450
+ const rotatedGlobal = pointRotateRads7(
7415
7451
  global2,
7416
7452
  globalMidPoint,
7417
7453
  bindableElement.angle
@@ -7501,11 +7537,11 @@ var calculateFixedPointForElbowArrowBinding = (linearElement, hoveredElement, st
7501
7537
  startOrEnd,
7502
7538
  elementsMap
7503
7539
  );
7504
- const globalMidPoint = pointFrom7(
7540
+ const globalMidPoint = pointFrom8(
7505
7541
  bounds[0] + (bounds[2] - bounds[0]) / 2,
7506
7542
  bounds[1] + (bounds[3] - bounds[1]) / 2
7507
7543
  );
7508
- const nonRotatedSnappedGlobalPoint = pointRotateRads6(
7544
+ const nonRotatedSnappedGlobalPoint = pointRotateRads7(
7509
7545
  snappedPoint,
7510
7546
  globalMidPoint,
7511
7547
  -hoveredElement.angle
@@ -7638,7 +7674,7 @@ var newBoundElements = (boundElements, idsToRemove, elementsToAdd = []) => {
7638
7674
  return nextBoundElements;
7639
7675
  };
7640
7676
  var bindingBorderTest = (element, { x, y }, elementsMap, zoom, fullShape) => {
7641
- const p = pointFrom7(x, y);
7677
+ const p = pointFrom8(x, y);
7642
7678
  const threshold = maxBindingGap(element, element.width, element.height, zoom);
7643
7679
  const shouldTestInside2 = (
7644
7680
  // disable fullshape snapping for frame elements so we
@@ -7680,8 +7716,8 @@ var determineFocusDistance = (element, elementsMap, a2, b2) => {
7680
7716
  if (pointsEqual5(a2, b2)) {
7681
7717
  return 0;
7682
7718
  }
7683
- const rotatedA = pointRotateRads6(a2, center, -element.angle);
7684
- const rotatedB = pointRotateRads6(b2, center, -element.angle);
7719
+ const rotatedA = pointRotateRads7(a2, center, -element.angle);
7720
+ const rotatedB = pointRotateRads7(b2, center, -element.angle);
7685
7721
  const sign = Math.sign(
7686
7722
  vectorCross3(
7687
7723
  vectorFromPoint6(rotatedB, a2),
@@ -7700,70 +7736,70 @@ var determineFocusDistance = (element, elementsMap, a2, b2) => {
7700
7736
  );
7701
7737
  const axes = element.type === "diamond" ? [
7702
7738
  lineSegment4(
7703
- pointFrom7(element.x + element.width / 2, element.y),
7704
- pointFrom7(
7739
+ pointFrom8(element.x + element.width / 2, element.y),
7740
+ pointFrom8(
7705
7741
  element.x + element.width / 2,
7706
7742
  element.y + element.height
7707
7743
  )
7708
7744
  ),
7709
7745
  lineSegment4(
7710
- pointFrom7(element.x, element.y + element.height / 2),
7711
- pointFrom7(
7746
+ pointFrom8(element.x, element.y + element.height / 2),
7747
+ pointFrom8(
7712
7748
  element.x + element.width,
7713
7749
  element.y + element.height / 2
7714
7750
  )
7715
7751
  )
7716
7752
  ] : [
7717
7753
  lineSegment4(
7718
- pointFrom7(element.x, element.y),
7719
- pointFrom7(
7754
+ pointFrom8(element.x, element.y),
7755
+ pointFrom8(
7720
7756
  element.x + element.width,
7721
7757
  element.y + element.height
7722
7758
  )
7723
7759
  ),
7724
7760
  lineSegment4(
7725
- pointFrom7(element.x + element.width, element.y),
7726
- pointFrom7(element.x, element.y + element.height)
7761
+ pointFrom8(element.x + element.width, element.y),
7762
+ pointFrom8(element.x, element.y + element.height)
7727
7763
  )
7728
7764
  ];
7729
7765
  const interceptees = element.type === "diamond" ? [
7730
7766
  lineSegment4(
7731
- pointFrom7(
7767
+ pointFrom8(
7732
7768
  element.x + element.width / 2,
7733
7769
  element.y - element.height
7734
7770
  ),
7735
- pointFrom7(
7771
+ pointFrom8(
7736
7772
  element.x + element.width / 2,
7737
7773
  element.y + element.height * 2
7738
7774
  )
7739
7775
  ),
7740
7776
  lineSegment4(
7741
- pointFrom7(
7777
+ pointFrom8(
7742
7778
  element.x - element.width,
7743
7779
  element.y + element.height / 2
7744
7780
  ),
7745
- pointFrom7(
7781
+ pointFrom8(
7746
7782
  element.x + element.width * 2,
7747
7783
  element.y + element.height / 2
7748
7784
  )
7749
7785
  )
7750
7786
  ] : [
7751
7787
  lineSegment4(
7752
- pointFrom7(
7788
+ pointFrom8(
7753
7789
  element.x - element.width,
7754
7790
  element.y - element.height
7755
7791
  ),
7756
- pointFrom7(
7792
+ pointFrom8(
7757
7793
  element.x + element.width * 2,
7758
7794
  element.y + element.height * 2
7759
7795
  )
7760
7796
  ),
7761
7797
  lineSegment4(
7762
- pointFrom7(
7798
+ pointFrom8(
7763
7799
  element.x + element.width * 2,
7764
7800
  element.y - element.height
7765
7801
  ),
7766
- pointFrom7(
7802
+ pointFrom8(
7767
7803
  element.x - element.width,
7768
7804
  element.y + element.height * 2
7769
7805
  )
@@ -7784,30 +7820,30 @@ var determineFocusPoint = (element, elementsMap, focus, adjacentPoint) => {
7784
7820
  return center;
7785
7821
  }
7786
7822
  const candidates = (element.type === "diamond" ? [
7787
- pointFrom7(element.x, element.y + element.height / 2),
7788
- pointFrom7(element.x + element.width / 2, element.y),
7789
- pointFrom7(
7823
+ pointFrom8(element.x, element.y + element.height / 2),
7824
+ pointFrom8(element.x + element.width / 2, element.y),
7825
+ pointFrom8(
7790
7826
  element.x + element.width,
7791
7827
  element.y + element.height / 2
7792
7828
  ),
7793
- pointFrom7(
7829
+ pointFrom8(
7794
7830
  element.x + element.width / 2,
7795
7831
  element.y + element.height
7796
7832
  )
7797
7833
  ] : [
7798
- pointFrom7(element.x, element.y),
7799
- pointFrom7(element.x + element.width, element.y),
7800
- pointFrom7(
7834
+ pointFrom8(element.x, element.y),
7835
+ pointFrom8(element.x + element.width, element.y),
7836
+ pointFrom8(
7801
7837
  element.x + element.width,
7802
7838
  element.y + element.height
7803
7839
  ),
7804
- pointFrom7(element.x, element.y + element.height)
7840
+ pointFrom8(element.x, element.y + element.height)
7805
7841
  ]).map(
7806
7842
  (p) => pointFromVector5(
7807
7843
  vectorScale6(vectorFromPoint6(p, center), Math.abs(focus)),
7808
7844
  center
7809
7845
  )
7810
- ).map((p) => pointRotateRads6(p, center, element.angle));
7846
+ ).map((p) => pointRotateRads7(p, center, element.angle));
7811
7847
  const selected = [
7812
7848
  vectorCross3(
7813
7849
  vectorFromPoint6(adjacentPoint, candidates[0]),
@@ -8052,8 +8088,8 @@ var BindableElement = class {
8052
8088
  };
8053
8089
  var getGlobalFixedPointForBindableElement = (fixedPointRatio, element, elementsMap) => {
8054
8090
  const [fixedX, fixedY] = normalizeFixedPoint(fixedPointRatio);
8055
- return pointRotateRads6(
8056
- pointFrom7(
8091
+ return pointRotateRads7(
8092
+ pointFrom8(
8057
8093
  element.x + element.width * fixedX,
8058
8094
  element.y + element.height * fixedY
8059
8095
  ),
@@ -8068,7 +8104,7 @@ var getGlobalFixedPoints = (arrow, elementsMap) => {
8068
8104
  arrow.startBinding.fixedPoint,
8069
8105
  startElement,
8070
8106
  elementsMap
8071
- ) : pointFrom7(
8107
+ ) : pointFrom8(
8072
8108
  arrow.x + arrow.points[0][0],
8073
8109
  arrow.y + arrow.points[0][1]
8074
8110
  );
@@ -8076,7 +8112,7 @@ var getGlobalFixedPoints = (arrow, elementsMap) => {
8076
8112
  arrow.endBinding.fixedPoint,
8077
8113
  endElement,
8078
8114
  elementsMap
8079
- ) : pointFrom7(
8115
+ ) : pointFrom8(
8080
8116
  arrow.x + arrow.points[arrow.points.length - 1][0],
8081
8117
  arrow.y + arrow.points[arrow.points.length - 1][1]
8082
8118
  );
@@ -8106,7 +8142,7 @@ var getNormalizedPoints = ({
8106
8142
  const offsetY = points[0][1];
8107
8143
  return {
8108
8144
  points: points.map((p) => {
8109
- return pointFrom8(p[0] - offsetX, p[1] - offsetY);
8145
+ return pointFrom9(p[0] - offsetX, p[1] - offsetY);
8110
8146
  }),
8111
8147
  offsetX,
8112
8148
  offsetY
@@ -8127,9 +8163,10 @@ var LinearElementEditor = class _LinearElementEditor {
8127
8163
  segmentMidPointHoveredCoords;
8128
8164
  elbowed;
8129
8165
  customLineAngle;
8130
- constructor(element, elementsMap) {
8166
+ isEditing;
8167
+ constructor(element, elementsMap, isEditing = false) {
8131
8168
  this.elementId = element.id;
8132
- if (!pointsEqual6(element.points[0], pointFrom8(0, 0))) {
8169
+ if (!pointsEqual6(element.points[0], pointFrom9(0, 0))) {
8133
8170
  console.error("Linear element is not normalized", Error().stack);
8134
8171
  mutateElement(
8135
8172
  element,
@@ -8158,6 +8195,7 @@ var LinearElementEditor = class _LinearElementEditor {
8158
8195
  this.segmentMidPointHoveredCoords = null;
8159
8196
  this.elbowed = isElbowArrow(element) && element.elbowed;
8160
8197
  this.customLineAngle = null;
8198
+ this.isEditing = isEditing;
8161
8199
  }
8162
8200
  // ---------------------------------------------------------------------------
8163
8201
  // static methods
@@ -8175,11 +8213,11 @@ var LinearElementEditor = class _LinearElementEditor {
8175
8213
  return null;
8176
8214
  }
8177
8215
  static handleBoxSelection(event, appState, setState, elementsMap) {
8178
- if (!appState.editingLinearElement || !appState.selectionElement) {
8216
+ if (!appState.selectedLinearElement?.isEditing || !appState.selectionElement) {
8179
8217
  return false;
8180
8218
  }
8181
- const { editingLinearElement } = appState;
8182
- const { selectedPointsIndices, elementId } = editingLinearElement;
8219
+ const { selectedLinearElement } = appState;
8220
+ const { selectedPointsIndices, elementId } = selectedLinearElement;
8183
8221
  const element = _LinearElementEditor.getElement(elementId, elementsMap);
8184
8222
  if (!element) {
8185
8223
  return false;
@@ -8201,8 +8239,8 @@ var LinearElementEditor = class _LinearElementEditor {
8201
8239
  return true;
8202
8240
  });
8203
8241
  setState({
8204
- editingLinearElement: {
8205
- ...editingLinearElement,
8242
+ selectedLinearElement: {
8243
+ ...selectedLinearElement,
8206
8244
  selectedPointsIndices: nextSelectedPoints.length ? nextSelectedPoints : null
8207
8245
  }
8208
8246
  });
@@ -8242,7 +8280,7 @@ var LinearElementEditor = class _LinearElementEditor {
8242
8280
  element,
8243
8281
  elementsMap,
8244
8282
  referencePoint,
8245
- pointFrom8(scenePointerX, scenePointerY),
8283
+ pointFrom9(scenePointerX, scenePointerY),
8246
8284
  event[KEYS2.CTRL_OR_CMD] ? null : app.getEffectiveGridSize(),
8247
8285
  customLineAngle
8248
8286
  );
@@ -8253,7 +8291,7 @@ var LinearElementEditor = class _LinearElementEditor {
8253
8291
  [
8254
8292
  selectedIndex,
8255
8293
  {
8256
- point: pointFrom8(
8294
+ point: pointFrom9(
8257
8295
  width + referencePoint[0],
8258
8296
  height + referencePoint[1]
8259
8297
  ),
@@ -8283,7 +8321,7 @@ var LinearElementEditor = class _LinearElementEditor {
8283
8321
  scenePointerX - linearElementEditor.pointerOffset.x,
8284
8322
  scenePointerY - linearElementEditor.pointerOffset.y,
8285
8323
  event[KEYS2.CTRL_OR_CMD] ? null : app.getEffectiveGridSize()
8286
- ) : pointFrom8(
8324
+ ) : pointFrom9(
8287
8325
  element.points[pointIndex][0] + deltaX,
8288
8326
  element.points[pointIndex][1] + deltaY
8289
8327
  );
@@ -8356,7 +8394,6 @@ var LinearElementEditor = class _LinearElementEditor {
8356
8394
  };
8357
8395
  return {
8358
8396
  ...app.state,
8359
- editingLinearElement: app.state.editingLinearElement ? newLinearElementEditor : null,
8360
8397
  selectedLinearElement: newLinearElementEditor,
8361
8398
  suggestedBindings
8362
8399
  };
@@ -8440,7 +8477,7 @@ var LinearElementEditor = class _LinearElementEditor {
8440
8477
  }
8441
8478
  static getEditorMidPoints = (element, elementsMap, appState) => {
8442
8479
  const boundText = getBoundTextElement(element, elementsMap);
8443
- if (!isElbowArrow(element) && !appState.editingLinearElement && element.points.length > 2 && !boundText) {
8480
+ if (!isElbowArrow(element) && !appState.selectedLinearElement?.isEditing && element.points.length > 2 && !boundText) {
8444
8481
  return [];
8445
8482
  }
8446
8483
  const points = _LinearElementEditor.getPointsGlobalCoordinates(
@@ -8490,18 +8527,18 @@ var LinearElementEditor = class _LinearElementEditor {
8490
8527
  element,
8491
8528
  elementsMap
8492
8529
  );
8493
- if (points.length >= 3 && !appState.editingLinearElement && !isElbowArrow(element)) {
8530
+ if (points.length >= 3 && !appState.selectedLinearElement?.isEditing && !isElbowArrow(element)) {
8494
8531
  return null;
8495
8532
  }
8496
8533
  const threshold = (_LinearElementEditor.POINT_HANDLE_SIZE + 1) / appState.zoom.value;
8497
8534
  const existingSegmentMidpointHitCoords = linearElementEditor.segmentMidPointHoveredCoords;
8498
8535
  if (existingSegmentMidpointHitCoords) {
8499
8536
  const distance3 = pointDistance5(
8500
- pointFrom8(
8537
+ pointFrom9(
8501
8538
  existingSegmentMidpointHitCoords[0],
8502
8539
  existingSegmentMidpointHitCoords[1]
8503
8540
  ),
8504
- pointFrom8(scenePointer.x, scenePointer.y)
8541
+ pointFrom9(scenePointer.x, scenePointer.y)
8505
8542
  );
8506
8543
  if (distance3 <= threshold) {
8507
8544
  return existingSegmentMidpointHitCoords;
@@ -8517,7 +8554,7 @@ var LinearElementEditor = class _LinearElementEditor {
8517
8554
  if (midPoints[index] !== null) {
8518
8555
  const distance3 = pointDistance5(
8519
8556
  midPoints[index],
8520
- pointFrom8(scenePointer.x, scenePointer.y)
8557
+ pointFrom9(scenePointer.x, scenePointer.y)
8521
8558
  );
8522
8559
  if (distance3 <= threshold) {
8523
8560
  return midPoints[index];
@@ -8556,7 +8593,7 @@ var LinearElementEditor = class _LinearElementEditor {
8556
8593
  "Invalid segment index while calculating elbow arrow mid point"
8557
8594
  );
8558
8595
  const p = pointCenter2(element.points[index - 1], element.points[index]);
8559
- return pointFrom8(element.x + p[0], element.y + p[1]);
8596
+ return pointFrom9(element.x + p[0], element.y + p[1]);
8560
8597
  }
8561
8598
  const [lines, curves] = deconstructLinearOrFreeDrawElement2(element);
8562
8599
  invariant6(
@@ -8630,7 +8667,7 @@ var LinearElementEditor = class _LinearElementEditor {
8630
8667
  segmentMidpoint,
8631
8668
  elementsMap
8632
8669
  );
8633
- } else if (event.altKey && appState.editingLinearElement) {
8670
+ } else if (event.altKey && appState.selectedLinearElement?.isEditing) {
8634
8671
  if (linearElementEditor.lastUncommittedPoint == null) {
8635
8672
  scene.mutateElement(element, {
8636
8673
  points: [
@@ -8696,12 +8733,12 @@ var LinearElementEditor = class _LinearElementEditor {
8696
8733
  const [x1, y1, x2, y2] = getElementAbsoluteCoords2(element, elementsMap);
8697
8734
  const cx = (x1 + x2) / 2;
8698
8735
  const cy = (y1 + y2) / 2;
8699
- const targetPoint = clickedPointIndex > -1 && pointRotateRads7(
8700
- pointFrom8(
8736
+ const targetPoint = clickedPointIndex > -1 && pointRotateRads8(
8737
+ pointFrom9(
8701
8738
  element.x + element.points[clickedPointIndex][0],
8702
8739
  element.y + element.points[clickedPointIndex][1]
8703
8740
  ),
8704
- pointFrom8(cx, cy),
8741
+ pointFrom9(cx, cy),
8705
8742
  element.angle
8706
8743
  );
8707
8744
  const nextSelectedPointsIndices = clickedPointIndex > -1 || event.shiftKey ? event.shiftKey || linearElementEditor.selectedPointsIndices?.includes(clickedPointIndex) ? normalizeSelectedPoints([
@@ -8740,14 +8777,14 @@ var LinearElementEditor = class _LinearElementEditor {
8740
8777
  }
8741
8778
  static handlePointerMove(event, scenePointerX, scenePointerY, app) {
8742
8779
  const appState = app.state;
8743
- if (!appState.editingLinearElement) {
8780
+ if (!appState.selectedLinearElement?.isEditing) {
8744
8781
  return null;
8745
8782
  }
8746
- const { elementId, lastUncommittedPoint } = appState.editingLinearElement;
8783
+ const { elementId, lastUncommittedPoint } = appState.selectedLinearElement;
8747
8784
  const elementsMap = app.scene.getNonDeletedElementsMap();
8748
8785
  const element = _LinearElementEditor.getElement(elementId, elementsMap);
8749
8786
  if (!element) {
8750
- return appState.editingLinearElement;
8787
+ return appState.selectedLinearElement;
8751
8788
  }
8752
8789
  const { points } = element;
8753
8790
  const lastPoint = points[points.length - 1];
@@ -8755,10 +8792,10 @@ var LinearElementEditor = class _LinearElementEditor {
8755
8792
  if (lastPoint === lastUncommittedPoint) {
8756
8793
  _LinearElementEditor.deletePoints(element, app, [points.length - 1]);
8757
8794
  }
8758
- return {
8759
- ...appState.editingLinearElement,
8795
+ return appState.selectedLinearElement?.lastUncommittedPoint ? {
8796
+ ...appState.selectedLinearElement,
8760
8797
  lastUncommittedPoint: null
8761
- };
8798
+ } : appState.selectedLinearElement;
8762
8799
  }
8763
8800
  let newPoint;
8764
8801
  if (shouldRotateWithDiscreteAngle(event) && points.length >= 2) {
@@ -8767,10 +8804,10 @@ var LinearElementEditor = class _LinearElementEditor {
8767
8804
  element,
8768
8805
  elementsMap,
8769
8806
  lastCommittedPoint,
8770
- pointFrom8(scenePointerX, scenePointerY),
8807
+ pointFrom9(scenePointerX, scenePointerY),
8771
8808
  event[KEYS2.CTRL_OR_CMD] ? null : app.getEffectiveGridSize()
8772
8809
  );
8773
- newPoint = pointFrom8(
8810
+ newPoint = pointFrom9(
8774
8811
  width + lastCommittedPoint[0],
8775
8812
  height + lastCommittedPoint[1]
8776
8813
  );
@@ -8778,8 +8815,8 @@ var LinearElementEditor = class _LinearElementEditor {
8778
8815
  newPoint = _LinearElementEditor.createPointAt(
8779
8816
  element,
8780
8817
  elementsMap,
8781
- scenePointerX - appState.editingLinearElement.pointerOffset.x,
8782
- scenePointerY - appState.editingLinearElement.pointerOffset.y,
8818
+ scenePointerX - appState.selectedLinearElement.pointerOffset.x,
8819
+ scenePointerY - appState.selectedLinearElement.pointerOffset.y,
8783
8820
  event[KEYS2.CTRL_OR_CMD] || isElbowArrow(element) ? null : app.getEffectiveGridSize()
8784
8821
  );
8785
8822
  }
@@ -8800,7 +8837,7 @@ var LinearElementEditor = class _LinearElementEditor {
8800
8837
  _LinearElementEditor.addPoints(element, app.scene, [newPoint]);
8801
8838
  }
8802
8839
  return {
8803
- ...appState.editingLinearElement,
8840
+ ...appState.selectedLinearElement,
8804
8841
  lastUncommittedPoint: element.points[element.points.length - 1]
8805
8842
  };
8806
8843
  }
@@ -8810,9 +8847,9 @@ var LinearElementEditor = class _LinearElementEditor {
8810
8847
  const cx = (x1 + x2) / 2;
8811
8848
  const cy = (y1 + y2) / 2;
8812
8849
  const { x, y } = element;
8813
- return pointRotateRads7(
8814
- pointFrom8(x + p[0], y + p[1]),
8815
- pointFrom8(cx, cy),
8850
+ return pointRotateRads8(
8851
+ pointFrom9(x + p[0], y + p[1]),
8852
+ pointFrom9(cx, cy),
8816
8853
  element.angle
8817
8854
  );
8818
8855
  }
@@ -8823,9 +8860,9 @@ var LinearElementEditor = class _LinearElementEditor {
8823
8860
  const cy = (y1 + y2) / 2;
8824
8861
  return element.points.map((p) => {
8825
8862
  const { x, y } = element;
8826
- return pointRotateRads7(
8827
- pointFrom8(x + p[0], y + p[1]),
8828
- pointFrom8(cx, cy),
8863
+ return pointRotateRads8(
8864
+ pointFrom9(x + p[0], y + p[1]),
8865
+ pointFrom9(cx, cy),
8829
8866
  element.angle
8830
8867
  );
8831
8868
  });
@@ -8837,15 +8874,15 @@ var LinearElementEditor = class _LinearElementEditor {
8837
8874
  const cy = (y1 + y2) / 2;
8838
8875
  const p = element.points[index];
8839
8876
  const { x, y } = element;
8840
- return p ? pointRotateRads7(
8841
- pointFrom8(x + p[0], y + p[1]),
8842
- pointFrom8(cx, cy),
8877
+ return p ? pointRotateRads8(
8878
+ pointFrom9(x + p[0], y + p[1]),
8879
+ pointFrom9(cx, cy),
8843
8880
  element.angle
8844
- ) : pointRotateRads7(pointFrom8(x, y), pointFrom8(cx, cy), element.angle);
8881
+ ) : pointRotateRads8(pointFrom9(x, y), pointFrom9(cx, cy), element.angle);
8845
8882
  }
8846
8883
  static pointFromAbsoluteCoords(element, absoluteCoords, elementsMap) {
8847
8884
  if (isElbowArrow(element)) {
8848
- return pointFrom8(
8885
+ return pointFrom9(
8849
8886
  absoluteCoords[0] - element.x,
8850
8887
  absoluteCoords[1] - element.y
8851
8888
  );
@@ -8853,12 +8890,12 @@ var LinearElementEditor = class _LinearElementEditor {
8853
8890
  const [x1, y1, x2, y2] = getElementAbsoluteCoords2(element, elementsMap);
8854
8891
  const cx = (x1 + x2) / 2;
8855
8892
  const cy = (y1 + y2) / 2;
8856
- const [x, y] = pointRotateRads7(
8857
- pointFrom8(absoluteCoords[0], absoluteCoords[1]),
8858
- pointFrom8(cx, cy),
8893
+ const [x, y] = pointRotateRads8(
8894
+ pointFrom9(absoluteCoords[0], absoluteCoords[1]),
8895
+ pointFrom9(cx, cy),
8859
8896
  -element.angle
8860
8897
  );
8861
- return pointFrom8(x - element.x, y - element.y);
8898
+ return pointFrom9(x - element.x, y - element.y);
8862
8899
  }
8863
8900
  static getPointIndexUnderCursor(element, elementsMap, zoom, x, y) {
8864
8901
  const pointHandles = _LinearElementEditor.getPointsGlobalCoordinates(
@@ -8868,7 +8905,7 @@ var LinearElementEditor = class _LinearElementEditor {
8868
8905
  let idx = pointHandles.length;
8869
8906
  while (--idx > -1) {
8870
8907
  const p = pointHandles[idx];
8871
- if (pointDistance5(pointFrom8(x, y), pointFrom8(p[0], p[1])) * zoom.value < // +1px to account for outline stroke
8908
+ if (pointDistance5(pointFrom9(x, y), pointFrom9(p[0], p[1])) * zoom.value < // +1px to account for outline stroke
8872
8909
  _LinearElementEditor.POINT_HANDLE_SIZE + 1) {
8873
8910
  return idx;
8874
8911
  }
@@ -8880,12 +8917,12 @@ var LinearElementEditor = class _LinearElementEditor {
8880
8917
  const [x1, y1, x2, y2] = getElementAbsoluteCoords2(element, elementsMap);
8881
8918
  const cx = (x1 + x2) / 2;
8882
8919
  const cy = (y1 + y2) / 2;
8883
- const [rotatedX, rotatedY] = pointRotateRads7(
8884
- pointFrom8(pointerOnGrid[0], pointerOnGrid[1]),
8885
- pointFrom8(cx, cy),
8920
+ const [rotatedX, rotatedY] = pointRotateRads8(
8921
+ pointFrom9(pointerOnGrid[0], pointerOnGrid[1]),
8922
+ pointFrom9(cx, cy),
8886
8923
  -element.angle
8887
8924
  );
8888
- return pointFrom8(rotatedX - element.x, rotatedY - element.y);
8925
+ return pointFrom9(rotatedX - element.x, rotatedY - element.y);
8889
8926
  }
8890
8927
  /**
8891
8928
  * Normalizes line points so that the start point is at [0,0]. This is
@@ -8906,11 +8943,11 @@ var LinearElementEditor = class _LinearElementEditor {
8906
8943
  // ---------------------------------------------------------------------------
8907
8944
  static duplicateSelectedPoints(appState, scene) {
8908
8945
  invariant6(
8909
- appState.editingLinearElement,
8946
+ appState.selectedLinearElement?.isEditing,
8910
8947
  "Not currently editing a linear element"
8911
8948
  );
8912
8949
  const elementsMap = scene.getNonDeletedElementsMap();
8913
- const { selectedPointsIndices, elementId } = appState.editingLinearElement;
8950
+ const { selectedPointsIndices, elementId } = appState.selectedLinearElement;
8914
8951
  const element = _LinearElementEditor.getElement(elementId, elementsMap);
8915
8952
  invariant6(
8916
8953
  element,
@@ -8934,7 +8971,7 @@ var LinearElementEditor = class _LinearElementEditor {
8934
8971
  pointAddedToEnd = true;
8935
8972
  }
8936
8973
  acc.push(
8937
- nextPoint ? pointFrom8((p[0] + nextPoint[0]) / 2, (p[1] + nextPoint[1]) / 2) : pointFrom8(p[0], p[1])
8974
+ nextPoint ? pointFrom9((p[0] + nextPoint[0]) / 2, (p[1] + nextPoint[1]) / 2) : pointFrom9(p[0], p[1])
8938
8975
  );
8939
8976
  nextSelectedIndices.push(indexCursor + 1);
8940
8977
  ++indexCursor;
@@ -8950,27 +8987,27 @@ var LinearElementEditor = class _LinearElementEditor {
8950
8987
  /* @__PURE__ */ new Map([
8951
8988
  [
8952
8989
  element.points.length - 1,
8953
- { point: pointFrom8(lastPoint[0] + 30, lastPoint[1] + 30) }
8990
+ { point: pointFrom9(lastPoint[0] + 30, lastPoint[1] + 30) }
8954
8991
  ]
8955
8992
  ])
8956
8993
  );
8957
8994
  }
8958
8995
  return {
8959
8996
  ...appState,
8960
- editingLinearElement: {
8961
- ...appState.editingLinearElement,
8997
+ selectedLinearElement: {
8998
+ ...appState.selectedLinearElement,
8962
8999
  selectedPointsIndices: nextSelectedIndices
8963
9000
  }
8964
9001
  };
8965
9002
  }
8966
9003
  static deletePoints(element, app, pointIndices) {
8967
- const isUncommittedPoint = app.state.editingLinearElement?.lastUncommittedPoint === element.points[element.points.length - 1];
9004
+ const isUncommittedPoint = app.state.selectedLinearElement?.isEditing && app.state.selectedLinearElement?.lastUncommittedPoint === element.points[element.points.length - 1];
8968
9005
  const nextPoints = element.points.filter((_, idx) => {
8969
9006
  return !pointIndices.includes(idx);
8970
9007
  });
8971
9008
  const isPolygon = isLineElement(element) && element.polygon;
8972
9009
  if (isPolygon && (isUncommittedPoint || pointIndices.includes(0) || pointIndices.includes(element.points.length - 1))) {
8973
- nextPoints[0] = pointFrom8(
9010
+ nextPoints[0] = pointFrom9(
8974
9011
  nextPoints[nextPoints.length - 1][0],
8975
9012
  nextPoints[nextPoints.length - 1][1]
8976
9013
  );
@@ -8991,7 +9028,7 @@ var LinearElementEditor = class _LinearElementEditor {
8991
9028
  static addPoints(element, scene, addedPoints) {
8992
9029
  const nextPoints = [...element.points, ...addedPoints];
8993
9030
  if (isLineElement(element) && element.polygon) {
8994
- nextPoints[0] = pointFrom8(
9031
+ nextPoints[0] = pointFrom9(
8995
9032
  nextPoints[nextPoints.length - 1][0],
8996
9033
  nextPoints[nextPoints.length - 1][1]
8997
9034
  );
@@ -9016,7 +9053,7 @@ var LinearElementEditor = class _LinearElementEditor {
9016
9053
  const lastPointUpdate = pointUpdates.get(points.length - 1);
9017
9054
  if (firstPointUpdate) {
9018
9055
  pointUpdates.set(points.length - 1, {
9019
- point: pointFrom8(
9056
+ point: pointFrom9(
9020
9057
  firstPointUpdate.point[0],
9021
9058
  firstPointUpdate.point[1]
9022
9059
  ),
@@ -9024,19 +9061,19 @@ var LinearElementEditor = class _LinearElementEditor {
9024
9061
  });
9025
9062
  } else if (lastPointUpdate) {
9026
9063
  pointUpdates.set(0, {
9027
- point: pointFrom8(lastPointUpdate.point[0], lastPointUpdate.point[1]),
9064
+ point: pointFrom9(lastPointUpdate.point[0], lastPointUpdate.point[1]),
9028
9065
  isDragging: lastPointUpdate.isDragging
9029
9066
  });
9030
9067
  }
9031
9068
  }
9032
- const updatedOriginPoint = pointUpdates.get(0)?.point ?? pointFrom8(0, 0);
9069
+ const updatedOriginPoint = pointUpdates.get(0)?.point ?? pointFrom9(0, 0);
9033
9070
  const [offsetX, offsetY] = updatedOriginPoint;
9034
9071
  const nextPoints = isElbowArrow(element) ? [
9035
9072
  pointUpdates.get(0)?.point ?? points[0],
9036
9073
  pointUpdates.get(points.length - 1)?.point ?? points[points.length - 1]
9037
9074
  ] : points.map((p, idx) => {
9038
9075
  const current = pointUpdates.get(idx)?.point ?? p;
9039
- return pointFrom8(
9076
+ return pointFrom9(
9040
9077
  current[0] - offsetX,
9041
9078
  current[1] - offsetY
9042
9079
  );
@@ -9070,10 +9107,10 @@ var LinearElementEditor = class _LinearElementEditor {
9070
9107
  }
9071
9108
  const origin = linearElementEditor.pointerDownState.origin;
9072
9109
  const dist = pointDistance5(
9073
- pointFrom8(origin.x, origin.y),
9074
- pointFrom8(pointerCoords.x, pointerCoords.y)
9110
+ pointFrom9(origin.x, origin.y),
9111
+ pointFrom9(pointerCoords.x, pointerCoords.y)
9075
9112
  );
9076
- if (!appState.editingLinearElement && dist < DRAGGING_THRESHOLD / appState.zoom.value) {
9113
+ if (!appState.selectedLinearElement?.isEditing && dist < DRAGGING_THRESHOLD / appState.zoom.value) {
9077
9114
  return false;
9078
9115
  }
9079
9116
  return true;
@@ -9139,9 +9176,9 @@ var LinearElementEditor = class _LinearElementEditor {
9139
9176
  const prevCenterY = (prevCoords[1] + prevCoords[3]) / 2;
9140
9177
  const dX = prevCenterX - nextCenterX;
9141
9178
  const dY = prevCenterY - nextCenterY;
9142
- const rotatedOffset = pointRotateRads7(
9143
- pointFrom8(offsetX, offsetY),
9144
- pointFrom8(dX, dY),
9179
+ const rotatedOffset = pointRotateRads8(
9180
+ pointFrom9(offsetX, offsetY),
9181
+ pointFrom9(dX, dY),
9145
9182
  element.angle
9146
9183
  );
9147
9184
  scene.mutateElement(element, {
@@ -9176,9 +9213,9 @@ var LinearElementEditor = class _LinearElementEditor {
9176
9213
  gridY,
9177
9214
  customLineAngle
9178
9215
  );
9179
- return pointRotateRads7(
9180
- pointFrom8(width, height),
9181
- pointFrom8(0, 0),
9216
+ return pointRotateRads8(
9217
+ pointFrom9(width, height),
9218
+ pointFrom9(0, 0),
9182
9219
  -element.angle
9183
9220
  );
9184
9221
  }
@@ -9223,34 +9260,34 @@ var LinearElementEditor = class _LinearElementEditor {
9223
9260
  );
9224
9261
  const boundTextX2 = boundTextX1 + boundTextElement.width;
9225
9262
  const boundTextY2 = boundTextY1 + boundTextElement.height;
9226
- const centerPoint = pointFrom8(cx, cy);
9227
- const topLeftRotatedPoint = pointRotateRads7(
9228
- pointFrom8(x1, y1),
9263
+ const centerPoint = pointFrom9(cx, cy);
9264
+ const topLeftRotatedPoint = pointRotateRads8(
9265
+ pointFrom9(x1, y1),
9229
9266
  centerPoint,
9230
9267
  element.angle
9231
9268
  );
9232
- const topRightRotatedPoint = pointRotateRads7(
9233
- pointFrom8(x2, y1),
9269
+ const topRightRotatedPoint = pointRotateRads8(
9270
+ pointFrom9(x2, y1),
9234
9271
  centerPoint,
9235
9272
  element.angle
9236
9273
  );
9237
- const counterRotateBoundTextTopLeft = pointRotateRads7(
9238
- pointFrom8(boundTextX1, boundTextY1),
9274
+ const counterRotateBoundTextTopLeft = pointRotateRads8(
9275
+ pointFrom9(boundTextX1, boundTextY1),
9239
9276
  centerPoint,
9240
9277
  -element.angle
9241
9278
  );
9242
- const counterRotateBoundTextTopRight = pointRotateRads7(
9243
- pointFrom8(boundTextX2, boundTextY1),
9279
+ const counterRotateBoundTextTopRight = pointRotateRads8(
9280
+ pointFrom9(boundTextX2, boundTextY1),
9244
9281
  centerPoint,
9245
9282
  -element.angle
9246
9283
  );
9247
- const counterRotateBoundTextBottomLeft = pointRotateRads7(
9248
- pointFrom8(boundTextX1, boundTextY2),
9284
+ const counterRotateBoundTextBottomLeft = pointRotateRads8(
9285
+ pointFrom9(boundTextX1, boundTextY2),
9249
9286
  centerPoint,
9250
9287
  -element.angle
9251
9288
  );
9252
- const counterRotateBoundTextBottomRight = pointRotateRads7(
9253
- pointFrom8(boundTextX2, boundTextY2),
9289
+ const counterRotateBoundTextBottomRight = pointRotateRads8(
9290
+ pointFrom9(boundTextX2, boundTextY2),
9254
9291
  centerPoint,
9255
9292
  -element.angle
9256
9293
  );
@@ -9366,11 +9403,11 @@ var LinearElementEditor = class _LinearElementEditor {
9366
9403
  );
9367
9404
  fixedSegments[index] = {
9368
9405
  index,
9369
- start: pointFrom8(
9406
+ start: pointFrom9(
9370
9407
  !isHorizontal ? x - element.x : element.points[index - 1][0],
9371
9408
  isHorizontal ? y - element.y : element.points[index - 1][1]
9372
9409
  ),
9373
- end: pointFrom8(
9410
+ end: pointFrom9(
9374
9411
  !isHorizontal ? x - element.x : element.points[index][0],
9375
9412
  isHorizontal ? y - element.y : element.points[index][1]
9376
9413
  )
@@ -9382,7 +9419,7 @@ var LinearElementEditor = class _LinearElementEditor {
9382
9419
  scene.mutateElement(element, {
9383
9420
  fixedSegments: nextFixedSegments
9384
9421
  });
9385
- const point = pointFrom8(
9422
+ const point = pointFrom9(
9386
9423
  element.x + (element.fixedSegments[offset].start[0] + element.fixedSegments[offset].end[0]) / 2,
9387
9424
  element.y + (element.fixedSegments[offset].start[1] + element.fixedSegments[offset].end[1]) / 2
9388
9425
  );
@@ -9420,7 +9457,7 @@ var normalizeSelectedPoints = (points) => {
9420
9457
  // src/frame.ts
9421
9458
  init_define_import_meta_env();
9422
9459
  import { arrayToMap as arrayToMap5 } from "@excalidraw/common";
9423
- import { isPointWithinBounds as isPointWithinBounds2, pointFrom as pointFrom10 } from "@excalidraw/math";
9460
+ import { isPointWithinBounds as isPointWithinBounds2, pointFrom as pointFrom11 } from "@excalidraw/math";
9424
9461
 
9425
9462
  // ../utils/src/bbox.ts
9426
9463
  init_define_import_meta_env();
@@ -9471,24 +9508,24 @@ import {
9471
9508
  } from "@excalidraw/element";
9472
9509
  import {
9473
9510
  rangeIncludesValue,
9474
- pointFrom as pointFrom9,
9475
- pointRotateRads as pointRotateRads8,
9511
+ pointFrom as pointFrom10,
9512
+ pointRotateRads as pointRotateRads9,
9476
9513
  rangeInclusive
9477
9514
  } from "@excalidraw/math";
9478
9515
  var getNonLinearElementRelativePoints = (element) => {
9479
9516
  if (element.type === "diamond") {
9480
9517
  return [
9481
- pointFrom9(element.width / 2, 0),
9482
- pointFrom9(element.width, element.height / 2),
9483
- pointFrom9(element.width / 2, element.height),
9484
- pointFrom9(0, element.height / 2)
9518
+ pointFrom10(element.width / 2, 0),
9519
+ pointFrom10(element.width, element.height / 2),
9520
+ pointFrom10(element.width / 2, element.height),
9521
+ pointFrom10(0, element.height / 2)
9485
9522
  ];
9486
9523
  }
9487
9524
  return [
9488
- pointFrom9(0, 0),
9489
- pointFrom9(0 + element.width, 0),
9490
- pointFrom9(0 + element.width, element.height),
9491
- pointFrom9(0, element.height)
9525
+ pointFrom10(0, 0),
9526
+ pointFrom10(0 + element.width, 0),
9527
+ pointFrom10(0 + element.width, element.height),
9528
+ pointFrom10(0, element.height)
9492
9529
  ];
9493
9530
  };
9494
9531
  var getElementRelativePoints = (element) => {
@@ -9522,9 +9559,9 @@ var getMinMaxPoints = (points) => {
9522
9559
  var getRotatedBBox = (element) => {
9523
9560
  const points = getElementRelativePoints(element);
9524
9561
  const { cx, cy } = getMinMaxPoints(points);
9525
- const centerPoint = pointFrom9(cx, cy);
9562
+ const centerPoint = pointFrom10(cx, cy);
9526
9563
  const rotatedPoints = points.map(
9527
- (p) => pointRotateRads8(p, centerPoint, element.angle)
9564
+ (p) => pointRotateRads9(p, centerPoint, element.angle)
9528
9565
  );
9529
9566
  const { minX, minY, maxX, maxY } = getMinMaxPoints(rotatedPoints);
9530
9567
  return [
@@ -9826,6 +9863,55 @@ var getNewGroupIdsForDuplication = (groupIds, editingGroupId, mapper) => {
9826
9863
  }
9827
9864
  return copy;
9828
9865
  };
9866
+ var getSelectedElementsByGroup = (selectedElements, elementsMap, appState) => {
9867
+ const selectedGroupIds = getSelectedGroupIds(appState);
9868
+ const unboundElements = selectedElements.filter(
9869
+ (element) => !isBoundToContainer(element)
9870
+ );
9871
+ const groups = /* @__PURE__ */ new Map();
9872
+ const elements = /* @__PURE__ */ new Map();
9873
+ const addToElementsMap = (element) => {
9874
+ const currentElementMembers = elements.get(element.id) || [];
9875
+ const boundTextElement = getBoundTextElement(element, elementsMap);
9876
+ if (boundTextElement) {
9877
+ currentElementMembers.push(boundTextElement);
9878
+ }
9879
+ elements.set(element.id, [...currentElementMembers, element]);
9880
+ };
9881
+ const addToGroupsMap = (element, groupId) => {
9882
+ const currentGroupMembers = groups.get(groupId) || [];
9883
+ const boundTextElement = getBoundTextElement(element, elementsMap);
9884
+ if (boundTextElement) {
9885
+ currentGroupMembers.push(boundTextElement);
9886
+ }
9887
+ groups.set(groupId, [...currentGroupMembers, element]);
9888
+ };
9889
+ const handleSingleSelectedGroupCase = (element, selectedGroupId) => {
9890
+ const indexOfSelectedGroupId = element.groupIds.indexOf(selectedGroupId, 0);
9891
+ const nestedGroupCount = element.groupIds.slice(
9892
+ 0,
9893
+ indexOfSelectedGroupId
9894
+ ).length;
9895
+ return nestedGroupCount > 0 ? addToGroupsMap(element, element.groupIds[indexOfSelectedGroupId - 1]) : addToElementsMap(element);
9896
+ };
9897
+ const isAllInSameGroup = selectedElements.every(
9898
+ (element) => isSelectedViaGroup(appState, element)
9899
+ );
9900
+ unboundElements.forEach((element) => {
9901
+ const selectedGroupId = getSelectedGroupIdForElement(
9902
+ element,
9903
+ appState.selectedGroupIds
9904
+ );
9905
+ if (!selectedGroupId) {
9906
+ addToElementsMap(element);
9907
+ } else if (selectedGroupIds.length === 1 && isAllInSameGroup) {
9908
+ handleSingleSelectedGroupCase(element, selectedGroupId);
9909
+ } else {
9910
+ addToGroupsMap(element, selectedGroupId);
9911
+ }
9912
+ });
9913
+ return Array.from(groups.values()).concat(Array.from(elements.values()));
9914
+ };
9829
9915
 
9830
9916
  // src/selection.ts
9831
9917
  var excludeElementsInFramesFromSelection = (selectedElements) => {
@@ -10039,9 +10125,9 @@ var elementOverlapsWithFrame = (element, frame, elementsMap) => {
10039
10125
  var isCursorInFrame = (cursorCoords, frame, elementsMap) => {
10040
10126
  const [fx1, fy1, fx2, fy2] = getElementAbsoluteCoords2(frame, elementsMap);
10041
10127
  return isPointWithinBounds2(
10042
- pointFrom10(fx1, fy1),
10043
- pointFrom10(cursorCoords.x, cursorCoords.y),
10044
- pointFrom10(fx2, fy2)
10128
+ pointFrom11(fx1, fy1),
10129
+ pointFrom11(cursorCoords.x, cursorCoords.y),
10130
+ pointFrom11(fx2, fy2)
10045
10131
  );
10046
10132
  };
10047
10133
  var groupsAreAtLeastIntersectingTheFrame = (elements, groupIds, frame) => {
@@ -10513,6 +10599,11 @@ var getCanvasPadding = (element) => {
10513
10599
  return element.strokeWidth * 12;
10514
10600
  case "text":
10515
10601
  return element.fontSize / 2;
10602
+ case "arrow":
10603
+ if (element.endArrowhead || element.endArrowhead) {
10604
+ return 40;
10605
+ }
10606
+ return 20;
10516
10607
  default:
10517
10608
  return 20;
10518
10609
  }
@@ -11395,26 +11486,26 @@ var generateLinearCollisionShape = (element) => {
11395
11486
  switch (element.type) {
11396
11487
  case "line":
11397
11488
  case "arrow": {
11398
- const points = element.points.length ? element.points : [pointFrom11(0, 0)];
11489
+ const points = element.points.length ? element.points : [pointFrom12(0, 0)];
11399
11490
  if (isElbowArrow(element)) {
11400
11491
  return generator.path(generateElbowArrowShape(points, 16), options).sets[0].ops;
11401
11492
  } else if (!element.roundness) {
11402
11493
  return points.map((point, idx) => {
11403
- const p = pointRotateRads9(
11404
- pointFrom11(element.x + point[0], element.y + point[1]),
11494
+ const p = pointRotateRads10(
11495
+ pointFrom12(element.x + point[0], element.y + point[1]),
11405
11496
  center,
11406
11497
  element.angle
11407
11498
  );
11408
11499
  return {
11409
11500
  op: idx === 0 ? "move" : "lineTo",
11410
- data: pointFrom11(p[0] - element.x, p[1] - element.y)
11501
+ data: pointFrom12(p[0] - element.x, p[1] - element.y)
11411
11502
  };
11412
11503
  });
11413
11504
  }
11414
11505
  return generator.curve(points, options).sets[0].ops.slice(0, element.points.length).map((op, i) => {
11415
11506
  if (i === 0) {
11416
- const p = pointRotateRads9(
11417
- pointFrom11(
11507
+ const p = pointRotateRads10(
11508
+ pointFrom12(
11418
11509
  element.x + op.data[0],
11419
11510
  element.y + op.data[1]
11420
11511
  ),
@@ -11423,30 +11514,30 @@ var generateLinearCollisionShape = (element) => {
11423
11514
  );
11424
11515
  return {
11425
11516
  op: "move",
11426
- data: pointFrom11(p[0] - element.x, p[1] - element.y)
11517
+ data: pointFrom12(p[0] - element.x, p[1] - element.y)
11427
11518
  };
11428
11519
  }
11429
11520
  return {
11430
11521
  op: "bcurveTo",
11431
11522
  data: [
11432
- pointRotateRads9(
11433
- pointFrom11(
11523
+ pointRotateRads10(
11524
+ pointFrom12(
11434
11525
  element.x + op.data[0],
11435
11526
  element.y + op.data[1]
11436
11527
  ),
11437
11528
  center,
11438
11529
  element.angle
11439
11530
  ),
11440
- pointRotateRads9(
11441
- pointFrom11(
11531
+ pointRotateRads10(
11532
+ pointFrom12(
11442
11533
  element.x + op.data[2],
11443
11534
  element.y + op.data[3]
11444
11535
  ),
11445
11536
  center,
11446
11537
  element.angle
11447
11538
  ),
11448
- pointRotateRads9(
11449
- pointFrom11(
11539
+ pointRotateRads10(
11540
+ pointFrom12(
11450
11541
  element.x + op.data[4],
11451
11542
  element.y + op.data[5]
11452
11543
  ),
@@ -11454,7 +11545,7 @@ var generateLinearCollisionShape = (element) => {
11454
11545
  element.angle
11455
11546
  )
11456
11547
  ].map(
11457
- (p) => pointFrom11(p[0] - element.x, p[1] - element.y)
11548
+ (p) => pointFrom12(p[0] - element.x, p[1] - element.y)
11458
11549
  ).flat()
11459
11550
  };
11460
11551
  });
@@ -11469,8 +11560,8 @@ var generateLinearCollisionShape = (element) => {
11469
11560
  );
11470
11561
  return generator.curve(simplifiedPoints, options).sets[0].ops.slice(0, element.points.length).map((op, i) => {
11471
11562
  if (i === 0) {
11472
- const p = pointRotateRads9(
11473
- pointFrom11(
11563
+ const p = pointRotateRads10(
11564
+ pointFrom12(
11474
11565
  element.x + op.data[0],
11475
11566
  element.y + op.data[1]
11476
11567
  ),
@@ -11479,30 +11570,30 @@ var generateLinearCollisionShape = (element) => {
11479
11570
  );
11480
11571
  return {
11481
11572
  op: "move",
11482
- data: pointFrom11(p[0] - element.x, p[1] - element.y)
11573
+ data: pointFrom12(p[0] - element.x, p[1] - element.y)
11483
11574
  };
11484
11575
  }
11485
11576
  return {
11486
11577
  op: "bcurveTo",
11487
11578
  data: [
11488
- pointRotateRads9(
11489
- pointFrom11(
11579
+ pointRotateRads10(
11580
+ pointFrom12(
11490
11581
  element.x + op.data[0],
11491
11582
  element.y + op.data[1]
11492
11583
  ),
11493
11584
  center,
11494
11585
  element.angle
11495
11586
  ),
11496
- pointRotateRads9(
11497
- pointFrom11(
11587
+ pointRotateRads10(
11588
+ pointFrom12(
11498
11589
  element.x + op.data[2],
11499
11590
  element.y + op.data[3]
11500
11591
  ),
11501
11592
  center,
11502
11593
  element.angle
11503
11594
  ),
11504
- pointRotateRads9(
11505
- pointFrom11(
11595
+ pointRotateRads10(
11596
+ pointFrom12(
11506
11597
  element.x + op.data[4],
11507
11598
  element.y + op.data[5]
11508
11599
  ),
@@ -11510,7 +11601,7 @@ var generateLinearCollisionShape = (element) => {
11510
11601
  element.angle
11511
11602
  )
11512
11603
  ].map(
11513
- (p) => pointFrom11(p[0] - element.x, p[1] - element.y)
11604
+ (p) => pointFrom12(p[0] - element.x, p[1] - element.y)
11514
11605
  ).flat()
11515
11606
  };
11516
11607
  });
@@ -11607,7 +11698,7 @@ var generateElementShape = (element, generator, {
11607
11698
  case "arrow": {
11608
11699
  let shape;
11609
11700
  const options = generateRoughOptions(element);
11610
- const points = element.points.length ? element.points : [pointFrom11(0, 0)];
11701
+ const points = element.points.length ? element.points : [pointFrom12(0, 0)];
11611
11702
  if (isElbowArrow(element)) {
11612
11703
  if (!points.every(
11613
11704
  (point) => Math.abs(point[0]) <= 1e6 && Math.abs(point[1]) <= 1e6
@@ -11769,14 +11860,14 @@ var getElementShape = (element, elementsMap) => {
11769
11860
  return shouldTestInside(element) ? getClosedCurveShape(
11770
11861
  element,
11771
11862
  roughShape,
11772
- pointFrom11(element.x, element.y),
11863
+ pointFrom12(element.x, element.y),
11773
11864
  element.angle,
11774
- pointFrom11(cx, cy)
11865
+ pointFrom12(cx, cy)
11775
11866
  ) : getCurveShape(
11776
11867
  roughShape,
11777
- pointFrom11(element.x, element.y),
11868
+ pointFrom12(element.x, element.y),
11778
11869
  element.angle,
11779
- pointFrom11(cx, cy)
11870
+ pointFrom12(cx, cy)
11780
11871
  );
11781
11872
  }
11782
11873
  case "ellipse":
@@ -11785,7 +11876,7 @@ var getElementShape = (element, elementsMap) => {
11785
11876
  const [, , , , cx, cy] = getElementAbsoluteCoords2(element, elementsMap);
11786
11877
  return getFreedrawShape(
11787
11878
  element,
11788
- pointFrom11(cx, cy),
11879
+ pointFrom12(cx, cy),
11789
11880
  shouldTestInside(element)
11790
11881
  );
11791
11882
  }
@@ -11804,9 +11895,9 @@ var toggleLinePolygonState = (element, nextPolygonState) => {
11804
11895
  firstPoint[1] - lastPoint[1]
11805
11896
  );
11806
11897
  if (distance3 > LINE_POLYGON_POINT_MERGE_DISTANCE || updatedPoints.length < 4) {
11807
- updatedPoints.push(pointFrom11(firstPoint[0], firstPoint[1]));
11898
+ updatedPoints.push(pointFrom12(firstPoint[0], firstPoint[1]));
11808
11899
  } else {
11809
- updatedPoints[updatedPoints.length - 1] = pointFrom11(
11900
+ updatedPoints[updatedPoints.length - 1] = pointFrom12(
11810
11901
  firstPoint[0],
11811
11902
  firstPoint[1]
11812
11903
  );
@@ -11860,9 +11951,9 @@ var ElementBounds = class _ElementBounds {
11860
11951
  if (isFreeDrawElement(element)) {
11861
11952
  const [minX, minY, maxX, maxY] = getBoundsFromPoints(
11862
11953
  element.points.map(
11863
- ([x, y]) => pointRotateRads10(
11864
- pointFrom12(x, y),
11865
- pointFrom12(cx - element.x, cy - element.y),
11954
+ ([x, y]) => pointRotateRads11(
11955
+ pointFrom13(x, y),
11956
+ pointFrom13(cx - element.x, cy - element.y),
11866
11957
  element.angle
11867
11958
  )
11868
11959
  )
@@ -11876,24 +11967,24 @@ var ElementBounds = class _ElementBounds {
11876
11967
  } else if (isLinearElement(element)) {
11877
11968
  bounds = getLinearElementRotatedBounds(element, cx, cy, elementsMap);
11878
11969
  } else if (element.type === "diamond") {
11879
- const [x11, y11] = pointRotateRads10(
11880
- pointFrom12(cx, y1),
11881
- pointFrom12(cx, cy),
11970
+ const [x11, y11] = pointRotateRads11(
11971
+ pointFrom13(cx, y1),
11972
+ pointFrom13(cx, cy),
11882
11973
  element.angle
11883
11974
  );
11884
- const [x12, y12] = pointRotateRads10(
11885
- pointFrom12(cx, y2),
11886
- pointFrom12(cx, cy),
11975
+ const [x12, y12] = pointRotateRads11(
11976
+ pointFrom13(cx, y2),
11977
+ pointFrom13(cx, cy),
11887
11978
  element.angle
11888
11979
  );
11889
- const [x22, y22] = pointRotateRads10(
11890
- pointFrom12(x1, cy),
11891
- pointFrom12(cx, cy),
11980
+ const [x22, y22] = pointRotateRads11(
11981
+ pointFrom13(x1, cy),
11982
+ pointFrom13(cx, cy),
11892
11983
  element.angle
11893
11984
  );
11894
- const [x21, y21] = pointRotateRads10(
11895
- pointFrom12(x2, cy),
11896
- pointFrom12(cx, cy),
11985
+ const [x21, y21] = pointRotateRads11(
11986
+ pointFrom13(x2, cy),
11987
+ pointFrom13(cx, cy),
11897
11988
  element.angle
11898
11989
  );
11899
11990
  const minX = Math.min(x11, x12, x22, x21);
@@ -11910,24 +12001,24 @@ var ElementBounds = class _ElementBounds {
11910
12001
  const hh = Math.hypot(h * cos, w * sin);
11911
12002
  bounds = [cx - ww, cy - hh, cx + ww, cy + hh];
11912
12003
  } else {
11913
- const [x11, y11] = pointRotateRads10(
11914
- pointFrom12(x1, y1),
11915
- pointFrom12(cx, cy),
12004
+ const [x11, y11] = pointRotateRads11(
12005
+ pointFrom13(x1, y1),
12006
+ pointFrom13(cx, cy),
11916
12007
  element.angle
11917
12008
  );
11918
- const [x12, y12] = pointRotateRads10(
11919
- pointFrom12(x1, y2),
11920
- pointFrom12(cx, cy),
12009
+ const [x12, y12] = pointRotateRads11(
12010
+ pointFrom13(x1, y2),
12011
+ pointFrom13(cx, cy),
11921
12012
  element.angle
11922
12013
  );
11923
- const [x22, y22] = pointRotateRads10(
11924
- pointFrom12(x2, y2),
11925
- pointFrom12(cx, cy),
12014
+ const [x22, y22] = pointRotateRads11(
12015
+ pointFrom13(x2, y2),
12016
+ pointFrom13(cx, cy),
11926
12017
  element.angle
11927
12018
  );
11928
- const [x21, y21] = pointRotateRads10(
11929
- pointFrom12(x2, y1),
11930
- pointFrom12(cx, cy),
12019
+ const [x21, y21] = pointRotateRads11(
12020
+ pointFrom13(x2, y1),
12021
+ pointFrom13(cx, cy),
11931
12022
  element.angle
11932
12023
  );
11933
12024
  const minX = Math.min(x11, x12, x22, x21);
@@ -11981,7 +12072,7 @@ var getElementLineSegments = (element, elementsMap) => {
11981
12072
  element,
11982
12073
  elementsMap
11983
12074
  );
11984
- const center = pointFrom12(cx, cy);
12075
+ const center = pointFrom13(cx, cy);
11985
12076
  if (shape.type === "polycurve") {
11986
12077
  const curves = shape.data;
11987
12078
  const points = curves.map((curve4) => pointsOnBezierCurves(curve4, 10)).flat();
@@ -11990,8 +12081,8 @@ var getElementLineSegments = (element, elementsMap) => {
11990
12081
  while (i < points.length - 1) {
11991
12082
  segments.push(
11992
12083
  lineSegment5(
11993
- pointFrom12(points[i][0], points[i][1]),
11994
- pointFrom12(points[i + 1][0], points[i + 1][1])
12084
+ pointFrom13(points[i][0], points[i][1]),
12085
+ pointFrom13(points[i + 1][0], points[i + 1][1])
11995
12086
  )
11996
12087
  );
11997
12088
  i++;
@@ -12014,10 +12105,10 @@ var getElementLineSegments = (element, elementsMap) => {
12014
12105
  const container = getContainerElement(element, elementsMap);
12015
12106
  if (container && isLinearElement(container)) {
12016
12107
  const segments2 = [
12017
- lineSegment5(pointFrom12(x1, y1), pointFrom12(x2, y1)),
12018
- lineSegment5(pointFrom12(x2, y1), pointFrom12(x2, y2)),
12019
- lineSegment5(pointFrom12(x2, y2), pointFrom12(x1, y2)),
12020
- lineSegment5(pointFrom12(x1, y2), pointFrom12(x1, y1))
12108
+ lineSegment5(pointFrom13(x1, y1), pointFrom13(x2, y1)),
12109
+ lineSegment5(pointFrom13(x2, y1), pointFrom13(x2, y2)),
12110
+ lineSegment5(pointFrom13(x2, y2), pointFrom13(x1, y2)),
12111
+ lineSegment5(pointFrom13(x1, y2), pointFrom13(x1, y1))
12021
12112
  ];
12022
12113
  return segments2;
12023
12114
  }
@@ -12040,7 +12131,7 @@ var getElementLineSegments = (element, elementsMap) => {
12040
12131
  [cx, y2],
12041
12132
  [x1, cy],
12042
12133
  [x2, cy]
12043
- ].map((point) => pointRotateRads10(point, center, element.angle));
12134
+ ].map((point) => pointRotateRads11(point, center, element.angle));
12044
12135
  return [
12045
12136
  lineSegment5(nw, ne),
12046
12137
  lineSegment5(sw, se2),
@@ -12058,8 +12149,8 @@ var _isRectanguloidElement = (element) => {
12058
12149
  var getRotatedSides = (sides, center, angle) => {
12059
12150
  return sides.map((side) => {
12060
12151
  return lineSegment5(
12061
- pointRotateRads10(side[0], center, angle),
12062
- pointRotateRads10(side[1], center, angle)
12152
+ pointRotateRads11(side[0], center, angle),
12153
+ pointRotateRads11(side[1], center, angle)
12063
12154
  );
12064
12155
  });
12065
12156
  };
@@ -12070,13 +12161,13 @@ var getSegmentsOnCurve = (curve4, center, angle) => {
12070
12161
  while (i < points.length - 1) {
12071
12162
  segments.push(
12072
12163
  lineSegment5(
12073
- pointRotateRads10(
12074
- pointFrom12(points[i][0], points[i][1]),
12164
+ pointRotateRads11(
12165
+ pointFrom13(points[i][0], points[i][1]),
12075
12166
  center,
12076
12167
  angle
12077
12168
  ),
12078
- pointRotateRads10(
12079
- pointFrom12(points[i + 1][0], points[i + 1][1]),
12169
+ pointRotateRads11(
12170
+ pointFrom13(points[i + 1][0], points[i + 1][1]),
12080
12171
  center,
12081
12172
  angle
12082
12173
  )
@@ -12087,7 +12178,7 @@ var getSegmentsOnCurve = (curve4, center, angle) => {
12087
12178
  return segments;
12088
12179
  };
12089
12180
  var getSegmentsOnEllipse = (ellipse4) => {
12090
- const center = pointFrom12(
12181
+ const center = pointFrom13(
12091
12182
  ellipse4.x + ellipse4.width / 2,
12092
12183
  ellipse4.y + ellipse4.height / 2
12093
12184
  );
@@ -12101,7 +12192,7 @@ var getSegmentsOnEllipse = (ellipse4) => {
12101
12192
  const t = i * deltaT;
12102
12193
  const x = center[0] + a2 * Math.cos(t);
12103
12194
  const y = center[1] + b2 * Math.sin(t);
12104
- points.push(pointRotateRads10(pointFrom12(x, y), center, ellipse4.angle));
12195
+ points.push(pointRotateRads11(pointFrom13(x, y), center, ellipse4.angle));
12105
12196
  }
12106
12197
  for (let i = 0; i < points.length - 1; i++) {
12107
12198
  segments.push(lineSegment5(points[i], points[i + 1]));
@@ -12184,7 +12275,7 @@ var getCubicBezierCurveBound = (p0, p1, p2, p3) => {
12184
12275
  return [minX, minY, maxX, maxY];
12185
12276
  };
12186
12277
  var getMinMaxXYFromCurvePathOps = (ops, transformXY) => {
12187
- let currentP = pointFrom12(0, 0);
12278
+ let currentP = pointFrom13(0, 0);
12188
12279
  const { minX, minY, maxX, maxY } = ops.reduce(
12189
12280
  (limits, { op, data }) => {
12190
12281
  if (op === "move") {
@@ -12192,9 +12283,9 @@ var getMinMaxXYFromCurvePathOps = (ops, transformXY) => {
12192
12283
  invariant7(p != null, "Op data is not a point");
12193
12284
  currentP = p;
12194
12285
  } else if (op === "bcurveTo") {
12195
- const _p1 = pointFrom12(data[0], data[1]);
12196
- const _p2 = pointFrom12(data[2], data[3]);
12197
- const _p3 = pointFrom12(data[4], data[5]);
12286
+ const _p1 = pointFrom13(data[0], data[1]);
12287
+ const _p2 = pointFrom13(data[2], data[3]);
12288
+ const _p3 = pointFrom13(data[4], data[5]);
12198
12289
  const p1 = transformXY ? transformXY(_p1) : _p1;
12199
12290
  const p2 = transformXY ? transformXY(_p2) : _p2;
12200
12291
  const p3 = transformXY ? transformXY(_p3) : _p3;
@@ -12276,17 +12367,17 @@ var getArrowheadPoints = (element, shape, position, arrowhead) => {
12276
12367
  const index = position === "start" ? 1 : ops.length - 1;
12277
12368
  const data = ops[index].data;
12278
12369
  invariant7(data.length === 6, "Op data length is not 6");
12279
- const p3 = pointFrom12(data[4], data[5]);
12280
- const p2 = pointFrom12(data[2], data[3]);
12281
- const p1 = pointFrom12(data[0], data[1]);
12370
+ const p3 = pointFrom13(data[4], data[5]);
12371
+ const p2 = pointFrom13(data[2], data[3]);
12372
+ const p1 = pointFrom13(data[0], data[1]);
12282
12373
  const prevOp = ops[index - 1];
12283
- let p0 = pointFrom12(0, 0);
12374
+ let p0 = pointFrom13(0, 0);
12284
12375
  if (prevOp.op === "move") {
12285
12376
  const p = pointFromArray3(prevOp.data);
12286
12377
  invariant7(p != null, "Op data is not a point");
12287
12378
  p0 = p;
12288
12379
  } else if (prevOp.op === "bcurveTo") {
12289
- p0 = pointFrom12(prevOp.data[4], prevOp.data[5]);
12380
+ p0 = pointFrom13(prevOp.data[4], prevOp.data[5]);
12290
12381
  }
12291
12382
  const equation = (t, idx) => Math.pow(1 - t, 3) * p3[idx] + 3 * t * Math.pow(1 - t, 2) * p2[idx] + 3 * Math.pow(t, 2) * (1 - t) * p1[idx] + p0[idx] * Math.pow(t, 3);
12292
12383
  const [x2, y2] = position === "start" ? p0 : p3;
@@ -12311,26 +12402,26 @@ var getArrowheadPoints = (element, shape, position, arrowhead) => {
12311
12402
  }
12312
12403
  const angle = getArrowheadAngle(arrowhead);
12313
12404
  if (arrowhead === "crowfoot_many" || arrowhead === "crowfoot_one_or_many") {
12314
- const [x32, y32] = pointRotateRads10(
12315
- pointFrom12(x2, y2),
12316
- pointFrom12(xs, ys),
12405
+ const [x32, y32] = pointRotateRads11(
12406
+ pointFrom13(x2, y2),
12407
+ pointFrom13(xs, ys),
12317
12408
  degreesToRadians(-angle)
12318
12409
  );
12319
- const [x42, y42] = pointRotateRads10(
12320
- pointFrom12(x2, y2),
12321
- pointFrom12(xs, ys),
12410
+ const [x42, y42] = pointRotateRads11(
12411
+ pointFrom13(x2, y2),
12412
+ pointFrom13(xs, ys),
12322
12413
  degreesToRadians(angle)
12323
12414
  );
12324
12415
  return [xs, ys, x32, y32, x42, y42];
12325
12416
  }
12326
- const [x3, y3] = pointRotateRads10(
12327
- pointFrom12(xs, ys),
12328
- pointFrom12(x2, y2),
12417
+ const [x3, y3] = pointRotateRads11(
12418
+ pointFrom13(xs, ys),
12419
+ pointFrom13(x2, y2),
12329
12420
  -angle * Math.PI / 180
12330
12421
  );
12331
- const [x4, y4] = pointRotateRads10(
12332
- pointFrom12(xs, ys),
12333
- pointFrom12(x2, y2),
12422
+ const [x4, y4] = pointRotateRads11(
12423
+ pointFrom13(xs, ys),
12424
+ pointFrom13(x2, y2),
12334
12425
  degreesToRadians(angle)
12335
12426
  );
12336
12427
  if (arrowhead === "diamond" || arrowhead === "diamond_outline") {
@@ -12338,16 +12429,16 @@ var getArrowheadPoints = (element, shape, position, arrowhead) => {
12338
12429
  let oy;
12339
12430
  if (position === "start") {
12340
12431
  const [px, py] = element.points.length > 1 ? element.points[1] : [0, 0];
12341
- [ox, oy] = pointRotateRads10(
12342
- pointFrom12(x2 + minSize * 2, y2),
12343
- pointFrom12(x2, y2),
12432
+ [ox, oy] = pointRotateRads11(
12433
+ pointFrom13(x2 + minSize * 2, y2),
12434
+ pointFrom13(x2, y2),
12344
12435
  Math.atan2(py - y2, px - x2)
12345
12436
  );
12346
12437
  } else {
12347
12438
  const [px, py] = element.points.length > 1 ? element.points[element.points.length - 2] : [0, 0];
12348
- [ox, oy] = pointRotateRads10(
12349
- pointFrom12(x2 - minSize * 2, y2),
12350
- pointFrom12(x2, y2),
12439
+ [ox, oy] = pointRotateRads11(
12440
+ pointFrom13(x2 - minSize * 2, y2),
12441
+ pointFrom13(x2, y2),
12351
12442
  Math.atan2(y2 - py, x2 - px)
12352
12443
  );
12353
12444
  }
@@ -12376,9 +12467,9 @@ var getLinearElementRotatedBounds = (element, cx, cy, elementsMap) => {
12376
12467
  const boundTextElement = getBoundTextElement(element, elementsMap);
12377
12468
  if (element.points.length < 2) {
12378
12469
  const [pointX, pointY] = element.points[0];
12379
- const [x, y] = pointRotateRads10(
12380
- pointFrom12(element.x + pointX, element.y + pointY),
12381
- pointFrom12(cx, cy),
12470
+ const [x, y] = pointRotateRads11(
12471
+ pointFrom13(element.x + pointX, element.y + pointY),
12472
+ pointFrom13(cx, cy),
12382
12473
  element.angle
12383
12474
  );
12384
12475
  let coords2 = [x, y, x, y];
@@ -12401,9 +12492,9 @@ var getLinearElementRotatedBounds = (element, cx, cy, elementsMap) => {
12401
12492
  const cachedShape = ShapeCache.get(element)?.[0];
12402
12493
  const shape = cachedShape ?? generateLinearElementShape(element);
12403
12494
  const ops = getCurvePathOps(shape);
12404
- const transformXY = ([x, y]) => pointRotateRads10(
12405
- pointFrom12(element.x + x, element.y + y),
12406
- pointFrom12(cx, cy),
12495
+ const transformXY = ([x, y]) => pointRotateRads11(
12496
+ pointFrom13(element.x + x, element.y + y),
12497
+ pointFrom13(cx, cy),
12407
12498
  element.angle
12408
12499
  );
12409
12500
  const res = getMinMaxXYFromCurvePathOps(ops, transformXY);
@@ -12514,8 +12605,8 @@ var getClosestElementBounds = (elements, from) => {
12514
12605
  elements.forEach((element) => {
12515
12606
  const [x1, y1, x2, y2] = getElementBounds(element, elementsMap);
12516
12607
  const distance3 = pointDistance7(
12517
- pointFrom12((x1 + x2) / 2, (y1 + y2) / 2),
12518
- pointFrom12(from.x, from.y)
12608
+ pointFrom13((x1 + x2) / 2, (y1 + y2) / 2),
12609
+ pointFrom13(from.x, from.y)
12519
12610
  );
12520
12611
  if (distance3 < minDistance) {
12521
12612
  minDistance = distance3;
@@ -12551,7 +12642,7 @@ var getVisibleSceneBounds = ({
12551
12642
  -scrollY + height / zoom.value
12552
12643
  ];
12553
12644
  };
12554
- var getCenterForBounds = (bounds) => pointFrom12(
12645
+ var getCenterForBounds = (bounds) => pointFrom13(
12555
12646
  bounds[0] + (bounds[2] - bounds[0]) / 2,
12556
12647
  bounds[1] + (bounds[3] - bounds[1]) / 2
12557
12648
  );
@@ -12565,23 +12656,23 @@ var aabbForElement = (element, elementsMap, offset) => {
12565
12656
  midY: element.y + element.height / 2
12566
12657
  };
12567
12658
  const center = elementCenterPoint(element, elementsMap);
12568
- const [topLeftX, topLeftY] = pointRotateRads10(
12569
- pointFrom12(bbox.minX, bbox.minY),
12659
+ const [topLeftX, topLeftY] = pointRotateRads11(
12660
+ pointFrom13(bbox.minX, bbox.minY),
12570
12661
  center,
12571
12662
  element.angle
12572
12663
  );
12573
- const [topRightX, topRightY] = pointRotateRads10(
12574
- pointFrom12(bbox.maxX, bbox.minY),
12664
+ const [topRightX, topRightY] = pointRotateRads11(
12665
+ pointFrom13(bbox.maxX, bbox.minY),
12575
12666
  center,
12576
12667
  element.angle
12577
12668
  );
12578
- const [bottomRightX, bottomRightY] = pointRotateRads10(
12579
- pointFrom12(bbox.maxX, bbox.maxY),
12669
+ const [bottomRightX, bottomRightY] = pointRotateRads11(
12670
+ pointFrom13(bbox.maxX, bbox.maxY),
12580
12671
  center,
12581
12672
  element.angle
12582
12673
  );
12583
- const [bottomLeftX, bottomLeftY] = pointRotateRads10(
12584
- pointFrom12(bbox.minX, bbox.maxY),
12674
+ const [bottomLeftX, bottomLeftY] = pointRotateRads11(
12675
+ pointFrom13(bbox.minX, bbox.maxY),
12585
12676
  center,
12586
12677
  element.angle
12587
12678
  );
@@ -12613,7 +12704,7 @@ var doBoundsIntersect = (bounds1, bounds2) => {
12613
12704
  };
12614
12705
  var elementCenterPoint = (element, elementsMap, xOffset = 0, yOffset = 0) => {
12615
12706
  const [x, y] = getCenterForBounds(getElementBounds(element, elementsMap));
12616
- return pointFrom12(x + xOffset, y + yOffset);
12707
+ return pointFrom13(x + xOffset, y + yOffset);
12617
12708
  };
12618
12709
 
12619
12710
  // src/sizeHelpers.ts
@@ -12742,11 +12833,11 @@ var getNormalizedDimensions = (element) => {
12742
12833
 
12743
12834
  // src/align.ts
12744
12835
  init_define_import_meta_env();
12745
- var alignElements = (selectedElements, alignment, scene) => {
12746
- const elementsMap = scene.getNonDeletedElementsMap();
12747
- const groups = getMaximumGroups(
12836
+ var alignElements = (selectedElements, alignment, scene, appState) => {
12837
+ const groups = getSelectedElementsByGroup(
12748
12838
  selectedElements,
12749
- elementsMap
12839
+ scene.getNonDeletedElementsMap(),
12840
+ appState
12750
12841
  );
12751
12842
  const selectionBoundingBox = getCommonBoundingBox(selectedElements);
12752
12843
  return groups.flatMap((group) => {
@@ -13182,8 +13273,9 @@ var Store = class {
13182
13273
  constructor(app) {
13183
13274
  this.app = app;
13184
13275
  }
13185
- // internally used by history
13276
+ // for internal use by history
13186
13277
  onDurableIncrementEmitter = new Emitter();
13278
+ // for public use as part of onIncrement API
13187
13279
  onStoreIncrementEmitter = new Emitter();
13188
13280
  scheduledMacroActions = /* @__PURE__ */ new Set();
13189
13281
  scheduledMicroActions = [];
@@ -13439,7 +13531,7 @@ var EphemeralIncrement = class extends StoreIncrement {
13439
13531
  this.change = change;
13440
13532
  }
13441
13533
  };
13442
- var StoreDelta = class {
13534
+ var StoreDelta = class _StoreDelta {
13443
13535
  constructor(id, elements, appState) {
13444
13536
  this.id = id;
13445
13537
  this.elements = elements;
@@ -13477,10 +13569,23 @@ var StoreDelta = class {
13477
13569
  */
13478
13570
  static load({
13479
13571
  id,
13480
- elements: { added, removed, updated }
13572
+ elements: { added, removed, updated },
13573
+ appState: { delta: appStateDelta }
13481
13574
  }) {
13482
13575
  const elements = ElementsDelta.create(added, removed, updated);
13483
- return new this(id, elements, AppStateDelta.empty());
13576
+ const appState = AppStateDelta.create(appStateDelta);
13577
+ return new this(id, elements, appState);
13578
+ }
13579
+ /**
13580
+ * Squash the passed deltas into the aggregated delta instance.
13581
+ */
13582
+ static squash(...deltas) {
13583
+ const aggregatedDelta = _StoreDelta.empty();
13584
+ for (const delta of deltas) {
13585
+ aggregatedDelta.elements.squash(delta.elements);
13586
+ aggregatedDelta.appState.squash(delta.appState);
13587
+ }
13588
+ return aggregatedDelta;
13484
13589
  }
13485
13590
  /**
13486
13591
  * Inverse store delta, creates new instance of `StoreDelta`.
@@ -13491,9 +13596,7 @@ var StoreDelta = class {
13491
13596
  /**
13492
13597
  * Apply the delta to the passed elements and appState, does not modify the snapshot.
13493
13598
  */
13494
- static applyTo(delta, elements, appState, options = {
13495
- excludedProperties: /* @__PURE__ */ new Set()
13496
- }) {
13599
+ static applyTo(delta, elements, appState, options) {
13497
13600
  const [nextElements, elementsContainVisibleChange] = delta.elements.applyTo(
13498
13601
  elements,
13499
13602
  StoreSnapshot.empty().elements,
@@ -13519,6 +13622,9 @@ var StoreDelta = class {
13519
13622
  }
13520
13623
  );
13521
13624
  }
13625
+ static empty() {
13626
+ return _StoreDelta.create(ElementsDelta.empty(), AppStateDelta.empty());
13627
+ }
13522
13628
  isEmpty() {
13523
13629
  return this.elements.isEmpty() && this.appState.isEmpty();
13524
13630
  }
@@ -13759,8 +13865,7 @@ var getDefaultObservedAppState = () => {
13759
13865
  viewBackgroundColor: COLOR_PALETTE2.white,
13760
13866
  selectedElementIds: {},
13761
13867
  selectedGroupIds: {},
13762
- editingLinearElementId: null,
13763
- selectedLinearElementId: null,
13868
+ selectedLinearElement: null,
13764
13869
  croppingElementId: null,
13765
13870
  activeLockedId: null,
13766
13871
  lockedMultiSelections: {}
@@ -13776,10 +13881,10 @@ var getObservedAppState = (appState) => {
13776
13881
  croppingElementId: appState.croppingElementId,
13777
13882
  activeLockedId: appState.activeLockedId,
13778
13883
  lockedMultiSelections: appState.lockedMultiSelections,
13779
- editingLinearElementId: appState.editingLinearElement?.elementId ?? // prefer app state, as it's likely newer
13780
- appState.editingLinearElementId ?? // fallback to observed app state, as it's likely older coming from a previous snapshot
13781
- null,
13782
- selectedLinearElementId: appState.selectedLinearElement?.elementId ?? appState.selectedLinearElementId ?? null
13884
+ selectedLinearElement: appState.selectedLinearElement ? {
13885
+ elementId: appState.selectedLinearElement.elementId,
13886
+ isEditing: !!appState.selectedLinearElement.isEditing
13887
+ } : null
13783
13888
  };
13784
13889
  Reflect.defineProperty(observedAppState, hiddenObservedAppStateProp, {
13785
13890
  value: true,
@@ -14343,9 +14448,9 @@ var Scene = class {
14343
14448
  getFramesIncludingDeleted() {
14344
14449
  return this.frames;
14345
14450
  }
14346
- constructor(elements = null) {
14451
+ constructor(elements = null, options) {
14347
14452
  if (elements) {
14348
- this.replaceAllElements(elements);
14453
+ this.replaceAllElements(elements, options);
14349
14454
  }
14350
14455
  }
14351
14456
  getSelectedElements(opts) {
@@ -14410,10 +14515,12 @@ var Scene = class {
14410
14515
  }
14411
14516
  return didChange;
14412
14517
  }
14413
- replaceAllElements(nextElements) {
14518
+ replaceAllElements(nextElements, options) {
14414
14519
  const _nextElements = toArray(nextElements);
14415
14520
  const nextFrameLikes = [];
14416
- validateIndicesThrottled(_nextElements);
14521
+ if (!options?.skipValidation) {
14522
+ validateIndicesThrottled(_nextElements);
14523
+ }
14417
14524
  this.elements = syncInvalidIndices2(_nextElements);
14418
14525
  this.elementsMap.clear();
14419
14526
  this.elements.forEach((element) => {
@@ -14583,10 +14690,19 @@ var Delta = class _Delta {
14583
14690
  static isEmpty(delta) {
14584
14691
  return !Object.keys(delta.deleted).length && !Object.keys(delta.inserted).length;
14585
14692
  }
14693
+ /**
14694
+ * Merges two deltas into a new one.
14695
+ */
14696
+ static merge(delta1, delta2, delta3 = _Delta.empty()) {
14697
+ return _Delta.create(
14698
+ { ...delta1.deleted, ...delta2.deleted, ...delta3.deleted },
14699
+ { ...delta1.inserted, ...delta2.inserted, ...delta3.inserted }
14700
+ );
14701
+ }
14586
14702
  /**
14587
14703
  * Merges deleted and inserted object partials.
14588
14704
  */
14589
- static mergeObjects(prev, added, removed) {
14705
+ static mergeObjects(prev, added, removed = {}) {
14590
14706
  const cloned = { ...prev };
14591
14707
  for (const key of Object.keys(removed)) {
14592
14708
  delete cloned[key];
@@ -14807,6 +14923,9 @@ var AppStateDelta = class _AppStateDelta {
14807
14923
  constructor(delta) {
14808
14924
  this.delta = delta;
14809
14925
  }
14926
+ static create(delta) {
14927
+ return new _AppStateDelta(delta);
14928
+ }
14810
14929
  static calculate(prevAppState, nextAppState) {
14811
14930
  const delta = Delta.calculate(
14812
14931
  prevAppState,
@@ -14828,50 +14947,98 @@ var AppStateDelta = class _AppStateDelta {
14828
14947
  const inversedDelta = Delta.create(this.delta.inserted, this.delta.deleted);
14829
14948
  return new _AppStateDelta(inversedDelta);
14830
14949
  }
14950
+ squash(delta) {
14951
+ if (delta.isEmpty()) {
14952
+ return this;
14953
+ }
14954
+ const mergedDeletedSelectedElementIds = Delta.mergeObjects(
14955
+ this.delta.deleted.selectedElementIds ?? {},
14956
+ delta.delta.deleted.selectedElementIds ?? {}
14957
+ );
14958
+ const mergedInsertedSelectedElementIds = Delta.mergeObjects(
14959
+ this.delta.inserted.selectedElementIds ?? {},
14960
+ delta.delta.inserted.selectedElementIds ?? {}
14961
+ );
14962
+ const mergedDeletedSelectedGroupIds = Delta.mergeObjects(
14963
+ this.delta.deleted.selectedGroupIds ?? {},
14964
+ delta.delta.deleted.selectedGroupIds ?? {}
14965
+ );
14966
+ const mergedInsertedSelectedGroupIds = Delta.mergeObjects(
14967
+ this.delta.inserted.selectedGroupIds ?? {},
14968
+ delta.delta.inserted.selectedGroupIds ?? {}
14969
+ );
14970
+ const mergedDeletedLockedMultiSelections = Delta.mergeObjects(
14971
+ this.delta.deleted.lockedMultiSelections ?? {},
14972
+ delta.delta.deleted.lockedMultiSelections ?? {}
14973
+ );
14974
+ const mergedInsertedLockedMultiSelections = Delta.mergeObjects(
14975
+ this.delta.inserted.lockedMultiSelections ?? {},
14976
+ delta.delta.inserted.lockedMultiSelections ?? {}
14977
+ );
14978
+ const mergedInserted = {};
14979
+ const mergedDeleted = {};
14980
+ if (Object.keys(mergedDeletedSelectedElementIds).length || Object.keys(mergedInsertedSelectedElementIds).length) {
14981
+ mergedDeleted.selectedElementIds = mergedDeletedSelectedElementIds;
14982
+ mergedInserted.selectedElementIds = mergedInsertedSelectedElementIds;
14983
+ }
14984
+ if (Object.keys(mergedDeletedSelectedGroupIds).length || Object.keys(mergedInsertedSelectedGroupIds).length) {
14985
+ mergedDeleted.selectedGroupIds = mergedDeletedSelectedGroupIds;
14986
+ mergedInserted.selectedGroupIds = mergedInsertedSelectedGroupIds;
14987
+ }
14988
+ if (Object.keys(mergedDeletedLockedMultiSelections).length || Object.keys(mergedInsertedLockedMultiSelections).length) {
14989
+ mergedDeleted.lockedMultiSelections = mergedDeletedLockedMultiSelections;
14990
+ mergedInserted.lockedMultiSelections = mergedInsertedLockedMultiSelections;
14991
+ }
14992
+ this.delta = Delta.merge(
14993
+ this.delta,
14994
+ delta.delta,
14995
+ Delta.create(mergedDeleted, mergedInserted)
14996
+ );
14997
+ return this;
14998
+ }
14831
14999
  applyTo(appState, nextElements) {
14832
15000
  try {
14833
15001
  const {
14834
- selectedElementIds: removedSelectedElementIds = {},
14835
- selectedGroupIds: removedSelectedGroupIds = {}
15002
+ selectedElementIds: deletedSelectedElementIds = {},
15003
+ selectedGroupIds: deletedSelectedGroupIds = {},
15004
+ lockedMultiSelections: deletedLockedMultiSelections = {}
14836
15005
  } = this.delta.deleted;
14837
15006
  const {
14838
- selectedElementIds: addedSelectedElementIds = {},
14839
- selectedGroupIds: addedSelectedGroupIds = {},
14840
- selectedLinearElementId,
14841
- editingLinearElementId,
15007
+ selectedElementIds: insertedSelectedElementIds = {},
15008
+ selectedGroupIds: insertedSelectedGroupIds = {},
15009
+ lockedMultiSelections: insertedLockedMultiSelections = {},
15010
+ selectedLinearElement: insertedSelectedLinearElement,
14842
15011
  ...directlyApplicablePartial
14843
15012
  } = this.delta.inserted;
14844
15013
  const mergedSelectedElementIds = Delta.mergeObjects(
14845
15014
  appState.selectedElementIds,
14846
- addedSelectedElementIds,
14847
- removedSelectedElementIds
15015
+ insertedSelectedElementIds,
15016
+ deletedSelectedElementIds
14848
15017
  );
14849
15018
  const mergedSelectedGroupIds = Delta.mergeObjects(
14850
15019
  appState.selectedGroupIds,
14851
- addedSelectedGroupIds,
14852
- removedSelectedGroupIds
15020
+ insertedSelectedGroupIds,
15021
+ deletedSelectedGroupIds
14853
15022
  );
14854
- const selectedLinearElement = selectedLinearElementId && nextElements.has(selectedLinearElementId) ? new LinearElementEditor(
14855
- nextElements.get(
14856
- selectedLinearElementId
14857
- ),
14858
- nextElements
14859
- ) : null;
14860
- const editingLinearElement = editingLinearElementId && nextElements.has(editingLinearElementId) ? new LinearElementEditor(
15023
+ const mergedLockedMultiSelections = Delta.mergeObjects(
15024
+ appState.lockedMultiSelections,
15025
+ insertedLockedMultiSelections,
15026
+ deletedLockedMultiSelections
15027
+ );
15028
+ const selectedLinearElement = insertedSelectedLinearElement && nextElements.has(insertedSelectedLinearElement.elementId) ? new LinearElementEditor(
14861
15029
  nextElements.get(
14862
- editingLinearElementId
15030
+ insertedSelectedLinearElement.elementId
14863
15031
  ),
14864
- nextElements
15032
+ nextElements,
15033
+ insertedSelectedLinearElement.isEditing
14865
15034
  ) : null;
14866
15035
  const nextAppState = {
14867
15036
  ...appState,
14868
15037
  ...directlyApplicablePartial,
14869
15038
  selectedElementIds: mergedSelectedElementIds,
14870
15039
  selectedGroupIds: mergedSelectedGroupIds,
14871
- selectedLinearElement: typeof selectedLinearElementId !== "undefined" ? selectedLinearElement : appState.selectedLinearElement,
14872
- // otherwise assign what we had before
14873
- editingLinearElement: typeof editingLinearElementId !== "undefined" ? editingLinearElement : appState.editingLinearElement
14874
- // otherwise assign what we had before
15040
+ lockedMultiSelections: mergedLockedMultiSelections,
15041
+ selectedLinearElement: typeof insertedSelectedLinearElement !== "undefined" ? selectedLinearElement : appState.selectedLinearElement
14875
15042
  };
14876
15043
  const constainsVisibleChanges = this.filterInvisibleChanges(
14877
15044
  appState,
@@ -14961,57 +15128,44 @@ var AppStateDelta = class _AppStateDelta {
14961
15128
  nextAppState[key] = null;
14962
15129
  }
14963
15130
  break;
14964
- case "selectedLinearElementId":
14965
- case "editingLinearElementId":
14966
- const appStateKey = _AppStateDelta.convertToAppStateKey(key);
14967
- const linearElement = nextAppState[appStateKey];
14968
- if (!linearElement) {
15131
+ case "selectedLinearElement":
15132
+ const nextLinearElement = nextAppState[key];
15133
+ if (!nextLinearElement) {
14969
15134
  visibleDifferenceFlag.value = true;
14970
15135
  } else {
14971
- const element = nextElements.get(linearElement.elementId);
15136
+ const element = nextElements.get(nextLinearElement.elementId);
14972
15137
  if (element && !element.isDeleted) {
14973
15138
  visibleDifferenceFlag.value = true;
14974
15139
  } else {
14975
- nextAppState[appStateKey] = null;
15140
+ nextAppState[key] = null;
14976
15141
  }
14977
15142
  }
14978
15143
  break;
14979
- case "lockedMultiSelections": {
15144
+ case "lockedMultiSelections":
14980
15145
  const prevLockedUnits = prevAppState[key] || {};
14981
15146
  const nextLockedUnits = nextAppState[key] || {};
14982
15147
  if (!isShallowEqual2(prevLockedUnits, nextLockedUnits)) {
14983
15148
  visibleDifferenceFlag.value = true;
14984
15149
  }
14985
15150
  break;
14986
- }
14987
- case "activeLockedId": {
15151
+ case "activeLockedId":
14988
15152
  const prevHitLockedId = prevAppState[key] || null;
14989
15153
  const nextHitLockedId = nextAppState[key] || null;
14990
15154
  if (prevHitLockedId !== nextHitLockedId) {
14991
15155
  visibleDifferenceFlag.value = true;
14992
15156
  }
14993
15157
  break;
14994
- }
14995
- default: {
15158
+ default:
14996
15159
  assertNever4(
14997
15160
  key,
14998
15161
  `Unknown ObservedElementsAppState's key "${key}"`,
14999
15162
  true
15000
15163
  );
15001
- }
15002
15164
  }
15003
15165
  }
15004
15166
  }
15005
15167
  return visibleDifferenceFlag.value;
15006
15168
  }
15007
- static convertToAppStateKey(key) {
15008
- switch (key) {
15009
- case "selectedLinearElementId":
15010
- return "selectedLinearElement";
15011
- case "editingLinearElementId":
15012
- return "editingLinearElement";
15013
- }
15014
- }
15015
15169
  static filterSelectedElements(selectedElementIds, elements, visibleDifferenceFlag) {
15016
15170
  const ids = Object.keys(selectedElementIds);
15017
15171
  if (!ids.length) {
@@ -15050,8 +15204,7 @@ var AppStateDelta = class _AppStateDelta {
15050
15204
  editingGroupId,
15051
15205
  selectedGroupIds,
15052
15206
  selectedElementIds,
15053
- editingLinearElementId,
15054
- selectedLinearElementId,
15207
+ selectedLinearElement,
15055
15208
  croppingElementId,
15056
15209
  lockedMultiSelections,
15057
15210
  activeLockedId,
@@ -15088,12 +15241,6 @@ var AppStateDelta = class _AppStateDelta {
15088
15241
  "lockedMultiSelections",
15089
15242
  (prevValue) => prevValue ?? {}
15090
15243
  );
15091
- Delta.diffObjects(
15092
- deleted,
15093
- inserted,
15094
- "activeLockedId",
15095
- (prevValue) => prevValue ?? null
15096
- );
15097
15244
  } catch (e) {
15098
15245
  console.error(`Couldn't postprocess appstate change deltas.`);
15099
15246
  if (isTestEnv8() || isDevEnv7()) {
@@ -15172,13 +15319,17 @@ var ElementsDelta = class _ElementsDelta {
15172
15319
  static satisfiesCommmonInvariants = ({
15173
15320
  deleted,
15174
15321
  inserted
15175
- }) => !!(deleted.version && inserted.version && // versions are required integers
15176
- Number.isInteger(deleted.version) && Number.isInteger(inserted.version) && // versions should be positive, zero included
15322
+ }) => !!// versions are required integers
15323
+ (Number.isInteger(deleted.version) && Number.isInteger(inserted.version) && // versions should be positive, zero included
15177
15324
  deleted.version >= 0 && inserted.version >= 0 && // versions should never be the same
15178
15325
  deleted.version !== inserted.version);
15326
+ static satisfiesUniqueInvariants = (elementsDelta, id) => {
15327
+ const { added, removed, updated } = elementsDelta;
15328
+ return [added[id], removed[id], updated[id]].filter(Boolean).length === 1;
15329
+ };
15179
15330
  static validate(elementsDelta, type, satifiesSpecialInvariants) {
15180
15331
  for (const [id, delta] of Object.entries(elementsDelta[type])) {
15181
- if (!this.satisfiesCommmonInvariants(delta) || !satifiesSpecialInvariants(delta)) {
15332
+ if (!this.satisfiesCommmonInvariants(delta) || !this.satisfiesUniqueInvariants(elementsDelta, id) || !satifiesSpecialInvariants(delta)) {
15182
15333
  console.error(
15183
15334
  `Broken invariant for "${type}" delta, element "${id}", delta:`,
15184
15335
  delta
@@ -15205,7 +15356,7 @@ var ElementsDelta = class _ElementsDelta {
15205
15356
  for (const prevElement of prevElements.values()) {
15206
15357
  const nextElement = nextElements.get(prevElement.id);
15207
15358
  if (!nextElement) {
15208
- const deleted = { ...prevElement, isDeleted: false };
15359
+ const deleted = { ...prevElement };
15209
15360
  const inserted = {
15210
15361
  isDeleted: true,
15211
15362
  version: prevElement.version + 1,
@@ -15216,7 +15367,11 @@ var ElementsDelta = class _ElementsDelta {
15216
15367
  inserted,
15217
15368
  _ElementsDelta.stripIrrelevantProps
15218
15369
  );
15219
- removed[prevElement.id] = delta;
15370
+ if (!prevElement.isDeleted) {
15371
+ removed[prevElement.id] = delta;
15372
+ } else {
15373
+ updated[prevElement.id] = delta;
15374
+ }
15220
15375
  }
15221
15376
  }
15222
15377
  for (const nextElement of nextElements.values()) {
@@ -15228,15 +15383,18 @@ var ElementsDelta = class _ElementsDelta {
15228
15383
  versionNonce: randomInteger4()
15229
15384
  };
15230
15385
  const inserted = {
15231
- ...nextElement,
15232
- isDeleted: false
15386
+ ...nextElement
15233
15387
  };
15234
15388
  const delta = Delta.create(
15235
15389
  deleted,
15236
15390
  inserted,
15237
15391
  _ElementsDelta.stripIrrelevantProps
15238
15392
  );
15239
- added[nextElement.id] = delta;
15393
+ if (!nextElement.isDeleted) {
15394
+ added[nextElement.id] = delta;
15395
+ } else {
15396
+ updated[nextElement.id] = delta;
15397
+ }
15240
15398
  continue;
15241
15399
  }
15242
15400
  if (prevElement.versionNonce !== nextElement.versionNonce) {
@@ -15257,9 +15415,7 @@ var ElementsDelta = class _ElementsDelta {
15257
15415
  }
15258
15416
  continue;
15259
15417
  }
15260
- if (!Delta.isEmpty(delta)) {
15261
- updated[nextElement.id] = delta;
15262
- }
15418
+ updated[nextElement.id] = delta;
15263
15419
  }
15264
15420
  }
15265
15421
  return _ElementsDelta.create(added, removed, updated);
@@ -15270,8 +15426,8 @@ var ElementsDelta = class _ElementsDelta {
15270
15426
  inverse() {
15271
15427
  const inverseInternal = (deltas) => {
15272
15428
  const inversedDeltas = {};
15273
- for (const [id, delta] of Object.entries(deltas)) {
15274
- inversedDeltas[id] = Delta.create(delta.inserted, delta.deleted);
15429
+ for (const [id, { inserted, deleted }] of Object.entries(deltas)) {
15430
+ inversedDeltas[id] = Delta.create({ ...inserted }, { ...deleted });
15275
15431
  }
15276
15432
  return inversedDeltas;
15277
15433
  };
@@ -15349,26 +15505,30 @@ var ElementsDelta = class _ElementsDelta {
15349
15505
  // redistribute the deltas as `isDeleted` could have been updated
15350
15506
  });
15351
15507
  }
15352
- applyTo(elements, snapshot = StoreSnapshot.empty().elements, options = {
15353
- excludedProperties: /* @__PURE__ */ new Set()
15354
- }) {
15508
+ applyTo(elements, snapshot = StoreSnapshot.empty().elements, options) {
15355
15509
  let nextElements = new Map(elements);
15356
15510
  let changedElements;
15357
15511
  const flags = {
15358
15512
  containsVisibleDifference: false,
15359
- containsZindexDifference: false
15513
+ containsZindexDifference: false,
15514
+ applyDirection: void 0
15360
15515
  };
15361
15516
  try {
15362
15517
  const applyDeltas = _ElementsDelta.createApplier(
15518
+ elements,
15363
15519
  nextElements,
15364
15520
  snapshot,
15365
- options,
15366
- flags
15521
+ flags,
15522
+ options
15367
15523
  );
15368
15524
  const addedElements = applyDeltas(this.added);
15369
15525
  const removedElements = applyDeltas(this.removed);
15370
15526
  const updatedElements = applyDeltas(this.updated);
15371
- const affectedElements = this.resolveConflicts(elements, nextElements);
15527
+ const affectedElements = this.resolveConflicts(
15528
+ elements,
15529
+ nextElements,
15530
+ flags.applyDirection
15531
+ );
15372
15532
  changedElements = new Map([
15373
15533
  ...addedElements,
15374
15534
  ...removedElements,
@@ -15388,9 +15548,7 @@ var ElementsDelta = class _ElementsDelta {
15388
15548
  changedElements,
15389
15549
  flags
15390
15550
  );
15391
- const tempScene = new Scene(nextElements);
15392
- _ElementsDelta.redrawTextBoundingBoxes(tempScene, changedElements);
15393
- _ElementsDelta.redrawBoundArrows(tempScene, changedElements);
15551
+ _ElementsDelta.redrawElements(nextElements, changedElements);
15394
15552
  } catch (e) {
15395
15553
  console.error(
15396
15554
  `Couldn't mutate elements after applying elements change`,
@@ -15403,7 +15561,82 @@ var ElementsDelta = class _ElementsDelta {
15403
15561
  return [nextElements, flags.containsVisibleDifference];
15404
15562
  }
15405
15563
  }
15406
- static createApplier = (nextElements, snapshot, options, flags) => (deltas) => {
15564
+ squash(delta) {
15565
+ if (delta.isEmpty()) {
15566
+ return this;
15567
+ }
15568
+ const { added, removed, updated } = delta;
15569
+ const mergeBoundElements = (prevDelta, nextDelta) => {
15570
+ const mergedDeletedBoundElements = Delta.mergeArrays(
15571
+ prevDelta.deleted.boundElements ?? [],
15572
+ nextDelta.deleted.boundElements ?? [],
15573
+ void 0,
15574
+ (x) => x.id
15575
+ ) ?? [];
15576
+ const mergedInsertedBoundElements = Delta.mergeArrays(
15577
+ prevDelta.inserted.boundElements ?? [],
15578
+ nextDelta.inserted.boundElements ?? [],
15579
+ void 0,
15580
+ (x) => x.id
15581
+ ) ?? [];
15582
+ if (!mergedDeletedBoundElements.length && !mergedInsertedBoundElements.length) {
15583
+ return;
15584
+ }
15585
+ return Delta.create(
15586
+ {
15587
+ boundElements: mergedDeletedBoundElements
15588
+ },
15589
+ {
15590
+ boundElements: mergedInsertedBoundElements
15591
+ }
15592
+ );
15593
+ };
15594
+ for (const [id, nextDelta] of Object.entries(added)) {
15595
+ const prevDelta = this.added[id] ?? this.removed[id] ?? this.updated[id];
15596
+ if (!prevDelta) {
15597
+ this.added[id] = nextDelta;
15598
+ } else {
15599
+ const mergedDelta = mergeBoundElements(prevDelta, nextDelta);
15600
+ delete this.removed[id];
15601
+ delete this.updated[id];
15602
+ this.added[id] = Delta.merge(prevDelta, nextDelta, mergedDelta);
15603
+ }
15604
+ }
15605
+ for (const [id, nextDelta] of Object.entries(removed)) {
15606
+ const prevDelta = this.added[id] ?? this.removed[id] ?? this.updated[id];
15607
+ if (!prevDelta) {
15608
+ this.removed[id] = nextDelta;
15609
+ } else {
15610
+ const mergedDelta = mergeBoundElements(prevDelta, nextDelta);
15611
+ delete this.added[id];
15612
+ delete this.updated[id];
15613
+ this.removed[id] = Delta.merge(prevDelta, nextDelta, mergedDelta);
15614
+ }
15615
+ }
15616
+ for (const [id, nextDelta] of Object.entries(updated)) {
15617
+ const prevDelta = this.added[id] ?? this.removed[id] ?? this.updated[id];
15618
+ if (!prevDelta) {
15619
+ this.updated[id] = nextDelta;
15620
+ } else {
15621
+ const mergedDelta = mergeBoundElements(prevDelta, nextDelta);
15622
+ const updatedDelta = Delta.merge(prevDelta, nextDelta, mergedDelta);
15623
+ if (prevDelta === this.added[id]) {
15624
+ this.added[id] = updatedDelta;
15625
+ } else if (prevDelta === this.removed[id]) {
15626
+ this.removed[id] = updatedDelta;
15627
+ } else {
15628
+ this.updated[id] = updatedDelta;
15629
+ }
15630
+ }
15631
+ }
15632
+ if (isTestEnv8() || isDevEnv7()) {
15633
+ _ElementsDelta.validate(this, "added", _ElementsDelta.satisfiesAddition);
15634
+ _ElementsDelta.validate(this, "removed", _ElementsDelta.satisfiesRemoval);
15635
+ _ElementsDelta.validate(this, "updated", _ElementsDelta.satisfiesUpdate);
15636
+ }
15637
+ return this;
15638
+ }
15639
+ static createApplier = (prevElements, nextElements, snapshot, flags, options) => (deltas) => {
15407
15640
  const getElement = _ElementsDelta.createGetter(
15408
15641
  nextElements,
15409
15642
  snapshot,
@@ -15412,14 +15645,20 @@ var ElementsDelta = class _ElementsDelta {
15412
15645
  return Object.entries(deltas).reduce((acc, [id, delta]) => {
15413
15646
  const element = getElement(id, delta.inserted);
15414
15647
  if (element) {
15415
- const newElement2 = _ElementsDelta.applyDelta(
15648
+ const nextElement = _ElementsDelta.applyDelta(
15416
15649
  element,
15417
15650
  delta,
15418
- options,
15419
- flags
15651
+ flags,
15652
+ options
15420
15653
  );
15421
- nextElements.set(newElement2.id, newElement2);
15422
- acc.set(newElement2.id, newElement2);
15654
+ nextElements.set(nextElement.id, nextElement);
15655
+ acc.set(nextElement.id, nextElement);
15656
+ if (!flags.applyDirection) {
15657
+ const prevElement = prevElements.get(id);
15658
+ if (prevElement) {
15659
+ flags.applyDirection = prevElement.version > nextElement.version ? "backward" : "forward";
15660
+ }
15661
+ }
15423
15662
  }
15424
15663
  return acc;
15425
15664
  }, /* @__PURE__ */ new Map());
@@ -15444,13 +15683,13 @@ var ElementsDelta = class _ElementsDelta {
15444
15683
  }
15445
15684
  return element;
15446
15685
  };
15447
- static applyDelta(element, delta, options, flags) {
15686
+ static applyDelta(element, delta, flags, options) {
15448
15687
  const directlyApplicablePartial = {};
15449
15688
  for (const key of Object.keys(delta.inserted)) {
15450
15689
  if (key === "boundElements") {
15451
15690
  continue;
15452
15691
  }
15453
- if (options.excludedProperties.has(key)) {
15692
+ if (options?.excludedProperties?.has(key)) {
15454
15693
  continue;
15455
15694
  }
15456
15695
  const value = delta.inserted[key];
@@ -15478,7 +15717,7 @@ var ElementsDelta = class _ElementsDelta {
15478
15717
  if (!flags.containsZindexDifference) {
15479
15718
  flags.containsZindexDifference = delta.deleted.index !== delta.inserted.index;
15480
15719
  }
15481
- return newElementWith(element, directlyApplicablePartial);
15720
+ return newElementWith(element, directlyApplicablePartial, true);
15482
15721
  }
15483
15722
  /**
15484
15723
  * Check for visible changes regardless of whether they were removed, added or updated.
@@ -15503,25 +15742,32 @@ var ElementsDelta = class _ElementsDelta {
15503
15742
  *
15504
15743
  * @returns all elements affected by the conflict resolution
15505
15744
  */
15506
- resolveConflicts(prevElements, nextElements) {
15745
+ resolveConflicts(prevElements, nextElements, applyDirection = "forward") {
15507
15746
  const nextAffectedElements = /* @__PURE__ */ new Map();
15508
15747
  const updater = (element, updates) => {
15509
15748
  const nextElement = nextElements.get(element.id);
15510
15749
  if (!nextElement) {
15511
15750
  return;
15512
15751
  }
15752
+ const prevElement = prevElements.get(element.id);
15753
+ const nextVersion = applyDirection === "forward" ? nextElement.version + 1 : nextElement.version - 1;
15754
+ const elementUpdates = updates;
15513
15755
  let affectedElement;
15514
- if (prevElements.get(element.id) === nextElement) {
15756
+ if (prevElement === nextElement) {
15515
15757
  affectedElement = newElementWith(
15516
15758
  nextElement,
15517
- updates
15759
+ {
15760
+ ...elementUpdates,
15761
+ version: nextVersion
15762
+ },
15763
+ true
15518
15764
  );
15519
15765
  } else {
15520
- affectedElement = mutateElement(
15521
- nextElement,
15522
- nextElements,
15523
- updates
15524
- );
15766
+ affectedElement = mutateElement(nextElement, nextElements, {
15767
+ ...elementUpdates,
15768
+ // don't modify the version further, if it's already different
15769
+ version: prevElement?.version !== nextElement.version ? nextElement.version : nextVersion
15770
+ });
15525
15771
  }
15526
15772
  nextAffectedElements.set(affectedElement.id, affectedElement);
15527
15773
  nextElements.set(affectedElement.id, affectedElement);
@@ -15546,19 +15792,10 @@ var ElementsDelta = class _ElementsDelta {
15546
15792
  const prevAffectedElements = new Map(
15547
15793
  Array.from(prevElements).filter(([id]) => nextAffectedElements.has(id))
15548
15794
  );
15549
- const { added, removed, updated } = _ElementsDelta.calculate(
15550
- prevAffectedElements,
15551
- nextAffectedElements
15795
+ this.squash(
15796
+ // technically we could do better here if perf. would become an issue
15797
+ _ElementsDelta.calculate(prevAffectedElements, nextAffectedElements)
15552
15798
  );
15553
- for (const [id, delta] of Object.entries(added)) {
15554
- this.added[id] = delta;
15555
- }
15556
- for (const [id, delta] of Object.entries(removed)) {
15557
- this.removed[id] = delta;
15558
- }
15559
- for (const [id, delta] of Object.entries(updated)) {
15560
- this.updated[id] = delta;
15561
- }
15562
15799
  return nextAffectedElements;
15563
15800
  }
15564
15801
  /**
@@ -15593,6 +15830,20 @@ var ElementsDelta = class _ElementsDelta {
15593
15830
  );
15594
15831
  BindableElement.rebindAffected(nextElements, nextElement(), updater);
15595
15832
  }
15833
+ static redrawElements(nextElements, changedElements) {
15834
+ try {
15835
+ const tempScene = new Scene(nextElements, { skipValidation: true });
15836
+ _ElementsDelta.redrawTextBoundingBoxes(tempScene, changedElements);
15837
+ _ElementsDelta.redrawBoundArrows(tempScene, changedElements);
15838
+ } catch (e) {
15839
+ console.error(`Couldn't redraw elements`, e);
15840
+ if (isTestEnv8() || isDevEnv7()) {
15841
+ throw e;
15842
+ }
15843
+ } finally {
15844
+ return nextElements;
15845
+ }
15846
+ }
15596
15847
  static redrawTextBoundingBoxes(scene, changed) {
15597
15848
  const elements = scene.getNonDeletedElementsMap();
15598
15849
  const boxesToRedraw = /* @__PURE__ */ new Map();
@@ -15622,9 +15873,6 @@ var ElementsDelta = class _ElementsDelta {
15622
15873
  if (container.isDeleted || boundText.isDeleted) {
15623
15874
  continue;
15624
15875
  }
15625
- if (!boundText.text) {
15626
- continue;
15627
- }
15628
15876
  redrawTextBoundingBox(boundText, container, scene);
15629
15877
  }
15630
15878
  }
@@ -15688,10 +15936,14 @@ var ElementsDelta = class _ElementsDelta {
15688
15936
 
15689
15937
  // src/distribute.ts
15690
15938
  init_define_import_meta_env();
15691
- var distributeElements = (selectedElements, elementsMap, distribution) => {
15939
+ var distributeElements = (selectedElements, elementsMap, distribution, appState) => {
15692
15940
  const [start, mid, end, extent] = distribution.axis === "x" ? ["minX", "midX", "maxX", "width"] : ["minY", "midY", "maxY", "height"];
15693
15941
  const bounds = getCommonBoundingBox(selectedElements);
15694
- const groups = getMaximumGroups(selectedElements, elementsMap).map((group) => [group, getCommonBoundingBox(group)]).sort((a2, b2) => a2[1][mid] - b2[1][mid]);
15942
+ const groups = getSelectedElementsByGroup(
15943
+ selectedElements,
15944
+ elementsMap,
15945
+ appState
15946
+ ).map((group) => [group, getCommonBoundingBox(group)]).sort((a2, b2) => a2[1][mid] - b2[1][mid]);
15695
15947
  let span = 0;
15696
15948
  for (const group of groups) {
15697
15949
  span += group[1][extent];
@@ -16684,7 +16936,7 @@ var embeddableURLValidator = (url, validateEmbeddable) => {
16684
16936
  // src/flowchart.ts
16685
16937
  init_define_import_meta_env();
16686
16938
  import { KEYS as KEYS3, invariant as invariant8, toBrandedType as toBrandedType2 } from "@excalidraw/common";
16687
- import { pointFrom as pointFrom13 } from "@excalidraw/math";
16939
+ import { pointFrom as pointFrom14 } from "@excalidraw/math";
16688
16940
  var VERTICAL_OFFSET = 100;
16689
16941
  var HORIZONTAL_OFFSET = 100;
16690
16942
  var getLinkDirectionFromKey = (key) => {
@@ -16964,7 +17216,7 @@ var createBindingArrow = (startBindingElement, endBindingElement, direction, app
16964
17216
  strokeWidth: startBindingElement.strokeWidth,
16965
17217
  opacity: startBindingElement.opacity,
16966
17218
  roughness: startBindingElement.roughness,
16967
- points: [pointFrom13(0, 0), pointFrom13(endX, endY)],
17219
+ points: [pointFrom14(0, 0), pointFrom14(endX, endY)],
16968
17220
  elbowed: true
16969
17221
  });
16970
17222
  const elementsMap = scene.getNonDeletedElementsMap();
@@ -17248,13 +17500,80 @@ var normalizeSVG = (SVGString) => {
17248
17500
  }
17249
17501
  };
17250
17502
 
17503
+ // src/positionElementsOnGrid.ts
17504
+ init_define_import_meta_env();
17505
+ var positionElementsOnGrid = (elements, centerX, centerY, padding = 50) => {
17506
+ if (!elements || elements.length === 0) {
17507
+ return [];
17508
+ }
17509
+ const res = [];
17510
+ const atomicUnits = Array.isArray(elements[0]) ? elements : elements.map((element) => [element]);
17511
+ const numUnits = atomicUnits.length;
17512
+ const numColumns = Math.max(1, Math.ceil(Math.sqrt(numUnits)));
17513
+ const rows = [];
17514
+ for (let i = 0; i < numUnits; i += numColumns) {
17515
+ rows.push(atomicUnits.slice(i, i + numColumns));
17516
+ }
17517
+ let totalGridActualHeight = 0;
17518
+ const rowProperties = rows.map((rowUnits) => {
17519
+ let rowWidth = 0;
17520
+ let maxUnitHeightInRow = 0;
17521
+ const unitBounds = rowUnits.map((unit) => {
17522
+ const [minX, minY, maxX, maxY] = getCommonBounds(unit);
17523
+ return {
17524
+ elements: unit,
17525
+ bounds: [minX, minY, maxX, maxY],
17526
+ width: maxX - minX,
17527
+ height: maxY - minY
17528
+ };
17529
+ });
17530
+ unitBounds.forEach((unitBound, index) => {
17531
+ rowWidth += unitBound.width;
17532
+ if (index < unitBounds.length - 1) {
17533
+ rowWidth += padding;
17534
+ }
17535
+ if (unitBound.height > maxUnitHeightInRow) {
17536
+ maxUnitHeightInRow = unitBound.height;
17537
+ }
17538
+ });
17539
+ totalGridActualHeight += maxUnitHeightInRow;
17540
+ return {
17541
+ unitBounds,
17542
+ width: rowWidth,
17543
+ maxHeight: maxUnitHeightInRow
17544
+ };
17545
+ });
17546
+ const totalGridHeightWithPadding = totalGridActualHeight + Math.max(0, rows.length - 1) * padding;
17547
+ let currentY = centerY - totalGridHeightWithPadding / 2;
17548
+ rowProperties.forEach((rowProp) => {
17549
+ const { unitBounds, width: rowWidth, maxHeight: rowMaxHeight } = rowProp;
17550
+ let currentX = centerX - rowWidth / 2;
17551
+ unitBounds.forEach((unitBound) => {
17552
+ const [originalMinX, originalMinY] = unitBound.bounds;
17553
+ const offsetX = currentX - originalMinX;
17554
+ const offsetY = currentY - originalMinY;
17555
+ unitBound.elements.forEach((element) => {
17556
+ res.push(
17557
+ newElementWith(element, {
17558
+ x: element.x + offsetX,
17559
+ y: element.y + offsetY
17560
+ })
17561
+ );
17562
+ });
17563
+ currentX += unitBound.width + padding;
17564
+ });
17565
+ currentY += rowMaxHeight + padding;
17566
+ });
17567
+ return res;
17568
+ };
17569
+
17251
17570
  // src/resizeElements.ts
17252
17571
  init_define_import_meta_env();
17253
17572
  import {
17254
17573
  pointCenter as pointCenter3,
17255
17574
  normalizeRadians as normalizeRadians2,
17256
- pointFrom as pointFrom14,
17257
- pointRotateRads as pointRotateRads11
17575
+ pointFrom as pointFrom15,
17576
+ pointRotateRads as pointRotateRads12
17258
17577
  } from "@excalidraw/math";
17259
17578
  import {
17260
17579
  MIN_FONT_SIZE,
@@ -17382,7 +17701,16 @@ var rotateSingleElement = (element, scene, pointerX, pointerY, shouldRotateWithD
17382
17701
  if (boundTextElementId) {
17383
17702
  const textElement = scene.getElement(boundTextElementId);
17384
17703
  if (textElement && !isArrowElement(element)) {
17385
- scene.mutateElement(textElement, { angle });
17704
+ const { x, y } = computeBoundTextPosition(
17705
+ element,
17706
+ textElement,
17707
+ scene.getNonDeletedElementsMap()
17708
+ );
17709
+ scene.mutateElement(textElement, {
17710
+ angle,
17711
+ x,
17712
+ y
17713
+ });
17386
17714
  }
17387
17715
  }
17388
17716
  };
@@ -17419,7 +17747,7 @@ var resizeSingleTextElement = (origElement, element, scene, transformHandleType,
17419
17747
  return;
17420
17748
  }
17421
17749
  if (transformHandleType.includes("n") || transformHandleType.includes("s")) {
17422
- const previousOrigin = pointFrom14(origElement.x, origElement.y);
17750
+ const previousOrigin = pointFrom15(origElement.x, origElement.y);
17423
17751
  const newOrigin = getResizedOrigin(
17424
17752
  previousOrigin,
17425
17753
  origElement.width,
@@ -17460,7 +17788,7 @@ var resizeSingleTextElement = (origElement, element, scene, transformHandleType,
17460
17788
  element.lineHeight
17461
17789
  );
17462
17790
  const newHeight = metrics2.height;
17463
- const previousOrigin = pointFrom14(origElement.x, origElement.y);
17791
+ const previousOrigin = pointFrom15(origElement.x, origElement.y);
17464
17792
  const newOrigin = getResizedOrigin(
17465
17793
  previousOrigin,
17466
17794
  origElement.width,
@@ -17496,9 +17824,9 @@ var rotateMultipleElements = (originalElements, elements, scene, pointerX, point
17496
17824
  const cx = (x1 + x2) / 2;
17497
17825
  const cy = (y1 + y2) / 2;
17498
17826
  const origAngle = originalElements.get(element.id)?.angle ?? element.angle;
17499
- const [rotatedCX, rotatedCY] = pointRotateRads11(
17500
- pointFrom14(cx, cy),
17501
- pointFrom14(centerX, centerY),
17827
+ const [rotatedCX, rotatedCY] = pointRotateRads12(
17828
+ pointFrom15(cx, cy),
17829
+ pointFrom15(centerX, centerY),
17502
17830
  centerAngle + origAngle - element.angle
17503
17831
  );
17504
17832
  const updates = isElbowArrow(element) ? {
@@ -17515,9 +17843,14 @@ var rotateMultipleElements = (originalElements, elements, scene, pointerX, point
17515
17843
  });
17516
17844
  const boundText = getBoundTextElement(element, elementsMap);
17517
17845
  if (boundText && !isArrowElement(element)) {
17846
+ const { x, y } = computeBoundTextPosition(
17847
+ element,
17848
+ boundText,
17849
+ elementsMap
17850
+ );
17518
17851
  scene.mutateElement(boundText, {
17519
- x: boundText.x + (rotatedCX - cx),
17520
- y: boundText.y + (rotatedCY - cy),
17852
+ x,
17853
+ y,
17521
17854
  angle: normalizeRadians2(centerAngle + origAngle)
17522
17855
  });
17523
17856
  }
@@ -17530,44 +17863,44 @@ var getResizeOffsetXY = (transformHandleType, selectedElements, elementsMap, x,
17530
17863
  const cx = (x1 + x2) / 2;
17531
17864
  const cy = (y1 + y2) / 2;
17532
17865
  const angle = selectedElements.length === 1 ? selectedElements[0].angle : 0;
17533
- [x, y] = pointRotateRads11(
17534
- pointFrom14(x, y),
17535
- pointFrom14(cx, cy),
17866
+ [x, y] = pointRotateRads12(
17867
+ pointFrom15(x, y),
17868
+ pointFrom15(cx, cy),
17536
17869
  -angle
17537
17870
  );
17538
17871
  switch (transformHandleType) {
17539
17872
  case "n":
17540
- return pointRotateRads11(
17541
- pointFrom14(x - (x1 + x2) / 2, y - y1),
17542
- pointFrom14(0, 0),
17873
+ return pointRotateRads12(
17874
+ pointFrom15(x - (x1 + x2) / 2, y - y1),
17875
+ pointFrom15(0, 0),
17543
17876
  angle
17544
17877
  );
17545
17878
  case "s":
17546
- return pointRotateRads11(
17547
- pointFrom14(x - (x1 + x2) / 2, y - y2),
17548
- pointFrom14(0, 0),
17879
+ return pointRotateRads12(
17880
+ pointFrom15(x - (x1 + x2) / 2, y - y2),
17881
+ pointFrom15(0, 0),
17549
17882
  angle
17550
17883
  );
17551
17884
  case "w":
17552
- return pointRotateRads11(
17553
- pointFrom14(x - x1, y - (y1 + y2) / 2),
17554
- pointFrom14(0, 0),
17885
+ return pointRotateRads12(
17886
+ pointFrom15(x - x1, y - (y1 + y2) / 2),
17887
+ pointFrom15(0, 0),
17555
17888
  angle
17556
17889
  );
17557
17890
  case "e":
17558
- return pointRotateRads11(
17559
- pointFrom14(x - x2, y - (y1 + y2) / 2),
17560
- pointFrom14(0, 0),
17891
+ return pointRotateRads12(
17892
+ pointFrom15(x - x2, y - (y1 + y2) / 2),
17893
+ pointFrom15(0, 0),
17561
17894
  angle
17562
17895
  );
17563
17896
  case "nw":
17564
- return pointRotateRads11(pointFrom14(x - x1, y - y1), pointFrom14(0, 0), angle);
17897
+ return pointRotateRads12(pointFrom15(x - x1, y - y1), pointFrom15(0, 0), angle);
17565
17898
  case "ne":
17566
- return pointRotateRads11(pointFrom14(x - x2, y - y1), pointFrom14(0, 0), angle);
17899
+ return pointRotateRads12(pointFrom15(x - x2, y - y1), pointFrom15(0, 0), angle);
17567
17900
  case "sw":
17568
- return pointRotateRads11(pointFrom14(x - x1, y - y2), pointFrom14(0, 0), angle);
17901
+ return pointRotateRads12(pointFrom15(x - x1, y - y2), pointFrom15(0, 0), angle);
17569
17902
  case "se":
17570
- return pointRotateRads11(pointFrom14(x - x2, y - y2), pointFrom14(0, 0), angle);
17903
+ return pointRotateRads12(pointFrom15(x - x2, y - y2), pointFrom15(0, 0), angle);
17571
17904
  default:
17572
17905
  return [0, 0];
17573
17906
  }
@@ -17730,10 +18063,10 @@ var resizeSingleElement = (nextWidth, nextHeight, latestElement, origElement, or
17730
18063
  nextHeight,
17731
18064
  true
17732
18065
  );
17733
- let previousOrigin = pointFrom14(origElement.x, origElement.y);
18066
+ let previousOrigin = pointFrom15(origElement.x, origElement.y);
17734
18067
  if (isLinearElement(origElement)) {
17735
18068
  const [x1, y1] = getElementBounds(origElement, originalElementsMap);
17736
- previousOrigin = pointFrom14(x1, y1);
18069
+ previousOrigin = pointFrom15(x1, y1);
17737
18070
  }
17738
18071
  const newOrigin = getResizedOrigin(
17739
18072
  previousOrigin,
@@ -17756,7 +18089,7 @@ var resizeSingleElement = (nextWidth, nextHeight, latestElement, origElement, or
17756
18089
  newOrigin.x += scaledX;
17757
18090
  newOrigin.y += scaledY;
17758
18091
  rescaledPoints.points = rescaledPoints.points.map(
17759
- (p) => pointFrom14(p[0] - scaledX, p[1] - scaledY)
18092
+ (p) => pointFrom15(p[0] - scaledX, p[1] - scaledY)
17760
18093
  );
17761
18094
  }
17762
18095
  if (nextWidth < 0) {
@@ -17819,11 +18152,11 @@ var getNextSingleWidthAndHeightFromPointer = (latestElement, origElement, handle
17819
18152
  origElement.height,
17820
18153
  true
17821
18154
  );
17822
- const startTopLeft = pointFrom14(x1, y1);
17823
- const startBottomRight = pointFrom14(x2, y2);
18155
+ const startTopLeft = pointFrom15(x1, y1);
18156
+ const startBottomRight = pointFrom15(x2, y2);
17824
18157
  const startCenter = pointCenter3(startTopLeft, startBottomRight);
17825
- const rotatedPointer = pointRotateRads11(
17826
- pointFrom14(pointerX, pointerY),
18158
+ const rotatedPointer = pointRotateRads12(
18159
+ pointFrom15(pointerX, pointerY),
17827
18160
  startCenter,
17828
18161
  -origElement.angle
17829
18162
  );
@@ -18181,9 +18514,9 @@ var resizeMultipleElements = (selectedElements, elementsMap, handleDirection, sc
18181
18514
  // src/resizeTest.ts
18182
18515
  init_define_import_meta_env();
18183
18516
  import {
18184
- pointFrom as pointFrom16,
18517
+ pointFrom as pointFrom17,
18185
18518
  pointOnLineSegment,
18186
- pointRotateRads as pointRotateRads13
18519
+ pointRotateRads as pointRotateRads14
18187
18520
  } from "@excalidraw/math";
18188
18521
  import { SIDE_RESIZING_THRESHOLD } from "@excalidraw/common";
18189
18522
 
@@ -18194,7 +18527,7 @@ import {
18194
18527
  isAndroid,
18195
18528
  isIOS
18196
18529
  } from "@excalidraw/common";
18197
- import { pointFrom as pointFrom15, pointRotateRads as pointRotateRads12 } from "@excalidraw/math";
18530
+ import { pointFrom as pointFrom16, pointRotateRads as pointRotateRads13 } from "@excalidraw/math";
18198
18531
  var transformHandleSizes = {
18199
18532
  mouse: 8,
18200
18533
  pen: 16,
@@ -18235,9 +18568,9 @@ var OMIT_SIDES_FOR_LINE_BACKSLASH = {
18235
18568
  w: true
18236
18569
  };
18237
18570
  var generateTransformHandle = (x, y, width, height, cx, cy, angle) => {
18238
- const [xx, yy] = pointRotateRads12(
18239
- pointFrom15(x + width / 2, y + height / 2),
18240
- pointFrom15(cx, cy),
18571
+ const [xx, yy] = pointRotateRads13(
18572
+ pointFrom16(x + width / 2, y + height / 2),
18573
+ pointFrom16(cx, cy),
18241
18574
  angle
18242
18575
  );
18243
18576
  return [xx - width / 2, yy - height / 2, width, height];
@@ -18403,7 +18736,7 @@ var getTransformHandles = (element, zoom, elementsMap, pointerType = "mouse", om
18403
18736
  );
18404
18737
  };
18405
18738
  var shouldShowBoundingBox = (elements, appState) => {
18406
- if (appState.editingLinearElement) {
18739
+ if (appState.selectedLinearElement?.isEditing) {
18407
18740
  return false;
18408
18741
  }
18409
18742
  if (elements.length > 1) {
@@ -18454,14 +18787,14 @@ var resizeTest = (element, elementsMap, appState, x, y, zoom, pointerType, devic
18454
18787
  const SPACING = isImageElement(element) ? 0 : SIDE_RESIZING_THRESHOLD / zoom.value;
18455
18788
  const ZOOMED_SIDE_RESIZING_THRESHOLD = SIDE_RESIZING_THRESHOLD / zoom.value;
18456
18789
  const sides = getSelectionBorders(
18457
- pointFrom16(x1 - SPACING, y1 - SPACING),
18458
- pointFrom16(x2 + SPACING, y2 + SPACING),
18459
- pointFrom16(cx, cy),
18790
+ pointFrom17(x1 - SPACING, y1 - SPACING),
18791
+ pointFrom17(x2 + SPACING, y2 + SPACING),
18792
+ pointFrom17(cx, cy),
18460
18793
  element.angle
18461
18794
  );
18462
18795
  for (const [dir, side] of Object.entries(sides)) {
18463
18796
  if (pointOnLineSegment(
18464
- pointFrom16(x, y),
18797
+ pointFrom17(x, y),
18465
18798
  side,
18466
18799
  ZOOMED_SIDE_RESIZING_THRESHOLD
18467
18800
  )) {
@@ -18510,14 +18843,14 @@ var getTransformHandleTypeFromCoords = ([x1, y1, x2, y2], scenePointerX, scenePo
18510
18843
  const cy = (y1 + y2) / 2;
18511
18844
  const SPACING = SIDE_RESIZING_THRESHOLD / zoom.value;
18512
18845
  const sides = getSelectionBorders(
18513
- pointFrom16(x1 - SPACING, y1 - SPACING),
18514
- pointFrom16(x2 + SPACING, y2 + SPACING),
18515
- pointFrom16(cx, cy),
18846
+ pointFrom17(x1 - SPACING, y1 - SPACING),
18847
+ pointFrom17(x2 + SPACING, y2 + SPACING),
18848
+ pointFrom17(cx, cy),
18516
18849
  0
18517
18850
  );
18518
18851
  for (const [dir, side] of Object.entries(sides)) {
18519
18852
  if (pointOnLineSegment(
18520
- pointFrom16(scenePointerX, scenePointerY),
18853
+ pointFrom17(scenePointerX, scenePointerY),
18521
18854
  side,
18522
18855
  SPACING
18523
18856
  )) {
@@ -18574,10 +18907,10 @@ var getCursorForResizingElement = (resizingElement) => {
18574
18907
  return cursor ? `${cursor}-resize` : "";
18575
18908
  };
18576
18909
  var getSelectionBorders = ([x1, y1], [x2, y2], center, angle) => {
18577
- const topLeft = pointRotateRads13(pointFrom16(x1, y1), center, angle);
18578
- const topRight = pointRotateRads13(pointFrom16(x2, y1), center, angle);
18579
- const bottomLeft = pointRotateRads13(pointFrom16(x1, y2), center, angle);
18580
- const bottomRight = pointRotateRads13(pointFrom16(x2, y2), center, angle);
18910
+ const topLeft = pointRotateRads14(pointFrom17(x1, y1), center, angle);
18911
+ const topRight = pointRotateRads14(pointFrom17(x2, y1), center, angle);
18912
+ const bottomLeft = pointRotateRads14(pointFrom17(x1, y2), center, angle);
18913
+ const bottomRight = pointRotateRads14(pointFrom17(x2, y2), center, angle);
18581
18914
  return {
18582
18915
  n: [topLeft, topRight],
18583
18916
  e: [topRight, bottomRight],
@@ -19151,6 +19484,7 @@ export {
19151
19484
  getRootElements,
19152
19485
  getSceneVersion,
19153
19486
  getSelectedElements,
19487
+ getSelectedElementsByGroup,
19154
19488
  getSelectedGroupForElement,
19155
19489
  getSelectedGroupIdForElement,
19156
19490
  getSelectedGroupIds,
@@ -19282,6 +19616,7 @@ export {
19282
19616
  parseTokens,
19283
19617
  pathsCache,
19284
19618
  pointInsideBounds,
19619
+ positionElementsOnGrid,
19285
19620
  redrawTextBoundingBox,
19286
19621
  refreshTextDimensions,
19287
19622
  removeAllElementsFromFrame,