@dwelle/excalidraw 0.5.0-611dd0d → 0.5.0-61258ed

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 (89) hide show
  1. package/dist/dev/{chunk-QYOG4VCN.js → chunk-FOPF4A62.js} +683 -336
  2. package/dist/dev/chunk-FOPF4A62.js.map +7 -0
  3. package/dist/dev/{chunk-V5BIR3MG.js → chunk-IHUW2ABU.js} +13 -3
  4. package/dist/dev/chunk-IHUW2ABU.js.map +7 -0
  5. package/dist/dev/{chunk-OC36B26O.js → chunk-OWPVDWDP.js} +2 -2
  6. package/dist/dev/components/TTDDialog/{CodeMirrorEditor-L55DYJSD.js → CodeMirrorEditor-GAACHFBI.js} +2 -2
  7. package/dist/dev/data/{image-WOLPNANH.js → image-LJOI7ED6.js} +3 -3
  8. package/dist/dev/index.css +35 -23
  9. package/dist/dev/index.css.map +2 -2
  10. package/dist/dev/index.js +1302 -374
  11. package/dist/dev/index.js.map +4 -4
  12. package/dist/dev/locales/{en-2JUZQ4KZ.js → en-VKRILXL5.js} +2 -2
  13. package/dist/dev/subset-shared.chunk.js +1 -1
  14. package/dist/dev/subset-worker.chunk.js +1 -1
  15. package/dist/prod/{chunk-WS2HXQMW.js → chunk-ADCEJGSL.js} +1 -1
  16. package/dist/prod/{chunk-DDHTQBPG.js → chunk-BZWW7FX6.js} +5 -5
  17. package/dist/prod/chunk-PMLJAENE.js +34 -0
  18. package/dist/prod/components/TTDDialog/{CodeMirrorEditor-WH5U77FS.js → CodeMirrorEditor-NEMGRIWU.js} +1 -1
  19. package/dist/prod/data/image-TEODVOOR.js +1 -0
  20. package/dist/prod/index.css +1 -1
  21. package/dist/prod/index.js +30 -28
  22. package/dist/prod/locales/{en-IVA5PAN7.js → en-L7BRGWWC.js} +1 -1
  23. package/dist/prod/subset-shared.chunk.js +1 -1
  24. package/dist/prod/subset-worker.chunk.js +1 -1
  25. package/dist/types/element/src/arrowheads.d.ts +3 -0
  26. package/dist/types/element/src/bounds.d.ts +5 -3
  27. package/dist/types/element/src/frame.d.ts +1 -1
  28. package/dist/types/element/src/index.d.ts +1 -0
  29. package/dist/types/element/src/linearElementEditor.d.ts +2 -2
  30. package/dist/types/element/src/selection.d.ts +7 -3
  31. package/dist/types/element/src/shape.d.ts +1 -1
  32. package/dist/types/element/src/textElement.d.ts +1 -1
  33. package/dist/types/element/src/textWrapping.d.ts +26 -0
  34. package/dist/types/element/src/types.d.ts +4 -1
  35. package/dist/types/element/src/utils.d.ts +1 -1
  36. package/dist/types/excalidraw/actions/actionAddToLibrary.d.ts +6 -3
  37. package/dist/types/excalidraw/actions/actionBoundText.d.ts +5 -3
  38. package/dist/types/excalidraw/actions/actionCanvas.d.ts +20 -10
  39. package/dist/types/excalidraw/actions/actionClipboard.d.ts +4 -2
  40. package/dist/types/excalidraw/actions/actionCropEditor.d.ts +2 -1
  41. package/dist/types/excalidraw/actions/actionDeleteSelected.d.ts +6 -3
  42. package/dist/types/excalidraw/actions/actionDeselect.d.ts +161 -0
  43. package/dist/types/excalidraw/actions/actionElementLink.d.ts +2 -1
  44. package/dist/types/excalidraw/actions/actionElementLock.d.ts +4 -2
  45. package/dist/types/excalidraw/actions/actionEmbeddable.d.ts +2 -1
  46. package/dist/types/excalidraw/actions/actionExport.d.ts +9 -4
  47. package/dist/types/excalidraw/actions/actionFrame.d.ts +8 -4
  48. package/dist/types/excalidraw/actions/actionGroup.d.ts +5 -3
  49. package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +2 -1
  50. package/dist/types/excalidraw/actions/actionLink.d.ts +2 -1
  51. package/dist/types/excalidraw/actions/actionMenu.d.ts +2 -1
  52. package/dist/types/excalidraw/actions/actionProperties.d.ts +6 -4
  53. package/dist/types/excalidraw/actions/actionSelectAll.d.ts +2 -1
  54. package/dist/types/excalidraw/actions/actionStyles.d.ts +3 -1
  55. package/dist/types/excalidraw/actions/actionTextAutoResize.d.ts +3 -3
  56. package/dist/types/excalidraw/actions/actionToggleArrowBinding.d.ts +2 -1
  57. package/dist/types/excalidraw/actions/actionToggleGridMode.d.ts +2 -1
  58. package/dist/types/excalidraw/actions/actionToggleMidpointSnapping.d.ts +2 -1
  59. package/dist/types/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +2 -1
  60. package/dist/types/excalidraw/actions/actionToggleSearchMenu.d.ts +2 -1
  61. package/dist/types/excalidraw/actions/actionToggleStats.d.ts +2 -1
  62. package/dist/types/excalidraw/actions/actionToggleViewMode.d.ts +2 -1
  63. package/dist/types/excalidraw/actions/actionToggleZenMode.d.ts +2 -1
  64. package/dist/types/excalidraw/actions/index.d.ts +1 -0
  65. package/dist/types/excalidraw/actions/types.d.ts +1 -1
  66. package/dist/types/excalidraw/appState.d.ts +1 -0
  67. package/dist/types/excalidraw/components/App.d.ts +11 -0
  68. package/dist/types/excalidraw/components/IconPicker.d.ts +14 -9
  69. package/dist/types/excalidraw/components/Range.d.ts +10 -4
  70. package/dist/types/excalidraw/components/canvases/InteractiveCanvas.d.ts +1 -0
  71. package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuItemContentRadio.d.ts +2 -1
  72. package/dist/types/excalidraw/components/icons.d.ts +17 -8
  73. package/dist/types/excalidraw/components/main-menu/DefaultItems.d.ts +1 -0
  74. package/dist/types/excalidraw/data/blob.d.ts +4 -2
  75. package/dist/types/excalidraw/data/json.d.ts +2 -1
  76. package/dist/types/excalidraw/textAutoResizeHandle.d.ts +15 -0
  77. package/dist/types/excalidraw/types.d.ts +6 -2
  78. package/dist/types/excalidraw/wysiwyg/textWysiwyg.d.ts +5 -1
  79. package/dist/types/math/src/curve.d.ts +4 -1
  80. package/dist/types/math/src/point.d.ts +1 -1
  81. package/package.json +2 -5
  82. package/dist/dev/chunk-QYOG4VCN.js.map +0 -7
  83. package/dist/dev/chunk-V5BIR3MG.js.map +0 -7
  84. package/dist/prod/chunk-RKBY2MGL.js +0 -33
  85. package/dist/prod/data/image-3NG2WBD6.js +0 -1
  86. /package/dist/dev/{chunk-OC36B26O.js.map → chunk-OWPVDWDP.js.map} +0 -0
  87. /package/dist/dev/components/TTDDialog/{CodeMirrorEditor-L55DYJSD.js.map → CodeMirrorEditor-GAACHFBI.js.map} +0 -0
  88. /package/dist/dev/data/{image-WOLPNANH.js.map → image-LJOI7ED6.js.map} +0 -0
  89. /package/dist/dev/locales/{en-2JUZQ4KZ.js.map → en-VKRILXL5.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  define_import_meta_env_default
3
- } from "./chunk-OC36B26O.js";
3
+ } from "./chunk-OWPVDWDP.js";
4
4
  import {
5
5
  __publicField
6
6
  } from "./chunk-XDFCUUT6.js";
@@ -212,7 +212,12 @@ function pointsEqual(a, b, tolerance = PRECISION) {
212
212
  const abs = Math.abs;
213
213
  return abs(a[0] - b[0]) < tolerance && abs(a[1] - b[1]) < tolerance;
214
214
  }
