@excalidraw/common 0.18.0-b9d27d3 → 0.18.0-c141960

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 (102) hide show
  1. package/dist/dev/index.js +321 -50
  2. package/dist/dev/index.js.map +3 -3
  3. package/dist/prod/index.js +3 -3
  4. package/dist/types/common/src/constants.d.ts +9 -13
  5. package/dist/types/common/src/editorInterface.d.ts +34 -0
  6. package/dist/types/common/src/index.d.ts +2 -0
  7. package/dist/types/common/src/utils.d.ts +9 -3
  8. package/dist/types/common/src/visualdebug.d.ts +41 -0
  9. package/dist/types/element/src/binding.d.ts +55 -43
  10. package/dist/types/element/src/collision.d.ts +6 -2
  11. package/dist/types/element/src/index.d.ts +0 -3
  12. package/dist/types/element/src/linearElementEditor.d.ts +15 -18
  13. package/dist/types/element/src/renderElement.d.ts +5 -2
  14. package/dist/types/element/src/resizeTest.d.ts +5 -4
  15. package/dist/types/element/src/transformHandles.d.ts +5 -4
  16. package/dist/types/element/src/typeChecks.d.ts +2 -3
  17. package/dist/types/element/src/types.d.ts +7 -11
  18. package/dist/types/element/src/utils.d.ts +2 -1
  19. package/dist/types/element/src/zindex.d.ts +7 -1
  20. package/dist/types/excalidraw/actions/actionAddToLibrary.d.ts +34 -13
  21. package/dist/types/excalidraw/actions/actionAlign.d.ts +6 -6
  22. package/dist/types/excalidraw/actions/actionBoundText.d.ts +25 -11
  23. package/dist/types/excalidraw/actions/actionCanvas.d.ts +152 -275
  24. package/dist/types/excalidraw/actions/actionClipboard.d.ts +46 -773
  25. package/dist/types/excalidraw/actions/actionCropEditor.d.ts +12 -5
  26. package/dist/types/excalidraw/actions/actionDeleteSelected.d.ts +42 -23
  27. package/dist/types/excalidraw/actions/actionDistribute.d.ts +2 -2
  28. package/dist/types/excalidraw/actions/actionDuplicateSelection.d.ts +2 -2
  29. package/dist/types/excalidraw/actions/actionElementLink.d.ts +11 -6
  30. package/dist/types/excalidraw/actions/actionElementLock.d.ts +23 -9
  31. package/dist/types/excalidraw/actions/actionEmbeddable.d.ts +12 -5
  32. package/dist/types/excalidraw/actions/actionExport.d.ts +68 -943
  33. package/dist/types/excalidraw/actions/actionFinalize.d.ts +10 -393
  34. package/dist/types/excalidraw/actions/actionFlip.d.ts +2 -2
  35. package/dist/types/excalidraw/actions/actionFrame.d.ts +50 -24
  36. package/dist/types/excalidraw/actions/actionGroup.d.ts +24 -10
  37. package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +22 -19
  38. package/dist/types/excalidraw/actions/actionLink.d.ts +9 -2
  39. package/dist/types/excalidraw/actions/actionMenu.d.ts +10 -371
  40. package/dist/types/excalidraw/actions/actionNavigate.d.ts +21 -359
  41. package/dist/types/excalidraw/actions/actionProperties.d.ts +87 -2403
  42. package/dist/types/excalidraw/actions/actionSelectAll.d.ts +12 -5
  43. package/dist/types/excalidraw/actions/actionStyles.d.ts +13 -6
  44. package/dist/types/excalidraw/actions/actionTextAutoResize.d.ts +1 -1
  45. package/dist/types/excalidraw/actions/actionToggleGridMode.d.ts +11 -4
  46. package/dist/types/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +11 -4
  47. package/dist/types/excalidraw/actions/actionToggleSearchMenu.d.ts +10 -5
  48. package/dist/types/excalidraw/actions/actionToggleShapeSwitch.d.ts +1 -1
  49. package/dist/types/excalidraw/actions/actionToggleStats.d.ts +11 -4
  50. package/dist/types/excalidraw/actions/actionToggleViewMode.d.ts +11 -4
  51. package/dist/types/excalidraw/actions/actionToggleZenMode.d.ts +12 -5
  52. package/dist/types/excalidraw/actions/actionZindex.d.ts +2 -2
  53. package/dist/types/excalidraw/actions/index.d.ts +2 -2
  54. package/dist/types/excalidraw/actions/manager.d.ts +1 -1
  55. package/dist/types/excalidraw/actions/register.d.ts +1 -1
  56. package/dist/types/excalidraw/actions/types.d.ts +4 -4
  57. package/dist/types/excalidraw/appState.d.ts +9 -4
  58. package/dist/types/excalidraw/clipboard.d.ts +2 -0
  59. package/dist/types/excalidraw/components/Actions.d.ts +21 -4
  60. package/dist/types/excalidraw/components/App.d.ts +26 -19
  61. package/dist/types/excalidraw/components/ColorPicker/Picker.d.ts +2 -0
  62. package/dist/types/excalidraw/components/ColorPicker/PickerColorList.d.ts +2 -1
  63. package/dist/types/excalidraw/components/ColorPicker/ShadeList.d.ts +2 -1
  64. package/dist/types/excalidraw/components/CommandPalette/CommandPalette.d.ts +1 -0
  65. package/dist/types/excalidraw/components/CommandPalette/types.d.ts +1 -2
  66. package/dist/types/excalidraw/components/ExcalidrawLogo.d.ts +1 -1
  67. package/dist/types/excalidraw/components/FilledButton.d.ts +1 -1
  68. package/dist/types/excalidraw/components/FontPicker/FontPicker.d.ts +2 -1
  69. package/dist/types/excalidraw/components/FontPicker/FontPickerTrigger.d.ts +3 -1
  70. package/dist/types/excalidraw/components/HintViewer.d.ts +4 -3
  71. package/dist/types/excalidraw/components/InlineIcon.d.ts +3 -1
  72. package/dist/types/excalidraw/components/LayerUI.d.ts +2 -1
  73. package/dist/types/excalidraw/components/LibraryMenuSection.d.ts +1 -1
  74. package/dist/types/excalidraw/components/MobileMenu.d.ts +3 -5
  75. package/dist/types/excalidraw/components/MobileToolBar.d.ts +11 -0
  76. package/dist/types/excalidraw/components/Popover.d.ts +2 -1
  77. package/dist/types/excalidraw/components/PropertiesPopover.d.ts +1 -0
  78. package/dist/types/excalidraw/components/Stats/utils.d.ts +1 -1
  79. package/dist/types/excalidraw/components/TTDDialog/TTDDialogTrigger.d.ts +1 -2
  80. package/dist/types/excalidraw/components/TextField.d.ts +1 -0
  81. package/dist/types/excalidraw/components/ToolPopover.d.ts +25 -0
  82. package/dist/types/excalidraw/components/canvases/InteractiveCanvas.d.ts +6 -3
  83. package/dist/types/excalidraw/components/dropdownMenu/DropdownMenu.d.ts +4 -2
  84. package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuContent.d.ts +2 -1
  85. package/dist/types/excalidraw/components/icons.d.ts +10 -0
  86. package/dist/types/excalidraw/components/live-collaboration/LiveCollaborationTrigger.d.ts +13 -1
  87. package/dist/types/excalidraw/components/main-menu/MainMenu.d.ts +0 -3
  88. package/dist/types/excalidraw/data/blob.d.ts +2 -2
  89. package/dist/types/excalidraw/data/restore.d.ts +3 -3
  90. package/dist/types/excalidraw/data/types.d.ts +4 -1
  91. package/dist/types/excalidraw/hooks/useLibraryItemSvg.d.ts +1 -1
  92. package/dist/types/excalidraw/hooks/useOutsideClick.d.ts +3 -1
  93. package/dist/types/excalidraw/hooks/useTextEditorFocus.d.ts +14 -0
  94. package/dist/types/excalidraw/index.d.ts +2 -3
  95. package/dist/types/excalidraw/renderer/animation.d.ts +12 -0
  96. package/dist/types/excalidraw/renderer/helpers.d.ts +2 -6
  97. package/dist/types/excalidraw/renderer/interactiveScene.d.ts +5 -13
  98. package/dist/types/excalidraw/scene/types.d.ts +15 -3
  99. package/dist/types/excalidraw/shortcut.d.ts +1 -0
  100. package/dist/types/excalidraw/types.d.ts +31 -21
  101. package/dist/types/math/src/segment.d.ts +1 -0
  102. package/package.json +1 -1