215
- function pointRotateRads([x, y], [cx, cy], angle) {
215
+ function pointRotateRads(point, center, angle) {
216
+ if (!angle) {
217
+ return point;
218
+ }
219
+ const [x, y] = point;
220
+ const [cx, cy] = center;
216
221
  return pointFrom(
217
222
  (x - cx) * Math.cos(angle) - (y - cy) * Math.sin(angle) + cx,
218
223
  (x - cx) * Math.sin(angle) + (y - cy) * Math.cos(angle) + cy
@@ -343,8 +348,15 @@ var initial_guesses = [
343
348
  [0.2, 0],
344
349
  [0.8, 0]
345
350
  ];
346
- var calculate = ([t0, s0], l, c) => {
347
- const solution = solveWithAnalyticalJacobian(c, l, t0, s0, 0.01, 4);
351
+ var calculate = ([t0, s0], l, c, tolerance = 0.01, iterLimit = 4) => {
352
+ const solution = solveWithAnalyticalJacobian(
353
+ c,
354
+ l,
355
+ t0,
356
+ s0,
357
+ tolerance,
358
+ iterLimit
359
+ );
348
360
  if (!solution) {
349
361
  return null;
350
362
  }
@@ -354,16 +366,34 @@ var calculate = ([t0, s0], l, c) => {
354
366
  }
355
367
  return bezierEquation(c, t);
356
368
  };
357
- function curveIntersectLineSegment(c, l) {
358
- let solution = calculate(initial_guesses[0], l, c);
369
+ function curveIntersectLineSegment(c, l, opts) {
370
+ let solution = calculate(
371
+ initial_guesses[0],
372
+ l,
373
+ c,
374
+ opts?.tolerance,
375
+ opts?.iterLimit
376
+ );
359
377
  if (solution) {
360
378
  return [solution];
361
379
  }
362
- solution = calculate(initial_guesses[1], l, c);
380
+ solution = calculate(
381
+ initial_guesses[1],
382
+ l,
383
+ c,
384
+ opts?.tolerance,
385
+ opts?.iterLimit
386
+ );
363
387
  if (solution) {
364
388
  return [solution];
365
389
  }
366
- solution = calculate(initial_guesses[2], l, c);
390
+ solution = calculate(
391
+ initial_guesses[2],
392
+ l,
393
+ c,
394
+ opts?.tolerance,
395
+ opts?.iterLimit
396
+ );
367
397
  if (solution) {
368
398
  return [solution];
369
399
  }
@@ -2745,7 +2775,8 @@ var getDefaultAppState = () => {
2745
2775
  searchMatches: null,
2746
2776
  lockedMultiSelections: {},
2747
2777
  activeLockedId: null,
2748
- bindMode: "orbit"
2778
+ bindMode: "orbit",
2779
+ boxSelectionMode: "contain"
2749
2780
  };
2750
2781
  };
2751
2782
  var APP_STATE_STORAGE_CONF = /* @__PURE__ */ ((config) => config)({
@@ -2795,6 +2826,7 @@ var APP_STATE_STORAGE_CONF = /* @__PURE__ */ ((config) => config)({
2795
2826
  gridModeEnabled: { browser: true, export: true, server: true },
2796
2827
  height: { browser: false, export: false, server: false },
2797
2828
  isBindingEnabled: { browser: true, export: false, server: false },
2829
+ boxSelectionMode: { browser: true, export: false, server: false },
2798
2830
  bindingPreference: { browser: true, export: false, server: false },
2799
2831
  isMidpointSnappingEnabled: { browser: true, export: false, server: false },
2800
2832
  defaultSidebarDockedPreference: {
@@ -3753,12 +3785,12 @@ var setElementShapesCacheEntry = (element, shape, offset) => {
3753
3785
  }
3754
3786
  shapes.set(offset, shape);
3755
3787
  };
3756
- function deconstructLinearOrFreeDrawElement(element) {
3788
+ function deconstructLinearOrFreeDrawElement(element, elementsMap) {
3757
3789
  const cachedShape = getElementShapesCacheEntry(element, 0);
3758
3790
  if (cachedShape) {
3759
3791
  return cachedShape;
3760
3792
  }
3761
- const ops = generateLinearCollisionShape(element);
3793
+ const ops = generateLinearCollisionShape(element, elementsMap);
3762
3794
  const lines = [];
3763
3795
  const curves = [];
3764
3796
  for (let idx = 0; idx < ops.length; idx += 1) {
@@ -4626,91 +4658,168 @@ var parseTokens = (line2) => {
4626
4658
  return line2.normalize("NFC").split(breakLineRegex).filter(Boolean);
4627
4659
  };
4628
4660
  var wrapText = (text, font, maxWidth) => {
4661
+ return getWrappedTextLines(text, font, maxWidth).map((line2) => line2.text).join("\n");
4662
+ };
4663
+ var getHardLineBreaks = (text) => {
4664
+ let offset = 0;
4665
+ return text.split("\n").map((line2) => {
4666
+ const start = offset;
4667
+ const end = start + line2.length;
4668
+ offset = end + 1;
4669
+ return {
4670
+ text: line2,
4671
+ start,
4672
+ end
4673
+ };
4674
+ });
4675
+ };
4676
+ var getWrappedTextLines = (text, font, maxWidth) => {
4629
4677
  if (!Number.isFinite(maxWidth) || maxWidth < 0) {
4630
- return text;
4678
+ return getHardLineBreaks(text);
4631
4679
  }
4632
4680
  const lines = [];
4633
- const originalLines = text.split("\n");
4634
- for (const originalLine of originalLines) {
4635
- const currentLineWidth = getLineWidth(originalLine, font);
4636
- if (currentLineWidth <= maxWidth) {
4637
- lines.push(originalLine);
4638
- continue;
4681
+ let offset = 0;
4682
+ for (const originalLine of text.split("\n")) {
4683
+ const originalLineWidth = getLineWidth(originalLine, font);
4684
+ if (originalLineWidth <= maxWidth) {
4685
+ lines.push({
4686
+ text: originalLine,
4687
+ start: offset,
4688
+ end: offset + originalLine.length
4689
+ });
4690
+ } else {
4691
+ lines.push(...wrapLine(originalLine, font, maxWidth, offset));
4639
4692
  }
4640
- const wrappedLine = wrapLine(originalLine, font, maxWidth);
4641
- lines.push(...wrappedLine);
4693
+ offset += originalLine.length + 1;
4642
4694
  }
4643
- return lines.join("\n");
4695
+ return lines;
4644
4696
  };
4645
- var wrapLine = (line2, font, maxWidth) => {
4697
+ var wrapLine = (line2, font, maxWidth, lineStart) => {
4646
4698
  const lines = [];
4647
4699
  const tokens = parseTokens(line2);
4648
- const tokenIterator = tokens[Symbol.iterator]();
4649
4700
  let currentLine = "";
4701
+ let currentLineStart = lineStart;
4702
+ let currentLineEnd = lineStart;
4650
4703
  let currentLineWidth = 0;
4651
- let iterator = tokenIterator.next();
4652
- while (!iterator.done) {
4653
- const token = iterator.value;
4704
+ let tokenOffset = lineStart;
4705
+ let tokenIndex = 0;
4706
+ while (tokenIndex < tokens.length) {
4707
+ const token = tokens[tokenIndex];
4708
+ const tokenStart = tokenOffset;
4709
+ const tokenEnd = tokenStart + token.length;
4654
4710
  const testLine = currentLine + token;
4655
4711
  const testLineWidth = isSingleCharacter(token) ? currentLineWidth + charWidth.calculate(token, font) : getLineWidth(testLine, font);
4656
4712
  if (/\s/.test(token) || testLineWidth <= maxWidth) {
4713
+ if (!currentLine) {
4714
+ currentLineStart = tokenStart;
4715
+ }
4657
4716
  currentLine = testLine;
4717
+ currentLineEnd = tokenEnd;
4658
4718
  currentLineWidth = testLineWidth;
4659
- iterator = tokenIterator.next();
4719
+ tokenOffset = tokenEnd;
4720
+ tokenIndex++;
4660
4721
  continue;
4661
4722
  }
4662
4723
  if (!currentLine) {
4663
- const wrappedWord = wrapWord(token, font, maxWidth);
4664
- const trailingLine = wrappedWord[wrappedWord.length - 1] ?? "";
4724
+ const wrappedWord = wrapWord(token, font, maxWidth, tokenStart);
4725
+ const trailingLine = wrappedWord[wrappedWord.length - 1] ?? {
4726
+ text: "",
4727
+ start: tokenStart,
4728
+ end: tokenStart
4729
+ };
4665
4730
  const precedingLines = wrappedWord.slice(0, -1);
4666
4731
  lines.push(...precedingLines);
4667
- currentLine = trailingLine;
4668
- currentLineWidth = getLineWidth(trailingLine, font);
4669
- iterator = tokenIterator.next();
4732
+ currentLine = trailingLine.text;
4733
+ currentLineStart = trailingLine.start;
4734
+ currentLineEnd = trailingLine.end;
4735
+ currentLineWidth = getLineWidth(trailingLine.text, font);
4736
+ tokenOffset = tokenEnd;
4737
+ tokenIndex++;
4670
4738
  } else {
4671
- lines.push(currentLine.trimEnd());
4739
+ lines.push(
4740
+ trimLineEndAtSoftBreak(currentLine, currentLineStart, currentLineEnd)
4741
+ );
4672
4742
  currentLine = "";
4743
+ currentLineStart = tokenStart;
4744
+ currentLineEnd = tokenStart;
4673
4745
  currentLineWidth = 0;
4674
4746
  }
4675
4747
  }
4676
4748
  if (currentLine) {
4677
- const trailingLine = trimLine(currentLine, font, maxWidth);
4749
+ const trailingLine = trimLine(
4750
+ currentLine,
4751
+ currentLineStart,
4752
+ currentLineEnd,
4753
+ font,
4754
+ maxWidth
4755
+ );
4678
4756
  lines.push(trailingLine);
4679
4757
  }
4680
4758
  return lines;
4681
4759
  };
4682
- var wrapWord = (word, font, maxWidth) => {
4760
+ var wrapWord = (word, font, maxWidth, wordStart) => {
4683
4761
  if (getEmojiRegex().test(word)) {
4684
- return [word];
4762
+ return [
4763
+ {
4764
+ text: word,
4765
+ start: wordStart,
4766
+ end: wordStart + word.length
4767
+ }
4768
+ ];
4685
4769
  }
4686
4770
  satisfiesWordInvariant(word);
4687
4771
  const lines = [];
4688
4772
  const chars = Array.from(word);
4689
4773
  let currentLine = "";
4774
+ let currentLineStart = wordStart;
4775
+ let currentLineEnd = wordStart;
4690
4776
  let currentLineWidth = 0;
4777
+ let offset = wordStart;
4691
4778
  for (const char of chars) {
4779
+ const charStart = offset;
4780
+ const charEnd = charStart + char.length;
4692
4781
  const _charWidth = charWidth.calculate(char, font);
4693
4782
  const testLineWidth = currentLineWidth + _charWidth;
4694
4783
  if (testLineWidth <= maxWidth) {
4784
+ if (!currentLine) {
4785
+ currentLineStart = charStart;
4786
+ }
4695
4787
  currentLine = currentLine + char;
4788
+ currentLineEnd = charEnd;
4696
4789
  currentLineWidth = testLineWidth;
4790
+ offset = charEnd;
4697
4791
  continue;
4698
4792
  }
4699
4793
  if (currentLine) {
4700
- lines.push(currentLine);
4794
+ lines.push({
4795
+ text: currentLine,
4796
+ start: currentLineStart,
4797
+ end: currentLineEnd
4798
+ });
4701
4799
  }
4702
4800
  currentLine = char;
4801
+ currentLineStart = charStart;
4802
+ currentLineEnd = charEnd;
4703
4803
  currentLineWidth = _charWidth;
4804
+ offset = charEnd;
4704
4805
  }
4705
4806
  if (currentLine) {
4706
- lines.push(currentLine);
4807
+ lines.push({
4808
+ text: currentLine,
4809
+ start: currentLineStart,
4810
+ end: currentLineEnd
4811
+ });
4707
4812
  }
4708
4813
  return lines;
4709
4814
  };
4710
- var trimLine = (line2, font, maxWidth) => {
4815
+ var trimLine = (line2, start, end, font, maxWidth) => {
4711
4816
  const shouldTrimWhitespaces = getLineWidth(line2, font) > maxWidth;
4712
4817
  if (!shouldTrimWhitespaces) {
4713
- return line2;
4818
+ return {
4819
+ text: line2,
4820
+ start,
4821
+ end
4822
+ };
4714
4823
  }
4715
4824
  let [, trimmedLine, whitespaces] = line2.match(/^(.+?)(\s+)$/) ?? [
4716
4825
  line2,
@@ -4727,7 +4836,19 @@ var trimLine = (line2, font, maxWidth) => {
4727
4836
  trimmedLine = trimmedLine + whitespace;
4728
4837
  trimmedLineWidth = testLineWidth;
4729
4838
  }
4730
- return trimmedLine;
4839
+ return {
4840
+ text: trimmedLine,
4841
+ start,
4842
+ end: end - (line2.length - trimmedLine.length)
4843
+ };
4844
+ };
4845
+ var trimLineEndAtSoftBreak = (line2, start, end) => {
4846
+ const trimmedLine = line2.trimEnd();
4847
+ return {
4848
+ text: trimmedLine,
4849
+ start,
4850
+ end: end - (line2.length - trimmedLine.length)
4851
+ };
4731
4852
  };
4732
4853
  var isSingleCharacter = (maybeSingleCharacter) => {
4733
4854
  return maybeSingleCharacter.codePointAt(0) !== void 0 && maybeSingleCharacter.codePointAt(1) === void 0;
@@ -4966,7 +5087,8 @@ var getContainerCenter = (container, appState, elementsMap) => {
4966
5087
  if (!midSegmentMidpoint) {
4967
5088
  midSegmentMidpoint = LinearElementEditor.getSegmentMidPoint(
4968
5089
  container,
4969
- index + 1
5090
+ index + 1,
5091
+ elementsMap
4970
5092
  );
4971
5093
  }
4972
5094
  return { x: midSegmentMidpoint[0], y: midSegmentMidpoint[1] };
@@ -5101,7 +5223,7 @@ var distanceToElement = (element, elementsMap, p) => {
5101
5223
  case "line":
5102
5224
  case "arrow":
5103
5225
  case "freedraw":
5104
- return distanceToLinearOrFreeDraElement(element, p);
5226
+ return distanceToLinearOrFreeDraElement(element, elementsMap, p);
5105
5227
  }
5106
5228
  };
5107
5229
  var distanceToRectanguloidElement = (element, elementsMap, p) => {
@@ -5130,8 +5252,11 @@ var distanceToEllipseElement = (element, elementsMap, p) => {
5130
5252
  ellipse(center, element.width / 2, element.height / 2)
5131
5253
  );
5132
5254
  };
5133
- var distanceToLinearOrFreeDraElement = (element, p) => {
5134
- const [lines, curves] = deconstructLinearOrFreeDrawElement(element);
5255
+ var distanceToLinearOrFreeDraElement = (element, elementsMap, p) => {
5256
+ const [lines, curves] = deconstructLinearOrFreeDrawElement(
5257
+ element,
5258
+ elementsMap
5259
+ );
5135
5260
  return Math.min(
5136
5261
  ...lines.map((s) => distanceToLineSegment(p, s)),
5137
5262
  ...curves.map((a) => curvePointDistance(a, p))
@@ -5180,14 +5305,11 @@ var hitElementItself = ({
5180
5305
  )
5181
5306
  ) : false;
5182
5307
  const bounds = getElementBounds(element, elementsMap, true);
5183
- const hitBounds = isPointWithinBounds(
5184
- pointFrom(bounds[0] - threshold, bounds[1] - threshold),
5185
- pointRotateRads(
5186
- point,
5187
- getCenterForBounds(bounds),
5188
- -element.angle
5189
- ),
5190
- pointFrom(bounds[2] + threshold, bounds[3] + threshold)
5308
+ const hitBounds = isPointInRotatedBounds(
5309
+ point,
5310
+ bounds,
5311
+ element.angle,
5312
+ threshold
5191
5313
  );
5192
5314
  if (!hitBounds && !hitFrameName) {
5193
5315
  return false;
@@ -5205,13 +5327,17 @@ var hitElementItself = ({
5205
5327
  cachedHit = result;
5206
5328
  return result;
5207
5329
  };
5330
+ var isPointInRotatedBounds = (point, bounds, angle, tolerance = 0) => {
5331
+ const adjustedPoint = angle === 0 ? point : pointRotateRads(point, getCenterForBounds(bounds), -angle);
5332
+ return isPointWithinBounds(
5333
+ pointFrom(bounds[0] - tolerance, bounds[1] - tolerance),
5334
+ adjustedPoint,
5335
+ pointFrom(bounds[2] + tolerance, bounds[3] + tolerance)
5336
+ );
5337
+ };
5208
5338
  var hitElementBoundingBox = (point, element, elementsMap, tolerance = 0) => {
5209
- let [x1, y1, x2, y2] = getElementBounds(element, elementsMap);
5210
- x1 -= tolerance;
5211
- y1 -= tolerance;
5212
- x2 += tolerance;
5213
- y2 += tolerance;
5214
- return isPointWithinBounds(pointFrom(x1, y1), point, pointFrom(x2, y2));
5339
+ const bounds = getElementBounds(element, elementsMap, true);
5340
+ return isPointInRotatedBounds(point, bounds, element.angle, tolerance);
5215
5341
  };
5216
5342
  var hitElementBoundingBoxOnly = (hitArgs, elementsMap) => !hitElementItself(hitArgs) && // bound text is considered part of the element (even if it's outside the bounding box)
5217
5343
  !hitElementBoundText(hitArgs.point, hitArgs.element, elementsMap) && hitElementBoundingBox(hitArgs.point, hitArgs.element, elementsMap);
@@ -5370,7 +5496,12 @@ var intersectElementWithLineSegment = (element, elementsMap, line2, offset = 0,
5370
5496
  case "line":
5371
5497
  case "freedraw":
5372
5498
  case "arrow":
5373
- return intersectLinearOrFreeDrawWithLineSegment(element, line2, onlyFirst);
5499
+ return intersectLinearOrFreeDrawWithLineSegment(
5500
+ element,
5501
+ line2,
5502
+ elementsMap,
5503
+ onlyFirst
5504
+ );
5374
5505
  }
5375
5506
  };
5376
5507
  var curveIntersections = (curves, segment, intersections, center, angle, onlyFirst = false) => {
@@ -5409,8 +5540,11 @@ var lineIntersections = (lines, segment, intersections, center, angle, onlyFirst
5409
5540
  }
5410
5541
  return intersections;
5411
5542
  };
5412
- var intersectLinearOrFreeDrawWithLineSegment = (element, segment, onlyFirst = false) => {
5413
- const [lines, curves] = deconstructLinearOrFreeDrawElement(element);
5543
+ var intersectLinearOrFreeDrawWithLineSegment = (element, segment, elementsMap, onlyFirst = false) => {
5544
+ const [lines, curves] = deconstructLinearOrFreeDrawElement(
5545
+ element,
5546
+ elementsMap
5547
+ );
5414
5548
  const intersections = [];
5415
5549
  for (const l of lines) {
5416
5550
  const intersection = lineSegmentIntersectionPoints(l, segment);
@@ -5432,7 +5566,9 @@ var intersectLinearOrFreeDrawWithLineSegment = (element, segment, onlyFirst = fa
5432
5566
  if (!doBoundsIntersect(b1, b2)) {
5433
5567
  continue;
5434
5568
  }
5435
- const hits = curveIntersectLineSegment(c, segment);
5569
+ const hits = curveIntersectLineSegment(c, segment, {
5570
+ iterLimit: 10
5571
+ });
5436
5572
  if (hits.length > 0) {
5437
5573
  intersections.push(...hits);
5438
5574
  if (onlyFirst) {
@@ -9324,7 +9460,7 @@ var _LinearElementEditor = class _LinearElementEditor {
9324
9460
  }
9325
9461
  };
9326
9462
  }
9327
- static isSegmentTooShort(element, startPoint, endPoint, index, zoom) {
9463
+ static isSegmentTooShort(element, startPoint, endPoint, index, zoom, elementsMap) {
9328
9464
  if (isElbowArrow(element)) {
9329
9465
  if (index >= 0 && index < element.points.length) {
9330
9466
  return pointDistance(startPoint, endPoint) * zoom.value < _LinearElementEditor.POINT_HANDLE_SIZE / 2;
@@ -9333,7 +9469,10 @@ var _LinearElementEditor = class _LinearElementEditor {
9333
9469
  }
9334
9470
  let distance2 = pointDistance(startPoint, endPoint);
9335
9471
  if (element.points.length > 2 && element.roundness) {
9336
- const [lines, curves] = deconstructLinearOrFreeDrawElement(element);
9472
+ const [lines, curves] = deconstructLinearOrFreeDrawElement(
9473
+ element,
9474
+ elementsMap
9475
+ );
9337
9476
  invariant(
9338
9477
  lines.length === 0 && curves.length > 0,
9339
9478
  "Only linears built out of curves are supported"
@@ -9346,7 +9485,7 @@ var _LinearElementEditor = class _LinearElementEditor {
9346
9485
  }
9347
9486
  return distance2 * zoom.value < _LinearElementEditor.POINT_HANDLE_SIZE * 4;
9348
9487
  }
9349
- static getSegmentMidPoint(element, index) {
9488
+ static getSegmentMidPoint(element, index, elementsMap) {
9350
9489
  if (isElbowArrow(element)) {
9351
9490
  invariant(
9352
9491
  element.points.length >= index,
@@ -9355,7 +9494,10 @@ var _LinearElementEditor = class _LinearElementEditor {
9355
9494
  const p = pointCenter(element.points[index - 1], element.points[index]);
9356
9495
  return pointFrom(element.x + p[0], element.y + p[1]);
9357
9496
  }
9358
- const [lines, curves] = deconstructLinearOrFreeDrawElement(element);
9497
+ const [lines, curves] = deconstructLinearOrFreeDrawElement(
9498
+ element,
9499
+ elementsMap
9500
+ );
9359
9501
  invariant(
9360
9502
  lines.length === 0 && curves.length > 0 || lines.length > 0 && curves.length === 0,
9361
9503
  "Only linears built out of either segments or curves are supported"
@@ -10055,7 +10197,8 @@ __publicField(_LinearElementEditor, "getEditorMidPoints", (element, elementsMap,
10055
10197
  element.points[index],
10056
10198
  element.points[index + 1],
10057
10199
  index,
10058
- appState.zoom
10200
+ appState.zoom,
10201
+ elementsMap
10059
10202
  )) {
10060
10203
  midpoints.push(null);
10061
10204
  index++;
@@ -10063,7 +10206,8 @@ __publicField(_LinearElementEditor, "getEditorMidPoints", (element, elementsMap,
10063
10206
  }
10064
10207
  const segmentMidPoint = _LinearElementEditor.getSegmentMidPoint(
10065
10208
  element,
10066
- index + 1
10209
+ index + 1,
10210
+ elementsMap
10067
10211
  );
10068
10212
  midpoints.push(segmentMidPoint);
10069
10213
  index++;
@@ -10150,7 +10294,8 @@ __publicField(_LinearElementEditor, "getBoundTextElementPosition", (element, bou
10150
10294
  const index = element.points.length / 2 - 1;
10151
10295
  const midSegmentMidpoint = _LinearElementEditor.getSegmentMidPoint(
10152
10296
  element,
10153
- index + 1
10297
+ index + 1,
10298
+ elementsMap
10154
10299
  );
10155
10300
  x = midSegmentMidpoint[0] - boundTextElement.width / 2;
10156
10301
  y = midSegmentMidpoint[1] - boundTextElement.height / 2;
@@ -10465,7 +10610,7 @@ var pointDraggingUpdates = (selectedPointsIndices, deltaX, deltaY, scenePointerX
10465
10610
  nextArrow.endBinding.elementId
10466
10611
  ) : null;
10467
10612
  const endLocalPoint = startIsDraggingOverEndElement ? nextArrow.points[nextArrow.points.length - 1] : endIsDraggingOverStartElement && app.state.bindMode !== "inside" && getFeatureFlag("COMPLEX_BINDINGS") ? nextArrow.points[0] : endBindable ? updateBoundPoint(
10468
- element,
10613
+ nextArrow,
10469
10614
  "endBinding",
10470
10615
  nextArrow.endBinding,
10471
10616
  endBindable,
@@ -10477,7 +10622,7 @@ var pointDraggingUpdates = (selectedPointsIndices, deltaX, deltaY, scenePointerX
10477
10622
  nextArrow.startBinding.elementId
10478
10623
  ) : null;
10479
10624
  const startLocalPoint = endIsDraggingOverStartElement && getFeatureFlag("COMPLEX_BINDINGS") ? nextArrow.points[0] : startIsDraggingOverEndElement && app.state.bindMode !== "inside" && getFeatureFlag("COMPLEX_BINDINGS") ? endLocalPoint : startBindable ? updateBoundPoint(
10480
- element,
10625
+ nextArrow,
10481
10626
  "startBinding",
10482
10627
  nextArrow.startBinding,
10483
10628
  startBindable,
@@ -10545,131 +10690,6 @@ function doLineSegmentsIntersect(a, b) {
10545
10690
  return doBBoxesIntersect(getBBox(a), getBBox(b)) && isLineSegmentTouchingOrCrossingLine(a, b) && isLineSegmentTouchingOrCrossingLine(b, a);
10546
10691
  }
10547
10692
 
10548
- // ../utils/src/withinBounds.ts
10549
- var getNonLinearElementRelativePoints = (element) => {
10550
- if (element.type === "diamond") {
10551
- return [
10552
- pointFrom(element.width / 2, 0),
10553
- pointFrom(element.width, element.height / 2),
10554
- pointFrom(element.width / 2, element.height),
10555
- pointFrom(0, element.height / 2)
10556
- ];
10557
- }
10558
- return [
10559
- pointFrom(0, 0),
10560
- pointFrom(0 + element.width, 0),
10561
- pointFrom(0 + element.width, element.height),
10562
- pointFrom(0, element.height)
10563
- ];
10564
- };
10565
- var getElementRelativePoints = (element) => {
10566
- if (isLinearElement(element) || isFreeDrawElement(element)) {
10567
- return element.points;
10568
- }
10569
- return getNonLinearElementRelativePoints(element);
10570
- };
10571
- var getMinMaxPoints = (points) => {
10572
- const ret = points.reduce(
10573
- (limits, [x, y]) => {
10574
- limits.minY = Math.min(limits.minY, y);
10575
- limits.minX = Math.min(limits.minX, x);
10576
- limits.maxX = Math.max(limits.maxX, x);
10577
- limits.maxY = Math.max(limits.maxY, y);
10578
- return limits;
10579
- },
10580
- {
10581
- minX: Infinity,
10582
- minY: Infinity,
10583
- maxX: -Infinity,
10584
- maxY: -Infinity,
10585
- cx: 0,
10586
- cy: 0
10587
- }
10588
- );
10589
- ret.cx = (ret.maxX + ret.minX) / 2;
10590
- ret.cy = (ret.maxY + ret.minY) / 2;
10591
- return ret;
10592
- };
10593
- var getRotatedBBox = (element) => {
10594
- const points = getElementRelativePoints(element);
10595
- const { cx, cy } = getMinMaxPoints(points);
10596
- const centerPoint = pointFrom(cx, cy);
10597
- const rotatedPoints = points.map(
10598
- (p) => pointRotateRads(p, centerPoint, element.angle)
10599
- );
10600
- const { minX, minY, maxX, maxY } = getMinMaxPoints(rotatedPoints);
10601
- return [
10602
- minX + element.x,
10603
- minY + element.y,
10604
- maxX + element.x,
10605
- maxY + element.y
10606
- ];
10607
- };
10608
- var isElementInsideBBox = (element, bbox, eitherDirection = false) => {
10609
- const elementBBox = getRotatedBBox(element);
10610
- const elementInsideBbox = bbox[0] <= elementBBox[0] && bbox[2] >= elementBBox[2] && bbox[1] <= elementBBox[1] && bbox[3] >= elementBBox[3];
10611
- if (!eitherDirection) {
10612
- return elementInsideBbox;
10613
- }
10614
- if (elementInsideBbox) {
10615
- return true;
10616
- }
10617
- return elementBBox[0] <= bbox[0] && elementBBox[2] >= bbox[2] && elementBBox[1] <= bbox[1] && elementBBox[3] >= bbox[3];
10618
- };
10619
- var elementPartiallyOverlapsWithOrContainsBBox = (element, bbox) => {
10620
- const elementBBox = getRotatedBBox(element);
10621
- return (rangeIncludesValue(elementBBox[0], rangeInclusive(bbox[0], bbox[2])) || rangeIncludesValue(
10622
- bbox[0],
10623
- rangeInclusive(elementBBox[0], elementBBox[2])
10624
- )) && (rangeIncludesValue(elementBBox[1], rangeInclusive(bbox[1], bbox[3])) || rangeIncludesValue(
10625
- bbox[1],
10626
- rangeInclusive(elementBBox[1], elementBBox[3])
10627
- ));
10628
- };
10629
- var elementsOverlappingBBox = ({
10630
- elements,
10631
- bounds,
10632
- type,
10633
- errorMargin = 0
10634
- }) => {
10635
- if (isExcalidrawElement(bounds)) {
10636
- bounds = getElementBounds(bounds, arrayToMap(elements));
10637
- }
10638
- const adjustedBBox = [
10639
- bounds[0] - errorMargin,
10640
- bounds[1] - errorMargin,
10641
- bounds[2] + errorMargin,
10642
- bounds[3] + errorMargin
10643
- ];
10644
- const includedElementSet = /* @__PURE__ */ new Set();
10645
- for (const element of elements) {
10646
- if (includedElementSet.has(element.id)) {
10647
- continue;
10648
- }
10649
- const isOverlaping = type === "overlap" ? elementPartiallyOverlapsWithOrContainsBBox(element, adjustedBBox) : type === "inside" ? isElementInsideBBox(element, adjustedBBox) : isElementInsideBBox(element, adjustedBBox, true);
10650
- if (isOverlaping) {
10651
- includedElementSet.add(element.id);
10652
- if (element.boundElements) {
10653
- for (const boundElement of element.boundElements) {
10654
- includedElementSet.add(boundElement.id);
10655
- }
10656
- }
10657
- if (isTextElement(element) && element.containerId) {
10658
- includedElementSet.add(element.containerId);
10659
- }
10660
- if (isArrowElement(element)) {
10661
- if (element.startBinding) {
10662
- includedElementSet.add(element.startBinding.elementId);
10663
- }
10664
- if (element.endBinding) {
10665
- includedElementSet.add(element.endBinding?.elementId);
10666
- }
10667
- }
10668
- }
10669
- }
10670
- return elements.filter((element) => includedElementSet.has(element.id));
10671
- };
10672
-
10673
10693
  // ../element/src/groups.ts
10674
10694
  var selectGroup = (groupId, appState, elements) => {
10675
10695
  const elementsInGroup = elements.reduce(
@@ -10943,6 +10963,15 @@ var getSelectedElementsByGroup = (selectedElements, elementsMap, appState) => {
10943
10963
  };
10944
10964
 
10945
10965
  // ../element/src/selection.ts
10966
+ var shouldIgnoreElementFromSelection = (element) => element.locked || isBoundToContainer(element);
10967
+ var excludeElementsFromFrames = (selectedElements, framesInSelection) => {
10968
+ return selectedElements.filter((element) => {
10969
+ if (element.frameId && framesInSelection.has(element.frameId)) {
10970
+ return false;
10971
+ }
10972
+ return true;
10973
+ });
10974
+ };
10946
10975
  var excludeElementsInFramesFromSelection = (selectedElements) => {
10947
10976
  const framesInSelection = /* @__PURE__ */ new Set();
10948
10977
  selectedElements.forEach((element) => {
@@ -10950,34 +10979,182 @@ var excludeElementsInFramesFromSelection = (selectedElements) => {
10950
10979
  framesInSelection.add(element.id);
10951
10980
  }
10952
10981
  });
10953
- return selectedElements.filter((element) => {
10954
- if (element.frameId && framesInSelection.has(element.frameId)) {
10955
- return false;
10982
+ return excludeElementsFromFrames(selectedElements, framesInSelection);
10983
+ };
10984
+ var getElementsWithinSelection = (elements, selection, elementsMap, excludeElementsInFrames = true, boxSelectionMode = "contain") => {
10985
+ const [selectionStartX, selectionStartY, selectionEndX, selectionEndY] = getElementAbsoluteCoords(selection, elementsMap);
10986
+ const selectionX1 = Math.min(selectionStartX, selectionEndX);
10987
+ const selectionY1 = Math.min(selectionStartY, selectionEndY);
10988
+ const selectionX2 = Math.max(selectionStartX, selectionEndX);
10989
+ const selectionY2 = Math.max(selectionStartY, selectionEndY);
10990
+ const selectionBounds = [
10991
+ selectionX1,
10992
+ selectionY1,
10993
+ selectionX2,
10994
+ selectionY2
10995
+ ];
10996
+ const selectionEdges = [
10997
+ lineSegment(
10998
+ pointFrom(selectionX1, selectionY1),
10999
+ pointFrom(selectionX2, selectionY1)
11000
+ ),
11001
+ lineSegment(
11002
+ pointFrom(selectionX2, selectionY1),
11003
+ pointFrom(selectionX2, selectionY2)
11004
+ ),
11005
+ lineSegment(
11006
+ pointFrom(selectionX2, selectionY2),
11007
+ pointFrom(selectionX1, selectionY2)
11008
+ ),
11009
+ lineSegment(
11010
+ pointFrom(selectionX1, selectionY2),
11011
+ pointFrom(selectionX1, selectionY1)
11012
+ )
11013
+ ];
11014
+ const framesInSelection = excludeElementsInFrames ? /* @__PURE__ */ new Set() : null;
11015
+ let elementsInSelection = [];
11016
+ for (const element of elements) {
11017
+ if (shouldIgnoreElementFromSelection(element)) {
11018
+ continue;
10956
11019
  }
10957
- return true;
10958
- });
10959
- };
10960
- var getElementsWithinSelection = (elements, selection, elementsMap, excludeElementsInFrames = true) => {
10961
- const [selectionX1, selectionY1, selectionX2, selectionY2] = getElementAbsoluteCoords(selection, elementsMap);
10962
- let elementsInSelection = elements.filter((element) => {
10963
- let [elementX1, elementY1, elementX2, elementY2] = getElementBounds(
10964
- element,
10965
- elementsMap
10966
- );
10967
- const containingFrame = getContainingFrame(element, elementsMap);
10968
- if (containingFrame) {
10969
- const [fx1, fy1, fx2, fy2] = getElementBounds(
10970
- containingFrame,
11020
+ const strokeWidth = element.strokeWidth;
11021
+ let labelAABB = null;
11022
+ let elementAABB = getElementBounds(element, elementsMap);
11023
+ elementAABB = [
11024
+ elementAABB[0] - strokeWidth / 2,
11025
+ elementAABB[1] - strokeWidth / 2,
11026
+ elementAABB[2] + strokeWidth / 2,
11027
+ elementAABB[3] + strokeWidth / 2
11028
+ ];
11029
+ const boundTextElement = isArrowElement(element) && getBoundTextElement(element, elementsMap);
11030
+ if (boundTextElement) {
11031
+ const { x, y } = LinearElementEditor.getBoundTextElementPosition(
11032
+ element,
11033
+ boundTextElement,
10971
11034
  elementsMap
10972
11035
  );
10973
- elementX1 = Math.max(fx1, elementX1);
10974
- elementY1 = Math.max(fy1, elementY1);
10975
- elementX2 = Math.min(fx2, elementX2);
10976
- elementY2 = Math.min(fy2, elementY2);
11036
+ labelAABB = [
11037
+ x,
11038
+ y,
11039
+ x + boundTextElement.width,
11040
+ y + boundTextElement.height
11041
+ ];
10977
11042
  }
10978
- return element.locked === false && element.type !== "selection" && !isBoundToContainer(element) && selectionX1 <= elementX1 && selectionY1 <= elementY1 && selectionX2 >= elementX2 && selectionY2 >= elementY2;
10979
- });
10980
- elementsInSelection = excludeElementsInFrames ? excludeElementsInFramesFromSelection(elementsInSelection) : elementsInSelection;
11043
+ const associatedFrame = getContainingFrame(element, elementsMap);
11044
+ if (associatedFrame && isElementIntersectingFrame(element, associatedFrame, elementsMap)) {
11045
+ const frameAABB = getElementBounds(associatedFrame, elementsMap);
11046
+ elementAABB = [
11047
+ Math.max(elementAABB[0], frameAABB[0]),
11048
+ Math.max(elementAABB[1], frameAABB[1]),
11049
+ Math.min(elementAABB[2], frameAABB[2]),
11050
+ Math.min(elementAABB[3], frameAABB[3])
11051
+ ];
11052
+ labelAABB = labelAABB ? [
11053
+ Math.max(labelAABB[0], frameAABB[0]),
11054
+ Math.max(labelAABB[1], frameAABB[1]),
11055
+ Math.min(labelAABB[2], frameAABB[2]),
11056
+ Math.min(labelAABB[3], frameAABB[3])
11057
+ ] : null;
11058
+ }
11059
+ const commonAABB2 = labelAABB ? [
11060
+ Math.min(labelAABB[0], elementAABB[0]),
11061
+ Math.min(labelAABB[1], elementAABB[1]),
11062
+ Math.max(labelAABB[2], elementAABB[2]),
11063
+ Math.max(labelAABB[3], elementAABB[3])
11064
+ ] : elementAABB;
11065
+ if (boundsContainBounds(selectionBounds, commonAABB2)) {
11066
+ if (framesInSelection && isFrameLikeElement(element)) {
11067
+ framesInSelection.add(element.id);
11068
+ } else {
11069
+ elementsInSelection.push(element);
11070
+ continue;
11071
+ }
11072
+ }
11073
+ if (boxSelectionMode === "overlap" && labelAABB && doBoundsIntersect(selectionBounds, labelAABB)) {
11074
+ elementsInSelection.push(element);
11075
+ continue;
11076
+ }
11077
+ if (boxSelectionMode === "overlap" && doBoundsIntersect(selectionBounds, elementAABB)) {
11078
+ let hasIntersection = false;
11079
+ if (isLinearElement(element) || isFreeDrawElement(element)) {
11080
+ const center = elementCenterPoint(element, elementsMap);
11081
+ hasIntersection = element.points.some((point) => {
11082
+ const rotatedPoint = pointRotateRads(
11083
+ pointFrom(element.x + point[0], element.y + point[1]),
11084
+ center,
11085
+ element.angle
11086
+ );
11087
+ return pointInsideBounds(rotatedPoint, selectionBounds);
11088
+ });
11089
+ } else {
11090
+ const nonRotatedElementBounds = getElementBounds(
11091
+ element,
11092
+ elementsMap,
11093
+ true
11094
+ );
11095
+ const center = elementCenterPoint(element, elementsMap);
11096
+ hasIntersection = [
11097
+ pointRotateRads(
11098
+ pointFrom(
11099
+ (nonRotatedElementBounds[0] + nonRotatedElementBounds[2]) / 2,
11100
+ nonRotatedElementBounds[1]
11101
+ ),
11102
+ center,
11103
+ element.angle
11104
+ ),
11105
+ pointRotateRads(
11106
+ pointFrom(
11107
+ nonRotatedElementBounds[2],
11108
+ (nonRotatedElementBounds[1] + nonRotatedElementBounds[3]) / 2
11109
+ ),
11110
+ center,
11111
+ element.angle
11112
+ ),
11113
+ pointRotateRads(
11114
+ pointFrom(
11115
+ (nonRotatedElementBounds[0] + nonRotatedElementBounds[2]) / 2,
11116
+ nonRotatedElementBounds[3]
11117
+ ),
11118
+ center,
11119
+ element.angle
11120
+ ),
11121
+ pointRotateRads(
11122
+ pointFrom(
11123
+ nonRotatedElementBounds[0],
11124
+ (nonRotatedElementBounds[1] + nonRotatedElementBounds[3]) / 2
11125
+ ),
11126
+ center,
11127
+ element.angle
11128
+ )
11129
+ ].some((point) => {
11130
+ return pointInsideBounds(
11131
+ pointRotateRads(point, center, element.angle),
11132
+ selectionBounds
11133
+ );
11134
+ });
11135
+ }
11136
+ if (!hasIntersection) {
11137
+ hasIntersection = selectionEdges.some(
11138
+ (selectionEdge) => intersectElementWithLineSegment(
11139
+ element,
11140
+ elementsMap,
11141
+ selectionEdge,
11142
+ strokeWidth / 2,
11143
+ true
11144
+ // Stop at first hit for better performance
11145
+ ).length > 0
11146
+ );
11147
+ }
11148
+ if (hasIntersection) {
11149
+ if (framesInSelection && isFrameLikeElement(element)) {
11150
+ framesInSelection.add(element.id);
11151
+ }
11152
+ elementsInSelection.push(element);
11153
+ continue;
11154
+ }
11155
+ }
11156
+ }
11157
+ elementsInSelection = framesInSelection ? excludeElementsFromFrames(elementsInSelection, framesInSelection) : elementsInSelection;
10981
11158
  elementsInSelection = elementsInSelection.filter((element) => {
10982
11159
  const containingFrame = getContainingFrame(element, elementsMap);
10983
11160
  if (containingFrame) {
@@ -11097,6 +11274,10 @@ var getSelectionStateForElements = (targetElements, allElements, appState) => {
11097
11274
  )
11098
11275
  };
11099
11276
  };
11277
+ var getActiveTextElement = (selectedElements, appState) => {
11278
+ const activeTextElement = appState.editingTextElement || selectedElements.length === 1 && isTextElement(selectedElements[0]) && selectedElements[0];
11279
+ return activeTextElement || null;
11280
+ };
11100
11281
 
11101
11282
  // ../element/src/frame.ts
11102
11283
  var bindElementsToFramesAfterDuplication = (nextElements, origElements, origIdToDuplicateId) => {
@@ -11572,12 +11753,17 @@ var getDefaultFrameName = (element) => {
11572
11753
  var getFrameLikeTitle = (element) => {
11573
11754
  return element.name === null ? getDefaultFrameName(element) : element.name;
11574
11755
  };
11575
- var getElementsOverlappingFrame = (elements, frame) => {
11576
- return elementsOverlappingBBox({
11577
- elements,
11578
- bounds: frame,
11579
- type: "overlap"
11580
- }).filter((el) => !el.frameId || el.frameId === frame.id);
11756
+ var getElementsOverlappingFrame = (elements, frame, elementsMap) => {
11757
+ return elements.filter(
11758
+ (el) => (
11759
+ // exclude elements which are overlapping, but are in a different frame,
11760
+ // and thus invisible in target frame
11761
+ (!el.frameId || el.frameId === frame.id) && doBoundsIntersect(
11762
+ getElementBounds(el, elementsMap),
11763
+ getElementBounds(frame, elementsMap)
11764
+ )
11765
+ )
11766
+ );
11581
11767
  };
11582
11768
  var frameAndChildrenSelectedTogether = (selectedElements) => {
11583
11769
  const selectedElementsMap = arrayToMap(selectedElements);
@@ -12410,45 +12596,88 @@ var modifyIframeLikeForRoughOptions = (element, isExporting, embedsValidationSta
12410
12596
  }
12411
12597
  return element;
12412
12598
  };
12413
- var getArrowheadShapes = (element, shape, position, arrowhead, generator, options, canvasBackgroundColor, isDarkMode) => {
12414
- canvasBackgroundColor = canvasBackgroundColor || "transparent";
12415
- const arrowheadPoints = getArrowheadPoints(
12416
- element,
12417
- shape,
12418
- position,
12419
- arrowhead
12420
- );
12599
+ var generateArrowheadCardinalityOne = (generator, arrowheadPoints, lineOptions) => {
12421
12600
  if (arrowheadPoints === null) {
12422
12601
  return [];
12423
12602
  }
12424
- const generateCrowfootOne = (arrowheadPoints2, options2) => {
12425
- if (arrowheadPoints2 === null) {
12426
- return [];
12427
- }
12428
- const [, , x3, y3, x4, y4] = arrowheadPoints2;
12429
- return [generator.line(x3, y3, x4, y4, options2)];
12603
+ const [, , x3, y3, x4, y4] = arrowheadPoints;
12604
+ return [generator.line(x3, y3, x4, y4, lineOptions)];
12605
+ };
12606
+ var generateArrowheadLinesToTip = (generator, arrowheadPoints, lineOptions) => {
12607
+ if (arrowheadPoints === null) {
12608
+ return [];
12609
+ }
12610
+ const [x2, y2, x3, y3, x4, y4] = arrowheadPoints;
12611
+ return [
12612
+ generator.line(x3, y3, x2, y2, lineOptions),
12613
+ generator.line(x4, y4, x2, y2, lineOptions)
12614
+ ];
12615
+ };
12616
+ var getArrowheadLineOptions = (element, options) => {
12617
+ const lineOptions = { ...options };
12618
+ if (element.strokeStyle === "dotted") {
12619
+ const dash = getDashArrayDotted(element.strokeWidth - 1);
12620
+ lineOptions.strokeLineDash = [dash[0], dash[1] - 1];
12621
+ } else {
12622
+ delete lineOptions.strokeLineDash;
12623
+ }
12624
+ lineOptions.roughness = Math.min(1, lineOptions.roughness || 0);
12625
+ return lineOptions;
12626
+ };
12627
+ var generateArrowheadOutlineCircle = (generator, options, strokeColor, arrowheadPoints, fill, diameterScale = 1) => {
12628
+ if (arrowheadPoints === null) {
12629
+ return [];
12630
+ }
12631
+ const [x, y, diameter] = arrowheadPoints;
12632
+ const circleOptions = {
12633
+ ...options,
12634
+ fill,
12635
+ fillStyle: "solid",
12636
+ stroke: strokeColor,
12637
+ roughness: Math.min(0.5, options.roughness || 0)
12430
12638
  };
12639
+ delete circleOptions.strokeLineDash;
12640
+ return [generator.circle(x, y, diameter * diameterScale, circleOptions)];
12641
+ };
12642
+ var getArrowheadShapes = (element, shape, position, arrowhead, generator, options, canvasBackgroundColor, isDarkMode) => {
12643
+ canvasBackgroundColor = canvasBackgroundColor || "transparent";
12644
+ if (arrowhead === null) {
12645
+ return [];
12646
+ }
12431
12647
  const strokeColor = isDarkMode ? applyDarkModeFilter(element.strokeColor) : element.strokeColor;
12648
+ const backgroundFillColor = isDarkMode ? applyDarkModeFilter(canvasBackgroundColor) : canvasBackgroundColor;
12649
+ const cardinalityOneOrManyOffset = -0.25;
12650
+ const cardinalityZeroCircleScale = 0.8;
12432
12651
  switch (arrowhead) {
12433
- case "dot":
12434
12652
  case "circle":
12435
12653
  case "circle_outline": {
12436
- const [x, y, diameter] = arrowheadPoints;
12437
- delete options.strokeLineDash;
12438
- return [
12439
- generator.circle(x, y, diameter, {
12440
- ...options,
12441
- fill: arrowhead === "circle_outline" ? canvasBackgroundColor : strokeColor,
12442
- fillStyle: "solid",
12443
- stroke: strokeColor,
12444
- roughness: Math.min(0.5, options.roughness || 0)
12445
- })
12446
- ];
12654
+ return generateArrowheadOutlineCircle(
12655
+ generator,
12656
+ options,
12657
+ strokeColor,
12658
+ getArrowheadPoints(element, shape, position, arrowhead),
12659
+ arrowhead === "circle_outline" ? backgroundFillColor : strokeColor
12660
+ );
12447
12661
  }
12448
12662
  case "triangle":
12449
12663
  case "triangle_outline": {
12664
+ const arrowheadPoints = getArrowheadPoints(
12665
+ element,
12666
+ shape,
12667
+ position,
12668
+ arrowhead
12669
+ );
12670
+ if (arrowheadPoints === null) {
12671
+ return [];
12672
+ }
12450
12673
  const [x, y, x2, y2, x3, y3] = arrowheadPoints;
12451
- delete options.strokeLineDash;
12674
+ const triangleOptions = {
12675
+ ...options,
12676
+ fill: arrowhead === "triangle_outline" ? backgroundFillColor : strokeColor,
12677
+ fillStyle: "solid",
12678
+ roughness: Math.min(1, options.roughness || 0)
12679
+ };
12680
+ delete triangleOptions.strokeLineDash;
12452
12681
  return [
12453
12682
  generator.polygon(
12454
12683
  [
@@ -12457,19 +12686,29 @@ var getArrowheadShapes = (element, shape, position, arrowhead, generator, option
12457
12686
  [x3, y3],
12458
12687
  [x, y]
12459
12688
  ],
12460
- {
12461
- ...options,
12462
- fill: arrowhead === "triangle_outline" ? canvasBackgroundColor : strokeColor,
12463
- fillStyle: "solid",
12464
- roughness: Math.min(1, options.roughness || 0)
12465
- }
12689
+ triangleOptions
12466
12690
  )
12467
12691
  ];
12468
12692
  }
12469
12693
  case "diamond":
12470
12694
  case "diamond_outline": {
12695
+ const arrowheadPoints = getArrowheadPoints(
12696
+ element,
12697
+ shape,
12698
+ position,
12699
+ arrowhead
12700
+ );
12701
+ if (arrowheadPoints === null) {
12702
+ return [];
12703
+ }
12471
12704
  const [x, y, x2, y2, x3, y3, x4, y4] = arrowheadPoints;
12472
- delete options.strokeLineDash;
12705
+ const diamondOptions = {
12706
+ ...options,
12707
+ fill: arrowhead === "diamond_outline" ? backgroundFillColor : strokeColor,
12708
+ fillStyle: "solid",
12709
+ roughness: Math.min(1, options.roughness || 0)
12710
+ };
12711
+ delete diamondOptions.strokeLineDash;
12473
12712
  return [
12474
12713
  generator.polygon(
12475
12714
  [
@@ -12479,42 +12718,106 @@ var getArrowheadShapes = (element, shape, position, arrowhead, generator, option
12479
12718
  [x4, y4],
12480
12719
  [x, y]
12481
12720
  ],
12482
- {
12483
- ...options,
12484
- fill: arrowhead === "diamond_outline" ? canvasBackgroundColor : strokeColor,
12485
- fillStyle: "solid",
12486
- roughness: Math.min(1, options.roughness || 0)
12487
- }
12721
+ diamondOptions
12722
+ )
12723
+ ];
12724
+ }
12725
+ case "cardinality_one":
12726
+ return generateArrowheadCardinalityOne(
12727
+ generator,
12728
+ getArrowheadPoints(element, shape, position, arrowhead),
12729
+ getArrowheadLineOptions(element, options)
12730
+ );
12731
+ case "cardinality_many":
12732
+ return generateArrowheadLinesToTip(
12733
+ generator,
12734
+ getArrowheadPoints(element, shape, position, arrowhead),
12735
+ getArrowheadLineOptions(element, options)
12736
+ );
12737
+ case "cardinality_one_or_many": {
12738
+ const lineOptions = getArrowheadLineOptions(element, options);
12739
+ return [
12740
+ ...generateArrowheadLinesToTip(
12741
+ generator,
12742
+ getArrowheadPoints(element, shape, position, "cardinality_many"),
12743
+ lineOptions
12744
+ ),
12745
+ ...generateArrowheadCardinalityOne(
12746
+ generator,
12747
+ getArrowheadPoints(
12748
+ element,
12749
+ shape,
12750
+ position,
12751
+ "cardinality_one",
12752
+ cardinalityOneOrManyOffset
12753
+ ),
12754
+ lineOptions
12755
+ )
12756
+ ];
12757
+ }
12758
+ case "cardinality_exactly_one": {
12759
+ const lineOptions = getArrowheadLineOptions(element, options);
12760
+ return [
12761
+ ...generateArrowheadCardinalityOne(
12762
+ generator,
12763
+ getArrowheadPoints(element, shape, position, "cardinality_one", -0.5),
12764
+ lineOptions
12765
+ ),
12766
+ ...generateArrowheadCardinalityOne(
12767
+ generator,
12768
+ getArrowheadPoints(element, shape, position, "cardinality_one"),
12769
+ lineOptions
12770
+ )
12771
+ ];
12772
+ }
12773
+ case "cardinality_zero_or_one": {
12774
+ const lineOptions = getArrowheadLineOptions(element, options);
12775
+ return [
12776
+ ...generateArrowheadOutlineCircle(
12777
+ generator,
12778
+ options,
12779
+ strokeColor,
12780
+ getArrowheadPoints(element, shape, position, "circle_outline", 1.5),
12781
+ backgroundFillColor,
12782
+ cardinalityZeroCircleScale
12783
+ ),
12784
+ ...generateArrowheadCardinalityOne(
12785
+ generator,
12786
+ getArrowheadPoints(element, shape, position, "cardinality_one", -0.5),
12787
+ lineOptions
12788
+ )
12789
+ ];
12790
+ }
12791
+ case "cardinality_zero_or_many": {
12792
+ const lineOptions = getArrowheadLineOptions(element, options);
12793
+ return [
12794
+ ...generateArrowheadLinesToTip(
12795
+ generator,
12796
+ getArrowheadPoints(element, shape, position, "cardinality_many"),
12797
+ lineOptions
12798
+ ),
12799
+ ...generateArrowheadOutlineCircle(
12800
+ generator,
12801
+ options,
12802
+ strokeColor,
12803
+ getArrowheadPoints(element, shape, position, "circle_outline", 1.5),
12804
+ backgroundFillColor,
12805
+ cardinalityZeroCircleScale
12488
12806
  )
12489
12807
  ];
12490
12808
  }
12491
- case "crowfoot_one":
12492
- return generateCrowfootOne(arrowheadPoints, options);
12493
12809
  case "bar":
12494
12810
  case "arrow":
12495
- case "crowfoot_many":
12496
- case "crowfoot_one_or_many":
12497
12811
  default: {
12498
- const [x2, y2, x3, y3, x4, y4] = arrowheadPoints;
12499
- if (element.strokeStyle === "dotted") {
12500
- const dash = getDashArrayDotted(element.strokeWidth - 1);
12501
- options.strokeLineDash = [dash[0], dash[1] - 1];
12502
- } else {
12503
- delete options.strokeLineDash;
12504
- }
12505
- options.roughness = Math.min(1, options.roughness || 0);
12506
- return [
12507
- generator.line(x3, y3, x2, y2, options),
12508
- generator.line(x4, y4, x2, y2, options),
12509
- ...arrowhead === "crowfoot_one_or_many" ? generateCrowfootOne(
12510
- getArrowheadPoints(element, shape, position, "crowfoot_one"),
12511
- options
12512
- ) : []
12513
- ];
12812
+ return generateArrowheadLinesToTip(
12813
+ generator,
12814
+ getArrowheadPoints(element, shape, position, arrowhead),
12815
+ getArrowheadLineOptions(element, options)
12816
+ );
12514
12817
  }
12515
12818
  }
12516
12819
  };
12517
- var generateLinearCollisionShape = (element) => {
12820
+ var generateLinearCollisionShape = (element, elementsMap) => {
12518
12821
  const generator = new RoughGenerator();
12519
12822
  const options = {
12520
12823
  seed: element.seed,
@@ -12523,20 +12826,7 @@ var generateLinearCollisionShape = (element) => {
12523
12826
  roughness: 0,
12524
12827
  preserveVertices: true
12525
12828
  };
12526
- const center = getCenterForBounds(
12527
- // Need a non-rotated center point
12528
- element.points.reduce(
12529
- (acc, point) => {
12530
- return [
12531
- Math.min(element.x + point[0], acc[0]),
12532
- Math.min(element.y + point[1], acc[1]),
12533
- Math.max(element.x + point[0], acc[2]),
12534
- Math.max(element.y + point[1], acc[3])
12535
- ];
12536
- },
12537
- [Infinity, Infinity, -Infinity, -Infinity]
12538
- )
12539
- );
12829
+ const center = elementCenterPoint(element, elementsMap);
12540
12830
  switch (element.type) {
12541
12831
  case "line":
12542
12832
  case "arrow": {
@@ -13418,7 +13708,7 @@ var getMinMaxXYFromCurvePathOps = (ops, transformXY) => {
13418
13708
  );
13419
13709
  return [minX, minY, maxX, maxY];
13420
13710
  };
13421
- var getBoundsFromPoints = (points) => {
13711
+ var getBoundsFromPoints = (points, padding = 0) => {
13422
13712
  let minX = Infinity;
13423
13713
  let minY = Infinity;
13424
13714
  let maxX = -Infinity;
@@ -13429,7 +13719,7 @@ var getBoundsFromPoints = (points) => {
13429
13719
  maxX = Math.max(maxX, x);
13430
13720
  maxY = Math.max(maxY, y);
13431
13721
  }
13432
- return [minX, minY, maxX, maxY];
13722
+ return [minX - padding, minY - padding, maxX + padding, maxY + padding];
13433
13723
  };
13434
13724
  var getFreeDrawElementAbsoluteCoords = (element) => {
13435
13725
  const [minX, minY, maxX, maxY] = getBoundsFromPoints(element.points);
@@ -13439,6 +13729,8 @@ var getFreeDrawElementAbsoluteCoords = (element) => {
13439
13729
  const y2 = maxY + element.y;
13440
13730
  return [x1, y1, x2, y2, (x1 + x2) / 2, (y1 + y2) / 2];
13441
13731
  };
13732
+ var CARDINALITY_MARKER_SIZE = 20;
13733
+ var CROWFOOT_ARROWHEAD_SIZE = 15;
13442
13734
  var getArrowheadSize = (arrowhead) => {
13443
13735
  switch (arrowhead) {
13444
13736
  case "arrow":
@@ -13446,10 +13738,14 @@ var getArrowheadSize = (arrowhead) => {
13446
13738
  case "diamond":
13447
13739
  case "diamond_outline":
13448
13740
  return 12;
13449
- case "crowfoot_many":
13450
- case "crowfoot_one":
13451
- case "crowfoot_one_or_many":
13452
- return 20;
13741
+ case "cardinality_many":
13742
+ case "cardinality_one_or_many":
13743
+ case "cardinality_zero_or_many":
13744
+ return CROWFOOT_ARROWHEAD_SIZE;
13745
+ case "cardinality_one":
13746
+ case "cardinality_exactly_one":
13747
+ case "cardinality_zero_or_one":
13748
+ return CARDINALITY_MARKER_SIZE;
13453
13749
  default:
13454
13750
  return 15;
13455
13751
  }
@@ -13464,7 +13760,10 @@ var getArrowheadAngle = (arrowhead) => {
13464
13760
  return 25;
13465
13761
  }
13466
13762
  };
13467
- var getArrowheadPoints = (element, shape, position, arrowhead) => {
13763
+ var getArrowheadPoints = (element, shape, position, arrowhead, offsetMultiplier = 0) => {
13764
+ if (arrowhead === null) {
13765
+ return null;
13766
+ }
13468
13767
  if (shape.length < 1) {
13469
13768
  return null;
13470
13769
  }
@@ -13502,21 +13801,23 @@ var getArrowheadPoints = (element, shape, position, arrowhead) => {
13502
13801
  }
13503
13802
  const lengthMultiplier = arrowhead === "diamond" || arrowhead === "diamond_outline" ? 0.25 : 0.5;
13504
13803
  const minSize = Math.min(size, length * lengthMultiplier);
13505
- const xs = x2 - nx * minSize;
13506
- const ys = y2 - ny * minSize;
13507
- if (arrowhead === "dot" || arrowhead === "circle" || arrowhead === "circle_outline") {
13508
- const diameter = Math.hypot(ys - y2, xs - x2) + element.strokeWidth - 2;
13509
- return [x2, y2, diameter];
13804
+ const tx = x2 - nx * minSize * offsetMultiplier;
13805
+ const ty = y2 - ny * minSize * offsetMultiplier;
13806
+ const xs = tx - nx * minSize;
13807
+ const ys = ty - ny * minSize;
13808
+ if (arrowhead === "circle" || arrowhead === "circle_outline") {
13809
+ const diameter = Math.hypot(ys - ty, xs - tx) + element.strokeWidth - 2;
13810
+ return [tx, ty, diameter];
13510
13811
  }
13511
13812
  const angle = getArrowheadAngle(arrowhead);
13512
- if (arrowhead === "crowfoot_many" || arrowhead === "crowfoot_one_or_many") {
13813
+ if (arrowhead === "cardinality_many" || arrowhead === "cardinality_one_or_many") {
13513
13814
  const [x32, y32] = pointRotateRads(
13514
- pointFrom(x2, y2),
13815
+ pointFrom(tx, ty),
13515
13816
  pointFrom(xs, ys),
13516
13817
  degreesToRadians(-angle)
13517
13818
  );
13518
13819
  const [x42, y42] = pointRotateRads(
13519
- pointFrom(x2, y2),
13820
+ pointFrom(tx, ty),
13520
13821
  pointFrom(xs, ys),
13521
13822
  degreesToRadians(angle)
13522
13823
  );
@@ -13524,12 +13825,12 @@ var getArrowheadPoints = (element, shape, position, arrowhead) => {
13524
13825
  }
13525
13826
  const [x3, y3] = pointRotateRads(
13526
13827
  pointFrom(xs, ys),
13527
- pointFrom(x2, y2),
13828
+ pointFrom(tx, ty),
13528
13829
  -angle * Math.PI / 180
13529
13830
  );
13530
13831
  const [x4, y4] = pointRotateRads(
13531
13832
  pointFrom(xs, ys),
13532
- pointFrom(x2, y2),
13833
+ pointFrom(tx, ty),
13533
13834
  degreesToRadians(angle)
13534
13835
  );
13535
13836
  if (arrowhead === "diamond" || arrowhead === "diamond_outline") {
@@ -13538,21 +13839,21 @@ var getArrowheadPoints = (element, shape, position, arrowhead) => {
13538
13839
  if (position === "start") {
13539
13840
  const [px, py] = element.points.length > 1 ? element.points[1] : [0, 0];
13540
13841
  [ox, oy] = pointRotateRads(
13541
- pointFrom(x2 + minSize * 2, y2),
13542
- pointFrom(x2, y2),
13543
- Math.atan2(py - y2, px - x2)
13842
+ pointFrom(tx + minSize * 2, ty),
13843
+ pointFrom(tx, ty),
13844
+ Math.atan2(py - ty, px - tx)
13544
13845
  );
13545
13846
  } else {
13546
13847
  const [px, py] = element.points.length > 1 ? element.points[element.points.length - 2] : [0, 0];
13547
13848
  [ox, oy] = pointRotateRads(
13548
- pointFrom(x2 - minSize * 2, y2),
13549
- pointFrom(x2, y2),
13550
- Math.atan2(y2 - py, x2 - px)
13849
+ pointFrom(tx - minSize * 2, ty),
13850
+ pointFrom(tx, ty),
13851
+ Math.atan2(ty - py, tx - px)
13551
13852
  );
13552
13853
  }
13553
- return [x2, y2, x3, y3, ox, oy, x4, y4];
13854
+ return [tx, ty, x3, y3, ox, oy, x4, y4];
13554
13855
  }
13555
- return [x2, y2, x3, y3, x4, y4];
13856
+ return [tx, ty, x3, y3, x4, y4];
13556
13857
  };
13557
13858
  var generateLinearElementShape = (element) => {
13558
13859
  const generator = rough2.generator();
@@ -13802,6 +14103,7 @@ var aabbForElement = (element, elementsMap, offset) => {
13802
14103
  return bounds;
13803
14104
  };
13804
14105
  var pointInsideBounds = (p, bounds) => p[0] > bounds[0] && p[0] < bounds[2] && p[1] > bounds[1] && p[1] < bounds[3];
14106
+ var pointInsideBoundsInclusive = (p, bounds) => p[0] >= bounds[0] && p[0] <= bounds[2] && p[1] >= bounds[1] && p[1] <= bounds[3];
13805
14107
  var doBoundsIntersect = (bounds1, bounds2) => {
13806
14108
  if (bounds1 == null || bounds2 == null) {
13807
14109
  return false;
@@ -13810,8 +14112,14 @@ var doBoundsIntersect = (bounds1, bounds2) => {
13810
14112
  const [minX2, minY2, maxX2, maxY2] = bounds2;
13811
14113
  return minX1 < maxX2 && maxX1 > minX2 && minY1 < maxY2 && maxY1 > minY2;
13812
14114
  };
14115
+ var boundsContainBounds = (outerBounds, innerBounds) => [
14116
+ pointFrom(innerBounds[0], innerBounds[1]),
14117
+ pointFrom(innerBounds[0], innerBounds[3]),
14118
+ pointFrom(innerBounds[2], innerBounds[1]),
14119
+ pointFrom(innerBounds[2], innerBounds[3])
14120
+ ].every((point) => pointInsideBoundsInclusive(point, outerBounds));
13813
14121
  var elementCenterPoint = (element, elementsMap, xOffset = 0, yOffset = 0) => {
13814
- if (isLinearElement(element)) {
14122
+ if (isLinearElement(element) || isFreeDrawElement(element)) {
13815
14123
  const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
13816
14124
  const [x3, y3] = pointFrom((x1 + x2) / 2, (y1 + y2) / 2);
13817
14125
  return pointFrom(x3 + xOffset, y3 + yOffset);
@@ -21071,6 +21379,32 @@ var maybeHandleArrowPointlikeDrag = ({
21071
21379
  return false;
21072
21380
  };
21073
21381
 
21382
+ // ../element/src/arrowheads.ts
21383
+ var normalizeArrowhead = (arrowhead) => {
21384
+ switch (arrowhead) {
21385
+ case void 0:
21386
+ case null:
21387
+ return null;
21388
+ case "dot":
21389
+ return "circle";
21390
+ case "crowfoot_one":
21391
+ return "cardinality_one";
21392
+ case "crowfoot_many":
21393
+ return "cardinality_many";
21394
+ case "crowfoot_one_or_many":
21395
+ return "cardinality_one_or_many";
21396
+ default:
21397
+ return arrowhead;
21398
+ }
21399
+ };
21400
+ var getArrowheadForPicker = (arrowhead) => {
21401
+ const normalizedArrowhead = normalizeArrowhead(arrowhead);
21402
+ if (normalizedArrowhead === null) {
21403
+ return null;
21404
+ }
21405
+ return normalizedArrowhead;
21406
+ };
21407
+
21074
21408
  // ../element/src/index.ts
21075
21409
  var getSceneVersion = (elements) => elements.reduce((acc, el) => acc + el.version, 0);
21076
21410
  var hashElementsVersion = (elements) => {
@@ -24942,7 +25276,8 @@ var restoreElement = (element, targetElementsMap, existingElementsMap, opts) =>
24942
25276
  });
24943
25277
  case "line":
24944
25278
  case "draw":
24945
- const { startArrowhead = null, endArrowhead = null } = element;
25279
+ const startArrowhead = normalizeArrowhead(element.startArrowhead);
25280
+ const endArrowhead = normalizeArrowhead(element.endArrowhead);
24946
25281
  let x = element.x;
24947
25282
  let y = element.y;
24948
25283
  let points = (
@@ -24967,7 +25302,8 @@ var restoreElement = (element, targetElementsMap, existingElementsMap, opts) =>
24967
25302
  ...getSizeFromPoints(points)
24968
25303
  });
24969
25304
  case "arrow": {
24970
- const { startArrowhead: startArrowhead2 = null, endArrowhead: endArrowhead2 = "arrow" } = element;
25305
+ const startArrowhead2 = normalizeArrowhead(element.startArrowhead);
25306
+ const endArrowhead2 = element.endArrowhead === void 0 ? "arrow" : normalizeArrowhead(element.endArrowhead);
24971
25307
  const x2 = element.x;
24972
25308
  const y2 = element.y;
24973
25309
  const points2 = (
@@ -25235,6 +25571,10 @@ var restoreAppState = (appState, localAppState) => {
25235
25571
  const localValue = localAppState ? localAppState[key] : void 0;
25236
25572
  nextAppState[key] = suppliedValue !== void 0 ? suppliedValue : localValue !== void 0 ? localValue : defaultValue;
25237
25573
  }
25574
+ const boxSelectionMode = appState.boxSelectionMode ?? localAppState?.boxSelectionMode;
25575
+ if (boxSelectionMode !== void 0) {
25576
+ nextAppState.boxSelectionMode = boxSelectionMode;
25577
+ }
25238
25578
  return {
25239
25579
  ...nextAppState,
25240
25580
  cursorButton: localAppState?.cursorButton || "up",
@@ -25365,7 +25705,11 @@ var prepareElementsForRender = ({
25365
25705
  }) => {
25366
25706
  let nextElements;
25367
25707
  if (exportingFrame) {
25368
- nextElements = getElementsOverlappingFrame(elements, exportingFrame);
25708
+ nextElements = getElementsOverlappingFrame(
25709
+ elements,
25710
+ exportingFrame,
25711
+ arrayToMap(elements)
25712
+ );
25369
25713
  } else if (frameRendering.enabled && frameRendering.name) {
25370
25714
  nextElements = addFrameLabelsAsTextElements(elements, {
25371
25715
  exportWithDarkMode
@@ -25764,7 +26108,7 @@ var parseFileContents = async (blob) => {
25764
26108
  let contents;
25765
26109
  if (blob.type === MIME_TYPES.png) {
25766
26110
  try {
25767
- return await (await import("./data/image-WOLPNANH.js")).decodePngMetadata(blob);
26111
+ return await (await import("./data/image-LJOI7ED6.js")).decodePngMetadata(blob);
25768
26112
  } catch (error) {
25769
26113
  if (error.message === "INVALID") {
25770
26114
  throw new ImageSceneDataError(
@@ -26153,6 +26497,7 @@ export {
26153
26497
  rangeInclusive,
26154
26498
  rangesOverlap,
26155
26499
  rangeIntersection,
26500
+ rangeIncludesValue,
26156
26501
  supportsResizeObserver,
26157
26502
  APP_NAME,
26158
26503
  DRAGGING_THRESHOLD,
@@ -26287,6 +26632,7 @@ export {
26287
26632
  viewportCoordsToSceneCoords,
26288
26633
  sceneCoordsToViewportCoords,
26289
26634
  getGlobalCSSVariable,
26635
+ isRTL,
26290
26636
  tupleToCoors,
26291
26637
  muteFSAbortError,
26292
26638
  findLastIndex,
@@ -26379,8 +26725,10 @@ export {
26379
26725
  getLineHeightInPx,
26380
26726
  getApproxMinLineHeight,
26381
26727
  setCustomTextMetricsProvider,
26728
+ getLineWidth,
26382
26729
  getTextWidth,
26383
26730
  wrapText,
26731
+ getWrappedTextLines,
26384
26732
  redrawTextBoundingBox,
26385
26733
  handleBindTextResize,
26386
26734
  computeBoundTextPosition,
@@ -26422,9 +26770,6 @@ export {
26422
26770
  fixBindingsAfterDeletion,
26423
26771
  getGlobalFixedPointForBindableElement,
26424
26772
  LinearElementEditor,
26425
- isElementInsideBBox,
26426
- elementPartiallyOverlapsWithOrContainsBBox,
26427
- elementsOverlappingBBox,
26428
26773
  selectGroup,
26429
26774
  selectGroupsForSelectedElements,
26430
26775
  isSelectedViaGroup,
@@ -26448,6 +26793,7 @@ export {
26448
26793
  getTargetElements,
26449
26794
  makeNextSelectedElementIds,
26450
26795
  getSelectionStateForElements,
26796
+ getActiveTextElement,
26451
26797
  elementOverlapsWithFrame,
26452
26798
  isCursorInFrame,
26453
26799
  groupByFrameLikes,
@@ -26569,6 +26915,7 @@ export {
26569
26915
  showSelectedShapeActions,
26570
26916
  convertToExcalidrawElements,
26571
26917
  maybeHandleArrowPointlikeDrag,
26918
+ getArrowheadForPicker,
26572
26919
  getSceneVersion,
26573
26920
  hashElementsVersion,
26574
26921
  hashString,
@@ -26637,4 +26984,4 @@ export {
26637
26984
  createFile,
26638
26985
  normalizeFile
26639
26986
  };
26640
- //# sourceMappingURL=chunk-QYOG4VCN.js.map
26987
+ //# sourceMappingURL=chunk-FOPF4A62.js.map