package/dist/dev/index.js CHANGED
@@ -281,49 +281,48 @@ var BinaryHeap = class {
281
281
  content = [];
282
282
  sinkDown(idx) {
283
283
  const node = this.content[idx];
284
+ const nodeScore = this.scoreFunction(node);
284
285
  while (idx > 0) {
285
286
  const parentN = (idx + 1 >> 1) - 1;
286
287
  const parent = this.content[parentN];
287
- if (this.scoreFunction(node) < this.scoreFunction(parent)) {
288
- this.content[parentN] = node;
288
+ if (nodeScore < this.scoreFunction(parent)) {
289
289
  this.content[idx] = parent;
290
290
  idx = parentN;
291
291
  } else {
292
292
  break;
293
293
  }
294
294
  }
295
+ this.content[idx] = node;
295
296
  }
296
297
  bubbleUp(idx) {
297
298
  const length = this.content.length;
298
299
  const node = this.content[idx];
299
300
  const score = this.scoreFunction(node);
300
301
  while (true) {
301
- const child2N = idx + 1 << 1;
302
- const child1N = child2N - 1;
303
- let swap = null;
304
- let child1Score = 0;
302
+ const child1N = (idx + 1 << 1) - 1;
303
+ const child2N = child1N + 1;
304
+ let smallestIdx = idx;
305
+ let smallestScore = score;
305
306
  if (child1N < length) {
306
- const child1 = this.content[child1N];
307
- child1Score = this.scoreFunction(child1);
308
- if (child1Score < score) {
309
- swap = child1N;
307
+ const child1Score = this.scoreFunction(this.content[child1N]);
308
+ if (child1Score < smallestScore) {
309
+ smallestIdx = child1N;
310
+ smallestScore = child1Score;
310
311
  }
311
312
  }
312
313
  if (child2N < length) {
313
- const child2 = this.content[child2N];
314
- const child2Score = this.scoreFunction(child2);
315
- if (child2Score < (swap === null ? score : child1Score)) {
316
- swap = child2N;
314
+ const child2Score = this.scoreFunction(this.content[child2N]);
315
+ if (child2Score < smallestScore) {
316
+ smallestIdx = child2N;
317
317
  }
318
318
  }
319
- if (swap !== null) {
320
- this.content[idx] = this.content[swap];
321
- this.content[swap] = node;
322
- idx = swap;
323
- } else {
319
+ if (smallestIdx === idx) {
324
320
  break;
325
321
  }
322
+ this.content[idx] = this.content[smallestIdx];
323
+ idx = smallestIdx;
326
324
  }
325
+ this.content[idx] = node;
327
326
  }
328
327
  push(node) {
329
328
  this.content.push(node);
@@ -641,18 +640,6 @@ var rgbToHex = (r, g, b) => `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(
641
640
 
642
641
  // src/constants.ts
643
642
  init_define_import_meta_env();
644
- var isDarwin = /Mac|iPod|iPhone|iPad/.test(navigator.platform);
645
- var isWindows = /^Win/.test(navigator.platform);
646
- var isAndroid = /\b(android)\b/i.test(navigator.userAgent);
647
- var isFirefox = typeof window !== "undefined" && "netscape" in window && navigator.userAgent.indexOf("rv:") > 1 && navigator.userAgent.indexOf("Gecko") > 1;
648
- var isChrome = navigator.userAgent.indexOf("Chrome") !== -1;
649
- var isSafari = !isChrome && navigator.userAgent.indexOf("Safari") !== -1;
650
- var isIOS = /iPad|iPhone/i.test(navigator.platform) || // iPadOS 13+
651
- navigator.userAgent.includes("Mac") && "ontouchend" in document;
652
- var isBrave = () => navigator.brave?.isBrave?.name === "isBrave";
653
- var isMobile = isIOS || /android|webos|ipod|blackberry|iemobile|opera mini/i.test(
654
- navigator.userAgent
655
- ) || /android|ios|ipod|blackberry|windows phone/i.test(navigator.platform);
656
643
  var supportsResizeObserver = typeof window !== "undefined" && "ResizeObserver" in window;
657
644
  var APP_NAME = "Excalidraw";
658
645
  var TEXT_AUTOWRAP_THRESHOLD = 36;
@@ -734,10 +721,13 @@ var ENV = {
734
721
  PRODUCTION: "production"
735
722
  };
736
723
  var CLASSES = {
724
+ SIDEBAR: "sidebar",
737
725
  SHAPE_ACTIONS_MENU: "App-menu__left",
738
726
  ZOOM_ACTIONS: "zoom-actions",
739
727
  SEARCH_MENU_INPUT_WRAPPER: "layer-ui__search-inputWrapper",
740
- CONVERT_ELEMENT_TYPE_POPUP: "ConvertElementTypePopup"
728
+ CONVERT_ELEMENT_TYPE_POPUP: "ConvertElementTypePopup",
729
+ SHAPE_ACTIONS_THEME_SCOPE: "shape-actions-theme-scope",
730
+ FRAME_NAME: "frame-name"
741
731
  };
742
732
  var CJK_HAND_DRAWN_FALLBACK_FONT = "Xiaolai";
743
733
  var WINDOWS_EMOJI_FALLBACK_FONT = "Segoe UI Emoji";
@@ -838,7 +828,10 @@ var STRING_MIME_TYPES = {
838
828
  json: "application/json",
839
829
  // excalidraw data
840
830
  excalidraw: "application/vnd.excalidraw+json",
841
- excalidrawlib: "application/vnd.excalidrawlib+json"
831
+ // LEGACY: fully-qualified library JSON data
832
+ excalidrawlib: "application/vnd.excalidrawlib+json",
833
+ // list of excalidraw library item ids
834
+ excalidrawlibIds: "application/vnd.excalidrawlib.ids+json"
842
835
  };
843
836
  var MIME_TYPES = {
844
837
  ...STRING_MIME_TYPES,
@@ -900,10 +893,6 @@ var DEFAULT_UI_OPTIONS = {
900
893
  image: true
901
894
  }
902
895
  };
903
- var MQ_MAX_WIDTH_PORTRAIT = 730;
904
- var MQ_MAX_WIDTH_LANDSCAPE = 1e3;
905
- var MQ_MAX_HEIGHT_LANDSCAPE = 500;
906
- var MQ_RIGHT_SIDEBAR_MIN_WIDTH = 1229;
907
896
  var MAX_DECIMALS_FOR_SVG_EXPORT = 2;
908
897
  var EXPORT_SCALES = [1, 2, 3];
909
898
  var DEFAULT_EXPORT_PADDING = 10;
@@ -1024,6 +1013,10 @@ var UserIdleState = /* @__PURE__ */ ((UserIdleState2) => {
1024
1013
  })(UserIdleState || {});
1025
1014
  var LINE_POLYGON_POINT_MERGE_DISTANCE = 20;
1026
1015
  var DOUBLE_TAP_POSITION_THRESHOLD = 35;
1016
+ var BIND_MODE_TIMEOUT = 700;
1017
+ var MOBILE_ACTION_BUTTON_BG = {
1018
+ background: "var(--mobile-action-button-bg)"
1019
+ };
1027
1020
 
1028
1021
  // src/font-metadata.ts
1029
1022
  init_define_import_meta_env();
@@ -1179,6 +1172,133 @@ var Queue = class {
1179
1172
 
1180
1173
  // src/keys.ts
1181
1174
  init_define_import_meta_env();
1175
+
1176
+ // src/editorInterface.ts
1177
+ init_define_import_meta_env();
1178
+ var DESKTOP_UI_MODE_STORAGE_KEY = "excalidraw.desktopUIMode";
1179
+ var MQ_MAX_MOBILE = 599;
1180
+ var MQ_MAX_WIDTH_LANDSCAPE = 1e3;
1181
+ var MQ_MAX_HEIGHT_LANDSCAPE = 500;
1182
+ var MQ_MIN_TABLET = MQ_MAX_MOBILE + 1;
1183
+ var MQ_MAX_TABLET = 1400;
1184
+ var MQ_MIN_WIDTH_DESKTOP = 1440;
1185
+ var MQ_RIGHT_SIDEBAR_MIN_WIDTH = 1229;
1186
+ var isDarwin = /Mac|iPod|iPhone|iPad/.test(navigator.platform);
1187
+ var isWindows = /^Win/.test(navigator.platform);
1188
+ var isAndroid = /\b(android)\b/i.test(navigator.userAgent);
1189
+ var isFirefox = typeof window !== "undefined" && "netscape" in window && navigator.userAgent.indexOf("rv:") > 1 && navigator.userAgent.indexOf("Gecko") > 1;
1190
+ var isChrome = navigator.userAgent.indexOf("Chrome") !== -1;
1191
+ var isSafari = !isChrome && navigator.userAgent.indexOf("Safari") !== -1;
1192
+ var isIOS = /iPad|iPhone/i.test(navigator.platform) || // iPadOS 13+
1193
+ navigator.userAgent.includes("Mac") && "ontouchend" in document;
1194
+ var isBrave = () => navigator.brave?.isBrave?.name === "isBrave";
1195
+ var isMobileBreakpoint = (width, height) => {
1196
+ return width <= MQ_MAX_MOBILE || height < MQ_MAX_HEIGHT_LANDSCAPE && width < MQ_MAX_WIDTH_LANDSCAPE;
1197
+ };
1198
+ var isTabletBreakpoint = (editorWidth, editorHeight) => {
1199
+ const minSide = Math.min(editorWidth, editorHeight);
1200
+ const maxSide = Math.max(editorWidth, editorHeight);
1201
+ return minSide >= MQ_MIN_TABLET && maxSide <= MQ_MAX_TABLET;
1202
+ };
1203
+ var isMobileOrTablet = () => {
1204
+ const ua = navigator.userAgent || "";
1205
+ const platform = navigator.platform || "";
1206
+ const uaData = navigator.userAgentData;
1207
+ if (uaData) {
1208
+ const plat = (uaData.platform || "").toLowerCase();
1209
+ const isDesktopOS = plat === "windows" || plat === "macos" || plat === "linux" || plat === "chrome os";
1210
+ if (uaData.mobile === true) {
1211
+ return true;
1212
+ }
1213
+ if (uaData.mobile === false && plat === "android") {
1214
+ const looksTouchTablet = matchMedia?.("(hover: none)").matches && matchMedia?.("(pointer: coarse)").matches;
1215
+ return looksTouchTablet;
1216
+ }
1217
+ if (isDesktopOS) {
1218
+ return false;
1219
+ }
1220
+ }
1221
+ if (isIOS) {
1222
+ return true;
1223
+ }
1224
+ if (isAndroid) {
1225
+ const isAndroidPhone = /Mobile/i.test(ua);
1226
+ const isAndroidTablet = !isAndroidPhone;
1227
+ if (isAndroidPhone || isAndroidTablet) {
1228
+ const looksTouchTablet = matchMedia?.("(hover: none)").matches && matchMedia?.("(pointer: coarse)").matches;
1229
+ return looksTouchTablet;
1230
+ }
1231
+ }
1232
+ const looksDesktopPlatform = /Win|Linux|CrOS|Mac/.test(platform) || /Windows NT|X11|CrOS|Macintosh/.test(ua);
1233
+ if (looksDesktopPlatform) {
1234
+ return false;
1235
+ }
1236
+ return false;
1237
+ };
1238
+ var getFormFactor = (editorWidth, editorHeight) => {
1239
+ if (isMobileBreakpoint(editorWidth, editorHeight)) {
1240
+ return "phone";
1241
+ }
1242
+ if (isTabletBreakpoint(editorWidth, editorHeight)) {
1243
+ return "tablet";
1244
+ }
1245
+ return "desktop";
1246
+ };
1247
+ var deriveStylesPanelMode = (editorInterface) => {
1248
+ if (editorInterface.formFactor === "phone") {
1249
+ return "mobile";
1250
+ }
1251
+ if (editorInterface.formFactor === "tablet") {
1252
+ return "compact";
1253
+ }
1254
+ return editorInterface.desktopUIMode;
1255
+ };
1256
+ var createUserAgentDescriptor = (userAgentString) => {
1257
+ const normalizedUA = userAgentString ?? "";
1258
+ let platform = "unknown";
1259
+ if (isIOS) {
1260
+ platform = "ios";
1261
+ } else if (isAndroid) {
1262
+ platform = "android";
1263
+ } else if (normalizedUA) {
1264
+ platform = "other";
1265
+ }
1266
+ return {
1267
+ isMobileDevice: isMobileOrTablet(),
1268
+ platform
1269
+ };
1270
+ };
1271
+ var loadDesktopUIModePreference = () => {
1272
+ if (typeof window === "undefined") {
1273
+ return null;
1274
+ }
1275
+ try {
1276
+ const stored = window.localStorage.getItem(DESKTOP_UI_MODE_STORAGE_KEY);
1277
+ if (stored === "compact" || stored === "full") {
1278
+ return stored;
1279
+ }
1280
+ } catch (error) {
1281
+ }
1282
+ return null;
1283
+ };
1284
+ var persistDesktopUIMode = (mode) => {
1285
+ if (typeof window === "undefined") {
1286
+ return;
1287
+ }
1288
+ try {
1289
+ window.localStorage.setItem(DESKTOP_UI_MODE_STORAGE_KEY, mode);
1290
+ } catch (error) {
1291
+ }
1292
+ };
1293
+ var setDesktopUIMode = (mode) => {
1294
+ if (mode !== "compact" && mode !== "full") {
1295
+ return;
1296
+ }
1297
+ persistDesktopUIMode(mode);
1298
+ return mode;
1299
+ };
1300
+
1301
+ // src/keys.ts
1182
1302
  var CODES = {
1183
1303
  EQUAL: "Equal",
1184
1304
  MINUS: "Minus",
@@ -1424,7 +1544,7 @@ var isInteractive = (target) => {
1424
1544
  return isInputLike(target) || target instanceof Element && !!target.closest("label, button");
1425
1545
  };
1426
1546
  var isWritableElement = (target) => target instanceof HTMLElement && target.dataset.type === "wysiwyg" || target instanceof HTMLBRElement || // newline in wysiwyg
1427
- target instanceof HTMLTextAreaElement || target instanceof HTMLInputElement && (target.type === "text" || target.type === "number" || target.type === "password");
1547
+ target instanceof HTMLTextAreaElement || target instanceof HTMLInputElement && (target.type === "text" || target.type === "number" || target.type === "password" || target.type === "search");
1428
1548
  var getFontFamilyString = ({
1429
1549
  fontFamily
1430
1550
  }) => {
@@ -1441,6 +1561,9 @@ var getFontString = ({
1441
1561
  }) => {
1442
1562
  return `${fontSize}px ${getFontFamilyString({ fontFamily })}`;
1443
1563
  };
1564
+ var nextAnimationFrame = async (cb) => {
1565
+ requestAnimationFrame(() => requestAnimationFrame(cb));
1566
+ };
1444
1567
  var debounce = (fn, timeout) => {
1445
1568
  let handle = 0;
1446
1569
  let lastArgs = null;
@@ -1605,6 +1728,9 @@ var removeSelection = () => {
1605
1728
  }
1606
1729
  };
1607
1730
  var distance = (x, y) => Math.abs(x - y);
1731
+ var isSelectionLikeTool = (type) => {
1732
+ return type === "selection" || type === "lasso";
1733
+ };
1608
1734
  var updateActiveTool = (appState, data) => {
1609
1735
  if (data.type === "custom") {
1610
1736
  return {
@@ -1626,13 +1752,6 @@ var updateActiveTool = (appState, data) => {
1626
1752
  var isFullScreen = () => document.fullscreenElement?.nodeName === "HTML";
1627
1753
  var allowFullScreen = () => document.documentElement.requestFullscreen();
1628
1754
  var exitFullScreen = () => document.exitFullscreen();
1629
- var getShortcutKey = (shortcut) => {
1630
- shortcut = shortcut.replace(/\bAlt\b/i, "Alt").replace(/\bShift\b/i, "Shift").replace(/\b(Enter|Return)\b/i, "Enter");
1631
- if (isDarwin) {
1632
- return shortcut.replace(/\bCtrlOrCmd\b/gi, "Cmd").replace(/\bAlt\b/i, "Option");
1633
- }
1634
- return shortcut.replace(/\bCtrlOrCmd\b/gi, "Ctrl");
1635
- };
1636
1755
  var viewportCoordsToSceneCoords = ({ clientX, clientY }, {
1637
1756
  zoom,
1638
1757
  offsetLeft,
@@ -1711,7 +1830,6 @@ var isTransparent = (color) => {
1711
1830
  const isRRGGBBTransparent = color.length === 9 && color.substr(7, 2) === "00";
1712
1831
  return isRGBTransparent || isRRGGBBTransparent || color === COLOR_PALETTE.transparent;
1713
1832
  };
1714
- var isBindingFallthroughEnabled = (el) => el.fillStyle !== "solid" || isTransparent(el.backgroundColor);
1715
1833
  var resolvablePromise = () => {
1716
1834
  let resolve;
1717
1835
  let reject;
@@ -2074,6 +2192,38 @@ var reduceToCommonValue = (collection, getValue) => {
2074
2192
  }
2075
2193
  return commonValue;
2076
2194
  };
2195
+ var FEATURE_FLAGS_STORAGE_KEY = "excalidraw-feature-flags";
2196
+ var DEFAULT_FEATURE_FLAGS = {
2197
+ COMPLEX_BINDINGS: false
2198
+ };
2199
+ var featureFlags = null;
2200
+ var getFeatureFlag = (flag) => {
2201
+ if (!featureFlags) {
2202
+ try {
2203
+ const serializedFlags = localStorage.getItem(FEATURE_FLAGS_STORAGE_KEY);
2204
+ if (serializedFlags) {
2205
+ const flags = JSON.parse(serializedFlags);
2206
+ featureFlags = flags ?? DEFAULT_FEATURE_FLAGS;
2207
+ }
2208
+ } catch {
2209
+ }
2210
+ }
2211
+ return (featureFlags || DEFAULT_FEATURE_FLAGS)[flag];
2212
+ };
2213
+ var setFeatureFlag = (flag, value) => {
2214
+ try {
2215
+ featureFlags = {
2216
+ ...featureFlags || DEFAULT_FEATURE_FLAGS,
2217
+ [flag]: value
2218
+ };
2219
+ localStorage.setItem(
2220
+ FEATURE_FLAGS_STORAGE_KEY,
2221
+ JSON.stringify(featureFlags)
2222
+ );
2223
+ } catch (e) {
2224
+ console.error("unable to set feature flag", e);
2225
+ }
2226
+ };
2077
2227
 
2078
2228
  // src/random.ts
2079
2229
  var random = new Random(Date.now());
@@ -2147,6 +2297,107 @@ var Emitter = class {
2147
2297
  this.subscribers = [];
2148
2298
  }
2149
2299
  };
2300
+
2301
+ // src/visualdebug.ts
2302
+ init_define_import_meta_env();
2303
+ import {
2304
+ isLineSegment,
2305
+ lineSegment,
2306
+ pointFrom
2307
+ } from "@excalidraw/math";
2308
+ import { isBounds } from "@excalidraw/element";
2309
+ var debugDrawCubicBezier = (c, opts) => {
2310
+ addToCurrentFrame({
2311
+ color: opts?.color ?? "purple",
2312
+ permanent: !!opts?.permanent,
2313
+ data: c
2314
+ });
2315
+ };
2316
+ var debugDrawLine = (segment, opts) => {
2317
+ const segments = isLineSegment(segment) ? [segment] : segment;
2318
+ segments.forEach(
2319
+ (data) => addToCurrentFrame({
2320
+ color: opts?.color ?? "red",
2321
+ data,
2322
+ permanent: !!opts?.permanent
2323
+ })
2324
+ );
2325
+ };
2326
+ var debugDrawPoint = (p, opts) => {
2327
+ const xOffset = opts?.fuzzy ? Math.random() * 3 : 0;
2328
+ const yOffset = opts?.fuzzy ? Math.random() * 3 : 0;
2329
+ debugDrawLine(
2330
+ lineSegment(
2331
+ pointFrom(p[0] + xOffset - 10, p[1] + yOffset - 10),
2332
+ pointFrom(p[0] + xOffset + 10, p[1] + yOffset + 10)
2333
+ ),
2334
+ {
2335
+ color: opts?.color ?? "cyan",
2336
+ permanent: opts?.permanent
2337
+ }
2338
+ );
2339
+ debugDrawLine(
2340
+ lineSegment(
2341
+ pointFrom(p[0] + xOffset - 10, p[1] + yOffset + 10),
2342
+ pointFrom(p[0] + xOffset + 10, p[1] + yOffset - 10)
2343
+ ),
2344
+ {
2345
+ color: opts?.color ?? "cyan",
2346
+ permanent: opts?.permanent
2347
+ }
2348
+ );
2349
+ };
2350
+ var debugDrawBounds = (box, opts) => {
2351
+ (isBounds(box) ? [box] : box).forEach(
2352
+ (bbox) => debugDrawLine(
2353
+ [
2354
+ lineSegment(
2355
+ pointFrom(bbox[0], bbox[1]),
2356
+ pointFrom(bbox[2], bbox[1])
2357
+ ),
2358
+ lineSegment(
2359
+ pointFrom(bbox[2], bbox[1]),
2360
+ pointFrom(bbox[2], bbox[3])
2361
+ ),
2362
+ lineSegment(
2363
+ pointFrom(bbox[2], bbox[3]),
2364
+ pointFrom(bbox[0], bbox[3])
2365
+ ),
2366
+ lineSegment(
2367
+ pointFrom(bbox[0], bbox[3]),
2368
+ pointFrom(bbox[0], bbox[1])
2369
+ )
2370
+ ],
2371
+ {
2372
+ color: opts?.color ?? "green",
2373
+ permanent: !!opts?.permanent
2374
+ }
2375
+ )
2376
+ );
2377
+ };
2378
+ var debugDrawPoints = ({
2379
+ x,
2380
+ y,
2381
+ points
2382
+ }, options) => {
2383
+ points.forEach(
2384
+ (p) => debugDrawPoint(pointFrom(x + p[0], y + p[1]), options)
2385
+ );
2386
+ };
2387
+ var debugCloseFrame = () => {
2388
+ window.visualDebug?.data.push([]);
2389
+ };
2390
+ var debugClear = () => {
2391
+ if (window.visualDebug?.data) {
2392
+ window.visualDebug.data = [];
2393
+ }
2394
+ };
2395
+ var addToCurrentFrame = (element) => {
2396
+ if (window.visualDebug?.data && window.visualDebug.data.length === 0) {
2397
+ window.visualDebug.data[0] = [];
2398
+ }
2399
+ window.visualDebug?.data && window.visualDebug.data[window.visualDebug.data.length - 1].push(element);
2400
+ };
2150
2401
  export {
2151
2402
  ACTIVE_THRESHOLD,
2152
2403
  ALLOWED_PASTE_MIME_TYPES,
@@ -2154,6 +2405,7 @@ export {
2154
2405
  ARROW_LABEL_FONT_SIZE_TO_MIN_WIDTH_RATIO,
2155
2406
  ARROW_LABEL_WIDTH_FRACTION,
2156
2407
  ARROW_TYPE,
2408
+ BIND_MODE_TIMEOUT,
2157
2409
  BOUND_TEXT_PADDING,
2158
2410
  BinaryHeap,
2159
2411
  CANVAS_ONLY_ACTIONS,
@@ -2238,10 +2490,14 @@ export {
2238
2490
  MIN_FONT_SIZE,
2239
2491
  MIN_WIDTH_OR_HEIGHT,
2240
2492
  MIN_ZOOM,
2493
+ MOBILE_ACTION_BUTTON_BG,
2241
2494
  MONOSPACE_GENERIC_FONT,
2242
2495
  MQ_MAX_HEIGHT_LANDSCAPE,
2496
+ MQ_MAX_MOBILE,
2497
+ MQ_MAX_TABLET,
2243
2498
  MQ_MAX_WIDTH_LANDSCAPE,
2244
- MQ_MAX_WIDTH_PORTRAIT,
2499
+ MQ_MIN_TABLET,
2500
+ MQ_MIN_WIDTH_DESKTOP,
2245
2501
  MQ_RIGHT_SIDEBAR_MIN_WIDTH,
2246
2502
  ORIG_ID,
2247
2503
  POINTER_BUTTON,
@@ -2290,7 +2546,16 @@ export {
2290
2546
  chunk,
2291
2547
  cloneJSON,
2292
2548
  composeEventHandlers,
2549
+ createUserAgentDescriptor,
2293
2550
  debounce,
2551
+ debugClear,
2552
+ debugCloseFrame,
2553
+ debugDrawBounds,
2554
+ debugDrawCubicBezier,
2555
+ debugDrawLine,
2556
+ debugDrawPoint,
2557
+ debugDrawPoints,
2558
+ deriveStylesPanelMode,
2294
2559
  distance,
2295
2560
  easeOut,
2296
2561
  easeToValuesRAF,
@@ -2302,16 +2567,17 @@ export {
2302
2567
  getAllColorsSpecificShade,
2303
2568
  getDateTime,
2304
2569
  getExportSource,
2570
+ getFeatureFlag,
2305
2571
  getFontFamilyFallbacks,
2306
2572
  getFontFamilyString,
2307
2573
  getFontString,
2574
+ getFormFactor,
2308
2575
  getFrame,
2309
2576
  getGenericFontFamilyFallback,
2310
2577
  getGlobalCSSVariable,
2311
2578
  getGridPoint,
2312
2579
  getLineHeight,
2313
2580
  getNearestScrollableContainer,
2314
- getShortcutKey,
2315
2581
  getSizeFromPoints,
2316
2582
  getSpecificColorShades,
2317
2583
  getSvgPathFromStroke,
@@ -2322,7 +2588,6 @@ export {
2322
2588
  isAndroid,
2323
2589
  isAnyTrue,
2324
2590
  isArrowKey,
2325
- isBindingFallthroughEnabled,
2326
2591
  isBrave,
2327
2592
  isChrome,
2328
2593
  isDarwin,
@@ -2335,7 +2600,7 @@ export {
2335
2600
  isLatinChar,
2336
2601
  isLocalLink,
2337
2602
  isMemberOf,
2338
- isMobile,
2603
+ isMobileBreakpoint,
2339
2604
  isPrimitive,
2340
2605
  isProdEnv,
2341
2606
  isPromiseLike,
@@ -2343,18 +2608,22 @@ export {
2343
2608
  isReadonlyArray,
2344
2609
  isRunningInIframe,
2345
2610
  isSafari,
2611
+ isSelectionLikeTool,
2346
2612
  isServerEnv,
2347
2613
  isShallowEqual,
2614
+ isTabletBreakpoint,
2348
2615
  isTestEnv,
2349
2616
  isToolIcon,
2350
2617
  isTransparent,
2351
2618
  isWindows,
2352
2619
  isWritableElement,
2620
+ loadDesktopUIModePreference,
2353
2621
  mapFind,
2354
2622
  matchKey,
2355
2623
  memoize,
2356
2624
  muteFSAbortError,
2357
2625
  nFormatter,
2626
+ nextAnimationFrame,
2358
2627
  normalizeEOL,
2359
2628
  normalizeLink,
2360
2629
  preventUnload,
@@ -2372,6 +2641,8 @@ export {
2372
2641
  sceneCoordsToViewportCoords,
2373
2642
  selectNode,
2374
2643
  setDateTimeForTests,
2644
+ setDesktopUIMode,
2645
+ setFeatureFlag,
2375
2646
  shouldMaintainAspectRatio,
2376
2647
  shouldResizeFromCenter,
2377
2648
  shouldRotateWithDiscreteAngle,