@zsviczian/excalidraw 0.16.1-obsidian-5 → 0.16.1-obsidian-6

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.
@@ -1940,7 +1940,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
1940
1940
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1941
1941
 
1942
1942
  "use strict";
1943
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"actionDuplicateSelection\": () => (/* binding */ actionDuplicateSelection)\n/* harmony export */ });\n/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react/jsx-runtime */ \"../../../node_modules/react/jsx-runtime.js\");\n/* harmony import */ var _keys__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../keys */ \"../../keys.ts\");\n/* harmony import */ var _register__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./register */ \"../../actions/register.ts\");\n/* harmony import */ var _element__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../element */ \"../../element/index.ts\");\n/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../scene */ \"../../scene/index.ts\");\n/* harmony import */ var _components_ToolButton__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../components/ToolButton */ \"../../components/ToolButton.tsx\");\n/* harmony import */ var _i18n__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../i18n */ \"../../i18n.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../element/linearElementEditor */ \"../../element/linearElementEditor.ts\");\n/* harmony import */ var _groups__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../groups */ \"../../groups.ts\");\n/* harmony import */ var _element_binding__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../element/binding */ \"../../element/binding.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _element_textElement__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../element/textElement */ \"../../element/textElement.ts\");\n/* harmony import */ var _element_typeChecks__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../element/typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var _element_sortElements__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../element/sortElements */ \"../../element/sortElements.ts\");\n/* harmony import */ var _components_icons__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../components/icons */ \"../../components/icons.tsx\");\n/* harmony import */ var _frame__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../frame */ \"../../frame.ts\");\n/* harmony import */ var _scene_selection__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../scene/selection */ \"../../scene/selection.ts\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst actionDuplicateSelection = (0,_register__WEBPACK_IMPORTED_MODULE_2__.register)({\n name: \"duplicateSelection\",\n trackEvent: {\n category: \"element\"\n },\n perform: (elements, appState) => {\n // duplicate selected point(s) if editing a line\n if (appState.editingLinearElement) {\n const ret = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_8__.LinearElementEditor.duplicateSelectedPoints(appState);\n\n if (!ret) {\n return false;\n }\n\n return {\n elements,\n appState: ret.appState,\n commitToHistory: true\n };\n }\n\n return Object.assign(Object.assign({}, duplicateElements(elements, appState)), {\n commitToHistory: true\n });\n },\n contextItemLabel: \"labels.duplicateSelection\",\n keyTest: event => event[_keys__WEBPACK_IMPORTED_MODULE_1__.KEYS.CTRL_OR_CMD] && event.key === _keys__WEBPACK_IMPORTED_MODULE_1__.KEYS.D,\n PanelComponent: ({\n elements,\n appState,\n updateData\n }) => (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_ToolButton__WEBPACK_IMPORTED_MODULE_5__.ToolButton, {\n type: \"button\",\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_15__.DuplicateIcon,\n title: `${(0,_i18n__WEBPACK_IMPORTED_MODULE_6__.t)(\"labels.duplicateSelection\")} — ${(0,_utils__WEBPACK_IMPORTED_MODULE_7__.getShortcutKey)(\"CtrlOrCmd+D\")}`,\n \"aria-label\": (0,_i18n__WEBPACK_IMPORTED_MODULE_6__.t)(\"labels.duplicateSelection\"),\n onClick: () => updateData(null),\n visible: (0,_scene__WEBPACK_IMPORTED_MODULE_4__.isSomeElementSelected)((0,_element__WEBPACK_IMPORTED_MODULE_3__.getNonDeletedElements)(elements), appState)\n })\n});\n\nconst duplicateElements = (elements, appState) => {\n // ---------------------------------------------------------------------------\n // step (1)\n const sortedElements = (0,_element_sortElements__WEBPACK_IMPORTED_MODULE_14__.normalizeElementOrder)(elements);\n const groupIdMap = new Map();\n const newElements = [];\n const oldElements = [];\n const oldIdToDuplicatedId = new Map();\n\n const duplicateAndOffsetElement = element => {\n const newElement = (0,_element__WEBPACK_IMPORTED_MODULE_3__.duplicateElement)(appState.editingGroupId, groupIdMap, element, {\n x: element.x + _constants__WEBPACK_IMPORTED_MODULE_11__.GRID_SIZE / 2,\n y: element.y + _constants__WEBPACK_IMPORTED_MODULE_11__.GRID_SIZE / 2\n });\n oldIdToDuplicatedId.set(element.id, newElement.id);\n oldElements.push(element);\n newElements.push(newElement);\n return newElement;\n };\n\n const idsOfElementsToDuplicate = (0,_utils__WEBPACK_IMPORTED_MODULE_7__.arrayToMap)((0,_scene_selection__WEBPACK_IMPORTED_MODULE_17__.getSelectedElements)(sortedElements, appState, {\n includeBoundTextElement: true,\n includeElementsInFrames: true\n })); // Ids of elements that have already been processed so we don't push them\n // into the array twice if we end up backtracking when retrieving\n // discontiguous group of elements (can happen due to a bug, or in edge\n // cases such as a group containing deleted elements which were not selected).\n //\n // This is not enough to prevent duplicates, so we do a second loop afterwards\n // to remove them.\n //\n // For convenience we mark even the newly created ones even though we don't\n // loop over them.\n\n const processedIds = new Map();\n\n const markAsProcessed = elements => {\n for (const element of elements) {\n processedIds.set(element.id, true);\n }\n\n return elements;\n };\n\n const elementsWithClones = [];\n let index = -1;\n\n while (++index < sortedElements.length) {\n const element = sortedElements[index];\n\n if (processedIds.get(element.id)) {\n continue;\n }\n\n const boundTextElement = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_12__.getBoundTextElement)(element);\n const isElementAFrame = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_13__.isFrameElement)(element);\n\n if (idsOfElementsToDuplicate.get(element.id)) {\n // if a group or a container/bound-text or frame, duplicate atomically\n if (element.groupIds.length || boundTextElement || isElementAFrame) {\n const groupId = (0,_groups__WEBPACK_IMPORTED_MODULE_9__.getSelectedGroupForElement)(appState, element);\n\n if (groupId) {\n // TODO:\n // remove `.flatMap...`\n // if the elements in a frame are grouped when the frame is grouped\n const groupElements = (0,_groups__WEBPACK_IMPORTED_MODULE_9__.getElementsInGroup)(sortedElements, groupId).flatMap(element => (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_13__.isFrameElement)(element) ? [...(0,_frame__WEBPACK_IMPORTED_MODULE_16__.getFrameElements)(elements, element.id, {\n includeBoundArrows: true\n }), element] : [element]);\n elementsWithClones.push(...markAsProcessed([...groupElements, ...groupElements.map(element => duplicateAndOffsetElement(element))]));\n continue;\n }\n\n if (boundTextElement) {\n elementsWithClones.push(...markAsProcessed([element, boundTextElement, duplicateAndOffsetElement(element), duplicateAndOffsetElement(boundTextElement)]));\n continue;\n }\n\n if (isElementAFrame) {\n const elementsInFrame = (0,_frame__WEBPACK_IMPORTED_MODULE_16__.getFrameElements)(sortedElements, element.id, {\n includeBoundArrows: true\n });\n elementsWithClones.push(...markAsProcessed([...elementsInFrame, element, ...elementsInFrame.map(e => duplicateAndOffsetElement(e)), duplicateAndOffsetElement(element)]));\n continue;\n }\n } // since elements in frames have a lower z-index than the frame itself,\n // they will be looped first and if their frames are selected as well,\n // they will have been copied along with the frame atomically in the\n // above branch, so we must skip those elements here\n //\n // now, for elements do not belong any frames or elements whose frames\n // are selected (or elements that are left out from the above\n // steps for whatever reason) we (should at least) duplicate them here\n\n\n if (!element.frameId || !idsOfElementsToDuplicate.has(element.frameId)) {\n elementsWithClones.push(...markAsProcessed([element, duplicateAndOffsetElement(element)]));\n }\n } else {\n elementsWithClones.push(...markAsProcessed([element]));\n }\n } // step (2)\n // second pass to remove duplicates. We loop from the end as it's likelier\n // that the last elements are in the correct order (contiguous or otherwise).\n // Thus we need to reverse as the last step (3).\n\n\n const finalElementsReversed = [];\n const finalElementIds = new Map();\n index = elementsWithClones.length;\n\n while (--index >= 0) {\n const element = elementsWithClones[index];\n\n if (!finalElementIds.get(element.id)) {\n finalElementIds.set(element.id, true);\n finalElementsReversed.push(element);\n }\n } // step (3)\n\n\n const finalElements = finalElementsReversed.reverse(); // ---------------------------------------------------------------------------\n\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_12__.bindTextToShapeAfterDuplication)(elementsWithClones, oldElements, oldIdToDuplicatedId);\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_10__.fixBindingsAfterDuplication)(elementsWithClones, oldElements, oldIdToDuplicatedId);\n (0,_frame__WEBPACK_IMPORTED_MODULE_16__.bindElementsToFramesAfterDuplication)(finalElements, oldElements, oldIdToDuplicatedId);\n const nextElementsToSelect = (0,_scene_selection__WEBPACK_IMPORTED_MODULE_17__.excludeElementsInFramesFromSelection)(newElements);\n return {\n elements: finalElements,\n appState: Object.assign(Object.assign({}, appState), (0,_groups__WEBPACK_IMPORTED_MODULE_9__.selectGroupsForSelectedElements)({\n editingGroupId: appState.editingGroupId,\n selectedElementIds: nextElementsToSelect.reduce((acc, element) => {\n if (!(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_13__.isBoundToContainer)(element)) {\n acc[element.id] = true;\n }\n\n return acc;\n }, {})\n }, (0,_element__WEBPACK_IMPORTED_MODULE_3__.getNonDeletedElements)(finalElements), appState, null))\n };\n};\n\n//# sourceURL=webpack://ExcalidrawLib/../../actions/actionDuplicateSelection.tsx?");
1943
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"actionDuplicateSelection\": () => (/* binding */ actionDuplicateSelection)\n/* harmony export */ });\n/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react/jsx-runtime */ \"../../../node_modules/react/jsx-runtime.js\");\n/* harmony import */ var _keys__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../keys */ \"../../keys.ts\");\n/* harmony import */ var _register__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./register */ \"../../actions/register.ts\");\n/* harmony import */ var _element__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../element */ \"../../element/index.ts\");\n/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../scene */ \"../../scene/index.ts\");\n/* harmony import */ var _components_ToolButton__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../components/ToolButton */ \"../../components/ToolButton.tsx\");\n/* harmony import */ var _i18n__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../i18n */ \"../../i18n.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../element/linearElementEditor */ \"../../element/linearElementEditor.ts\");\n/* harmony import */ var _groups__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../groups */ \"../../groups.ts\");\n/* harmony import */ var _element_binding__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../element/binding */ \"../../element/binding.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _element_textElement__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../element/textElement */ \"../../element/textElement.ts\");\n/* harmony import */ var _element_typeChecks__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../element/typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var _element_sortElements__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../element/sortElements */ \"../../element/sortElements.ts\");\n/* harmony import */ var _components_icons__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../components/icons */ \"../../components/icons.tsx\");\n/* harmony import */ var _frame__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../frame */ \"../../frame.ts\");\n/* harmony import */ var _scene_selection__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../scene/selection */ \"../../scene/selection.ts\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst actionDuplicateSelection = (0,_register__WEBPACK_IMPORTED_MODULE_2__.register)({\n name: \"duplicateSelection\",\n trackEvent: {\n category: \"element\"\n },\n perform: (elements, appState) => {\n // duplicate selected point(s) if editing a line\n if (appState.editingLinearElement) {\n const ret = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_8__.LinearElementEditor.duplicateSelectedPoints(appState);\n\n if (!ret) {\n return false;\n }\n\n return {\n elements,\n appState: ret.appState,\n commitToHistory: true\n };\n }\n\n return Object.assign(Object.assign({}, duplicateElements(elements, appState)), {\n commitToHistory: true\n });\n },\n contextItemLabel: \"labels.duplicateSelection\",\n keyTest: event => event[_keys__WEBPACK_IMPORTED_MODULE_1__.KEYS.CTRL_OR_CMD] && event.key === _keys__WEBPACK_IMPORTED_MODULE_1__.KEYS.D,\n PanelComponent: ({\n elements,\n appState,\n updateData\n }) => (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_ToolButton__WEBPACK_IMPORTED_MODULE_5__.ToolButton, {\n type: \"button\",\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_15__.DuplicateIcon,\n title: `${(0,_i18n__WEBPACK_IMPORTED_MODULE_6__.t)(\"labels.duplicateSelection\")} — ${(0,_utils__WEBPACK_IMPORTED_MODULE_7__.getShortcutKey)(\"CtrlOrCmd+D\")}`,\n \"aria-label\": (0,_i18n__WEBPACK_IMPORTED_MODULE_6__.t)(\"labels.duplicateSelection\"),\n onClick: () => updateData(null),\n visible: (0,_scene__WEBPACK_IMPORTED_MODULE_4__.isSomeElementSelected)((0,_element__WEBPACK_IMPORTED_MODULE_3__.getNonDeletedElements)(elements), appState)\n })\n});\n\nconst duplicateElements = (elements, appState) => {\n // ---------------------------------------------------------------------------\n // step (1)\n const sortedElements = (0,_element_sortElements__WEBPACK_IMPORTED_MODULE_14__.normalizeElementOrder)(elements);\n const groupIdMap = new Map();\n const newElements = [];\n const oldElements = [];\n const oldIdToDuplicatedId = new Map();\n\n const duplicateAndOffsetElement = element => {\n const newElement = (0,_element__WEBPACK_IMPORTED_MODULE_3__.duplicateElement)(appState.editingGroupId, groupIdMap, element, {\n x: element.x + _constants__WEBPACK_IMPORTED_MODULE_11__.GRID_SIZE / 2,\n y: element.y + _constants__WEBPACK_IMPORTED_MODULE_11__.GRID_SIZE / 2\n });\n oldIdToDuplicatedId.set(element.id, newElement.id);\n oldElements.push(element);\n newElements.push(newElement);\n return newElement;\n };\n\n const idsOfElementsToDuplicate = (0,_utils__WEBPACK_IMPORTED_MODULE_7__.arrayToMap)((0,_scene_selection__WEBPACK_IMPORTED_MODULE_17__.getSelectedElements)(sortedElements, appState, {\n includeBoundTextElement: true,\n includeElementsInFrames: true\n })); // Ids of elements that have already been processed so we don't push them\n // into the array twice if we end up backtracking when retrieving\n // discontiguous group of elements (can happen due to a bug, or in edge\n // cases such as a group containing deleted elements which were not selected).\n //\n // This is not enough to prevent duplicates, so we do a second loop afterwards\n // to remove them.\n //\n // For convenience we mark even the newly created ones even though we don't\n // loop over them.\n\n const processedIds = new Map();\n\n const markAsProcessed = elements => {\n for (const element of elements) {\n processedIds.set(element.id, true);\n }\n\n return elements;\n };\n\n const elementsWithClones = [];\n let index = -1;\n\n while (++index < sortedElements.length) {\n const element = sortedElements[index];\n\n if (processedIds.get(element.id)) {\n continue;\n }\n\n const boundTextElement = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_12__.getBoundTextElement)(element);\n const isElementAFrame = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_13__.isFrameElement)(element);\n\n if (idsOfElementsToDuplicate.get(element.id)) {\n // if a group or a container/bound-text or frame, duplicate atomically\n if (element.groupIds.length || boundTextElement || isElementAFrame) {\n const groupId = (0,_groups__WEBPACK_IMPORTED_MODULE_9__.getSelectedGroupForElement)(appState, element);\n\n if (groupId) {\n // TODO:\n // remove `.flatMap...`\n // if the elements in a frame are grouped when the frame is grouped\n const groupElements = (0,_groups__WEBPACK_IMPORTED_MODULE_9__.getElementsInGroup)(sortedElements, groupId).flatMap(element => (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_13__.isFrameElement)(element) ? [...(0,_frame__WEBPACK_IMPORTED_MODULE_16__.getFrameElements)(elements, element.id), element] : [element]);\n elementsWithClones.push(...markAsProcessed([...groupElements, ...groupElements.map(element => duplicateAndOffsetElement(element))]));\n continue;\n }\n\n if (boundTextElement) {\n elementsWithClones.push(...markAsProcessed([element, boundTextElement, duplicateAndOffsetElement(element), duplicateAndOffsetElement(boundTextElement)]));\n continue;\n }\n\n if (isElementAFrame) {\n const elementsInFrame = (0,_frame__WEBPACK_IMPORTED_MODULE_16__.getFrameElements)(sortedElements, element.id);\n elementsWithClones.push(...markAsProcessed([...elementsInFrame, element, ...elementsInFrame.map(e => duplicateAndOffsetElement(e)), duplicateAndOffsetElement(element)]));\n continue;\n }\n } // since elements in frames have a lower z-index than the frame itself,\n // they will be looped first and if their frames are selected as well,\n // they will have been copied along with the frame atomically in the\n // above branch, so we must skip those elements here\n //\n // now, for elements do not belong any frames or elements whose frames\n // are selected (or elements that are left out from the above\n // steps for whatever reason) we (should at least) duplicate them here\n\n\n if (!element.frameId || !idsOfElementsToDuplicate.has(element.frameId)) {\n elementsWithClones.push(...markAsProcessed([element, duplicateAndOffsetElement(element)]));\n }\n } else {\n elementsWithClones.push(...markAsProcessed([element]));\n }\n } // step (2)\n // second pass to remove duplicates. We loop from the end as it's likelier\n // that the last elements are in the correct order (contiguous or otherwise).\n // Thus we need to reverse as the last step (3).\n\n\n const finalElementsReversed = [];\n const finalElementIds = new Map();\n index = elementsWithClones.length;\n\n while (--index >= 0) {\n const element = elementsWithClones[index];\n\n if (!finalElementIds.get(element.id)) {\n finalElementIds.set(element.id, true);\n finalElementsReversed.push(element);\n }\n } // step (3)\n\n\n const finalElements = finalElementsReversed.reverse(); // ---------------------------------------------------------------------------\n\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_12__.bindTextToShapeAfterDuplication)(elementsWithClones, oldElements, oldIdToDuplicatedId);\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_10__.fixBindingsAfterDuplication)(elementsWithClones, oldElements, oldIdToDuplicatedId);\n (0,_frame__WEBPACK_IMPORTED_MODULE_16__.bindElementsToFramesAfterDuplication)(finalElements, oldElements, oldIdToDuplicatedId);\n const nextElementsToSelect = (0,_scene_selection__WEBPACK_IMPORTED_MODULE_17__.excludeElementsInFramesFromSelection)(newElements);\n return {\n elements: finalElements,\n appState: Object.assign(Object.assign({}, appState), (0,_groups__WEBPACK_IMPORTED_MODULE_9__.selectGroupsForSelectedElements)({\n editingGroupId: appState.editingGroupId,\n selectedElementIds: nextElementsToSelect.reduce((acc, element) => {\n if (!(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_13__.isBoundToContainer)(element)) {\n acc[element.id] = true;\n }\n\n return acc;\n }, {})\n }, (0,_element__WEBPACK_IMPORTED_MODULE_3__.getNonDeletedElements)(finalElements), appState, null))\n };\n};\n\n//# sourceURL=webpack://ExcalidrawLib/../../actions/actionDuplicateSelection.tsx?");
1944
1944
 
1945
1945
  /***/ }),
1946
1946
 
@@ -2061,7 +2061,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
2061
2061
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2062
2062
 
2063
2063
  "use strict";
2064
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"actionChangeArrowhead\": () => (/* binding */ actionChangeArrowhead),\n/* harmony export */ \"actionChangeBackgroundColor\": () => (/* binding */ actionChangeBackgroundColor),\n/* harmony export */ \"actionChangeFillStyle\": () => (/* binding */ actionChangeFillStyle),\n/* harmony export */ \"actionChangeFontFamily\": () => (/* binding */ actionChangeFontFamily),\n/* harmony export */ \"actionChangeFontSize\": () => (/* binding */ actionChangeFontSize),\n/* harmony export */ \"actionChangeOpacity\": () => (/* binding */ actionChangeOpacity),\n/* harmony export */ \"actionChangeRoundness\": () => (/* binding */ actionChangeRoundness),\n/* harmony export */ \"actionChangeSloppiness\": () => (/* binding */ actionChangeSloppiness),\n/* harmony export */ \"actionChangeStrokeColor\": () => (/* binding */ actionChangeStrokeColor),\n/* harmony export */ \"actionChangeStrokeStyle\": () => (/* binding */ actionChangeStrokeStyle),\n/* harmony export */ \"actionChangeStrokeWidth\": () => (/* binding */ actionChangeStrokeWidth),\n/* harmony export */ \"actionChangeTextAlign\": () => (/* binding */ actionChangeTextAlign),\n/* harmony export */ \"actionChangeVerticalAlign\": () => (/* binding */ actionChangeVerticalAlign),\n/* harmony export */ \"actionDecreaseFontSize\": () => (/* binding */ actionDecreaseFontSize),\n/* harmony export */ \"actionIncreaseFontSize\": () => (/* binding */ actionIncreaseFontSize),\n/* harmony export */ \"changeProperty\": () => (/* binding */ changeProperty),\n/* harmony export */ \"getFormValue\": () => (/* binding */ getFormValue)\n/* harmony export */ });\n/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react/jsx-runtime */ \"../../../node_modules/react/jsx-runtime.js\");\n/* harmony import */ var _colors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../colors */ \"../../colors.ts\");\n/* harmony import */ var _analytics__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../analytics */ \"../../analytics.ts\");\n/* harmony import */ var _components_ButtonIconSelect__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../components/ButtonIconSelect */ \"../../components/ButtonIconSelect.tsx\");\n/* harmony import */ var _components_ColorPicker_ColorPicker__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../components/ColorPicker/ColorPicker */ \"../../components/ColorPicker/ColorPicker.tsx\");\n/* harmony import */ var _components_IconPicker__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../components/IconPicker */ \"../../components/IconPicker.tsx\");\n/* harmony import */ var _components_App__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../components/App */ \"../../components/App.tsx\");\n/* harmony import */ var _components_icons__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../components/icons */ \"../../components/icons.tsx\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _element__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../element */ \"../../element/index.ts\");\n/* harmony import */ var _element_mutateElement__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../element/mutateElement */ \"../../element/mutateElement.ts\");\n/* harmony import */ var _element_textElement__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../element/textElement */ \"../../element/textElement.ts\");\n/* harmony import */ var _element_typeChecks__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../element/typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var _i18n__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../i18n */ \"../../i18n.ts\");\n/* harmony import */ var _keys__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../keys */ \"../../keys.ts\");\n/* harmony import */ var _random__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../random */ \"../../random.ts\");\n/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../scene */ \"../../scene/index.ts\");\n/* harmony import */ var _scene_comparisons__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../scene/comparisons */ \"../../scene/comparisons.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _register__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./register */ \"../../actions/register.ts\");\n\n\n\n\n\n\n // TODO barnabasmolnar/editor-redesign\n// TextAlignTopIcon, TextAlignBottomIcon,TextAlignMiddleIcon,\n// ArrowHead icons\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst FONT_SIZE_RELATIVE_INCREASE_STEP = 0.1;\nconst changeProperty = (elements, appState, callback, includeBoundText = false) => {\n const selectedElementIds = (0,_utils__WEBPACK_IMPORTED_MODULE_18__.arrayToMap)((0,_scene__WEBPACK_IMPORTED_MODULE_16__.getSelectedElements)(elements, appState, {\n includeBoundTextElement: includeBoundText\n }));\n return elements.map(element => {\n var _a;\n\n if (selectedElementIds.get(element.id) || element.id === ((_a = appState.editingElement) === null || _a === void 0 ? void 0 : _a.id)) {\n return callback(element);\n }\n\n return element;\n });\n};\nconst getFormValue = function (elements, appState, getAttribute, defaultValue) {\n var _a, _b;\n\n const editingElement = appState.editingElement;\n const nonDeletedElements = (0,_element__WEBPACK_IMPORTED_MODULE_9__.getNonDeletedElements)(elements);\n return (_b = (_a = editingElement && getAttribute(editingElement)) !== null && _a !== void 0 ? _a : (0,_scene__WEBPACK_IMPORTED_MODULE_16__.isSomeElementSelected)(nonDeletedElements, appState) ? (0,_scene__WEBPACK_IMPORTED_MODULE_16__.getCommonAttributeOfSelectedElements)(nonDeletedElements, appState, getAttribute) : defaultValue) !== null && _b !== void 0 ? _b : defaultValue;\n};\n\nconst offsetElementAfterFontResize = (prevElement, nextElement) => {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_12__.isBoundToContainer)(nextElement)) {\n return nextElement;\n }\n\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.mutateElement)(nextElement, {\n x: prevElement.textAlign === \"left\" ? prevElement.x : prevElement.x + (prevElement.width - nextElement.width) / (prevElement.textAlign === \"center\" ? 2 : 1),\n // centering vertically is non-standard, but for Excalidraw I think\n // it makes sense\n y: prevElement.y + (prevElement.height - nextElement.height) / 2\n }, false);\n};\n\nconst changeFontSize = (elements, appState, getNewFontSize, fallbackValue) => {\n const newFontSizes = new Set();\n return {\n elements: changeProperty(elements, appState, oldElement => {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(oldElement)) {\n const newFontSize = getNewFontSize(oldElement);\n newFontSizes.add(newFontSize);\n let newElement = (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(oldElement, {\n fontSize: newFontSize\n });\n (0,_element__WEBPACK_IMPORTED_MODULE_9__.redrawTextBoundingBox)(newElement, (0,_element_textElement__WEBPACK_IMPORTED_MODULE_11__.getContainerElement)(oldElement));\n newElement = offsetElementAfterFontResize(oldElement, newElement);\n return newElement;\n }\n\n return oldElement;\n }, true),\n appState: Object.assign(Object.assign({}, appState), {\n // update state only if we've set all select text elements to\n // the same font size\n currentItemFontSize: newFontSizes.size === 1 ? [...newFontSizes][0] : fallbackValue !== null && fallbackValue !== void 0 ? fallbackValue : appState.currentItemFontSize\n }),\n commitToHistory: true\n };\n}; // -----------------------------------------------------------------------------\n\n\nconst actionChangeStrokeColor = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"changeStrokeColor\",\n trackEvent: false,\n perform: (elements, appState, value) => {\n //zsviczian added containers\n const containers = (0,_scene__WEBPACK_IMPORTED_MODULE_16__.getSelectedElements)(elements, appState, {\n includeBoundTextElement: false\n }).filter(el => el.boundElements).map(el => el.id);\n return Object.assign(Object.assign({}, value.currentItemStrokeColor && {\n elements: changeProperty(elements, appState, el => {\n var _a;\n\n if ( //zsviczian\n (0,_element__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(el) && el.containerId && containers.includes(el.containerId) && ((_a = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_11__.getContainerElement)(el)) === null || _a === void 0 ? void 0 : _a.strokeColor) !== el.strokeColor) {\n return el;\n }\n\n return (0,_scene_comparisons__WEBPACK_IMPORTED_MODULE_17__.hasStrokeColor)(el.type) ? (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(el, {\n strokeColor: value.currentItemStrokeColor\n }) : el;\n }, true)\n }), {\n appState: Object.assign(Object.assign({}, appState), value),\n commitToHistory: !!value.currentItemStrokeColor\n });\n },\n PanelComponent: ({\n elements,\n appState,\n updateData,\n appProps\n }) => {\n var _a, _b, _c, _d, _e;\n\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"h3\", Object.assign({\n \"aria-hidden\": \"true\"\n }, {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.stroke\")\n })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_ColorPicker_ColorPicker__WEBPACK_IMPORTED_MODULE_4__.ColorPicker, {\n topPicks: //zsviczian\n (_c = (_b = (_a = appState.colorPalette) === null || _a === void 0 ? void 0 : _a.topPicks) === null || _b === void 0 ? void 0 : _b.elementStroke) !== null && _c !== void 0 ? _c : _colors__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_ELEMENT_STROKE_PICKS,\n palette: //zsviczian\n (_e = (_d = appState.colorPalette) === null || _d === void 0 ? void 0 : _d.elementStroke) !== null && _e !== void 0 ? _e : _colors__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_ELEMENT_STROKE_COLOR_PALETTE,\n type: \"elementStroke\",\n label: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.stroke\"),\n color: getFormValue(elements, appState, element => element.strokeColor, appState.currentItemStrokeColor),\n onChange: color => updateData({\n currentItemStrokeColor: color\n }),\n elements: elements,\n appState: appState,\n updateData: updateData\n })]\n });\n }\n});\nconst actionChangeBackgroundColor = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"changeBackgroundColor\",\n trackEvent: false,\n perform: (elements, appState, value) => {\n return Object.assign(Object.assign({}, value.currentItemBackgroundColor && {\n elements: changeProperty(elements, appState, el => (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(el, {\n backgroundColor: value.currentItemBackgroundColor\n }))\n }), {\n appState: Object.assign(Object.assign({}, appState), value),\n commitToHistory: !!value.currentItemBackgroundColor\n });\n },\n PanelComponent: ({\n elements,\n appState,\n updateData,\n appProps\n }) => {\n var _a, _b, _c, _d, _e;\n\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"h3\", Object.assign({\n \"aria-hidden\": \"true\"\n }, {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.background\")\n })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_ColorPicker_ColorPicker__WEBPACK_IMPORTED_MODULE_4__.ColorPicker, {\n topPicks: //zsviczian\n (_c = (_b = (_a = appState.colorPalette) === null || _a === void 0 ? void 0 : _a.topPicks) === null || _b === void 0 ? void 0 : _b.elementBackground) !== null && _c !== void 0 ? _c : _colors__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_ELEMENT_BACKGROUND_PICKS,\n palette: //zsviczian\n (_e = (_d = appState.colorPalette) === null || _d === void 0 ? void 0 : _d.elementBackground) !== null && _e !== void 0 ? _e : _colors__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_ELEMENT_BACKGROUND_COLOR_PALETTE,\n type: \"elementBackground\",\n label: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.background\"),\n color: getFormValue(elements, appState, element => element.backgroundColor, appState.currentItemBackgroundColor),\n onChange: color => updateData({\n currentItemBackgroundColor: color\n }),\n elements: elements,\n appState: appState,\n updateData: updateData\n })]\n });\n }\n});\nconst actionChangeFillStyle = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"changeFillStyle\",\n trackEvent: false,\n perform: (elements, appState, value, app) => {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_2__.trackEvent)(\"element\", \"changeFillStyle\", `${value} (${app.device.isMobile ? \"mobile\" : \"desktop\"})`);\n return {\n elements: changeProperty(elements, appState, el => (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(el, {\n fillStyle: value\n })),\n appState: Object.assign(Object.assign({}, appState), {\n currentItemFillStyle: value\n }),\n commitToHistory: true\n };\n },\n PanelComponent: ({\n elements,\n appState,\n updateData\n }) => {\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_16__.getSelectedElements)(elements, appState);\n const allElementsZigZag = selectedElements.length > 0 && selectedElements.every(el => el.fillStyle === \"zigzag\");\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"fieldset\", {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"legend\", {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.fill\")\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_ButtonIconSelect__WEBPACK_IMPORTED_MODULE_3__.ButtonIconSelect, {\n type: \"button\",\n options: [{\n value: \"hachure\",\n text: `${allElementsZigZag ? (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.zigzag\") : (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.hachure\")} (${(0,_utils__WEBPACK_IMPORTED_MODULE_18__.getShortcutKey)(\"Alt-Click\")})`,\n icon: allElementsZigZag ? _components_icons__WEBPACK_IMPORTED_MODULE_7__.FillZigZagIcon : _components_icons__WEBPACK_IMPORTED_MODULE_7__.FillHachureIcon,\n active: allElementsZigZag ? true : undefined\n }, {\n value: \"cross-hatch\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.crossHatch\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.FillCrossHatchIcon\n }, {\n value: \"solid\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.solid\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.FillSolidIcon\n }],\n value: getFormValue(elements, appState, element => element.fillStyle, appState.currentItemFillStyle),\n onClick: (value, event) => {\n const nextValue = event.altKey && value === \"hachure\" && selectedElements.every(el => el.fillStyle === \"hachure\") ? \"zigzag\" : value;\n updateData(nextValue);\n }\n })]\n });\n }\n});\nconst actionChangeStrokeWidth = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"changeStrokeWidth\",\n trackEvent: false,\n perform: (elements, appState, value) => {\n return {\n elements: changeProperty(elements, appState, el => (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(el, {\n strokeWidth: value\n })),\n appState: Object.assign(Object.assign({}, appState), {\n currentItemStrokeWidth: value\n }),\n commitToHistory: true\n };\n },\n PanelComponent: ({\n elements,\n appState,\n updateData\n }) => (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"fieldset\", {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"legend\", {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.strokeWidth\")\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_ButtonIconSelect__WEBPACK_IMPORTED_MODULE_3__.ButtonIconSelect, {\n group: \"stroke-width\",\n options: [{\n value: 0.5,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.extraThin\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.StrokeWidthThinIcon\n }, {\n value: 1,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.thin\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.StrokeWidthBaseIcon\n }, {\n value: 2,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.bold\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.StrokeWidthBoldIcon\n }, {\n value: 4,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.extraBold\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.StrokeWidthExtraBoldIcon\n }],\n value: getFormValue(elements, appState, element => element.strokeWidth, appState.currentItemStrokeWidth),\n onChange: value => updateData(value)\n })]\n })\n});\nconst actionChangeSloppiness = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"changeSloppiness\",\n trackEvent: false,\n perform: (elements, appState, value) => {\n return {\n elements: changeProperty(elements, appState, el => (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(el, {\n seed: (0,_random__WEBPACK_IMPORTED_MODULE_15__.randomInteger)(),\n roughness: value\n })),\n appState: Object.assign(Object.assign({}, appState), {\n currentItemRoughness: value\n }),\n commitToHistory: true\n };\n },\n PanelComponent: ({\n elements,\n appState,\n updateData\n }) => (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"fieldset\", {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"legend\", {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.sloppiness\")\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_ButtonIconSelect__WEBPACK_IMPORTED_MODULE_3__.ButtonIconSelect, {\n group: \"sloppiness\",\n options: [{\n value: 0,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.architect\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.SloppinessArchitectIcon\n }, {\n value: 1,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.artist\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.SloppinessArtistIcon\n }, {\n value: 2,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.cartoonist\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.SloppinessCartoonistIcon\n }],\n value: getFormValue(elements, appState, element => element.roughness, appState.currentItemRoughness),\n onChange: value => updateData(value)\n })]\n })\n});\nconst actionChangeStrokeStyle = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"changeStrokeStyle\",\n trackEvent: false,\n perform: (elements, appState, value) => {\n return {\n elements: changeProperty(elements, appState, el => (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(el, {\n strokeStyle: value\n })),\n appState: Object.assign(Object.assign({}, appState), {\n currentItemStrokeStyle: value\n }),\n commitToHistory: true\n };\n },\n PanelComponent: ({\n elements,\n appState,\n updateData\n }) => (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"fieldset\", {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"legend\", {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.strokeStyle\")\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_ButtonIconSelect__WEBPACK_IMPORTED_MODULE_3__.ButtonIconSelect, {\n group: \"strokeStyle\",\n options: [{\n value: \"solid\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.strokeStyle_solid\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.StrokeWidthBaseIcon\n }, {\n value: \"dashed\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.strokeStyle_dashed\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.StrokeStyleDashedIcon\n }, {\n value: \"dotted\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.strokeStyle_dotted\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.StrokeStyleDottedIcon\n }],\n value: getFormValue(elements, appState, element => element.strokeStyle, appState.currentItemStrokeStyle),\n onChange: value => updateData(value)\n })]\n })\n});\nconst actionChangeOpacity = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"changeOpacity\",\n trackEvent: false,\n perform: (elements, appState, value) => {\n return {\n elements: changeProperty(elements, appState, el => (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(el, {\n opacity: value\n }), true),\n appState: Object.assign(Object.assign({}, appState), {\n currentItemOpacity: value\n }),\n commitToHistory: true\n };\n },\n PanelComponent: ({\n elements,\n appState,\n updateData\n }) => {\n var _a;\n\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"label\", Object.assign({\n className: \"control-label\"\n }, {\n children: [(0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.opacity\"), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"input\", {\n type: \"range\",\n min: \"0\",\n max: \"100\",\n step: \"10\",\n onChange: event => updateData(+event.target.value),\n value: (_a = getFormValue(elements, appState, element => element.opacity, appState.currentItemOpacity)) !== null && _a !== void 0 ? _a : undefined\n })]\n }));\n }\n});\nconst actionChangeFontSize = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"changeFontSize\",\n trackEvent: false,\n perform: (elements, appState, value) => {\n return changeFontSize(elements, appState, () => value, value);\n },\n PanelComponent: ({\n elements,\n appState,\n updateData\n }) => (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"fieldset\", {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"legend\", {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.fontSize\")\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_ButtonIconSelect__WEBPACK_IMPORTED_MODULE_3__.ButtonIconSelect, {\n group: \"font-size\",\n options: [{\n value: 16,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.small\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.FontSizeSmallIcon,\n testId: \"fontSize-small\"\n }, {\n value: 20,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.medium\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.FontSizeMediumIcon,\n testId: \"fontSize-medium\"\n }, {\n value: 28,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.large\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.FontSizeLargeIcon,\n testId: \"fontSize-large\"\n }, {\n value: 36,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.veryLarge\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.FontSizeExtraLargeIcon,\n testId: \"fontSize-veryLarge\"\n }],\n value: getFormValue(elements, appState, element => {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(element)) {\n return element.fontSize;\n }\n\n const boundTextElement = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_11__.getBoundTextElement)(element);\n\n if (boundTextElement) {\n return boundTextElement.fontSize;\n }\n\n return null;\n }, appState.currentItemFontSize || _constants__WEBPACK_IMPORTED_MODULE_8__.DEFAULT_FONT_SIZE),\n onChange: value => updateData(value)\n })]\n })\n});\nconst actionDecreaseFontSize = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"decreaseFontSize\",\n trackEvent: false,\n perform: (elements, appState, value) => {\n return changeFontSize(elements, appState, element => Math.round( // get previous value before relative increase (doesn't work fully\n // due to rounding and float precision issues)\n 1 / (1 + FONT_SIZE_RELATIVE_INCREASE_STEP) * element.fontSize));\n },\n keyTest: event => {\n return event[_keys__WEBPACK_IMPORTED_MODULE_14__.KEYS.CTRL_OR_CMD] && event.shiftKey && ( // KEYS.COMMA needed for MacOS\n event.key === _keys__WEBPACK_IMPORTED_MODULE_14__.KEYS.CHEVRON_LEFT || event.key === _keys__WEBPACK_IMPORTED_MODULE_14__.KEYS.COMMA);\n }\n});\nconst actionIncreaseFontSize = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"increaseFontSize\",\n trackEvent: false,\n perform: (elements, appState, value) => {\n return changeFontSize(elements, appState, element => Math.round(element.fontSize * (1 + FONT_SIZE_RELATIVE_INCREASE_STEP)));\n },\n keyTest: event => {\n return event[_keys__WEBPACK_IMPORTED_MODULE_14__.KEYS.CTRL_OR_CMD] && event.shiftKey && ( // KEYS.PERIOD needed for MacOS\n event.key === _keys__WEBPACK_IMPORTED_MODULE_14__.KEYS.CHEVRON_RIGHT || event.key === _keys__WEBPACK_IMPORTED_MODULE_14__.KEYS.PERIOD);\n }\n});\nconst actionChangeFontFamily = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"changeFontFamily\",\n trackEvent: false,\n perform: (elements, appState, value) => {\n return {\n elements: changeProperty(elements, appState, oldElement => {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(oldElement)) {\n const newElement = (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(oldElement, {\n fontFamily: value,\n lineHeight: (0,_element_textElement__WEBPACK_IMPORTED_MODULE_11__.getDefaultLineHeight)(value)\n });\n (0,_element__WEBPACK_IMPORTED_MODULE_9__.redrawTextBoundingBox)(newElement, (0,_element_textElement__WEBPACK_IMPORTED_MODULE_11__.getContainerElement)(oldElement));\n return newElement;\n }\n\n return oldElement;\n }, true),\n appState: Object.assign(Object.assign({}, appState), {\n currentItemFontFamily: value\n }),\n commitToHistory: true\n };\n },\n PanelComponent: ({\n elements,\n appState,\n updateData\n }) => {\n const options = [{\n value: _constants__WEBPACK_IMPORTED_MODULE_8__.FONT_FAMILY.Virgil,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.handDrawn\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.FreedrawIcon\n }, {\n value: _constants__WEBPACK_IMPORTED_MODULE_8__.FONT_FAMILY.Helvetica,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.normal\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.FontFamilyNormalIcon\n }, {\n value: _constants__WEBPACK_IMPORTED_MODULE_8__.FONT_FAMILY.Cascadia,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.code\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.FontFamilyCodeIcon\n }, ...(_components_App__WEBPACK_IMPORTED_MODULE_6__.showFourthFont ? [{\n value: _constants__WEBPACK_IMPORTED_MODULE_8__.FONT_FAMILY.LocalFont,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.localFont\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.FontFamilyLocalFontIcon\n }] : [])];\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"fieldset\", {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"legend\", {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.fontFamily\")\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_ButtonIconSelect__WEBPACK_IMPORTED_MODULE_3__.ButtonIconSelect, {\n group: \"font-family\",\n options: options,\n value: getFormValue(elements, appState, element => {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(element)) {\n return element.fontFamily;\n }\n\n const boundTextElement = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_11__.getBoundTextElement)(element);\n\n if (boundTextElement) {\n return boundTextElement.fontFamily;\n }\n\n return null;\n }, appState.currentItemFontFamily || _constants__WEBPACK_IMPORTED_MODULE_8__.DEFAULT_FONT_FAMILY),\n onChange: value => updateData(value)\n })]\n });\n }\n});\nconst actionChangeTextAlign = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"changeTextAlign\",\n trackEvent: false,\n perform: (elements, appState, value) => {\n return {\n elements: changeProperty(elements, appState, oldElement => {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(oldElement)) {\n const newElement = (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(oldElement, {\n textAlign: value\n });\n (0,_element__WEBPACK_IMPORTED_MODULE_9__.redrawTextBoundingBox)(newElement, (0,_element_textElement__WEBPACK_IMPORTED_MODULE_11__.getContainerElement)(oldElement));\n return newElement;\n }\n\n return oldElement;\n }, true),\n appState: Object.assign(Object.assign({}, appState), {\n currentItemTextAlign: value\n }),\n commitToHistory: true\n };\n },\n PanelComponent: ({\n elements,\n appState,\n updateData\n }) => {\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"fieldset\", {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"legend\", {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.textAlign\")\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_ButtonIconSelect__WEBPACK_IMPORTED_MODULE_3__.ButtonIconSelect, {\n group: \"text-align\",\n options: [{\n value: \"left\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.left\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.TextAlignLeftIcon,\n testId: \"align-left\"\n }, {\n value: \"center\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.center\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.TextAlignCenterIcon,\n testId: \"align-horizontal-center\"\n }, {\n value: \"right\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.right\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.TextAlignRightIcon,\n testId: \"align-right\"\n }],\n value: getFormValue(elements, appState, element => {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(element)) {\n return element.textAlign;\n }\n\n const boundTextElement = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_11__.getBoundTextElement)(element);\n\n if (boundTextElement) {\n return boundTextElement.textAlign;\n }\n\n return null;\n }, appState.currentItemTextAlign),\n onChange: value => updateData(value)\n })]\n });\n }\n});\nconst actionChangeVerticalAlign = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"changeVerticalAlign\",\n trackEvent: {\n category: \"element\"\n },\n perform: (elements, appState, value) => {\n return {\n elements: changeProperty(elements, appState, oldElement => {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(oldElement)) {\n const newElement = (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(oldElement, {\n verticalAlign: value\n });\n (0,_element__WEBPACK_IMPORTED_MODULE_9__.redrawTextBoundingBox)(newElement, (0,_element_textElement__WEBPACK_IMPORTED_MODULE_11__.getContainerElement)(oldElement));\n return newElement;\n }\n\n return oldElement;\n }, true),\n appState: Object.assign({}, appState),\n commitToHistory: true\n };\n },\n PanelComponent: ({\n elements,\n appState,\n updateData\n }) => {\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"fieldset\", {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_ButtonIconSelect__WEBPACK_IMPORTED_MODULE_3__.ButtonIconSelect, {\n group: \"text-align\",\n options: [{\n value: _constants__WEBPACK_IMPORTED_MODULE_8__.VERTICAL_ALIGN.TOP,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.alignTop\"),\n icon: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_icons__WEBPACK_IMPORTED_MODULE_7__.TextAlignTopIcon, {\n theme: appState.theme\n }),\n testId: \"align-top\"\n }, {\n value: _constants__WEBPACK_IMPORTED_MODULE_8__.VERTICAL_ALIGN.MIDDLE,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.centerVertically\"),\n icon: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_icons__WEBPACK_IMPORTED_MODULE_7__.TextAlignMiddleIcon, {\n theme: appState.theme\n }),\n testId: \"align-middle\"\n }, {\n value: _constants__WEBPACK_IMPORTED_MODULE_8__.VERTICAL_ALIGN.BOTTOM,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.alignBottom\"),\n icon: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_icons__WEBPACK_IMPORTED_MODULE_7__.TextAlignBottomIcon, {\n theme: appState.theme\n }),\n testId: \"align-bottom\"\n }],\n value: getFormValue(elements, appState, element => {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(element) && element.containerId) {\n return element.verticalAlign;\n }\n\n const boundTextElement = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_11__.getBoundTextElement)(element);\n\n if (boundTextElement) {\n return boundTextElement.verticalAlign;\n }\n\n return null;\n }, _constants__WEBPACK_IMPORTED_MODULE_8__.VERTICAL_ALIGN.MIDDLE),\n onChange: value => updateData(value)\n })\n });\n }\n});\nconst actionChangeRoundness = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"changeRoundness\",\n trackEvent: false,\n perform: (elements, appState, value) => {\n return {\n elements: changeProperty(elements, appState, el => (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(el, {\n roundness: value === \"round\" ? {\n type: (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_12__.isUsingAdaptiveRadius)(el.type) ? _constants__WEBPACK_IMPORTED_MODULE_8__.ROUNDNESS.ADAPTIVE_RADIUS : _constants__WEBPACK_IMPORTED_MODULE_8__.ROUNDNESS.PROPORTIONAL_RADIUS\n } : null\n })),\n appState: Object.assign(Object.assign({}, appState), {\n currentItemRoundness: value\n }),\n commitToHistory: true\n };\n },\n PanelComponent: ({\n elements,\n appState,\n updateData\n }) => {\n const targetElements = (0,_scene__WEBPACK_IMPORTED_MODULE_16__.getTargetElements)((0,_element__WEBPACK_IMPORTED_MODULE_9__.getNonDeletedElements)(elements), appState);\n const hasLegacyRoundness = targetElements.some(el => {\n var _a;\n\n return ((_a = el.roundness) === null || _a === void 0 ? void 0 : _a.type) === _constants__WEBPACK_IMPORTED_MODULE_8__.ROUNDNESS.LEGACY;\n });\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"fieldset\", {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"legend\", {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.edges\")\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_ButtonIconSelect__WEBPACK_IMPORTED_MODULE_3__.ButtonIconSelect, {\n group: \"edges\",\n options: [{\n value: \"sharp\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.sharp\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.EdgeSharpIcon\n }, {\n value: \"round\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.round\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.EdgeRoundIcon\n }],\n value: getFormValue(elements, appState, element => hasLegacyRoundness ? null : element.roundness ? \"round\" : \"sharp\", (0,_scene__WEBPACK_IMPORTED_MODULE_16__.canChangeRoundness)(appState.activeTool.type) && appState.currentItemRoundness || null),\n onChange: value => updateData(value)\n })]\n });\n }\n});\nconst actionChangeArrowhead = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"changeArrowhead\",\n trackEvent: false,\n perform: (elements, appState, value) => {\n return {\n elements: changeProperty(elements, appState, el => {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_12__.isLinearElement)(el)) {\n const {\n position,\n type\n } = value;\n\n if (position === \"start\") {\n const element = (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(el, {\n startArrowhead: type\n });\n return element;\n } else if (position === \"end\") {\n const element = (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(el, {\n endArrowhead: type\n });\n return element;\n }\n }\n\n return el;\n }),\n appState: Object.assign(Object.assign({}, appState), {\n [value.position === \"start\" ? \"currentItemStartArrowhead\" : \"currentItemEndArrowhead\"]: value.type\n }),\n commitToHistory: true\n };\n },\n PanelComponent: ({\n elements,\n appState,\n updateData\n }) => {\n const isRTL = (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.getLanguage)().rtl;\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"fieldset\", {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"legend\", {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.arrowheads\")\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"div\", Object.assign({\n className: \"iconSelectList buttonList\"\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_IconPicker__WEBPACK_IMPORTED_MODULE_5__.IconPicker, {\n label: \"arrowhead_start\",\n options: [{\n value: null,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.arrowhead_none\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.ArrowheadNoneIcon,\n keyBinding: \"q\"\n }, {\n value: \"arrow\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.arrowhead_arrow\"),\n icon: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_icons__WEBPACK_IMPORTED_MODULE_7__.ArrowheadArrowIcon, {\n flip: !isRTL\n }),\n keyBinding: \"w\"\n }, {\n value: \"bar\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.arrowhead_bar\"),\n icon: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_icons__WEBPACK_IMPORTED_MODULE_7__.ArrowheadBarIcon, {\n flip: !isRTL\n }),\n keyBinding: \"e\"\n }, {\n value: \"dot\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.arrowhead_dot\"),\n icon: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_icons__WEBPACK_IMPORTED_MODULE_7__.ArrowheadDotIcon, {\n flip: !isRTL\n }),\n keyBinding: \"r\"\n }, {\n value: \"triangle\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.arrowhead_triangle\"),\n icon: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_icons__WEBPACK_IMPORTED_MODULE_7__.ArrowheadTriangleIcon, {\n flip: !isRTL\n }),\n keyBinding: \"t\"\n }],\n value: getFormValue(elements, appState, element => (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_12__.isLinearElement)(element) && (0,_scene__WEBPACK_IMPORTED_MODULE_16__.canHaveArrowheads)(element.type) ? element.startArrowhead : appState.currentItemStartArrowhead, appState.currentItemStartArrowhead),\n onChange: value => updateData({\n position: \"start\",\n type: value\n })\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_IconPicker__WEBPACK_IMPORTED_MODULE_5__.IconPicker, {\n label: \"arrowhead_end\",\n group: \"arrowheads\",\n options: [{\n value: null,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.arrowhead_none\"),\n keyBinding: \"q\",\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.ArrowheadNoneIcon\n }, {\n value: \"arrow\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.arrowhead_arrow\"),\n keyBinding: \"w\",\n icon: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_icons__WEBPACK_IMPORTED_MODULE_7__.ArrowheadArrowIcon, {\n flip: isRTL\n })\n }, {\n value: \"bar\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.arrowhead_bar\"),\n keyBinding: \"e\",\n icon: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_icons__WEBPACK_IMPORTED_MODULE_7__.ArrowheadBarIcon, {\n flip: isRTL\n })\n }, {\n value: \"dot\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.arrowhead_dot\"),\n keyBinding: \"r\",\n icon: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_icons__WEBPACK_IMPORTED_MODULE_7__.ArrowheadDotIcon, {\n flip: isRTL\n })\n }, {\n value: \"triangle\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.arrowhead_triangle\"),\n icon: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_icons__WEBPACK_IMPORTED_MODULE_7__.ArrowheadTriangleIcon, {\n flip: isRTL\n }),\n keyBinding: \"t\"\n }],\n value: getFormValue(elements, appState, element => (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_12__.isLinearElement)(element) && (0,_scene__WEBPACK_IMPORTED_MODULE_16__.canHaveArrowheads)(element.type) ? element.endArrowhead : appState.currentItemEndArrowhead, appState.currentItemEndArrowhead),\n onChange: value => updateData({\n position: \"end\",\n type: value\n })\n })]\n }))]\n });\n }\n});\n\n//# sourceURL=webpack://ExcalidrawLib/../../actions/actionProperties.tsx?");
2064
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"actionChangeArrowhead\": () => (/* binding */ actionChangeArrowhead),\n/* harmony export */ \"actionChangeBackgroundColor\": () => (/* binding */ actionChangeBackgroundColor),\n/* harmony export */ \"actionChangeFillStyle\": () => (/* binding */ actionChangeFillStyle),\n/* harmony export */ \"actionChangeFontFamily\": () => (/* binding */ actionChangeFontFamily),\n/* harmony export */ \"actionChangeFontSize\": () => (/* binding */ actionChangeFontSize),\n/* harmony export */ \"actionChangeOpacity\": () => (/* binding */ actionChangeOpacity),\n/* harmony export */ \"actionChangeRoundness\": () => (/* binding */ actionChangeRoundness),\n/* harmony export */ \"actionChangeSloppiness\": () => (/* binding */ actionChangeSloppiness),\n/* harmony export */ \"actionChangeStrokeColor\": () => (/* binding */ actionChangeStrokeColor),\n/* harmony export */ \"actionChangeStrokeStyle\": () => (/* binding */ actionChangeStrokeStyle),\n/* harmony export */ \"actionChangeStrokeWidth\": () => (/* binding */ actionChangeStrokeWidth),\n/* harmony export */ \"actionChangeTextAlign\": () => (/* binding */ actionChangeTextAlign),\n/* harmony export */ \"actionChangeVerticalAlign\": () => (/* binding */ actionChangeVerticalAlign),\n/* harmony export */ \"actionDecreaseFontSize\": () => (/* binding */ actionDecreaseFontSize),\n/* harmony export */ \"actionIncreaseFontSize\": () => (/* binding */ actionIncreaseFontSize),\n/* harmony export */ \"changeProperty\": () => (/* binding */ changeProperty),\n/* harmony export */ \"getFormValue\": () => (/* binding */ getFormValue)\n/* harmony export */ });\n/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react/jsx-runtime */ \"../../../node_modules/react/jsx-runtime.js\");\n/* harmony import */ var _colors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../colors */ \"../../colors.ts\");\n/* harmony import */ var _analytics__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../analytics */ \"../../analytics.ts\");\n/* harmony import */ var _components_ButtonIconSelect__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../components/ButtonIconSelect */ \"../../components/ButtonIconSelect.tsx\");\n/* harmony import */ var _components_ColorPicker_ColorPicker__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../components/ColorPicker/ColorPicker */ \"../../components/ColorPicker/ColorPicker.tsx\");\n/* harmony import */ var _components_IconPicker__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../components/IconPicker */ \"../../components/IconPicker.tsx\");\n/* harmony import */ var _components_App__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../components/App */ \"../../components/App.tsx\");\n/* harmony import */ var _components_icons__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../components/icons */ \"../../components/icons.tsx\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _element__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../element */ \"../../element/index.ts\");\n/* harmony import */ var _element_mutateElement__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../element/mutateElement */ \"../../element/mutateElement.ts\");\n/* harmony import */ var _element_textElement__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../element/textElement */ \"../../element/textElement.ts\");\n/* harmony import */ var _element_typeChecks__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../element/typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var _i18n__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../i18n */ \"../../i18n.ts\");\n/* harmony import */ var _keys__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../keys */ \"../../keys.ts\");\n/* harmony import */ var _random__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../random */ \"../../random.ts\");\n/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../scene */ \"../../scene/index.ts\");\n/* harmony import */ var _scene_comparisons__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../scene/comparisons */ \"../../scene/comparisons.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _register__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./register */ \"../../actions/register.ts\");\n\n\n\n\n\n\n // TODO barnabasmolnar/editor-redesign\n// TextAlignTopIcon, TextAlignBottomIcon,TextAlignMiddleIcon,\n// ArrowHead icons\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst FONT_SIZE_RELATIVE_INCREASE_STEP = 0.1;\nconst changeProperty = (elements, appState, callback, includeBoundText = false) => {\n const selectedElementIds = (0,_utils__WEBPACK_IMPORTED_MODULE_18__.arrayToMap)((0,_scene__WEBPACK_IMPORTED_MODULE_16__.getSelectedElements)(elements, appState, {\n includeBoundTextElement: includeBoundText\n }));\n return elements.map(element => {\n var _a;\n\n if (selectedElementIds.get(element.id) || element.id === ((_a = appState.editingElement) === null || _a === void 0 ? void 0 : _a.id)) {\n return callback(element);\n }\n\n return element;\n });\n};\nconst getFormValue = function (elements, appState, getAttribute, isRelevantElement, defaultValue) {\n var _a;\n\n const editingElement = appState.editingElement;\n const nonDeletedElements = (0,_element__WEBPACK_IMPORTED_MODULE_9__.getNonDeletedElements)(elements);\n let ret = null;\n\n if (editingElement) {\n ret = getAttribute(editingElement);\n }\n\n if (!ret) {\n const hasSelection = (0,_scene__WEBPACK_IMPORTED_MODULE_16__.isSomeElementSelected)(nonDeletedElements, appState);\n\n if (hasSelection) {\n ret = (_a = (0,_scene__WEBPACK_IMPORTED_MODULE_16__.getCommonAttributeOfSelectedElements)(isRelevantElement === true ? nonDeletedElements : nonDeletedElements.filter(el => isRelevantElement(el)), appState, getAttribute)) !== null && _a !== void 0 ? _a : typeof defaultValue === \"function\" ? defaultValue(true) : defaultValue;\n } else {\n ret = typeof defaultValue === \"function\" ? defaultValue(false) : defaultValue;\n }\n }\n\n return ret;\n};\n\nconst offsetElementAfterFontResize = (prevElement, nextElement) => {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_12__.isBoundToContainer)(nextElement)) {\n return nextElement;\n }\n\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.mutateElement)(nextElement, {\n x: prevElement.textAlign === \"left\" ? prevElement.x : prevElement.x + (prevElement.width - nextElement.width) / (prevElement.textAlign === \"center\" ? 2 : 1),\n // centering vertically is non-standard, but for Excalidraw I think\n // it makes sense\n y: prevElement.y + (prevElement.height - nextElement.height) / 2\n }, false);\n};\n\nconst changeFontSize = (elements, appState, getNewFontSize, fallbackValue) => {\n const newFontSizes = new Set();\n return {\n elements: changeProperty(elements, appState, oldElement => {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(oldElement)) {\n const newFontSize = getNewFontSize(oldElement);\n newFontSizes.add(newFontSize);\n let newElement = (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(oldElement, {\n fontSize: newFontSize\n });\n (0,_element__WEBPACK_IMPORTED_MODULE_9__.redrawTextBoundingBox)(newElement, (0,_element_textElement__WEBPACK_IMPORTED_MODULE_11__.getContainerElement)(oldElement));\n newElement = offsetElementAfterFontResize(oldElement, newElement);\n return newElement;\n }\n\n return oldElement;\n }, true),\n appState: Object.assign(Object.assign({}, appState), {\n // update state only if we've set all select text elements to\n // the same font size\n currentItemFontSize: newFontSizes.size === 1 ? [...newFontSizes][0] : fallbackValue !== null && fallbackValue !== void 0 ? fallbackValue : appState.currentItemFontSize\n }),\n commitToHistory: true\n };\n}; // -----------------------------------------------------------------------------\n\n\nconst actionChangeStrokeColor = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"changeStrokeColor\",\n trackEvent: false,\n perform: (elements, appState, value) => {\n //zsviczian added containers\n const containers = (0,_scene__WEBPACK_IMPORTED_MODULE_16__.getSelectedElements)(elements, appState, {\n includeBoundTextElement: false\n }).filter(el => el.boundElements).map(el => el.id);\n return Object.assign(Object.assign({}, value.currentItemStrokeColor && {\n elements: changeProperty(elements, appState, el => {\n var _a;\n\n if ( //zsviczian\n (0,_element__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(el) && el.containerId && containers.includes(el.containerId) && ((_a = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_11__.getContainerElement)(el)) === null || _a === void 0 ? void 0 : _a.strokeColor) !== el.strokeColor) {\n return el;\n }\n\n return (0,_scene_comparisons__WEBPACK_IMPORTED_MODULE_17__.hasStrokeColor)(el.type) ? (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(el, {\n strokeColor: value.currentItemStrokeColor\n }) : el;\n }, true)\n }), {\n appState: Object.assign(Object.assign({}, appState), value),\n commitToHistory: !!value.currentItemStrokeColor\n });\n },\n PanelComponent: ({\n elements,\n appState,\n updateData,\n appProps\n }) => {\n var _a, _b, _c, _d, _e;\n\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"h3\", Object.assign({\n \"aria-hidden\": \"true\"\n }, {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.stroke\")\n })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_ColorPicker_ColorPicker__WEBPACK_IMPORTED_MODULE_4__.ColorPicker, {\n topPicks: //zsviczian\n (_c = (_b = (_a = appState.colorPalette) === null || _a === void 0 ? void 0 : _a.topPicks) === null || _b === void 0 ? void 0 : _b.elementStroke) !== null && _c !== void 0 ? _c : _colors__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_ELEMENT_STROKE_PICKS,\n palette: //zsviczian\n (_e = (_d = appState.colorPalette) === null || _d === void 0 ? void 0 : _d.elementStroke) !== null && _e !== void 0 ? _e : _colors__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_ELEMENT_STROKE_COLOR_PALETTE,\n type: \"elementStroke\",\n label: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.stroke\"),\n color: getFormValue(elements, appState, element => element.strokeColor, true, appState.currentItemStrokeColor),\n onChange: color => updateData({\n currentItemStrokeColor: color\n }),\n elements: elements,\n appState: appState,\n updateData: updateData\n })]\n });\n }\n});\nconst actionChangeBackgroundColor = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"changeBackgroundColor\",\n trackEvent: false,\n perform: (elements, appState, value) => {\n return Object.assign(Object.assign({}, value.currentItemBackgroundColor && {\n elements: changeProperty(elements, appState, el => (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(el, {\n backgroundColor: value.currentItemBackgroundColor\n }))\n }), {\n appState: Object.assign(Object.assign({}, appState), value),\n commitToHistory: !!value.currentItemBackgroundColor\n });\n },\n PanelComponent: ({\n elements,\n appState,\n updateData,\n appProps\n }) => {\n var _a, _b, _c, _d, _e;\n\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"h3\", Object.assign({\n \"aria-hidden\": \"true\"\n }, {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.background\")\n })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_ColorPicker_ColorPicker__WEBPACK_IMPORTED_MODULE_4__.ColorPicker, {\n topPicks: //zsviczian\n (_c = (_b = (_a = appState.colorPalette) === null || _a === void 0 ? void 0 : _a.topPicks) === null || _b === void 0 ? void 0 : _b.elementBackground) !== null && _c !== void 0 ? _c : _colors__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_ELEMENT_BACKGROUND_PICKS,\n palette: //zsviczian\n (_e = (_d = appState.colorPalette) === null || _d === void 0 ? void 0 : _d.elementBackground) !== null && _e !== void 0 ? _e : _colors__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_ELEMENT_BACKGROUND_COLOR_PALETTE,\n type: \"elementBackground\",\n label: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.background\"),\n color: getFormValue(elements, appState, element => element.backgroundColor, true, appState.currentItemBackgroundColor),\n onChange: color => updateData({\n currentItemBackgroundColor: color\n }),\n elements: elements,\n appState: appState,\n updateData: updateData\n })]\n });\n }\n});\nconst actionChangeFillStyle = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"changeFillStyle\",\n trackEvent: false,\n perform: (elements, appState, value, app) => {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_2__.trackEvent)(\"element\", \"changeFillStyle\", `${value} (${app.device.isMobile ? \"mobile\" : \"desktop\"})`);\n return {\n elements: changeProperty(elements, appState, el => (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(el, {\n fillStyle: value\n })),\n appState: Object.assign(Object.assign({}, appState), {\n currentItemFillStyle: value\n }),\n commitToHistory: true\n };\n },\n PanelComponent: ({\n elements,\n appState,\n updateData\n }) => {\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_16__.getSelectedElements)(elements, appState);\n const allElementsZigZag = selectedElements.length > 0 && selectedElements.every(el => el.fillStyle === \"zigzag\");\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"fieldset\", {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"legend\", {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.fill\")\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_ButtonIconSelect__WEBPACK_IMPORTED_MODULE_3__.ButtonIconSelect, {\n type: \"button\",\n options: [{\n value: \"hachure\",\n text: `${allElementsZigZag ? (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.zigzag\") : (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.hachure\")} (${(0,_utils__WEBPACK_IMPORTED_MODULE_18__.getShortcutKey)(\"Alt-Click\")})`,\n icon: allElementsZigZag ? _components_icons__WEBPACK_IMPORTED_MODULE_7__.FillZigZagIcon : _components_icons__WEBPACK_IMPORTED_MODULE_7__.FillHachureIcon,\n active: allElementsZigZag ? true : undefined,\n testId: `fill-hachure`\n }, {\n value: \"cross-hatch\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.crossHatch\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.FillCrossHatchIcon,\n testId: `fill-cross-hatch`\n }, {\n value: \"solid\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.solid\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.FillSolidIcon,\n testId: `fill-solid`\n }],\n value: getFormValue(elements, appState, element => element.fillStyle, element => element.hasOwnProperty(\"fillStyle\"), hasSelection => hasSelection ? null : appState.currentItemFillStyle),\n onClick: (value, event) => {\n const nextValue = event.altKey && value === \"hachure\" && selectedElements.every(el => el.fillStyle === \"hachure\") ? \"zigzag\" : value;\n updateData(nextValue);\n }\n })]\n });\n }\n});\nconst actionChangeStrokeWidth = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"changeStrokeWidth\",\n trackEvent: false,\n perform: (elements, appState, value) => {\n return {\n elements: changeProperty(elements, appState, el => (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(el, {\n strokeWidth: value\n })),\n appState: Object.assign(Object.assign({}, appState), {\n currentItemStrokeWidth: value\n }),\n commitToHistory: true\n };\n },\n PanelComponent: ({\n elements,\n appState,\n updateData\n }) => (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"fieldset\", {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"legend\", {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.strokeWidth\")\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_ButtonIconSelect__WEBPACK_IMPORTED_MODULE_3__.ButtonIconSelect, {\n group: \"stroke-width\",\n options: [{\n value: _constants__WEBPACK_IMPORTED_MODULE_8__.STROKE_WIDTH.thin,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.thin\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.StrokeWidthBaseIcon,\n testId: \"strokeWidth-thin\"\n }, {\n value: _constants__WEBPACK_IMPORTED_MODULE_8__.STROKE_WIDTH.bold,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.bold\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.StrokeWidthBoldIcon,\n testId: \"strokeWidth-bold\"\n }, {\n value: _constants__WEBPACK_IMPORTED_MODULE_8__.STROKE_WIDTH.extraBold,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.extraBold\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.StrokeWidthExtraBoldIcon,\n testId: \"strokeWidth-extraBold\"\n }],\n value: getFormValue(elements, appState, element => element.strokeWidth, element => element.hasOwnProperty(\"strokeWidth\"), hasSelection => hasSelection ? null : appState.currentItemStrokeWidth),\n onChange: value => updateData(value)\n })]\n })\n});\nconst actionChangeSloppiness = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"changeSloppiness\",\n trackEvent: false,\n perform: (elements, appState, value) => {\n return {\n elements: changeProperty(elements, appState, el => (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(el, {\n seed: (0,_random__WEBPACK_IMPORTED_MODULE_15__.randomInteger)(),\n roughness: value\n })),\n appState: Object.assign(Object.assign({}, appState), {\n currentItemRoughness: value\n }),\n commitToHistory: true\n };\n },\n PanelComponent: ({\n elements,\n appState,\n updateData\n }) => (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"fieldset\", {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"legend\", {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.sloppiness\")\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_ButtonIconSelect__WEBPACK_IMPORTED_MODULE_3__.ButtonIconSelect, {\n group: \"sloppiness\",\n options: [{\n value: 0,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.architect\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.SloppinessArchitectIcon\n }, {\n value: 1,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.artist\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.SloppinessArtistIcon\n }, {\n value: 2,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.cartoonist\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.SloppinessCartoonistIcon\n }],\n value: getFormValue(elements, appState, element => element.roughness, element => element.hasOwnProperty(\"roughness\"), hasSelection => hasSelection ? null : appState.currentItemRoughness),\n onChange: value => updateData(value)\n })]\n })\n});\nconst actionChangeStrokeStyle = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"changeStrokeStyle\",\n trackEvent: false,\n perform: (elements, appState, value) => {\n return {\n elements: changeProperty(elements, appState, el => (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(el, {\n strokeStyle: value\n })),\n appState: Object.assign(Object.assign({}, appState), {\n currentItemStrokeStyle: value\n }),\n commitToHistory: true\n };\n },\n PanelComponent: ({\n elements,\n appState,\n updateData\n }) => (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"fieldset\", {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"legend\", {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.strokeStyle\")\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_ButtonIconSelect__WEBPACK_IMPORTED_MODULE_3__.ButtonIconSelect, {\n group: \"strokeStyle\",\n options: [{\n value: \"solid\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.strokeStyle_solid\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.StrokeWidthBaseIcon\n }, {\n value: \"dashed\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.strokeStyle_dashed\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.StrokeStyleDashedIcon\n }, {\n value: \"dotted\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.strokeStyle_dotted\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.StrokeStyleDottedIcon\n }],\n value: getFormValue(elements, appState, element => element.strokeStyle, element => element.hasOwnProperty(\"strokeStyle\"), hasSelection => hasSelection ? null : appState.currentItemStrokeStyle),\n onChange: value => updateData(value)\n })]\n })\n});\nconst actionChangeOpacity = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"changeOpacity\",\n trackEvent: false,\n perform: (elements, appState, value) => {\n return {\n elements: changeProperty(elements, appState, el => (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(el, {\n opacity: value\n }), true),\n appState: Object.assign(Object.assign({}, appState), {\n currentItemOpacity: value\n }),\n commitToHistory: true\n };\n },\n PanelComponent: ({\n elements,\n appState,\n updateData\n }) => {\n var _a;\n\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"label\", Object.assign({\n className: \"control-label\"\n }, {\n children: [(0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.opacity\"), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"input\", {\n type: \"range\",\n min: \"0\",\n max: \"100\",\n step: \"10\",\n onChange: event => updateData(+event.target.value),\n value: (_a = getFormValue(elements, appState, element => element.opacity, true, appState.currentItemOpacity)) !== null && _a !== void 0 ? _a : undefined\n })]\n }));\n }\n});\nconst actionChangeFontSize = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"changeFontSize\",\n trackEvent: false,\n perform: (elements, appState, value) => {\n return changeFontSize(elements, appState, () => value, value);\n },\n PanelComponent: ({\n elements,\n appState,\n updateData\n }) => (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"fieldset\", {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"legend\", {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.fontSize\")\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_ButtonIconSelect__WEBPACK_IMPORTED_MODULE_3__.ButtonIconSelect, {\n group: \"font-size\",\n options: [{\n value: 16,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.small\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.FontSizeSmallIcon,\n testId: \"fontSize-small\"\n }, {\n value: 20,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.medium\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.FontSizeMediumIcon,\n testId: \"fontSize-medium\"\n }, {\n value: 28,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.large\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.FontSizeLargeIcon,\n testId: \"fontSize-large\"\n }, {\n value: 36,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.veryLarge\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.FontSizeExtraLargeIcon,\n testId: \"fontSize-veryLarge\"\n }],\n value: getFormValue(elements, appState, element => {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(element)) {\n return element.fontSize;\n }\n\n const boundTextElement = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_11__.getBoundTextElement)(element);\n\n if (boundTextElement) {\n return boundTextElement.fontSize;\n }\n\n return null;\n }, element => (0,_element__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(element) || (0,_element_textElement__WEBPACK_IMPORTED_MODULE_11__.getBoundTextElement)(element) !== null, hasSelection => hasSelection ? null : appState.currentItemFontSize || _constants__WEBPACK_IMPORTED_MODULE_8__.DEFAULT_FONT_SIZE),\n onChange: value => updateData(value)\n })]\n })\n});\nconst actionDecreaseFontSize = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"decreaseFontSize\",\n trackEvent: false,\n perform: (elements, appState, value) => {\n return changeFontSize(elements, appState, element => Math.round( // get previous value before relative increase (doesn't work fully\n // due to rounding and float precision issues)\n 1 / (1 + FONT_SIZE_RELATIVE_INCREASE_STEP) * element.fontSize));\n },\n keyTest: event => {\n return event[_keys__WEBPACK_IMPORTED_MODULE_14__.KEYS.CTRL_OR_CMD] && event.shiftKey && ( // KEYS.COMMA needed for MacOS\n event.key === _keys__WEBPACK_IMPORTED_MODULE_14__.KEYS.CHEVRON_LEFT || event.key === _keys__WEBPACK_IMPORTED_MODULE_14__.KEYS.COMMA);\n }\n});\nconst actionIncreaseFontSize = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"increaseFontSize\",\n trackEvent: false,\n perform: (elements, appState, value) => {\n return changeFontSize(elements, appState, element => Math.round(element.fontSize * (1 + FONT_SIZE_RELATIVE_INCREASE_STEP)));\n },\n keyTest: event => {\n return event[_keys__WEBPACK_IMPORTED_MODULE_14__.KEYS.CTRL_OR_CMD] && event.shiftKey && ( // KEYS.PERIOD needed for MacOS\n event.key === _keys__WEBPACK_IMPORTED_MODULE_14__.KEYS.CHEVRON_RIGHT || event.key === _keys__WEBPACK_IMPORTED_MODULE_14__.KEYS.PERIOD);\n }\n});\nconst actionChangeFontFamily = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"changeFontFamily\",\n trackEvent: false,\n perform: (elements, appState, value) => {\n return {\n elements: changeProperty(elements, appState, oldElement => {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(oldElement)) {\n const newElement = (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(oldElement, {\n fontFamily: value,\n lineHeight: (0,_element_textElement__WEBPACK_IMPORTED_MODULE_11__.getDefaultLineHeight)(value)\n });\n (0,_element__WEBPACK_IMPORTED_MODULE_9__.redrawTextBoundingBox)(newElement, (0,_element_textElement__WEBPACK_IMPORTED_MODULE_11__.getContainerElement)(oldElement));\n return newElement;\n }\n\n return oldElement;\n }, true),\n appState: Object.assign(Object.assign({}, appState), {\n currentItemFontFamily: value\n }),\n commitToHistory: true\n };\n },\n PanelComponent: ({\n elements,\n appState,\n updateData\n }) => {\n const options = [{\n value: _constants__WEBPACK_IMPORTED_MODULE_8__.FONT_FAMILY.Virgil,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.handDrawn\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.FreedrawIcon,\n testId: \"font-family-virgil\"\n }, {\n value: _constants__WEBPACK_IMPORTED_MODULE_8__.FONT_FAMILY.Helvetica,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.normal\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.FontFamilyNormalIcon,\n testId: \"font-family-normal\"\n }, {\n value: _constants__WEBPACK_IMPORTED_MODULE_8__.FONT_FAMILY.Cascadia,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.code\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.FontFamilyCodeIcon,\n testId: \"font-family-code\"\n }, ...(_components_App__WEBPACK_IMPORTED_MODULE_6__.showFourthFont ? [{\n value: _constants__WEBPACK_IMPORTED_MODULE_8__.FONT_FAMILY.LocalFont,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.localFont\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.FontFamilyLocalFontIcon,\n testId: \"font-family-fourth\"\n }] : [])];\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"fieldset\", {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"legend\", {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.fontFamily\")\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_ButtonIconSelect__WEBPACK_IMPORTED_MODULE_3__.ButtonIconSelect, {\n group: \"font-family\",\n options: options,\n value: getFormValue(elements, appState, element => {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(element)) {\n return element.fontFamily;\n }\n\n const boundTextElement = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_11__.getBoundTextElement)(element);\n\n if (boundTextElement) {\n return boundTextElement.fontFamily;\n }\n\n return null;\n }, element => (0,_element__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(element) || (0,_element_textElement__WEBPACK_IMPORTED_MODULE_11__.getBoundTextElement)(element) !== null, hasSelection => hasSelection ? null : appState.currentItemFontFamily || _constants__WEBPACK_IMPORTED_MODULE_8__.DEFAULT_FONT_FAMILY),\n onChange: value => updateData(value)\n })]\n });\n }\n});\nconst actionChangeTextAlign = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"changeTextAlign\",\n trackEvent: false,\n perform: (elements, appState, value) => {\n return {\n elements: changeProperty(elements, appState, oldElement => {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(oldElement)) {\n const newElement = (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(oldElement, {\n textAlign: value\n });\n (0,_element__WEBPACK_IMPORTED_MODULE_9__.redrawTextBoundingBox)(newElement, (0,_element_textElement__WEBPACK_IMPORTED_MODULE_11__.getContainerElement)(oldElement));\n return newElement;\n }\n\n return oldElement;\n }, true),\n appState: Object.assign(Object.assign({}, appState), {\n currentItemTextAlign: value\n }),\n commitToHistory: true\n };\n },\n PanelComponent: ({\n elements,\n appState,\n updateData\n }) => {\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"fieldset\", {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"legend\", {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.textAlign\")\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_ButtonIconSelect__WEBPACK_IMPORTED_MODULE_3__.ButtonIconSelect, {\n group: \"text-align\",\n options: [{\n value: \"left\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.left\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.TextAlignLeftIcon,\n testId: \"align-left\"\n }, {\n value: \"center\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.center\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.TextAlignCenterIcon,\n testId: \"align-horizontal-center\"\n }, {\n value: \"right\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.right\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.TextAlignRightIcon,\n testId: \"align-right\"\n }],\n value: getFormValue(elements, appState, element => {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(element)) {\n return element.textAlign;\n }\n\n const boundTextElement = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_11__.getBoundTextElement)(element);\n\n if (boundTextElement) {\n return boundTextElement.textAlign;\n }\n\n return null;\n }, element => (0,_element__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(element) || (0,_element_textElement__WEBPACK_IMPORTED_MODULE_11__.getBoundTextElement)(element) !== null, hasSelection => hasSelection ? null : appState.currentItemTextAlign),\n onChange: value => updateData(value)\n })]\n });\n }\n});\nconst actionChangeVerticalAlign = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"changeVerticalAlign\",\n trackEvent: {\n category: \"element\"\n },\n perform: (elements, appState, value) => {\n return {\n elements: changeProperty(elements, appState, oldElement => {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(oldElement)) {\n const newElement = (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(oldElement, {\n verticalAlign: value\n });\n (0,_element__WEBPACK_IMPORTED_MODULE_9__.redrawTextBoundingBox)(newElement, (0,_element_textElement__WEBPACK_IMPORTED_MODULE_11__.getContainerElement)(oldElement));\n return newElement;\n }\n\n return oldElement;\n }, true),\n appState: Object.assign({}, appState),\n commitToHistory: true\n };\n },\n PanelComponent: ({\n elements,\n appState,\n updateData\n }) => {\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"fieldset\", {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_ButtonIconSelect__WEBPACK_IMPORTED_MODULE_3__.ButtonIconSelect, {\n group: \"text-align\",\n options: [{\n value: _constants__WEBPACK_IMPORTED_MODULE_8__.VERTICAL_ALIGN.TOP,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.alignTop\"),\n icon: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_icons__WEBPACK_IMPORTED_MODULE_7__.TextAlignTopIcon, {\n theme: appState.theme\n }),\n testId: \"align-top\"\n }, {\n value: _constants__WEBPACK_IMPORTED_MODULE_8__.VERTICAL_ALIGN.MIDDLE,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.centerVertically\"),\n icon: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_icons__WEBPACK_IMPORTED_MODULE_7__.TextAlignMiddleIcon, {\n theme: appState.theme\n }),\n testId: \"align-middle\"\n }, {\n value: _constants__WEBPACK_IMPORTED_MODULE_8__.VERTICAL_ALIGN.BOTTOM,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.alignBottom\"),\n icon: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_icons__WEBPACK_IMPORTED_MODULE_7__.TextAlignBottomIcon, {\n theme: appState.theme\n }),\n testId: \"align-bottom\"\n }],\n value: getFormValue(elements, appState, element => {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(element) && element.containerId) {\n return element.verticalAlign;\n }\n\n const boundTextElement = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_11__.getBoundTextElement)(element);\n\n if (boundTextElement) {\n return boundTextElement.verticalAlign;\n }\n\n return null;\n }, element => (0,_element__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(element) || (0,_element_textElement__WEBPACK_IMPORTED_MODULE_11__.getBoundTextElement)(element) !== null, hasSelection => hasSelection ? null : _constants__WEBPACK_IMPORTED_MODULE_8__.VERTICAL_ALIGN.MIDDLE),\n onChange: value => updateData(value)\n })\n });\n }\n});\nconst actionChangeRoundness = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"changeRoundness\",\n trackEvent: false,\n perform: (elements, appState, value) => {\n return {\n elements: changeProperty(elements, appState, el => (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(el, {\n roundness: value === \"round\" ? {\n type: (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_12__.isUsingAdaptiveRadius)(el.type) ? _constants__WEBPACK_IMPORTED_MODULE_8__.ROUNDNESS.ADAPTIVE_RADIUS : _constants__WEBPACK_IMPORTED_MODULE_8__.ROUNDNESS.PROPORTIONAL_RADIUS\n } : null\n })),\n appState: Object.assign(Object.assign({}, appState), {\n currentItemRoundness: value\n }),\n commitToHistory: true\n };\n },\n PanelComponent: ({\n elements,\n appState,\n updateData\n }) => {\n const targetElements = (0,_scene__WEBPACK_IMPORTED_MODULE_16__.getTargetElements)((0,_element__WEBPACK_IMPORTED_MODULE_9__.getNonDeletedElements)(elements), appState);\n const hasLegacyRoundness = targetElements.some(el => {\n var _a;\n\n return ((_a = el.roundness) === null || _a === void 0 ? void 0 : _a.type) === _constants__WEBPACK_IMPORTED_MODULE_8__.ROUNDNESS.LEGACY;\n });\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"fieldset\", {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"legend\", {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.edges\")\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_ButtonIconSelect__WEBPACK_IMPORTED_MODULE_3__.ButtonIconSelect, {\n group: \"edges\",\n options: [{\n value: \"sharp\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.sharp\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.EdgeSharpIcon\n }, {\n value: \"round\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.round\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.EdgeRoundIcon\n }],\n value: getFormValue(elements, appState, element => hasLegacyRoundness ? null : element.roundness ? \"round\" : \"sharp\", element => element.hasOwnProperty(\"roundness\"), hasSelection => hasSelection ? null : appState.currentItemRoundness),\n onChange: value => updateData(value)\n })]\n });\n }\n});\nconst actionChangeArrowhead = (0,_register__WEBPACK_IMPORTED_MODULE_19__.register)({\n name: \"changeArrowhead\",\n trackEvent: false,\n perform: (elements, appState, value) => {\n return {\n elements: changeProperty(elements, appState, el => {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_12__.isLinearElement)(el)) {\n const {\n position,\n type\n } = value;\n\n if (position === \"start\") {\n const element = (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(el, {\n startArrowhead: type\n });\n return element;\n } else if (position === \"end\") {\n const element = (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_10__.newElementWith)(el, {\n endArrowhead: type\n });\n return element;\n }\n }\n\n return el;\n }),\n appState: Object.assign(Object.assign({}, appState), {\n [value.position === \"start\" ? \"currentItemStartArrowhead\" : \"currentItemEndArrowhead\"]: value.type\n }),\n commitToHistory: true\n };\n },\n PanelComponent: ({\n elements,\n appState,\n updateData\n }) => {\n const isRTL = (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.getLanguage)().rtl;\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"fieldset\", {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"legend\", {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.arrowheads\")\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"div\", Object.assign({\n className: \"iconSelectList buttonList\"\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_IconPicker__WEBPACK_IMPORTED_MODULE_5__.IconPicker, {\n label: \"arrowhead_start\",\n options: [{\n value: null,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.arrowhead_none\"),\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.ArrowheadNoneIcon,\n keyBinding: \"q\"\n }, {\n value: \"arrow\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.arrowhead_arrow\"),\n icon: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_icons__WEBPACK_IMPORTED_MODULE_7__.ArrowheadArrowIcon, {\n flip: !isRTL\n }),\n keyBinding: \"w\"\n }, {\n value: \"bar\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.arrowhead_bar\"),\n icon: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_icons__WEBPACK_IMPORTED_MODULE_7__.ArrowheadBarIcon, {\n flip: !isRTL\n }),\n keyBinding: \"e\"\n }, {\n value: \"dot\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.arrowhead_dot\"),\n icon: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_icons__WEBPACK_IMPORTED_MODULE_7__.ArrowheadDotIcon, {\n flip: !isRTL\n }),\n keyBinding: \"r\"\n }, {\n value: \"triangle\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.arrowhead_triangle\"),\n icon: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_icons__WEBPACK_IMPORTED_MODULE_7__.ArrowheadTriangleIcon, {\n flip: !isRTL\n }),\n keyBinding: \"t\"\n }],\n value: getFormValue(elements, appState, element => (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_12__.isLinearElement)(element) && (0,_scene__WEBPACK_IMPORTED_MODULE_16__.canHaveArrowheads)(element.type) ? element.startArrowhead : appState.currentItemStartArrowhead, true, appState.currentItemStartArrowhead),\n onChange: value => updateData({\n position: \"start\",\n type: value\n })\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_IconPicker__WEBPACK_IMPORTED_MODULE_5__.IconPicker, {\n label: \"arrowhead_end\",\n group: \"arrowheads\",\n options: [{\n value: null,\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.arrowhead_none\"),\n keyBinding: \"q\",\n icon: _components_icons__WEBPACK_IMPORTED_MODULE_7__.ArrowheadNoneIcon\n }, {\n value: \"arrow\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.arrowhead_arrow\"),\n keyBinding: \"w\",\n icon: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_icons__WEBPACK_IMPORTED_MODULE_7__.ArrowheadArrowIcon, {\n flip: isRTL\n })\n }, {\n value: \"bar\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.arrowhead_bar\"),\n keyBinding: \"e\",\n icon: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_icons__WEBPACK_IMPORTED_MODULE_7__.ArrowheadBarIcon, {\n flip: isRTL\n })\n }, {\n value: \"dot\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.arrowhead_dot\"),\n keyBinding: \"r\",\n icon: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_icons__WEBPACK_IMPORTED_MODULE_7__.ArrowheadDotIcon, {\n flip: isRTL\n })\n }, {\n value: \"triangle\",\n text: (0,_i18n__WEBPACK_IMPORTED_MODULE_13__.t)(\"labels.arrowhead_triangle\"),\n icon: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_components_icons__WEBPACK_IMPORTED_MODULE_7__.ArrowheadTriangleIcon, {\n flip: isRTL\n }),\n keyBinding: \"t\"\n }],\n value: getFormValue(elements, appState, element => (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_12__.isLinearElement)(element) && (0,_scene__WEBPACK_IMPORTED_MODULE_16__.canHaveArrowheads)(element.type) ? element.endArrowhead : appState.currentItemEndArrowhead, true, appState.currentItemEndArrowhead),\n onChange: value => updateData({\n position: \"end\",\n type: value\n })\n })]\n }))]\n });\n }\n});\n\n//# sourceURL=webpack://ExcalidrawLib/../../actions/actionProperties.tsx?");
2065
2065
 
2066
2066
  /***/ }),
2067
2067
 
@@ -2215,7 +2215,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
2215
2215
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2216
2216
 
2217
2217
  "use strict";
2218
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"trackEvent\": () => (/* binding */ trackEvent)\n/* harmony export */ });\nconst trackEvent = (category, action, label, value) => {\n try {\n // place here categories that you want to track as events\n // KEEP IN MIND THE PRICING\n const ALLOWED_CATEGORIES_TO_TRACK = []; // Uncomment the next line to track locally\n // console.log(\"Track Event\", { category, action, label, value });\n\n if (typeof window === \"undefined\" || ({\"VITE_APP_BACKEND_V2_GET_URL\":\"https://json-dev.excalidraw.com/api/v2/\",\"VITE_APP_BACKEND_V2_POST_URL\":\"https://json-dev.excalidraw.com/api/v2/post/\",\"VITE_APP_LIBRARY_URL\":\"https://libraries.excalidraw.com\",\"VITE_APP_LIBRARY_BACKEND\":\"https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries\",\"VITE_APP_WS_SERVER_URL\":\"http://localhost:3002\",\"VITE_APP_PORTAL_URL\":\"\",\"VITE_APP_PLUS_LP\":\"https://plus.excalidraw.com\",\"VITE_APP_PLUS_APP\":\"https://app.excalidraw.com\",\"VITE_APP_FIREBASE_CONFIG\":\"{\\\"apiKey\\\":\\\"AIzaSyCMkxA60XIW8KbqMYL7edC4qT5l4qHX2h8\\\",\\\"authDomain\\\":\\\"excalidraw-oss-dev.firebaseapp.com\\\",\\\"projectId\\\":\\\"excalidraw-oss-dev\\\",\\\"storageBucket\\\":\\\"excalidraw-oss-dev.appspot.com\\\",\\\"messagingSenderId\\\":\\\"664559512677\\\",\\\"appId\\\":\\\"1:664559512677:web:a385181f2928d328a7aa8c\\\"}\",\"VITE_APP_DEV_ENABLE_SW\":\"\",\"VITE_APP_DEV_DISABLE_LIVE_RELOAD\":\"\",\"VITE_APP_DISABLE_TRACKING\":\"true\",\"FAST_REFRESH\":\"false\",\"VITE_APP_PORT\":\"3000\",\"VITE_APP_DEBUG_ENABLE_TEXT_CONTAINER_BOUNDING_BOX\":\"\",\"VITE_APP_COLLAPSE_OVERLAY\":\"true\",\"VITE_APP_ENABLE_ESLINT\":\"true\",\"VITE_PKG_NAME\":\"@zsviczian/excalidraw\",\"VITE_PKG_VERSION\":\"0.16.1-obsidian-4\",\"VITE_IS_EXCALIDRAW_NPM_PACKAGE\":true}).VITE_WORKER_ID) {\n return;\n }\n\n if (!ALLOWED_CATEGORIES_TO_TRACK.includes(category)) {\n return;\n }\n\n if (window.sa_event) {\n window.sa_event(action, {\n category,\n label,\n value\n });\n }\n } catch (error) {\n console.error(\"error during analytics\", error);\n }\n};\n\n//# sourceURL=webpack://ExcalidrawLib/../../analytics.ts?");
2218
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"trackEvent\": () => (/* binding */ trackEvent)\n/* harmony export */ });\nconst trackEvent = (category, action, label, value) => {\n try {\n // place here categories that you want to track as events\n // KEEP IN MIND THE PRICING\n const ALLOWED_CATEGORIES_TO_TRACK = []; // Uncomment the next line to track locally\n // console.log(\"Track Event\", { category, action, label, value });\n\n if (typeof window === \"undefined\" || ({\"VITE_APP_BACKEND_V2_GET_URL\":\"https://json-dev.excalidraw.com/api/v2/\",\"VITE_APP_BACKEND_V2_POST_URL\":\"https://json-dev.excalidraw.com/api/v2/post/\",\"VITE_APP_LIBRARY_URL\":\"https://libraries.excalidraw.com\",\"VITE_APP_LIBRARY_BACKEND\":\"https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries\",\"VITE_APP_WS_SERVER_URL\":\"http://localhost:3002\",\"VITE_APP_PORTAL_URL\":\"\",\"VITE_APP_PLUS_LP\":\"https://plus.excalidraw.com\",\"VITE_APP_PLUS_APP\":\"https://app.excalidraw.com\",\"VITE_APP_FIREBASE_CONFIG\":\"{\\\"apiKey\\\":\\\"AIzaSyCMkxA60XIW8KbqMYL7edC4qT5l4qHX2h8\\\",\\\"authDomain\\\":\\\"excalidraw-oss-dev.firebaseapp.com\\\",\\\"projectId\\\":\\\"excalidraw-oss-dev\\\",\\\"storageBucket\\\":\\\"excalidraw-oss-dev.appspot.com\\\",\\\"messagingSenderId\\\":\\\"664559512677\\\",\\\"appId\\\":\\\"1:664559512677:web:a385181f2928d328a7aa8c\\\"}\",\"VITE_APP_DEV_ENABLE_SW\":\"\",\"VITE_APP_DEV_DISABLE_LIVE_RELOAD\":\"\",\"VITE_APP_DISABLE_TRACKING\":\"true\",\"FAST_REFRESH\":\"false\",\"VITE_APP_PORT\":\"3000\",\"VITE_APP_DEBUG_ENABLE_TEXT_CONTAINER_BOUNDING_BOX\":\"\",\"VITE_APP_COLLAPSE_OVERLAY\":\"true\",\"VITE_APP_ENABLE_ESLINT\":\"true\",\"VITE_PKG_NAME\":\"@zsviczian/excalidraw\",\"VITE_PKG_VERSION\":\"0.16.1-obsidian-5\",\"VITE_IS_EXCALIDRAW_NPM_PACKAGE\":true}).VITE_WORKER_ID) {\n return;\n }\n\n if (!ALLOWED_CATEGORIES_TO_TRACK.includes(category)) {\n return;\n }\n\n if (window.sa_event) {\n window.sa_event(action, {\n category,\n label,\n value\n });\n }\n } catch (error) {\n console.error(\"error during analytics\", error);\n }\n};\n\n//# sourceURL=webpack://ExcalidrawLib/../../analytics.ts?");
2219
2219
 
2220
2220
  /***/ }),
2221
2221
 
@@ -2281,7 +2281,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
2281
2281
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2282
2282
 
2283
2283
  "use strict";
2284
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"ExitZenModeAction\": () => (/* binding */ ExitZenModeAction),\n/* harmony export */ \"FinalizeAction\": () => (/* binding */ FinalizeAction),\n/* harmony export */ \"SelectedShapeActions\": () => (/* binding */ SelectedShapeActions),\n/* harmony export */ \"ShapesSwitcher\": () => (/* binding */ ShapesSwitcher),\n/* harmony export */ \"UndoRedoActions\": () => (/* binding */ UndoRedoActions),\n/* harmony export */ \"ZoomActions\": () => (/* binding */ ZoomActions)\n/* harmony export */ });\n/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react/jsx-runtime */ \"../../../node_modules/react/jsx-runtime.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ \"react\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _element__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../element */ \"../../element/index.ts\");\n/* harmony import */ var _i18n__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../i18n */ \"../../i18n.ts\");\n/* harmony import */ var _components_App__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../components/App */ \"../../components/App.tsx\");\n/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../scene */ \"../../scene/index.ts\");\n/* harmony import */ var _shapes__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../shapes */ \"../../shapes.tsx\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _Stack__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./Stack */ \"../../components/Stack.tsx\");\n/* harmony import */ var _ToolButton__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./ToolButton */ \"../../components/ToolButton.tsx\");\n/* harmony import */ var _scene_comparisons__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../scene/comparisons */ \"../../scene/comparisons.ts\");\n/* harmony import */ var _analytics__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../analytics */ \"../../analytics.ts\");\n/* harmony import */ var _element_typeChecks__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../element/typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var clsx__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! clsx */ \"../../../node_modules/clsx/dist/clsx.m.js\");\n/* harmony import */ var _actions__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../actions */ \"../../actions/index.ts\");\n/* harmony import */ var _element_textElement__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../element/textElement */ \"../../element/textElement.ts\");\n/* harmony import */ var _Actions_scss__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./Actions.scss */ \"../../components/Actions.scss\");\n/* harmony import */ var _dropdownMenu_DropdownMenu__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./dropdownMenu/DropdownMenu */ \"../../components/dropdownMenu/DropdownMenu.tsx\");\n/* harmony import */ var _icons__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./icons */ \"../../components/icons.tsx\");\n/* harmony import */ var _keys__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../keys */ \"../../keys.ts\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n // import { Tooltip } from \"./Tooltip\"; //zsviczian\n\n\n\n\n\n\nconst SelectedShapeActions = ({\n appState,\n elements,\n renderAction\n}) => {\n var _a;\n\n const targetElements = (0,_scene__WEBPACK_IMPORTED_MODULE_5__.getTargetElements)((0,_element__WEBPACK_IMPORTED_MODULE_2__.getNonDeletedElements)(elements), appState);\n let isSingleElementBoundContainer = false;\n\n if (targetElements.length === 2 && ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_12__.hasBoundTextElement)(targetElements[0]) || (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_12__.hasBoundTextElement)(targetElements[1]))) {\n isSingleElementBoundContainer = true;\n }\n\n const isEditing = Boolean(appState.editingElement);\n const device = (0,_components_App__WEBPACK_IMPORTED_MODULE_4__.useDevice)();\n const isRTL = document.documentElement.getAttribute(\"dir\") === \"rtl\";\n const showFillIcons = (0,_scene__WEBPACK_IMPORTED_MODULE_5__.hasBackground)(appState.activeTool.type) || targetElements.some(element => (0,_scene__WEBPACK_IMPORTED_MODULE_5__.hasBackground)(element.type) && !(0,_utils__WEBPACK_IMPORTED_MODULE_7__.isTransparent)(element.backgroundColor));\n const showChangeBackgroundIcons = (0,_scene__WEBPACK_IMPORTED_MODULE_5__.hasBackground)(appState.activeTool.type) || targetElements.some(element => (0,_scene__WEBPACK_IMPORTED_MODULE_5__.hasBackground)(element.type));\n const showLinkIcon = targetElements.length === 1 || isSingleElementBoundContainer;\n let commonSelectedType = ((_a = targetElements[0]) === null || _a === void 0 ? void 0 : _a.type) || null;\n\n for (const element of targetElements) {\n if (element.type !== commonSelectedType) {\n commonSelectedType = null;\n break;\n }\n }\n\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"div\", Object.assign({\n className: \"panelColumn\"\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", {\n children: ((0,_scene_comparisons__WEBPACK_IMPORTED_MODULE_10__.hasStrokeColor)(appState.activeTool.type) && appState.activeTool.type !== \"image\" && commonSelectedType !== \"image\" && commonSelectedType !== \"frame\" || targetElements.some(element => (0,_scene_comparisons__WEBPACK_IMPORTED_MODULE_10__.hasStrokeColor)(element.type))) && renderAction(\"changeStrokeColor\")\n }), showChangeBackgroundIcons && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", {\n children: renderAction(\"changeBackgroundColor\")\n }), showFillIcons && renderAction(\"changeFillStyle\"), ((0,_scene__WEBPACK_IMPORTED_MODULE_5__.hasStrokeWidth)(appState.activeTool.type) || targetElements.some(element => (0,_scene__WEBPACK_IMPORTED_MODULE_5__.hasStrokeWidth)(element.type))) && renderAction(\"changeStrokeWidth\"), (appState.activeTool.type === \"freedraw\" || targetElements.some(element => element.type === \"freedraw\")) && renderAction(\"changeStrokeShape\"), ((0,_scene__WEBPACK_IMPORTED_MODULE_5__.hasStrokeStyle)(appState.activeTool.type) || targetElements.some(element => (0,_scene__WEBPACK_IMPORTED_MODULE_5__.hasStrokeStyle)(element.type))) && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n children: [renderAction(\"changeStrokeStyle\"), renderAction(\"changeSloppiness\")]\n }), ((0,_scene__WEBPACK_IMPORTED_MODULE_5__.canChangeRoundness)(appState.activeTool.type) || targetElements.some(element => (0,_scene__WEBPACK_IMPORTED_MODULE_5__.canChangeRoundness)(element.type))) && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n children: renderAction(\"changeRoundness\")\n }), ((0,_scene__WEBPACK_IMPORTED_MODULE_5__.hasText)(appState.activeTool.type) || targetElements.some(element => (0,_scene__WEBPACK_IMPORTED_MODULE_5__.hasText)(element.type))) && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n children: [renderAction(\"changeFontSize\"), renderAction(\"changeFontFamily\"), (0,_element_textElement__WEBPACK_IMPORTED_MODULE_15__.suppportsHorizontalAlign)(targetElements) && renderAction(\"changeTextAlign\")]\n }), (0,_element_textElement__WEBPACK_IMPORTED_MODULE_15__.shouldAllowVerticalAlign)(targetElements) && renderAction(\"changeVerticalAlign\"), ((0,_scene__WEBPACK_IMPORTED_MODULE_5__.canHaveArrowheads)(appState.activeTool.type) || targetElements.some(element => (0,_scene__WEBPACK_IMPORTED_MODULE_5__.canHaveArrowheads)(element.type))) && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n children: renderAction(\"changeArrowhead\")\n }), renderAction(\"changeOpacity\"), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"fieldset\", {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"legend\", {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"labels.layers\")\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"div\", Object.assign({\n className: \"buttonList\"\n }, {\n children: [renderAction(\"sendToBack\"), renderAction(\"sendBackward\"), renderAction(\"bringToFront\"), renderAction(\"bringForward\")]\n }))]\n }), targetElements.length > 1 && !isSingleElementBoundContainer && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"fieldset\", {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"legend\", {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"labels.align\")\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"div\", Object.assign({\n className: \"buttonList\"\n }, {\n children: [isRTL ? (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n children: [renderAction(\"alignRight\"), renderAction(\"alignHorizontallyCentered\"), renderAction(\"alignLeft\")]\n }) : (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n children: [renderAction(\"alignLeft\"), renderAction(\"alignHorizontallyCentered\"), renderAction(\"alignRight\")]\n }), targetElements.length > 2 && renderAction(\"distributeHorizontally\"), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", {\n style: {\n flexBasis: \"100%\",\n height: 0\n }\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"div\", Object.assign({\n style: {\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: \".5rem\",\n marginTop: \"-0.5rem\"\n }\n }, {\n children: [renderAction(\"alignTop\"), renderAction(\"alignVerticallyCentered\"), renderAction(\"alignBottom\"), targetElements.length > 2 && renderAction(\"distributeVertically\")]\n }))]\n }))]\n }), !isEditing && targetElements.length > 0 && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"fieldset\", {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"legend\", {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"labels.actions\")\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"div\", Object.assign({\n className: \"buttonList\"\n }, {\n children: [!device.isMobile && renderAction(\"duplicateSelection\"), !device.isMobile && renderAction(\"deleteSelectedElements\"), renderAction(\"group\"), renderAction(\"ungroup\"), showLinkIcon && renderAction(\"hyperlink\")]\n }))]\n })]\n }));\n};\nconst ShapesSwitcher = ({\n activeTool,\n appState,\n app\n}) => {\n const {\n renderMermaid\n } = (0,_components_App__WEBPACK_IMPORTED_MODULE_4__.useAppProps)(); //zsviczian\n\n const [isExtraToolsMenuOpen, setIsExtraToolsMenuOpen] = (0,react__WEBPACK_IMPORTED_MODULE_1__.useState)(false);\n const device = (0,_components_App__WEBPACK_IMPORTED_MODULE_4__.useDevice)();\n const frameToolSelected = activeTool.type === \"frame\";\n const laserToolSelected = activeTool.type === \"laser\";\n const embeddableToolSelected = activeTool.type === \"embeddable\";\n const mermaidToolSelected = activeTool.type === \"mermaid\";\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n children: [_shapes__WEBPACK_IMPORTED_MODULE_6__.SHAPES.map(({\n value,\n icon,\n key,\n numericKey,\n fillable\n }, index) => {\n const label = (0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(`toolBar.${value}`);\n const letter = key && (0,_utils__WEBPACK_IMPORTED_MODULE_7__.capitalizeString)(typeof key === \"string\" ? key : key[0]);\n const shortcut = letter ? `${letter} ${(0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"helpDialog.or\")} ${numericKey}` : `${numericKey}`;\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_ToolButton__WEBPACK_IMPORTED_MODULE_9__.ToolButton, {\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_13__[\"default\"])(\"Shape\", {\n fillable\n }),\n type: \"radio\",\n icon: icon,\n checked: activeTool.type === value,\n name: \"editor-current-shape\",\n title: `${(0,_utils__WEBPACK_IMPORTED_MODULE_7__.capitalizeString)(label)} — ${shortcut}`,\n keyBindingLabel: numericKey || letter,\n \"aria-label\": (0,_utils__WEBPACK_IMPORTED_MODULE_7__.capitalizeString)(label),\n \"aria-keyshortcuts\": shortcut,\n \"data-testid\": `toolbar-${value}`,\n onPointerDown: ({\n pointerType\n }) => {\n if (!appState.penDetected && pointerType === \"pen\") {\n app.togglePenMode(true);\n }\n },\n onChange: ({\n pointerType\n }) => {\n if (appState.activeTool.type !== value) {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_11__.trackEvent)(\"toolbar\", value, \"ui\");\n }\n\n if (value === \"image\") {\n app.setActiveTool({\n type: value,\n insertOnCanvasDirectly: pointerType !== \"mouse\"\n });\n } else {\n app.setActiveTool({\n type: value\n });\n }\n }\n }, value);\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", {\n className: \"App-toolbar__divider\"\n }), device.isMobile ? (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_ToolButton__WEBPACK_IMPORTED_MODULE_9__.ToolButton, {\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_13__[\"default\"])(\"Shape\", {\n fillable: false\n }),\n type: \"radio\",\n icon: _icons__WEBPACK_IMPORTED_MODULE_18__.frameToolIcon,\n checked: activeTool.type === \"frame\",\n name: \"editor-current-shape\",\n title: `${(0,_utils__WEBPACK_IMPORTED_MODULE_7__.capitalizeString)((0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"toolBar.frame\"))} — ${_keys__WEBPACK_IMPORTED_MODULE_19__.KEYS.F.toLocaleUpperCase()}`,\n keyBindingLabel: _keys__WEBPACK_IMPORTED_MODULE_19__.KEYS.F.toLocaleUpperCase(),\n \"aria-label\": (0,_utils__WEBPACK_IMPORTED_MODULE_7__.capitalizeString)((0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"toolBar.frame\")),\n \"aria-keyshortcuts\": _keys__WEBPACK_IMPORTED_MODULE_19__.KEYS.F.toLocaleUpperCase(),\n \"data-testid\": `toolbar-frame`,\n onPointerDown: ({\n pointerType\n }) => {\n if (!appState.penDetected && pointerType === \"pen\") {\n app.togglePenMode(true);\n }\n },\n onChange: ({\n pointerType\n }) => {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_11__.trackEvent)(\"toolbar\", \"frame\", \"ui\");\n app.setActiveTool({\n type: \"frame\"\n });\n },\n selected: activeTool.type === \"frame\"\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_ToolButton__WEBPACK_IMPORTED_MODULE_9__.ToolButton, {\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_13__[\"default\"])(\"Shape\", {\n fillable: false\n }),\n type: \"radio\",\n icon: _icons__WEBPACK_IMPORTED_MODULE_18__.EmbedIcon,\n checked: activeTool.type === \"embeddable\",\n name: \"editor-current-shape\",\n title: (0,_utils__WEBPACK_IMPORTED_MODULE_7__.capitalizeString)((0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"toolBar.embeddable\")),\n \"aria-label\": (0,_utils__WEBPACK_IMPORTED_MODULE_7__.capitalizeString)((0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"toolBar.embeddable\")),\n \"data-testid\": `toolbar-embeddable`,\n onPointerDown: ({\n pointerType\n }) => {\n if (!appState.penDetected && pointerType === \"pen\") {\n app.togglePenMode(true);\n }\n },\n onChange: ({\n pointerType\n }) => {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_11__.trackEvent)(\"toolbar\", \"embeddable\", \"ui\");\n app.setActiveTool({\n type: \"embeddable\"\n });\n },\n selected: activeTool.type === \"embeddable\"\n }), renderMermaid && //zsviczian\n (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_ToolButton__WEBPACK_IMPORTED_MODULE_9__.ToolButton, {\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_13__[\"default\"])(\"Shape\", {\n fillable: false\n }),\n type: \"radio\",\n icon: _icons__WEBPACK_IMPORTED_MODULE_18__.mermaidLogoIcon,\n checked: activeTool.type === \"mermaid\",\n name: \"editor-current-shape\",\n title: (0,_utils__WEBPACK_IMPORTED_MODULE_7__.capitalizeString)((0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"toolBar.mermaidToExcalidraw\")),\n \"aria-label\": (0,_utils__WEBPACK_IMPORTED_MODULE_7__.capitalizeString)((0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"toolBar.mermaidToExcalidraw\")),\n \"data-testid\": `toolbar-mermaidToExcalidraw`,\n onPointerDown: ({\n pointerType\n }) => {\n if (!appState.penDetected && pointerType === \"pen\") {\n app.togglePenMode(true);\n }\n },\n onChange: ({\n pointerType\n }) => {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_11__.trackEvent)(\"toolbar\", \"mermaid\", \"ui\");\n app.setActiveTool({\n type: \"mermaid\"\n });\n },\n selected: activeTool.type === \"mermaid\"\n })]\n }) : (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(_dropdownMenu_DropdownMenu__WEBPACK_IMPORTED_MODULE_17__[\"default\"], Object.assign({\n open: isExtraToolsMenuOpen\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_dropdownMenu_DropdownMenu__WEBPACK_IMPORTED_MODULE_17__[\"default\"].Trigger, Object.assign({\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_13__[\"default\"])(\"App-toolbar__extra-tools-trigger\", {\n \"App-toolbar__extra-tools-trigger--selected\": frameToolSelected || embeddableToolSelected || // in collab we're already highlighting the laser button\n // outside toolbar, so let's not highlight extra-tools button\n // on top of it\n laserToolSelected && !app.props.isCollaborating\n }),\n onToggle: () => setIsExtraToolsMenuOpen(!isExtraToolsMenuOpen),\n title: (0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"toolBar.extraTools\")\n }, {\n children: _icons__WEBPACK_IMPORTED_MODULE_18__.extraToolsIcon\n })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(_dropdownMenu_DropdownMenu__WEBPACK_IMPORTED_MODULE_17__[\"default\"].Content, Object.assign({\n onClickOutside: () => setIsExtraToolsMenuOpen(false),\n onSelect: () => setIsExtraToolsMenuOpen(false),\n className: \"App-toolbar__extra-tools-dropdown\"\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_dropdownMenu_DropdownMenu__WEBPACK_IMPORTED_MODULE_17__[\"default\"].Item, Object.assign({\n onSelect: () => {\n app.setActiveTool({\n type: \"frame\"\n });\n },\n icon: _icons__WEBPACK_IMPORTED_MODULE_18__.frameToolIcon,\n shortcut: _keys__WEBPACK_IMPORTED_MODULE_19__.KEYS.F.toLocaleUpperCase(),\n \"data-testid\": \"toolbar-frame\",\n selected: frameToolSelected\n }, {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"toolBar.frame\")\n })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_dropdownMenu_DropdownMenu__WEBPACK_IMPORTED_MODULE_17__[\"default\"].Item, Object.assign({\n onSelect: () => {\n app.setActiveTool({\n type: \"embeddable\"\n });\n },\n icon: _icons__WEBPACK_IMPORTED_MODULE_18__.EmbedIcon,\n \"data-testid\": \"toolbar-embeddable\",\n selected: embeddableToolSelected\n }, {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"toolBar.embeddable\")\n })), renderMermaid && //zsviczian\n (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_dropdownMenu_DropdownMenu__WEBPACK_IMPORTED_MODULE_17__[\"default\"].Item, Object.assign({\n onSelect: () => {\n app.setActiveTool({\n type: \"mermaid\"\n });\n },\n icon: _icons__WEBPACK_IMPORTED_MODULE_18__.mermaidLogoIcon,\n \"data-testid\": \"toolbar-mermaidToExcalidraw\",\n selected: mermaidToolSelected\n }, {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"toolBar.mermaidToExcalidraw\")\n })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_dropdownMenu_DropdownMenu__WEBPACK_IMPORTED_MODULE_17__[\"default\"].Item, Object.assign({\n onSelect: () => {\n app.setActiveTool({\n type: \"laser\"\n });\n },\n icon: _icons__WEBPACK_IMPORTED_MODULE_18__.laserPointerToolIcon,\n \"data-testid\": \"toolbar-laser\",\n selected: laserToolSelected,\n shortcut: _keys__WEBPACK_IMPORTED_MODULE_19__.KEYS.K.toLocaleUpperCase()\n }, {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"toolBar.laser\")\n }))]\n }))]\n }))]\n });\n};\nconst ZoomActions = ({\n renderAction,\n zoom,\n trayMode = false //zsviczian\n\n}) => (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Stack__WEBPACK_IMPORTED_MODULE_8__[\"default\"].Col, Object.assign({\n gap: 1,\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_13__[\"default\"])(\"zoom-actions\", {\n \"tray-zoom\": trayMode\n })\n}, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(_Stack__WEBPACK_IMPORTED_MODULE_8__[\"default\"].Row, Object.assign({\n align: \"center\"\n }, {\n children: [renderAction(\"zoomOut\"), renderAction(\"resetZoom\"), renderAction(\"zoomIn\")]\n }))\n}));\nconst UndoRedoActions = ({\n renderAction,\n className\n}) => (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"div\", Object.assign({\n className: `undo-redo-buttons ${className}`\n}, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", Object.assign({\n className: \"undo-button-container\"\n }, {\n children: renderAction(\"undo\")\n /* //zsviczian */\n\n })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", Object.assign({\n className: \"redo-button-container\"\n }, {\n children: renderAction(\"redo\")\n /* //zsviczian */\n\n }))]\n}));\nconst ExitZenModeAction = ({\n actionManager,\n showExitZenModeBtn\n}) => (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"button\", Object.assign({\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_13__[\"default\"])(\"disable-zen-mode\", {\n \"disable-zen-mode--visible\": showExitZenModeBtn\n }),\n onClick: () => actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_14__.actionToggleZenMode)\n}, {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"buttons.exitZenMode\")\n}));\nconst FinalizeAction = ({\n renderAction,\n className\n}) => (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", Object.assign({\n className: `finalize-button ${className}`\n}, {\n children: renderAction(\"finalize\", {\n size: \"small\"\n })\n}));\n\n//# sourceURL=webpack://ExcalidrawLib/../../components/Actions.tsx?");
2284
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"ExitZenModeAction\": () => (/* binding */ ExitZenModeAction),\n/* harmony export */ \"FinalizeAction\": () => (/* binding */ FinalizeAction),\n/* harmony export */ \"SelectedShapeActions\": () => (/* binding */ SelectedShapeActions),\n/* harmony export */ \"ShapesSwitcher\": () => (/* binding */ ShapesSwitcher),\n/* harmony export */ \"UndoRedoActions\": () => (/* binding */ UndoRedoActions),\n/* harmony export */ \"ZoomActions\": () => (/* binding */ ZoomActions)\n/* harmony export */ });\n/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react/jsx-runtime */ \"../../../node_modules/react/jsx-runtime.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ \"react\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _element__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../element */ \"../../element/index.ts\");\n/* harmony import */ var _i18n__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../i18n */ \"../../i18n.ts\");\n/* harmony import */ var _components_App__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../components/App */ \"../../components/App.tsx\");\n/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../scene */ \"../../scene/index.ts\");\n/* harmony import */ var _shapes__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../shapes */ \"../../shapes.tsx\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _Stack__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./Stack */ \"../../components/Stack.tsx\");\n/* harmony import */ var _ToolButton__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./ToolButton */ \"../../components/ToolButton.tsx\");\n/* harmony import */ var _scene_comparisons__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../scene/comparisons */ \"../../scene/comparisons.ts\");\n/* harmony import */ var _analytics__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../analytics */ \"../../analytics.ts\");\n/* harmony import */ var _element_typeChecks__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../element/typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var clsx__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! clsx */ \"../../../node_modules/clsx/dist/clsx.m.js\");\n/* harmony import */ var _actions__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../actions */ \"../../actions/index.ts\");\n/* harmony import */ var _element_textElement__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../element/textElement */ \"../../element/textElement.ts\");\n/* harmony import */ var _Actions_scss__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./Actions.scss */ \"../../components/Actions.scss\");\n/* harmony import */ var _dropdownMenu_DropdownMenu__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./dropdownMenu/DropdownMenu */ \"../../components/dropdownMenu/DropdownMenu.tsx\");\n/* harmony import */ var _icons__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./icons */ \"../../components/icons.tsx\");\n/* harmony import */ var _keys__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../keys */ \"../../keys.ts\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n // import { Tooltip } from \"./Tooltip\"; //zsviczian\n\n\n\n\n\n\nconst SelectedShapeActions = ({\n appState,\n elements,\n renderAction\n}) => {\n var _a;\n\n const targetElements = (0,_scene__WEBPACK_IMPORTED_MODULE_5__.getTargetElements)((0,_element__WEBPACK_IMPORTED_MODULE_2__.getNonDeletedElements)(elements), appState);\n let isSingleElementBoundContainer = false;\n\n if (targetElements.length === 2 && ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_12__.hasBoundTextElement)(targetElements[0]) || (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_12__.hasBoundTextElement)(targetElements[1]))) {\n isSingleElementBoundContainer = true;\n }\n\n const isEditing = Boolean(appState.editingElement);\n const device = (0,_components_App__WEBPACK_IMPORTED_MODULE_4__.useDevice)();\n const isRTL = document.documentElement.getAttribute(\"dir\") === \"rtl\";\n const showFillIcons = (0,_scene__WEBPACK_IMPORTED_MODULE_5__.hasBackground)(appState.activeTool.type) && !(0,_utils__WEBPACK_IMPORTED_MODULE_7__.isTransparent)(appState.currentItemBackgroundColor) || targetElements.some(element => (0,_scene__WEBPACK_IMPORTED_MODULE_5__.hasBackground)(element.type) && !(0,_utils__WEBPACK_IMPORTED_MODULE_7__.isTransparent)(element.backgroundColor));\n const showChangeBackgroundIcons = (0,_scene__WEBPACK_IMPORTED_MODULE_5__.hasBackground)(appState.activeTool.type) || targetElements.some(element => (0,_scene__WEBPACK_IMPORTED_MODULE_5__.hasBackground)(element.type));\n const showLinkIcon = targetElements.length === 1 || isSingleElementBoundContainer;\n let commonSelectedType = ((_a = targetElements[0]) === null || _a === void 0 ? void 0 : _a.type) || null;\n\n for (const element of targetElements) {\n if (element.type !== commonSelectedType) {\n commonSelectedType = null;\n break;\n }\n }\n\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"div\", Object.assign({\n className: \"panelColumn\"\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", {\n children: ((0,_scene_comparisons__WEBPACK_IMPORTED_MODULE_10__.hasStrokeColor)(appState.activeTool.type) && appState.activeTool.type !== \"image\" && commonSelectedType !== \"image\" && commonSelectedType !== \"frame\" || targetElements.some(element => (0,_scene_comparisons__WEBPACK_IMPORTED_MODULE_10__.hasStrokeColor)(element.type))) && renderAction(\"changeStrokeColor\")\n }), showChangeBackgroundIcons && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", {\n children: renderAction(\"changeBackgroundColor\")\n }), showFillIcons && renderAction(\"changeFillStyle\"), ((0,_scene__WEBPACK_IMPORTED_MODULE_5__.hasStrokeWidth)(appState.activeTool.type) || targetElements.some(element => (0,_scene__WEBPACK_IMPORTED_MODULE_5__.hasStrokeWidth)(element.type))) && renderAction(\"changeStrokeWidth\"), (appState.activeTool.type === \"freedraw\" || targetElements.some(element => element.type === \"freedraw\")) && renderAction(\"changeStrokeShape\"), ((0,_scene__WEBPACK_IMPORTED_MODULE_5__.hasStrokeStyle)(appState.activeTool.type) || targetElements.some(element => (0,_scene__WEBPACK_IMPORTED_MODULE_5__.hasStrokeStyle)(element.type))) && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n children: [renderAction(\"changeStrokeStyle\"), renderAction(\"changeSloppiness\")]\n }), ((0,_scene__WEBPACK_IMPORTED_MODULE_5__.canChangeRoundness)(appState.activeTool.type) || targetElements.some(element => (0,_scene__WEBPACK_IMPORTED_MODULE_5__.canChangeRoundness)(element.type))) && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n children: renderAction(\"changeRoundness\")\n }), (appState.activeTool.type === \"text\" || targetElements.some(_element_typeChecks__WEBPACK_IMPORTED_MODULE_12__.isTextElement)) && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n children: [renderAction(\"changeFontSize\"), renderAction(\"changeFontFamily\"), (appState.activeTool.type === \"text\" || (0,_element_textElement__WEBPACK_IMPORTED_MODULE_15__.suppportsHorizontalAlign)(targetElements)) && renderAction(\"changeTextAlign\")]\n }), (0,_element_textElement__WEBPACK_IMPORTED_MODULE_15__.shouldAllowVerticalAlign)(targetElements) && renderAction(\"changeVerticalAlign\"), ((0,_scene__WEBPACK_IMPORTED_MODULE_5__.canHaveArrowheads)(appState.activeTool.type) || targetElements.some(element => (0,_scene__WEBPACK_IMPORTED_MODULE_5__.canHaveArrowheads)(element.type))) && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n children: renderAction(\"changeArrowhead\")\n }), renderAction(\"changeOpacity\"), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"fieldset\", {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"legend\", {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"labels.layers\")\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"div\", Object.assign({\n className: \"buttonList\"\n }, {\n children: [renderAction(\"sendToBack\"), renderAction(\"sendBackward\"), renderAction(\"bringToFront\"), renderAction(\"bringForward\")]\n }))]\n }), targetElements.length > 1 && !isSingleElementBoundContainer && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"fieldset\", {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"legend\", {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"labels.align\")\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"div\", Object.assign({\n className: \"buttonList\"\n }, {\n children: [isRTL ? (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n children: [renderAction(\"alignRight\"), renderAction(\"alignHorizontallyCentered\"), renderAction(\"alignLeft\")]\n }) : (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n children: [renderAction(\"alignLeft\"), renderAction(\"alignHorizontallyCentered\"), renderAction(\"alignRight\")]\n }), targetElements.length > 2 && renderAction(\"distributeHorizontally\"), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", {\n style: {\n flexBasis: \"100%\",\n height: 0\n }\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"div\", Object.assign({\n style: {\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: \".5rem\",\n marginTop: \"-0.5rem\"\n }\n }, {\n children: [renderAction(\"alignTop\"), renderAction(\"alignVerticallyCentered\"), renderAction(\"alignBottom\"), targetElements.length > 2 && renderAction(\"distributeVertically\")]\n }))]\n }))]\n }), !isEditing && targetElements.length > 0 && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"fieldset\", {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"legend\", {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"labels.actions\")\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"div\", Object.assign({\n className: \"buttonList\"\n }, {\n children: [!device.isMobile && renderAction(\"duplicateSelection\"), !device.isMobile && renderAction(\"deleteSelectedElements\"), renderAction(\"group\"), renderAction(\"ungroup\"), showLinkIcon && renderAction(\"hyperlink\")]\n }))]\n })]\n }));\n};\nconst ShapesSwitcher = ({\n activeTool,\n appState,\n app\n}) => {\n const {\n renderMermaid\n } = (0,_components_App__WEBPACK_IMPORTED_MODULE_4__.useAppProps)(); //zsviczian\n\n const [isExtraToolsMenuOpen, setIsExtraToolsMenuOpen] = (0,react__WEBPACK_IMPORTED_MODULE_1__.useState)(false);\n const device = (0,_components_App__WEBPACK_IMPORTED_MODULE_4__.useDevice)();\n const frameToolSelected = activeTool.type === \"frame\";\n const laserToolSelected = activeTool.type === \"laser\";\n const embeddableToolSelected = activeTool.type === \"embeddable\";\n const mermaidToolSelected = activeTool.type === \"mermaid\";\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n children: [_shapes__WEBPACK_IMPORTED_MODULE_6__.SHAPES.map(({\n value,\n icon,\n key,\n numericKey,\n fillable\n }, index) => {\n const label = (0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(`toolBar.${value}`);\n const letter = key && (0,_utils__WEBPACK_IMPORTED_MODULE_7__.capitalizeString)(typeof key === \"string\" ? key : key[0]);\n const shortcut = letter ? `${letter} ${(0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"helpDialog.or\")} ${numericKey}` : `${numericKey}`;\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_ToolButton__WEBPACK_IMPORTED_MODULE_9__.ToolButton, {\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_13__[\"default\"])(\"Shape\", {\n fillable\n }),\n type: \"radio\",\n icon: icon,\n checked: activeTool.type === value,\n name: \"editor-current-shape\",\n title: `${(0,_utils__WEBPACK_IMPORTED_MODULE_7__.capitalizeString)(label)} — ${shortcut}`,\n keyBindingLabel: numericKey || letter,\n \"aria-label\": (0,_utils__WEBPACK_IMPORTED_MODULE_7__.capitalizeString)(label),\n \"aria-keyshortcuts\": shortcut,\n \"data-testid\": `toolbar-${value}`,\n onPointerDown: ({\n pointerType\n }) => {\n if (!appState.penDetected && pointerType === \"pen\") {\n app.togglePenMode(true);\n }\n },\n onChange: ({\n pointerType\n }) => {\n if (appState.activeTool.type !== value) {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_11__.trackEvent)(\"toolbar\", value, \"ui\");\n }\n\n if (value === \"image\") {\n app.setActiveTool({\n type: value,\n insertOnCanvasDirectly: pointerType !== \"mouse\"\n });\n } else {\n app.setActiveTool({\n type: value\n });\n }\n }\n }, value);\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", {\n className: \"App-toolbar__divider\"\n }), device.isMobile ? (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_ToolButton__WEBPACK_IMPORTED_MODULE_9__.ToolButton, {\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_13__[\"default\"])(\"Shape\", {\n fillable: false\n }),\n type: \"radio\",\n icon: _icons__WEBPACK_IMPORTED_MODULE_18__.frameToolIcon,\n checked: activeTool.type === \"frame\",\n name: \"editor-current-shape\",\n title: `${(0,_utils__WEBPACK_IMPORTED_MODULE_7__.capitalizeString)((0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"toolBar.frame\"))} — ${_keys__WEBPACK_IMPORTED_MODULE_19__.KEYS.F.toLocaleUpperCase()}`,\n keyBindingLabel: _keys__WEBPACK_IMPORTED_MODULE_19__.KEYS.F.toLocaleUpperCase(),\n \"aria-label\": (0,_utils__WEBPACK_IMPORTED_MODULE_7__.capitalizeString)((0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"toolBar.frame\")),\n \"aria-keyshortcuts\": _keys__WEBPACK_IMPORTED_MODULE_19__.KEYS.F.toLocaleUpperCase(),\n \"data-testid\": `toolbar-frame`,\n onPointerDown: ({\n pointerType\n }) => {\n if (!appState.penDetected && pointerType === \"pen\") {\n app.togglePenMode(true);\n }\n },\n onChange: ({\n pointerType\n }) => {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_11__.trackEvent)(\"toolbar\", \"frame\", \"ui\");\n app.setActiveTool({\n type: \"frame\"\n });\n },\n selected: activeTool.type === \"frame\"\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_ToolButton__WEBPACK_IMPORTED_MODULE_9__.ToolButton, {\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_13__[\"default\"])(\"Shape\", {\n fillable: false\n }),\n type: \"radio\",\n icon: _icons__WEBPACK_IMPORTED_MODULE_18__.EmbedIcon,\n checked: activeTool.type === \"embeddable\",\n name: \"editor-current-shape\",\n title: (0,_utils__WEBPACK_IMPORTED_MODULE_7__.capitalizeString)((0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"toolBar.embeddable\")),\n \"aria-label\": (0,_utils__WEBPACK_IMPORTED_MODULE_7__.capitalizeString)((0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"toolBar.embeddable\")),\n \"data-testid\": `toolbar-embeddable`,\n onPointerDown: ({\n pointerType\n }) => {\n if (!appState.penDetected && pointerType === \"pen\") {\n app.togglePenMode(true);\n }\n },\n onChange: ({\n pointerType\n }) => {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_11__.trackEvent)(\"toolbar\", \"embeddable\", \"ui\");\n app.setActiveTool({\n type: \"embeddable\"\n });\n },\n selected: activeTool.type === \"embeddable\"\n }), renderMermaid && //zsviczian\n (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_ToolButton__WEBPACK_IMPORTED_MODULE_9__.ToolButton, {\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_13__[\"default\"])(\"Shape\", {\n fillable: false\n }),\n type: \"radio\",\n icon: _icons__WEBPACK_IMPORTED_MODULE_18__.mermaidLogoIcon,\n checked: activeTool.type === \"mermaid\",\n name: \"editor-current-shape\",\n title: (0,_utils__WEBPACK_IMPORTED_MODULE_7__.capitalizeString)((0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"toolBar.mermaidToExcalidraw\")),\n \"aria-label\": (0,_utils__WEBPACK_IMPORTED_MODULE_7__.capitalizeString)((0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"toolBar.mermaidToExcalidraw\")),\n \"data-testid\": `toolbar-mermaidToExcalidraw`,\n onPointerDown: ({\n pointerType\n }) => {\n if (!appState.penDetected && pointerType === \"pen\") {\n app.togglePenMode(true);\n }\n },\n onChange: ({\n pointerType\n }) => {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_11__.trackEvent)(\"toolbar\", \"mermaid\", \"ui\");\n app.setActiveTool({\n type: \"mermaid\"\n });\n },\n selected: activeTool.type === \"mermaid\"\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_ToolButton__WEBPACK_IMPORTED_MODULE_9__.ToolButton //zsviczian\n , {\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_13__[\"default\"])(\"Shape\", {\n fillable: false\n }),\n type: \"radio\",\n icon: _icons__WEBPACK_IMPORTED_MODULE_18__.laserPointerToolIcon,\n checked: activeTool.type === \"laser\",\n name: \"editor-current-shape\",\n title: (0,_utils__WEBPACK_IMPORTED_MODULE_7__.capitalizeString)((0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"toolBar.laser\")),\n \"aria-label\": (0,_utils__WEBPACK_IMPORTED_MODULE_7__.capitalizeString)((0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"toolBar.laser\")),\n \"data-testid\": `toolbar-laser`,\n onPointerDown: ({\n pointerType\n }) => {\n if (!appState.penDetected && pointerType === \"pen\") {\n app.togglePenMode(true);\n }\n },\n onChange: ({\n pointerType\n }) => {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_11__.trackEvent)(\"toolbar\", \"laser\", \"ui\");\n app.setActiveTool({\n type: \"laser\"\n });\n },\n selected: activeTool.type === \"laser\"\n })]\n }) : (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(_dropdownMenu_DropdownMenu__WEBPACK_IMPORTED_MODULE_17__[\"default\"], Object.assign({\n open: isExtraToolsMenuOpen\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_dropdownMenu_DropdownMenu__WEBPACK_IMPORTED_MODULE_17__[\"default\"].Trigger, Object.assign({\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_13__[\"default\"])(\"App-toolbar__extra-tools-trigger\", {\n \"App-toolbar__extra-tools-trigger--selected\": frameToolSelected || embeddableToolSelected || // in collab we're already highlighting the laser button\n // outside toolbar, so let's not highlight extra-tools button\n // on top of it\n laserToolSelected && !app.props.isCollaborating\n }),\n onToggle: () => setIsExtraToolsMenuOpen(!isExtraToolsMenuOpen),\n title: (0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"toolBar.extraTools\")\n }, {\n children: _icons__WEBPACK_IMPORTED_MODULE_18__.extraToolsIcon\n })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(_dropdownMenu_DropdownMenu__WEBPACK_IMPORTED_MODULE_17__[\"default\"].Content, Object.assign({\n onClickOutside: () => setIsExtraToolsMenuOpen(false),\n onSelect: () => setIsExtraToolsMenuOpen(false),\n className: \"App-toolbar__extra-tools-dropdown\"\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_dropdownMenu_DropdownMenu__WEBPACK_IMPORTED_MODULE_17__[\"default\"].Item, Object.assign({\n onSelect: () => {\n app.setActiveTool({\n type: \"frame\"\n });\n },\n icon: _icons__WEBPACK_IMPORTED_MODULE_18__.frameToolIcon,\n shortcut: _keys__WEBPACK_IMPORTED_MODULE_19__.KEYS.F.toLocaleUpperCase(),\n \"data-testid\": \"toolbar-frame\",\n selected: frameToolSelected\n }, {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"toolBar.frame\")\n })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_dropdownMenu_DropdownMenu__WEBPACK_IMPORTED_MODULE_17__[\"default\"].Item, Object.assign({\n onSelect: () => {\n app.setActiveTool({\n type: \"embeddable\"\n });\n },\n icon: _icons__WEBPACK_IMPORTED_MODULE_18__.EmbedIcon,\n \"data-testid\": \"toolbar-embeddable\",\n selected: embeddableToolSelected\n }, {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"toolBar.embeddable\")\n })), renderMermaid && //zsviczian\n (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_dropdownMenu_DropdownMenu__WEBPACK_IMPORTED_MODULE_17__[\"default\"].Item, Object.assign({\n onSelect: () => {\n app.setActiveTool({\n type: \"mermaid\"\n });\n },\n icon: _icons__WEBPACK_IMPORTED_MODULE_18__.mermaidLogoIcon,\n \"data-testid\": \"toolbar-mermaidToExcalidraw\",\n selected: mermaidToolSelected\n }, {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"toolBar.mermaidToExcalidraw\")\n })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_dropdownMenu_DropdownMenu__WEBPACK_IMPORTED_MODULE_17__[\"default\"].Item, Object.assign({\n onSelect: () => {\n app.setActiveTool({\n type: \"laser\"\n });\n },\n icon: _icons__WEBPACK_IMPORTED_MODULE_18__.laserPointerToolIcon,\n \"data-testid\": \"toolbar-laser\",\n selected: laserToolSelected,\n shortcut: _keys__WEBPACK_IMPORTED_MODULE_19__.KEYS.K.toLocaleUpperCase()\n }, {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"toolBar.laser\")\n }))]\n }))]\n }))]\n });\n};\nconst ZoomActions = ({\n renderAction,\n zoom,\n trayMode = false //zsviczian\n\n}) => (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Stack__WEBPACK_IMPORTED_MODULE_8__[\"default\"].Col, Object.assign({\n gap: 1,\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_13__[\"default\"])(\"zoom-actions\", {\n \"tray-zoom\": trayMode\n })\n}, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(_Stack__WEBPACK_IMPORTED_MODULE_8__[\"default\"].Row, Object.assign({\n align: \"center\"\n }, {\n children: [renderAction(\"zoomOut\"), renderAction(\"resetZoom\"), renderAction(\"zoomIn\")]\n }))\n}));\nconst UndoRedoActions = ({\n renderAction,\n className\n}) => (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"div\", Object.assign({\n className: `undo-redo-buttons ${className}`\n}, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", Object.assign({\n className: \"undo-button-container\"\n }, {\n children: renderAction(\"undo\")\n /* //zsviczian */\n\n })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", Object.assign({\n className: \"redo-button-container\"\n }, {\n children: renderAction(\"redo\")\n /* //zsviczian */\n\n }))]\n}));\nconst ExitZenModeAction = ({\n actionManager,\n showExitZenModeBtn\n}) => (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"button\", Object.assign({\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_13__[\"default\"])(\"disable-zen-mode\", {\n \"disable-zen-mode--visible\": showExitZenModeBtn\n }),\n onClick: () => actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_14__.actionToggleZenMode)\n}, {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_3__.t)(\"buttons.exitZenMode\")\n}));\nconst FinalizeAction = ({\n renderAction,\n className\n}) => (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", Object.assign({\n className: `finalize-button ${className}`\n}, {\n children: renderAction(\"finalize\", {\n size: \"small\"\n })\n}));\n\n//# sourceURL=webpack://ExcalidrawLib/../../components/Actions.tsx?");
2285
2285
 
2286
2286
  /***/ }),
2287
2287
 
@@ -2303,7 +2303,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
2303
2303
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2304
2304
 
2305
2305
  "use strict";
2306
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"ExcalidrawContainerContext\": () => (/* binding */ ExcalidrawContainerContext),\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__),\n/* harmony export */ \"showFourthFont\": () => (/* binding */ showFourthFont),\n/* harmony export */ \"useApp\": () => (/* binding */ useApp),\n/* harmony export */ \"useAppProps\": () => (/* binding */ useAppProps),\n/* harmony export */ \"useDevice\": () => (/* binding */ useDevice),\n/* harmony export */ \"useExcalidrawActionManager\": () => (/* binding */ useExcalidrawActionManager),\n/* harmony export */ \"useExcalidrawAppState\": () => (/* binding */ useExcalidrawAppState),\n/* harmony export */ \"useExcalidrawContainer\": () => (/* binding */ useExcalidrawContainer),\n/* harmony export */ \"useExcalidrawElements\": () => (/* binding */ useExcalidrawElements),\n/* harmony export */ \"useExcalidrawSetAppState\": () => (/* binding */ useExcalidrawSetAppState)\n/* harmony export */ });\n/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react/jsx-runtime */ \"../../../node_modules/react/jsx-runtime.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ \"react\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react-dom */ \"react-dom\");\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! roughjs/bin/rough */ \"../../../node_modules/roughjs/bin/rough.js\");\n/* harmony import */ var clsx__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! clsx */ \"../../../node_modules/clsx/dist/clsx.m.js\");\n/* harmony import */ var nanoid__WEBPACK_IMPORTED_MODULE_72__ = __webpack_require__(/*! nanoid */ \"../../../node_modules/nanoid/index.browser.js\");\n/* harmony import */ var _actions__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../actions */ \"../../actions/index.ts\");\n/* harmony import */ var _actions_actionHistory__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../actions/actionHistory */ \"../../actions/actionHistory.tsx\");\n/* harmony import */ var _actions_manager__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../actions/manager */ \"../../actions/manager.tsx\");\n/* harmony import */ var _actions_register__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../actions/register */ \"../../actions/register.ts\");\n/* harmony import */ var _analytics__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../analytics */ \"../../analytics.ts\");\n/* harmony import */ var _appState__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../appState */ \"../../appState.ts\");\n/* harmony import */ var _clipboard__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../clipboard */ \"../../clipboard.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _data__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../data */ \"../../data/index.ts\");\n/* harmony import */ var _data_library__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../data/library */ \"../../data/library.ts\");\n/* harmony import */ var _data_restore__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../data/restore */ \"../../data/restore.ts\");\n/* harmony import */ var _element__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../element */ \"../../element/index.ts\");\n/* harmony import */ var _element_binding__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../element/binding */ \"../../element/binding.ts\");\n/* harmony import */ var _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../element/linearElementEditor */ \"../../element/linearElementEditor.ts\");\n/* harmony import */ var _element_mutateElement__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../element/mutateElement */ \"../../element/mutateElement.ts\");\n/* harmony import */ var _element_newElement__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../element/newElement */ \"../../element/newElement.ts\");\n/* harmony import */ var _element_typeChecks__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../element/typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var _gesture__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ../gesture */ \"../../gesture.ts\");\n/* harmony import */ var _groups__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ../groups */ \"../../groups.ts\");\n/* harmony import */ var _history__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ../history */ \"../../history.ts\");\n/* harmony import */ var _i18n__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ../i18n */ \"../../i18n.ts\");\n/* harmony import */ var _keys__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ../keys */ \"../../keys.ts\");\n/* harmony import */ var _element_sizeHelpers__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ../element/sizeHelpers */ \"../../element/sizeHelpers.ts\");\n/* harmony import */ var _math__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ../math */ \"../../math.ts\");\n/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ../scene */ \"../../scene/index.ts\");\n/* harmony import */ var _scene_Scene__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ../scene/Scene */ \"../../scene/Scene.ts\");\n/* harmony import */ var _scene_zoom__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ../scene/zoom */ \"../../scene/zoom.ts\");\n/* harmony import */ var _shapes__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ../shapes */ \"../../shapes.tsx\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _element_embeddable__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ../element/embeddable */ \"../../element/embeddable.ts\");\n/* harmony import */ var _ContextMenu__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ./ContextMenu */ \"../../components/ContextMenu.tsx\");\n/* harmony import */ var _LayerUI__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ./LayerUI */ \"../../components/LayerUI.tsx\");\n/* harmony import */ var _Toast__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ./Toast */ \"../../components/Toast.tsx\");\n/* harmony import */ var _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! ../actions/actionToggleViewMode */ \"../../actions/actionToggleViewMode.tsx\");\n/* harmony import */ var _data_blob__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(/*! ../data/blob */ \"../../data/blob.ts\");\n/* harmony import */ var _element_image__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(/*! ../element/image */ \"../../element/image.ts\");\n/* harmony import */ var lodash_throttle__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(/*! lodash.throttle */ \"../../../node_modules/lodash.throttle/index.js\");\n/* harmony import */ var lodash_throttle__WEBPACK_IMPORTED_MODULE_41___default = /*#__PURE__*/__webpack_require__.n(lodash_throttle__WEBPACK_IMPORTED_MODULE_41__);\n/* harmony import */ var _data_filesystem__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(/*! ../data/filesystem */ \"../../data/filesystem.ts\");\n/* harmony import */ var _element_textElement__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(/*! ../element/textElement */ \"../../element/textElement.ts\");\n/* harmony import */ var _element_collision__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(/*! ../element/collision */ \"../../element/collision.ts\");\n/* harmony import */ var _element_resizeElements__WEBPACK_IMPORTED_MODULE_45__ = __webpack_require__(/*! ../element/resizeElements */ \"../../element/resizeElements.ts\");\n/* harmony import */ var _element_Hyperlink__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(/*! ../element/Hyperlink */ \"../../element/Hyperlink.tsx\");\n/* harmony import */ var _data_url__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(/*! ../data/url */ \"../../data/url.ts\");\n/* harmony import */ var _element_transformHandles__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(/*! ../element/transformHandles */ \"../../element/transformHandles.ts\");\n/* harmony import */ var _actions_actionElementLock__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(/*! ../actions/actionElementLock */ \"../../actions/actionElementLock.ts\");\n/* harmony import */ var _scene_Fonts__WEBPACK_IMPORTED_MODULE_50__ = __webpack_require__(/*! ../scene/Fonts */ \"../../scene/Fonts.ts\");\n/* harmony import */ var _frame__WEBPACK_IMPORTED_MODULE_51__ = __webpack_require__(/*! ../frame */ \"../../frame.ts\");\n/* harmony import */ var _scene_selection__WEBPACK_IMPORTED_MODULE_52__ = __webpack_require__(/*! ../scene/selection */ \"../../scene/selection.ts\");\n/* harmony import */ var _actions_actionClipboard__WEBPACK_IMPORTED_MODULE_53__ = __webpack_require__(/*! ../actions/actionClipboard */ \"../../actions/actionClipboard.tsx\");\n/* harmony import */ var _actions_actionFrame__WEBPACK_IMPORTED_MODULE_54__ = __webpack_require__(/*! ../actions/actionFrame */ \"../../actions/actionFrame.ts\");\n/* harmony import */ var _actions_actionCanvas__WEBPACK_IMPORTED_MODULE_55__ = __webpack_require__(/*! ../actions/actionCanvas */ \"../../actions/actionCanvas.tsx\");\n/* harmony import */ var _jotai__WEBPACK_IMPORTED_MODULE_56__ = __webpack_require__(/*! ../jotai */ \"../../jotai.ts\");\n/* harmony import */ var _ActiveConfirmDialog__WEBPACK_IMPORTED_MODULE_57__ = __webpack_require__(/*! ./ActiveConfirmDialog */ \"../../components/ActiveConfirmDialog.tsx\");\n/* harmony import */ var _snapping__WEBPACK_IMPORTED_MODULE_58__ = __webpack_require__(/*! ../snapping */ \"../../snapping.ts\");\n/* harmony import */ var _actions_actionBoundText__WEBPACK_IMPORTED_MODULE_59__ = __webpack_require__(/*! ../actions/actionBoundText */ \"../../actions/actionBoundText.tsx\");\n/* harmony import */ var _BraveMeasureTextError__WEBPACK_IMPORTED_MODULE_60__ = __webpack_require__(/*! ./BraveMeasureTextError */ \"../../components/BraveMeasureTextError.tsx\");\n/* harmony import */ var _EyeDropper__WEBPACK_IMPORTED_MODULE_61__ = __webpack_require__(/*! ./EyeDropper */ \"../../components/EyeDropper.tsx\");\n/* harmony import */ var _data_transform__WEBPACK_IMPORTED_MODULE_62__ = __webpack_require__(/*! ../data/transform */ \"../../data/transform.ts\");\n/* harmony import */ var _Sidebar_Sidebar__WEBPACK_IMPORTED_MODULE_63__ = __webpack_require__(/*! ./Sidebar/Sidebar */ \"../../components/Sidebar/Sidebar.tsx\");\n/* harmony import */ var _canvases__WEBPACK_IMPORTED_MODULE_64__ = __webpack_require__(/*! ./canvases */ \"../../components/canvases/index.tsx\");\n/* harmony import */ var _scene_Renderer__WEBPACK_IMPORTED_MODULE_65__ = __webpack_require__(/*! ../scene/Renderer */ \"../../scene/Renderer.ts\");\n/* harmony import */ var _scene_ShapeCache__WEBPACK_IMPORTED_MODULE_66__ = __webpack_require__(/*! ../scene/ShapeCache */ \"../../scene/ShapeCache.ts\");\n/* harmony import */ var _MermaidToExcalidraw__WEBPACK_IMPORTED_MODULE_67__ = __webpack_require__(/*! ./MermaidToExcalidraw */ \"../../components/MermaidToExcalidraw.tsx\");\n/* harmony import */ var _LaserTool_LaserTool__WEBPACK_IMPORTED_MODULE_68__ = __webpack_require__(/*! ./LaserTool/LaserTool */ \"../../components/LaserTool/LaserTool.tsx\");\n/* harmony import */ var _LaserTool_LaserPathManager__WEBPACK_IMPORTED_MODULE_69__ = __webpack_require__(/*! ./LaserTool/LaserPathManager */ \"../../components/LaserTool/LaserPathManager.ts\");\n/* harmony import */ var _cursor__WEBPACK_IMPORTED_MODULE_70__ = __webpack_require__(/*! ../cursor */ \"../../cursor.ts\");\n/* harmony import */ var _emitter__WEBPACK_IMPORTED_MODULE_71__ = __webpack_require__(/*! ../emitter */ \"../../emitter.ts\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst AppContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(null);\nconst AppPropsContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(null);\nlet showFourthFont = false; //zsviczian\n\nconst deviceContextInitialValue = {\n isSmScreen: false,\n isMobile: false,\n isTouchScreen: false,\n canDeviceFitSidebar: false,\n isLandscape: false\n};\nconst DeviceContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(deviceContextInitialValue);\nDeviceContext.displayName = \"DeviceContext\";\nconst ExcalidrawContainerContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext({\n container: null,\n id: null\n});\nExcalidrawContainerContext.displayName = \"ExcalidrawContainerContext\";\nconst ExcalidrawElementsContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext([]);\nExcalidrawElementsContext.displayName = \"ExcalidrawElementsContext\";\nconst ExcalidrawAppStateContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(Object.assign(Object.assign({}, (0,_appState__WEBPACK_IMPORTED_MODULE_10__.getDefaultAppState)()), {\n width: 0,\n height: 0,\n offsetLeft: 0,\n offsetTop: 0\n}));\nExcalidrawAppStateContext.displayName = \"ExcalidrawAppStateContext\";\nconst ExcalidrawSetAppStateContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(() => {\n console.warn(\"unitialized ExcalidrawSetAppStateContext context!\");\n});\nExcalidrawSetAppStateContext.displayName = \"ExcalidrawSetAppStateContext\";\nconst ExcalidrawActionManagerContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(null);\nExcalidrawActionManagerContext.displayName = \"ExcalidrawActionManagerContext\";\nconst useApp = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(AppContext);\nconst useAppProps = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(AppPropsContext);\nconst useDevice = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(DeviceContext);\nconst useExcalidrawContainer = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawContainerContext);\nconst useExcalidrawElements = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawElementsContext);\nconst useExcalidrawAppState = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawAppStateContext);\nconst useExcalidrawSetAppState = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawSetAppStateContext);\nconst useExcalidrawActionManager = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawActionManagerContext);\nlet didTapTwice = false;\nlet tappedTwiceTimer = 0;\nlet isHoldingSpace = false;\nlet isPanning = false;\nlet isDraggingScrollBar = false;\nlet currentScrollBars = {\n horizontal: null,\n vertical: null\n};\nlet touchTimeout = 0;\nlet invalidateContextMenu = false;\n/**\r\n * Map of youtube embed video states\r\n */\n\nconst YOUTUBE_VIDEO_STATES = new Map();\nlet IS_PLAIN_PASTE = false;\nlet IS_PLAIN_PASTE_TIMER = 0;\nlet PLAIN_PASTE_TOAST_SHOWN = false;\nlet lastPointerUp = null;\nconst gesture = {\n pointers: new Map(),\n lastCenter: null,\n initialDistance: null,\n initialScale: null\n};\n\nclass App extends (react__WEBPACK_IMPORTED_MODULE_1___default().Component) {\n constructor(props) {\n var _a;\n\n super(props);\n this.interactiveCanvas = null;\n this.unmounted = false;\n this.device = deviceContextInitialValue;\n this.excalidrawContainerRef = react__WEBPACK_IMPORTED_MODULE_1___default().createRef();\n this.files = {};\n this.imageCache = new Map();\n this.iFrameRefs = new Map();\n this.lastPointerDownEvent = null;\n this.lastPointerUpEvent = null;\n this.lastViewportPosition = {\n x: 0,\n y: 0\n };\n this.allowMobileMode = true; //zsviczian\n\n this.laserPathManager = new _LaserTool_LaserPathManager__WEBPACK_IMPORTED_MODULE_69__.LaserPathManager(this);\n this.onChangeEmitter = new _emitter__WEBPACK_IMPORTED_MODULE_71__.Emitter();\n this.onPointerDownEmitter = new _emitter__WEBPACK_IMPORTED_MODULE_71__.Emitter();\n this.onPointerUpEmitter = new _emitter__WEBPACK_IMPORTED_MODULE_71__.Emitter();\n\n this.updateEmbeddables = () => {\n const embeddableElements = new Map();\n let updated = false;\n this.scene.getNonDeletedElements().filter(element => {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isEmbeddableElement)(element)) {\n embeddableElements.set(element.id, true);\n\n if (element.validated == null) {\n updated = true;\n const validated = (0,_element_embeddable__WEBPACK_IMPORTED_MODULE_34__.embeddableURLValidator)(element.link, this.props.validateEmbeddable);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n validated\n }, false);\n _scene_ShapeCache__WEBPACK_IMPORTED_MODULE_66__.ShapeCache[\"delete\"](element);\n }\n }\n\n return false;\n });\n\n if (updated) {\n this.scene.informMutation();\n } // GC\n\n\n this.iFrameRefs.forEach((ref, id) => {\n if (!embeddableElements.has(id)) {\n this.iFrameRefs.delete(id);\n }\n });\n };\n\n this.getFrameNameDOMId = frameElement => {\n return `${this.id}-frame-name-${frameElement.id}`;\n };\n\n this.frameNameBoundsCache = {\n get: frameElement => {\n let bounds = this.frameNameBoundsCache._cache.get(frameElement.id);\n\n if (!bounds || bounds.zoom !== this.state.zoom.value || bounds.versionNonce !== frameElement.versionNonce) {\n const frameNameDiv = document.getElementById(this.getFrameNameDOMId(frameElement));\n\n if (frameNameDiv) {\n const box = frameNameDiv.getBoundingClientRect();\n const boxSceneTopLeft = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)({\n clientX: box.x,\n clientY: box.y\n }, this.state);\n const boxSceneBottomRight = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)({\n clientX: box.right,\n clientY: box.bottom\n }, this.state);\n bounds = {\n x: boxSceneTopLeft.x,\n y: boxSceneTopLeft.y,\n width: boxSceneBottomRight.x - boxSceneTopLeft.x,\n height: boxSceneBottomRight.y - boxSceneTopLeft.y,\n angle: 0,\n zoom: this.state.zoom.value,\n versionNonce: frameElement.versionNonce\n };\n\n this.frameNameBoundsCache._cache.set(frameElement.id, bounds);\n\n return bounds;\n }\n\n return null;\n }\n\n return bounds;\n },\n\n /**\r\n * @private\r\n */\n _cache: new Map()\n };\n\n this.renderFrameNames = () => {\n if (!this.state.frameRendering.enabled || !this.state.frameRendering.name) {\n return null;\n }\n\n const isDarkTheme = this.state.theme === \"dark\";\n return this.scene.getNonDeletedFrames().map((f, index) => {\n if (!(0,_element_sizeHelpers__WEBPACK_IMPORTED_MODULE_27__.isElementInViewport)(f, this.canvas.width / window.devicePixelRatio, this.canvas.height / window.devicePixelRatio, {\n offsetLeft: this.state.offsetLeft,\n offsetTop: this.state.offsetTop,\n scrollX: this.state.scrollX,\n scrollY: this.state.scrollY,\n zoom: this.state.zoom\n })) {\n // if frame not visible, don't render its name\n return null;\n }\n\n const {\n x: x1,\n y: y1\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.sceneCoordsToViewportCoords)({\n sceneX: f.x,\n sceneY: f.y\n }, this.state);\n const {\n x: x2\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.sceneCoordsToViewportCoords)({\n sceneX: f.x + f.width,\n sceneY: f.y + f.height\n }, this.state);\n const FRAME_NAME_GAP = 20;\n const FRAME_NAME_EDIT_PADDING = 6;\n\n const reset = () => {\n var _a;\n\n if (((_a = f.name) === null || _a === void 0 ? void 0 : _a.trim()) === \"\") {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(f, {\n name: null\n });\n }\n\n this.setState({\n editingFrame: null\n });\n };\n\n let frameNameJSX;\n\n if (f.id === this.state.editingFrame) {\n const frameNameInEdit = f.name == null ? `Frame ${(index + 1).toString().padStart(2, \"0\")}` //zsviczian\n : f.name;\n frameNameJSX = (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"input\", {\n autoFocus: true,\n value: frameNameInEdit,\n onChange: e => {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(f, {\n name: e.target.value\n });\n },\n onBlur: () => reset(),\n onKeyDown: event => {\n // for some inexplicable reason, `onBlur` triggered on ESC\n // does not reset `state.editingFrame` despite being called,\n // and we need to reset it here as well\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ESCAPE || event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ENTER) {\n reset();\n }\n },\n style: {\n background: this.state.viewBackgroundColor,\n filter: isDarkTheme ? _constants__WEBPACK_IMPORTED_MODULE_12__.THEME_FILTER : \"none\",\n zIndex: 2,\n border: \"none\",\n display: \"block\",\n padding: `${FRAME_NAME_EDIT_PADDING}px`,\n borderRadius: 4,\n boxShadow: \"inset 0 0 0 1px var(--color-primary)\",\n fontFamily: \"Assistant\",\n fontSize: \"14px\",\n transform: `translateY(-${FRAME_NAME_EDIT_PADDING}px)`,\n color: \"var(--color-gray-80)\",\n overflow: \"hidden\",\n maxWidth: `${Math.min(x2 - x1 - FRAME_NAME_EDIT_PADDING, document.body.clientWidth - x1 - FRAME_NAME_EDIT_PADDING)}px`\n },\n size: frameNameInEdit.length + 1 || 1,\n dir: \"auto\",\n autoComplete: \"off\",\n autoCapitalize: \"off\",\n autoCorrect: \"off\"\n });\n } else {\n frameNameJSX = f.name == null || f.name.trim() === \"\" ? `Frame ${(index + 1).toString().padStart(2, \"0\")}` //zsviczian\n : f.name.trim();\n }\n\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", Object.assign({\n id: this.getFrameNameDOMId(f),\n style: {\n position: \"absolute\",\n top: `${y1 - FRAME_NAME_GAP - this.state.offsetTop}px`,\n left: `${x1 - this.state.offsetLeft - (this.state.editingFrame === f.id ? FRAME_NAME_EDIT_PADDING : 0)}px`,\n zIndex: 2,\n fontSize: \"14px\",\n color: isDarkTheme ? \"var(--color-gray-60)\" : \"var(--color-gray-50)\",\n width: \"max-content\",\n maxWidth: `${x2 - x1 + FRAME_NAME_EDIT_PADDING * 2}px`,\n overflow: f.id === this.state.editingFrame ? \"visible\" : \"hidden\",\n whiteSpace: \"nowrap\",\n textOverflow: \"ellipsis\",\n cursor: _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.MOVE,\n pointerEvents: this.state.viewModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_EVENTS.disabled : _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_EVENTS.enabled\n },\n onPointerDown: event => this.handleCanvasPointerDown(event),\n onWheel: event => this.handleWheel(event),\n onContextMenu: this.handleCanvasContextMenu,\n onDoubleClick: () => {\n this.setState({\n editingFrame: f.id\n });\n }\n }, {\n children: frameNameJSX\n }), f.id);\n });\n };\n\n this.focusContainer = () => {\n var _a;\n\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.focus();\n };\n\n this.getSceneElementsIncludingDeleted = () => {\n return this.scene.getElementsIncludingDeleted();\n };\n\n this.getSceneElements = () => {\n return this.scene.getNonDeletedElements();\n };\n\n this.onInsertElements = elements => {\n this.addElementsFromPasteOrLibrary({\n elements,\n position: \"center\",\n files: null\n });\n };\n\n this.onExportImage = async (type, elements) => {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_9__.trackEvent)(\"export\", type, \"ui\");\n const fileHandle = await (0,_data__WEBPACK_IMPORTED_MODULE_13__.exportCanvas)(type, elements, this.state, this.files, {\n exportBackground: this.state.exportBackground,\n name: this.state.name,\n viewBackgroundColor: this.state.viewBackgroundColor\n }).catch(_utils__WEBPACK_IMPORTED_MODULE_33__.muteFSAbortError).catch(error => {\n console.error(error);\n this.setState({\n errorMessage: error.message\n });\n });\n\n if (this.state.exportEmbedScene && fileHandle && (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.isImageFileHandle)(fileHandle)) {\n this.setState({\n fileHandle\n });\n }\n };\n\n this.openEyeDropper = ({\n type\n }) => {\n _jotai__WEBPACK_IMPORTED_MODULE_56__.jotaiStore.set(_EyeDropper__WEBPACK_IMPORTED_MODULE_61__.activeEyeDropperAtom, {\n swapPreviewOnAlt: true,\n colorPickerType: type === \"stroke\" ? \"elementStroke\" : \"elementBackground\",\n onSelect: (color, event) => {\n const shouldUpdateStrokeColor = type === \"background\" && event.altKey || type === \"stroke\" && !event.altKey;\n const selectedElements = this.scene.getSelectedElements(this.state);\n\n if (!selectedElements.length || this.state.activeTool.type !== \"selection\") {\n if (shouldUpdateStrokeColor) {\n this.syncActionResult({\n appState: Object.assign(Object.assign({}, this.state), {\n currentItemStrokeColor: color\n }),\n commitToHistory: true\n });\n } else {\n this.syncActionResult({\n appState: Object.assign(Object.assign({}, this.state), {\n currentItemBackgroundColor: color\n }),\n commitToHistory: true\n });\n }\n } else {\n this.updateScene({\n elements: this.scene.getElementsIncludingDeleted().map(el => {\n if (this.state.selectedElementIds[el.id]) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(el, {\n [shouldUpdateStrokeColor ? \"strokeColor\" : \"backgroundColor\"]: color\n });\n }\n\n return el;\n })\n });\n }\n },\n keepOpenOnAlt: false\n });\n };\n\n this.syncActionResult = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(actionResult => {\n var _a, _b, _c, _d, _e, _f, _g, _h, _j;\n\n if (this.unmounted || actionResult === false) {\n return;\n }\n\n let editingElement = null;\n\n if (actionResult.elements) {\n actionResult.elements.forEach(element => {\n var _a;\n\n if (((_a = this.state.editingElement) === null || _a === void 0 ? void 0 : _a.id) === element.id && this.state.editingElement !== element && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isNonDeletedElement)(element)) {\n editingElement = element;\n }\n });\n this.scene.replaceAllElements(actionResult.elements);\n\n if (actionResult.commitToHistory) {\n this.history.resumeRecording();\n }\n }\n\n if (actionResult.files) {\n this.files = actionResult.replaceFiles ? actionResult.files : Object.assign(Object.assign({}, this.files), actionResult.files);\n this.addNewImagesToImageCache();\n }\n\n if (actionResult.appState || editingElement || this.state.contextMenu) {\n if (actionResult.commitToHistory) {\n this.history.resumeRecording();\n }\n\n let viewModeEnabled = ((_a = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _a === void 0 ? void 0 : _a.viewModeEnabled) || false;\n let zenModeEnabled = ((_b = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _b === void 0 ? void 0 : _b.zenModeEnabled) || false;\n let gridSize = ((_c = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _c === void 0 ? void 0 : _c.gridSize) || null;\n const theme = ((_d = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _d === void 0 ? void 0 : _d.theme) || this.props.theme || _constants__WEBPACK_IMPORTED_MODULE_12__.THEME.LIGHT;\n let name = (_f = (_e = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _e === void 0 ? void 0 : _e.name) !== null && _f !== void 0 ? _f : this.state.name;\n const errorMessage = (_h = (_g = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _g === void 0 ? void 0 : _g.errorMessage) !== null && _h !== void 0 ? _h : this.state.errorMessage;\n\n if (typeof this.props.viewModeEnabled !== \"undefined\") {\n viewModeEnabled = this.props.viewModeEnabled;\n }\n\n if (typeof this.props.zenModeEnabled !== \"undefined\") {\n zenModeEnabled = this.props.zenModeEnabled;\n }\n\n if (typeof this.props.gridModeEnabled !== \"undefined\") {\n gridSize = this.props.gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_12__.GRID_SIZE : null;\n }\n\n if (typeof this.props.name !== \"undefined\") {\n name = this.props.name;\n }\n\n editingElement = editingElement || ((_j = actionResult.appState) === null || _j === void 0 ? void 0 : _j.editingElement) || null;\n\n if (editingElement === null || editingElement === void 0 ? void 0 : editingElement.isDeleted) {\n editingElement = null;\n }\n\n this.setState(state => {\n // using Object.assign instead of spread to fool TS 4.2.2+ into\n // regarding the resulting type as not containing undefined\n // (which the following expression will never contain)\n return Object.assign(actionResult.appState || {}, {\n // NOTE this will prevent opening context menu using an action\n // or programmatically from the host, so it will need to be\n // rewritten later\n contextMenu: null,\n editingElement,\n viewModeEnabled,\n zenModeEnabled,\n gridSize,\n theme,\n name,\n errorMessage\n });\n }, () => {\n if (actionResult.syncHistory) {\n this.history.setCurrentState(this.state, this.scene.getElementsIncludingDeleted());\n }\n });\n }\n }); // Lifecycle\n\n this.onBlur = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(() => {\n isHoldingSpace = false;\n this.setState({\n isBindingEnabled: true\n });\n });\n\n this.onUnload = () => {\n this.onBlur();\n };\n\n this.disableEvent = event => {\n event.preventDefault();\n };\n\n this.resetHistory = () => {\n this.history.clear();\n };\n /**\r\n * Resets scene & history.\r\n * ! Do not use to clear scene user action !\r\n */\n\n\n this.resetScene = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(opts => {\n this.scene.replaceAllElements([]);\n this.setState(state => Object.assign(Object.assign({}, (0,_appState__WEBPACK_IMPORTED_MODULE_10__.getDefaultAppState)()), {\n isLoading: (opts === null || opts === void 0 ? void 0 : opts.resetLoadingState) ? false : state.isLoading,\n theme: this.state.theme\n }));\n this.resetHistory();\n });\n\n this.initializeScene = async () => {\n var _a;\n\n if (\"launchQueue\" in window && \"LaunchParams\" in window) {\n window.launchQueue.setConsumer(async launchParams => {\n if (!launchParams.files.length) {\n return;\n }\n\n const fileHandle = launchParams.files[0];\n const blob = await fileHandle.getFile();\n this.loadFileToCanvas(new File([blob], blob.name || \"\", {\n type: blob.type\n }), fileHandle);\n });\n }\n\n if (this.props.theme) {\n this.setState({\n theme: this.props.theme\n });\n }\n\n if (!this.state.isLoading) {\n this.setState({\n isLoading: true\n });\n }\n\n let initialData = null;\n\n try {\n initialData = (await this.props.initialData) || null;\n\n if (initialData === null || initialData === void 0 ? void 0 : initialData.libraryItems) {\n this.library.updateLibrary({\n libraryItems: initialData.libraryItems,\n merge: true\n }).catch(error => {\n console.error(error);\n });\n }\n } catch (error) {\n console.error(error);\n initialData = {\n appState: {\n errorMessage: error.message || \"Encountered an error during importing or restoring scene data\"\n }\n };\n }\n\n const scene = (0,_data_restore__WEBPACK_IMPORTED_MODULE_15__.restore)(initialData, null, null, {\n repairBindings: true\n });\n scene.appState = Object.assign(Object.assign({}, scene.appState), {\n theme: this.props.theme || scene.appState.theme,\n // we're falling back to current (pre-init) state when deciding\n // whether to open the library, to handle a case where we\n // update the state outside of initialData (e.g. when loading the app\n // with a library install link, which should auto-open the library)\n openSidebar: ((_a = scene.appState) === null || _a === void 0 ? void 0 : _a.openSidebar) || this.state.openSidebar,\n activeTool: scene.appState.activeTool.type === \"image\" ? Object.assign(Object.assign({}, scene.appState.activeTool), {\n type: \"selection\"\n }) : scene.appState.activeTool,\n isLoading: false,\n toast: this.state.toast\n });\n\n if (initialData === null || initialData === void 0 ? void 0 : initialData.scrollToContent) {\n scene.appState = Object.assign(Object.assign({}, scene.appState), (0,_scene__WEBPACK_IMPORTED_MODULE_29__.calculateScrollCenter)(scene.elements, Object.assign(Object.assign({}, scene.appState), {\n width: this.state.width,\n height: this.state.height,\n offsetTop: this.state.offsetTop,\n offsetLeft: this.state.offsetLeft\n })));\n } // FontFaceSet loadingdone event we listen on may not always fire\n // (looking at you Safari), so on init we manually load fonts for current\n // text elements on canvas, and rerender them once done. This also\n // seems faster even in browsers that do fire the loadingdone event.\n\n\n this.fonts.loadFontsForElements(scene.elements);\n this.resetHistory();\n this.syncActionResult(Object.assign(Object.assign({}, scene), {\n commitToHistory: true\n }));\n };\n\n this.refreshDeviceState = container => {\n const {\n width,\n height\n } = container.getBoundingClientRect();\n const sidebarBreakpoint = this.props.UIOptions.dockedSidebarBreakpoint != null ? this.props.UIOptions.dockedSidebarBreakpoint : _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_RIGHT_SIDEBAR_MIN_WIDTH;\n this.device = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.updateObject)(this.device, {\n isLandscape: width > height,\n isSmScreen: width < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_SM_MAX_WIDTH,\n isMobile: this.allowMobileMode && ( //zsviczian\n width < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_PORTRAIT || height < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_HEIGHT_LANDSCAPE && width < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_LANDSCAPE),\n canDeviceFitSidebar: width > sidebarBreakpoint\n });\n };\n\n this.onResize = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(() => {\n this.scene.getElementsIncludingDeleted().forEach(element => _scene_ShapeCache__WEBPACK_IMPORTED_MODULE_66__.ShapeCache[\"delete\"](element));\n this.setState({});\n });\n\n this.renderInteractiveSceneCallback = ({\n atLeastOneVisibleElement,\n scrollBars,\n elements\n }) => {\n if (!document.querySelector(\".excalidraw\")) {\n return;\n } //zsviczian - address issue when moving excalidraw to a new window/document\n\n\n if (scrollBars) {\n currentScrollBars = scrollBars;\n }\n\n const scrolledOutside = // hide when editing text\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement) ? false : !atLeastOneVisibleElement && elements.length > 0;\n\n if (this.state.scrolledOutside !== scrolledOutside) {\n this.setState({\n scrolledOutside\n });\n }\n\n this.scheduleImageRefresh();\n };\n\n this.onScroll = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.debounce)(() => {\n const {\n offsetTop,\n offsetLeft\n } = this.getCanvasOffsets();\n this.setState(state => {\n if (state.offsetLeft === offsetLeft && state.offsetTop === offsetTop) {\n return null;\n }\n\n return {\n offsetTop,\n offsetLeft\n };\n });\n }, _constants__WEBPACK_IMPORTED_MODULE_12__.SCROLL_TIMEOUT); // Copy/paste\n\n this.onCut = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(event => {\n var _a;\n\n const isExcalidrawActive = (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement);\n\n if (!isExcalidrawActive || (0,_utils__WEBPACK_IMPORTED_MODULE_33__.isWritableElement)(event.target)) {\n return;\n }\n\n this.cutAll();\n event.preventDefault();\n event.stopPropagation();\n });\n this.onCopy = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(event => {\n var _a;\n\n const isExcalidrawActive = (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement);\n\n if (!isExcalidrawActive || (0,_utils__WEBPACK_IMPORTED_MODULE_33__.isWritableElement)(event.target)) {\n return;\n }\n\n this.copyAll();\n event.preventDefault();\n event.stopPropagation();\n });\n\n this.cutAll = () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionCut, \"keyboard\");\n };\n\n this.copyAll = () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionCopy, \"keyboard\");\n };\n\n this.onTouchStart = event => {\n // fix for Apple Pencil Scribble\n // On Android, preventing the event would disable contextMenu on tap-hold\n if (!_constants__WEBPACK_IMPORTED_MODULE_12__.isAndroid) {\n event.preventDefault();\n }\n\n if (!didTapTwice) {\n didTapTwice = true;\n clearTimeout(tappedTwiceTimer);\n tappedTwiceTimer = window.setTimeout(App.resetTapTwice, _constants__WEBPACK_IMPORTED_MODULE_12__.TAP_TWICE_TIMEOUT);\n return;\n } // insert text only if we tapped twice with a single finger\n // event.touches.length === 1 will also prevent inserting text when user's zooming\n\n\n if (didTapTwice && event.touches.length === 1) {\n const touch = event.touches[0]; // @ts-ignore\n\n this.handleCanvasDoubleClick({\n clientX: touch.clientX,\n clientY: touch.clientY\n });\n didTapTwice = false;\n clearTimeout(tappedTwiceTimer);\n }\n\n if (_constants__WEBPACK_IMPORTED_MODULE_12__.isAndroid) {\n event.preventDefault();\n }\n\n if (event.touches.length === 2) {\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({}, this.state),\n activeEmbeddable: null\n });\n }\n };\n\n this.onTouchEnd = event => {\n this.resetContextMenuTimer();\n\n if (event.touches.length > 0) {\n this.setState({\n previousSelectedElementIds: {},\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(this.state.previousSelectedElementIds, this.state)\n });\n } else {\n gesture.pointers.clear();\n }\n };\n\n this.pasteFromClipboard = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(async event => {\n var _a, _b, _c;\n\n const isPlainPaste = !!(IS_PLAIN_PASTE && event); // #686\n\n const target = document.activeElement;\n const isExcalidrawActive = (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(target);\n\n if (event && !isExcalidrawActive) {\n return;\n }\n\n const elementUnderCursor = document.elementFromPoint(this.lastViewportPosition.x, this.lastViewportPosition.y);\n\n if (event && (!(elementUnderCursor instanceof HTMLCanvasElement) || (0,_utils__WEBPACK_IMPORTED_MODULE_33__.isWritableElement)(target))) {\n return;\n }\n\n const {\n x: sceneX,\n y: sceneY\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)({\n clientX: this.lastViewportPosition.x,\n clientY: this.lastViewportPosition.y\n }, this.state); // must be called in the same frame (thus before any awaits) as the paste\n // event else some browsers (FF...) will clear the clipboardData\n // (something something security)\n\n let file = (_b = event === null || event === void 0 ? void 0 : event.clipboardData) === null || _b === void 0 ? void 0 : _b.files[0];\n const data = await (0,_clipboard__WEBPACK_IMPORTED_MODULE_11__.parseClipboard)(event, isPlainPaste);\n\n if (!file && !isPlainPaste) {\n if (data.mixedContent) {\n return this.addElementsFromMixedContentPaste(data.mixedContent, {\n isPlainPaste,\n sceneX,\n sceneY\n });\n } else if (data.text) {\n const string = data.text.trim();\n\n if (string.startsWith(\"<svg\") && string.endsWith(\"</svg>\")) {\n // ignore SVG validation/normalization which will be done during image\n // initialization\n file = (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.SVGStringToFile)(string);\n }\n }\n } // prefer spreadsheet data over image file (MS Office/Libre Office)\n\n\n if ((0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.isSupportedImageFile)(file) && !data.spreadsheet) {\n const imageElement = this.createImageElement({\n sceneX,\n sceneY\n });\n this.insertImageElement(imageElement, file);\n this.initializeImageDimensions(imageElement);\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({\n [imageElement.id]: true\n }, this.state)\n });\n return;\n }\n\n if (this.props.onPaste) {\n try {\n if ((await this.props.onPaste(data, event)) === false) {\n return;\n }\n } catch (error) {\n console.error(error);\n }\n }\n\n if (data.errorMessage) {\n this.setState({\n errorMessage: data.errorMessage\n });\n } else if (data.spreadsheet && !isPlainPaste) {\n this.setState({\n pasteDialog: {\n data: data.spreadsheet,\n shown: true\n }\n });\n } else if (data.elements) {\n const elements = data.programmaticAPI ? (0,_data_transform__WEBPACK_IMPORTED_MODULE_62__.convertToExcalidrawElements)(data.elements) : data.elements; // TODO remove formatting from elements if isPlainPaste\n\n this.addElementsFromPasteOrLibrary({\n elements,\n files: data.files || null,\n position: \"cursor\",\n retainSeed: isPlainPaste\n });\n } else if (data.text) {\n const maybeUrl = (0,_element_embeddable__WEBPACK_IMPORTED_MODULE_34__.extractSrc)(data.text);\n\n if (!isPlainPaste && (0,_element_embeddable__WEBPACK_IMPORTED_MODULE_34__.embeddableURLValidator)(maybeUrl, this.props.validateEmbeddable) && (/^(http|https):\\/\\/[^\\s/$.?#].[^\\s]*$/.test(maybeUrl) || ((_c = (0,_element_embeddable__WEBPACK_IMPORTED_MODULE_34__.getEmbedLink)(maybeUrl)) === null || _c === void 0 ? void 0 : _c.type) === \"video\")) {\n const embeddable = this.insertEmbeddableElement({\n sceneX,\n sceneY,\n link: (0,_data_url__WEBPACK_IMPORTED_MODULE_47__.normalizeLink)(maybeUrl)\n });\n\n if (embeddable) {\n this.setState({\n selectedElementIds: {\n [embeddable.id]: true\n }\n });\n }\n\n return;\n }\n\n this.addTextFromPaste(data.text, isPlainPaste);\n }\n\n this.setActiveTool({\n type: \"selection\"\n });\n event === null || event === void 0 ? void 0 : event.preventDefault();\n });\n\n this.addElementsFromPasteOrLibrary = opts => {\n const elements = (0,_data_restore__WEBPACK_IMPORTED_MODULE_15__.restoreElements)(opts.elements, null, undefined);\n const [minX, minY, maxX, maxY] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(elements);\n const elementsCenterX = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.distance)(minX, maxX) / 2;\n const elementsCenterY = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.distance)(minY, maxY) / 2;\n const clientX = typeof opts.position === \"object\" ? opts.position.clientX : opts.position === \"cursor\" ? this.lastViewportPosition.x : this.state.width / 2 + this.state.offsetLeft;\n const clientY = typeof opts.position === \"object\" ? opts.position.clientY : opts.position === \"cursor\" ? this.lastViewportPosition.y : this.state.height / 2 + this.state.offsetTop;\n const {\n x,\n y\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)({\n clientX,\n clientY\n }, this.state);\n const dx = x - elementsCenterX;\n const dy = y - elementsCenterY;\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_28__.getGridPoint)(dx, dy, this.state.gridSize);\n const newElements = (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.duplicateElements)(elements.map(element => {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(element, {\n x: element.x + gridX - minX,\n y: element.y + gridY - minY\n });\n }), {\n randomizeSeed: !opts.retainSeed\n });\n const nextElements = [...this.scene.getElementsIncludingDeleted(), ...newElements];\n this.scene.replaceAllElements(nextElements);\n newElements.forEach(newElement => {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(newElement) && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(newElement)) {\n const container = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getContainerElement)(newElement);\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.redrawTextBoundingBox)(newElement, container);\n }\n });\n\n if (opts.files) {\n this.files = Object.assign(Object.assign({}, this.files), opts.files);\n }\n\n this.history.resumeRecording();\n const nextElementsToSelect = (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.excludeElementsInFramesFromSelection)(newElements);\n this.setState(Object.assign(Object.assign(Object.assign({}, this.state), {\n // keep sidebar (presumably the library) open if it's docked and\n // can fit.\n //\n // Note, we should close the sidebar only if we're dropping items\n // from library, not when pasting from clipboard. Alas.\n openSidebar: this.state.openSidebar && this.device.canDeviceFitSidebar && _jotai__WEBPACK_IMPORTED_MODULE_56__.jotaiStore.get(_Sidebar_Sidebar__WEBPACK_IMPORTED_MODULE_63__.isSidebarDockedAtom) ? this.state.openSidebar : null\n }), (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)({\n editingGroupId: null,\n selectedElementIds: nextElementsToSelect.reduce((acc, element) => {\n if (!(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(element)) {\n acc[element.id] = true;\n }\n\n return acc;\n }, {})\n }, this.scene.getNonDeletedElements(), this.state, this)), () => {\n if (opts.files) {\n this.addNewImagesToImageCache();\n }\n });\n this.setActiveTool({\n type: \"selection\"\n });\n\n if (opts.fitToContent) {\n this.scrollToContent(newElements, {\n fitToContent: true\n });\n }\n };\n\n this.setAppState = (state, callback) => {\n this.setState(state, callback);\n };\n\n this.removePointer = event => {\n if (touchTimeout) {\n this.resetContextMenuTimer();\n }\n\n gesture.pointers.delete(event.pointerId);\n };\n\n this.toggleLock = (source = \"ui\") => {\n if (!this.state.activeTool.locked) {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_9__.trackEvent)(\"toolbar\", \"toggleLock\", `${source} (${this.device.isMobile ? \"mobile\" : \"desktop\"})`);\n }\n\n this.setState(prevState => {\n return {\n activeTool: Object.assign(Object.assign(Object.assign({}, prevState.activeTool), (0,_utils__WEBPACK_IMPORTED_MODULE_33__.updateActiveTool)(this.state, prevState.activeTool.locked ? {\n type: \"selection\"\n } : prevState.activeTool)), {\n locked: !prevState.activeTool.locked\n })\n };\n });\n };\n\n this.updateFrameRendering = opts => {\n this.setState(prevState => {\n var _a, _b, _c, _d;\n\n const next = typeof opts === \"function\" ? opts(prevState.frameRendering) : opts;\n return {\n frameRendering: {\n enabled: (_a = next === null || next === void 0 ? void 0 : next.enabled) !== null && _a !== void 0 ? _a : prevState.frameRendering.enabled,\n clip: (_b = next === null || next === void 0 ? void 0 : next.clip) !== null && _b !== void 0 ? _b : prevState.frameRendering.clip,\n name: (_c = next === null || next === void 0 ? void 0 : next.name) !== null && _c !== void 0 ? _c : prevState.frameRendering.name,\n outline: (_d = next === null || next === void 0 ? void 0 : next.outline) !== null && _d !== void 0 ? _d : prevState.frameRendering.outline\n }\n };\n });\n };\n\n this.togglePenMode = force => {\n this.setState(prevState => {\n return {\n penMode: force !== null && force !== void 0 ? force : !prevState.penMode,\n penDetected: true\n };\n });\n };\n\n this.onHandToolToggle = () => {\n this.actionManager.executeAction(_actions_actionCanvas__WEBPACK_IMPORTED_MODULE_55__.actionToggleHandTool);\n };\n /**\r\n * Zooms on canvas viewport center\r\n */\n\n\n this.zoomCanvas = (\n /** decimal fraction between 0.1 (10% zoom) and 30 (3000% zoom) */\n value) => {\n this.setState(Object.assign({}, (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_31__.getStateForZoom)({\n viewportX: this.state.width / 2 + this.state.offsetLeft,\n viewportY: this.state.height / 2 + this.state.offsetTop,\n nextZoom: (0,_scene__WEBPACK_IMPORTED_MODULE_29__.getNormalizedZoom)(value)\n }, this.state)));\n };\n\n this.cancelInProgresAnimation = null;\n\n this.scrollToContent = (target = this.scene.getNonDeletedElements(), opts) => {\n var _a, _b;\n\n (_a = this.cancelInProgresAnimation) === null || _a === void 0 ? void 0 : _a.call(this); // convert provided target into ExcalidrawElement[] if necessary\n\n const targetElements = Array.isArray(target) ? target : [target];\n let zoom = this.state.zoom;\n let scrollX = this.state.scrollX;\n let scrollY = this.state.scrollY;\n\n if ((opts === null || opts === void 0 ? void 0 : opts.fitToContent) || (opts === null || opts === void 0 ? void 0 : opts.fitToViewport)) {\n const {\n appState\n } = (0,_actions_actionCanvas__WEBPACK_IMPORTED_MODULE_55__.zoomToFit)({\n targetElements,\n appState: this.state,\n fitToViewport: !!(opts === null || opts === void 0 ? void 0 : opts.fitToViewport),\n viewportZoomFactor: opts === null || opts === void 0 ? void 0 : opts.viewportZoomFactor\n });\n zoom = appState.zoom;\n scrollX = appState.scrollX;\n scrollY = appState.scrollY;\n } else {\n // compute only the viewport location, without any zoom adjustment\n const scroll = (0,_scene__WEBPACK_IMPORTED_MODULE_29__.calculateScrollCenter)(targetElements, this.state);\n scrollX = scroll.scrollX;\n scrollY = scroll.scrollY;\n } // when animating, we use RequestAnimationFrame to prevent the animation\n // from slowing down other processes\n\n\n if (opts === null || opts === void 0 ? void 0 : opts.animate) {\n const origScrollX = this.state.scrollX;\n const origScrollY = this.state.scrollY;\n const origZoom = this.state.zoom.value;\n const cancel = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.easeToValuesRAF)({\n fromValues: {\n scrollX: origScrollX,\n scrollY: origScrollY,\n zoom: origZoom\n },\n toValues: {\n scrollX,\n scrollY,\n zoom: zoom.value\n },\n interpolateValue: (from, to, progress, key) => {\n // for zoom, use different easing\n if (key === \"zoom\") {\n return from * Math.pow(to / from, (0,_utils__WEBPACK_IMPORTED_MODULE_33__.easeOut)(progress));\n } // handle using default\n\n\n return undefined;\n },\n onStep: ({\n scrollX,\n scrollY,\n zoom\n }) => {\n this.setState({\n scrollX,\n scrollY,\n zoom: {\n value: zoom\n }\n });\n },\n onStart: () => {\n this.setState({\n shouldCacheIgnoreZoom: true\n });\n },\n onEnd: () => {\n this.setState({\n shouldCacheIgnoreZoom: false\n });\n },\n onCancel: () => {\n this.setState({\n shouldCacheIgnoreZoom: false\n });\n },\n duration: (_b = opts === null || opts === void 0 ? void 0 : opts.duration) !== null && _b !== void 0 ? _b : 500\n });\n\n this.cancelInProgresAnimation = () => {\n cancel();\n this.cancelInProgresAnimation = null;\n };\n } else {\n this.setState({\n scrollX,\n scrollY,\n zoom\n });\n }\n };\n /** use when changing scrollX/scrollY/zoom based on user interaction */\n\n\n this.translateCanvas = state => {\n var _a;\n\n (_a = this.cancelInProgresAnimation) === null || _a === void 0 ? void 0 : _a.call(this);\n this.setState(state);\n }; //zsviczian\n\n\n this.zoomToFit = (target = this.scene.getNonDeletedElements(), maxZoom = 1, //null will zoom to max based on viewport\n margin = 0.03) => {\n if (!target) {\n target = this.scene.getNonDeletedElements();\n }\n\n if (target.length === 0) {\n maxZoom = 1;\n }\n\n this.setState((0,_actions_actionCanvas__WEBPACK_IMPORTED_MODULE_55__.zoomToFitElements)(target, this.state, false, this, maxZoom, margin).appState);\n }; //zsviczian\n\n\n this.startLineEditor = (el, selectedPointsIndices = null) => {\n if (!el || !(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(el)) {\n return;\n }\n\n const editingLinearElement = new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(el, this.scene);\n this.setState({\n selectedLinearElement: editingLinearElement,\n editingLinearElement: Object.assign(Object.assign({}, editingLinearElement), {\n selectedPointsIndices\n })\n });\n }; //zsviczian\n\n\n this.updateContainerSize = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(containers => {\n containers.forEach(el => {\n const [x, y] = (0,_math__WEBPACK_IMPORTED_MODULE_28__.rotate)(el.x + el.width, el.y + el.height, el.x + el.width / 2, el.y + el.height / 2, el.angle);\n (0,_element_resizeElements__WEBPACK_IMPORTED_MODULE_45__.resizeSingleElement)(new Map().set(el.id, el), false, el, \"se\", true, x, y);\n });\n });\n\n this.setToast = toast => {\n this.setState({\n toast\n });\n };\n\n this.restoreFileFromShare = async () => {\n try {\n const webShareTargetCache = await caches.open(\"web-share-target\");\n const response = await webShareTargetCache.match(\"shared-file\");\n\n if (response) {\n const blob = await response.blob();\n const file = new File([blob], blob.name || \"\", {\n type: blob.type\n });\n this.loadFileToCanvas(file, null);\n await webShareTargetCache.delete(\"shared-file\");\n window.history.replaceState(null, _constants__WEBPACK_IMPORTED_MODULE_12__.APP_NAME, window.location.pathname);\n }\n } catch (error) {\n this.setState({\n errorMessage: error.message\n });\n }\n };\n /** adds supplied files to existing files in the appState */\n\n\n this.addFiles = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(files => {\n const filesMap = files.reduce((acc, fileData) => {\n acc.set(fileData.id, fileData);\n return acc;\n }, new Map());\n this.files = Object.assign(Object.assign({}, this.files), Object.fromEntries(filesMap));\n this.scene.getNonDeletedElements().forEach(element => {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(element) && filesMap.has(element.fileId)) {\n this.imageCache.delete(element.fileId);\n _scene_ShapeCache__WEBPACK_IMPORTED_MODULE_66__.ShapeCache[\"delete\"](element);\n }\n });\n this.scene.informMutation();\n this.addNewImagesToImageCache();\n }); //zsviczian https://github.com/zsviczian/excalibrain/issues/9\n\n this.setMobileModeAllowed = allow => {\n const {\n width,\n height\n } = this.excalidrawContainerRef.current.getBoundingClientRect();\n this.allowMobileMode = allow;\n\n if (allow) {\n this.device = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.updateObject)(this.device, {\n isMobile: width < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_PORTRAIT || height < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_HEIGHT_LANDSCAPE && width < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_LANDSCAPE\n });\n } else {\n this.device = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.updateObject)(this.device, {\n isMobile: false\n });\n }\n\n this.forceUpdate();\n }; //zsviczian\n\n\n this.setLocalFont = showOnPanel => {\n showFourthFont = showOnPanel;\n };\n\n this.selectElements = elements => {\n this.updateScene({\n appState: Object.assign(Object.assign({}, this.state), {\n editingGroupId: null,\n selectedElementIds: elements.reduce((map, element) => {\n map[element.id] = true;\n return map;\n }, {})\n }),\n commitToHistory: true\n });\n };\n\n this.bringToFront = elements => {\n this.selectElements(elements);\n this.updateScene(_actions__WEBPACK_IMPORTED_MODULE_5__.actionBringToFront.perform(this.scene.getNonDeletedElements(), this.state));\n };\n\n this.bringForward = elements => {\n this.selectElements(elements);\n this.updateScene(_actions__WEBPACK_IMPORTED_MODULE_5__.actionBringForward.perform(this.scene.getNonDeletedElements(), this.state));\n };\n\n this.sendToBack = elements => {\n this.selectElements(elements);\n this.updateScene(_actions__WEBPACK_IMPORTED_MODULE_5__.actionSendToBack.perform(this.scene.getNonDeletedElements(), this.state));\n };\n\n this.sendBackward = elements => {\n this.selectElements(elements);\n this.updateScene(_actions__WEBPACK_IMPORTED_MODULE_5__.actionSendBackward.perform(this.scene.getNonDeletedElements(), this.state));\n };\n\n this.updateScene = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(sceneData => {\n if (sceneData.commitToHistory) {\n this.history.resumeRecording();\n }\n\n (0,react_dom__WEBPACK_IMPORTED_MODULE_2__.flushSync)(() => {\n if (sceneData.appState) {\n this.setState(sceneData.appState);\n }\n });\n\n if (sceneData.elements) {\n this.scene.replaceAllElements(sceneData.elements);\n }\n\n if (sceneData.collaborators) {\n this.setState({\n collaborators: sceneData.collaborators\n });\n }\n });\n\n this.onSceneUpdated = () => {\n this.setState({});\n };\n /**\r\n * @returns whether the menu was toggled on or off\r\n */\n\n\n this.toggleSidebar = ({\n name,\n tab,\n force\n }) => {\n var _a;\n\n let nextName;\n\n if (force === undefined) {\n nextName = ((_a = this.state.openSidebar) === null || _a === void 0 ? void 0 : _a.name) === name ? null : name;\n } else {\n nextName = force ? name : null;\n }\n\n this.setState({\n openSidebar: nextName ? {\n name: nextName,\n tab\n } : null\n });\n return !!nextName;\n };\n\n this.updateCurrentCursorPosition = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(event => {\n this.lastViewportPosition.x = event.clientX;\n this.lastViewportPosition.y = event.clientY;\n }); // Input handling\n\n this.onKeyDown = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(event => {\n // normalize `event.key` when CapsLock is pressed #2372\n if (\"Proxy\" in window && (!event.shiftKey && /^[A-Z]$/.test(event.key) || event.shiftKey && /^[a-z]$/.test(event.key))) {\n event = new Proxy(event, {\n get(ev, prop) {\n const value = ev[prop];\n\n if (typeof value === \"function\") {\n // fix for Proxies hijacking `this`\n return value.bind(ev);\n }\n\n return prop === \"key\" ? // CapsLock inverts capitalization based on ShiftKey, so invert\n // it back\n event.shiftKey ? ev.key.toUpperCase() : ev.key.toLowerCase() : value;\n }\n\n });\n }\n\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && event.key.toLowerCase() === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.V) {\n IS_PLAIN_PASTE = event.shiftKey;\n clearTimeout(IS_PLAIN_PASTE_TIMER); // reset (100ms to be safe that we it runs after the ensuing\n // paste event). Though, technically unnecessary to reset since we\n // (re)set the flag before each paste event.\n\n IS_PLAIN_PASTE_TIMER = window.setTimeout(() => {\n IS_PLAIN_PASTE = false;\n }, 100);\n } // prevent browser zoom in input fields\n\n\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && (0,_utils__WEBPACK_IMPORTED_MODULE_33__.isWritableElement)(event.target)) {\n if (event.code === _keys__WEBPACK_IMPORTED_MODULE_26__.CODES.MINUS || event.code === _keys__WEBPACK_IMPORTED_MODULE_26__.CODES.EQUAL) {\n event.preventDefault();\n return;\n }\n } // bail if\n\n\n if ( // inside an input\n (0,_utils__WEBPACK_IMPORTED_MODULE_33__.isWritableElement)(event.target) && // unless pressing escape (finalize action)\n event.key !== _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ESCAPE || // or unless using arrows (to move between buttons)\n (0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key) && (0,_utils__WEBPACK_IMPORTED_MODULE_33__.isInputLike)(event.target)) {\n return;\n }\n\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.QUESTION_MARK) {\n this.setState({\n openDialog: \"help\"\n });\n return;\n } else if (event.key.toLowerCase() === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.E && event.shiftKey && event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\n event.preventDefault();\n this.setState({\n openDialog: \"imageExport\"\n });\n return;\n }\n\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.PAGE_UP || event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.PAGE_DOWN) {\n let offset = (event.shiftKey ? this.state.width : this.state.height) / this.state.zoom.value;\n\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.PAGE_DOWN) {\n offset = -offset;\n }\n\n if (event.shiftKey) {\n this.translateCanvas(state => ({\n scrollX: state.scrollX + offset\n }));\n } else {\n this.translateCanvas(state => ({\n scrollY: state.scrollY + offset\n }));\n }\n }\n\n if (this.actionManager.handleKeyDown(event)) {\n return;\n }\n\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.K && !event.altKey && !event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\n if ((0,_appState__WEBPACK_IMPORTED_MODULE_10__.isLaserPointerActive)(this.state)) {\n this.setActiveTool({\n type: \"selection\"\n });\n } else {\n this.setActiveTool({\n type: \"laser\"\n });\n }\n\n return;\n }\n\n if (this.state.viewModeEnabled) {\n //revert to hand in case a key is pressed (K is handled above)\n if (event.key !== _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.K) {\n this.setActiveTool({\n type: \"selection\"\n });\n }\n\n return;\n }\n\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && this.state.isBindingEnabled) {\n this.setState({\n isBindingEnabled: false\n });\n }\n\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key)) {\n const step = this.state.gridSize && (event.shiftKey ? _constants__WEBPACK_IMPORTED_MODULE_12__.ELEMENT_TRANSLATE_AMOUNT : this.state.gridSize) || (event.shiftKey ? _constants__WEBPACK_IMPORTED_MODULE_12__.ELEMENT_SHIFT_TRANSLATE_AMOUNT : _constants__WEBPACK_IMPORTED_MODULE_12__.ELEMENT_TRANSLATE_AMOUNT);\n let offsetX = 0;\n let offsetY = 0;\n\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_LEFT) {\n offsetX = -step;\n } else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_RIGHT) {\n offsetX = step;\n } else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_UP) {\n offsetY = -step;\n } else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_DOWN) {\n offsetY = step;\n }\n\n const selectedElements = this.scene.getSelectedElements({\n selectedElementIds: this.state.selectedElementIds,\n includeBoundTextElement: true,\n includeElementsInFrames: true\n });\n selectedElements.forEach(element => {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n x: element.x + offsetX,\n y: element.y + offsetY\n });\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.updateBoundElements)(element, {\n simultaneouslyUpdated: selectedElements\n });\n });\n this.maybeSuggestBindingForAll(selectedElements);\n event.preventDefault();\n } else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ENTER) {\n const selectedElements = this.scene.getSelectedElements(this.state);\n\n if (selectedElements.length === 1) {\n const selectedElement = selectedElements[0];\n\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElement)) {\n if (!this.state.editingLinearElement || this.state.editingLinearElement.elementId !== selectedElements[0].id) {\n this.history.resumeRecording();\n this.setState({\n editingLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(selectedElement, this.scene)\n });\n }\n }\n } else if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(selectedElement) || (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.isValidTextContainer)(selectedElement)) {\n let container;\n\n if (!(0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(selectedElement)) {\n container = selectedElement;\n }\n\n const midPoint = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getContainerCenter)(selectedElement, this.state);\n const sceneX = midPoint.x;\n const sceneY = midPoint.y;\n this.startTextEditing({\n sceneX,\n sceneY,\n container\n });\n event.preventDefault();\n return;\n } else if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isFrameElement)(selectedElement)) {\n this.setState({\n editingFrame: selectedElement.id\n });\n }\n }\n } else if (!event.ctrlKey && !event.altKey && !event.metaKey && this.state.draggingElement === null) {\n const shape = (0,_shapes__WEBPACK_IMPORTED_MODULE_32__.findShapeByKey)(event.key);\n\n if (shape) {\n if (this.state.activeTool.type !== shape) {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_9__.trackEvent)(\"toolbar\", shape, `keyboard (${this.device.isMobile ? \"mobile\" : \"desktop\"})`);\n }\n\n this.setActiveTool({\n type: shape\n });\n event.stopPropagation();\n } else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.Q) {\n this.toggleLock(\"keyboard\");\n event.stopPropagation();\n }\n }\n\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.SPACE && gesture.pointers.size === 0) {\n isHoldingSpace = true;\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n event.preventDefault();\n }\n\n if ((event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.G || event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.S) && !event.altKey && !event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\n const selectedElements = this.scene.getSelectedElements(this.state);\n\n if (this.state.activeTool.type === \"selection\" && !selectedElements.length) {\n return;\n }\n\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.G && ((0,_scene__WEBPACK_IMPORTED_MODULE_29__.hasBackground)(this.state.activeTool.type) || selectedElements.some(element => (0,_scene__WEBPACK_IMPORTED_MODULE_29__.hasBackground)(element.type)))) {\n this.setState({\n openPopup: \"elementBackground\"\n });\n event.stopPropagation();\n }\n\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.S) {\n this.setState({\n openPopup: \"elementStroke\"\n });\n event.stopPropagation();\n }\n }\n\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.BACKSPACE || event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.DELETE)) {\n _jotai__WEBPACK_IMPORTED_MODULE_56__.jotaiStore.set(_ActiveConfirmDialog__WEBPACK_IMPORTED_MODULE_57__.activeConfirmDialogAtom, \"clearCanvas\");\n } // eye dropper\n // -----------------------------------------------------------------------\n\n\n const lowerCased = event.key.toLocaleLowerCase();\n const isPickingStroke = lowerCased === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.S && event.shiftKey;\n const isPickingBackground = event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.I || lowerCased === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.G && event.shiftKey;\n\n if (isPickingStroke || isPickingBackground) {\n this.openEyeDropper({\n type: isPickingStroke ? \"stroke\" : \"background\"\n });\n } // -----------------------------------------------------------------------\n\n });\n this.onWheel = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(event => {\n // prevent browser pinch zoom on DOM elements\n if (!(event.target instanceof HTMLCanvasElement) && event.ctrlKey) {\n event.preventDefault();\n }\n });\n this.onKeyUp = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(event => {\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.SPACE) {\n if (this.state.viewModeEnabled) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n } else if (this.state.activeTool.type === \"selection\") {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.resetCursor)(this.interactiveCanvas);\n } else {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursorForShape)(this.interactiveCanvas, this.state);\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({}, this.state),\n selectedGroupIds: {},\n editingGroupId: null,\n activeEmbeddable: null\n });\n }\n\n isHoldingSpace = false;\n }\n\n if (!event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && !this.state.isBindingEnabled) {\n this.setState({\n isBindingEnabled: true\n });\n }\n\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key)) {\n const selectedElements = this.scene.getSelectedElements(this.state);\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state) ? (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.bindOrUnbindSelectedElements)(selectedElements) : (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.unbindLinearElements)(selectedElements);\n this.setState({\n suggestedBindings: []\n });\n }\n });\n\n this.setActiveTool = tool => {\n var _a;\n\n const nextActiveTool = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.updateActiveTool)(this.state, tool);\n\n if (nextActiveTool.type === \"hand\") {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n } else if (!isHoldingSpace) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursorForShape)(this.interactiveCanvas, this.state);\n }\n\n if ((0,_utils__WEBPACK_IMPORTED_MODULE_33__.isToolIcon)(document.activeElement)) {\n this.focusContainer();\n }\n\n if (!(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElementType)(nextActiveTool.type)) {\n this.setState({\n suggestedBindings: []\n });\n }\n\n if (nextActiveTool.type === \"image\") {\n this.onImageAction({\n insertOnCanvasDirectly: (_a = tool.type === \"image\" && tool.insertOnCanvasDirectly) !== null && _a !== void 0 ? _a : false\n });\n }\n\n this.setState(prevState => {\n const commonResets = {\n snapLines: prevState.snapLines.length ? [] : prevState.snapLines,\n originSnapOffset: null,\n activeEmbeddable: null\n };\n\n if (nextActiveTool.type !== \"selection\") {\n return Object.assign(Object.assign(Object.assign({}, prevState), {\n activeTool: nextActiveTool,\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(nextActiveTool.type === \"mermaid\" //zsviczian\n ? this.state.selectedElementIds : {}, prevState),\n selectedGroupIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({}, prevState),\n editingGroupId: null,\n multiElement: null\n }), commonResets);\n }\n\n return Object.assign(Object.assign(Object.assign({}, prevState), {\n activeTool: nextActiveTool\n }), commonResets);\n });\n };\n\n this.setCursor = cursor => {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, cursor);\n };\n\n this.resetCursor = () => {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.resetCursor)(this.interactiveCanvas);\n };\n /**\r\n * returns whether user is making a gesture with >= 2 fingers (points)\r\n * on o touch screen (not on a trackpad). Currently only relates to Darwin\r\n * (iOS/iPadOS,MacOS), but may work on other devices in the future if\r\n * GestureEvent is standardized.\r\n */\n\n\n this.isTouchScreenMultiTouchGesture = () => {\n // we don't want to deselect when using trackpad, and multi-point gestures\n // only work on touch screens, so checking for >= pointers means we're on a\n // touchscreen\n return gesture.pointers.size >= 2;\n }; // fires only on Safari\n\n\n this.onGestureStart = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(event => {\n event.preventDefault(); // we only want to deselect on touch screens because user may have selected\n // elements by mistake while zooming\n\n if (this.isTouchScreenMultiTouchGesture()) {\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({}, this.state),\n activeEmbeddable: null\n });\n }\n\n gesture.initialScale = this.state.zoom.value;\n }); // fires only on Safari\n\n this.onGestureChange = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(event => {\n event.preventDefault(); // onGestureChange only has zoom factor but not the center.\n // If we're on iPad or iPhone, then we recognize multi-touch and will\n // zoom in at the right location in the touchmove handler\n // (handleCanvasPointerMove).\n //\n // On Macbook trackpad, we don't have those events so will zoom in at the\n // current location instead.\n //\n // As such, bail from this handler on touch devices.\n\n if (this.isTouchScreenMultiTouchGesture()) {\n return;\n }\n\n const initialScale = gesture.initialScale;\n\n if (initialScale) {\n this.setState(state => Object.assign({}, (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_31__.getStateForZoom)({\n viewportX: this.lastViewportPosition.x,\n viewportY: this.lastViewportPosition.y,\n nextZoom: (0,_scene__WEBPACK_IMPORTED_MODULE_29__.getNormalizedZoom)(initialScale * event.scale)\n }, state)));\n }\n }); // fires only on Safari\n\n this.onGestureEnd = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(event => {\n event.preventDefault(); // reselect elements only on touch screens (see onGestureStart)\n\n if (this.isTouchScreenMultiTouchGesture()) {\n this.setState({\n previousSelectedElementIds: {},\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(this.state.previousSelectedElementIds, this.state)\n });\n }\n\n gesture.initialScale = null;\n });\n\n this.startTextEditing = ({\n sceneX,\n sceneY,\n insertAtParentCenter = true,\n container\n }) => {\n var _a, _b;\n\n let shouldBindToContainer = false;\n let parentCenterPosition = insertAtParentCenter && this.getTextWysiwygSnappedToCenterPosition(sceneX, sceneY, this.state, container);\n\n if (container && parentCenterPosition) {\n const boundTextElementToContainer = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getBoundTextElement)(container);\n\n if (!boundTextElementToContainer) {\n shouldBindToContainer = true;\n }\n }\n\n let existingTextElement = null;\n const selectedElements = this.scene.getSelectedElements(this.state);\n\n if (selectedElements.length === 1) {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(selectedElements[0])) {\n existingTextElement = selectedElements[0];\n } else if (container) {\n existingTextElement = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getBoundTextElement)(selectedElements[0]);\n } else {\n existingTextElement = this.getTextElementAtPosition(sceneX, sceneY);\n }\n } else {\n existingTextElement = this.getTextElementAtPosition(sceneX, sceneY);\n }\n\n const fontFamily = (existingTextElement === null || existingTextElement === void 0 ? void 0 : existingTextElement.fontFamily) || this.state.currentItemFontFamily;\n const lineHeight = (existingTextElement === null || existingTextElement === void 0 ? void 0 : existingTextElement.lineHeight) || (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getDefaultLineHeight)(fontFamily);\n const fontSize = this.state.currentItemFontSize;\n\n if (!existingTextElement && shouldBindToContainer && container && !(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isArrowElement)(container)) {\n const fontString = {\n fontSize,\n fontFamily\n };\n const minWidth = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getApproxMinLineWidth)((0,_utils__WEBPACK_IMPORTED_MODULE_33__.getFontString)(fontString), lineHeight);\n const minHeight = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getApproxMinLineHeight)(fontSize, lineHeight);\n const newHeight = Math.max(container.height, minHeight);\n const newWidth = Math.max(container.width, minWidth);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(container, {\n height: newHeight,\n width: newWidth\n });\n sceneX = container.x + newWidth / 2;\n sceneY = container.y + newHeight / 2;\n\n if (parentCenterPosition) {\n parentCenterPosition = this.getTextWysiwygSnappedToCenterPosition(sceneX, sceneY, this.state, container);\n }\n }\n\n const topLayerFrame = this.getTopLayerFrameAtSceneCoords({\n x: sceneX,\n y: sceneY\n });\n const element = existingTextElement ? existingTextElement : (0,_element__WEBPACK_IMPORTED_MODULE_16__.newTextElement)({\n x: parentCenterPosition ? parentCenterPosition.elementCenterX : sceneX,\n y: parentCenterPosition ? parentCenterPosition.elementCenterY : sceneY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n text: \"\",\n rawText: \"\",\n fontSize,\n fontFamily,\n textAlign: parentCenterPosition ? \"center\" : this.state.currentItemTextAlign,\n verticalAlign: parentCenterPosition ? _constants__WEBPACK_IMPORTED_MODULE_12__.VERTICAL_ALIGN.MIDDLE : _constants__WEBPACK_IMPORTED_MODULE_12__.DEFAULT_VERTICAL_ALIGN,\n containerId: shouldBindToContainer ? container === null || container === void 0 ? void 0 : container.id : undefined,\n groupIds: (_a = container === null || container === void 0 ? void 0 : container.groupIds) !== null && _a !== void 0 ? _a : [],\n lineHeight,\n angle: (_b = container === null || container === void 0 ? void 0 : container.angle) !== null && _b !== void 0 ? _b : 0,\n frameId: topLayerFrame ? topLayerFrame.id : null\n });\n\n if (!existingTextElement && shouldBindToContainer && container) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(container, {\n boundElements: (container.boundElements || []).concat({\n type: \"text\",\n id: element.id\n })\n });\n }\n\n this.setState({\n editingElement: element\n });\n\n if (!existingTextElement) {\n if (container && shouldBindToContainer) {\n const containerIndex = this.scene.getElementIndex(container.id);\n this.scene.insertElementAtIndex(element, containerIndex + 1);\n } else {\n this.scene.addNewElement(element);\n }\n }\n\n this.setState({\n editingElement: element\n });\n this.handleTextWysiwyg(element, {\n isExistingElement: !!existingTextElement\n });\n };\n\n this.handleCanvasDoubleClick = event => {\n // case: double-clicking with arrow/line tool selected would both create\n // text and enter multiElement mode\n if (this.state.multiElement) {\n return;\n }\n\n if (this.state.viewModeEnabled) {\n if (this.state.activeTool.type === \"laser\") {\n this.setActiveTool({\n type: \"selection\"\n });\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n } else {\n this.setActiveTool({\n type: \"laser\"\n });\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.CROSSHAIR);\n }\n\n return;\n } // we should only be able to double click when mode is selection\n\n\n if (this.state.activeTool.type !== \"selection\") {\n return;\n }\n\n const selectedElements = this.scene.getSelectedElements(this.state);\n\n if (selectedElements.length === 1 && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0])) {\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && (!this.state.editingLinearElement || this.state.editingLinearElement.elementId !== selectedElements[0].id)) {\n this.history.resumeRecording();\n this.setState({\n editingLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(selectedElements[0], this.scene)\n });\n return;\n } else if (this.state.editingLinearElement && this.state.editingLinearElement.elementId === selectedElements[0].id) {\n return;\n }\n }\n\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.resetCursor)(this.interactiveCanvas);\n let {\n x: sceneX,\n y: sceneY\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)(event, this.state);\n const selectedGroupIds = (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getSelectedGroupIds)(this.state);\n\n if (selectedGroupIds.length > 0) {\n const hitElement = this.getElementAtPosition(sceneX, sceneY);\n const selectedGroupId = hitElement && (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getSelectedGroupIdForElement)(hitElement, this.state.selectedGroupIds);\n\n if (selectedGroupId) {\n this.setState(prevState => Object.assign(Object.assign({}, prevState), (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)({\n editingGroupId: selectedGroupId,\n selectedElementIds: {\n [hitElement.id]: true\n }\n }, this.scene.getNonDeletedElements(), prevState, this)));\n return;\n }\n }\n\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.resetCursor)(this.interactiveCanvas);\n\n if (!event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && !this.state.viewModeEnabled) {\n const hitElement = this.getElementAtPosition(sceneX, sceneY);\n\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isEmbeddableElement)(hitElement)) {\n this.setState({\n activeEmbeddable: {\n element: hitElement,\n state: \"active\"\n }\n });\n return;\n }\n\n const container = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getTextBindableContainerAtPosition)(this.scene.getNonDeletedElements(), this.state, sceneX, sceneY);\n\n if (container) {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.hasBoundTextElement)(container) || !(0,_utils__WEBPACK_IMPORTED_MODULE_33__.isTransparent)(container.backgroundColor) || (0,_element_collision__WEBPACK_IMPORTED_MODULE_44__.isHittingElementNotConsideringBoundingBox)(container, this.state, this.frameNameBoundsCache, [sceneX, sceneY])) {\n const midPoint = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getContainerCenter)(container, this.state);\n sceneX = midPoint.x;\n sceneY = midPoint.y;\n }\n }\n\n this.startTextEditing({\n sceneX,\n sceneY,\n insertAtParentCenter: !event.altKey,\n container\n });\n }\n };\n\n this.getElementLinkAtPosition = (scenePointer, hitElement) => {\n // Reversing so we traverse the elements in decreasing order\n // of z-index\n const elements = this.scene.getNonDeletedElements().slice().reverse();\n let hitElementIndex = Infinity;\n return elements.find((element, index) => {\n if (hitElement && element.id === hitElement.id) {\n hitElementIndex = index;\n }\n\n return element.link && index <= hitElementIndex && (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_46__.isPointHittingLink)(element, this.state, [scenePointer.x, scenePointer.y], this.device.isMobile);\n });\n };\n\n this.redirectToLink = (event, isTouchScreen) => {\n const draggedDistance = (0,_math__WEBPACK_IMPORTED_MODULE_28__.distance2d)(this.lastPointerDownEvent.clientX, this.lastPointerDownEvent.clientY, this.lastPointerUpEvent.clientX, this.lastPointerUpEvent.clientY);\n\n if (!this.hitLinkElement || // For touch screen allow dragging threshold else strict check\n isTouchScreen && draggedDistance > _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD || !isTouchScreen && draggedDistance !== 0) {\n return;\n }\n\n const lastPointerDownCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)(this.lastPointerDownEvent, this.state);\n const lastPointerDownHittingLinkIcon = (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_46__.isPointHittingLink)(this.hitLinkElement, this.state, [lastPointerDownCoords.x, lastPointerDownCoords.y], this.device.isMobile);\n const lastPointerUpCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)(this.lastPointerUpEvent, this.state);\n const lastPointerUpHittingLinkIcon = (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_46__.isPointHittingLink)(this.hitLinkElement, this.state, [lastPointerUpCoords.x, lastPointerUpCoords.y], this.device.isMobile);\n\n if (lastPointerDownHittingLinkIcon && lastPointerUpHittingLinkIcon) {\n let url = this.hitLinkElement.link;\n\n if (url) {\n url = (0,_data_url__WEBPACK_IMPORTED_MODULE_47__.normalizeLink)(url);\n let customEvent;\n\n if (this.props.onLinkOpen) {\n customEvent = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.wrapEvent)(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.EXCALIDRAW_LINK, event.nativeEvent);\n this.props.onLinkOpen(Object.assign(Object.assign({}, this.hitLinkElement), {\n link: url\n }), customEvent);\n }\n\n if (!(customEvent === null || customEvent === void 0 ? void 0 : customEvent.defaultPrevented)) {\n const target = (0,_data_url__WEBPACK_IMPORTED_MODULE_47__.isLocalLink)(url) ? \"_self\" : \"_blank\";\n const newWindow = window.open(undefined, target); // https://mathiasbynens.github.io/rel-noopener/\n\n if (newWindow) {\n newWindow.opener = null;\n newWindow.location = url;\n }\n }\n }\n }\n };\n\n this.getTopLayerFrameAtSceneCoords = sceneCoords => {\n const frames = this.scene.getNonDeletedFrames().filter(frame => (0,_frame__WEBPACK_IMPORTED_MODULE_51__.isCursorInFrame)(sceneCoords, frame));\n return frames.length ? frames[frames.length - 1] : null;\n };\n\n this.handleCanvasPointerMove = event => {\n var _a, _b;\n\n this.savePointer(event.clientX, event.clientY, this.state.cursorButton);\n\n if (gesture.pointers.has(event.pointerId)) {\n gesture.pointers.set(event.pointerId, {\n x: event.clientX,\n y: event.clientY\n });\n }\n\n const initialScale = gesture.initialScale;\n\n if (gesture.pointers.size === 2 && gesture.lastCenter && initialScale && gesture.initialDistance) {\n const center = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getCenter)(gesture.pointers);\n const deltaX = center.x - gesture.lastCenter.x;\n const deltaY = center.y - gesture.lastCenter.y;\n gesture.lastCenter = center;\n const distance = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getDistance)(Array.from(gesture.pointers.values()));\n const scaleFactor = !this.state.allowPinchZoom && //zsviczian\n this.state.activeTool.type === \"freedraw\" && this.state.penMode ? 1 : distance / gesture.initialDistance;\n const nextZoom = scaleFactor ? (0,_scene__WEBPACK_IMPORTED_MODULE_29__.getNormalizedZoom)(initialScale * scaleFactor) : this.state.zoom.value;\n this.setState(state => {\n const zoomState = (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_31__.getStateForZoom)({\n viewportX: center.x,\n viewportY: center.y,\n nextZoom\n }, state);\n this.translateCanvas({\n zoom: zoomState.zoom,\n scrollX: zoomState.scrollX + deltaX / nextZoom,\n scrollY: zoomState.scrollY + deltaY / nextZoom,\n shouldCacheIgnoreZoom: true\n });\n });\n this.resetShouldCacheIgnoreZoomDebounced();\n } else {\n gesture.lastCenter = gesture.initialDistance = gesture.initialScale = null;\n }\n\n if (isHoldingSpace || isPanning || isDraggingScrollBar || (0,_appState__WEBPACK_IMPORTED_MODULE_10__.isHandToolActive)(this.state)) {\n return;\n }\n\n const isPointerOverScrollBars = (0,_scene__WEBPACK_IMPORTED_MODULE_29__.isOverScrollBars)(currentScrollBars, event.clientX - this.state.offsetLeft, event.clientY - this.state.offsetTop);\n const isOverScrollBar = isPointerOverScrollBars.isOverEither;\n\n if (!this.state.draggingElement && !this.state.multiElement) {\n if (isOverScrollBar) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.resetCursor)(this.interactiveCanvas);\n } else {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursorForShape)(this.interactiveCanvas, this.state);\n }\n }\n\n const scenePointer = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)(event, this.state);\n const {\n x: scenePointerX,\n y: scenePointerY\n } = scenePointer;\n\n if (!this.state.draggingElement && (0,_snapping__WEBPACK_IMPORTED_MODULE_58__.isActiveToolNonLinearSnappable)(this.state.activeTool.type)) {\n const {\n originOffset,\n snapLines\n } = (0,_snapping__WEBPACK_IMPORTED_MODULE_58__.getSnapLinesAtPointer)(this.scene.getNonDeletedElements(), this.state, {\n x: scenePointerX,\n y: scenePointerY\n }, event);\n this.setState({\n snapLines,\n originSnapOffset: originOffset\n });\n } else if (!this.state.draggingElement) {\n this.setState({\n snapLines: []\n });\n }\n\n if (this.state.editingLinearElement && !this.state.editingLinearElement.isDragging) {\n const editingLinearElement = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerMove(event, scenePointerX, scenePointerY, this.state);\n\n if (editingLinearElement && editingLinearElement !== this.state.editingLinearElement) {\n // Since we are reading from previous state which is not possible with\n // automatic batching in React 18 hence using flush sync to synchronously\n // update the state. Check https://github.com/excalidraw/excalidraw/pull/5508 for more details.\n (0,react_dom__WEBPACK_IMPORTED_MODULE_2__.flushSync)(() => {\n this.setState({\n editingLinearElement\n });\n });\n }\n\n if ((editingLinearElement === null || editingLinearElement === void 0 ? void 0 : editingLinearElement.lastUncommittedPoint) != null) {\n this.maybeSuggestBindingAtCursor(scenePointer);\n } else {\n // causes stack overflow if not sync\n (0,react_dom__WEBPACK_IMPORTED_MODULE_2__.flushSync)(() => {\n this.setState({\n suggestedBindings: []\n });\n });\n }\n }\n\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElementType)(this.state.activeTool.type)) {\n // Hovering with a selected tool or creating new linear element via click\n // and point\n const {\n draggingElement\n } = this.state;\n\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement, false)) {\n this.maybeSuggestBindingsForLinearElementAtCoords(draggingElement, [scenePointer], this.state.startBoundElement);\n } else {\n this.maybeSuggestBindingAtCursor(scenePointer);\n }\n }\n\n if (this.state.multiElement) {\n const {\n multiElement\n } = this.state;\n const {\n x: rx,\n y: ry\n } = multiElement;\n const {\n points,\n lastCommittedPoint\n } = multiElement;\n const lastPoint = points[points.length - 1];\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursorForShape)(this.interactiveCanvas, this.state);\n\n if (lastPoint === lastCommittedPoint) {\n // if we haven't yet created a temp point and we're beyond commit-zone\n // threshold, add a point\n if ((0,_math__WEBPACK_IMPORTED_MODULE_28__.distance2d)(scenePointerX - rx, scenePointerY - ry, lastPoint[0], lastPoint[1]) >= _constants__WEBPACK_IMPORTED_MODULE_12__.LINE_CONFIRM_THRESHOLD) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n points: [...points, [scenePointerX - rx, scenePointerY - ry]]\n });\n } else {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER); // in this branch, we're inside the commit zone, and no uncommitted\n // point exists. Thus do nothing (don't add/remove points).\n }\n } else if (points.length > 2 && lastCommittedPoint && (0,_math__WEBPACK_IMPORTED_MODULE_28__.distance2d)(scenePointerX - rx, scenePointerY - ry, lastCommittedPoint[0], lastCommittedPoint[1]) < _constants__WEBPACK_IMPORTED_MODULE_12__.LINE_CONFIRM_THRESHOLD) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n points: points.slice(0, -1)\n });\n } else {\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_28__.getGridPoint)(scenePointerX, scenePointerY, event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] ? null : this.state.gridSize);\n const [lastCommittedX, lastCommittedY] = (_a = multiElement === null || multiElement === void 0 ? void 0 : multiElement.lastCommittedPoint) !== null && _a !== void 0 ? _a : [0, 0];\n let dxFromLastCommitted = gridX - rx - lastCommittedX;\n let dyFromLastCommitted = gridY - ry - lastCommittedY;\n\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldRotateWithDiscreteAngle)(event)) {\n ({\n width: dxFromLastCommitted,\n height: dyFromLastCommitted\n } = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getLockedLinearCursorAlignSize)( // actual coordinate of the last committed point\n lastCommittedX + rx, lastCommittedY + ry, // cursor-grid coordinate\n gridX, gridY));\n }\n\n if ((0,_math__WEBPACK_IMPORTED_MODULE_28__.isPathALoop)(points, this.state.zoom.value)) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n } // update last uncommitted point\n\n\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n points: [...points.slice(0, -1), [lastCommittedX + dxFromLastCommitted, lastCommittedY + dyFromLastCommitted]]\n });\n }\n\n return;\n }\n\n const hasDeselectedButton = Boolean(event.buttons);\n\n if (hasDeselectedButton || this.state.activeTool.type !== \"selection\" && this.state.activeTool.type !== \"text\" && this.state.activeTool.type !== \"eraser\") {\n return;\n }\n\n const elements = this.scene.getNonDeletedElements();\n const selectedElements = this.scene.getSelectedElements(this.state);\n\n if (selectedElements.length === 1 && !isOverScrollBar && !this.state.editingLinearElement) {\n const elementWithTransformHandleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getElementWithTransformHandleType)(elements, this.state, scenePointerX, scenePointerY, this.state.zoom, event.pointerType);\n\n if (elementWithTransformHandleType && elementWithTransformHandleType.transformHandleType) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)(elementWithTransformHandleType));\n return;\n }\n } else if (selectedElements.length > 1 && !isOverScrollBar) {\n const transformHandleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getTransformHandleTypeFromCoords)((0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements), scenePointerX, scenePointerY, this.state.zoom, event.pointerType);\n\n if (transformHandleType) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)({\n transformHandleType\n }));\n return;\n }\n }\n\n const hitElement = this.getElementAtPosition(scenePointer.x, scenePointer.y);\n this.hitLinkElement = this.getElementLinkAtPosition(scenePointer, hitElement);\n\n if ((0,_appState__WEBPACK_IMPORTED_MODULE_10__.isEraserActive)(this.state)) {\n return;\n }\n\n if (this.hitLinkElement && !this.state.selectedElementIds[this.hitLinkElement.id]) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_46__.showHyperlinkTooltip)(this.hitLinkElement, this.state);\n\n if (this.props.onLinkHover) {\n this.props.onLinkHover(this.hitLinkElement, event);\n } //zsviczian\n\n } else {\n (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_46__.hideHyperlinkToolip)();\n\n if (hitElement && (hitElement.link || (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isEmbeddableElement)(hitElement)) && this.state.selectedElementIds[hitElement.id] && !this.state.contextMenu && !this.state.showHyperlinkPopup) {\n this.setState({\n showHyperlinkPopup: \"info\"\n });\n } else if (this.state.activeTool.type === \"text\") {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(hitElement) ? _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.TEXT : _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.CROSSHAIR);\n } else if (this.state.viewModeEnabled) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n } else if (isOverScrollBar) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.AUTO);\n } else if (this.state.selectedLinearElement) {\n this.handleHoverSelectedLinearElement(this.state.selectedLinearElement, scenePointerX, scenePointerY);\n } else if ( // if using cmd/ctrl, we're not dragging\n !event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\n if ((hitElement || this.isHittingCommonBoundingBoxOfSelectedElements(scenePointer, selectedElements)) && !(hitElement === null || hitElement === void 0 ? void 0 : hitElement.locked)) {\n if (hitElement && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isEmbeddableElement)(hitElement) && this.isEmbeddableCenter(hitElement, event, scenePointerX, scenePointerY)) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n this.setState({\n activeEmbeddable: {\n element: hitElement,\n state: \"hover\"\n }\n });\n } else {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.MOVE);\n\n if (((_b = this.state.activeEmbeddable) === null || _b === void 0 ? void 0 : _b.state) === \"hover\") {\n this.setState({\n activeEmbeddable: null\n });\n }\n }\n }\n } else {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.AUTO);\n }\n }\n };\n\n this.handleEraser = (event, pointerDownState, scenePointer) => {\n const updateElementIds = elements => {\n elements.forEach(element => {\n if (element.locked) {\n return;\n }\n\n idsToUpdate.push(element.id);\n\n if (event.altKey) {\n if (pointerDownState.elementIdsToErase[element.id] && pointerDownState.elementIdsToErase[element.id].erase) {\n pointerDownState.elementIdsToErase[element.id].erase = false;\n }\n } else if (!pointerDownState.elementIdsToErase[element.id]) {\n pointerDownState.elementIdsToErase[element.id] = {\n erase: true,\n opacity: element.opacity\n };\n }\n });\n };\n\n const idsToUpdate = [];\n const distance = (0,_math__WEBPACK_IMPORTED_MODULE_28__.distance2d)(pointerDownState.lastCoords.x, pointerDownState.lastCoords.y, scenePointer.x, scenePointer.y);\n const threshold = 10 / this.state.zoom.value;\n const point = Object.assign({}, pointerDownState.lastCoords);\n let samplingInterval = 0;\n\n while (samplingInterval <= distance) {\n const hitElements = this.getElementsAtPosition(point.x, point.y);\n updateElementIds(hitElements); // Exit since we reached current point\n\n if (samplingInterval === distance) {\n break;\n } // Calculate next point in the line at a distance of sampling interval\n\n\n samplingInterval = Math.min(samplingInterval + threshold, distance);\n const distanceRatio = samplingInterval / distance;\n const nextX = (1 - distanceRatio) * point.x + distanceRatio * scenePointer.x;\n const nextY = (1 - distanceRatio) * point.y + distanceRatio * scenePointer.y;\n point.x = nextX;\n point.y = nextY;\n }\n\n const elements = this.scene.getElementsIncludingDeleted().map(ele => {\n const id = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(ele) && idsToUpdate.includes(ele.containerId) ? ele.containerId : ele.id;\n\n if (idsToUpdate.includes(id)) {\n if (event.altKey) {\n if (pointerDownState.elementIdsToErase[id] && pointerDownState.elementIdsToErase[id].erase === false) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n opacity: pointerDownState.elementIdsToErase[id].opacity\n });\n }\n } else {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n opacity: _constants__WEBPACK_IMPORTED_MODULE_12__.ELEMENT_READY_TO_ERASE_OPACITY\n });\n }\n }\n\n return ele;\n });\n this.scene.replaceAllElements(elements);\n pointerDownState.lastCoords.x = scenePointer.x;\n pointerDownState.lastCoords.y = scenePointer.y;\n }; // set touch moving for mobile context menu\n\n\n this.handleTouchMove = event => {\n invalidateContextMenu = true;\n };\n\n this.handleCanvasPointerDown = event => {\n var _a, _b;\n\n this.focusContainer(); //zsviczian\n // since contextMenu options are potentially evaluated on each render,\n // and an contextMenu action may depend on selection state, we must\n // close the contextMenu before we update the selection on pointerDown\n // (e.g. resetting selection)\n\n if (this.state.contextMenu) {\n this.setState({\n contextMenu: null\n });\n }\n\n if (this.state.snapLines) {\n this.setAppState({\n snapLines: []\n });\n }\n\n this.updateGestureOnPointerDown(event); // if dragging element is freedraw and another pointerdown event occurs\n // a second finger is on the screen\n // discard the freedraw element if it is very short because it is likely\n // just a spike, otherwise finalize the freedraw element when the second\n // finger is lifted\n\n if (event.pointerType === \"touch\" && this.state.draggingElement && this.state.draggingElement.type === \"freedraw\") {\n const element = this.state.draggingElement;\n this.updateScene(Object.assign(Object.assign({}, element.points.length < 10 ? {\n elements: this.scene.getElementsIncludingDeleted().filter(el => el.id !== element.id)\n } : {}), {\n appState: {\n draggingElement: null,\n editingElement: null,\n startBoundElement: null,\n suggestedBindings: [],\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(Object.keys(this.state.selectedElementIds).filter(key => key !== element.id).reduce((obj, key) => {\n obj[key] = this.state.selectedElementIds[key];\n return obj;\n }, {}), this.state)\n }\n }));\n return;\n } // remove any active selection when we start to interact with canvas\n // (mainly, we care about removing selection outside the component which\n // would prevent our copy handling otherwise)\n\n\n const selection = document.getSelection();\n\n if (selection === null || selection === void 0 ? void 0 : selection.anchorNode) {\n selection.removeAllRanges();\n }\n\n this.maybeOpenContextMenuAfterPointerDownOnTouchDevices(event);\n this.maybeCleanupAfterMissingPointerUp(event); //fires only once, if pen is detected, penMode is enabled\n //the user can disable this by toggling the penMode button\n\n if (!this.state.penDetected && event.pointerType === \"pen\") {\n this.setState(prevState => {\n return {\n penMode: true,\n penDetected: true\n };\n });\n }\n\n if (!this.device.isTouchScreen && [\"pen\", \"touch\"].includes(event.pointerType)) {\n this.device = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.updateObject)(this.device, {\n isTouchScreen: true\n });\n }\n\n if (isPanning) {\n return;\n }\n\n this.lastPointerDownEvent = event; // we must exit before we set `cursorButton` state and `savePointer`\n // else it will send pointer state & laser pointer events in collab when\n // panning\n\n if (this.handleCanvasPanUsingWheelOrSpaceDrag(event)) {\n return;\n }\n\n this.setState({\n lastPointerDownWith: event.pointerType,\n cursorButton: \"down\"\n });\n this.savePointer(event.clientX, event.clientY, \"down\");\n\n if (this.handleCanvasPanUsingWheelOrSpaceDrag(event)) {\n return;\n } // only handle left mouse button or touch\n\n\n if (event.button !== _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.MAIN && event.button !== _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.TOUCH) {\n return;\n } // don't select while panning\n\n\n if (gesture.pointers.size > 1) {\n return;\n } // State for the duration of a pointer interaction, which starts with a\n // pointerDown event, ends with a pointerUp event (or another pointerDown)\n\n\n const pointerDownState = this.initialPointerDownState(event);\n this.setState({\n selectedElementsAreBeingDragged: false\n });\n\n if (this.handleDraggingScrollBar(event, pointerDownState)) {\n return;\n }\n\n this.clearSelectionIfNotUsingSelection();\n this.updateBindingEnabledOnPointerMove(event);\n\n if (this.handleSelectionOnPointerDown(event, pointerDownState)) {\n return;\n }\n\n const allowOnPointerDown = !this.state.penMode || event.pointerType !== \"touch\" || this.state.activeTool.type === \"selection\" || this.state.activeTool.type === \"text\" || this.state.activeTool.type === \"image\";\n\n if (!allowOnPointerDown) {\n return;\n }\n\n if (this.state.activeTool.type === \"text\") {\n this.handleTextOnPointerDown(event, pointerDownState);\n return;\n } else if (this.state.activeTool.type === \"arrow\" || this.state.activeTool.type === \"line\") {\n this.handleLinearElementOnPointerDown(event, this.state.activeTool.type, pointerDownState);\n } else if (this.state.activeTool.type === \"image\") {\n // reset image preview on pointerdown\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.CROSSHAIR); // retrieve the latest element as the state may be stale\n\n const pendingImageElement = this.state.pendingImageElementId && this.scene.getElement(this.state.pendingImageElementId);\n\n if (!pendingImageElement) {\n return;\n }\n\n this.setState({\n draggingElement: pendingImageElement,\n editingElement: pendingImageElement,\n pendingImageElementId: null,\n multiElement: null\n });\n const {\n x,\n y\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)(event, this.state);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(pendingImageElement, {\n x,\n y\n });\n } else if (this.state.activeTool.type === \"freedraw\") {\n this.handleFreeDrawElementOnPointerDown(event, this.state.activeTool.type, pointerDownState);\n } else if (this.state.activeTool.type === \"custom\") {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursorForShape)(this.interactiveCanvas, this.state);\n } else if (this.state.activeTool.type === \"frame\") {\n this.createFrameElementOnPointerDown(pointerDownState);\n } else if (this.state.activeTool.type === \"laser\") {\n this.laserPathManager.startPath(pointerDownState.lastCoords.x, pointerDownState.lastCoords.y);\n } else if (this.state.activeTool.type !== \"eraser\" && this.state.activeTool.type !== \"hand\" && this.state.activeTool.type !== \"mermaid\") {\n this.createGenericElementOnPointerDown(this.state.activeTool.type, pointerDownState);\n }\n\n (_b = (_a = this.props) === null || _a === void 0 ? void 0 : _a.onPointerDown) === null || _b === void 0 ? void 0 : _b.call(_a, this.state.activeTool, pointerDownState);\n this.onPointerDownEmitter.trigger(this.state.activeTool, pointerDownState, event);\n const onPointerMove = this.onPointerMoveFromPointerDownHandler(pointerDownState);\n const onPointerUp = this.onPointerUpFromPointerDownHandler(pointerDownState);\n const onKeyDown = this.onKeyDownFromPointerDownHandler(pointerDownState);\n const onKeyUp = this.onKeyUpFromPointerDownHandler(pointerDownState);\n lastPointerUp = onPointerUp;\n\n if (!this.state.viewModeEnabled || this.state.activeTool.type === \"laser\") {\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, onPointerUp);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYDOWN, onKeyDown);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYUP, onKeyUp);\n pointerDownState.eventListeners.onMove = onPointerMove;\n pointerDownState.eventListeners.onUp = onPointerUp;\n pointerDownState.eventListeners.onKeyUp = onKeyUp;\n pointerDownState.eventListeners.onKeyDown = onKeyDown;\n }\n };\n\n this.handleCanvasPointerUp = event => {\n var _a, _b;\n\n this.removePointer(event);\n this.lastPointerUpEvent = event;\n const scenePointer = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)({\n clientX: event.clientX,\n clientY: event.clientY\n }, this.state);\n const clicklength = event.timeStamp - ((_b = (_a = this.lastPointerDownEvent) === null || _a === void 0 ? void 0 : _a.timeStamp) !== null && _b !== void 0 ? _b : 0);\n\n if (this.device.isMobile && clicklength < 300) {\n const hitElement = this.getElementAtPosition(scenePointer.x, scenePointer.y);\n\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isEmbeddableElement)(hitElement) && this.isEmbeddableCenter(hitElement, event, scenePointer.x, scenePointer.y)) {\n this.handleEmbeddableCenterClick(hitElement);\n return;\n }\n }\n\n if (this.device.isTouchScreen) {\n const hitElement = this.getElementAtPosition(scenePointer.x, scenePointer.y);\n this.hitLinkElement = this.getElementLinkAtPosition(scenePointer, hitElement);\n }\n\n if (this.hitLinkElement && !this.state.selectedElementIds[this.hitLinkElement.id]) {\n if (clicklength < 300 && this.hitLinkElement.type === \"embeddable\" && !(0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_46__.isPointHittingLinkIcon)(this.hitLinkElement, this.state, [scenePointer.x, scenePointer.y])) {\n this.handleEmbeddableCenterClick(this.hitLinkElement);\n } else {\n this.redirectToLink(event, this.device.isTouchScreen);\n }\n } else if (this.state.viewModeEnabled) {\n this.setState({\n activeEmbeddable: null,\n selectedElementIds: {}\n });\n }\n };\n\n this.maybeOpenContextMenuAfterPointerDownOnTouchDevices = event => {\n // deal with opening context menu on touch devices\n if (event.pointerType === \"touch\") {\n invalidateContextMenu = false;\n\n if (touchTimeout) {\n // If there's already a touchTimeout, this means that there's another\n // touch down and we are doing another touch, so we shouldn't open the\n // context menu.\n invalidateContextMenu = true;\n } else {\n // open the context menu with the first touch's clientX and clientY\n // if the touch is not moving\n touchTimeout = window.setTimeout(() => {\n touchTimeout = 0;\n\n if (!invalidateContextMenu) {\n this.handleCanvasContextMenu(event);\n }\n }, _constants__WEBPACK_IMPORTED_MODULE_12__.TOUCH_CTX_MENU_TIMEOUT);\n }\n }\n };\n\n this.resetContextMenuTimer = () => {\n clearTimeout(touchTimeout);\n touchTimeout = 0;\n invalidateContextMenu = false;\n }; // Returns whether the event is a panning\n\n\n this.handleCanvasPanUsingWheelOrSpaceDrag = event => {\n if (!(gesture.pointers.size <= 1 && (event.button === _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.WHEEL || event.button === _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.MAIN && isHoldingSpace || (0,_appState__WEBPACK_IMPORTED_MODULE_10__.isHandToolActive)(this.state) || this.state.viewModeEnabled && !(0,_appState__WEBPACK_IMPORTED_MODULE_10__.isLaserPointerActive)(this.state))) || (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)) {\n return false;\n }\n\n isPanning = true;\n event.preventDefault();\n let nextPastePrevented = false;\n const isLinux = /Linux/.test(window.navigator.platform);\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRABBING);\n let {\n clientX: lastX,\n clientY: lastY\n } = event;\n const onPointerMove = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdatesThrottled)(event => {\n const deltaX = lastX - event.clientX;\n const deltaY = lastY - event.clientY;\n lastX = event.clientX;\n lastY = event.clientY;\n /*\r\n * Prevent paste event if we move while middle clicking on Linux.\r\n * See issue #1383.\r\n */\n\n if (isLinux && !nextPastePrevented && (Math.abs(deltaX) > 1 || Math.abs(deltaY) > 1)) {\n nextPastePrevented = true;\n /* Prevent the next paste event */\n\n const preventNextPaste = event => {\n document.body.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, preventNextPaste);\n event.stopPropagation();\n };\n /*\r\n * Reenable next paste in case of disabled middle click paste for\r\n * any reason:\r\n * - right click paste\r\n * - empty clipboard\r\n */\n\n\n const enableNextPaste = () => {\n setTimeout(() => {\n document.body.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, preventNextPaste);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, enableNextPaste);\n }, 100);\n };\n\n document.body.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, preventNextPaste);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, enableNextPaste);\n }\n\n this.translateCanvas({\n scrollX: this.state.scrollX - deltaX / this.state.zoom.value,\n scrollY: this.state.scrollY - deltaY / this.state.zoom.value\n });\n });\n const teardown = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(lastPointerUp = () => {\n lastPointerUp = null;\n isPanning = false;\n\n if (!isHoldingSpace) {\n if (this.state.viewModeEnabled) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n } else {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursorForShape)(this.interactiveCanvas, this.state);\n }\n }\n\n this.setState({\n cursorButton: \"up\"\n });\n this.savePointer(event.clientX, event.clientY, \"up\");\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, teardown);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.BLUR, teardown);\n onPointerMove.flush();\n });\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.BLUR, teardown);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove, {\n passive: true\n });\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, teardown);\n return true;\n };\n\n this.clearSelectionIfNotUsingSelection = () => {\n if (this.state.activeTool.type !== \"selection\") {\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({}, this.state),\n selectedGroupIds: {},\n editingGroupId: null,\n activeEmbeddable: null\n });\n }\n };\n /**\r\n * @returns whether the pointer event has been completely handled\r\n */\n\n\n this.handleSelectionOnPointerDown = (event, pointerDownState) => {\n var _a;\n\n if (this.state.activeTool.type === \"selection\") {\n const elements = this.scene.getNonDeletedElements();\n const selectedElements = this.scene.getSelectedElements(this.state);\n\n if (selectedElements.length === 1 && !this.state.editingLinearElement) {\n const elementWithTransformHandleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getElementWithTransformHandleType)(elements, this.state, pointerDownState.origin.x, pointerDownState.origin.y, this.state.zoom, event.pointerType);\n\n if (elementWithTransformHandleType != null) {\n this.setState({\n resizingElement: elementWithTransformHandleType.element\n });\n pointerDownState.resize.handleType = elementWithTransformHandleType.transformHandleType;\n }\n } else if (selectedElements.length > 1) {\n pointerDownState.resize.handleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getTransformHandleTypeFromCoords)((0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements), pointerDownState.origin.x, pointerDownState.origin.y, this.state.zoom, event.pointerType);\n }\n\n if (pointerDownState.resize.handleType) {\n pointerDownState.resize.isResizing = true;\n pointerDownState.resize.offset = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.tupleToCoors)((0,_element__WEBPACK_IMPORTED_MODULE_16__.getResizeOffsetXY)(pointerDownState.resize.handleType, selectedElements, pointerDownState.origin.x, pointerDownState.origin.y));\n\n if (selectedElements.length === 1 && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0]) && selectedElements[0].points.length === 2) {\n pointerDownState.resize.arrowDirection = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getResizeArrowDirection)(pointerDownState.resize.handleType, selectedElements[0]);\n }\n } else {\n if (this.state.selectedLinearElement) {\n const linearElementEditor = this.state.editingLinearElement || this.state.selectedLinearElement;\n const ret = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerDown(event, this.state, this.history, pointerDownState.origin, linearElementEditor);\n\n if (ret.hitElement) {\n pointerDownState.hit.element = ret.hitElement;\n }\n\n if (ret.linearElementEditor) {\n this.setState({\n selectedLinearElement: ret.linearElementEditor\n });\n\n if (this.state.editingLinearElement) {\n this.setState({\n editingLinearElement: ret.linearElementEditor\n });\n }\n }\n\n if (ret.didAddPoint) {\n return true;\n }\n } // hitElement may already be set above, so check first\n\n\n pointerDownState.hit.element = (_a = pointerDownState.hit.element) !== null && _a !== void 0 ? _a : this.getElementAtPosition(pointerDownState.origin.x, pointerDownState.origin.y);\n\n if (pointerDownState.hit.element) {\n // Early return if pointer is hitting link icon\n const hitLinkElement = this.getElementLinkAtPosition({\n x: pointerDownState.origin.x,\n y: pointerDownState.origin.y\n }, pointerDownState.hit.element);\n\n if (hitLinkElement) {\n return false;\n }\n } // For overlapped elements one position may hit\n // multiple elements\n\n\n pointerDownState.hit.allHitElements = this.getElementsAtPosition(pointerDownState.origin.x, pointerDownState.origin.y);\n const hitElement = pointerDownState.hit.element;\n const someHitElementIsSelected = pointerDownState.hit.allHitElements.some(element => this.isASelectedElement(element));\n\n if ((hitElement === null || !someHitElementIsSelected) && !event.shiftKey && !pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) {\n this.clearSelection(hitElement);\n }\n\n if (this.state.editingLinearElement) {\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({\n [this.state.editingLinearElement.elementId]: true\n }, this.state)\n }); // If we click on something\n } else if (hitElement != null) {\n // on CMD/CTRL, drill down to hit element regardless of groups etc.\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\n if (!this.state.selectedElementIds[hitElement.id]) {\n pointerDownState.hit.wasAddedToSelection = true;\n }\n\n this.setState(prevState => Object.assign(Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.editGroupForSelectedElement)(prevState, hitElement)), {\n previousSelectedElementIds: this.state.selectedElementIds\n })); // mark as not completely handled so as to allow dragging etc.\n\n return false;\n } // deselect if item is selected\n // if shift is not clicked, this will always return true\n // otherwise, it will trigger selection based on current\n // state of the box\n\n\n if (!this.state.selectedElementIds[hitElement.id]) {\n // if we are currently editing a group, exiting editing mode and deselect the group.\n if (this.state.editingGroupId && !(0,_groups__WEBPACK_IMPORTED_MODULE_23__.isElementInGroup)(hitElement, this.state.editingGroupId)) {\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({}, this.state),\n selectedGroupIds: {},\n editingGroupId: null,\n activeEmbeddable: null\n });\n } // Add hit element to selection. At this point if we're not holding\n // SHIFT the previously selected element(s) were deselected above\n // (make sure you use setState updater to use latest state)\n // With shift-selection, we want to make sure that frames and their containing\n // elements are not selected at the same time.\n\n\n if (!someHitElementIsSelected && !pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) {\n this.setState(prevState => {\n const nextSelectedElementIds = Object.assign(Object.assign({}, prevState.selectedElementIds), {\n [hitElement.id]: true\n });\n const previouslySelectedElements = [];\n Object.keys(prevState.selectedElementIds).forEach(id => {\n const element = this.scene.getElement(id);\n element && previouslySelectedElements.push(element);\n }); // if hitElement is frame, deselect all of its elements if they are selected\n\n if (hitElement.type === \"frame\") {\n (0,_frame__WEBPACK_IMPORTED_MODULE_51__.getFrameElements)(previouslySelectedElements, hitElement.id).forEach(element => {\n delete nextSelectedElementIds[element.id];\n });\n } else if (hitElement.frameId) {\n // if hitElement is in a frame and its frame has been selected\n // disable selection for the given element\n if (nextSelectedElementIds[hitElement.frameId]) {\n delete nextSelectedElementIds[hitElement.id];\n }\n } else {\n // hitElement is neither a frame nor an element in a frame\n // but since hitElement could be in a group with some frames\n // this means selecting hitElement will have the frames selected as well\n // because we want to keep the invariant:\n // - frames and their elements are not selected at the same time\n // we deselect elements in those frames that were previously selected\n const groupIds = hitElement.groupIds;\n const framesInGroups = new Set(groupIds.flatMap(gid => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getElementsInGroup)(this.scene.getNonDeletedElements(), gid)).filter(element => element.type === \"frame\").map(frame => frame.id));\n\n if (framesInGroups.size > 0) {\n previouslySelectedElements.forEach(element => {\n if (element.frameId && framesInGroups.has(element.frameId)) {\n // deselect element and groups containing the element\n delete nextSelectedElementIds[element.id];\n element.groupIds.flatMap(gid => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getElementsInGroup)(this.scene.getNonDeletedElements(), gid)).forEach(element => {\n delete nextSelectedElementIds[element.id];\n });\n }\n });\n }\n }\n\n return Object.assign(Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)({\n editingGroupId: prevState.editingGroupId,\n selectedElementIds: nextSelectedElementIds\n }, this.scene.getNonDeletedElements(), prevState, this)), {\n showHyperlinkPopup: hitElement.link || (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isEmbeddableElement)(hitElement) ? \"info\" : false\n });\n });\n pointerDownState.hit.wasAddedToSelection = true;\n }\n }\n }\n\n this.setState({\n previousSelectedElementIds: this.state.selectedElementIds\n });\n }\n }\n\n return false;\n };\n\n this.handleTextOnPointerDown = (event, pointerDownState) => {\n // if we're currently still editing text, clicking outside\n // should only finalize it, not create another (irrespective\n // of state.activeTool.locked)\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)) {\n return;\n }\n\n let sceneX = pointerDownState.origin.x;\n let sceneY = pointerDownState.origin.y;\n const element = this.getElementAtPosition(sceneX, sceneY, {\n includeBoundTextElement: true\n }); // FIXME\n\n let container = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getTextBindableContainerAtPosition)(this.scene.getNonDeletedElements(), this.state, sceneX, sceneY);\n\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.hasBoundTextElement)(element)) {\n container = element;\n sceneX = element.x + element.width / 2;\n sceneY = element.y + element.height / 2;\n }\n\n this.startTextEditing({\n sceneX,\n sceneY,\n insertAtParentCenter: !event.altKey,\n container\n });\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.resetCursor)(this.interactiveCanvas);\n\n if (!this.state.activeTool.locked) {\n this.setState({\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_33__.updateActiveTool)(this.state, {\n type: \"selection\"\n })\n });\n }\n };\n\n this.handleFreeDrawElementOnPointerDown = (event, elementType, pointerDownState) => {\n // Begin a mark capture. This does not have to update state yet.\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_28__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, null);\n const strokeOptions = this.state.currentStrokeOptions; //zsviczian\n\n const simulatePressure = (strokeOptions === null || strokeOptions === void 0 ? void 0 : strokeOptions.constantPressure) ? false : event.pressure === 0.5;\n const topLayerFrame = this.getTopLayerFrameAtSceneCoords({\n x: gridX,\n y: gridY\n });\n const element = (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.newFreeDrawElement)(Object.assign(Object.assign({\n type: elementType,\n x: gridX,\n y: gridY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n roundness: null,\n simulatePressure,\n locked: false\n }, strokeOptions //zsviczian\n ? {\n customData: {\n strokeOptions\n }\n } : {}), {\n frameId: topLayerFrame ? topLayerFrame.id : null\n }));\n this.setState(prevState => {\n const nextSelectedElementIds = Object.assign({}, prevState.selectedElementIds);\n delete nextSelectedElementIds[element.id];\n return {\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(nextSelectedElementIds, prevState)\n };\n });\n const pressures = element.simulatePressure ? element.pressures : [//zsviczian\n ...element.pressures, (strokeOptions === null || strokeOptions === void 0 ? void 0 : strokeOptions.constantPressure) ? 1 : event.pressure];\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n points: [[0, 0]],\n pressures\n });\n const boundElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerDownState.origin, this.scene);\n\n if (strokeOptions === null || strokeOptions === void 0 ? void 0 : strokeOptions.highlighter) {\n //zsviczian\n this.scene.replaceAllElements([element, ...this.scene.getElementsIncludingDeleted()]);\n } else {\n this.scene.addNewElement(element);\n }\n\n this.setState({\n draggingElement: element,\n editingElement: element,\n startBoundElement: boundElement,\n suggestedBindings: []\n });\n }; //create rectangle element with youtube top left on nearest grid point width / hight 640/360\n\n\n this.insertEmbeddableElement = ({\n sceneX,\n sceneY,\n link\n }) => {\n var _a;\n\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_28__.getGridPoint)(sceneX, sceneY, ((_a = this.lastPointerDownEvent) === null || _a === void 0 ? void 0 : _a[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) ? null : this.state.gridSize);\n const embedLink = (0,_element_embeddable__WEBPACK_IMPORTED_MODULE_34__.getEmbedLink)(link);\n\n if (!embedLink) {\n return;\n }\n\n if (embedLink.warning) {\n this.setToast({\n message: embedLink.warning,\n closable: true\n });\n }\n\n const element = (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.newEmbeddableElement)({\n type: \"embeddable\",\n x: gridX,\n y: gridY,\n strokeColor: \"transparent\",\n backgroundColor: \"transparent\",\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n roundness: this.getCurrentItemRoundness(\"embeddable\"),\n opacity: this.state.currentItemOpacity,\n locked: false,\n width: embedLink.aspectRatio.w,\n height: embedLink.aspectRatio.h,\n link,\n validated: null\n });\n this.scene.replaceAllElements([...this.scene.getElementsIncludingDeleted(), element]);\n return element;\n };\n\n this.createImageElement = ({\n sceneX,\n sceneY\n }) => {\n var _a;\n\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_28__.getGridPoint)(sceneX, sceneY, ((_a = this.lastPointerDownEvent) === null || _a === void 0 ? void 0 : _a[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) ? null : this.state.gridSize);\n const topLayerFrame = this.getTopLayerFrameAtSceneCoords({\n x: gridX,\n y: gridY\n });\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newImageElement)({\n type: \"image\",\n x: gridX,\n y: gridY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n roundness: null,\n opacity: this.state.currentItemOpacity,\n locked: false,\n frameId: topLayerFrame ? topLayerFrame.id : null\n });\n return element;\n };\n\n this.handleLinearElementOnPointerDown = (event, elementType, pointerDownState) => {\n if (this.state.multiElement) {\n const {\n multiElement\n } = this.state; // finalize if completing a loop\n\n if (multiElement.type === \"line\" && (0,_math__WEBPACK_IMPORTED_MODULE_28__.isPathALoop)(multiElement.points, this.state.zoom.value)) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n lastCommittedPoint: multiElement.points[multiElement.points.length - 1]\n });\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n return;\n }\n\n const {\n x: rx,\n y: ry,\n lastCommittedPoint\n } = multiElement; // clicking inside commit zone → finalize arrow\n\n if (multiElement.points.length > 1 && lastCommittedPoint && (0,_math__WEBPACK_IMPORTED_MODULE_28__.distance2d)(pointerDownState.origin.x - rx, pointerDownState.origin.y - ry, lastCommittedPoint[0], lastCommittedPoint[1]) < _constants__WEBPACK_IMPORTED_MODULE_12__.LINE_CONFIRM_THRESHOLD) {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n return;\n }\n\n this.setState(prevState => ({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(Object.assign(Object.assign({}, prevState.selectedElementIds), {\n [multiElement.id]: true\n }), prevState)\n })); // clicking outside commit zone → update reference for last committed\n // point\n\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n lastCommittedPoint: multiElement.points[multiElement.points.length - 1]\n });\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n } else {\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_28__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] ? null : this.state.gridSize);\n const topLayerFrame = this.getTopLayerFrameAtSceneCoords({\n x: gridX,\n y: gridY\n });\n /* If arrow is pre-arrowheads, it will have undefined for both start and end arrowheads.\r\n If so, we want it to be null for start and \"arrow\" for end. If the linear item is not\r\n an arrow, we want it to be null for both. Otherwise, we want it to use the\r\n values from appState. */\n\n const {\n currentItemStartArrowhead,\n currentItemEndArrowhead\n } = this.state;\n const [startArrowhead, endArrowhead] = elementType === \"arrow\" ? [currentItemStartArrowhead, currentItemEndArrowhead] : [null, null];\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newLinearElement)({\n type: elementType,\n x: gridX,\n y: gridY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n roundness: this.state.currentItemRoundness === \"round\" ? {\n type: _constants__WEBPACK_IMPORTED_MODULE_12__.ROUNDNESS.PROPORTIONAL_RADIUS\n } : null,\n startArrowhead,\n endArrowhead,\n locked: false,\n frameId: topLayerFrame ? topLayerFrame.id : null\n });\n this.setState(prevState => {\n const nextSelectedElementIds = Object.assign({}, prevState.selectedElementIds);\n delete nextSelectedElementIds[element.id];\n return {\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(nextSelectedElementIds, prevState)\n };\n });\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n points: [...element.points, [0, 0]]\n });\n const boundElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerDownState.origin, this.scene);\n this.scene.addNewElement(element);\n this.setState({\n draggingElement: element,\n editingElement: element,\n startBoundElement: boundElement,\n suggestedBindings: []\n });\n }\n };\n\n this.createGenericElementOnPointerDown = (elementType, pointerDownState) => {\n var _a;\n\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_28__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, ((_a = this.lastPointerDownEvent) === null || _a === void 0 ? void 0 : _a[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) ? null : this.state.gridSize);\n const topLayerFrame = this.getTopLayerFrameAtSceneCoords({\n x: gridX,\n y: gridY\n });\n const baseElementAttributes = {\n x: gridX,\n y: gridY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n roundness: this.getCurrentItemRoundness(elementType),\n locked: false,\n frameId: topLayerFrame ? topLayerFrame.id : null\n };\n let element;\n\n if (elementType === \"embeddable\") {\n element = (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.newEmbeddableElement)(Object.assign({\n type: \"embeddable\",\n validated: null\n }, baseElementAttributes));\n } else {\n element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newElement)(Object.assign({\n type: elementType\n }, baseElementAttributes));\n }\n\n if (element.type === \"selection\") {\n this.setState({\n selectionElement: element,\n draggingElement: element\n });\n } else {\n this.scene.addNewElement(element);\n this.setState({\n multiElement: null,\n draggingElement: element,\n editingElement: element\n });\n }\n };\n\n this.createFrameElementOnPointerDown = pointerDownState => {\n var _a;\n\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_28__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, ((_a = this.lastPointerDownEvent) === null || _a === void 0 ? void 0 : _a[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) ? null : this.state.gridSize);\n const frame = (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.newFrameElement)(Object.assign({\n x: gridX,\n y: gridY,\n opacity: this.state.currentItemOpacity,\n locked: false\n }, _constants__WEBPACK_IMPORTED_MODULE_12__.FRAME_STYLE));\n this.scene.replaceAllElements([...this.scene.getElementsIncludingDeleted(), frame]);\n this.setState({\n multiElement: null,\n draggingElement: frame,\n editingElement: frame\n });\n };\n\n this.restoreReadyToEraseElements = pointerDownState => {\n const elements = this.scene.getElementsIncludingDeleted().map(ele => {\n if (pointerDownState.elementIdsToErase[ele.id] && pointerDownState.elementIdsToErase[ele.id].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n opacity: pointerDownState.elementIdsToErase[ele.id].opacity\n });\n } else if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(ele) && pointerDownState.elementIdsToErase[ele.containerId] && pointerDownState.elementIdsToErase[ele.containerId].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n opacity: pointerDownState.elementIdsToErase[ele.containerId].opacity\n });\n } else if (ele.frameId && pointerDownState.elementIdsToErase[ele.frameId] && pointerDownState.elementIdsToErase[ele.frameId].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n opacity: pointerDownState.elementIdsToErase[ele.frameId].opacity\n });\n }\n\n return ele;\n });\n this.scene.replaceAllElements(elements);\n };\n\n this.eraseElements = pointerDownState => {\n const elements = this.scene.getElementsIncludingDeleted().map(ele => {\n if (pointerDownState.elementIdsToErase[ele.id] && pointerDownState.elementIdsToErase[ele.id].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n isDeleted: true\n });\n } else if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(ele) && pointerDownState.elementIdsToErase[ele.containerId] && pointerDownState.elementIdsToErase[ele.containerId].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n isDeleted: true\n });\n } else if (ele.frameId && pointerDownState.elementIdsToErase[ele.frameId] && pointerDownState.elementIdsToErase[ele.frameId].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n isDeleted: true\n });\n }\n\n return ele;\n });\n this.history.resumeRecording();\n this.scene.replaceAllElements(elements);\n };\n\n this.initializeImage = async ({\n imageFile,\n imageElement: _imageElement,\n showCursorImagePreview = false\n }) => {\n var _a, _b, _c, _d; // at this point this should be guaranteed image file, but we do this check\n // to satisfy TS down the line\n\n\n if (!(0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.isSupportedImageFile)(imageFile)) {\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.unsupportedFileType\"));\n }\n\n const mimeType = imageFile.type;\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, \"wait\");\n\n if (mimeType === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.svg) {\n try {\n imageFile = (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.SVGStringToFile)(await (0,_element_image__WEBPACK_IMPORTED_MODULE_40__.normalizeSVG)(await imageFile.text()), imageFile.name);\n } catch (error) {\n console.warn(error);\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.svgImageInsertError\"));\n }\n } // generate image id (by default the file digest) before any\n // resizing/compression takes place to keep it more portable\n\n\n const fileId = await (((_b = (_a = this.props).generateIdForFile) === null || _b === void 0 ? void 0 : _b.call(_a, imageFile)) || (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.generateIdFromFile)(imageFile));\n\n if (!fileId) {\n console.warn(\"Couldn't generate file id or the supplied `generateIdForFile` didn't resolve to one.\");\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\"));\n }\n\n const existingFileData = this.files[fileId];\n\n if (!(existingFileData === null || existingFileData === void 0 ? void 0 : existingFileData.dataURL)) {\n try {\n imageFile = await (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.resizeImageFile)(imageFile, {\n maxWidthOrHeight: _constants__WEBPACK_IMPORTED_MODULE_12__.DEFAULT_MAX_IMAGE_WIDTH_OR_HEIGHT\n });\n } catch (error) {\n console.error(\"error trying to resing image file on insertion\", error);\n }\n\n if (imageFile.size > _constants__WEBPACK_IMPORTED_MODULE_12__.MAX_ALLOWED_FILE_BYTES) {\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.fileTooBig\", {\n maxSize: `${Math.trunc(_constants__WEBPACK_IMPORTED_MODULE_12__.MAX_ALLOWED_FILE_BYTES / 1024 / 1024)}MB`\n }));\n }\n }\n\n if (showCursorImagePreview) {\n const dataURL = (_c = this.files[fileId]) === null || _c === void 0 ? void 0 : _c.dataURL; // optimization so that we don't unnecessarily resize the original\n // full-size file for cursor preview\n // (it's much faster to convert the resized dataURL to File)\n\n const resizedFile = dataURL && (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.dataURLToFile)(dataURL);\n this.setImagePreviewCursor(resizedFile || imageFile);\n }\n\n const dataURL = ((_d = this.files[fileId]) === null || _d === void 0 ? void 0 : _d.dataURL) || (await (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.getDataURL)(imageFile));\n const imageElement = (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(_imageElement, {\n fileId\n }, false);\n return new Promise(async (resolve, reject) => {\n var _a;\n\n try {\n this.files = Object.assign(Object.assign({}, this.files), {\n [fileId]: {\n mimeType,\n id: fileId,\n dataURL,\n created: Date.now(),\n lastRetrieved: Date.now()\n }\n });\n const cachedImageData = this.imageCache.get(fileId);\n\n if (!cachedImageData) {\n this.addNewImagesToImageCache();\n await this.updateImageCache([imageElement]);\n }\n\n if ((cachedImageData === null || cachedImageData === void 0 ? void 0 : cachedImageData.image) instanceof Promise) {\n await cachedImageData.image;\n }\n\n if (this.state.pendingImageElementId !== imageElement.id && ((_a = this.state.draggingElement) === null || _a === void 0 ? void 0 : _a.id) !== imageElement.id) {\n this.initializeImageDimensions(imageElement, true);\n }\n\n resolve(imageElement);\n } catch (error) {\n console.error(error);\n reject(new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\")));\n } finally {\n if (!showCursorImagePreview) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.resetCursor)(this.interactiveCanvas);\n }\n }\n });\n };\n /**\r\n * inserts image into elements array and rerenders\r\n */\n\n\n this.insertImageElement = async (imageElement, imageFile, showCursorImagePreview) => {\n this.scene.addNewElement(imageElement);\n\n try {\n return await this.initializeImage({\n imageFile,\n imageElement,\n showCursorImagePreview\n });\n } catch (error) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, {\n isDeleted: true\n });\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n this.setState({\n errorMessage: error.message || (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\")\n });\n return null;\n }\n };\n\n this.setImagePreviewCursor = async imageFile => {\n // mustn't be larger than 128 px\n // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property\n const cursorImageSizePx = 96;\n const imagePreview = await (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.resizeImageFile)(imageFile, {\n maxWidthOrHeight: cursorImageSizePx\n });\n let previewDataURL = await (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.getDataURL)(imagePreview); // SVG cannot be resized via `resizeImageFile` so we resize by rendering to\n // a small canvas\n\n if (imageFile.type === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.svg) {\n const img = await (0,_element_image__WEBPACK_IMPORTED_MODULE_40__.loadHTMLImageElement)(previewDataURL);\n let height = Math.min(img.height, cursorImageSizePx);\n let width = height * (img.width / img.height);\n\n if (width > cursorImageSizePx) {\n width = cursorImageSizePx;\n height = width * (img.height / img.width);\n }\n\n const canvas = document.createElement(\"canvas\");\n canvas.height = height;\n canvas.width = width;\n const context = canvas.getContext(\"2d\");\n context.drawImage(img, 0, 0, width, height);\n previewDataURL = canvas.toDataURL(_constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.svg);\n }\n\n if (this.state.pendingImageElementId) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, `url(${previewDataURL}) 4 4, auto`);\n }\n };\n\n this.onImageAction = async ({\n insertOnCanvasDirectly\n }) => {\n try {\n const clientX = this.state.width / 2 + this.state.offsetLeft;\n const clientY = this.state.height / 2 + this.state.offsetTop;\n const {\n x,\n y\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)({\n clientX,\n clientY\n }, this.state);\n const imageFile = await (0,_data_filesystem__WEBPACK_IMPORTED_MODULE_42__.fileOpen)({\n description: \"Image\",\n extensions: Object.keys(_constants__WEBPACK_IMPORTED_MODULE_12__.IMAGE_MIME_TYPES)\n });\n const imageElement = this.createImageElement({\n sceneX: x,\n sceneY: y\n });\n\n if (insertOnCanvasDirectly) {\n this.insertImageElement(imageElement, imageFile);\n this.initializeImageDimensions(imageElement);\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({\n [imageElement.id]: true\n }, this.state)\n }, () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n });\n } else {\n this.setState({\n pendingImageElementId: imageElement.id\n }, () => {\n this.insertImageElement(imageElement, imageFile,\n /* showCursorImagePreview */\n true);\n });\n }\n } catch (error) {\n if (error.name !== \"AbortError\") {\n console.error(error);\n } else {\n console.warn(error);\n }\n\n this.setState({\n pendingImageElementId: null,\n editingElement: null,\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_33__.updateActiveTool)(this.state, {\n type: \"selection\"\n })\n }, () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n });\n }\n };\n\n this.initializeImageDimensions = (imageElement, forceNaturalSize = false) => {\n var _a;\n\n const image = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(imageElement) && ((_a = this.imageCache.get(imageElement.fileId)) === null || _a === void 0 ? void 0 : _a.image);\n\n if (!image || image instanceof Promise) {\n if (imageElement.width < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD / this.state.zoom.value && imageElement.height < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD / this.state.zoom.value) {\n const placeholderSize = 100 / this.state.zoom.value;\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, {\n x: imageElement.x - placeholderSize / 2,\n y: imageElement.y - placeholderSize / 2,\n width: placeholderSize,\n height: placeholderSize\n });\n }\n\n return;\n }\n\n if (forceNaturalSize || // if user-created bounding box is below threshold, assume the\n // intention was to click instead of drag, and use the image's\n // intrinsic size\n imageElement.width < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD / this.state.zoom.value && imageElement.height < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD / this.state.zoom.value) {\n const minHeight = Math.max(this.state.height - 120, 160); // max 65% of canvas height, clamped to <300px, vh - 120px>\n\n const maxHeight = Math.min(minHeight, Math.floor(this.state.height * 0.5) / this.state.zoom.value);\n const height = Math.min(image.naturalHeight, maxHeight);\n const width = height * (image.naturalWidth / image.naturalHeight); // add current imageElement width/height to account for previous centering\n // of the placeholder image\n\n const x = imageElement.x + imageElement.width / 2 - width / 2;\n const y = imageElement.y + imageElement.height / 2 - height / 2;\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, {\n x,\n y,\n width,\n height\n });\n }\n };\n /** updates image cache, refreshing updated elements and/or setting status\r\n to error for images that fail during <img> element creation */\n\n\n this.updateImageCache = async (elements, files = this.files) => {\n const {\n updatedFiles,\n erroredFiles\n } = await (0,_element_image__WEBPACK_IMPORTED_MODULE_40__.updateImageCache)({\n imageCache: this.imageCache,\n fileIds: elements.map(element => element.fileId),\n files\n });\n\n if (updatedFiles.size || erroredFiles.size) {\n for (const element of elements) {\n if (updatedFiles.has(element.fileId)) {\n _scene_ShapeCache__WEBPACK_IMPORTED_MODULE_66__.ShapeCache[\"delete\"](element);\n }\n }\n }\n\n if (erroredFiles.size) {\n this.scene.replaceAllElements(this.scene.getElementsIncludingDeleted().map(element => {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(element) && erroredFiles.has(element.fileId)) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(element, {\n status: \"error\"\n });\n }\n\n return element;\n }));\n }\n\n return {\n updatedFiles,\n erroredFiles\n };\n };\n /** adds new images to imageCache and re-renders if needed */\n\n\n this.addNewImagesToImageCache = async (imageElements = (0,_element_image__WEBPACK_IMPORTED_MODULE_40__.getInitializedImageElements)(this.scene.getNonDeletedElements()), files = this.files) => {\n const uncachedImageElements = imageElements.filter(element => !element.isDeleted && !this.imageCache.has(element.fileId));\n\n if (uncachedImageElements.length) {\n const {\n updatedFiles\n } = await this.updateImageCache(uncachedImageElements, files);\n\n if (updatedFiles.size) {\n this.scene.informMutation();\n }\n }\n };\n /** generally you should use `addNewImagesToImageCache()` directly if you need\r\n * to render new images. This is just a failsafe */\n\n\n this.scheduleImageRefresh = lodash_throttle__WEBPACK_IMPORTED_MODULE_41___default()(() => {\n this.addNewImagesToImageCache();\n }, _constants__WEBPACK_IMPORTED_MODULE_12__.IMAGE_RENDER_TIMEOUT);\n\n this.updateBindingEnabledOnPointerMove = event => {\n const shouldEnableBinding = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.shouldEnableBindingForPointerEvent)(event);\n\n if (this.state.isBindingEnabled !== shouldEnableBinding) {\n this.setState({\n isBindingEnabled: shouldEnableBinding\n });\n }\n };\n\n this.maybeSuggestBindingAtCursor = pointerCoords => {\n const hoveredBindableElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerCoords, this.scene);\n this.setState({\n suggestedBindings: hoveredBindableElement != null ? [hoveredBindableElement] : []\n });\n };\n\n this.maybeSuggestBindingsForLinearElementAtCoords = (linearElement,\n /** scene coords */\n pointerCoords, // During line creation the start binding hasn't been written yet\n // into `linearElement`\n oppositeBindingBoundElement) => {\n if (!pointerCoords.length) {\n return;\n }\n\n const suggestedBindings = pointerCoords.reduce((acc, coords) => {\n const hoveredBindableElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(coords, this.scene);\n\n if (hoveredBindableElement != null && !(0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isLinearElementSimpleAndAlreadyBound)(linearElement, oppositeBindingBoundElement === null || oppositeBindingBoundElement === void 0 ? void 0 : oppositeBindingBoundElement.id, hoveredBindableElement)) {\n acc.push(hoveredBindableElement);\n }\n\n return acc;\n }, []);\n this.setState({\n suggestedBindings\n });\n };\n\n this.handleInteractiveCanvasRef = canvas => {\n var _a, _b, _c; // canvas is null when unmounting\n\n\n if (canvas !== null) {\n this.interactiveCanvas = canvas; // -----------------------------------------------------------------------\n // NOTE wheel, touchstart, touchend events must be registered outside\n // of react because react binds them them passively (so we can't prevent\n // default on them)\n\n this.interactiveCanvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.WHEEL, this.handleWheel);\n this.interactiveCanvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.TOUCH_START, this.onTouchStart);\n this.interactiveCanvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.TOUCH_END, this.onTouchEnd); // -----------------------------------------------------------------------\n } else {\n (_a = this.interactiveCanvas) === null || _a === void 0 ? void 0 : _a.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.WHEEL, this.handleWheel);\n (_b = this.interactiveCanvas) === null || _b === void 0 ? void 0 : _b.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.TOUCH_START, this.onTouchStart);\n (_c = this.interactiveCanvas) === null || _c === void 0 ? void 0 : _c.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.TOUCH_END, this.onTouchEnd);\n }\n };\n\n this.handleAppOnDrop = async event => {\n var _a, _b, _c, _d;\n\n if (this.props.onDrop) {\n try {\n if ((await this.props.onDrop(event)) === false) {\n return;\n }\n } catch (e) {\n console.error(e);\n }\n } // must be retrieved first, in the same frame\n\n\n const {\n file,\n fileHandle\n } = await (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.getFileFromEvent)(event);\n const {\n x: sceneX,\n y: sceneY\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)(event, this.state);\n\n try {\n if ((0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.isSupportedImageFile)(file)) {\n // first attempt to decode scene from the image if it's embedded\n // ---------------------------------------------------------------------\n if ((file === null || file === void 0 ? void 0 : file.type) === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.png || (file === null || file === void 0 ? void 0 : file.type) === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.svg) {\n try {\n const scene = await (0,_data__WEBPACK_IMPORTED_MODULE_13__.loadFromBlob)(file, this.state, this.scene.getElementsIncludingDeleted(), fileHandle);\n this.syncActionResult(Object.assign(Object.assign({}, scene), {\n appState: Object.assign(Object.assign({}, scene.appState || this.state), {\n isLoading: false\n }),\n replaceFiles: true,\n commitToHistory: true\n }));\n return;\n } catch (error) {\n if (error.name !== \"EncodingError\") {\n throw error;\n }\n }\n } // if no scene is embedded or we fail for whatever reason, fall back\n // to importing as regular image\n // ---------------------------------------------------------------------\n\n\n const imageElement = this.createImageElement({\n sceneX,\n sceneY\n });\n this.insertImageElement(imageElement, file);\n this.initializeImageDimensions(imageElement);\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({\n [imageElement.id]: true\n }, this.state)\n });\n return;\n }\n } catch (error) {\n return this.setState({\n isLoading: false,\n errorMessage: error.message\n });\n }\n\n const libraryJSON = event.dataTransfer.getData(_constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.excalidrawlib);\n\n if (libraryJSON && typeof libraryJSON === \"string\") {\n try {\n const libraryItems = (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.parseLibraryJSON)(libraryJSON);\n this.addElementsFromPasteOrLibrary({\n elements: (0,_data_library__WEBPACK_IMPORTED_MODULE_14__.distributeLibraryItemsOnSquareGrid)(libraryItems),\n position: event,\n files: null\n });\n } catch (error) {\n this.setState({\n errorMessage: error.message\n });\n }\n\n return;\n }\n\n if (file) {\n // atetmpt to parse an excalidraw/excalidrawlib file\n await this.loadFileToCanvas(file, fileHandle);\n }\n\n if ((_b = (_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.types) === null || _b === void 0 ? void 0 : _b.includes(\"text/plain\")) {\n const text = (_c = event.dataTransfer) === null || _c === void 0 ? void 0 : _c.getData(\"text\");\n\n if (text && (0,_element_embeddable__WEBPACK_IMPORTED_MODULE_34__.embeddableURLValidator)(text, this.props.validateEmbeddable) && (/^(http|https):\\/\\/[^\\s/$.?#].[^\\s]*$/.test(text) || ((_d = (0,_element_embeddable__WEBPACK_IMPORTED_MODULE_34__.getEmbedLink)(text)) === null || _d === void 0 ? void 0 : _d.type) === \"video\")) {\n const embeddable = this.insertEmbeddableElement({\n sceneX,\n sceneY,\n link: (0,_data_url__WEBPACK_IMPORTED_MODULE_47__.normalizeLink)(text)\n });\n\n if (embeddable) {\n this.setState({\n selectedElementIds: {\n [embeddable.id]: true\n }\n });\n }\n }\n }\n };\n\n this.loadFileToCanvas = async (file, fileHandle) => {\n file = await (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.normalizeFile)(file);\n\n try {\n const ret = await (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.loadSceneOrLibraryFromBlob)(file, this.state, this.scene.getElementsIncludingDeleted(), fileHandle);\n\n if (ret.type === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.excalidraw) {\n this.setState({\n isLoading: true\n });\n this.syncActionResult(Object.assign(Object.assign({}, ret.data), {\n appState: Object.assign(Object.assign({}, ret.data.appState || this.state), {\n isLoading: false\n }),\n replaceFiles: true,\n commitToHistory: true\n }));\n } else if (ret.type === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.excalidrawlib) {\n await this.library.updateLibrary({\n libraryItems: file,\n merge: true,\n openLibraryMenu: true\n }).catch(error => {\n console.error(error);\n this.setState({\n errorMessage: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.importLibraryError\")\n });\n });\n }\n } catch (error) {\n this.setState({\n isLoading: false,\n errorMessage: error.message\n });\n }\n };\n\n this.handleCanvasContextMenu = event => {\n event.preventDefault();\n\n if ((\"pointerType\" in event.nativeEvent && event.nativeEvent.pointerType === \"touch\" || \"pointerType\" in event.nativeEvent && event.nativeEvent.pointerType === \"pen\" && // always allow if user uses a pen secondary button\n event.button !== _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.SECONDARY) && this.state.activeTool.type !== \"selection\") {\n return;\n }\n\n const {\n x,\n y\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)(event, this.state);\n const element = this.getElementAtPosition(x, y, {\n preferSelected: true,\n includeLockedElements: true\n });\n const selectedElements = this.scene.getSelectedElements(this.state);\n const isHittignCommonBoundBox = this.isHittingCommonBoundingBoxOfSelectedElements({\n x,\n y\n }, selectedElements);\n const type = element || isHittignCommonBoundBox ? \"element\" : \"canvas\";\n const container = this.excalidrawContainerRef.current;\n const {\n top: offsetTop,\n left: offsetLeft\n } = container.getBoundingClientRect();\n const left = event.clientX - offsetLeft;\n const top = event.clientY - offsetTop;\n (0,_analytics__WEBPACK_IMPORTED_MODULE_9__.trackEvent)(\"contextMenu\", \"openContextMenu\", type);\n this.setState(Object.assign(Object.assign({}, element && !this.state.selectedElementIds[element.id] ? Object.assign(Object.assign(Object.assign({}, this.state), (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)({\n editingGroupId: this.state.editingGroupId,\n selectedElementIds: {\n [element.id]: true\n }\n }, this.scene.getNonDeletedElements(), this.state, this)), {\n selectedLinearElement: (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(element) ? new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(element, this.scene) : null\n }) : this.state), {\n showHyperlinkPopup: false\n }), () => {\n this.setState({\n contextMenu: {\n top,\n left,\n items: this.getContextMenuItems(type)\n }\n });\n });\n };\n\n this.maybeDragNewGenericElement = (pointerDownState, event) => {\n var _a, _b, _c, _d, _e;\n\n const draggingElement = this.state.draggingElement;\n const pointerCoords = pointerDownState.lastCoords;\n\n if (!draggingElement) {\n return;\n }\n\n if (draggingElement.type === \"selection\" && this.state.activeTool.type !== \"eraser\") {\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragNewElement)(draggingElement, this.state.activeTool.type, pointerDownState.origin.x, pointerDownState.origin.y, pointerCoords.x, pointerCoords.y, (0,_utils__WEBPACK_IMPORTED_MODULE_33__.distance)(pointerDownState.origin.x, pointerCoords.x), (0,_utils__WEBPACK_IMPORTED_MODULE_33__.distance)(pointerDownState.origin.y, pointerCoords.y), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldResizeFromCenter)(event));\n } else {\n let [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_28__.getGridPoint)(pointerCoords.x, pointerCoords.y, event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] ? null : this.state.gridSize);\n const image = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(draggingElement) && ((_a = this.imageCache.get(draggingElement.fileId)) === null || _a === void 0 ? void 0 : _a.image);\n const aspectRatio = image && !(image instanceof Promise) ? image.width / image.height : null;\n this.maybeCacheReferenceSnapPoints(event, [draggingElement]);\n const {\n snapOffset,\n snapLines\n } = (0,_snapping__WEBPACK_IMPORTED_MODULE_58__.snapNewElement)(draggingElement, this.state, event, {\n x: pointerDownState.originInGrid.x + ((_c = (_b = this.state.originSnapOffset) === null || _b === void 0 ? void 0 : _b.x) !== null && _c !== void 0 ? _c : 0),\n y: pointerDownState.originInGrid.y + ((_e = (_d = this.state.originSnapOffset) === null || _d === void 0 ? void 0 : _d.y) !== null && _e !== void 0 ? _e : 0)\n }, {\n x: gridX - pointerDownState.originInGrid.x,\n y: gridY - pointerDownState.originInGrid.y\n });\n gridX += snapOffset.x;\n gridY += snapOffset.y;\n this.setState({\n snapLines\n });\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragNewElement)(draggingElement, this.state.activeTool.type, pointerDownState.originInGrid.x, pointerDownState.originInGrid.y, gridX, gridY, (0,_utils__WEBPACK_IMPORTED_MODULE_33__.distance)(pointerDownState.originInGrid.x, gridX), (0,_utils__WEBPACK_IMPORTED_MODULE_33__.distance)(pointerDownState.originInGrid.y, gridY), (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(draggingElement) ? !(0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event) : (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldResizeFromCenter)(event), aspectRatio, this.state.originSnapOffset);\n this.maybeSuggestBindingForAll([draggingElement]); // highlight elements that are to be added to frames on frames creation\n\n if (this.state.activeTool.type === \"frame\") {\n this.setState({\n elementsToHighlight: (0,_frame__WEBPACK_IMPORTED_MODULE_51__.getElementsInResizingFrame)(this.scene.getNonDeletedElements(), draggingElement, this.state)\n });\n }\n }\n };\n\n this.maybeHandleResize = (pointerDownState, event) => {\n const selectedElements = this.scene.getSelectedElements(this.state);\n const selectedFrames = selectedElements.filter(element => element.type === \"frame\");\n const transformHandleType = pointerDownState.resize.handleType;\n\n if (selectedFrames.length > 0 && transformHandleType === \"rotation\") {\n return false;\n }\n\n this.setState({\n // TODO: rename this state field to \"isScaling\" to distinguish\n // it from the generic \"isResizing\" which includes scaling and\n // rotating\n isResizing: transformHandleType && transformHandleType !== \"rotation\",\n isRotating: transformHandleType === \"rotation\",\n activeEmbeddable: null\n });\n const pointerCoords = pointerDownState.lastCoords;\n let [resizeX, resizeY] = (0,_math__WEBPACK_IMPORTED_MODULE_28__.getGridPoint)(pointerCoords.x - pointerDownState.resize.offset.x, pointerCoords.y - pointerDownState.resize.offset.y, event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] ? null : this.state.gridSize);\n const frameElementsOffsetsMap = new Map();\n selectedFrames.forEach(frame => {\n const elementsInFrame = (0,_frame__WEBPACK_IMPORTED_MODULE_51__.getFrameElements)(this.scene.getNonDeletedElements(), frame.id);\n elementsInFrame.forEach(element => {\n frameElementsOffsetsMap.set(frame.id + element.id, {\n x: element.x - frame.x,\n y: element.y - frame.y\n });\n });\n }); // check needed for avoiding flickering when a key gets pressed\n // during dragging\n\n if (!this.state.selectedElementsAreBeingDragged) {\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_28__.getGridPoint)(pointerCoords.x, pointerCoords.y, event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] ? null : this.state.gridSize);\n const dragOffset = {\n x: gridX - pointerDownState.originInGrid.x,\n y: gridY - pointerDownState.originInGrid.y\n };\n const originalElements = [...pointerDownState.originalElements.values()];\n this.maybeCacheReferenceSnapPoints(event, selectedElements);\n const {\n snapOffset,\n snapLines\n } = (0,_snapping__WEBPACK_IMPORTED_MODULE_58__.snapResizingElements)(selectedElements, (0,_scene__WEBPACK_IMPORTED_MODULE_29__.getSelectedElements)(originalElements, this.state), this.state, event, dragOffset, transformHandleType);\n resizeX += snapOffset.x;\n resizeY += snapOffset.y;\n this.setState({\n snapLines\n });\n }\n\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.transformElements)(pointerDownState, transformHandleType, selectedElements, pointerDownState.resize.arrowDirection, (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldRotateWithDiscreteAngle)(event), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldResizeFromCenter)(event), selectedElements.length === 1 && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(selectedElements[0]) ? !(0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event) : (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event), resizeX, resizeY, pointerDownState.resize.center.x, pointerDownState.resize.center.y, this.state)) {\n this.maybeSuggestBindingForAll(selectedElements);\n const elementsToHighlight = new Set();\n selectedFrames.forEach(frame => {\n const elementsInFrame = (0,_frame__WEBPACK_IMPORTED_MODULE_51__.getFrameElements)(this.scene.getNonDeletedElements(), frame.id); // keep elements' positions relative to their frames on frames resizing\n\n if (transformHandleType) {\n if (transformHandleType.includes(\"w\")) {\n elementsInFrame.forEach(element => {\n var _a, _b;\n\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n x: frame.x + (((_a = frameElementsOffsetsMap.get(frame.id + element.id)) === null || _a === void 0 ? void 0 : _a.x) || 0),\n y: frame.y + (((_b = frameElementsOffsetsMap.get(frame.id + element.id)) === null || _b === void 0 ? void 0 : _b.y) || 0)\n });\n });\n }\n\n if (transformHandleType.includes(\"n\")) {\n elementsInFrame.forEach(element => {\n var _a, _b;\n\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n x: frame.x + (((_a = frameElementsOffsetsMap.get(frame.id + element.id)) === null || _a === void 0 ? void 0 : _a.x) || 0),\n y: frame.y + (((_b = frameElementsOffsetsMap.get(frame.id + element.id)) === null || _b === void 0 ? void 0 : _b.y) || 0)\n });\n });\n }\n }\n\n (0,_frame__WEBPACK_IMPORTED_MODULE_51__.getElementsInResizingFrame)(this.scene.getNonDeletedElements(), frame, this.state).forEach(element => elementsToHighlight.add(element));\n });\n this.setState({\n elementsToHighlight: [...elementsToHighlight]\n });\n return true;\n }\n\n return false;\n };\n\n this.getContextMenuItems = type => {\n const options = [];\n options.push(_actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsPng, _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsSvg); // canvas contextMenu\n // -------------------------------------------------------------------------\n\n if (type === \"canvas\") {\n if (this.state.viewModeEnabled) {\n return [...options, _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleGridMode, _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleZenMode, _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_38__.actionToggleViewMode, _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleStats, _actions_actionCanvas__WEBPACK_IMPORTED_MODULE_55__.actionToggleLaserPointer];\n }\n\n return [_actions_actionClipboard__WEBPACK_IMPORTED_MODULE_53__.actionPaste, _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR, _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsPng, _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsSvg, _actions__WEBPACK_IMPORTED_MODULE_5__.copyText, _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR, _actions__WEBPACK_IMPORTED_MODULE_5__.actionSelectAll, _actions_actionElementLock__WEBPACK_IMPORTED_MODULE_49__.actionUnlockAllElements, _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR, _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleGridMode, _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleObjectsSnapMode, _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleZenMode, _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_38__.actionToggleViewMode, _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleStats];\n } // element contextMenu\n // -------------------------------------------------------------------------\n\n\n options.push(_actions__WEBPACK_IMPORTED_MODULE_5__.copyText);\n\n if (this.state.viewModeEnabled) {\n return [_actions__WEBPACK_IMPORTED_MODULE_5__.actionCopy, ...options];\n }\n\n return [_actions__WEBPACK_IMPORTED_MODULE_5__.actionCut, _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopy, _actions_actionClipboard__WEBPACK_IMPORTED_MODULE_53__.actionPaste, _actions_actionFrame__WEBPACK_IMPORTED_MODULE_54__.actionSelectAllElementsInFrame, _actions_actionFrame__WEBPACK_IMPORTED_MODULE_54__.actionRemoveAllElementsFromFrame, _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR, ...options, _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR, _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyStyles, _actions__WEBPACK_IMPORTED_MODULE_5__.actionPasteStyles, _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR, _actions__WEBPACK_IMPORTED_MODULE_5__.actionGroup, _actions__WEBPACK_IMPORTED_MODULE_5__.actionUnbindText, _actions__WEBPACK_IMPORTED_MODULE_5__.actionBindText, _actions_actionBoundText__WEBPACK_IMPORTED_MODULE_59__.actionWrapTextInContainer, _actions__WEBPACK_IMPORTED_MODULE_5__.actionUngroup, _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR, _actions__WEBPACK_IMPORTED_MODULE_5__.actionAddToLibrary, _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR, _actions__WEBPACK_IMPORTED_MODULE_5__.actionSendBackward, _actions__WEBPACK_IMPORTED_MODULE_5__.actionBringForward, _actions__WEBPACK_IMPORTED_MODULE_5__.actionSendToBack, _actions__WEBPACK_IMPORTED_MODULE_5__.actionBringToFront, _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR, _actions__WEBPACK_IMPORTED_MODULE_5__.actionFlipHorizontal, _actions__WEBPACK_IMPORTED_MODULE_5__.actionFlipVertical, _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR, _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleLinearEditor, _actions__WEBPACK_IMPORTED_MODULE_5__.actionLink, _actions__WEBPACK_IMPORTED_MODULE_5__.actionDuplicateSelection, _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleElementLock, _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR, _actions__WEBPACK_IMPORTED_MODULE_5__.actionDeleteSelected];\n };\n\n this.handleWheel = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(event => {\n event.preventDefault();\n\n if (isPanning) {\n return;\n }\n\n const {\n deltaX,\n deltaY\n } = event; // note that event.ctrlKey is necessary to handle pinch zooming\n\n if ( //zsviczian\n (event.metaKey || event.ctrlKey) && !this.state.allowWheelZoom || !(event.metaKey || event.ctrlKey) && this.state.allowWheelZoom) {\n const sign = Math.sign(deltaY);\n const MAX_STEP = _constants__WEBPACK_IMPORTED_MODULE_12__.ZOOM_STEP * 100;\n const absDelta = Math.abs(deltaY);\n let delta = deltaY;\n\n if (absDelta > MAX_STEP) {\n delta = MAX_STEP * sign;\n }\n\n let newZoom = this.state.zoom.value - delta / 100; // increase zoom steps the more zoomed-in we are (applies to >100% only)\n\n newZoom += Math.log10(Math.max(1, this.state.zoom.value)) * -sign * // reduced amplification for small deltas (small movements on a trackpad)\n Math.min(1, absDelta / 20);\n this.translateCanvas(state => Object.assign(Object.assign({}, (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_31__.getStateForZoom)({\n viewportX: this.lastViewportPosition.x,\n viewportY: this.lastViewportPosition.y,\n nextZoom: (0,_scene__WEBPACK_IMPORTED_MODULE_29__.getNormalizedZoom)(newZoom)\n }, state)), {\n shouldCacheIgnoreZoom: true\n }));\n this.resetShouldCacheIgnoreZoomDebounced();\n return;\n } // scroll horizontally when shift pressed\n\n\n if (event.shiftKey) {\n this.translateCanvas(({\n zoom,\n scrollX\n }) => ({\n // on Mac, shift+wheel tends to result in deltaX\n scrollX: scrollX - (deltaY || deltaX) / zoom.value\n }));\n return;\n }\n\n this.translateCanvas(({\n zoom,\n scrollX,\n scrollY\n }) => ({\n scrollX: scrollX - deltaX / zoom.value,\n scrollY: scrollY - deltaY / zoom.value\n }));\n });\n\n this.savePointer = (x, y, button) => {\n var _a, _b;\n\n if (!x || !y) {\n return;\n }\n\n const {\n x: sceneX,\n y: sceneY\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)({\n clientX: x,\n clientY: y\n }, this.state);\n\n if (isNaN(sceneX) || isNaN(sceneY)) {// sometimes the pointer goes off screen\n }\n\n const pointer = {\n x: sceneX,\n y: sceneY,\n tool: this.state.activeTool.type === \"laser\" ? \"laser\" : \"pointer\"\n };\n (_b = (_a = this.props).onPointerUpdate) === null || _b === void 0 ? void 0 : _b.call(_a, {\n pointer,\n button,\n pointersMap: gesture.pointers\n });\n };\n\n this.resetShouldCacheIgnoreZoomDebounced = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.debounce)(() => {\n if (!this.unmounted) {\n this.setState({\n shouldCacheIgnoreZoom: false\n });\n }\n }, 300);\n\n this.updateDOMRect = cb => {\n var _a;\n\n if ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current) {\n const excalidrawContainer = this.excalidrawContainerRef.current;\n const {\n width,\n height,\n left: offsetLeft,\n top: offsetTop\n } = excalidrawContainer.getBoundingClientRect();\n const {\n width: currentWidth,\n height: currentHeight,\n offsetTop: currentOffsetTop,\n offsetLeft: currentOffsetLeft\n } = this.state;\n\n if (width === currentWidth && height === currentHeight && offsetLeft === currentOffsetLeft && offsetTop === currentOffsetTop) {\n if (cb) {\n cb();\n }\n\n return;\n } //zsviczian\n\n\n if (width === 0 || height === 0) {\n if (cb) {\n cb();\n }\n\n return;\n }\n\n this.setState({\n width,\n height,\n offsetLeft,\n offsetTop\n }, () => {\n cb && cb();\n });\n }\n };\n\n this.refresh = () => {\n this.setState(Object.assign({}, this.getCanvasOffsets()));\n };\n\n const defaultAppState = (0,_appState__WEBPACK_IMPORTED_MODULE_10__.getDefaultAppState)();\n const {\n excalidrawRef,\n viewModeEnabled = false,\n zenModeEnabled = false,\n gridModeEnabled = false,\n objectsSnapModeEnabled = false,\n theme = defaultAppState.theme,\n name = defaultAppState.name,\n initState //zsviczian\n\n } = props;\n this.state = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, defaultAppState), {\n theme,\n isLoading: true\n }), this.getCanvasOffsets()), {\n viewModeEnabled,\n zenModeEnabled,\n objectsSnapModeEnabled,\n gridSize: gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_12__.GRID_SIZE : null,\n name,\n width: window.innerWidth,\n height: window.innerHeight\n }), initState !== null && initState !== void 0 ? initState : {});\n this.id = (0,nanoid__WEBPACK_IMPORTED_MODULE_72__.nanoid)();\n this.library = new _data_library__WEBPACK_IMPORTED_MODULE_14__[\"default\"](this);\n this.scene = new _scene_Scene__WEBPACK_IMPORTED_MODULE_30__[\"default\"]();\n this.canvas = document.createElement(\"canvas\");\n this.rc = roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_3__[\"default\"].canvas(this.canvas);\n this.renderer = new _scene_Renderer__WEBPACK_IMPORTED_MODULE_65__.Renderer(this.scene);\n\n if (excalidrawRef) {\n const readyPromise = \"current\" in excalidrawRef && ((_a = excalidrawRef.current) === null || _a === void 0 ? void 0 : _a.readyPromise) || (0,_utils__WEBPACK_IMPORTED_MODULE_33__.resolvablePromise)();\n const api = {\n ready: true,\n readyPromise,\n updateScene: this.updateScene,\n updateLibrary: this.library.updateLibrary,\n addFiles: this.addFiles,\n resetScene: this.resetScene,\n getSceneElementsIncludingDeleted: this.getSceneElementsIncludingDeleted,\n history: {\n clear: this.resetHistory\n },\n scrollToContent: this.scrollToContent,\n zoomToFit: this.zoomToFit,\n startLineEditor: this.startLineEditor,\n getSceneElements: this.getSceneElements,\n getAppState: () => this.state,\n getFiles: () => this.files,\n refresh: this.refresh,\n setToast: this.setToast,\n updateContainerSize: this.updateContainerSize,\n id: this.id,\n setLocalFont: this.setLocalFont,\n selectElements: this.selectElements,\n sendBackward: this.sendBackward,\n bringForward: this.bringForward,\n sendToBack: this.sendToBack,\n bringToFront: this.bringToFront,\n setMobileModeAllowed: this.setMobileModeAllowed,\n setActiveTool: this.setActiveTool,\n setCursor: this.setCursor,\n resetCursor: this.resetCursor,\n updateFrameRendering: this.updateFrameRendering,\n toggleSidebar: this.toggleSidebar,\n getHTMLIFrameElement: id => this.getHTMLIFrameElement(id),\n onChange: cb => this.onChangeEmitter.on(cb),\n onPointerDown: cb => this.onPointerDownEmitter.on(cb),\n onPointerUp: cb => this.onPointerUpEmitter.on(cb)\n };\n\n if (typeof excalidrawRef === \"function\") {\n excalidrawRef(api);\n } else {\n excalidrawRef.current = api;\n }\n\n readyPromise.resolve(api);\n }\n\n this.excalidrawContainerValue = {\n container: this.excalidrawContainerRef.current,\n id: this.id\n };\n this.fonts = new _scene_Fonts__WEBPACK_IMPORTED_MODULE_50__.Fonts({\n scene: this.scene,\n onSceneUpdated: this.onSceneUpdated\n });\n this.history = new _history__WEBPACK_IMPORTED_MODULE_24__[\"default\"]();\n this.actionManager = new _actions_manager__WEBPACK_IMPORTED_MODULE_7__.ActionManager(this.syncActionResult, () => this.state, () => this.scene.getElementsIncludingDeleted(), this);\n this.actionManager.registerAll(_actions_register__WEBPACK_IMPORTED_MODULE_8__.actions);\n this.actionManager.registerAction((0,_actions_actionHistory__WEBPACK_IMPORTED_MODULE_6__.createUndoAction)(this.history));\n this.actionManager.registerAction((0,_actions_actionHistory__WEBPACK_IMPORTED_MODULE_6__.createRedoAction)(this.history));\n }\n\n onWindowMessage(event) {\n if (event.origin !== \"https://player.vimeo.com\" && event.origin !== \"https://www.youtube.com\") {\n return;\n }\n\n let data = null;\n\n try {\n data = JSON.parse(event.data);\n } catch (e) {}\n\n if (!data) {\n return;\n }\n\n switch (event.origin) {\n case \"https://player.vimeo.com\":\n //Allowing for multiple instances of Excalidraw running in the window\n if (data.method === \"paused\") {\n let source = null;\n const iframes = document.body.querySelectorAll(\"iframe.excalidraw__embeddable\");\n\n if (!iframes) {\n break;\n }\n\n for (const iframe of iframes) {\n if (iframe.contentWindow === event.source) {\n source = iframe.contentWindow;\n }\n }\n\n source === null || source === void 0 ? void 0 : source.postMessage(JSON.stringify({\n method: data.value ? \"play\" : \"pause\",\n value: true\n }), \"*\");\n }\n\n break;\n\n case \"https://www.youtube.com\":\n if (data.event === \"infoDelivery\" && data.info && data.id && typeof data.info.playerState === \"number\") {\n const id = data.id;\n const playerState = data.info.playerState;\n\n if (Object.values(_constants__WEBPACK_IMPORTED_MODULE_12__.YOUTUBE_STATES).includes(playerState)) {\n YOUTUBE_VIDEO_STATES.set(id, playerState);\n }\n }\n\n break;\n }\n }\n\n updateEmbeddableRef(id, ref) {\n if (ref) {\n this.iFrameRefs.set(id, ref);\n }\n }\n\n getHTMLIFrameElement(id) {\n return this.iFrameRefs.get(id);\n }\n\n handleEmbeddableCenterClick(element) {\n var _a, _b, _c, _d;\n\n if (((_a = this.state.activeEmbeddable) === null || _a === void 0 ? void 0 : _a.element) === element && ((_b = this.state.activeEmbeddable) === null || _b === void 0 ? void 0 : _b.state) === \"active\") {\n return;\n } // The delay serves two purposes\n // 1. To prevent first click propagating to iframe on mobile,\n // else the click will immediately start and stop the video\n // 2. If the user double clicks the frame center to activate it\n // without the delay youtube will immediately open the video\n // in fullscreen mode\n\n\n setTimeout(() => {\n this.setState({\n activeEmbeddable: {\n element,\n state: \"active\"\n },\n selectedElementIds: {\n [element.id]: true\n },\n draggingElement: null,\n selectionElement: null\n });\n }, 100);\n const iframe = this.getHTMLIFrameElement(element.id);\n\n if (!(iframe === null || iframe === void 0 ? void 0 : iframe.contentWindow)) {\n return;\n }\n\n if (iframe.src.includes(\"youtube\")) {\n const state = YOUTUBE_VIDEO_STATES.get(element.id);\n\n if (!state) {\n YOUTUBE_VIDEO_STATES.set(element.id, _constants__WEBPACK_IMPORTED_MODULE_12__.YOUTUBE_STATES.UNSTARTED);\n iframe.contentWindow.postMessage(JSON.stringify({\n event: \"listening\",\n id: element.id\n }), \"*\");\n }\n\n switch (state) {\n case _constants__WEBPACK_IMPORTED_MODULE_12__.YOUTUBE_STATES.PLAYING:\n case _constants__WEBPACK_IMPORTED_MODULE_12__.YOUTUBE_STATES.BUFFERING:\n (_c = iframe.contentWindow) === null || _c === void 0 ? void 0 : _c.postMessage(JSON.stringify({\n event: \"command\",\n func: \"pauseVideo\",\n args: \"\"\n }), \"*\");\n break;\n\n default:\n (_d = iframe.contentWindow) === null || _d === void 0 ? void 0 : _d.postMessage(JSON.stringify({\n event: \"command\",\n func: \"playVideo\",\n args: \"\"\n }), \"*\");\n }\n }\n\n if (iframe.src.includes(\"player.vimeo.com\")) {\n iframe.contentWindow.postMessage(JSON.stringify({\n method: \"paused\" //video play/pause in onWindowMessage handler\n\n }), \"*\");\n }\n }\n\n isEmbeddableCenter(el, event, sceneX, sceneY) {\n var _a, _b;\n\n return el && !event.altKey && !event.shiftKey && !event.metaKey && !event.ctrlKey && (((_a = this.state.activeEmbeddable) === null || _a === void 0 ? void 0 : _a.element) !== el || ((_b = this.state.activeEmbeddable) === null || _b === void 0 ? void 0 : _b.state) === \"hover\" || !this.state.activeEmbeddable) && sceneX >= el.x + el.width / 3 && sceneX <= el.x + 2 * el.width / 3 && sceneY >= el.y + el.height / 3 && sceneY <= el.y + 2 * el.height / 3;\n }\n\n renderEmbeddables() {\n const scale = this.state.zoom.value;\n const normalizedWidth = this.state.width;\n const normalizedHeight = this.state.height;\n const embeddableElements = this.scene.getNonDeletedElements().filter(el => (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isEmbeddableElement)(el) && !!el.validated);\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n children: embeddableElements.map(el => {\n var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;\n\n const {\n x,\n y\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.sceneCoordsToViewportCoords)({\n sceneX: el.x,\n sceneY: el.y\n }, this.state);\n const embedLink = (0,_element_embeddable__WEBPACK_IMPORTED_MODULE_34__.getEmbedLink)((0,_data_url__WEBPACK_IMPORTED_MODULE_47__.toValidURL)(el.link || \"\"));\n const isVisible = (0,_element_sizeHelpers__WEBPACK_IMPORTED_MODULE_27__.isElementInViewport)(el, normalizedWidth, normalizedHeight, this.state);\n const isActive = ((_a = this.state.activeEmbeddable) === null || _a === void 0 ? void 0 : _a.element) === el && ((_b = this.state.activeEmbeddable) === null || _b === void 0 ? void 0 : _b.state) === \"active\";\n const isHovered = ((_c = this.state.activeEmbeddable) === null || _c === void 0 ? void 0 : _c.element) === el && ((_d = this.state.activeEmbeddable) === null || _d === void 0 ? void 0 : _d.state) === \"hover\";\n const isWebview = //zsviczian\n this.props.renderWebview && (embedLink === null || embedLink === void 0 ? void 0 : embedLink.type) !== \"document\" && !((_f = (_e = embedLink === null || embedLink === void 0 ? void 0 : embedLink.link) === null || _e === void 0 ? void 0 : _e.startsWith) === null || _f === void 0 ? void 0 : _f.call(_e, \"https://player.vimeo.com\"));\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", Object.assign({\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_4__[\"default\"])(\"excalidraw__embeddable-container\", {\n \"is-hovered\": isHovered\n }),\n style: {\n transform: isVisible ? `translate(${x - this.state.offsetLeft}px, ${y - this.state.offsetTop}px) scale(${scale})` : \"none\",\n display: isVisible ? \"block\" : \"none\",\n opacity: el.opacity / 100,\n [\"--embeddable-radius\"]: `${(0,_math__WEBPACK_IMPORTED_MODULE_28__.getCornerRadius)(Math.min(el.width, el.height), el)}px`\n }\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"div\", Object.assign({\n //this is a hack that addresses isse with embedded excalidraw.com embeddable\n //https://github.com/excalidraw/excalidraw/pull/6691#issuecomment-1607383938\n\n /*ref={(ref) => {\r\n if (!this.excalidrawContainerRef.current) {\r\n return;\r\n }\r\n const container = this.excalidrawContainerRef.current;\r\n const sh = container.scrollHeight;\r\n const ch = container.clientHeight;\r\n if (sh !== ch) {\r\n container.style.height = `${sh}px`;\r\n setTimeout(() => {\r\n container.style.height = `100%`;\r\n });\r\n }\r\n }}*/\n className: \"excalidraw__embeddable-container__inner\",\n style: {\n width: isVisible ? `${el.width}px` : 0,\n height: isVisible ? `${el.height}px` : 0,\n transform: isVisible ? `rotate(${el.angle}rad)` : \"none\",\n pointerEvents: isActive ? _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_EVENTS.enabled : _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_EVENTS.disabled\n }\n }, {\n children: [isHovered && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", Object.assign({\n className: \"excalidraw__embeddable-hint\"\n }, {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"buttons.embeddableInteractionButton\")\n })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", Object.assign({\n className: \"excalidraw__embeddable__outer\",\n style: {\n padding: `${el.strokeWidth}px`\n }\n }, {\n children: (_j = (_h = (_g = this.props).renderEmbeddable) === null || _h === void 0 ? void 0 : _h.call(_g, el, this.state)) !== null && _j !== void 0 ? _j : isWebview ? (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"webview\", {\n ref: ref => this.updateEmbeddableRef(el.id, ref),\n className: \"excalidraw__embeddable\",\n src: (_k = embedLink === null || embedLink === void 0 ? void 0 : embedLink.link) !== null && _k !== void 0 ? _k : \"\",\n title: \"Excalidraw Embedded Content\",\n allowFullScreen: true\n }) : (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"iframe\", {\n ref: ref => this.updateEmbeddableRef(el.id, ref),\n className: \"excalidraw__embeddable\",\n srcDoc: (embedLink === null || embedLink === void 0 ? void 0 : embedLink.type) === \"document\" ? embedLink.srcdoc(this.state.theme) : undefined,\n src: (embedLink === null || embedLink === void 0 ? void 0 : embedLink.type) !== \"document\" ? (_l = embedLink === null || embedLink === void 0 ? void 0 : embedLink.link) !== null && _l !== void 0 ? _l : \"\" : undefined,\n // https://stackoverflow.com/q/18470015\n scrolling: \"no\",\n referrerPolicy: \"no-referrer-when-downgrade\",\n title: \"Excalidraw Embedded Content\",\n allow: \"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\",\n allowFullScreen: true,\n sandbox: \"allow-same-origin allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation allow-downloads\"\n })\n }))]\n }))\n }), el.id);\n })\n });\n }\n\n render() {\n var _a, _b, _c, _d, _e, _f;\n\n const selectedElements = this.scene.getSelectedElements(this.state);\n const {\n renderTopRightUI,\n renderCustomStats\n } = this.props;\n const versionNonce = this.scene.getVersionNonce();\n const {\n canvasElements,\n visibleElements\n } = this.renderer.getRenderableElements({\n versionNonce,\n zoom: this.state.zoom,\n offsetLeft: this.state.offsetLeft,\n offsetTop: this.state.offsetTop,\n scrollX: this.state.scrollX,\n scrollY: this.state.scrollY,\n height: this.state.height,\n width: this.state.width,\n editingElement: this.state.editingElement,\n pendingImageElementId: this.state.pendingImageElementId\n });\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", Object.assign({\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_4__[\"default\"])(\"excalidraw excalidraw-container\", {\n \"excalidraw--view-mode\": this.state.viewModeEnabled,\n \"excalidraw--mobile\": this.device.isMobile || !(this.state.viewModeEnabled || this.state.zenModeEnabled) && this.state.trayModeEnabled //zsviczian\n\n }),\n style: {\n [\"--ui-pointerEvents\"]: this.state.selectionElement || this.state.draggingElement || this.state.resizingElement || this.state.activeTool.type === \"laser\" && // technically we can just test on this once we make it more safe\n this.state.cursorButton === \"down\" || this.state.editingElement && !(0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement) ? _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_EVENTS.disabled : _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_EVENTS.enabled\n },\n ref: this.excalidrawContainerRef,\n onDrop: this.handleAppOnDrop,\n tabIndex: 0,\n onKeyDown: this.props.handleKeyboardGlobally ? undefined : this.onKeyDown\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(AppContext.Provider, Object.assign({\n value: this\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(AppPropsContext.Provider, Object.assign({\n value: this.props\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(ExcalidrawContainerContext.Provider, Object.assign({\n value: this.excalidrawContainerValue\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(DeviceContext.Provider, Object.assign({\n value: this.device\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(ExcalidrawSetAppStateContext.Provider, Object.assign({\n value: this.setAppState\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(ExcalidrawAppStateContext.Provider, Object.assign({\n value: this.state\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(ExcalidrawElementsContext.Provider, Object.assign({\n value: this.scene.getNonDeletedElements()\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(ExcalidrawActionManagerContext.Provider, Object.assign({\n value: this.actionManager\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(_LayerUI__WEBPACK_IMPORTED_MODULE_36__[\"default\"], Object.assign({\n canvas: this.canvas,\n appState: this.state,\n files: this.files,\n setAppState: this.setAppState,\n actionManager: this.actionManager,\n elements: this.scene.getNonDeletedElements(),\n onLockToggle: this.toggleLock,\n onPenModeToggle: this.togglePenMode,\n onHandToolToggle: this.onHandToolToggle,\n langCode: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.getLanguage)().code,\n renderTopRightUI: renderTopRightUI,\n renderCustomStats: renderCustomStats,\n showExitZenModeBtn: typeof ((_a = this.props) === null || _a === void 0 ? void 0 : _a.zenModeEnabled) === \"undefined\" && this.state.zenModeEnabled,\n UIOptions: this.props.UIOptions,\n onExportImage: this.onExportImage,\n renderWelcomeScreen: !this.state.isLoading && this.state.showWelcomeScreen && this.state.activeTool.type === \"selection\" && !this.state.zenModeEnabled && !this.scene.getElementsIncludingDeleted().length,\n app: this,\n isCollaborating: this.props.isCollaborating\n }, {\n children: [this.props.children, this.props.renderMermaid && this.state.activeTool.type === \"mermaid\" && //zsviczian\n (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_MermaidToExcalidraw__WEBPACK_IMPORTED_MODULE_67__[\"default\"], {\n selectedElements: this.scene.getSelectedElements(this.state)\n })]\n })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", {\n className: \"excalidraw-textEditorContainer\"\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", {\n className: \"excalidraw-contextMenuContainer\"\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", {\n className: \"excalidraw-eye-dropper-container\"\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_LaserTool_LaserTool__WEBPACK_IMPORTED_MODULE_68__.LaserToolOverlay, {\n manager: this.laserPathManager\n }), selectedElements.length === 1 && !this.state.contextMenu && this.state.showHyperlinkPopup && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_element_Hyperlink__WEBPACK_IMPORTED_MODULE_46__.Hyperlink, {\n element: selectedElements[0],\n setAppState: this.setAppState,\n onLinkOpen: this.props.onLinkOpen,\n setToast: this.setToast\n }, selectedElements[0].id), this.state.toast !== null && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Toast__WEBPACK_IMPORTED_MODULE_37__.Toast, {\n message: this.state.toast.message,\n onClose: () => this.setToast(null),\n duration: this.state.toast.duration,\n closable: this.state.toast.closable\n }), this.state.contextMenu && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_ContextMenu__WEBPACK_IMPORTED_MODULE_35__.ContextMenu, {\n items: this.state.contextMenu.items,\n top: this.state.contextMenu.top,\n left: this.state.contextMenu.left,\n actionManager: this.actionManager\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_canvases__WEBPACK_IMPORTED_MODULE_64__.StaticCanvas, {\n canvas: this.canvas,\n rc: this.rc,\n elements: canvasElements,\n visibleElements: visibleElements,\n versionNonce: versionNonce,\n selectionNonce: (_b = this.state.selectionElement) === null || _b === void 0 ? void 0 : _b.versionNonce,\n scale: window.devicePixelRatio,\n appState: this.state,\n renderConfig: {\n imageCache: this.imageCache,\n isExporting: false,\n renderGrid: true\n }\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_canvases__WEBPACK_IMPORTED_MODULE_64__.InteractiveCanvas, {\n containerRef: this.excalidrawContainerRef,\n canvas: this.interactiveCanvas,\n elements: canvasElements,\n visibleElements: visibleElements,\n selectedElements: selectedElements,\n versionNonce: versionNonce,\n selectionNonce: (_c = this.state.selectionElement) === null || _c === void 0 ? void 0 : _c.versionNonce,\n scale: window.devicePixelRatio,\n appState: this.state,\n renderInteractiveSceneCallback: this.renderInteractiveSceneCallback,\n handleCanvasRef: this.handleInteractiveCanvasRef,\n onContextMenu: this.handleCanvasContextMenu,\n onPointerMove: this.handleCanvasPointerMove,\n onPointerUp: this.handleCanvasPointerUp,\n onPointerCancel: this.removePointer,\n onTouchMove: this.handleTouchMove,\n onPointerDown: this.handleCanvasPointerDown,\n onDoubleClick: this.handleCanvasDoubleClick\n }), this.renderFrameNames(), ((_d = this.state.activeEmbeddable) === null || _d === void 0 ? void 0 : _d.state) === \"active\" && ( //zsviczian\n (_f = (_e = this.props).renderEmbeddableMenu) === null || _f === void 0 ? void 0 : _f.call(_e, this.state))]\n })), this.renderEmbeddables()]\n }))\n }))\n }))\n }))\n }))\n }))\n }))\n }));\n }\n\n async componentDidMount() {\n var _a, _b;\n\n this.unmounted = false;\n this.excalidrawContainerValue.container = this.excalidrawContainerRef.current;\n\n if (\"development\" === _constants__WEBPACK_IMPORTED_MODULE_12__.ENV.TEST || \"development\" !== \"production\") {\n const setState = this.setState.bind(this);\n Object.defineProperties(window.h, {\n state: {\n configurable: true,\n get: () => {\n return this.state;\n }\n },\n setState: {\n configurable: true,\n value: (...args) => {\n return this.setState(...args);\n }\n },\n app: {\n configurable: true,\n value: this\n },\n history: {\n configurable: true,\n value: this.history\n }\n });\n }\n\n this.scene.addCallback(this.onSceneUpdated);\n this.addEventListeners();\n\n if (this.props.autoFocus && this.excalidrawContainerRef.current) {\n this.focusContainer();\n }\n\n if (this.excalidrawContainerRef.current && // bounding rects don't work in tests so updating\n // the state on init would result in making the test enviro run\n // in mobile breakpoint (0 width/height), making everything fail\n !(0,_utils__WEBPACK_IMPORTED_MODULE_33__.isTestEnv)()) {\n this.refreshDeviceState(this.excalidrawContainerRef.current);\n }\n\n if (\"ResizeObserver\" in window && ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current)) {\n this.resizeObserver = new ResizeObserver(() => {\n // recompute device dimensions state\n // ---------------------------------------------------------------------\n this.refreshDeviceState(this.excalidrawContainerRef.current); // refresh offsets\n // ---------------------------------------------------------------------\n\n this.updateDOMRect();\n });\n (_b = this.resizeObserver) === null || _b === void 0 ? void 0 : _b.observe(this.excalidrawContainerRef.current);\n } else if (window.matchMedia) {\n const mdScreenQuery = window.matchMedia(`(max-width: ${_constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_PORTRAIT}px), (max-height: ${_constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_HEIGHT_LANDSCAPE}px) and (max-width: ${_constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_LANDSCAPE}px)`);\n const smScreenQuery = window.matchMedia(`(max-width: ${_constants__WEBPACK_IMPORTED_MODULE_12__.MQ_SM_MAX_WIDTH}px)`);\n const canDeviceFitSidebarMediaQuery = window.matchMedia(`(min-width: ${// NOTE this won't update if a different breakpoint is supplied\n // after mount\n this.props.UIOptions.dockedSidebarBreakpoint != null ? this.props.UIOptions.dockedSidebarBreakpoint : _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_RIGHT_SIDEBAR_MIN_WIDTH}px)`);\n\n const handler = () => {\n this.excalidrawContainerRef.current.getBoundingClientRect();\n this.device = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.updateObject)(this.device, {\n isSmScreen: smScreenQuery.matches,\n isMobile: mdScreenQuery.matches && this.allowMobileMode,\n canDeviceFitSidebar: canDeviceFitSidebarMediaQuery.matches\n });\n };\n\n mdScreenQuery.addListener(handler);\n\n this.detachIsMobileMqHandler = () => mdScreenQuery.removeListener(handler);\n }\n\n const searchParams = new URLSearchParams(window.location.search.slice(1));\n\n if (searchParams.has(\"web-share-target\")) {\n // Obtain a file that was shared via the Web Share Target API.\n this.restoreFileFromShare();\n } else {\n this.updateDOMRect(this.initializeScene);\n } // note that this check seems to always pass in localhost\n\n\n if ((0,_constants__WEBPACK_IMPORTED_MODULE_12__.isBrave)() && !(0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.isMeasureTextSupported)()) {\n this.setState({\n errorMessage: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_BraveMeasureTextError__WEBPACK_IMPORTED_MODULE_60__[\"default\"], {})\n });\n }\n }\n\n componentWillUnmount() {\n var _a;\n\n this.renderer.destroy();\n this.scene = new _scene_Scene__WEBPACK_IMPORTED_MODULE_30__[\"default\"]();\n this.renderer = new _scene_Renderer__WEBPACK_IMPORTED_MODULE_65__.Renderer(this.scene);\n this.files = {};\n this.imageCache.clear();\n (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();\n this.unmounted = true;\n this.removeEventListeners();\n this.scene.destroy();\n this.library.destroy();\n this.laserPathManager.destroy();\n this.onChangeEmitter.destroy();\n _scene_ShapeCache__WEBPACK_IMPORTED_MODULE_66__.ShapeCache.destroy();\n _snapping__WEBPACK_IMPORTED_MODULE_58__.SnapCache.destroy();\n clearTimeout(touchTimeout);\n _scene__WEBPACK_IMPORTED_MODULE_29__.isSomeElementSelected.clearCache();\n _groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements.clearCache();\n touchTimeout = 0;\n }\n\n removeEventListeners() {\n var _a, _b, _c, _d, _e;\n\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, this.removePointer);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.COPY, this.onCopy);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, this.pasteFromClipboard);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.CUT, this.onCut);\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.WHEEL, this.onWheel);\n (_b = this.nearestScrollableContainer) === null || _b === void 0 ? void 0 : _b.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.SCROLL, this.onScroll);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYDOWN, this.onKeyDown, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.MOUSE_MOVE, this.updateCurrentCursorPosition, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYUP, this.onKeyUp);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.RESIZE, this.onResize, false);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.UNLOAD, this.onUnload, false);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.BLUR, this.onBlur, false);\n (_c = this.excalidrawContainerRef.current) === null || _c === void 0 ? void 0 : _c.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.DRAG_OVER, this.disableEvent, false);\n (_d = this.excalidrawContainerRef.current) === null || _d === void 0 ? void 0 : _d.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.DROP, this.disableEvent, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_START, this.onGestureStart, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_CHANGE, this.onGestureChange, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_END, this.onGestureEnd, false);\n (_e = this.detachIsMobileMqHandler) === null || _e === void 0 ? void 0 : _e.call(this);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.MESSAGE, this.onWindowMessage, false);\n }\n\n addEventListeners() {\n var _a, _b, _c, _d, _e;\n\n this.removeEventListeners();\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.MESSAGE, this.onWindowMessage, false);\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, this.removePointer); // #3553\n\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.COPY, this.onCopy);\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.WHEEL, this.onWheel, {\n passive: false\n });\n\n if (this.props.handleKeyboardGlobally) {\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYDOWN, this.onKeyDown, false);\n }\n\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYUP, this.onKeyUp, {\n passive: true\n });\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.MOUSE_MOVE, this.updateCurrentCursorPosition); // rerender text elements on font load to fix #637 && #1553\n\n (_c = (_b = document.fonts) === null || _b === void 0 ? void 0 : _b.addEventListener) === null || _c === void 0 ? void 0 : _c.call(_b, \"loadingdone\", event => {\n const loadedFontFaces = event.fontfaces;\n this.fonts.onFontsLoaded(loadedFontFaces);\n }); // Safari-only desktop pinch zoom\n\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_START, this.onGestureStart, false);\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_CHANGE, this.onGestureChange, false);\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_END, this.onGestureEnd, false);\n\n if (this.state.viewModeEnabled) {\n return;\n }\n\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, this.pasteFromClipboard);\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.CUT, this.onCut);\n\n if (this.props.detectScroll) {\n this.nearestScrollableContainer = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.getNearestScrollableContainer)(this.excalidrawContainerRef.current);\n this.nearestScrollableContainer.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.SCROLL, this.onScroll);\n }\n\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.RESIZE, this.onResize, false);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.UNLOAD, this.onUnload, false);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.BLUR, this.onBlur, false);\n (_d = this.excalidrawContainerRef.current) === null || _d === void 0 ? void 0 : _d.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.DRAG_OVER, this.disableEvent, false);\n (_e = this.excalidrawContainerRef.current) === null || _e === void 0 ? void 0 : _e.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.DROP, this.disableEvent, false);\n }\n\n componentDidUpdate(prevProps, prevState) {\n var _a, _b, _c, _d, _e, _f;\n\n this.updateEmbeddables();\n\n if (!this.state.showWelcomeScreen && !this.scene.getElementsIncludingDeleted().length) {\n this.setState({\n showWelcomeScreen: true\n });\n }\n\n if (this.excalidrawContainerRef.current && prevProps.UIOptions.dockedSidebarBreakpoint !== this.props.UIOptions.dockedSidebarBreakpoint) {\n this.refreshDeviceState(this.excalidrawContainerRef.current);\n }\n\n if (prevState.scrollX !== this.state.scrollX || prevState.scrollY !== this.state.scrollY) {\n (_b = (_a = this.props) === null || _a === void 0 ? void 0 : _a.onScrollChange) === null || _b === void 0 ? void 0 : _b.call(_a, this.state.scrollX, this.state.scrollY);\n }\n\n if (Object.keys(this.state.selectedElementIds).length && (0,_appState__WEBPACK_IMPORTED_MODULE_10__.isEraserActive)(this.state)) {\n this.setState({\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_33__.updateActiveTool)(this.state, {\n type: \"selection\"\n })\n });\n }\n\n if (this.state.activeTool.type === \"eraser\" && prevState.theme !== this.state.theme) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setEraserCursor)(this.interactiveCanvas, this.state.theme);\n } // Hide hyperlink popup if shown when element type is not selection\n\n\n if (prevState.activeTool.type === \"selection\" && this.state.activeTool.type !== \"selection\" && this.state.showHyperlinkPopup) {\n this.setState({\n showHyperlinkPopup: false\n });\n }\n\n if (prevProps.langCode !== this.props.langCode) {\n this.updateLanguage();\n }\n\n if (prevProps.viewModeEnabled !== this.props.viewModeEnabled) {\n this.setState({\n viewModeEnabled: !!this.props.viewModeEnabled\n });\n }\n\n if (prevState.viewModeEnabled !== this.state.viewModeEnabled) {\n this.addEventListeners();\n this.deselectElements();\n }\n\n if (prevProps.zenModeEnabled !== this.props.zenModeEnabled) {\n this.setState({\n zenModeEnabled: !!this.props.zenModeEnabled\n });\n }\n\n if (prevProps.theme !== this.props.theme && this.props.theme) {\n this.setState({\n theme: this.props.theme\n });\n }\n\n if (prevProps.gridModeEnabled !== this.props.gridModeEnabled) {\n this.setState({\n gridSize: this.props.gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_12__.GRID_SIZE : null\n });\n }\n\n if (this.props.name && prevProps.name !== this.props.name) {\n this.setState({\n name: this.props.name\n });\n }\n\n (_c = this.excalidrawContainerRef.current) === null || _c === void 0 ? void 0 : _c.classList.toggle(\"theme--dark\", this.state.theme === \"dark\");\n\n if (this.state.editingLinearElement && !this.state.selectedElementIds[this.state.editingLinearElement.elementId]) {\n // defer so that the commitToHistory flag isn't reset via current update\n setTimeout(() => {\n // execute only if the condition still holds when the deferred callback\n // executes (it can be scheduled multiple times depending on how\n // many times the component renders)\n this.state.editingLinearElement && this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n });\n } // failsafe in case the state is being updated in incorrect order resulting\n // in the editingElement being now a deleted element\n\n\n if ((_d = this.state.editingElement) === null || _d === void 0 ? void 0 : _d.isDeleted) {\n this.setState({\n editingElement: null\n });\n }\n\n if (this.state.selectedLinearElement && !this.state.selectedElementIds[this.state.selectedLinearElement.elementId]) {\n // To make sure `selectedLinearElement` is in sync with `selectedElementIds`, however this shouldn't be needed once\n // we have a single API to update `selectedElementIds`\n this.setState({\n selectedLinearElement: null\n });\n }\n\n const {\n multiElement\n } = prevState;\n\n if (prevState.activeTool !== this.state.activeTool && multiElement != null && (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state) && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(multiElement, false)) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.maybeBindLinearElement)(multiElement, this.state, this.scene, (0,_utils__WEBPACK_IMPORTED_MODULE_33__.tupleToCoors)(_element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.getPointAtIndexGlobalCoordinates(multiElement, -1)));\n }\n\n this.history.record(this.state, this.scene.getElementsIncludingDeleted()); // Do not notify consumers if we're still loading the scene. Among other\n // potential issues, this fixes a case where the tab isn't focused during\n // init, which would trigger onChange with empty elements, which would then\n // override whatever is in localStorage currently.\n\n if (!this.state.isLoading) {\n (_f = (_e = this.props).onChange) === null || _f === void 0 ? void 0 : _f.call(_e, this.scene.getElementsIncludingDeleted(), this.state, this.files);\n this.onChangeEmitter.trigger(this.scene.getElementsIncludingDeleted(), this.state, this.files);\n }\n }\n\n static resetTapTwice() {\n didTapTwice = false;\n } // TODO rewrite this to paste both text & images at the same time if\n // pasted data contains both\n\n\n async addElementsFromMixedContentPaste(mixedContent, {\n isPlainPaste,\n sceneX,\n sceneY\n }) {\n if (!isPlainPaste && mixedContent.some(node => node.type === \"imageUrl\")) {\n const imageURLs = mixedContent.filter(node => node.type === \"imageUrl\").map(node => node.value);\n const responses = await Promise.all(imageURLs.map(async url => {\n try {\n return {\n file: await (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.ImageURLToFile)(url)\n };\n } catch (error) {\n return {\n errorMessage: error.message\n };\n }\n }));\n let y = sceneY;\n let firstImageYOffsetDone = false;\n const nextSelectedIds = {};\n\n for (const response of responses) {\n if (response.file) {\n const imageElement = this.createImageElement({\n sceneX,\n sceneY: y\n });\n const initializedImageElement = await this.insertImageElement(imageElement, response.file);\n\n if (initializedImageElement) {\n // vertically center first image in the batch\n if (!firstImageYOffsetDone) {\n firstImageYOffsetDone = true;\n y -= initializedImageElement.height / 2;\n } // hack to reset the `y` coord because we vertically center during\n // insertImageElement\n\n\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(initializedImageElement, {\n y\n }, false);\n y = imageElement.y + imageElement.height + 25;\n nextSelectedIds[imageElement.id] = true;\n }\n }\n }\n\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(nextSelectedIds, this.state)\n });\n const error = responses.find(response => !!response.errorMessage);\n\n if (error && error.errorMessage) {\n this.setState({\n errorMessage: error.errorMessage\n });\n }\n } else {\n const textNodes = mixedContent.filter(node => node.type === \"text\");\n\n if (textNodes.length) {\n this.addTextFromPaste(textNodes.map(node => node.value).join(\"\\n\\n\"), isPlainPaste);\n }\n }\n }\n\n addTextFromPaste(text, isPlainPaste = false) {\n const {\n x,\n y\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)({\n clientX: this.lastViewportPosition.x,\n clientY: this.lastViewportPosition.y\n }, this.state);\n const textElementProps = {\n x,\n y,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roundness: null,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n text,\n rawText: text,\n fontSize: this.state.currentItemFontSize,\n fontFamily: this.state.currentItemFontFamily,\n textAlign: this.state.currentItemTextAlign,\n verticalAlign: _constants__WEBPACK_IMPORTED_MODULE_12__.DEFAULT_VERTICAL_ALIGN,\n locked: false\n };\n const LINE_GAP = 10;\n let currentY = y;\n const lines = isPlainPaste ? [text] : text.split(\"\\n\");\n const textElements = lines.reduce((acc, line, idx) => {\n var _a;\n\n const text = line.trim();\n const lineHeight = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getDefaultLineHeight)(textElementProps.fontFamily);\n\n if (text.length) {\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newTextElement)(Object.assign(Object.assign({}, textElementProps), {\n x,\n y: currentY,\n text,\n rawText: text,\n //zsviczian\n lineHeight\n }));\n acc.push(element);\n currentY += element.height + LINE_GAP;\n } else {\n const prevLine = (_a = lines[idx - 1]) === null || _a === void 0 ? void 0 : _a.trim(); // add paragraph only if previous line was not empty, IOW don't add\n // more than one empty line\n\n if (prevLine) {\n currentY += (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getLineHeightInPx)(textElementProps.fontSize, lineHeight) + LINE_GAP;\n }\n }\n\n return acc;\n }, []);\n\n if (textElements.length === 0) {\n return;\n }\n\n const frameId = textElements[0].frameId;\n\n if (frameId) {\n this.scene.insertElementsAtIndex(textElements, this.scene.getElementIndex(frameId));\n } else {\n this.scene.replaceAllElements([...this.scene.getElementsIncludingDeleted(), ...textElements]);\n }\n\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(Object.fromEntries(textElements.map(el => [el.id, true])), this.state)\n });\n\n if (!isPlainPaste && textElements.length > 1 && PLAIN_PASTE_TOAST_SHOWN === false && !this.device.isMobile) {\n this.setToast({\n message: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"toast.pasteAsSingleElement\", {\n shortcut: (0,_utils__WEBPACK_IMPORTED_MODULE_33__.getShortcutKey)(\"CtrlOrCmd+Shift+V\")\n }),\n duration: 5000\n });\n PLAIN_PASTE_TOAST_SHOWN = true;\n }\n\n this.history.resumeRecording();\n }\n\n handleTextWysiwyg(element, {\n isExistingElement = false\n }) {\n const updateElement = (text, originalText, isDeleted, rawText, link) => {\n this.scene.replaceAllElements([...this.scene.getElementsIncludingDeleted().map(_element => {\n if (_element.id === element.id && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(_element)) {\n return (0,_element__WEBPACK_IMPORTED_MODULE_16__.updateTextElement)(_element, {\n text,\n isDeleted,\n originalText,\n rawText: rawText !== null && rawText !== void 0 ? rawText : originalText,\n link\n });\n }\n\n return _element;\n })]);\n };\n\n if (isExistingElement && this.props.onBeforeTextEdit) {\n const text = this.props.onBeforeTextEdit(element);\n\n if (text) {\n this.scene.replaceAllElements([...this.scene.getElementsIncludingDeleted().map(_element => {\n if (_element.id === element.id && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(_element)) {\n element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.updateTextElement)(_element, {\n text,\n isDeleted: false,\n originalText: text\n });\n return element;\n }\n\n return _element;\n })]);\n }\n }\n\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.textWysiwyg)({\n id: element.id,\n canvas: this.canvas,\n getViewportCoords: (x, y) => {\n const {\n x: viewportX,\n y: viewportY\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.sceneCoordsToViewportCoords)({\n sceneX: x,\n sceneY: y\n }, this.state);\n return [viewportX - this.state.offsetLeft, viewportY - this.state.offsetTop];\n },\n onChange: (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(text => {\n updateElement(text, text, false);\n\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isNonDeletedElement)(element)) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.updateBoundElements)(element);\n }\n }),\n onSubmit: (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(({\n text,\n viaKeyboard,\n originalText\n }) => {\n const isDeleted = !text.trim();\n const rawText = originalText; //should this be originalText??\n\n let link = undefined;\n\n if (this.props.onBeforeTextSubmit) {\n const [updatedText, updatedOriginalText, l] = this.props.onBeforeTextSubmit(element, text, originalText, isDeleted);\n text = updatedText !== null && updatedText !== void 0 ? updatedText : text;\n originalText = updatedOriginalText !== null && updatedOriginalText !== void 0 ? updatedOriginalText : originalText;\n link = l;\n }\n\n updateElement(text, originalText, isDeleted, rawText, link); // select the created text element only if submitting via keyboard\n // (when submitting via click it should act as signal to deselect)\n\n if (!isDeleted && viaKeyboard) {\n const elementIdToSelect = element.containerId ? element.containerId : element.id;\n this.setState(prevState => ({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(Object.assign(Object.assign({}, prevState.selectedElementIds), {\n [elementIdToSelect]: true\n }), prevState)\n }));\n }\n\n if (isDeleted) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDeletion)(this.scene.getNonDeletedElements(), [element]);\n }\n\n if (!isDeleted || isExistingElement) {\n this.history.resumeRecording();\n }\n\n this.setState({\n draggingElement: null,\n editingElement: null\n });\n\n if (this.state.activeTool.locked) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursorForShape)(this.interactiveCanvas, this.state);\n }\n\n this.focusContainer();\n }),\n element,\n excalidrawContainer: this.excalidrawContainerRef.current,\n app: this\n }); // deselect all other elements when inserting text\n\n this.deselectElements(); // do an initial update to re-initialize element position since we were\n // modifying element's x/y for sake of editor (case: syncing to remote)\n\n updateElement(element.text, element.originalText, false);\n }\n\n deselectElements() {\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({}, this.state),\n selectedGroupIds: {},\n editingGroupId: null,\n activeEmbeddable: null\n });\n }\n\n getTextElementAtPosition(x, y) {\n const element = this.getElementAtPosition(x, y, {\n includeBoundTextElement: true\n });\n\n if (element && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element) && !element.isDeleted) {\n return element;\n }\n\n return null;\n }\n\n getElementAtPosition(x, y, opts) {\n const allHitElements = this.getElementsAtPosition(x, y, opts === null || opts === void 0 ? void 0 : opts.includeBoundTextElement, opts === null || opts === void 0 ? void 0 : opts.includeLockedElements);\n\n if (allHitElements.length > 1) {\n if (opts === null || opts === void 0 ? void 0 : opts.preferSelected) {\n for (let index = allHitElements.length - 1; index > -1; index--) {\n if (this.state.selectedElementIds[allHitElements[index].id]) {\n return allHitElements[index];\n }\n }\n }\n\n const elementWithHighestZIndex = allHitElements[allHitElements.length - 1]; // If we're hitting element with highest z-index only on its bounding box\n // while also hitting other element figure, the latter should be considered.\n\n return (0,_element__WEBPACK_IMPORTED_MODULE_16__.isHittingElementBoundingBoxWithoutHittingElement)(elementWithHighestZIndex, this.state, this.frameNameBoundsCache, x, y) ? allHitElements[allHitElements.length - 2] : elementWithHighestZIndex;\n }\n\n if (allHitElements.length === 1) {\n return allHitElements[0];\n }\n\n return null;\n }\n\n getElementsAtPosition(x, y, includeBoundTextElement = false, includeLockedElements = false) {\n const elements = includeBoundTextElement && includeLockedElements ? this.scene.getNonDeletedElements() : this.scene.getNonDeletedElements().filter(element => (includeLockedElements || !element.locked) && (includeBoundTextElement || !((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element) && element.containerId)));\n return (0,_scene__WEBPACK_IMPORTED_MODULE_29__.getElementsAtPosition)(elements, element => (0,_element__WEBPACK_IMPORTED_MODULE_16__.hitTest)(element, this.state, this.frameNameBoundsCache, x, y)).filter(element => {\n // arrows don't clip even if they're children of frames,\n // so always allow hitbox regardless of beinging contained in frame\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isArrowElement)(element)) {\n return true;\n } // hitting a frame's element from outside the frame is not considered a hit\n\n\n const containingFrame = (0,_frame__WEBPACK_IMPORTED_MODULE_51__.getContainingFrame)(element);\n return containingFrame && this.state.frameRendering.enabled && this.state.frameRendering.clip ? (0,_frame__WEBPACK_IMPORTED_MODULE_51__.isCursorInFrame)({\n x,\n y\n }, containingFrame) : true;\n });\n }\n\n handleHoverSelectedLinearElement(linearElementEditor, scenePointerX, scenePointerY) {\n const element = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.getElement(linearElementEditor.elementId);\n const boundTextElement = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getBoundTextElement)(element);\n\n if (!element) {\n return;\n }\n\n if (this.state.selectedLinearElement) {\n let hoverPointIndex = -1;\n let segmentMidPointHoveredCoords = null;\n\n if ((0,_element_collision__WEBPACK_IMPORTED_MODULE_44__.isHittingElementNotConsideringBoundingBox)(element, this.state, this.frameNameBoundsCache, [scenePointerX, scenePointerY])) {\n hoverPointIndex = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.getPointIndexUnderCursor(element, this.state.zoom, scenePointerX, scenePointerY);\n segmentMidPointHoveredCoords = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.getSegmentMidpointHitCoords(linearElementEditor, {\n x: scenePointerX,\n y: scenePointerY\n }, this.state);\n\n if (hoverPointIndex >= 0 || segmentMidPointHoveredCoords) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n } else {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.MOVE);\n }\n } else if ((0,_element_transformHandles__WEBPACK_IMPORTED_MODULE_48__.shouldShowBoundingBox)([element], this.state) && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isHittingElementBoundingBoxWithoutHittingElement)(element, this.state, this.frameNameBoundsCache, scenePointerX, scenePointerY)) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.MOVE);\n } else if (boundTextElement && (0,_element__WEBPACK_IMPORTED_MODULE_16__.hitTest)(boundTextElement, this.state, this.frameNameBoundsCache, scenePointerX, scenePointerY)) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.MOVE);\n }\n\n if (this.state.selectedLinearElement.hoverPointIndex !== hoverPointIndex) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, this.state.selectedLinearElement), {\n hoverPointIndex\n })\n });\n }\n\n if (!_element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.arePointsEqual(this.state.selectedLinearElement.segmentMidPointHoveredCoords, segmentMidPointHoveredCoords)) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, this.state.selectedLinearElement), {\n segmentMidPointHoveredCoords\n })\n });\n }\n } else {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.AUTO);\n }\n }\n\n maybeCleanupAfterMissingPointerUp(event) {\n if (lastPointerUp !== null) {\n // Unfortunately, sometimes we don't get a pointerup after a pointerdown,\n // this can happen when a contextual menu or alert is triggered. In order to avoid\n // being in a weird state, we clean up on the next pointerdown\n lastPointerUp(event);\n }\n }\n\n updateGestureOnPointerDown(event) {\n gesture.pointers.set(event.pointerId, {\n x: event.clientX,\n y: event.clientY\n });\n\n if (gesture.pointers.size === 2) {\n gesture.lastCenter = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getCenter)(gesture.pointers);\n gesture.initialScale = this.state.zoom.value;\n gesture.initialDistance = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getDistance)(Array.from(gesture.pointers.values()));\n }\n }\n\n initialPointerDownState(event) {\n const origin = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)(event, this.state);\n const selectedElements = this.scene.getSelectedElements(this.state);\n const [minX, minY, maxX, maxY] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements);\n return {\n origin,\n withCmdOrCtrl: event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD],\n originInGrid: (0,_utils__WEBPACK_IMPORTED_MODULE_33__.tupleToCoors)((0,_math__WEBPACK_IMPORTED_MODULE_28__.getGridPoint)(origin.x, origin.y, event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] ? null : this.state.gridSize)),\n scrollbars: (0,_scene__WEBPACK_IMPORTED_MODULE_29__.isOverScrollBars)(currentScrollBars, event.clientX - this.state.offsetLeft, event.clientY - this.state.offsetTop),\n // we need to duplicate because we'll be updating this state\n lastCoords: Object.assign({}, origin),\n originalElements: this.scene.getNonDeletedElements().reduce((acc, element) => {\n acc.set(element.id, (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.deepCopyElement)(element));\n return acc;\n }, new Map()),\n resize: {\n handleType: false,\n isResizing: false,\n offset: {\n x: 0,\n y: 0\n },\n arrowDirection: \"origin\",\n center: {\n x: (maxX + minX) / 2,\n y: (maxY + minY) / 2\n }\n },\n hit: {\n element: null,\n allHitElements: [],\n wasAddedToSelection: false,\n hasBeenDuplicated: false,\n hasHitCommonBoundingBoxOfSelectedElements: this.isHittingCommonBoundingBoxOfSelectedElements(origin, selectedElements)\n },\n drag: {\n hasOccurred: false,\n offset: null\n },\n eventListeners: {\n onMove: null,\n onUp: null,\n onKeyUp: null,\n onKeyDown: null\n },\n boxSelection: {\n hasOccurred: false\n },\n elementIdsToErase: {}\n };\n } // Returns whether the event is a dragging a scrollbar\n\n\n handleDraggingScrollBar(event, pointerDownState) {\n if (!(pointerDownState.scrollbars.isOverEither && !this.state.multiElement)) {\n return false;\n }\n\n isDraggingScrollBar = true;\n pointerDownState.lastCoords.x = event.clientX;\n pointerDownState.lastCoords.y = event.clientY;\n const onPointerMove = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdatesThrottled)(event => {\n const target = event.target;\n\n if (!(target instanceof HTMLElement)) {\n return;\n }\n\n this.handlePointerMoveOverScrollbars(event, pointerDownState);\n });\n const onPointerUp = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(() => {\n isDraggingScrollBar = false;\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursorForShape)(this.interactiveCanvas, this.state);\n lastPointerUp = null;\n this.setState({\n cursorButton: \"up\"\n });\n this.savePointer(event.clientX, event.clientY, \"up\");\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, onPointerUp);\n onPointerMove.flush();\n });\n lastPointerUp = onPointerUp;\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, onPointerUp);\n return true;\n }\n\n isASelectedElement(hitElement) {\n return hitElement != null && this.state.selectedElementIds[hitElement.id];\n }\n\n isHittingCommonBoundingBoxOfSelectedElements(point, selectedElements) {\n if (selectedElements.length < 2) {\n return false;\n } // How many pixels off the shape boundary we still consider a hit\n\n\n const threshold = 10 / this.state.zoom.value;\n const [x1, y1, x2, y2] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements);\n return point.x > x1 - threshold && point.x < x2 + threshold && point.y > y1 - threshold && point.y < y2 + threshold;\n }\n\n getCurrentItemRoundness(elementType) {\n return this.state.currentItemRoundness === \"round\" ? {\n type: (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isUsingAdaptiveRadius)(elementType) ? _constants__WEBPACK_IMPORTED_MODULE_12__.ROUNDNESS.ADAPTIVE_RADIUS : _constants__WEBPACK_IMPORTED_MODULE_12__.ROUNDNESS.PROPORTIONAL_RADIUS\n } : null;\n }\n\n maybeCacheReferenceSnapPoints(event, selectedElements, recomputeAnyways = false) {\n if ((0,_snapping__WEBPACK_IMPORTED_MODULE_58__.isSnappingEnabled)({\n event,\n appState: this.state,\n selectedElements\n }) && (recomputeAnyways || !_snapping__WEBPACK_IMPORTED_MODULE_58__.SnapCache.getReferenceSnapPoints())) {\n _snapping__WEBPACK_IMPORTED_MODULE_58__.SnapCache.setReferenceSnapPoints((0,_snapping__WEBPACK_IMPORTED_MODULE_58__.getReferenceSnapPoints)(this.scene.getNonDeletedElements(), selectedElements, this.state));\n }\n }\n\n maybeCacheVisibleGaps(event, selectedElements, recomputeAnyways = false) {\n if ((0,_snapping__WEBPACK_IMPORTED_MODULE_58__.isSnappingEnabled)({\n event,\n appState: this.state,\n selectedElements\n }) && (recomputeAnyways || !_snapping__WEBPACK_IMPORTED_MODULE_58__.SnapCache.getVisibleGaps())) {\n _snapping__WEBPACK_IMPORTED_MODULE_58__.SnapCache.setVisibleGaps((0,_snapping__WEBPACK_IMPORTED_MODULE_58__.getVisibleGaps)(this.scene.getNonDeletedElements(), selectedElements, this.state));\n }\n }\n\n onKeyDownFromPointerDownHandler(pointerDownState) {\n return (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(event => {\n if (this.maybeHandleResize(pointerDownState, event)) {\n return;\n }\n\n this.maybeDragNewGenericElement(pointerDownState, event);\n });\n }\n\n onKeyUpFromPointerDownHandler(pointerDownState) {\n return (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(event => {\n // Prevents focus from escaping excalidraw tab\n event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ALT && event.preventDefault();\n\n if (this.maybeHandleResize(pointerDownState, event)) {\n return;\n }\n\n this.maybeDragNewGenericElement(pointerDownState, event);\n });\n }\n\n onPointerMoveFromPointerDownHandler(pointerDownState) {\n return (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdatesThrottled)(event => {\n var _a, _b; // We need to initialize dragOffsetXY only after we've updated\n // `state.selectedElementIds` on pointerDown. Doing it here in pointerMove\n // event handler should hopefully ensure we're already working with\n // the updated state.\n\n\n if (pointerDownState.drag.offset === null) {\n pointerDownState.drag.offset = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.tupleToCoors)((0,_element__WEBPACK_IMPORTED_MODULE_16__.getDragOffsetXY)(this.scene.getSelectedElements(this.state), pointerDownState.origin.x, pointerDownState.origin.y));\n }\n\n const target = event.target;\n\n if (!(target instanceof HTMLElement)) {\n return;\n }\n\n if (this.handlePointerMoveOverScrollbars(event, pointerDownState)) {\n return;\n }\n\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)(event, this.state);\n\n if ((0,_appState__WEBPACK_IMPORTED_MODULE_10__.isEraserActive)(this.state)) {\n this.handleEraser(event, pointerDownState, pointerCoords);\n return;\n }\n\n if (this.state.activeTool.type === \"laser\") {\n this.laserPathManager.addPointToPath(pointerCoords.x, pointerCoords.y);\n }\n\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_28__.getGridPoint)(pointerCoords.x, pointerCoords.y, event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] ? null : this.state.gridSize); // for arrows/lines, don't start dragging until a given threshold\n // to ensure we don't create a 2-point arrow by mistake when\n // user clicks mouse in a way that it moves a tiny bit (thus\n // triggering pointermove)\n\n if (!pointerDownState.drag.hasOccurred && (this.state.activeTool.type === \"arrow\" || this.state.activeTool.type === \"line\")) {\n if ((0,_math__WEBPACK_IMPORTED_MODULE_28__.distance2d)(pointerCoords.x, pointerCoords.y, pointerDownState.origin.x, pointerDownState.origin.y) < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD) {\n return;\n }\n }\n\n if (pointerDownState.resize.isResizing) {\n pointerDownState.lastCoords.x = pointerCoords.x;\n pointerDownState.lastCoords.y = pointerCoords.y;\n\n if (this.maybeHandleResize(pointerDownState, event)) {\n return true;\n }\n }\n\n if (this.state.selectedLinearElement) {\n const linearElementEditor = this.state.editingLinearElement || this.state.selectedLinearElement;\n\n if (_element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.shouldAddMidpoint(this.state.selectedLinearElement, pointerCoords, this.state)) {\n const ret = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.addMidpoint(this.state.selectedLinearElement, pointerCoords, this.state, !event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]);\n\n if (!ret) {\n return;\n } // Since we are reading from previous state which is not possible with\n // automatic batching in React 18 hence using flush sync to synchronously\n // update the state. Check https://github.com/excalidraw/excalidraw/pull/5508 for more details.\n\n\n (0,react_dom__WEBPACK_IMPORTED_MODULE_2__.flushSync)(() => {\n if (this.state.selectedLinearElement) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, this.state.selectedLinearElement), {\n pointerDownState: ret.pointerDownState,\n selectedPointsIndices: ret.selectedPointsIndices\n })\n });\n }\n\n if (this.state.editingLinearElement) {\n this.setState({\n editingLinearElement: Object.assign(Object.assign({}, this.state.editingLinearElement), {\n pointerDownState: ret.pointerDownState,\n selectedPointsIndices: ret.selectedPointsIndices\n })\n });\n }\n });\n return;\n } else if (linearElementEditor.pointerDownState.segmentMidpoint.value !== null && !linearElementEditor.pointerDownState.segmentMidpoint.added) {\n return;\n }\n\n const didDrag = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointDragging(event, this.state, pointerCoords.x, pointerCoords.y, (element, pointsSceneCoords) => {\n this.maybeSuggestBindingsForLinearElementAtCoords(element, pointsSceneCoords);\n }, linearElementEditor);\n\n if (didDrag) {\n pointerDownState.lastCoords.x = pointerCoords.x;\n pointerDownState.lastCoords.y = pointerCoords.y;\n pointerDownState.drag.hasOccurred = true;\n\n if (this.state.editingLinearElement && !this.state.editingLinearElement.isDragging) {\n this.setState({\n editingLinearElement: Object.assign(Object.assign({}, this.state.editingLinearElement), {\n isDragging: true\n })\n });\n }\n\n if (!this.state.selectedLinearElement.isDragging) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, this.state.selectedLinearElement), {\n isDragging: true\n })\n });\n }\n\n return;\n }\n }\n\n const hasHitASelectedElement = pointerDownState.hit.allHitElements.some(element => this.isASelectedElement(element));\n const isSelectingPointsInLineEditor = this.state.editingLinearElement && event.shiftKey && this.state.editingLinearElement.elementId === ((_a = pointerDownState.hit.element) === null || _a === void 0 ? void 0 : _a.id);\n\n if ((hasHitASelectedElement || pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) && !isSelectingPointsInLineEditor) {\n const selectedElements = this.scene.getSelectedElements(this.state);\n\n if (selectedElements.every(element => element.locked)) {\n return;\n }\n\n const selectedElementsHasAFrame = selectedElements.find(e => (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isFrameElement)(e));\n const topLayerFrame = this.getTopLayerFrameAtSceneCoords(pointerCoords);\n this.setState({\n frameToHighlight: topLayerFrame && !selectedElementsHasAFrame ? topLayerFrame : null\n }); // Marking that click was used for dragging to check\n // if elements should be deselected on pointerup\n\n pointerDownState.drag.hasOccurred = true;\n this.setState({\n selectedElementsAreBeingDragged: true\n }); // prevent dragging even if we're no longer holding cmd/ctrl otherwise\n // it would have weird results (stuff jumping all over the screen)\n // Checking for editingElement to avoid jump while editing on mobile #6503\n\n if (selectedElements.length > 0 && !pointerDownState.withCmdOrCtrl && !this.state.editingElement && ((_b = this.state.activeEmbeddable) === null || _b === void 0 ? void 0 : _b.state) !== \"active\") {\n const dragOffset = {\n x: pointerCoords.x - pointerDownState.origin.x,\n y: pointerCoords.y - pointerDownState.origin.y\n };\n const originalElements = [...pointerDownState.originalElements.values()]; // We only drag in one direction if shift is pressed\n\n const lockDirection = event.shiftKey;\n\n if (lockDirection) {\n const distanceX = Math.abs(dragOffset.x);\n const distanceY = Math.abs(dragOffset.y);\n const lockX = lockDirection && distanceX < distanceY;\n const lockY = lockDirection && distanceX > distanceY;\n\n if (lockX) {\n dragOffset.x = 0;\n }\n\n if (lockY) {\n dragOffset.y = 0;\n }\n } // Snap cache *must* be synchronously popuplated before initial drag,\n // otherwise the first drag even will not snap, causing a jump before\n // it snaps to its position if previously snapped already.\n\n\n this.maybeCacheVisibleGaps(event, selectedElements);\n this.maybeCacheReferenceSnapPoints(event, selectedElements);\n const {\n snapOffset,\n snapLines\n } = (0,_snapping__WEBPACK_IMPORTED_MODULE_58__.snapDraggedElements)((0,_scene__WEBPACK_IMPORTED_MODULE_29__.getSelectedElements)(originalElements, this.state), dragOffset, this.state, event);\n this.setState({\n snapLines\n }); // when we're editing the name of a frame, we want the user to be\n // able to select and interact with the text input\n\n !this.state.editingFrame && (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragSelectedElements)(pointerDownState, selectedElements, dragOffset, this.state, this.scene, snapOffset, event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] ? null : this.state.gridSize);\n this.maybeSuggestBindingForAll(selectedElements); // We duplicate the selected element if alt is pressed on pointer move\n\n if (event.altKey && !pointerDownState.hit.hasBeenDuplicated) {\n // Move the currently selected elements to the top of the z index stack, and\n // put the duplicates where the selected elements used to be.\n // (the origin point where the dragging started)\n pointerDownState.hit.hasBeenDuplicated = true;\n const nextElements = [];\n const elementsToAppend = [];\n const groupIdMap = new Map();\n const oldIdToDuplicatedId = new Map();\n const hitElement = pointerDownState.hit.element;\n const selectedElementIds = new Set(this.scene.getSelectedElements({\n selectedElementIds: this.state.selectedElementIds,\n includeBoundTextElement: true,\n includeElementsInFrames: true\n }).map(element => element.id));\n const elements = this.scene.getElementsIncludingDeleted();\n\n for (const element of elements) {\n if (selectedElementIds.has(element.id) || // case: the state.selectedElementIds might not have been\n // updated yet by the time this mousemove event is fired\n element.id === (hitElement === null || hitElement === void 0 ? void 0 : hitElement.id) && pointerDownState.hit.wasAddedToSelection) {\n const duplicatedElement = (0,_element__WEBPACK_IMPORTED_MODULE_16__.duplicateElement)(this.state.editingGroupId, groupIdMap, element);\n const origElement = pointerDownState.originalElements.get(element.id);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(duplicatedElement, {\n x: origElement.x,\n y: origElement.y\n }); // put duplicated element to pointerDownState.originalElements\n // so that we can snap to the duplicated element without releasing\n\n pointerDownState.originalElements.set(duplicatedElement.id, duplicatedElement);\n nextElements.push(duplicatedElement);\n elementsToAppend.push(element);\n oldIdToDuplicatedId.set(element.id, duplicatedElement.id);\n } else {\n nextElements.push(element);\n }\n }\n\n const nextSceneElements = [...nextElements, ...elementsToAppend];\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.bindTextToShapeAfterDuplication)(nextElements, elementsToAppend, oldIdToDuplicatedId);\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDuplication)(nextSceneElements, elementsToAppend, oldIdToDuplicatedId, \"duplicatesServeAsOld\");\n (0,_frame__WEBPACK_IMPORTED_MODULE_51__.bindElementsToFramesAfterDuplication)(nextSceneElements, elementsToAppend, oldIdToDuplicatedId);\n this.scene.replaceAllElements(nextSceneElements);\n this.maybeCacheVisibleGaps(event, selectedElements, true);\n this.maybeCacheReferenceSnapPoints(event, selectedElements, true);\n }\n\n return;\n }\n } // It is very important to read this.state within each move event,\n // otherwise we would read a stale one!\n\n\n const draggingElement = this.state.draggingElement;\n\n if (!draggingElement) {\n return;\n }\n\n if (draggingElement.type === \"freedraw\") {\n const points = draggingElement.points;\n const dx = pointerCoords.x - draggingElement.x;\n const dy = pointerCoords.y - draggingElement.y;\n const lastPoint = points.length > 0 && points[points.length - 1];\n const discardPoint = lastPoint && lastPoint[0] === dx && lastPoint[1] === dy;\n\n if (!discardPoint) {\n const strokeOptions = this.state.currentStrokeOptions; //zsviczian\n\n const pressures = draggingElement.simulatePressure ? draggingElement.pressures : [//zsviczian\n ...draggingElement.pressures, (strokeOptions === null || strokeOptions === void 0 ? void 0 : strokeOptions.constantPressure) ? 1 : event.pressure];\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [...points, [dx, dy]],\n pressures\n });\n }\n } else if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(draggingElement)) {\n pointerDownState.drag.hasOccurred = true;\n this.setState({\n selectedElementsAreBeingDragged: true\n });\n const points = draggingElement.points;\n let dx = gridX - draggingElement.x;\n let dy = gridY - draggingElement.y;\n\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldRotateWithDiscreteAngle)(event) && points.length === 2) {\n ({\n width: dx,\n height: dy\n } = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getLockedLinearCursorAlignSize)(draggingElement.x, draggingElement.y, pointerCoords.x, pointerCoords.y));\n }\n\n if (points.length === 1) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [...points, [dx, dy]]\n });\n } else if (points.length === 2) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [...points.slice(0, -1), [dx, dy]]\n });\n }\n\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement, false)) {\n // When creating a linear element by dragging\n this.maybeSuggestBindingsForLinearElementAtCoords(draggingElement, [pointerCoords], this.state.startBoundElement);\n }\n } else {\n pointerDownState.lastCoords.x = pointerCoords.x;\n pointerDownState.lastCoords.y = pointerCoords.y;\n this.maybeDragNewGenericElement(pointerDownState, event);\n }\n\n if (this.state.activeTool.type === \"selection\") {\n pointerDownState.boxSelection.hasOccurred = true;\n const elements = this.scene.getNonDeletedElements(); // box-select line editor points\n\n if (this.state.editingLinearElement) {\n _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handleBoxSelection(event, this.state, this.setState.bind(this)); // regular box-select\n } else {\n let shouldReuseSelection = true;\n\n if (!event.shiftKey && (0,_scene__WEBPACK_IMPORTED_MODULE_29__.isSomeElementSelected)(elements, this.state)) {\n if (pointerDownState.withCmdOrCtrl && pointerDownState.hit.element) {\n this.setState(prevState => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), {\n selectedElementIds: {\n [pointerDownState.hit.element.id]: true\n }\n }), this.scene.getNonDeletedElements(), prevState, this));\n } else {\n shouldReuseSelection = false;\n }\n }\n\n const elementsWithinSelection = (0,_scene__WEBPACK_IMPORTED_MODULE_29__.getElementsWithinSelection)(elements, draggingElement);\n this.setState(prevState => {\n const nextSelectedElementIds = Object.assign(Object.assign({}, shouldReuseSelection && prevState.selectedElementIds), elementsWithinSelection.reduce((acc, element) => {\n acc[element.id] = true;\n return acc;\n }, {}));\n\n if (pointerDownState.hit.element) {\n // if using ctrl/cmd, select the hitElement only if we\n // haven't box-selected anything else\n if (!elementsWithinSelection.length) {\n nextSelectedElementIds[pointerDownState.hit.element.id] = true;\n } else {\n delete nextSelectedElementIds[pointerDownState.hit.element.id];\n }\n }\n\n prevState = !shouldReuseSelection ? Object.assign(Object.assign({}, prevState), {\n selectedGroupIds: {},\n editingGroupId: null\n }) : prevState;\n return Object.assign(Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)({\n editingGroupId: prevState.editingGroupId,\n selectedElementIds: nextSelectedElementIds\n }, this.scene.getNonDeletedElements(), prevState, this)), {\n // select linear element only when we haven't box-selected anything else\n selectedLinearElement: elementsWithinSelection.length === 1 && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(elementsWithinSelection[0]) ? new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(elementsWithinSelection[0], this.scene) : null,\n showHyperlinkPopup: elementsWithinSelection.length === 1 && (elementsWithinSelection[0].link || (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isEmbeddableElement)(elementsWithinSelection[0])) ? \"info\" : false\n });\n });\n }\n }\n });\n } // Returns whether the pointer move happened over either scrollbar\n\n\n handlePointerMoveOverScrollbars(event, pointerDownState) {\n if (pointerDownState.scrollbars.isOverHorizontal) {\n const x = event.clientX;\n const dx = x - pointerDownState.lastCoords.x;\n this.translateCanvas({\n scrollX: this.state.scrollX - dx / this.state.zoom.value\n });\n pointerDownState.lastCoords.x = x;\n return true;\n }\n\n if (pointerDownState.scrollbars.isOverVertical) {\n const y = event.clientY;\n const dy = y - pointerDownState.lastCoords.y;\n this.translateCanvas({\n scrollY: this.state.scrollY - dy / this.state.zoom.value\n });\n pointerDownState.lastCoords.y = y;\n return true;\n }\n\n return false;\n }\n\n onPointerUpFromPointerDownHandler(pointerDownState) {\n return (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(childEvent => {\n var _a, _b, _c, _d, _e, _f;\n\n if (pointerDownState.eventListeners.onMove) {\n pointerDownState.eventListeners.onMove.flush();\n }\n\n const {\n draggingElement,\n resizingElement,\n multiElement,\n activeTool,\n isResizing,\n isRotating\n } = this.state;\n this.setState({\n isResizing: false,\n isRotating: false,\n resizingElement: null,\n selectionElement: null,\n frameToHighlight: null,\n elementsToHighlight: null,\n cursorButton: \"up\",\n // text elements are reset on finalize, and resetting on pointerup\n // may cause issues with double taps\n editingElement: multiElement || (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement) ? this.state.editingElement : null,\n snapLines: [],\n originSnapOffset: null\n });\n _snapping__WEBPACK_IMPORTED_MODULE_58__.SnapCache.setReferenceSnapPoints(null);\n _snapping__WEBPACK_IMPORTED_MODULE_58__.SnapCache.setVisibleGaps(null);\n this.savePointer(childEvent.clientX, childEvent.clientY, \"up\");\n this.setState({\n selectedElementsAreBeingDragged: false\n }); // Handle end of dragging a point of a linear element, might close a loop\n // and sets binding element\n\n if (this.state.editingLinearElement) {\n if (!pointerDownState.boxSelection.hasOccurred && ((_b = (_a = pointerDownState.hit) === null || _a === void 0 ? void 0 : _a.element) === null || _b === void 0 ? void 0 : _b.id) !== this.state.editingLinearElement.elementId) {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n } else {\n const editingLinearElement = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerUp(childEvent, this.state.editingLinearElement, this.state);\n\n if (editingLinearElement !== this.state.editingLinearElement) {\n this.setState({\n editingLinearElement,\n suggestedBindings: []\n });\n }\n }\n } else if (this.state.selectedLinearElement) {\n if (((_d = (_c = pointerDownState.hit) === null || _c === void 0 ? void 0 : _c.element) === null || _d === void 0 ? void 0 : _d.id) !== this.state.selectedLinearElement.elementId) {\n const selectedELements = this.scene.getSelectedElements(this.state); // set selectedLinearElement to null if there is more than one element selected since we don't want to show linear element handles\n\n if (selectedELements.length > 1) {\n this.setState({\n selectedLinearElement: null\n });\n }\n } else {\n const linearElementEditor = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerUp(childEvent, this.state.selectedLinearElement, this.state);\n const {\n startBindingElement,\n endBindingElement\n } = linearElementEditor;\n const element = this.scene.getElement(linearElementEditor.elementId);\n\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(element)) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.bindOrUnbindLinearElement)(element, startBindingElement, endBindingElement);\n }\n\n if (linearElementEditor !== this.state.selectedLinearElement) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, linearElementEditor), {\n selectedPointsIndices: null\n }),\n suggestedBindings: []\n });\n }\n }\n }\n\n lastPointerUp = null;\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, pointerDownState.eventListeners.onMove);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, pointerDownState.eventListeners.onUp);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYDOWN, pointerDownState.eventListeners.onKeyDown);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYUP, pointerDownState.eventListeners.onKeyUp);\n\n if (this.state.pendingImageElementId) {\n this.setState({\n pendingImageElementId: null\n });\n }\n\n this.onPointerUpEmitter.trigger(this.state.activeTool, pointerDownState, childEvent);\n\n if ((draggingElement === null || draggingElement === void 0 ? void 0 : draggingElement.type) === \"freedraw\") {\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)(childEvent, this.state);\n const points = draggingElement.points;\n let dx = pointerCoords.x - draggingElement.x;\n let dy = pointerCoords.y - draggingElement.y; // Allows dots to avoid being flagged as infinitely small\n\n if (dx === points[0][0] && dy === points[0][1]) {\n dy += 0.0001;\n dx += 0.0001;\n }\n\n const pressures = draggingElement.simulatePressure ? [] : [...draggingElement.pressures, childEvent.pressure];\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [...points, [dx, dy]],\n pressures,\n lastCommittedPoint: [dx, dy]\n });\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n return;\n }\n\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(draggingElement)) {\n const imageElement = draggingElement;\n\n try {\n this.initializeImageDimensions(imageElement);\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({\n [imageElement.id]: true\n }, this.state)\n }, () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n });\n } catch (error) {\n console.error(error);\n this.scene.replaceAllElements(this.scene.getElementsIncludingDeleted().filter(el => el.id !== imageElement.id));\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n }\n\n return;\n }\n\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(draggingElement)) {\n if (draggingElement.points.length > 1) {\n this.history.resumeRecording();\n }\n\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)(childEvent, this.state);\n\n if (!pointerDownState.drag.hasOccurred && draggingElement && !multiElement) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [...draggingElement.points, [pointerCoords.x - draggingElement.x, pointerCoords.y - draggingElement.y]]\n });\n this.setState({\n multiElement: draggingElement,\n editingElement: this.state.draggingElement\n });\n } else if (pointerDownState.drag.hasOccurred && !multiElement) {\n if ((0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state) && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement, false)) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.maybeBindLinearElement)(draggingElement, this.state, this.scene, pointerCoords);\n }\n\n this.setState({\n suggestedBindings: [],\n startBoundElement: null\n });\n\n if (!activeTool.locked) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.resetCursor)(this.interactiveCanvas);\n this.setState(prevState => ({\n draggingElement: null,\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_33__.updateActiveTool)(this.state, {\n type: \"selection\"\n }),\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(Object.assign(Object.assign({}, prevState.selectedElementIds), {\n [draggingElement.id]: true\n }), prevState),\n selectedLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(draggingElement, this.scene)\n }));\n } else {\n this.setState(prevState => ({\n draggingElement: null\n }));\n }\n }\n\n return;\n }\n\n if (activeTool.type !== \"selection\" && draggingElement && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isInvisiblySmallElement)(draggingElement)) {\n // remove invisible element which was added in onPointerDown\n this.scene.replaceAllElements(this.scene.getElementsIncludingDeleted().filter(el => el.id !== draggingElement.id));\n this.setState({\n draggingElement: null\n });\n return;\n }\n\n if (draggingElement) {\n if (pointerDownState.drag.hasOccurred) {\n const sceneCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)(childEvent, this.state); // when editing the points of a linear element, we check if the\n // linear element still is in the frame afterwards\n // if not, the linear element will be removed from its frame (if any)\n\n if (this.state.selectedLinearElement && this.state.selectedLinearElement.isDragging) {\n const linearElement = this.scene.getElement(this.state.selectedLinearElement.elementId);\n\n if (linearElement === null || linearElement === void 0 ? void 0 : linearElement.frameId) {\n const frame = (0,_frame__WEBPACK_IMPORTED_MODULE_51__.getContainingFrame)(linearElement);\n\n if (frame && linearElement) {\n if (!(0,_frame__WEBPACK_IMPORTED_MODULE_51__.elementOverlapsWithFrame)(linearElement, frame)) {\n // remove the linear element from all groups\n // before removing it from the frame as well\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(linearElement, {\n groupIds: []\n });\n this.scene.replaceAllElements((0,_frame__WEBPACK_IMPORTED_MODULE_51__.removeElementsFromFrame)(this.scene.getElementsIncludingDeleted(), [linearElement], this.state));\n }\n }\n }\n } else {\n // update the relationships between selected elements and frames\n const topLayerFrame = this.getTopLayerFrameAtSceneCoords(sceneCoords);\n const selectedElements = this.scene.getSelectedElements(this.state);\n let nextElements = this.scene.getElementsIncludingDeleted();\n\n const updateGroupIdsAfterEditingGroup = elements => {\n if (elements.length > 0) {\n for (const element of elements) {\n const index = element.groupIds.indexOf(this.state.editingGroupId);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n groupIds: element.groupIds.slice(0, index)\n }, false);\n }\n\n nextElements.forEach(element => {\n if (element.groupIds.length && (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getElementsInGroup)(nextElements, element.groupIds[element.groupIds.length - 1]).length < 2) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n groupIds: []\n }, false);\n }\n });\n this.setState({\n editingGroupId: null\n });\n }\n };\n\n if (topLayerFrame && !this.state.selectedElementIds[topLayerFrame.id]) {\n const elementsToAdd = selectedElements.filter(element => element.frameId !== topLayerFrame.id && (0,_frame__WEBPACK_IMPORTED_MODULE_51__.isElementInFrame)(element, nextElements, this.state));\n\n if (this.state.editingGroupId) {\n updateGroupIdsAfterEditingGroup(elementsToAdd);\n }\n\n nextElements = (0,_frame__WEBPACK_IMPORTED_MODULE_51__.addElementsToFrame)(nextElements, elementsToAdd, topLayerFrame);\n } else if (!topLayerFrame) {\n if (this.state.editingGroupId) {\n const elementsToRemove = selectedElements.filter(element => element.frameId && !(0,_frame__WEBPACK_IMPORTED_MODULE_51__.isElementInFrame)(element, nextElements, this.state));\n updateGroupIdsAfterEditingGroup(elementsToRemove);\n }\n }\n\n nextElements = (0,_frame__WEBPACK_IMPORTED_MODULE_51__.updateFrameMembershipOfSelectedElements)(nextElements, this.state, this);\n this.scene.replaceAllElements(nextElements);\n }\n }\n\n if (draggingElement.type === \"frame\") {\n const elementsInsideFrame = (0,_frame__WEBPACK_IMPORTED_MODULE_51__.getElementsInNewFrame)(this.scene.getElementsIncludingDeleted(), draggingElement);\n this.scene.replaceAllElements((0,_frame__WEBPACK_IMPORTED_MODULE_51__.addElementsToFrame)(this.scene.getElementsIncludingDeleted(), elementsInsideFrame, draggingElement));\n }\n\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getNormalizedDimensions)(draggingElement));\n }\n\n if (resizingElement) {\n this.history.resumeRecording();\n }\n\n if (resizingElement && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isInvisiblySmallElement)(resizingElement)) {\n this.scene.replaceAllElements(this.scene.getElementsIncludingDeleted().filter(el => el.id !== resizingElement.id));\n } // handle frame membership for resizing frames and/or selected elements\n\n\n if (pointerDownState.resize.isResizing) {\n let nextElements = (0,_frame__WEBPACK_IMPORTED_MODULE_51__.updateFrameMembershipOfSelectedElements)(this.scene.getElementsIncludingDeleted(), this.state, this);\n const selectedFrames = this.scene.getSelectedElements(this.state).filter(element => element.type === \"frame\");\n\n for (const frame of selectedFrames) {\n nextElements = (0,_frame__WEBPACK_IMPORTED_MODULE_51__.replaceAllElementsInFrame)(nextElements, (0,_frame__WEBPACK_IMPORTED_MODULE_51__.getElementsInResizingFrame)(this.scene.getElementsIncludingDeleted(), frame, this.state), frame, this.state);\n }\n\n this.scene.replaceAllElements(nextElements);\n } // Code below handles selection when element(s) weren't\n // drag or added to selection on pointer down phase.\n\n\n const hitElement = pointerDownState.hit.element;\n\n if (((_e = this.state.selectedLinearElement) === null || _e === void 0 ? void 0 : _e.elementId) !== (hitElement === null || hitElement === void 0 ? void 0 : hitElement.id) && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(hitElement)) {\n const selectedELements = this.scene.getSelectedElements(this.state); // set selectedLinearElement when no other element selected except\n // the one we've hit\n\n if (selectedELements.length === 1) {\n this.setState({\n selectedLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(hitElement, this.scene)\n });\n }\n }\n\n if ((0,_appState__WEBPACK_IMPORTED_MODULE_10__.isEraserActive)(this.state)) {\n const draggedDistance = (0,_math__WEBPACK_IMPORTED_MODULE_28__.distance2d)(this.lastPointerDownEvent.clientX, this.lastPointerDownEvent.clientY, this.lastPointerUpEvent.clientX, this.lastPointerUpEvent.clientY);\n\n if (draggedDistance === 0) {\n const scenePointer = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)({\n clientX: this.lastPointerUpEvent.clientX,\n clientY: this.lastPointerUpEvent.clientY\n }, this.state);\n const hitElements = this.getElementsAtPosition(scenePointer.x, scenePointer.y);\n hitElements.forEach(hitElement => pointerDownState.elementIdsToErase[hitElement.id] = {\n erase: true,\n opacity: hitElement.opacity\n });\n }\n\n this.eraseElements(pointerDownState);\n return;\n } else if (Object.keys(pointerDownState.elementIdsToErase).length) {\n this.restoreReadyToEraseElements(pointerDownState);\n }\n\n if (hitElement && !pointerDownState.drag.hasOccurred && !pointerDownState.hit.wasAddedToSelection && ( // if we're editing a line, pointerup shouldn't switch selection if\n // box selected\n !this.state.editingLinearElement || !pointerDownState.boxSelection.hasOccurred)) {\n // when inside line editor, shift selects points instead\n if (childEvent.shiftKey && !this.state.editingLinearElement) {\n if (this.state.selectedElementIds[hitElement.id]) {\n if ((0,_groups__WEBPACK_IMPORTED_MODULE_23__.isSelectedViaGroup)(this.state, hitElement)) {\n this.setState(_prevState => {\n const nextSelectedElementIds = Object.assign({}, _prevState.selectedElementIds); // We want to unselect all groups hitElement is part of\n // as well as all elements that are part of the groups\n // hitElement is part of\n\n for (const groupedElement of hitElement.groupIds.flatMap(groupId => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getElementsInGroup)(this.scene.getNonDeletedElements(), groupId))) {\n delete nextSelectedElementIds[groupedElement.id];\n }\n\n return {\n selectedGroupIds: Object.assign(Object.assign({}, _prevState.selectedElementIds), hitElement.groupIds.map(gId => ({\n [gId]: false\n })).reduce((prev, acc) => Object.assign(Object.assign({}, prev), acc), {})),\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(nextSelectedElementIds, _prevState)\n };\n }); // if not gragging a linear element point (outside editor)\n } else if (!((_f = this.state.selectedLinearElement) === null || _f === void 0 ? void 0 : _f.isDragging)) {\n // remove element from selection while\n // keeping prev elements selected\n this.setState(prevState => {\n const newSelectedElementIds = Object.assign({}, prevState.selectedElementIds);\n delete newSelectedElementIds[hitElement.id];\n const newSelectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_29__.getSelectedElements)(this.scene.getNonDeletedElements(), {\n selectedElementIds: newSelectedElementIds\n });\n return Object.assign(Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)({\n editingGroupId: prevState.editingGroupId,\n selectedElementIds: newSelectedElementIds\n }, this.scene.getNonDeletedElements(), prevState, this)), {\n // set selectedLinearElement only if thats the only element selected\n selectedLinearElement: newSelectedElements.length === 1 && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(newSelectedElements[0]) ? new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(newSelectedElements[0], this.scene) : prevState.selectedLinearElement\n });\n });\n }\n } else if (hitElement.frameId && this.state.selectedElementIds[hitElement.frameId]) {\n // when hitElement is part of a selected frame, deselect the frame\n // to avoid frame and containing elements selected simultaneously\n this.setState(prevState => {\n var _a, _b;\n\n const nextSelectedElementIds = Object.assign(Object.assign({}, prevState.selectedElementIds), {\n [hitElement.id]: true\n }); // deselect the frame\n\n delete nextSelectedElementIds[hitElement.frameId]; // deselect groups containing the frame\n\n ((_b = (_a = this.scene.getElement(hitElement.frameId)) === null || _a === void 0 ? void 0 : _a.groupIds) !== null && _b !== void 0 ? _b : []).flatMap(gid => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getElementsInGroup)(this.scene.getNonDeletedElements(), gid)).forEach(element => {\n delete nextSelectedElementIds[element.id];\n });\n return Object.assign(Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)({\n editingGroupId: prevState.editingGroupId,\n selectedElementIds: nextSelectedElementIds\n }, this.scene.getNonDeletedElements(), prevState, this)), {\n showHyperlinkPopup: hitElement.link || (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isEmbeddableElement)(hitElement) ? \"info\" : false\n });\n });\n } else {\n // add element to selection while keeping prev elements selected\n this.setState(_prevState => ({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(Object.assign(Object.assign({}, _prevState.selectedElementIds), {\n [hitElement.id]: true\n }), _prevState)\n }));\n }\n } else {\n this.setState(prevState => {\n var _a;\n\n return Object.assign(Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)({\n editingGroupId: prevState.editingGroupId,\n selectedElementIds: {\n [hitElement.id]: true\n }\n }, this.scene.getNonDeletedElements(), prevState, this)), {\n selectedLinearElement: (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(hitElement) && // Don't set `selectedLinearElement` if its same as the hitElement, this is mainly to prevent resetting the `hoverPointIndex` to -1.\n // Future we should update the API to take care of setting the correct `hoverPointIndex` when initialized\n ((_a = prevState.selectedLinearElement) === null || _a === void 0 ? void 0 : _a.elementId) !== hitElement.id ? new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(hitElement, this.scene) : prevState.selectedLinearElement\n });\n });\n }\n }\n\n if (!pointerDownState.drag.hasOccurred && !this.state.isResizing && (hitElement && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isHittingElementBoundingBoxWithoutHittingElement)(hitElement, this.state, this.frameNameBoundsCache, pointerDownState.origin.x, pointerDownState.origin.y) || !hitElement && pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements)) {\n if (this.state.editingLinearElement) {\n this.setState({\n editingLinearElement: null\n });\n } else {\n // Deselect selected elements\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({}, this.state),\n selectedGroupIds: {},\n editingGroupId: null,\n activeEmbeddable: null\n });\n }\n\n return;\n }\n\n if (!activeTool.locked && activeTool.type !== \"freedraw\" && draggingElement && draggingElement.type !== \"selection\") {\n this.setState(prevState => ({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(Object.assign(Object.assign({}, prevState.selectedElementIds), {\n [draggingElement.id]: true\n }), prevState),\n showHyperlinkPopup: (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isEmbeddableElement)(draggingElement) && !draggingElement.link ? \"editor\" : prevState.showHyperlinkPopup\n }));\n }\n\n if (activeTool.type !== \"selection\" || (0,_scene__WEBPACK_IMPORTED_MODULE_29__.isSomeElementSelected)(this.scene.getNonDeletedElements(), this.state)) {\n this.history.resumeRecording();\n }\n\n if (pointerDownState.drag.hasOccurred || isResizing || isRotating) {\n ((0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state) ? _element_binding__WEBPACK_IMPORTED_MODULE_17__.bindOrUnbindSelectedElements : _element_binding__WEBPACK_IMPORTED_MODULE_17__.unbindLinearElements)(this.scene.getSelectedElements(this.state));\n }\n\n if (activeTool.type === \"laser\") {\n this.laserPathManager.endPath();\n return;\n }\n\n if (!activeTool.locked && activeTool.type !== \"freedraw\") {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.resetCursor)(this.interactiveCanvas);\n this.setState({\n draggingElement: null,\n suggestedBindings: [],\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_33__.updateActiveTool)(this.state, {\n type: \"selection\"\n })\n });\n } else {\n this.setState({\n draggingElement: null,\n suggestedBindings: []\n });\n }\n\n if (hitElement && this.lastPointerUpEvent && this.lastPointerDownEvent && this.lastPointerUpEvent.timeStamp - this.lastPointerDownEvent.timeStamp < 300 && gesture.pointers.size <= 1 && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isEmbeddableElement)(hitElement) && this.isEmbeddableCenter(hitElement, this.lastPointerUpEvent, pointerDownState.origin.x, pointerDownState.origin.y)) {\n this.handleEmbeddableCenterClick(hitElement);\n }\n });\n }\n\n maybeSuggestBindingForAll(selectedElements) {\n if (selectedElements.length > 50) {\n return;\n }\n\n const suggestedBindings = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getEligibleElementsForBinding)(selectedElements);\n this.setState({\n suggestedBindings\n });\n }\n\n setSelection(elements) {\n const selectedElementIds = {};\n const selectedGroupIds = {};\n elements.forEach(ele => {\n if (ele.groupIds.length) {\n selectedElementIds[ele.id] = true;\n ele.groupIds.forEach(id => {\n selectedGroupIds[id] = true;\n });\n } // exclude bound text elements as we don't mark them as selected when\n // container is selected unless in group\n else if (!(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(ele)) {\n selectedElementIds[ele.id] = true;\n }\n });\n this.setState({\n previousSelectedElementIds: this.state.selectedElementIds,\n selectedElementIds,\n selectedGroupIds\n });\n }\n\n clearSelection(hitElement) {\n this.setState(prevState => ({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({}, prevState),\n activeEmbeddable: null,\n selectedGroupIds: {},\n // Continue editing the same group if the user selected a different\n // element from it\n editingGroupId: prevState.editingGroupId && hitElement != null && (0,_groups__WEBPACK_IMPORTED_MODULE_23__.isElementInGroup)(hitElement, prevState.editingGroupId) ? prevState.editingGroupId : null\n }));\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({}, this.state),\n activeEmbeddable: null,\n previousSelectedElementIds: this.state.selectedElementIds\n });\n }\n\n getTextWysiwygSnappedToCenterPosition(x, y, appState, container) {\n if (container) {\n let elementCenterX = container.x + container.width / 2;\n let elementCenterY = container.y + container.height / 2;\n const elementCenter = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getContainerCenter)(container, appState);\n\n if (elementCenter) {\n elementCenterX = elementCenter.x;\n elementCenterY = elementCenter.y;\n }\n\n const distanceToCenter = Math.hypot(x - elementCenterX, y - elementCenterY);\n const isSnappedToCenter = distanceToCenter < _constants__WEBPACK_IMPORTED_MODULE_12__.TEXT_TO_CENTER_SNAP_THRESHOLD;\n\n if (isSnappedToCenter) {\n const {\n x: viewportX,\n y: viewportY\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.sceneCoordsToViewportCoords)({\n sceneX: elementCenterX,\n sceneY: elementCenterY\n }, appState);\n return {\n viewportX,\n viewportY,\n elementCenterX,\n elementCenterY\n };\n }\n }\n }\n\n getCanvasOffsets() {\n var _a;\n\n if ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current) {\n const excalidrawContainer = this.excalidrawContainerRef.current;\n const {\n left,\n top\n } = excalidrawContainer.getBoundingClientRect();\n return {\n offsetLeft: left,\n offsetTop: top\n };\n }\n\n return {\n offsetLeft: 0,\n offsetTop: 0\n };\n }\n\n async updateLanguage() {\n const currentLang = _i18n__WEBPACK_IMPORTED_MODULE_25__.languages.find(lang => lang.code === this.props.langCode) || _i18n__WEBPACK_IMPORTED_MODULE_25__.defaultLang;\n await (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.setLanguage)(currentLang);\n this.setAppState({});\n }\n\n}\n\nApp.defaultProps = {\n // needed for tests to pass since we directly render App in many tests\n UIOptions: _constants__WEBPACK_IMPORTED_MODULE_12__.DEFAULT_UI_OPTIONS\n};\n\nif (\"development\" === _constants__WEBPACK_IMPORTED_MODULE_12__.ENV.TEST || \"development\" !== \"production\") {\n window.h = window.h || {};\n Object.defineProperties(window.h, {\n elements: {\n configurable: true,\n\n get() {\n var _a;\n\n return (_a = this.app) === null || _a === void 0 ? void 0 : _a.scene.getElementsIncludingDeleted();\n },\n\n set(elements) {\n var _a;\n\n return (_a = this.app) === null || _a === void 0 ? void 0 : _a.scene.replaceAllElements(elements);\n }\n\n }\n });\n}\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (App);\n\n//# sourceURL=webpack://ExcalidrawLib/../../components/App.tsx?");
2306
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"ExcalidrawContainerContext\": () => (/* binding */ ExcalidrawContainerContext),\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__),\n/* harmony export */ \"showFourthFont\": () => (/* binding */ showFourthFont),\n/* harmony export */ \"useApp\": () => (/* binding */ useApp),\n/* harmony export */ \"useAppProps\": () => (/* binding */ useAppProps),\n/* harmony export */ \"useDevice\": () => (/* binding */ useDevice),\n/* harmony export */ \"useExcalidrawActionManager\": () => (/* binding */ useExcalidrawActionManager),\n/* harmony export */ \"useExcalidrawAppState\": () => (/* binding */ useExcalidrawAppState),\n/* harmony export */ \"useExcalidrawContainer\": () => (/* binding */ useExcalidrawContainer),\n/* harmony export */ \"useExcalidrawElements\": () => (/* binding */ useExcalidrawElements),\n/* harmony export */ \"useExcalidrawSetAppState\": () => (/* binding */ useExcalidrawSetAppState)\n/* harmony export */ });\n/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react/jsx-runtime */ \"../../../node_modules/react/jsx-runtime.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ \"react\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react-dom */ \"react-dom\");\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! roughjs/bin/rough */ \"../../../node_modules/roughjs/bin/rough.js\");\n/* harmony import */ var clsx__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! clsx */ \"../../../node_modules/clsx/dist/clsx.m.js\");\n/* harmony import */ var nanoid__WEBPACK_IMPORTED_MODULE_72__ = __webpack_require__(/*! nanoid */ \"../../../node_modules/nanoid/index.browser.js\");\n/* harmony import */ var _actions__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../actions */ \"../../actions/index.ts\");\n/* harmony import */ var _actions_actionHistory__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../actions/actionHistory */ \"../../actions/actionHistory.tsx\");\n/* harmony import */ var _actions_manager__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../actions/manager */ \"../../actions/manager.tsx\");\n/* harmony import */ var _actions_register__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../actions/register */ \"../../actions/register.ts\");\n/* harmony import */ var _analytics__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../analytics */ \"../../analytics.ts\");\n/* harmony import */ var _appState__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../appState */ \"../../appState.ts\");\n/* harmony import */ var _clipboard__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../clipboard */ \"../../clipboard.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _data__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../data */ \"../../data/index.ts\");\n/* harmony import */ var _data_library__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../data/library */ \"../../data/library.ts\");\n/* harmony import */ var _data_restore__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../data/restore */ \"../../data/restore.ts\");\n/* harmony import */ var _element__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../element */ \"../../element/index.ts\");\n/* harmony import */ var _element_binding__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../element/binding */ \"../../element/binding.ts\");\n/* harmony import */ var _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../element/linearElementEditor */ \"../../element/linearElementEditor.ts\");\n/* harmony import */ var _element_mutateElement__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../element/mutateElement */ \"../../element/mutateElement.ts\");\n/* harmony import */ var _element_newElement__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../element/newElement */ \"../../element/newElement.ts\");\n/* harmony import */ var _element_typeChecks__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../element/typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var _gesture__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ../gesture */ \"../../gesture.ts\");\n/* harmony import */ var _groups__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ../groups */ \"../../groups.ts\");\n/* harmony import */ var _history__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ../history */ \"../../history.ts\");\n/* harmony import */ var _i18n__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ../i18n */ \"../../i18n.ts\");\n/* harmony import */ var _keys__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ../keys */ \"../../keys.ts\");\n/* harmony import */ var _element_sizeHelpers__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ../element/sizeHelpers */ \"../../element/sizeHelpers.ts\");\n/* harmony import */ var _math__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ../math */ \"../../math.ts\");\n/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ../scene */ \"../../scene/index.ts\");\n/* harmony import */ var _scene_Scene__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ../scene/Scene */ \"../../scene/Scene.ts\");\n/* harmony import */ var _scene_zoom__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ../scene/zoom */ \"../../scene/zoom.ts\");\n/* harmony import */ var _shapes__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ../shapes */ \"../../shapes.tsx\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _element_embeddable__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ../element/embeddable */ \"../../element/embeddable.ts\");\n/* harmony import */ var _ContextMenu__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ./ContextMenu */ \"../../components/ContextMenu.tsx\");\n/* harmony import */ var _LayerUI__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ./LayerUI */ \"../../components/LayerUI.tsx\");\n/* harmony import */ var _Toast__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ./Toast */ \"../../components/Toast.tsx\");\n/* harmony import */ var _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! ../actions/actionToggleViewMode */ \"../../actions/actionToggleViewMode.tsx\");\n/* harmony import */ var _data_blob__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(/*! ../data/blob */ \"../../data/blob.ts\");\n/* harmony import */ var _element_image__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(/*! ../element/image */ \"../../element/image.ts\");\n/* harmony import */ var lodash_throttle__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(/*! lodash.throttle */ \"../../../node_modules/lodash.throttle/index.js\");\n/* harmony import */ var lodash_throttle__WEBPACK_IMPORTED_MODULE_41___default = /*#__PURE__*/__webpack_require__.n(lodash_throttle__WEBPACK_IMPORTED_MODULE_41__);\n/* harmony import */ var _data_filesystem__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(/*! ../data/filesystem */ \"../../data/filesystem.ts\");\n/* harmony import */ var _element_textElement__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(/*! ../element/textElement */ \"../../element/textElement.ts\");\n/* harmony import */ var _element_collision__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(/*! ../element/collision */ \"../../element/collision.ts\");\n/* harmony import */ var _element_resizeElements__WEBPACK_IMPORTED_MODULE_45__ = __webpack_require__(/*! ../element/resizeElements */ \"../../element/resizeElements.ts\");\n/* harmony import */ var _element_Hyperlink__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(/*! ../element/Hyperlink */ \"../../element/Hyperlink.tsx\");\n/* harmony import */ var _data_url__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(/*! ../data/url */ \"../../data/url.ts\");\n/* harmony import */ var _element_transformHandles__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(/*! ../element/transformHandles */ \"../../element/transformHandles.ts\");\n/* harmony import */ var _actions_actionElementLock__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(/*! ../actions/actionElementLock */ \"../../actions/actionElementLock.ts\");\n/* harmony import */ var _scene_Fonts__WEBPACK_IMPORTED_MODULE_50__ = __webpack_require__(/*! ../scene/Fonts */ \"../../scene/Fonts.ts\");\n/* harmony import */ var _frame__WEBPACK_IMPORTED_MODULE_51__ = __webpack_require__(/*! ../frame */ \"../../frame.ts\");\n/* harmony import */ var _scene_selection__WEBPACK_IMPORTED_MODULE_52__ = __webpack_require__(/*! ../scene/selection */ \"../../scene/selection.ts\");\n/* harmony import */ var _actions_actionClipboard__WEBPACK_IMPORTED_MODULE_53__ = __webpack_require__(/*! ../actions/actionClipboard */ \"../../actions/actionClipboard.tsx\");\n/* harmony import */ var _actions_actionFrame__WEBPACK_IMPORTED_MODULE_54__ = __webpack_require__(/*! ../actions/actionFrame */ \"../../actions/actionFrame.ts\");\n/* harmony import */ var _actions_actionCanvas__WEBPACK_IMPORTED_MODULE_55__ = __webpack_require__(/*! ../actions/actionCanvas */ \"../../actions/actionCanvas.tsx\");\n/* harmony import */ var _jotai__WEBPACK_IMPORTED_MODULE_56__ = __webpack_require__(/*! ../jotai */ \"../../jotai.ts\");\n/* harmony import */ var _ActiveConfirmDialog__WEBPACK_IMPORTED_MODULE_57__ = __webpack_require__(/*! ./ActiveConfirmDialog */ \"../../components/ActiveConfirmDialog.tsx\");\n/* harmony import */ var _snapping__WEBPACK_IMPORTED_MODULE_58__ = __webpack_require__(/*! ../snapping */ \"../../snapping.ts\");\n/* harmony import */ var _actions_actionBoundText__WEBPACK_IMPORTED_MODULE_59__ = __webpack_require__(/*! ../actions/actionBoundText */ \"../../actions/actionBoundText.tsx\");\n/* harmony import */ var _BraveMeasureTextError__WEBPACK_IMPORTED_MODULE_60__ = __webpack_require__(/*! ./BraveMeasureTextError */ \"../../components/BraveMeasureTextError.tsx\");\n/* harmony import */ var _EyeDropper__WEBPACK_IMPORTED_MODULE_61__ = __webpack_require__(/*! ./EyeDropper */ \"../../components/EyeDropper.tsx\");\n/* harmony import */ var _data_transform__WEBPACK_IMPORTED_MODULE_62__ = __webpack_require__(/*! ../data/transform */ \"../../data/transform.ts\");\n/* harmony import */ var _Sidebar_Sidebar__WEBPACK_IMPORTED_MODULE_63__ = __webpack_require__(/*! ./Sidebar/Sidebar */ \"../../components/Sidebar/Sidebar.tsx\");\n/* harmony import */ var _canvases__WEBPACK_IMPORTED_MODULE_64__ = __webpack_require__(/*! ./canvases */ \"../../components/canvases/index.tsx\");\n/* harmony import */ var _scene_Renderer__WEBPACK_IMPORTED_MODULE_65__ = __webpack_require__(/*! ../scene/Renderer */ \"../../scene/Renderer.ts\");\n/* harmony import */ var _scene_ShapeCache__WEBPACK_IMPORTED_MODULE_66__ = __webpack_require__(/*! ../scene/ShapeCache */ \"../../scene/ShapeCache.ts\");\n/* harmony import */ var _MermaidToExcalidraw__WEBPACK_IMPORTED_MODULE_67__ = __webpack_require__(/*! ./MermaidToExcalidraw */ \"../../components/MermaidToExcalidraw.tsx\");\n/* harmony import */ var _LaserTool_LaserTool__WEBPACK_IMPORTED_MODULE_68__ = __webpack_require__(/*! ./LaserTool/LaserTool */ \"../../components/LaserTool/LaserTool.tsx\");\n/* harmony import */ var _LaserTool_LaserPathManager__WEBPACK_IMPORTED_MODULE_69__ = __webpack_require__(/*! ./LaserTool/LaserPathManager */ \"../../components/LaserTool/LaserPathManager.ts\");\n/* harmony import */ var _cursor__WEBPACK_IMPORTED_MODULE_70__ = __webpack_require__(/*! ../cursor */ \"../../cursor.ts\");\n/* harmony import */ var _emitter__WEBPACK_IMPORTED_MODULE_71__ = __webpack_require__(/*! ../emitter */ \"../../emitter.ts\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst AppContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(null);\nconst AppPropsContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(null);\nlet showFourthFont = false; //zsviczian\n\nconst deviceContextInitialValue = {\n isSmScreen: false,\n isMobile: false,\n isTouchScreen: false,\n canDeviceFitSidebar: false,\n isLandscape: false\n};\nconst DeviceContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(deviceContextInitialValue);\nDeviceContext.displayName = \"DeviceContext\";\nconst ExcalidrawContainerContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext({\n container: null,\n id: null\n});\nExcalidrawContainerContext.displayName = \"ExcalidrawContainerContext\";\nconst ExcalidrawElementsContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext([]);\nExcalidrawElementsContext.displayName = \"ExcalidrawElementsContext\";\nconst ExcalidrawAppStateContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(Object.assign(Object.assign({}, (0,_appState__WEBPACK_IMPORTED_MODULE_10__.getDefaultAppState)()), {\n width: 0,\n height: 0,\n offsetLeft: 0,\n offsetTop: 0\n}));\nExcalidrawAppStateContext.displayName = \"ExcalidrawAppStateContext\";\nconst ExcalidrawSetAppStateContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(() => {\n console.warn(\"unitialized ExcalidrawSetAppStateContext context!\");\n});\nExcalidrawSetAppStateContext.displayName = \"ExcalidrawSetAppStateContext\";\nconst ExcalidrawActionManagerContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(null);\nExcalidrawActionManagerContext.displayName = \"ExcalidrawActionManagerContext\";\nconst useApp = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(AppContext);\nconst useAppProps = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(AppPropsContext);\nconst useDevice = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(DeviceContext);\nconst useExcalidrawContainer = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawContainerContext);\nconst useExcalidrawElements = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawElementsContext);\nconst useExcalidrawAppState = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawAppStateContext);\nconst useExcalidrawSetAppState = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawSetAppStateContext);\nconst useExcalidrawActionManager = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawActionManagerContext);\nlet didTapTwice = false;\nlet tappedTwiceTimer = 0;\nlet isHoldingSpace = false;\nlet isPanning = false;\nlet isDraggingScrollBar = false;\nlet currentScrollBars = {\n horizontal: null,\n vertical: null\n};\nlet touchTimeout = 0;\nlet invalidateContextMenu = false;\n/**\r\n * Map of youtube embed video states\r\n */\n\nconst YOUTUBE_VIDEO_STATES = new Map();\nlet IS_PLAIN_PASTE = false;\nlet IS_PLAIN_PASTE_TIMER = 0;\nlet PLAIN_PASTE_TOAST_SHOWN = false;\nlet lastPointerUp = null;\nconst gesture = {\n pointers: new Map(),\n lastCenter: null,\n initialDistance: null,\n initialScale: null\n};\n\nclass App extends (react__WEBPACK_IMPORTED_MODULE_1___default().Component) {\n constructor(props) {\n var _a;\n\n super(props);\n this.interactiveCanvas = null;\n this.unmounted = false;\n this.device = deviceContextInitialValue;\n this.excalidrawContainerRef = react__WEBPACK_IMPORTED_MODULE_1___default().createRef();\n this.files = {};\n this.imageCache = new Map();\n this.iFrameRefs = new Map();\n this.lastPointerDownEvent = null;\n this.lastPointerUpEvent = null;\n this.lastViewportPosition = {\n x: 0,\n y: 0\n };\n this.allowMobileMode = true; //zsviczian\n\n this.laserPathManager = new _LaserTool_LaserPathManager__WEBPACK_IMPORTED_MODULE_69__.LaserPathManager(this);\n this.onChangeEmitter = new _emitter__WEBPACK_IMPORTED_MODULE_71__.Emitter();\n this.onPointerDownEmitter = new _emitter__WEBPACK_IMPORTED_MODULE_71__.Emitter();\n this.onPointerUpEmitter = new _emitter__WEBPACK_IMPORTED_MODULE_71__.Emitter();\n\n this.updateEmbeddables = () => {\n const embeddableElements = new Map();\n let updated = false;\n this.scene.getNonDeletedElements().filter(element => {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isEmbeddableElement)(element)) {\n embeddableElements.set(element.id, true);\n\n if (element.validated == null) {\n updated = true;\n const validated = (0,_element_embeddable__WEBPACK_IMPORTED_MODULE_34__.embeddableURLValidator)(element.link, this.props.validateEmbeddable);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n validated\n }, false);\n _scene_ShapeCache__WEBPACK_IMPORTED_MODULE_66__.ShapeCache[\"delete\"](element);\n }\n }\n\n return false;\n });\n\n if (updated) {\n this.scene.informMutation();\n } // GC\n\n\n this.iFrameRefs.forEach((ref, id) => {\n if (!embeddableElements.has(id)) {\n this.iFrameRefs.delete(id);\n }\n });\n };\n\n this.getFrameNameDOMId = frameElement => {\n return `${this.id}-frame-name-${frameElement.id}`;\n };\n\n this.frameNameBoundsCache = {\n get: frameElement => {\n let bounds = this.frameNameBoundsCache._cache.get(frameElement.id);\n\n if (!bounds || bounds.zoom !== this.state.zoom.value || bounds.versionNonce !== frameElement.versionNonce) {\n const frameNameDiv = document.getElementById(this.getFrameNameDOMId(frameElement));\n\n if (frameNameDiv) {\n const box = frameNameDiv.getBoundingClientRect();\n const boxSceneTopLeft = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)({\n clientX: box.x,\n clientY: box.y\n }, this.state);\n const boxSceneBottomRight = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)({\n clientX: box.right,\n clientY: box.bottom\n }, this.state);\n bounds = {\n x: boxSceneTopLeft.x,\n y: boxSceneTopLeft.y,\n width: boxSceneBottomRight.x - boxSceneTopLeft.x,\n height: boxSceneBottomRight.y - boxSceneTopLeft.y,\n angle: 0,\n zoom: this.state.zoom.value,\n versionNonce: frameElement.versionNonce\n };\n\n this.frameNameBoundsCache._cache.set(frameElement.id, bounds);\n\n return bounds;\n }\n\n return null;\n }\n\n return bounds;\n },\n\n /**\r\n * @private\r\n */\n _cache: new Map()\n };\n\n this.renderFrameNames = () => {\n if (!this.state.frameRendering.enabled || !this.state.frameRendering.name) {\n return null;\n }\n\n const isDarkTheme = this.state.theme === \"dark\";\n return this.scene.getNonDeletedFrames().map((f, index) => {\n if (!(0,_element_sizeHelpers__WEBPACK_IMPORTED_MODULE_27__.isElementInViewport)(f, this.canvas.width / window.devicePixelRatio, this.canvas.height / window.devicePixelRatio, {\n offsetLeft: this.state.offsetLeft,\n offsetTop: this.state.offsetTop,\n scrollX: this.state.scrollX,\n scrollY: this.state.scrollY,\n zoom: this.state.zoom\n })) {\n // if frame not visible, don't render its name\n return null;\n }\n\n const {\n x: x1,\n y: y1\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.sceneCoordsToViewportCoords)({\n sceneX: f.x,\n sceneY: f.y\n }, this.state);\n const {\n x: x2\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.sceneCoordsToViewportCoords)({\n sceneX: f.x + f.width,\n sceneY: f.y + f.height\n }, this.state);\n const FRAME_NAME_GAP = 20;\n const FRAME_NAME_EDIT_PADDING = 6;\n\n const reset = () => {\n var _a;\n\n if (((_a = f.name) === null || _a === void 0 ? void 0 : _a.trim()) === \"\") {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(f, {\n name: null\n });\n }\n\n this.setState({\n editingFrame: null\n });\n };\n\n let frameNameJSX;\n\n if (f.id === this.state.editingFrame) {\n const frameNameInEdit = f.name == null ? `Frame ${(index + 1).toString().padStart(2, \"0\")}` //zsviczian\n : f.name;\n frameNameJSX = (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"input\", {\n autoFocus: true,\n value: frameNameInEdit,\n onChange: e => {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(f, {\n name: e.target.value\n });\n },\n onBlur: () => reset(),\n onKeyDown: event => {\n // for some inexplicable reason, `onBlur` triggered on ESC\n // does not reset `state.editingFrame` despite being called,\n // and we need to reset it here as well\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ESCAPE || event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ENTER) {\n reset();\n }\n },\n style: {\n background: this.state.viewBackgroundColor,\n filter: isDarkTheme ? _constants__WEBPACK_IMPORTED_MODULE_12__.THEME_FILTER : \"none\",\n zIndex: 2,\n border: \"none\",\n display: \"block\",\n padding: `${FRAME_NAME_EDIT_PADDING}px`,\n borderRadius: 4,\n boxShadow: \"inset 0 0 0 1px var(--color-primary)\",\n fontFamily: \"Assistant\",\n fontSize: \"14px\",\n transform: `translateY(-${FRAME_NAME_EDIT_PADDING}px)`,\n color: \"var(--color-gray-80)\",\n overflow: \"hidden\",\n maxWidth: `${Math.min(x2 - x1 - FRAME_NAME_EDIT_PADDING, document.body.clientWidth - x1 - FRAME_NAME_EDIT_PADDING)}px`\n },\n size: frameNameInEdit.length + 1 || 1,\n dir: \"auto\",\n autoComplete: \"off\",\n autoCapitalize: \"off\",\n autoCorrect: \"off\"\n });\n } else {\n frameNameJSX = f.name == null || f.name.trim() === \"\" ? `Frame ${(index + 1).toString().padStart(2, \"0\")}` //zsviczian\n : f.name.trim();\n }\n\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", Object.assign({\n id: this.getFrameNameDOMId(f),\n style: {\n position: \"absolute\",\n top: `${y1 - FRAME_NAME_GAP - this.state.offsetTop}px`,\n left: `${x1 - this.state.offsetLeft - (this.state.editingFrame === f.id ? FRAME_NAME_EDIT_PADDING : 0)}px`,\n zIndex: 2,\n fontSize: \"14px\",\n color: isDarkTheme ? \"var(--color-gray-60)\" : \"var(--color-gray-50)\",\n width: \"max-content\",\n maxWidth: `${x2 - x1 + FRAME_NAME_EDIT_PADDING * 2}px`,\n overflow: f.id === this.state.editingFrame ? \"visible\" : \"hidden\",\n whiteSpace: \"nowrap\",\n textOverflow: \"ellipsis\",\n cursor: _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.MOVE,\n pointerEvents: this.state.viewModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_EVENTS.disabled : _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_EVENTS.enabled\n },\n onPointerDown: event => this.handleCanvasPointerDown(event),\n onWheel: event => this.handleWheel(event),\n onContextMenu: this.handleCanvasContextMenu,\n onDoubleClick: () => {\n this.setState({\n editingFrame: f.id\n });\n }\n }, {\n children: frameNameJSX\n }), f.id);\n });\n };\n\n this.focusContainer = () => {\n var _a;\n\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.focus();\n };\n\n this.getSceneElementsIncludingDeleted = () => {\n return this.scene.getElementsIncludingDeleted();\n };\n\n this.getSceneElements = () => {\n return this.scene.getNonDeletedElements();\n };\n\n this.onInsertElements = elements => {\n this.addElementsFromPasteOrLibrary({\n elements,\n position: \"center\",\n files: null\n });\n };\n\n this.onExportImage = async (type, elements) => {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_9__.trackEvent)(\"export\", type, \"ui\");\n const fileHandle = await (0,_data__WEBPACK_IMPORTED_MODULE_13__.exportCanvas)(type, elements, this.state, this.files, {\n exportBackground: this.state.exportBackground,\n name: this.state.name,\n viewBackgroundColor: this.state.viewBackgroundColor\n }).catch(_utils__WEBPACK_IMPORTED_MODULE_33__.muteFSAbortError).catch(error => {\n console.error(error);\n this.setState({\n errorMessage: error.message\n });\n });\n\n if (this.state.exportEmbedScene && fileHandle && (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.isImageFileHandle)(fileHandle)) {\n this.setState({\n fileHandle\n });\n }\n };\n\n this.openEyeDropper = ({\n type\n }) => {\n _jotai__WEBPACK_IMPORTED_MODULE_56__.jotaiStore.set(_EyeDropper__WEBPACK_IMPORTED_MODULE_61__.activeEyeDropperAtom, {\n swapPreviewOnAlt: true,\n colorPickerType: type === \"stroke\" ? \"elementStroke\" : \"elementBackground\",\n onSelect: (color, event) => {\n const shouldUpdateStrokeColor = type === \"background\" && event.altKey || type === \"stroke\" && !event.altKey;\n const selectedElements = this.scene.getSelectedElements(this.state);\n\n if (!selectedElements.length || this.state.activeTool.type !== \"selection\") {\n if (shouldUpdateStrokeColor) {\n this.syncActionResult({\n appState: Object.assign(Object.assign({}, this.state), {\n currentItemStrokeColor: color\n }),\n commitToHistory: true\n });\n } else {\n this.syncActionResult({\n appState: Object.assign(Object.assign({}, this.state), {\n currentItemBackgroundColor: color\n }),\n commitToHistory: true\n });\n }\n } else {\n this.updateScene({\n elements: this.scene.getElementsIncludingDeleted().map(el => {\n if (this.state.selectedElementIds[el.id]) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(el, {\n [shouldUpdateStrokeColor ? \"strokeColor\" : \"backgroundColor\"]: color\n });\n }\n\n return el;\n })\n });\n }\n },\n keepOpenOnAlt: false\n });\n };\n\n this.syncActionResult = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(actionResult => {\n var _a, _b, _c, _d, _e, _f, _g, _h, _j;\n\n if (this.unmounted || actionResult === false) {\n return;\n }\n\n let editingElement = null;\n\n if (actionResult.elements) {\n actionResult.elements.forEach(element => {\n var _a;\n\n if (((_a = this.state.editingElement) === null || _a === void 0 ? void 0 : _a.id) === element.id && this.state.editingElement !== element && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isNonDeletedElement)(element)) {\n editingElement = element;\n }\n });\n this.scene.replaceAllElements(actionResult.elements);\n\n if (actionResult.commitToHistory) {\n this.history.resumeRecording();\n }\n }\n\n if (actionResult.files) {\n this.files = actionResult.replaceFiles ? actionResult.files : Object.assign(Object.assign({}, this.files), actionResult.files);\n this.addNewImagesToImageCache();\n }\n\n if (actionResult.appState || editingElement || this.state.contextMenu) {\n if (actionResult.commitToHistory) {\n this.history.resumeRecording();\n }\n\n let viewModeEnabled = ((_a = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _a === void 0 ? void 0 : _a.viewModeEnabled) || false;\n let zenModeEnabled = ((_b = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _b === void 0 ? void 0 : _b.zenModeEnabled) || false;\n let gridSize = ((_c = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _c === void 0 ? void 0 : _c.gridSize) || null;\n const theme = ((_d = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _d === void 0 ? void 0 : _d.theme) || this.props.theme || _constants__WEBPACK_IMPORTED_MODULE_12__.THEME.LIGHT;\n let name = (_f = (_e = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _e === void 0 ? void 0 : _e.name) !== null && _f !== void 0 ? _f : this.state.name;\n const errorMessage = (_h = (_g = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _g === void 0 ? void 0 : _g.errorMessage) !== null && _h !== void 0 ? _h : this.state.errorMessage;\n\n if (typeof this.props.viewModeEnabled !== \"undefined\") {\n viewModeEnabled = this.props.viewModeEnabled;\n }\n\n if (typeof this.props.zenModeEnabled !== \"undefined\") {\n zenModeEnabled = this.props.zenModeEnabled;\n }\n\n if (typeof this.props.gridModeEnabled !== \"undefined\") {\n gridSize = this.props.gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_12__.GRID_SIZE : null;\n }\n\n if (typeof this.props.name !== \"undefined\") {\n name = this.props.name;\n }\n\n editingElement = editingElement || ((_j = actionResult.appState) === null || _j === void 0 ? void 0 : _j.editingElement) || null;\n\n if (editingElement === null || editingElement === void 0 ? void 0 : editingElement.isDeleted) {\n editingElement = null;\n }\n\n this.setState(state => {\n // using Object.assign instead of spread to fool TS 4.2.2+ into\n // regarding the resulting type as not containing undefined\n // (which the following expression will never contain)\n return Object.assign(actionResult.appState || {}, {\n // NOTE this will prevent opening context menu using an action\n // or programmatically from the host, so it will need to be\n // rewritten later\n contextMenu: null,\n editingElement,\n viewModeEnabled,\n zenModeEnabled,\n gridSize,\n theme,\n name,\n errorMessage\n });\n }, () => {\n if (actionResult.syncHistory) {\n this.history.setCurrentState(this.state, this.scene.getElementsIncludingDeleted());\n }\n });\n }\n }); // Lifecycle\n\n this.onBlur = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(() => {\n isHoldingSpace = false;\n this.setState({\n isBindingEnabled: true\n });\n });\n\n this.onUnload = () => {\n this.onBlur();\n };\n\n this.disableEvent = event => {\n event.preventDefault();\n };\n\n this.resetHistory = () => {\n this.history.clear();\n };\n /**\r\n * Resets scene & history.\r\n * ! Do not use to clear scene user action !\r\n */\n\n\n this.resetScene = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(opts => {\n this.scene.replaceAllElements([]);\n this.setState(state => Object.assign(Object.assign({}, (0,_appState__WEBPACK_IMPORTED_MODULE_10__.getDefaultAppState)()), {\n isLoading: (opts === null || opts === void 0 ? void 0 : opts.resetLoadingState) ? false : state.isLoading,\n theme: this.state.theme\n }));\n this.resetHistory();\n });\n\n this.initializeScene = async () => {\n var _a;\n\n if (\"launchQueue\" in window && \"LaunchParams\" in window) {\n window.launchQueue.setConsumer(async launchParams => {\n if (!launchParams.files.length) {\n return;\n }\n\n const fileHandle = launchParams.files[0];\n const blob = await fileHandle.getFile();\n this.loadFileToCanvas(new File([blob], blob.name || \"\", {\n type: blob.type\n }), fileHandle);\n });\n }\n\n if (this.props.theme) {\n this.setState({\n theme: this.props.theme\n });\n }\n\n if (!this.state.isLoading) {\n this.setState({\n isLoading: true\n });\n }\n\n let initialData = null;\n\n try {\n initialData = (await this.props.initialData) || null;\n\n if (initialData === null || initialData === void 0 ? void 0 : initialData.libraryItems) {\n this.library.updateLibrary({\n libraryItems: initialData.libraryItems,\n merge: true\n }).catch(error => {\n console.error(error);\n });\n }\n } catch (error) {\n console.error(error);\n initialData = {\n appState: {\n errorMessage: error.message || \"Encountered an error during importing or restoring scene data\"\n }\n };\n }\n\n const scene = (0,_data_restore__WEBPACK_IMPORTED_MODULE_15__.restore)(initialData, null, null, {\n repairBindings: true\n });\n scene.appState = Object.assign(Object.assign({}, scene.appState), {\n theme: this.props.theme || scene.appState.theme,\n // we're falling back to current (pre-init) state when deciding\n // whether to open the library, to handle a case where we\n // update the state outside of initialData (e.g. when loading the app\n // with a library install link, which should auto-open the library)\n openSidebar: ((_a = scene.appState) === null || _a === void 0 ? void 0 : _a.openSidebar) || this.state.openSidebar,\n activeTool: scene.appState.activeTool.type === \"image\" ? Object.assign(Object.assign({}, scene.appState.activeTool), {\n type: \"selection\"\n }) : scene.appState.activeTool,\n isLoading: false,\n toast: this.state.toast\n });\n\n if (initialData === null || initialData === void 0 ? void 0 : initialData.scrollToContent) {\n scene.appState = Object.assign(Object.assign({}, scene.appState), (0,_scene__WEBPACK_IMPORTED_MODULE_29__.calculateScrollCenter)(scene.elements, Object.assign(Object.assign({}, scene.appState), {\n width: this.state.width,\n height: this.state.height,\n offsetTop: this.state.offsetTop,\n offsetLeft: this.state.offsetLeft\n })));\n } // FontFaceSet loadingdone event we listen on may not always fire\n // (looking at you Safari), so on init we manually load fonts for current\n // text elements on canvas, and rerender them once done. This also\n // seems faster even in browsers that do fire the loadingdone event.\n\n\n this.fonts.loadFontsForElements(scene.elements);\n this.resetHistory();\n this.syncActionResult(Object.assign(Object.assign({}, scene), {\n commitToHistory: true\n }));\n };\n\n this.refreshDeviceState = container => {\n const {\n width,\n height\n } = container.getBoundingClientRect();\n const sidebarBreakpoint = this.props.UIOptions.dockedSidebarBreakpoint != null ? this.props.UIOptions.dockedSidebarBreakpoint : _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_RIGHT_SIDEBAR_MIN_WIDTH;\n this.device = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.updateObject)(this.device, {\n isLandscape: width > height,\n isSmScreen: width < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_SM_MAX_WIDTH,\n isMobile: width !== 0 && //zsviczian changing tabs in Obsidian causes MobileMenu to be rendered\n this.allowMobileMode && ( //zsviczian\n width < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_PORTRAIT || height < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_HEIGHT_LANDSCAPE && width < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_LANDSCAPE),\n canDeviceFitSidebar: width > sidebarBreakpoint\n });\n };\n\n this.onResize = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(() => {\n this.scene.getElementsIncludingDeleted().forEach(element => _scene_ShapeCache__WEBPACK_IMPORTED_MODULE_66__.ShapeCache[\"delete\"](element));\n this.setState({});\n });\n\n this.renderInteractiveSceneCallback = ({\n atLeastOneVisibleElement,\n scrollBars,\n elements\n }) => {\n if (!document.querySelector(\".excalidraw\")) {\n return;\n } //zsviczian - address issue when moving excalidraw to a new window/document\n\n\n if (scrollBars) {\n currentScrollBars = scrollBars;\n }\n\n const scrolledOutside = // hide when editing text\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement) ? false : !atLeastOneVisibleElement && elements.length > 0;\n\n if (this.state.scrolledOutside !== scrolledOutside) {\n this.setState({\n scrolledOutside\n });\n }\n\n this.scheduleImageRefresh();\n };\n\n this.onScroll = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.debounce)(() => {\n const {\n offsetTop,\n offsetLeft\n } = this.getCanvasOffsets();\n this.setState(state => {\n if (state.offsetLeft === offsetLeft && state.offsetTop === offsetTop) {\n return null;\n }\n\n return {\n offsetTop,\n offsetLeft\n };\n });\n }, _constants__WEBPACK_IMPORTED_MODULE_12__.SCROLL_TIMEOUT); // Copy/paste\n\n this.onCut = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(event => {\n var _a;\n\n const isExcalidrawActive = (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement);\n\n if (!isExcalidrawActive || (0,_utils__WEBPACK_IMPORTED_MODULE_33__.isWritableElement)(event.target)) {\n return;\n }\n\n this.cutAll();\n event.preventDefault();\n event.stopPropagation();\n });\n this.onCopy = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(event => {\n var _a;\n\n const isExcalidrawActive = (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement);\n\n if (!isExcalidrawActive || (0,_utils__WEBPACK_IMPORTED_MODULE_33__.isWritableElement)(event.target)) {\n return;\n }\n\n this.copyAll();\n event.preventDefault();\n event.stopPropagation();\n });\n\n this.cutAll = () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionCut, \"keyboard\");\n };\n\n this.copyAll = () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionCopy, \"keyboard\");\n };\n\n this.onTouchStart = event => {\n // fix for Apple Pencil Scribble\n // On Android, preventing the event would disable contextMenu on tap-hold\n if (!_constants__WEBPACK_IMPORTED_MODULE_12__.isAndroid) {\n event.preventDefault();\n }\n\n if (!didTapTwice) {\n didTapTwice = true;\n clearTimeout(tappedTwiceTimer);\n tappedTwiceTimer = window.setTimeout(App.resetTapTwice, _constants__WEBPACK_IMPORTED_MODULE_12__.TAP_TWICE_TIMEOUT);\n return;\n } // insert text only if we tapped twice with a single finger\n // event.touches.length === 1 will also prevent inserting text when user's zooming\n\n\n if (didTapTwice && event.touches.length === 1) {\n const touch = event.touches[0]; // @ts-ignore\n\n this.handleCanvasDoubleClick({\n clientX: touch.clientX,\n clientY: touch.clientY\n });\n didTapTwice = false;\n clearTimeout(tappedTwiceTimer);\n }\n\n if (_constants__WEBPACK_IMPORTED_MODULE_12__.isAndroid) {\n event.preventDefault();\n }\n\n if (event.touches.length === 2) {\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({}, this.state),\n activeEmbeddable: null\n });\n }\n };\n\n this.onTouchEnd = event => {\n this.resetContextMenuTimer();\n\n if (event.touches.length > 0) {\n this.setState({\n previousSelectedElementIds: {},\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(this.state.previousSelectedElementIds, this.state)\n });\n } else {\n gesture.pointers.clear();\n }\n };\n\n this.pasteFromClipboard = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(async event => {\n var _a, _b, _c;\n\n const isPlainPaste = !!(IS_PLAIN_PASTE && event); // #686\n\n const target = document.activeElement;\n const isExcalidrawActive = (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(target);\n\n if (event && !isExcalidrawActive) {\n return;\n }\n\n const elementUnderCursor = document.elementFromPoint(this.lastViewportPosition.x, this.lastViewportPosition.y);\n\n if (event && (!(elementUnderCursor instanceof HTMLCanvasElement) || (0,_utils__WEBPACK_IMPORTED_MODULE_33__.isWritableElement)(target))) {\n return;\n }\n\n const {\n x: sceneX,\n y: sceneY\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)({\n clientX: this.lastViewportPosition.x,\n clientY: this.lastViewportPosition.y\n }, this.state); // must be called in the same frame (thus before any awaits) as the paste\n // event else some browsers (FF...) will clear the clipboardData\n // (something something security)\n\n let file = (_b = event === null || event === void 0 ? void 0 : event.clipboardData) === null || _b === void 0 ? void 0 : _b.files[0];\n const data = await (0,_clipboard__WEBPACK_IMPORTED_MODULE_11__.parseClipboard)(event, isPlainPaste);\n\n if (!file && !isPlainPaste) {\n if (data.mixedContent) {\n return this.addElementsFromMixedContentPaste(data.mixedContent, {\n isPlainPaste,\n sceneX,\n sceneY\n });\n } else if (data.text) {\n const string = data.text.trim();\n\n if (string.startsWith(\"<svg\") && string.endsWith(\"</svg>\")) {\n // ignore SVG validation/normalization which will be done during image\n // initialization\n file = (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.SVGStringToFile)(string);\n }\n }\n } // prefer spreadsheet data over image file (MS Office/Libre Office)\n\n\n if ((0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.isSupportedImageFile)(file) && !data.spreadsheet) {\n const imageElement = this.createImageElement({\n sceneX,\n sceneY\n });\n this.insertImageElement(imageElement, file);\n this.initializeImageDimensions(imageElement);\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({\n [imageElement.id]: true\n }, this.state)\n });\n return;\n }\n\n if (this.props.onPaste) {\n try {\n if ((await this.props.onPaste(data, event)) === false) {\n return;\n }\n } catch (error) {\n console.error(error);\n }\n }\n\n if (data.errorMessage) {\n this.setState({\n errorMessage: data.errorMessage\n });\n } else if (data.spreadsheet && !isPlainPaste) {\n this.setState({\n pasteDialog: {\n data: data.spreadsheet,\n shown: true\n }\n });\n } else if (data.elements) {\n const elements = data.programmaticAPI ? (0,_data_transform__WEBPACK_IMPORTED_MODULE_62__.convertToExcalidrawElements)(data.elements) : data.elements; // TODO remove formatting from elements if isPlainPaste\n\n this.addElementsFromPasteOrLibrary({\n elements,\n files: data.files || null,\n position: \"cursor\",\n retainSeed: isPlainPaste\n });\n } else if (data.text) {\n const maybeUrl = (0,_element_embeddable__WEBPACK_IMPORTED_MODULE_34__.extractSrc)(data.text);\n\n if (!isPlainPaste && (0,_element_embeddable__WEBPACK_IMPORTED_MODULE_34__.embeddableURLValidator)(maybeUrl, this.props.validateEmbeddable) && (/^(http|https):\\/\\/[^\\s/$.?#].[^\\s]*$/.test(maybeUrl) || ((_c = (0,_element_embeddable__WEBPACK_IMPORTED_MODULE_34__.getEmbedLink)(maybeUrl)) === null || _c === void 0 ? void 0 : _c.type) === \"video\")) {\n const embeddable = this.insertEmbeddableElement({\n sceneX,\n sceneY,\n link: (0,_data_url__WEBPACK_IMPORTED_MODULE_47__.normalizeLink)(maybeUrl)\n });\n\n if (embeddable) {\n this.setState({\n selectedElementIds: {\n [embeddable.id]: true\n }\n });\n }\n\n return;\n }\n\n this.addTextFromPaste(data.text, isPlainPaste);\n }\n\n this.setActiveTool({\n type: \"selection\"\n });\n event === null || event === void 0 ? void 0 : event.preventDefault();\n });\n\n this.addElementsFromPasteOrLibrary = opts => {\n const elements = (0,_data_restore__WEBPACK_IMPORTED_MODULE_15__.restoreElements)(opts.elements, null, undefined);\n const [minX, minY, maxX, maxY] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(elements);\n const elementsCenterX = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.distance)(minX, maxX) / 2;\n const elementsCenterY = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.distance)(minY, maxY) / 2;\n const clientX = typeof opts.position === \"object\" ? opts.position.clientX : opts.position === \"cursor\" ? this.lastViewportPosition.x : this.state.width / 2 + this.state.offsetLeft;\n const clientY = typeof opts.position === \"object\" ? opts.position.clientY : opts.position === \"cursor\" ? this.lastViewportPosition.y : this.state.height / 2 + this.state.offsetTop;\n const {\n x,\n y\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)({\n clientX,\n clientY\n }, this.state);\n const dx = x - elementsCenterX;\n const dy = y - elementsCenterY;\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_28__.getGridPoint)(dx, dy, this.state.gridSize);\n const newElements = (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.duplicateElements)(elements.map(element => {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(element, {\n x: element.x + gridX - minX,\n y: element.y + gridY - minY\n });\n }), {\n randomizeSeed: !opts.retainSeed\n });\n const nextElements = [...this.scene.getElementsIncludingDeleted(), ...newElements];\n this.scene.replaceAllElements(nextElements);\n newElements.forEach(newElement => {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(newElement) && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(newElement)) {\n const container = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getContainerElement)(newElement);\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.redrawTextBoundingBox)(newElement, container);\n }\n });\n\n if (opts.files) {\n this.files = Object.assign(Object.assign({}, this.files), opts.files);\n }\n\n this.history.resumeRecording();\n const nextElementsToSelect = (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.excludeElementsInFramesFromSelection)(newElements);\n this.setState(Object.assign(Object.assign(Object.assign({}, this.state), {\n // keep sidebar (presumably the library) open if it's docked and\n // can fit.\n //\n // Note, we should close the sidebar only if we're dropping items\n // from library, not when pasting from clipboard. Alas.\n openSidebar: this.state.openSidebar && this.device.canDeviceFitSidebar && _jotai__WEBPACK_IMPORTED_MODULE_56__.jotaiStore.get(_Sidebar_Sidebar__WEBPACK_IMPORTED_MODULE_63__.isSidebarDockedAtom) ? this.state.openSidebar : null\n }), (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)({\n editingGroupId: null,\n selectedElementIds: nextElementsToSelect.reduce((acc, element) => {\n if (!(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(element)) {\n acc[element.id] = true;\n }\n\n return acc;\n }, {})\n }, this.scene.getNonDeletedElements(), this.state, this)), () => {\n if (opts.files) {\n this.addNewImagesToImageCache();\n }\n });\n this.setActiveTool({\n type: \"selection\"\n });\n\n if (opts.fitToContent) {\n this.scrollToContent(newElements, {\n fitToContent: true\n });\n }\n };\n\n this.setAppState = (state, callback) => {\n this.setState(state, callback);\n };\n\n this.removePointer = event => {\n if (touchTimeout) {\n this.resetContextMenuTimer();\n }\n\n gesture.pointers.delete(event.pointerId);\n };\n\n this.toggleLock = (source = \"ui\") => {\n if (!this.state.activeTool.locked) {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_9__.trackEvent)(\"toolbar\", \"toggleLock\", `${source} (${this.device.isMobile ? \"mobile\" : \"desktop\"})`);\n }\n\n this.setState(prevState => {\n return {\n activeTool: Object.assign(Object.assign(Object.assign({}, prevState.activeTool), (0,_utils__WEBPACK_IMPORTED_MODULE_33__.updateActiveTool)(this.state, prevState.activeTool.locked ? {\n type: \"selection\"\n } : prevState.activeTool)), {\n locked: !prevState.activeTool.locked\n })\n };\n });\n };\n\n this.updateFrameRendering = opts => {\n this.setState(prevState => {\n var _a, _b, _c, _d;\n\n const next = typeof opts === \"function\" ? opts(prevState.frameRendering) : opts;\n return {\n frameRendering: {\n enabled: (_a = next === null || next === void 0 ? void 0 : next.enabled) !== null && _a !== void 0 ? _a : prevState.frameRendering.enabled,\n clip: (_b = next === null || next === void 0 ? void 0 : next.clip) !== null && _b !== void 0 ? _b : prevState.frameRendering.clip,\n name: (_c = next === null || next === void 0 ? void 0 : next.name) !== null && _c !== void 0 ? _c : prevState.frameRendering.name,\n outline: (_d = next === null || next === void 0 ? void 0 : next.outline) !== null && _d !== void 0 ? _d : prevState.frameRendering.outline\n }\n };\n });\n };\n\n this.togglePenMode = force => {\n this.setState(prevState => {\n return {\n penMode: force !== null && force !== void 0 ? force : !prevState.penMode,\n penDetected: true\n };\n });\n };\n\n this.onHandToolToggle = () => {\n this.actionManager.executeAction(_actions_actionCanvas__WEBPACK_IMPORTED_MODULE_55__.actionToggleHandTool);\n };\n /**\r\n * Zooms on canvas viewport center\r\n */\n\n\n this.zoomCanvas = (\n /** decimal fraction between 0.1 (10% zoom) and 30 (3000% zoom) */\n value) => {\n this.setState(Object.assign({}, (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_31__.getStateForZoom)({\n viewportX: this.state.width / 2 + this.state.offsetLeft,\n viewportY: this.state.height / 2 + this.state.offsetTop,\n nextZoom: (0,_scene__WEBPACK_IMPORTED_MODULE_29__.getNormalizedZoom)(value)\n }, this.state)));\n };\n\n this.cancelInProgresAnimation = null;\n\n this.scrollToContent = (target = this.scene.getNonDeletedElements(), opts) => {\n var _a, _b;\n\n (_a = this.cancelInProgresAnimation) === null || _a === void 0 ? void 0 : _a.call(this); // convert provided target into ExcalidrawElement[] if necessary\n\n const targetElements = Array.isArray(target) ? target : [target];\n let zoom = this.state.zoom;\n let scrollX = this.state.scrollX;\n let scrollY = this.state.scrollY;\n\n if ((opts === null || opts === void 0 ? void 0 : opts.fitToContent) || (opts === null || opts === void 0 ? void 0 : opts.fitToViewport)) {\n const {\n appState\n } = (0,_actions_actionCanvas__WEBPACK_IMPORTED_MODULE_55__.zoomToFit)({\n targetElements,\n appState: this.state,\n fitToViewport: !!(opts === null || opts === void 0 ? void 0 : opts.fitToViewport),\n viewportZoomFactor: opts === null || opts === void 0 ? void 0 : opts.viewportZoomFactor\n });\n zoom = appState.zoom;\n scrollX = appState.scrollX;\n scrollY = appState.scrollY;\n } else {\n // compute only the viewport location, without any zoom adjustment\n const scroll = (0,_scene__WEBPACK_IMPORTED_MODULE_29__.calculateScrollCenter)(targetElements, this.state);\n scrollX = scroll.scrollX;\n scrollY = scroll.scrollY;\n } // when animating, we use RequestAnimationFrame to prevent the animation\n // from slowing down other processes\n\n\n if (opts === null || opts === void 0 ? void 0 : opts.animate) {\n const origScrollX = this.state.scrollX;\n const origScrollY = this.state.scrollY;\n const origZoom = this.state.zoom.value;\n const cancel = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.easeToValuesRAF)({\n fromValues: {\n scrollX: origScrollX,\n scrollY: origScrollY,\n zoom: origZoom\n },\n toValues: {\n scrollX,\n scrollY,\n zoom: zoom.value\n },\n interpolateValue: (from, to, progress, key) => {\n // for zoom, use different easing\n if (key === \"zoom\") {\n return from * Math.pow(to / from, (0,_utils__WEBPACK_IMPORTED_MODULE_33__.easeOut)(progress));\n } // handle using default\n\n\n return undefined;\n },\n onStep: ({\n scrollX,\n scrollY,\n zoom\n }) => {\n this.setState({\n scrollX,\n scrollY,\n zoom: {\n value: zoom\n }\n });\n },\n onStart: () => {\n this.setState({\n shouldCacheIgnoreZoom: true\n });\n },\n onEnd: () => {\n this.setState({\n shouldCacheIgnoreZoom: false\n });\n },\n onCancel: () => {\n this.setState({\n shouldCacheIgnoreZoom: false\n });\n },\n duration: (_b = opts === null || opts === void 0 ? void 0 : opts.duration) !== null && _b !== void 0 ? _b : 500\n });\n\n this.cancelInProgresAnimation = () => {\n cancel();\n this.cancelInProgresAnimation = null;\n };\n } else {\n this.setState({\n scrollX,\n scrollY,\n zoom\n });\n }\n };\n /** use when changing scrollX/scrollY/zoom based on user interaction */\n\n\n this.translateCanvas = state => {\n var _a;\n\n (_a = this.cancelInProgresAnimation) === null || _a === void 0 ? void 0 : _a.call(this);\n this.setState(state);\n }; //zsviczian\n\n\n this.zoomToFit = (target = this.scene.getNonDeletedElements(), maxZoom = 1, //null will zoom to max based on viewport\n margin = 0.03) => {\n if (!target) {\n target = this.scene.getNonDeletedElements();\n }\n\n if (target.length === 0) {\n maxZoom = 1;\n }\n\n this.setState((0,_actions_actionCanvas__WEBPACK_IMPORTED_MODULE_55__.zoomToFitElements)(target, this.state, false, this, maxZoom, margin).appState);\n }; //zsviczian\n\n\n this.startLineEditor = (el, selectedPointsIndices = null) => {\n if (!el || !(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(el)) {\n return;\n }\n\n const editingLinearElement = new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(el, this.scene);\n this.setState({\n selectedLinearElement: editingLinearElement,\n editingLinearElement: Object.assign(Object.assign({}, editingLinearElement), {\n selectedPointsIndices\n })\n });\n }; //zsviczian\n\n\n this.updateContainerSize = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(containers => {\n containers.forEach(el => {\n const [x, y] = (0,_math__WEBPACK_IMPORTED_MODULE_28__.rotate)(el.x + el.width, el.y + el.height, el.x + el.width / 2, el.y + el.height / 2, el.angle);\n (0,_element_resizeElements__WEBPACK_IMPORTED_MODULE_45__.resizeSingleElement)(new Map().set(el.id, el), false, el, \"se\", true, x, y);\n });\n });\n\n this.setToast = toast => {\n this.setState({\n toast\n });\n };\n\n this.restoreFileFromShare = async () => {\n try {\n const webShareTargetCache = await caches.open(\"web-share-target\");\n const response = await webShareTargetCache.match(\"shared-file\");\n\n if (response) {\n const blob = await response.blob();\n const file = new File([blob], blob.name || \"\", {\n type: blob.type\n });\n this.loadFileToCanvas(file, null);\n await webShareTargetCache.delete(\"shared-file\");\n window.history.replaceState(null, _constants__WEBPACK_IMPORTED_MODULE_12__.APP_NAME, window.location.pathname);\n }\n } catch (error) {\n this.setState({\n errorMessage: error.message\n });\n }\n };\n /** adds supplied files to existing files in the appState */\n\n\n this.addFiles = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(files => {\n const filesMap = files.reduce((acc, fileData) => {\n acc.set(fileData.id, fileData);\n return acc;\n }, new Map());\n this.files = Object.assign(Object.assign({}, this.files), Object.fromEntries(filesMap));\n this.scene.getNonDeletedElements().forEach(element => {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(element) && filesMap.has(element.fileId)) {\n this.imageCache.delete(element.fileId);\n _scene_ShapeCache__WEBPACK_IMPORTED_MODULE_66__.ShapeCache[\"delete\"](element);\n }\n });\n this.scene.informMutation();\n this.addNewImagesToImageCache();\n }); //zsviczian https://github.com/zsviczian/excalibrain/issues/9\n\n this.setMobileModeAllowed = allow => {\n const {\n width,\n height\n } = this.excalidrawContainerRef.current.getBoundingClientRect();\n this.allowMobileMode = allow;\n\n if (allow) {\n this.device = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.updateObject)(this.device, {\n isMobile: width < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_PORTRAIT || height < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_HEIGHT_LANDSCAPE && width < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_LANDSCAPE\n });\n } else {\n this.device = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.updateObject)(this.device, {\n isMobile: false\n });\n }\n\n this.forceUpdate();\n }; //zsviczian\n\n\n this.setLocalFont = showOnPanel => {\n showFourthFont = showOnPanel;\n };\n\n this.selectElements = elements => {\n this.updateScene({\n appState: Object.assign(Object.assign({}, this.state), {\n editingGroupId: null,\n selectedElementIds: elements.reduce((map, element) => {\n map[element.id] = true;\n return map;\n }, {})\n }),\n commitToHistory: true\n });\n };\n\n this.bringToFront = elements => {\n this.selectElements(elements);\n this.updateScene(_actions__WEBPACK_IMPORTED_MODULE_5__.actionBringToFront.perform(this.scene.getNonDeletedElements(), this.state));\n };\n\n this.bringForward = elements => {\n this.selectElements(elements);\n this.updateScene(_actions__WEBPACK_IMPORTED_MODULE_5__.actionBringForward.perform(this.scene.getNonDeletedElements(), this.state));\n };\n\n this.sendToBack = elements => {\n this.selectElements(elements);\n this.updateScene(_actions__WEBPACK_IMPORTED_MODULE_5__.actionSendToBack.perform(this.scene.getNonDeletedElements(), this.state));\n };\n\n this.sendBackward = elements => {\n this.selectElements(elements);\n this.updateScene(_actions__WEBPACK_IMPORTED_MODULE_5__.actionSendBackward.perform(this.scene.getNonDeletedElements(), this.state));\n };\n\n this.updateScene = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(sceneData => {\n if (sceneData.commitToHistory) {\n this.history.resumeRecording();\n }\n\n (0,react_dom__WEBPACK_IMPORTED_MODULE_2__.flushSync)(() => {\n if (sceneData.appState) {\n this.setState(sceneData.appState);\n }\n });\n\n if (sceneData.elements) {\n this.scene.replaceAllElements(sceneData.elements);\n }\n\n if (sceneData.collaborators) {\n this.setState({\n collaborators: sceneData.collaborators\n });\n }\n });\n\n this.onSceneUpdated = () => {\n this.setState({});\n };\n /**\r\n * @returns whether the menu was toggled on or off\r\n */\n\n\n this.toggleSidebar = ({\n name,\n tab,\n force\n }) => {\n var _a;\n\n let nextName;\n\n if (force === undefined) {\n nextName = ((_a = this.state.openSidebar) === null || _a === void 0 ? void 0 : _a.name) === name ? null : name;\n } else {\n nextName = force ? name : null;\n }\n\n this.setState({\n openSidebar: nextName ? {\n name: nextName,\n tab\n } : null\n });\n return !!nextName;\n };\n\n this.updateCurrentCursorPosition = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(event => {\n this.lastViewportPosition.x = event.clientX;\n this.lastViewportPosition.y = event.clientY;\n }); // Input handling\n\n this.onKeyDown = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(event => {\n // normalize `event.key` when CapsLock is pressed #2372\n if (\"Proxy\" in window && (!event.shiftKey && /^[A-Z]$/.test(event.key) || event.shiftKey && /^[a-z]$/.test(event.key))) {\n event = new Proxy(event, {\n get(ev, prop) {\n const value = ev[prop];\n\n if (typeof value === \"function\") {\n // fix for Proxies hijacking `this`\n return value.bind(ev);\n }\n\n return prop === \"key\" ? // CapsLock inverts capitalization based on ShiftKey, so invert\n // it back\n event.shiftKey ? ev.key.toUpperCase() : ev.key.toLowerCase() : value;\n }\n\n });\n }\n\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && event.key.toLowerCase() === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.V) {\n IS_PLAIN_PASTE = event.shiftKey;\n clearTimeout(IS_PLAIN_PASTE_TIMER); // reset (100ms to be safe that we it runs after the ensuing\n // paste event). Though, technically unnecessary to reset since we\n // (re)set the flag before each paste event.\n\n IS_PLAIN_PASTE_TIMER = window.setTimeout(() => {\n IS_PLAIN_PASTE = false;\n }, 100);\n } // prevent browser zoom in input fields\n\n\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && (0,_utils__WEBPACK_IMPORTED_MODULE_33__.isWritableElement)(event.target)) {\n if (event.code === _keys__WEBPACK_IMPORTED_MODULE_26__.CODES.MINUS || event.code === _keys__WEBPACK_IMPORTED_MODULE_26__.CODES.EQUAL) {\n event.preventDefault();\n return;\n }\n } // bail if\n\n\n if ( // inside an input\n (0,_utils__WEBPACK_IMPORTED_MODULE_33__.isWritableElement)(event.target) && // unless pressing escape (finalize action)\n event.key !== _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ESCAPE || // or unless using arrows (to move between buttons)\n (0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key) && (0,_utils__WEBPACK_IMPORTED_MODULE_33__.isInputLike)(event.target)) {\n return;\n }\n\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.QUESTION_MARK) {\n this.setState({\n openDialog: \"help\"\n });\n return;\n } else if (event.key.toLowerCase() === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.E && event.shiftKey && event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\n event.preventDefault();\n this.setState({\n openDialog: \"imageExport\"\n });\n return;\n }\n\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.PAGE_UP || event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.PAGE_DOWN) {\n let offset = (event.shiftKey ? this.state.width : this.state.height) / this.state.zoom.value;\n\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.PAGE_DOWN) {\n offset = -offset;\n }\n\n if (event.shiftKey) {\n this.translateCanvas(state => ({\n scrollX: state.scrollX + offset\n }));\n } else {\n this.translateCanvas(state => ({\n scrollY: state.scrollY + offset\n }));\n }\n }\n\n if (this.actionManager.handleKeyDown(event)) {\n return;\n }\n\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.K && !event.altKey && !event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\n if ((0,_appState__WEBPACK_IMPORTED_MODULE_10__.isLaserPointerActive)(this.state)) {\n this.setActiveTool({\n type: \"selection\"\n });\n } else {\n this.setActiveTool({\n type: \"laser\"\n });\n }\n\n return;\n }\n\n if (this.state.viewModeEnabled) {\n //revert to hand in case a key is pressed (K is handled above)\n if (event.key !== _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.K) {\n this.setActiveTool({\n type: \"selection\"\n });\n }\n\n return;\n }\n\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && this.state.isBindingEnabled) {\n this.setState({\n isBindingEnabled: false\n });\n }\n\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key)) {\n const step = this.state.gridSize && (event.shiftKey ? _constants__WEBPACK_IMPORTED_MODULE_12__.ELEMENT_TRANSLATE_AMOUNT : this.state.gridSize) || (event.shiftKey ? _constants__WEBPACK_IMPORTED_MODULE_12__.ELEMENT_SHIFT_TRANSLATE_AMOUNT : _constants__WEBPACK_IMPORTED_MODULE_12__.ELEMENT_TRANSLATE_AMOUNT);\n let offsetX = 0;\n let offsetY = 0;\n\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_LEFT) {\n offsetX = -step;\n } else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_RIGHT) {\n offsetX = step;\n } else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_UP) {\n offsetY = -step;\n } else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_DOWN) {\n offsetY = step;\n }\n\n const selectedElements = this.scene.getSelectedElements({\n selectedElementIds: this.state.selectedElementIds,\n includeBoundTextElement: true,\n includeElementsInFrames: true\n });\n selectedElements.forEach(element => {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n x: element.x + offsetX,\n y: element.y + offsetY\n });\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.updateBoundElements)(element, {\n simultaneouslyUpdated: selectedElements\n });\n });\n this.maybeSuggestBindingForAll(selectedElements);\n event.preventDefault();\n } else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ENTER) {\n const selectedElements = this.scene.getSelectedElements(this.state);\n\n if (selectedElements.length === 1) {\n const selectedElement = selectedElements[0];\n\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElement)) {\n if (!this.state.editingLinearElement || this.state.editingLinearElement.elementId !== selectedElements[0].id) {\n this.history.resumeRecording();\n this.setState({\n editingLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(selectedElement, this.scene)\n });\n }\n }\n } else if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(selectedElement) || (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.isValidTextContainer)(selectedElement)) {\n let container;\n\n if (!(0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(selectedElement)) {\n container = selectedElement;\n }\n\n const midPoint = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getContainerCenter)(selectedElement, this.state);\n const sceneX = midPoint.x;\n const sceneY = midPoint.y;\n this.startTextEditing({\n sceneX,\n sceneY,\n container\n });\n event.preventDefault();\n return;\n } else if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isFrameElement)(selectedElement)) {\n this.setState({\n editingFrame: selectedElement.id\n });\n }\n }\n } else if (!event.ctrlKey && !event.altKey && !event.metaKey && this.state.draggingElement === null) {\n const shape = (0,_shapes__WEBPACK_IMPORTED_MODULE_32__.findShapeByKey)(event.key);\n\n if (shape) {\n if (this.state.activeTool.type !== shape) {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_9__.trackEvent)(\"toolbar\", shape, `keyboard (${this.device.isMobile ? \"mobile\" : \"desktop\"})`);\n }\n\n this.setActiveTool({\n type: shape\n });\n event.stopPropagation();\n } else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.Q) {\n this.toggleLock(\"keyboard\");\n event.stopPropagation();\n }\n }\n\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.SPACE && gesture.pointers.size === 0) {\n isHoldingSpace = true;\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n event.preventDefault();\n }\n\n if ((event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.G || event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.S) && !event.altKey && !event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\n const selectedElements = this.scene.getSelectedElements(this.state);\n\n if (this.state.activeTool.type === \"selection\" && !selectedElements.length) {\n return;\n }\n\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.G && ((0,_scene__WEBPACK_IMPORTED_MODULE_29__.hasBackground)(this.state.activeTool.type) || selectedElements.some(element => (0,_scene__WEBPACK_IMPORTED_MODULE_29__.hasBackground)(element.type)))) {\n this.setState({\n openPopup: \"elementBackground\"\n });\n event.stopPropagation();\n }\n\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.S) {\n this.setState({\n openPopup: \"elementStroke\"\n });\n event.stopPropagation();\n }\n }\n\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.BACKSPACE || event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.DELETE)) {\n _jotai__WEBPACK_IMPORTED_MODULE_56__.jotaiStore.set(_ActiveConfirmDialog__WEBPACK_IMPORTED_MODULE_57__.activeConfirmDialogAtom, \"clearCanvas\");\n } // eye dropper\n // -----------------------------------------------------------------------\n\n\n const lowerCased = event.key.toLocaleLowerCase();\n const isPickingStroke = lowerCased === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.S && event.shiftKey;\n const isPickingBackground = event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.I || lowerCased === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.G && event.shiftKey;\n\n if (isPickingStroke || isPickingBackground) {\n this.openEyeDropper({\n type: isPickingStroke ? \"stroke\" : \"background\"\n });\n } // -----------------------------------------------------------------------\n\n });\n this.onWheel = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(event => {\n // prevent browser pinch zoom on DOM elements\n if (!(event.target instanceof HTMLCanvasElement) && event.ctrlKey) {\n event.preventDefault();\n }\n });\n this.onKeyUp = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(event => {\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.SPACE) {\n if (this.state.viewModeEnabled) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n } else if (this.state.activeTool.type === \"selection\") {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.resetCursor)(this.interactiveCanvas);\n } else {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursorForShape)(this.interactiveCanvas, this.state);\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({}, this.state),\n selectedGroupIds: {},\n editingGroupId: null,\n activeEmbeddable: null\n });\n }\n\n isHoldingSpace = false;\n }\n\n if (!event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && !this.state.isBindingEnabled) {\n this.setState({\n isBindingEnabled: true\n });\n }\n\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key)) {\n const selectedElements = this.scene.getSelectedElements(this.state);\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state) ? (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.bindOrUnbindSelectedElements)(selectedElements) : (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.unbindLinearElements)(selectedElements);\n this.setState({\n suggestedBindings: []\n });\n }\n });\n\n this.setActiveTool = tool => {\n var _a;\n\n const nextActiveTool = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.updateActiveTool)(this.state, tool);\n\n if (nextActiveTool.type === \"hand\") {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n } else if (!isHoldingSpace) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursorForShape)(this.interactiveCanvas, this.state);\n }\n\n if ((0,_utils__WEBPACK_IMPORTED_MODULE_33__.isToolIcon)(document.activeElement)) {\n this.focusContainer();\n }\n\n if (!(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElementType)(nextActiveTool.type)) {\n this.setState({\n suggestedBindings: []\n });\n }\n\n if (nextActiveTool.type === \"image\") {\n this.onImageAction({\n insertOnCanvasDirectly: (_a = tool.type === \"image\" && tool.insertOnCanvasDirectly) !== null && _a !== void 0 ? _a : false\n });\n }\n\n this.setState(prevState => {\n const commonResets = {\n snapLines: prevState.snapLines.length ? [] : prevState.snapLines,\n originSnapOffset: null,\n activeEmbeddable: null\n };\n\n if (nextActiveTool.type !== \"selection\") {\n return Object.assign(Object.assign(Object.assign({}, prevState), {\n activeTool: nextActiveTool,\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(nextActiveTool.type === \"mermaid\" //zsviczian\n ? this.state.selectedElementIds : {}, prevState),\n selectedGroupIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({}, prevState),\n editingGroupId: null,\n multiElement: null\n }), commonResets);\n }\n\n return Object.assign(Object.assign(Object.assign({}, prevState), {\n activeTool: nextActiveTool\n }), commonResets);\n });\n };\n\n this.setCursor = cursor => {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, cursor);\n };\n\n this.resetCursor = () => {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.resetCursor)(this.interactiveCanvas);\n };\n /**\r\n * returns whether user is making a gesture with >= 2 fingers (points)\r\n * on o touch screen (not on a trackpad). Currently only relates to Darwin\r\n * (iOS/iPadOS,MacOS), but may work on other devices in the future if\r\n * GestureEvent is standardized.\r\n */\n\n\n this.isTouchScreenMultiTouchGesture = () => {\n // we don't want to deselect when using trackpad, and multi-point gestures\n // only work on touch screens, so checking for >= pointers means we're on a\n // touchscreen\n return gesture.pointers.size >= 2;\n }; // fires only on Safari\n\n\n this.onGestureStart = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(event => {\n event.preventDefault(); // we only want to deselect on touch screens because user may have selected\n // elements by mistake while zooming\n\n if (this.isTouchScreenMultiTouchGesture()) {\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({}, this.state),\n activeEmbeddable: null\n });\n }\n\n gesture.initialScale = this.state.zoom.value;\n }); // fires only on Safari\n\n this.onGestureChange = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(event => {\n event.preventDefault(); // onGestureChange only has zoom factor but not the center.\n // If we're on iPad or iPhone, then we recognize multi-touch and will\n // zoom in at the right location in the touchmove handler\n // (handleCanvasPointerMove).\n //\n // On Macbook trackpad, we don't have those events so will zoom in at the\n // current location instead.\n //\n // As such, bail from this handler on touch devices.\n\n if (this.isTouchScreenMultiTouchGesture()) {\n return;\n }\n\n const initialScale = gesture.initialScale;\n\n if (initialScale) {\n this.setState(state => Object.assign({}, (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_31__.getStateForZoom)({\n viewportX: this.lastViewportPosition.x,\n viewportY: this.lastViewportPosition.y,\n nextZoom: (0,_scene__WEBPACK_IMPORTED_MODULE_29__.getNormalizedZoom)(initialScale * event.scale)\n }, state)));\n }\n }); // fires only on Safari\n\n this.onGestureEnd = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(event => {\n event.preventDefault(); // reselect elements only on touch screens (see onGestureStart)\n\n if (this.isTouchScreenMultiTouchGesture()) {\n this.setState({\n previousSelectedElementIds: {},\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(this.state.previousSelectedElementIds, this.state)\n });\n }\n\n gesture.initialScale = null;\n });\n\n this.startTextEditing = ({\n sceneX,\n sceneY,\n insertAtParentCenter = true,\n container\n }) => {\n var _a, _b;\n\n let shouldBindToContainer = false;\n let parentCenterPosition = insertAtParentCenter && this.getTextWysiwygSnappedToCenterPosition(sceneX, sceneY, this.state, container);\n\n if (container && parentCenterPosition) {\n const boundTextElementToContainer = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getBoundTextElement)(container);\n\n if (!boundTextElementToContainer) {\n shouldBindToContainer = true;\n }\n }\n\n let existingTextElement = null;\n const selectedElements = this.scene.getSelectedElements(this.state);\n\n if (selectedElements.length === 1) {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(selectedElements[0])) {\n existingTextElement = selectedElements[0];\n } else if (container) {\n existingTextElement = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getBoundTextElement)(selectedElements[0]);\n } else {\n existingTextElement = this.getTextElementAtPosition(sceneX, sceneY);\n }\n } else {\n existingTextElement = this.getTextElementAtPosition(sceneX, sceneY);\n }\n\n const fontFamily = (existingTextElement === null || existingTextElement === void 0 ? void 0 : existingTextElement.fontFamily) || this.state.currentItemFontFamily;\n const lineHeight = (existingTextElement === null || existingTextElement === void 0 ? void 0 : existingTextElement.lineHeight) || (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getDefaultLineHeight)(fontFamily);\n const fontSize = this.state.currentItemFontSize;\n\n if (!existingTextElement && shouldBindToContainer && container && !(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isArrowElement)(container)) {\n const fontString = {\n fontSize,\n fontFamily\n };\n const minWidth = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getApproxMinLineWidth)((0,_utils__WEBPACK_IMPORTED_MODULE_33__.getFontString)(fontString), lineHeight);\n const minHeight = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getApproxMinLineHeight)(fontSize, lineHeight);\n const newHeight = Math.max(container.height, minHeight);\n const newWidth = Math.max(container.width, minWidth);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(container, {\n height: newHeight,\n width: newWidth\n });\n sceneX = container.x + newWidth / 2;\n sceneY = container.y + newHeight / 2;\n\n if (parentCenterPosition) {\n parentCenterPosition = this.getTextWysiwygSnappedToCenterPosition(sceneX, sceneY, this.state, container);\n }\n }\n\n const topLayerFrame = this.getTopLayerFrameAtSceneCoords({\n x: sceneX,\n y: sceneY\n });\n const element = existingTextElement ? existingTextElement : (0,_element__WEBPACK_IMPORTED_MODULE_16__.newTextElement)({\n x: parentCenterPosition ? parentCenterPosition.elementCenterX : sceneX,\n y: parentCenterPosition ? parentCenterPosition.elementCenterY : sceneY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n text: \"\",\n rawText: \"\",\n fontSize,\n fontFamily,\n textAlign: parentCenterPosition ? \"center\" : this.state.currentItemTextAlign,\n verticalAlign: parentCenterPosition ? _constants__WEBPACK_IMPORTED_MODULE_12__.VERTICAL_ALIGN.MIDDLE : _constants__WEBPACK_IMPORTED_MODULE_12__.DEFAULT_VERTICAL_ALIGN,\n containerId: shouldBindToContainer ? container === null || container === void 0 ? void 0 : container.id : undefined,\n groupIds: (_a = container === null || container === void 0 ? void 0 : container.groupIds) !== null && _a !== void 0 ? _a : [],\n lineHeight,\n angle: (_b = container === null || container === void 0 ? void 0 : container.angle) !== null && _b !== void 0 ? _b : 0,\n frameId: topLayerFrame ? topLayerFrame.id : null\n });\n\n if (!existingTextElement && shouldBindToContainer && container) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(container, {\n boundElements: (container.boundElements || []).concat({\n type: \"text\",\n id: element.id\n })\n });\n }\n\n this.setState({\n editingElement: element\n });\n\n if (!existingTextElement) {\n if (container && shouldBindToContainer) {\n const containerIndex = this.scene.getElementIndex(container.id);\n this.scene.insertElementAtIndex(element, containerIndex + 1);\n } else {\n this.scene.addNewElement(element);\n }\n }\n\n this.setState({\n editingElement: element\n });\n this.handleTextWysiwyg(element, {\n isExistingElement: !!existingTextElement\n });\n };\n\n this.handleCanvasDoubleClick = event => {\n // case: double-clicking with arrow/line tool selected would both create\n // text and enter multiElement mode\n if (this.state.multiElement) {\n return;\n }\n\n if (this.state.viewModeEnabled) {\n if (this.state.activeTool.type === \"laser\") {\n this.setActiveTool({\n type: \"selection\"\n });\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n } else {\n this.setActiveTool({\n type: \"laser\"\n });\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.CROSSHAIR);\n }\n\n return;\n } // we should only be able to double click when mode is selection\n\n\n if (this.state.activeTool.type !== \"selection\") {\n return;\n }\n\n const selectedElements = this.scene.getSelectedElements(this.state);\n\n if (selectedElements.length === 1 && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0])) {\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && (!this.state.editingLinearElement || this.state.editingLinearElement.elementId !== selectedElements[0].id)) {\n this.history.resumeRecording();\n this.setState({\n editingLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(selectedElements[0], this.scene)\n });\n return;\n } else if (this.state.editingLinearElement && this.state.editingLinearElement.elementId === selectedElements[0].id) {\n return;\n }\n }\n\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.resetCursor)(this.interactiveCanvas);\n let {\n x: sceneX,\n y: sceneY\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)(event, this.state);\n const selectedGroupIds = (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getSelectedGroupIds)(this.state);\n\n if (selectedGroupIds.length > 0) {\n const hitElement = this.getElementAtPosition(sceneX, sceneY);\n const selectedGroupId = hitElement && (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getSelectedGroupIdForElement)(hitElement, this.state.selectedGroupIds);\n\n if (selectedGroupId) {\n this.setState(prevState => Object.assign(Object.assign({}, prevState), (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)({\n editingGroupId: selectedGroupId,\n selectedElementIds: {\n [hitElement.id]: true\n }\n }, this.scene.getNonDeletedElements(), prevState, this)));\n return;\n }\n }\n\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.resetCursor)(this.interactiveCanvas);\n\n if (!event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && !this.state.viewModeEnabled) {\n const hitElement = this.getElementAtPosition(sceneX, sceneY);\n\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isEmbeddableElement)(hitElement)) {\n this.setState({\n activeEmbeddable: {\n element: hitElement,\n state: \"active\"\n }\n });\n return;\n }\n\n const container = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getTextBindableContainerAtPosition)(this.scene.getNonDeletedElements(), this.state, sceneX, sceneY);\n\n if (container) {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.hasBoundTextElement)(container) || !(0,_utils__WEBPACK_IMPORTED_MODULE_33__.isTransparent)(container.backgroundColor) || (0,_element_collision__WEBPACK_IMPORTED_MODULE_44__.isHittingElementNotConsideringBoundingBox)(container, this.state, this.frameNameBoundsCache, [sceneX, sceneY])) {\n const midPoint = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getContainerCenter)(container, this.state);\n sceneX = midPoint.x;\n sceneY = midPoint.y;\n }\n }\n\n this.startTextEditing({\n sceneX,\n sceneY,\n insertAtParentCenter: !event.altKey,\n container\n });\n }\n };\n\n this.getElementLinkAtPosition = (scenePointer, hitElement) => {\n // Reversing so we traverse the elements in decreasing order\n // of z-index\n const elements = this.scene.getNonDeletedElements().slice().reverse();\n let hitElementIndex = Infinity;\n return elements.find((element, index) => {\n if (hitElement && element.id === hitElement.id) {\n hitElementIndex = index;\n }\n\n return element.link && index <= hitElementIndex && (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_46__.isPointHittingLink)(element, this.state, [scenePointer.x, scenePointer.y], this.device.isMobile);\n });\n };\n\n this.redirectToLink = (event, isTouchScreen) => {\n const draggedDistance = (0,_math__WEBPACK_IMPORTED_MODULE_28__.distance2d)(this.lastPointerDownEvent.clientX, this.lastPointerDownEvent.clientY, this.lastPointerUpEvent.clientX, this.lastPointerUpEvent.clientY);\n\n if (!this.hitLinkElement || // For touch screen allow dragging threshold else strict check\n isTouchScreen && draggedDistance > _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD || !isTouchScreen && draggedDistance !== 0) {\n return;\n }\n\n const lastPointerDownCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)(this.lastPointerDownEvent, this.state);\n const lastPointerDownHittingLinkIcon = (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_46__.isPointHittingLink)(this.hitLinkElement, this.state, [lastPointerDownCoords.x, lastPointerDownCoords.y], this.device.isMobile);\n const lastPointerUpCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)(this.lastPointerUpEvent, this.state);\n const lastPointerUpHittingLinkIcon = (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_46__.isPointHittingLink)(this.hitLinkElement, this.state, [lastPointerUpCoords.x, lastPointerUpCoords.y], this.device.isMobile);\n\n if (lastPointerDownHittingLinkIcon && lastPointerUpHittingLinkIcon) {\n let url = this.hitLinkElement.link;\n\n if (url) {\n url = (0,_data_url__WEBPACK_IMPORTED_MODULE_47__.normalizeLink)(url);\n let customEvent;\n\n if (this.props.onLinkOpen) {\n customEvent = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.wrapEvent)(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.EXCALIDRAW_LINK, event.nativeEvent);\n this.props.onLinkOpen(Object.assign(Object.assign({}, this.hitLinkElement), {\n link: url\n }), customEvent);\n }\n\n if (!(customEvent === null || customEvent === void 0 ? void 0 : customEvent.defaultPrevented)) {\n const target = (0,_data_url__WEBPACK_IMPORTED_MODULE_47__.isLocalLink)(url) ? \"_self\" : \"_blank\";\n const newWindow = window.open(undefined, target); // https://mathiasbynens.github.io/rel-noopener/\n\n if (newWindow) {\n newWindow.opener = null;\n newWindow.location = url;\n }\n }\n }\n }\n };\n\n this.getTopLayerFrameAtSceneCoords = sceneCoords => {\n const frames = this.scene.getNonDeletedFrames().filter(frame => (0,_frame__WEBPACK_IMPORTED_MODULE_51__.isCursorInFrame)(sceneCoords, frame));\n return frames.length ? frames[frames.length - 1] : null;\n };\n\n this.handleCanvasPointerMove = event => {\n var _a, _b;\n\n this.savePointer(event.clientX, event.clientY, this.state.cursorButton);\n\n if (gesture.pointers.has(event.pointerId)) {\n gesture.pointers.set(event.pointerId, {\n x: event.clientX,\n y: event.clientY\n });\n }\n\n const initialScale = gesture.initialScale;\n\n if (gesture.pointers.size === 2 && gesture.lastCenter && initialScale && gesture.initialDistance) {\n const center = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getCenter)(gesture.pointers);\n const deltaX = center.x - gesture.lastCenter.x;\n const deltaY = center.y - gesture.lastCenter.y;\n gesture.lastCenter = center;\n const distance = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getDistance)(Array.from(gesture.pointers.values()));\n const scaleFactor = !this.state.allowPinchZoom && //zsviczian\n this.state.activeTool.type === \"freedraw\" && this.state.penMode ? 1 : distance / gesture.initialDistance;\n const nextZoom = scaleFactor ? (0,_scene__WEBPACK_IMPORTED_MODULE_29__.getNormalizedZoom)(initialScale * scaleFactor) : this.state.zoom.value;\n this.setState(state => {\n const zoomState = (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_31__.getStateForZoom)({\n viewportX: center.x,\n viewportY: center.y,\n nextZoom\n }, state);\n this.translateCanvas({\n zoom: zoomState.zoom,\n scrollX: zoomState.scrollX + deltaX / nextZoom,\n scrollY: zoomState.scrollY + deltaY / nextZoom,\n shouldCacheIgnoreZoom: true\n });\n });\n this.resetShouldCacheIgnoreZoomDebounced();\n } else {\n gesture.lastCenter = gesture.initialDistance = gesture.initialScale = null;\n }\n\n if (isHoldingSpace || isPanning || isDraggingScrollBar || (0,_appState__WEBPACK_IMPORTED_MODULE_10__.isHandToolActive)(this.state)) {\n return;\n }\n\n const isPointerOverScrollBars = (0,_scene__WEBPACK_IMPORTED_MODULE_29__.isOverScrollBars)(currentScrollBars, event.clientX - this.state.offsetLeft, event.clientY - this.state.offsetTop);\n const isOverScrollBar = isPointerOverScrollBars.isOverEither;\n\n if (!this.state.draggingElement && !this.state.multiElement) {\n if (isOverScrollBar) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.resetCursor)(this.interactiveCanvas);\n } else {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursorForShape)(this.interactiveCanvas, this.state);\n }\n }\n\n const scenePointer = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)(event, this.state);\n const {\n x: scenePointerX,\n y: scenePointerY\n } = scenePointer;\n\n if (!this.state.draggingElement && (0,_snapping__WEBPACK_IMPORTED_MODULE_58__.isActiveToolNonLinearSnappable)(this.state.activeTool.type)) {\n const {\n originOffset,\n snapLines\n } = (0,_snapping__WEBPACK_IMPORTED_MODULE_58__.getSnapLinesAtPointer)(this.scene.getNonDeletedElements(), this.state, {\n x: scenePointerX,\n y: scenePointerY\n }, event);\n this.setState({\n snapLines,\n originSnapOffset: originOffset\n });\n } else if (!this.state.draggingElement) {\n this.setState({\n snapLines: []\n });\n }\n\n if (this.state.editingLinearElement && !this.state.editingLinearElement.isDragging) {\n const editingLinearElement = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerMove(event, scenePointerX, scenePointerY, this.state);\n\n if (editingLinearElement && editingLinearElement !== this.state.editingLinearElement) {\n // Since we are reading from previous state which is not possible with\n // automatic batching in React 18 hence using flush sync to synchronously\n // update the state. Check https://github.com/excalidraw/excalidraw/pull/5508 for more details.\n (0,react_dom__WEBPACK_IMPORTED_MODULE_2__.flushSync)(() => {\n this.setState({\n editingLinearElement\n });\n });\n }\n\n if ((editingLinearElement === null || editingLinearElement === void 0 ? void 0 : editingLinearElement.lastUncommittedPoint) != null) {\n this.maybeSuggestBindingAtCursor(scenePointer);\n } else {\n // causes stack overflow if not sync\n (0,react_dom__WEBPACK_IMPORTED_MODULE_2__.flushSync)(() => {\n this.setState({\n suggestedBindings: []\n });\n });\n }\n }\n\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElementType)(this.state.activeTool.type)) {\n // Hovering with a selected tool or creating new linear element via click\n // and point\n const {\n draggingElement\n } = this.state;\n\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement, false)) {\n this.maybeSuggestBindingsForLinearElementAtCoords(draggingElement, [scenePointer], this.state.startBoundElement);\n } else {\n this.maybeSuggestBindingAtCursor(scenePointer);\n }\n }\n\n if (this.state.multiElement) {\n const {\n multiElement\n } = this.state;\n const {\n x: rx,\n y: ry\n } = multiElement;\n const {\n points,\n lastCommittedPoint\n } = multiElement;\n const lastPoint = points[points.length - 1];\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursorForShape)(this.interactiveCanvas, this.state);\n\n if (lastPoint === lastCommittedPoint) {\n // if we haven't yet created a temp point and we're beyond commit-zone\n // threshold, add a point\n if ((0,_math__WEBPACK_IMPORTED_MODULE_28__.distance2d)(scenePointerX - rx, scenePointerY - ry, lastPoint[0], lastPoint[1]) >= _constants__WEBPACK_IMPORTED_MODULE_12__.LINE_CONFIRM_THRESHOLD) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n points: [...points, [scenePointerX - rx, scenePointerY - ry]]\n });\n } else {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER); // in this branch, we're inside the commit zone, and no uncommitted\n // point exists. Thus do nothing (don't add/remove points).\n }\n } else if (points.length > 2 && lastCommittedPoint && (0,_math__WEBPACK_IMPORTED_MODULE_28__.distance2d)(scenePointerX - rx, scenePointerY - ry, lastCommittedPoint[0], lastCommittedPoint[1]) < _constants__WEBPACK_IMPORTED_MODULE_12__.LINE_CONFIRM_THRESHOLD) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n points: points.slice(0, -1)\n });\n } else {\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_28__.getGridPoint)(scenePointerX, scenePointerY, event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] ? null : this.state.gridSize);\n const [lastCommittedX, lastCommittedY] = (_a = multiElement === null || multiElement === void 0 ? void 0 : multiElement.lastCommittedPoint) !== null && _a !== void 0 ? _a : [0, 0];\n let dxFromLastCommitted = gridX - rx - lastCommittedX;\n let dyFromLastCommitted = gridY - ry - lastCommittedY;\n\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldRotateWithDiscreteAngle)(event)) {\n ({\n width: dxFromLastCommitted,\n height: dyFromLastCommitted\n } = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getLockedLinearCursorAlignSize)( // actual coordinate of the last committed point\n lastCommittedX + rx, lastCommittedY + ry, // cursor-grid coordinate\n gridX, gridY));\n }\n\n if ((0,_math__WEBPACK_IMPORTED_MODULE_28__.isPathALoop)(points, this.state.zoom.value)) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n } // update last uncommitted point\n\n\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n points: [...points.slice(0, -1), [lastCommittedX + dxFromLastCommitted, lastCommittedY + dyFromLastCommitted]]\n });\n }\n\n return;\n }\n\n const hasDeselectedButton = Boolean(event.buttons);\n\n if (hasDeselectedButton || this.state.activeTool.type !== \"selection\" && this.state.activeTool.type !== \"text\" && this.state.activeTool.type !== \"eraser\") {\n return;\n }\n\n const elements = this.scene.getNonDeletedElements();\n const selectedElements = this.scene.getSelectedElements(this.state);\n\n if (selectedElements.length === 1 && !isOverScrollBar && !this.state.editingLinearElement) {\n const elementWithTransformHandleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getElementWithTransformHandleType)(elements, this.state, scenePointerX, scenePointerY, this.state.zoom, event.pointerType);\n\n if (elementWithTransformHandleType && elementWithTransformHandleType.transformHandleType) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)(elementWithTransformHandleType));\n return;\n }\n } else if (selectedElements.length > 1 && !isOverScrollBar) {\n const transformHandleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getTransformHandleTypeFromCoords)((0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements), scenePointerX, scenePointerY, this.state.zoom, event.pointerType);\n\n if (transformHandleType) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)({\n transformHandleType\n }));\n return;\n }\n }\n\n const hitElement = this.getElementAtPosition(scenePointer.x, scenePointer.y);\n this.hitLinkElement = this.getElementLinkAtPosition(scenePointer, hitElement);\n\n if ((0,_appState__WEBPACK_IMPORTED_MODULE_10__.isEraserActive)(this.state)) {\n return;\n }\n\n if (this.hitLinkElement && !this.state.selectedElementIds[this.hitLinkElement.id]) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_46__.showHyperlinkTooltip)(this.hitLinkElement, this.state);\n\n if (this.props.onLinkHover) {\n this.props.onLinkHover(this.hitLinkElement, event);\n } //zsviczian\n\n } else {\n (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_46__.hideHyperlinkToolip)();\n\n if (hitElement && (hitElement.link || (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isEmbeddableElement)(hitElement)) && this.state.selectedElementIds[hitElement.id] && !this.state.contextMenu && !this.state.showHyperlinkPopup) {\n this.setState({\n showHyperlinkPopup: \"info\"\n });\n } else if (this.state.activeTool.type === \"text\") {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(hitElement) ? _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.TEXT : _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.CROSSHAIR);\n } else if (this.state.viewModeEnabled) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n } else if (isOverScrollBar) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.AUTO);\n } else if (this.state.selectedLinearElement) {\n this.handleHoverSelectedLinearElement(this.state.selectedLinearElement, scenePointerX, scenePointerY);\n } else if ( // if using cmd/ctrl, we're not dragging\n !event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\n if ((hitElement || this.isHittingCommonBoundingBoxOfSelectedElements(scenePointer, selectedElements)) && !(hitElement === null || hitElement === void 0 ? void 0 : hitElement.locked)) {\n if (hitElement && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isEmbeddableElement)(hitElement) && this.isEmbeddableCenter(hitElement, event, scenePointerX, scenePointerY)) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n this.setState({\n activeEmbeddable: {\n element: hitElement,\n state: \"hover\"\n }\n });\n } else {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.MOVE);\n\n if (((_b = this.state.activeEmbeddable) === null || _b === void 0 ? void 0 : _b.state) === \"hover\") {\n this.setState({\n activeEmbeddable: null\n });\n }\n }\n }\n } else {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.AUTO);\n }\n }\n };\n\n this.handleEraser = (event, pointerDownState, scenePointer) => {\n const updateElementIds = elements => {\n elements.forEach(element => {\n if (element.locked) {\n return;\n }\n\n idsToUpdate.push(element.id);\n\n if (event.altKey) {\n if (pointerDownState.elementIdsToErase[element.id] && pointerDownState.elementIdsToErase[element.id].erase) {\n pointerDownState.elementIdsToErase[element.id].erase = false;\n }\n } else if (!pointerDownState.elementIdsToErase[element.id]) {\n pointerDownState.elementIdsToErase[element.id] = {\n erase: true,\n opacity: element.opacity\n };\n }\n });\n };\n\n const idsToUpdate = [];\n const distance = (0,_math__WEBPACK_IMPORTED_MODULE_28__.distance2d)(pointerDownState.lastCoords.x, pointerDownState.lastCoords.y, scenePointer.x, scenePointer.y);\n const threshold = 10 / this.state.zoom.value;\n const point = Object.assign({}, pointerDownState.lastCoords);\n let samplingInterval = 0;\n\n while (samplingInterval <= distance) {\n const hitElements = this.getElementsAtPosition(point.x, point.y);\n updateElementIds(hitElements); // Exit since we reached current point\n\n if (samplingInterval === distance) {\n break;\n } // Calculate next point in the line at a distance of sampling interval\n\n\n samplingInterval = Math.min(samplingInterval + threshold, distance);\n const distanceRatio = samplingInterval / distance;\n const nextX = (1 - distanceRatio) * point.x + distanceRatio * scenePointer.x;\n const nextY = (1 - distanceRatio) * point.y + distanceRatio * scenePointer.y;\n point.x = nextX;\n point.y = nextY;\n }\n\n const elements = this.scene.getElementsIncludingDeleted().map(ele => {\n const id = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(ele) && idsToUpdate.includes(ele.containerId) ? ele.containerId : ele.id;\n\n if (idsToUpdate.includes(id)) {\n if (event.altKey) {\n if (pointerDownState.elementIdsToErase[id] && pointerDownState.elementIdsToErase[id].erase === false) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n opacity: pointerDownState.elementIdsToErase[id].opacity\n });\n }\n } else {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n opacity: _constants__WEBPACK_IMPORTED_MODULE_12__.ELEMENT_READY_TO_ERASE_OPACITY\n });\n }\n }\n\n return ele;\n });\n this.scene.replaceAllElements(elements);\n pointerDownState.lastCoords.x = scenePointer.x;\n pointerDownState.lastCoords.y = scenePointer.y;\n }; // set touch moving for mobile context menu\n\n\n this.handleTouchMove = event => {\n invalidateContextMenu = true;\n };\n\n this.handleCanvasPointerDown = event => {\n var _a, _b;\n\n this.focusContainer(); //zsviczian\n // since contextMenu options are potentially evaluated on each render,\n // and an contextMenu action may depend on selection state, we must\n // close the contextMenu before we update the selection on pointerDown\n // (e.g. resetting selection)\n\n if (this.state.contextMenu) {\n this.setState({\n contextMenu: null\n });\n }\n\n if (this.state.snapLines) {\n this.setAppState({\n snapLines: []\n });\n }\n\n this.updateGestureOnPointerDown(event); // if dragging element is freedraw and another pointerdown event occurs\n // a second finger is on the screen\n // discard the freedraw element if it is very short because it is likely\n // just a spike, otherwise finalize the freedraw element when the second\n // finger is lifted\n\n if (event.pointerType === \"touch\" && this.state.draggingElement && this.state.draggingElement.type === \"freedraw\") {\n const element = this.state.draggingElement;\n this.updateScene(Object.assign(Object.assign({}, element.points.length < 10 ? {\n elements: this.scene.getElementsIncludingDeleted().filter(el => el.id !== element.id)\n } : {}), {\n appState: {\n draggingElement: null,\n editingElement: null,\n startBoundElement: null,\n suggestedBindings: [],\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(Object.keys(this.state.selectedElementIds).filter(key => key !== element.id).reduce((obj, key) => {\n obj[key] = this.state.selectedElementIds[key];\n return obj;\n }, {}), this.state)\n }\n }));\n return;\n } // remove any active selection when we start to interact with canvas\n // (mainly, we care about removing selection outside the component which\n // would prevent our copy handling otherwise)\n\n\n const selection = document.getSelection();\n\n if (selection === null || selection === void 0 ? void 0 : selection.anchorNode) {\n selection.removeAllRanges();\n }\n\n this.maybeOpenContextMenuAfterPointerDownOnTouchDevices(event);\n this.maybeCleanupAfterMissingPointerUp(event); //fires only once, if pen is detected, penMode is enabled\n //the user can disable this by toggling the penMode button\n\n if (!this.state.penDetected && event.pointerType === \"pen\") {\n this.setState(prevState => {\n return {\n penMode: true,\n penDetected: true\n };\n });\n }\n\n if (!this.device.isTouchScreen && [\"pen\", \"touch\"].includes(event.pointerType)) {\n this.device = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.updateObject)(this.device, {\n isTouchScreen: true\n });\n }\n\n if (isPanning) {\n return;\n }\n\n this.lastPointerDownEvent = event; // we must exit before we set `cursorButton` state and `savePointer`\n // else it will send pointer state & laser pointer events in collab when\n // panning\n\n if (this.handleCanvasPanUsingWheelOrSpaceDrag(event)) {\n return;\n }\n\n this.setState({\n lastPointerDownWith: event.pointerType,\n cursorButton: \"down\"\n });\n this.savePointer(event.clientX, event.clientY, \"down\");\n\n if (this.handleCanvasPanUsingWheelOrSpaceDrag(event)) {\n return;\n } // only handle left mouse button or touch\n\n\n if (event.button !== _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.MAIN && event.button !== _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.TOUCH) {\n return;\n } // don't select while panning\n\n\n if (gesture.pointers.size > 1) {\n return;\n } // State for the duration of a pointer interaction, which starts with a\n // pointerDown event, ends with a pointerUp event (or another pointerDown)\n\n\n const pointerDownState = this.initialPointerDownState(event);\n this.setState({\n selectedElementsAreBeingDragged: false\n });\n\n if (this.handleDraggingScrollBar(event, pointerDownState)) {\n return;\n }\n\n this.clearSelectionIfNotUsingSelection();\n this.updateBindingEnabledOnPointerMove(event);\n\n if (this.handleSelectionOnPointerDown(event, pointerDownState)) {\n return;\n }\n\n const allowOnPointerDown = !this.state.penMode || event.pointerType !== \"touch\" || this.state.activeTool.type === \"selection\" || this.state.activeTool.type === \"text\" || this.state.activeTool.type === \"image\";\n\n if (!allowOnPointerDown) {\n return;\n }\n\n if (this.state.activeTool.type === \"text\") {\n this.handleTextOnPointerDown(event, pointerDownState);\n return;\n } else if (this.state.activeTool.type === \"arrow\" || this.state.activeTool.type === \"line\") {\n this.handleLinearElementOnPointerDown(event, this.state.activeTool.type, pointerDownState);\n } else if (this.state.activeTool.type === \"image\") {\n // reset image preview on pointerdown\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.CROSSHAIR); // retrieve the latest element as the state may be stale\n\n const pendingImageElement = this.state.pendingImageElementId && this.scene.getElement(this.state.pendingImageElementId);\n\n if (!pendingImageElement) {\n return;\n }\n\n this.setState({\n draggingElement: pendingImageElement,\n editingElement: pendingImageElement,\n pendingImageElementId: null,\n multiElement: null\n });\n const {\n x,\n y\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)(event, this.state);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(pendingImageElement, {\n x,\n y\n });\n } else if (this.state.activeTool.type === \"freedraw\") {\n this.handleFreeDrawElementOnPointerDown(event, this.state.activeTool.type, pointerDownState);\n } else if (this.state.activeTool.type === \"custom\") {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursorForShape)(this.interactiveCanvas, this.state);\n } else if (this.state.activeTool.type === \"frame\") {\n this.createFrameElementOnPointerDown(pointerDownState);\n } else if (this.state.activeTool.type === \"laser\") {\n this.laserPathManager.startPath(pointerDownState.lastCoords.x, pointerDownState.lastCoords.y);\n } else if (this.state.activeTool.type !== \"eraser\" && this.state.activeTool.type !== \"hand\" && this.state.activeTool.type !== \"mermaid\") {\n this.createGenericElementOnPointerDown(this.state.activeTool.type, pointerDownState);\n }\n\n (_b = (_a = this.props) === null || _a === void 0 ? void 0 : _a.onPointerDown) === null || _b === void 0 ? void 0 : _b.call(_a, this.state.activeTool, pointerDownState);\n this.onPointerDownEmitter.trigger(this.state.activeTool, pointerDownState, event);\n const onPointerMove = this.onPointerMoveFromPointerDownHandler(pointerDownState);\n const onPointerUp = this.onPointerUpFromPointerDownHandler(pointerDownState);\n const onKeyDown = this.onKeyDownFromPointerDownHandler(pointerDownState);\n const onKeyUp = this.onKeyUpFromPointerDownHandler(pointerDownState);\n lastPointerUp = onPointerUp;\n\n if (!this.state.viewModeEnabled || this.state.activeTool.type === \"laser\") {\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, onPointerUp);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYDOWN, onKeyDown);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYUP, onKeyUp);\n pointerDownState.eventListeners.onMove = onPointerMove;\n pointerDownState.eventListeners.onUp = onPointerUp;\n pointerDownState.eventListeners.onKeyUp = onKeyUp;\n pointerDownState.eventListeners.onKeyDown = onKeyDown;\n }\n };\n\n this.handleCanvasPointerUp = event => {\n var _a, _b;\n\n this.removePointer(event);\n this.lastPointerUpEvent = event;\n const scenePointer = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)({\n clientX: event.clientX,\n clientY: event.clientY\n }, this.state);\n const clicklength = event.timeStamp - ((_b = (_a = this.lastPointerDownEvent) === null || _a === void 0 ? void 0 : _a.timeStamp) !== null && _b !== void 0 ? _b : 0);\n\n if (this.device.isMobile && clicklength < 300) {\n const hitElement = this.getElementAtPosition(scenePointer.x, scenePointer.y);\n\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isEmbeddableElement)(hitElement) && this.isEmbeddableCenter(hitElement, event, scenePointer.x, scenePointer.y)) {\n this.handleEmbeddableCenterClick(hitElement);\n return;\n }\n }\n\n if (this.device.isTouchScreen) {\n const hitElement = this.getElementAtPosition(scenePointer.x, scenePointer.y);\n this.hitLinkElement = this.getElementLinkAtPosition(scenePointer, hitElement);\n }\n\n if (this.hitLinkElement && !this.state.selectedElementIds[this.hitLinkElement.id]) {\n if (clicklength < 300 && this.hitLinkElement.type === \"embeddable\" && !(0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_46__.isPointHittingLinkIcon)(this.hitLinkElement, this.state, [scenePointer.x, scenePointer.y])) {\n this.handleEmbeddableCenterClick(this.hitLinkElement);\n } else {\n this.redirectToLink(event, this.device.isTouchScreen);\n }\n } else if (this.state.viewModeEnabled) {\n this.setState({\n activeEmbeddable: null,\n selectedElementIds: {}\n });\n }\n };\n\n this.maybeOpenContextMenuAfterPointerDownOnTouchDevices = event => {\n // deal with opening context menu on touch devices\n if (event.pointerType === \"touch\") {\n invalidateContextMenu = false;\n\n if (touchTimeout) {\n // If there's already a touchTimeout, this means that there's another\n // touch down and we are doing another touch, so we shouldn't open the\n // context menu.\n invalidateContextMenu = true;\n } else {\n // open the context menu with the first touch's clientX and clientY\n // if the touch is not moving\n touchTimeout = window.setTimeout(() => {\n touchTimeout = 0;\n\n if (!invalidateContextMenu) {\n this.handleCanvasContextMenu(event);\n }\n }, _constants__WEBPACK_IMPORTED_MODULE_12__.TOUCH_CTX_MENU_TIMEOUT);\n }\n }\n };\n\n this.resetContextMenuTimer = () => {\n clearTimeout(touchTimeout);\n touchTimeout = 0;\n invalidateContextMenu = false;\n }; // Returns whether the event is a panning\n\n\n this.handleCanvasPanUsingWheelOrSpaceDrag = event => {\n if (!(gesture.pointers.size <= 1 && (event.button === _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.WHEEL || event.button === _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.MAIN && isHoldingSpace || (0,_appState__WEBPACK_IMPORTED_MODULE_10__.isHandToolActive)(this.state) || this.state.viewModeEnabled && !(0,_appState__WEBPACK_IMPORTED_MODULE_10__.isLaserPointerActive)(this.state))) || (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)) {\n return false;\n }\n\n isPanning = true;\n event.preventDefault();\n let nextPastePrevented = false;\n const isLinux = /Linux/.test(window.navigator.platform);\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRABBING);\n let {\n clientX: lastX,\n clientY: lastY\n } = event;\n const onPointerMove = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdatesThrottled)(event => {\n const deltaX = lastX - event.clientX;\n const deltaY = lastY - event.clientY;\n lastX = event.clientX;\n lastY = event.clientY;\n /*\r\n * Prevent paste event if we move while middle clicking on Linux.\r\n * See issue #1383.\r\n */\n\n if (isLinux && !nextPastePrevented && (Math.abs(deltaX) > 1 || Math.abs(deltaY) > 1)) {\n nextPastePrevented = true;\n /* Prevent the next paste event */\n\n const preventNextPaste = event => {\n document.body.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, preventNextPaste);\n event.stopPropagation();\n };\n /*\r\n * Reenable next paste in case of disabled middle click paste for\r\n * any reason:\r\n * - right click paste\r\n * - empty clipboard\r\n */\n\n\n const enableNextPaste = () => {\n setTimeout(() => {\n document.body.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, preventNextPaste);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, enableNextPaste);\n }, 100);\n };\n\n document.body.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, preventNextPaste);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, enableNextPaste);\n }\n\n this.translateCanvas({\n scrollX: this.state.scrollX - deltaX / this.state.zoom.value,\n scrollY: this.state.scrollY - deltaY / this.state.zoom.value\n });\n });\n const teardown = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(lastPointerUp = () => {\n lastPointerUp = null;\n isPanning = false;\n\n if (!isHoldingSpace) {\n if (this.state.viewModeEnabled) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n } else {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursorForShape)(this.interactiveCanvas, this.state);\n }\n }\n\n this.setState({\n cursorButton: \"up\"\n });\n this.savePointer(event.clientX, event.clientY, \"up\");\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, teardown);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.BLUR, teardown);\n onPointerMove.flush();\n });\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.BLUR, teardown);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove, {\n passive: true\n });\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, teardown);\n return true;\n };\n\n this.clearSelectionIfNotUsingSelection = () => {\n if (this.state.activeTool.type !== \"selection\") {\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({}, this.state),\n selectedGroupIds: {},\n editingGroupId: null,\n activeEmbeddable: null\n });\n }\n };\n /**\r\n * @returns whether the pointer event has been completely handled\r\n */\n\n\n this.handleSelectionOnPointerDown = (event, pointerDownState) => {\n var _a;\n\n if (this.state.activeTool.type === \"selection\") {\n const elements = this.scene.getNonDeletedElements();\n const selectedElements = this.scene.getSelectedElements(this.state);\n\n if (selectedElements.length === 1 && !this.state.editingLinearElement) {\n const elementWithTransformHandleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getElementWithTransformHandleType)(elements, this.state, pointerDownState.origin.x, pointerDownState.origin.y, this.state.zoom, event.pointerType);\n\n if (elementWithTransformHandleType != null) {\n this.setState({\n resizingElement: elementWithTransformHandleType.element\n });\n pointerDownState.resize.handleType = elementWithTransformHandleType.transformHandleType;\n }\n } else if (selectedElements.length > 1) {\n pointerDownState.resize.handleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getTransformHandleTypeFromCoords)((0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements), pointerDownState.origin.x, pointerDownState.origin.y, this.state.zoom, event.pointerType);\n }\n\n if (pointerDownState.resize.handleType) {\n pointerDownState.resize.isResizing = true;\n pointerDownState.resize.offset = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.tupleToCoors)((0,_element__WEBPACK_IMPORTED_MODULE_16__.getResizeOffsetXY)(pointerDownState.resize.handleType, selectedElements, pointerDownState.origin.x, pointerDownState.origin.y));\n\n if (selectedElements.length === 1 && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0]) && selectedElements[0].points.length === 2) {\n pointerDownState.resize.arrowDirection = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getResizeArrowDirection)(pointerDownState.resize.handleType, selectedElements[0]);\n }\n } else {\n if (this.state.selectedLinearElement) {\n const linearElementEditor = this.state.editingLinearElement || this.state.selectedLinearElement;\n const ret = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerDown(event, this.state, this.history, pointerDownState.origin, linearElementEditor);\n\n if (ret.hitElement) {\n pointerDownState.hit.element = ret.hitElement;\n }\n\n if (ret.linearElementEditor) {\n this.setState({\n selectedLinearElement: ret.linearElementEditor\n });\n\n if (this.state.editingLinearElement) {\n this.setState({\n editingLinearElement: ret.linearElementEditor\n });\n }\n }\n\n if (ret.didAddPoint) {\n return true;\n }\n } // hitElement may already be set above, so check first\n\n\n pointerDownState.hit.element = (_a = pointerDownState.hit.element) !== null && _a !== void 0 ? _a : this.getElementAtPosition(pointerDownState.origin.x, pointerDownState.origin.y);\n\n if (pointerDownState.hit.element) {\n // Early return if pointer is hitting link icon\n const hitLinkElement = this.getElementLinkAtPosition({\n x: pointerDownState.origin.x,\n y: pointerDownState.origin.y\n }, pointerDownState.hit.element);\n\n if (hitLinkElement) {\n return false;\n }\n } // For overlapped elements one position may hit\n // multiple elements\n\n\n pointerDownState.hit.allHitElements = this.getElementsAtPosition(pointerDownState.origin.x, pointerDownState.origin.y);\n const hitElement = pointerDownState.hit.element;\n const someHitElementIsSelected = pointerDownState.hit.allHitElements.some(element => this.isASelectedElement(element));\n\n if ((hitElement === null || !someHitElementIsSelected) && !event.shiftKey && !pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) {\n this.clearSelection(hitElement);\n }\n\n if (this.state.editingLinearElement) {\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({\n [this.state.editingLinearElement.elementId]: true\n }, this.state)\n }); // If we click on something\n } else if (hitElement != null) {\n // on CMD/CTRL, drill down to hit element regardless of groups etc.\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\n if (!this.state.selectedElementIds[hitElement.id]) {\n pointerDownState.hit.wasAddedToSelection = true;\n }\n\n this.setState(prevState => Object.assign(Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.editGroupForSelectedElement)(prevState, hitElement)), {\n previousSelectedElementIds: this.state.selectedElementIds\n })); // mark as not completely handled so as to allow dragging etc.\n\n return false;\n } // deselect if item is selected\n // if shift is not clicked, this will always return true\n // otherwise, it will trigger selection based on current\n // state of the box\n\n\n if (!this.state.selectedElementIds[hitElement.id]) {\n // if we are currently editing a group, exiting editing mode and deselect the group.\n if (this.state.editingGroupId && !(0,_groups__WEBPACK_IMPORTED_MODULE_23__.isElementInGroup)(hitElement, this.state.editingGroupId)) {\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({}, this.state),\n selectedGroupIds: {},\n editingGroupId: null,\n activeEmbeddable: null\n });\n } // Add hit element to selection. At this point if we're not holding\n // SHIFT the previously selected element(s) were deselected above\n // (make sure you use setState updater to use latest state)\n // With shift-selection, we want to make sure that frames and their containing\n // elements are not selected at the same time.\n\n\n if (!someHitElementIsSelected && !pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) {\n this.setState(prevState => {\n const nextSelectedElementIds = Object.assign(Object.assign({}, prevState.selectedElementIds), {\n [hitElement.id]: true\n });\n const previouslySelectedElements = [];\n Object.keys(prevState.selectedElementIds).forEach(id => {\n const element = this.scene.getElement(id);\n element && previouslySelectedElements.push(element);\n }); // if hitElement is frame, deselect all of its elements if they are selected\n\n if (hitElement.type === \"frame\") {\n (0,_frame__WEBPACK_IMPORTED_MODULE_51__.getFrameElements)(previouslySelectedElements, hitElement.id).forEach(element => {\n delete nextSelectedElementIds[element.id];\n });\n } else if (hitElement.frameId) {\n // if hitElement is in a frame and its frame has been selected\n // disable selection for the given element\n if (nextSelectedElementIds[hitElement.frameId]) {\n delete nextSelectedElementIds[hitElement.id];\n }\n } else {\n // hitElement is neither a frame nor an element in a frame\n // but since hitElement could be in a group with some frames\n // this means selecting hitElement will have the frames selected as well\n // because we want to keep the invariant:\n // - frames and their elements are not selected at the same time\n // we deselect elements in those frames that were previously selected\n const groupIds = hitElement.groupIds;\n const framesInGroups = new Set(groupIds.flatMap(gid => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getElementsInGroup)(this.scene.getNonDeletedElements(), gid)).filter(element => element.type === \"frame\").map(frame => frame.id));\n\n if (framesInGroups.size > 0) {\n previouslySelectedElements.forEach(element => {\n if (element.frameId && framesInGroups.has(element.frameId)) {\n // deselect element and groups containing the element\n delete nextSelectedElementIds[element.id];\n element.groupIds.flatMap(gid => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getElementsInGroup)(this.scene.getNonDeletedElements(), gid)).forEach(element => {\n delete nextSelectedElementIds[element.id];\n });\n }\n });\n }\n }\n\n return Object.assign(Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)({\n editingGroupId: prevState.editingGroupId,\n selectedElementIds: nextSelectedElementIds\n }, this.scene.getNonDeletedElements(), prevState, this)), {\n showHyperlinkPopup: hitElement.link || (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isEmbeddableElement)(hitElement) ? \"info\" : false\n });\n });\n pointerDownState.hit.wasAddedToSelection = true;\n }\n }\n }\n\n this.setState({\n previousSelectedElementIds: this.state.selectedElementIds\n });\n }\n }\n\n return false;\n };\n\n this.handleTextOnPointerDown = (event, pointerDownState) => {\n // if we're currently still editing text, clicking outside\n // should only finalize it, not create another (irrespective\n // of state.activeTool.locked)\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)) {\n return;\n }\n\n let sceneX = pointerDownState.origin.x;\n let sceneY = pointerDownState.origin.y;\n const element = this.getElementAtPosition(sceneX, sceneY, {\n includeBoundTextElement: true\n }); // FIXME\n\n let container = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getTextBindableContainerAtPosition)(this.scene.getNonDeletedElements(), this.state, sceneX, sceneY);\n\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.hasBoundTextElement)(element)) {\n container = element;\n sceneX = element.x + element.width / 2;\n sceneY = element.y + element.height / 2;\n }\n\n this.startTextEditing({\n sceneX,\n sceneY,\n insertAtParentCenter: !event.altKey,\n container\n });\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.resetCursor)(this.interactiveCanvas);\n\n if (!this.state.activeTool.locked) {\n this.setState({\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_33__.updateActiveTool)(this.state, {\n type: \"selection\"\n })\n });\n }\n };\n\n this.handleFreeDrawElementOnPointerDown = (event, elementType, pointerDownState) => {\n // Begin a mark capture. This does not have to update state yet.\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_28__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, null);\n const strokeOptions = this.state.currentStrokeOptions; //zsviczian\n\n const simulatePressure = (strokeOptions === null || strokeOptions === void 0 ? void 0 : strokeOptions.constantPressure) ? false : event.pressure === 0.5;\n const topLayerFrame = this.getTopLayerFrameAtSceneCoords({\n x: gridX,\n y: gridY\n });\n const element = (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.newFreeDrawElement)(Object.assign(Object.assign({\n type: elementType,\n x: gridX,\n y: gridY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n roundness: null,\n simulatePressure,\n locked: false\n }, strokeOptions //zsviczian\n ? {\n customData: {\n strokeOptions\n }\n } : {}), {\n frameId: topLayerFrame ? topLayerFrame.id : null\n }));\n this.setState(prevState => {\n const nextSelectedElementIds = Object.assign({}, prevState.selectedElementIds);\n delete nextSelectedElementIds[element.id];\n return {\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(nextSelectedElementIds, prevState)\n };\n });\n const pressures = element.simulatePressure ? element.pressures : [//zsviczian\n ...element.pressures, (strokeOptions === null || strokeOptions === void 0 ? void 0 : strokeOptions.constantPressure) ? 1 : event.pressure];\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n points: [[0, 0]],\n pressures\n });\n const boundElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerDownState.origin, this.scene);\n\n if (strokeOptions === null || strokeOptions === void 0 ? void 0 : strokeOptions.highlighter) {\n //zsviczian\n this.scene.replaceAllElements([element, ...this.scene.getElementsIncludingDeleted()]);\n } else {\n this.scene.addNewElement(element);\n }\n\n this.setState({\n draggingElement: element,\n editingElement: element,\n startBoundElement: boundElement,\n suggestedBindings: []\n });\n }; //create rectangle element with youtube top left on nearest grid point width / hight 640/360\n\n\n this.insertEmbeddableElement = ({\n sceneX,\n sceneY,\n link\n }) => {\n var _a;\n\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_28__.getGridPoint)(sceneX, sceneY, ((_a = this.lastPointerDownEvent) === null || _a === void 0 ? void 0 : _a[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) ? null : this.state.gridSize);\n const embedLink = (0,_element_embeddable__WEBPACK_IMPORTED_MODULE_34__.getEmbedLink)(link);\n\n if (!embedLink) {\n return;\n }\n\n if (embedLink.warning) {\n this.setToast({\n message: embedLink.warning,\n closable: true\n });\n }\n\n const element = (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.newEmbeddableElement)({\n type: \"embeddable\",\n x: gridX,\n y: gridY,\n strokeColor: \"transparent\",\n backgroundColor: \"transparent\",\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n roundness: this.getCurrentItemRoundness(\"embeddable\"),\n opacity: this.state.currentItemOpacity,\n locked: false,\n width: embedLink.aspectRatio.w,\n height: embedLink.aspectRatio.h,\n link,\n validated: null\n });\n this.scene.replaceAllElements([...this.scene.getElementsIncludingDeleted(), element]);\n return element;\n };\n\n this.createImageElement = ({\n sceneX,\n sceneY\n }) => {\n var _a;\n\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_28__.getGridPoint)(sceneX, sceneY, ((_a = this.lastPointerDownEvent) === null || _a === void 0 ? void 0 : _a[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) ? null : this.state.gridSize);\n const topLayerFrame = this.getTopLayerFrameAtSceneCoords({\n x: gridX,\n y: gridY\n });\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newImageElement)({\n type: \"image\",\n x: gridX,\n y: gridY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n roundness: null,\n opacity: this.state.currentItemOpacity,\n locked: false,\n frameId: topLayerFrame ? topLayerFrame.id : null\n });\n return element;\n };\n\n this.handleLinearElementOnPointerDown = (event, elementType, pointerDownState) => {\n if (this.state.multiElement) {\n const {\n multiElement\n } = this.state; // finalize if completing a loop\n\n if (multiElement.type === \"line\" && (0,_math__WEBPACK_IMPORTED_MODULE_28__.isPathALoop)(multiElement.points, this.state.zoom.value)) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n lastCommittedPoint: multiElement.points[multiElement.points.length - 1]\n });\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n return;\n }\n\n const {\n x: rx,\n y: ry,\n lastCommittedPoint\n } = multiElement; // clicking inside commit zone → finalize arrow\n\n if (multiElement.points.length > 1 && lastCommittedPoint && (0,_math__WEBPACK_IMPORTED_MODULE_28__.distance2d)(pointerDownState.origin.x - rx, pointerDownState.origin.y - ry, lastCommittedPoint[0], lastCommittedPoint[1]) < _constants__WEBPACK_IMPORTED_MODULE_12__.LINE_CONFIRM_THRESHOLD) {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n return;\n }\n\n this.setState(prevState => ({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(Object.assign(Object.assign({}, prevState.selectedElementIds), {\n [multiElement.id]: true\n }), prevState)\n })); // clicking outside commit zone → update reference for last committed\n // point\n\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n lastCommittedPoint: multiElement.points[multiElement.points.length - 1]\n });\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n } else {\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_28__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] ? null : this.state.gridSize);\n const topLayerFrame = this.getTopLayerFrameAtSceneCoords({\n x: gridX,\n y: gridY\n });\n /* If arrow is pre-arrowheads, it will have undefined for both start and end arrowheads.\r\n If so, we want it to be null for start and \"arrow\" for end. If the linear item is not\r\n an arrow, we want it to be null for both. Otherwise, we want it to use the\r\n values from appState. */\n\n const {\n currentItemStartArrowhead,\n currentItemEndArrowhead\n } = this.state;\n const [startArrowhead, endArrowhead] = elementType === \"arrow\" ? [currentItemStartArrowhead, currentItemEndArrowhead] : [null, null];\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newLinearElement)({\n type: elementType,\n x: gridX,\n y: gridY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n roundness: this.state.currentItemRoundness === \"round\" ? {\n type: _constants__WEBPACK_IMPORTED_MODULE_12__.ROUNDNESS.PROPORTIONAL_RADIUS\n } : null,\n startArrowhead,\n endArrowhead,\n locked: false,\n frameId: topLayerFrame ? topLayerFrame.id : null\n });\n this.setState(prevState => {\n const nextSelectedElementIds = Object.assign({}, prevState.selectedElementIds);\n delete nextSelectedElementIds[element.id];\n return {\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(nextSelectedElementIds, prevState)\n };\n });\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n points: [...element.points, [0, 0]]\n });\n const boundElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerDownState.origin, this.scene);\n this.scene.addNewElement(element);\n this.setState({\n draggingElement: element,\n editingElement: element,\n startBoundElement: boundElement,\n suggestedBindings: []\n });\n }\n };\n\n this.createGenericElementOnPointerDown = (elementType, pointerDownState) => {\n var _a;\n\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_28__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, ((_a = this.lastPointerDownEvent) === null || _a === void 0 ? void 0 : _a[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) ? null : this.state.gridSize);\n const topLayerFrame = this.getTopLayerFrameAtSceneCoords({\n x: gridX,\n y: gridY\n });\n const baseElementAttributes = {\n x: gridX,\n y: gridY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n roundness: this.getCurrentItemRoundness(elementType),\n locked: false,\n frameId: topLayerFrame ? topLayerFrame.id : null\n };\n let element;\n\n if (elementType === \"embeddable\") {\n element = (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.newEmbeddableElement)(Object.assign({\n type: \"embeddable\",\n validated: null\n }, baseElementAttributes));\n } else {\n element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newElement)(Object.assign({\n type: elementType\n }, baseElementAttributes));\n }\n\n if (element.type === \"selection\") {\n this.setState({\n selectionElement: element,\n draggingElement: element\n });\n } else {\n this.scene.addNewElement(element);\n this.setState({\n multiElement: null,\n draggingElement: element,\n editingElement: element\n });\n }\n };\n\n this.createFrameElementOnPointerDown = pointerDownState => {\n var _a;\n\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_28__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, ((_a = this.lastPointerDownEvent) === null || _a === void 0 ? void 0 : _a[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) ? null : this.state.gridSize);\n const frame = (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.newFrameElement)(Object.assign({\n x: gridX,\n y: gridY,\n opacity: this.state.currentItemOpacity,\n locked: false\n }, _constants__WEBPACK_IMPORTED_MODULE_12__.FRAME_STYLE));\n this.scene.replaceAllElements([...this.scene.getElementsIncludingDeleted(), frame]);\n this.setState({\n multiElement: null,\n draggingElement: frame,\n editingElement: frame\n });\n };\n\n this.restoreReadyToEraseElements = pointerDownState => {\n const elements = this.scene.getElementsIncludingDeleted().map(ele => {\n if (pointerDownState.elementIdsToErase[ele.id] && pointerDownState.elementIdsToErase[ele.id].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n opacity: pointerDownState.elementIdsToErase[ele.id].opacity\n });\n } else if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(ele) && pointerDownState.elementIdsToErase[ele.containerId] && pointerDownState.elementIdsToErase[ele.containerId].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n opacity: pointerDownState.elementIdsToErase[ele.containerId].opacity\n });\n } else if (ele.frameId && pointerDownState.elementIdsToErase[ele.frameId] && pointerDownState.elementIdsToErase[ele.frameId].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n opacity: pointerDownState.elementIdsToErase[ele.frameId].opacity\n });\n }\n\n return ele;\n });\n this.scene.replaceAllElements(elements);\n };\n\n this.eraseElements = pointerDownState => {\n const elements = this.scene.getElementsIncludingDeleted().map(ele => {\n if (pointerDownState.elementIdsToErase[ele.id] && pointerDownState.elementIdsToErase[ele.id].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n isDeleted: true\n });\n } else if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(ele) && pointerDownState.elementIdsToErase[ele.containerId] && pointerDownState.elementIdsToErase[ele.containerId].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n isDeleted: true\n });\n } else if (ele.frameId && pointerDownState.elementIdsToErase[ele.frameId] && pointerDownState.elementIdsToErase[ele.frameId].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n isDeleted: true\n });\n }\n\n return ele;\n });\n this.history.resumeRecording();\n this.scene.replaceAllElements(elements);\n };\n\n this.initializeImage = async ({\n imageFile,\n imageElement: _imageElement,\n showCursorImagePreview = false\n }) => {\n var _a, _b, _c, _d; // at this point this should be guaranteed image file, but we do this check\n // to satisfy TS down the line\n\n\n if (!(0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.isSupportedImageFile)(imageFile)) {\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.unsupportedFileType\"));\n }\n\n const mimeType = imageFile.type;\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, \"wait\");\n\n if (mimeType === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.svg) {\n try {\n imageFile = (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.SVGStringToFile)(await (0,_element_image__WEBPACK_IMPORTED_MODULE_40__.normalizeSVG)(await imageFile.text()), imageFile.name);\n } catch (error) {\n console.warn(error);\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.svgImageInsertError\"));\n }\n } // generate image id (by default the file digest) before any\n // resizing/compression takes place to keep it more portable\n\n\n const fileId = await (((_b = (_a = this.props).generateIdForFile) === null || _b === void 0 ? void 0 : _b.call(_a, imageFile)) || (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.generateIdFromFile)(imageFile));\n\n if (!fileId) {\n console.warn(\"Couldn't generate file id or the supplied `generateIdForFile` didn't resolve to one.\");\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\"));\n }\n\n const existingFileData = this.files[fileId];\n\n if (!(existingFileData === null || existingFileData === void 0 ? void 0 : existingFileData.dataURL)) {\n try {\n imageFile = await (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.resizeImageFile)(imageFile, {\n maxWidthOrHeight: _constants__WEBPACK_IMPORTED_MODULE_12__.DEFAULT_MAX_IMAGE_WIDTH_OR_HEIGHT\n });\n } catch (error) {\n console.error(\"error trying to resing image file on insertion\", error);\n }\n\n if (imageFile.size > _constants__WEBPACK_IMPORTED_MODULE_12__.MAX_ALLOWED_FILE_BYTES) {\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.fileTooBig\", {\n maxSize: `${Math.trunc(_constants__WEBPACK_IMPORTED_MODULE_12__.MAX_ALLOWED_FILE_BYTES / 1024 / 1024)}MB`\n }));\n }\n }\n\n if (showCursorImagePreview) {\n const dataURL = (_c = this.files[fileId]) === null || _c === void 0 ? void 0 : _c.dataURL; // optimization so that we don't unnecessarily resize the original\n // full-size file for cursor preview\n // (it's much faster to convert the resized dataURL to File)\n\n const resizedFile = dataURL && (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.dataURLToFile)(dataURL);\n this.setImagePreviewCursor(resizedFile || imageFile);\n }\n\n const dataURL = ((_d = this.files[fileId]) === null || _d === void 0 ? void 0 : _d.dataURL) || (await (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.getDataURL)(imageFile));\n const imageElement = (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(_imageElement, {\n fileId\n }, false);\n return new Promise(async (resolve, reject) => {\n var _a;\n\n try {\n this.files = Object.assign(Object.assign({}, this.files), {\n [fileId]: {\n mimeType,\n id: fileId,\n dataURL,\n created: Date.now(),\n lastRetrieved: Date.now()\n }\n });\n const cachedImageData = this.imageCache.get(fileId);\n\n if (!cachedImageData) {\n this.addNewImagesToImageCache();\n await this.updateImageCache([imageElement]);\n }\n\n if ((cachedImageData === null || cachedImageData === void 0 ? void 0 : cachedImageData.image) instanceof Promise) {\n await cachedImageData.image;\n }\n\n if (this.state.pendingImageElementId !== imageElement.id && ((_a = this.state.draggingElement) === null || _a === void 0 ? void 0 : _a.id) !== imageElement.id) {\n this.initializeImageDimensions(imageElement, true);\n }\n\n resolve(imageElement);\n } catch (error) {\n console.error(error);\n reject(new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\")));\n } finally {\n if (!showCursorImagePreview) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.resetCursor)(this.interactiveCanvas);\n }\n }\n });\n };\n /**\r\n * inserts image into elements array and rerenders\r\n */\n\n\n this.insertImageElement = async (imageElement, imageFile, showCursorImagePreview) => {\n this.scene.addNewElement(imageElement);\n\n try {\n return await this.initializeImage({\n imageFile,\n imageElement,\n showCursorImagePreview\n });\n } catch (error) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, {\n isDeleted: true\n });\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n this.setState({\n errorMessage: error.message || (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\")\n });\n return null;\n }\n };\n\n this.setImagePreviewCursor = async imageFile => {\n // mustn't be larger than 128 px\n // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property\n const cursorImageSizePx = 96;\n const imagePreview = await (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.resizeImageFile)(imageFile, {\n maxWidthOrHeight: cursorImageSizePx\n });\n let previewDataURL = await (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.getDataURL)(imagePreview); // SVG cannot be resized via `resizeImageFile` so we resize by rendering to\n // a small canvas\n\n if (imageFile.type === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.svg) {\n const img = await (0,_element_image__WEBPACK_IMPORTED_MODULE_40__.loadHTMLImageElement)(previewDataURL);\n let height = Math.min(img.height, cursorImageSizePx);\n let width = height * (img.width / img.height);\n\n if (width > cursorImageSizePx) {\n width = cursorImageSizePx;\n height = width * (img.height / img.width);\n }\n\n const canvas = document.createElement(\"canvas\");\n canvas.height = height;\n canvas.width = width;\n const context = canvas.getContext(\"2d\");\n context.drawImage(img, 0, 0, width, height);\n previewDataURL = canvas.toDataURL(_constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.svg);\n }\n\n if (this.state.pendingImageElementId) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, `url(${previewDataURL}) 4 4, auto`);\n }\n };\n\n this.onImageAction = async ({\n insertOnCanvasDirectly\n }) => {\n try {\n const clientX = this.state.width / 2 + this.state.offsetLeft;\n const clientY = this.state.height / 2 + this.state.offsetTop;\n const {\n x,\n y\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)({\n clientX,\n clientY\n }, this.state);\n const imageFile = await (0,_data_filesystem__WEBPACK_IMPORTED_MODULE_42__.fileOpen)({\n description: \"Image\",\n extensions: Object.keys(_constants__WEBPACK_IMPORTED_MODULE_12__.IMAGE_MIME_TYPES)\n });\n const imageElement = this.createImageElement({\n sceneX: x,\n sceneY: y\n });\n\n if (insertOnCanvasDirectly) {\n this.insertImageElement(imageElement, imageFile);\n this.initializeImageDimensions(imageElement);\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({\n [imageElement.id]: true\n }, this.state)\n }, () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n });\n } else {\n this.setState({\n pendingImageElementId: imageElement.id\n }, () => {\n this.insertImageElement(imageElement, imageFile,\n /* showCursorImagePreview */\n true);\n });\n }\n } catch (error) {\n if (error.name !== \"AbortError\") {\n console.error(error);\n } else {\n console.warn(error);\n }\n\n this.setState({\n pendingImageElementId: null,\n editingElement: null,\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_33__.updateActiveTool)(this.state, {\n type: \"selection\"\n })\n }, () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n });\n }\n };\n\n this.initializeImageDimensions = (imageElement, forceNaturalSize = false) => {\n var _a;\n\n const image = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(imageElement) && ((_a = this.imageCache.get(imageElement.fileId)) === null || _a === void 0 ? void 0 : _a.image);\n\n if (!image || image instanceof Promise) {\n if (imageElement.width < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD / this.state.zoom.value && imageElement.height < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD / this.state.zoom.value) {\n const placeholderSize = 100 / this.state.zoom.value;\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, {\n x: imageElement.x - placeholderSize / 2,\n y: imageElement.y - placeholderSize / 2,\n width: placeholderSize,\n height: placeholderSize\n });\n }\n\n return;\n }\n\n if (forceNaturalSize || // if user-created bounding box is below threshold, assume the\n // intention was to click instead of drag, and use the image's\n // intrinsic size\n imageElement.width < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD / this.state.zoom.value && imageElement.height < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD / this.state.zoom.value) {\n const minHeight = Math.max(this.state.height - 120, 160); // max 65% of canvas height, clamped to <300px, vh - 120px>\n\n const maxHeight = Math.min(minHeight, Math.floor(this.state.height * 0.5) / this.state.zoom.value);\n const height = Math.min(image.naturalHeight, maxHeight);\n const width = height * (image.naturalWidth / image.naturalHeight); // add current imageElement width/height to account for previous centering\n // of the placeholder image\n\n const x = imageElement.x + imageElement.width / 2 - width / 2;\n const y = imageElement.y + imageElement.height / 2 - height / 2;\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, {\n x,\n y,\n width,\n height\n });\n }\n };\n /** updates image cache, refreshing updated elements and/or setting status\r\n to error for images that fail during <img> element creation */\n\n\n this.updateImageCache = async (elements, files = this.files) => {\n const {\n updatedFiles,\n erroredFiles\n } = await (0,_element_image__WEBPACK_IMPORTED_MODULE_40__.updateImageCache)({\n imageCache: this.imageCache,\n fileIds: elements.map(element => element.fileId),\n files\n });\n\n if (updatedFiles.size || erroredFiles.size) {\n for (const element of elements) {\n if (updatedFiles.has(element.fileId)) {\n _scene_ShapeCache__WEBPACK_IMPORTED_MODULE_66__.ShapeCache[\"delete\"](element);\n }\n }\n }\n\n if (erroredFiles.size) {\n this.scene.replaceAllElements(this.scene.getElementsIncludingDeleted().map(element => {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(element) && erroredFiles.has(element.fileId)) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(element, {\n status: \"error\"\n });\n }\n\n return element;\n }));\n }\n\n return {\n updatedFiles,\n erroredFiles\n };\n };\n /** adds new images to imageCache and re-renders if needed */\n\n\n this.addNewImagesToImageCache = async (imageElements = (0,_element_image__WEBPACK_IMPORTED_MODULE_40__.getInitializedImageElements)(this.scene.getNonDeletedElements()), files = this.files) => {\n const uncachedImageElements = imageElements.filter(element => !element.isDeleted && !this.imageCache.has(element.fileId));\n\n if (uncachedImageElements.length) {\n const {\n updatedFiles\n } = await this.updateImageCache(uncachedImageElements, files);\n\n if (updatedFiles.size) {\n this.scene.informMutation();\n }\n }\n };\n /** generally you should use `addNewImagesToImageCache()` directly if you need\r\n * to render new images. This is just a failsafe */\n\n\n this.scheduleImageRefresh = lodash_throttle__WEBPACK_IMPORTED_MODULE_41___default()(() => {\n this.addNewImagesToImageCache();\n }, _constants__WEBPACK_IMPORTED_MODULE_12__.IMAGE_RENDER_TIMEOUT);\n\n this.updateBindingEnabledOnPointerMove = event => {\n const shouldEnableBinding = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.shouldEnableBindingForPointerEvent)(event);\n\n if (this.state.isBindingEnabled !== shouldEnableBinding) {\n this.setState({\n isBindingEnabled: shouldEnableBinding\n });\n }\n };\n\n this.maybeSuggestBindingAtCursor = pointerCoords => {\n const hoveredBindableElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerCoords, this.scene);\n this.setState({\n suggestedBindings: hoveredBindableElement != null ? [hoveredBindableElement] : []\n });\n };\n\n this.maybeSuggestBindingsForLinearElementAtCoords = (linearElement,\n /** scene coords */\n pointerCoords, // During line creation the start binding hasn't been written yet\n // into `linearElement`\n oppositeBindingBoundElement) => {\n if (!pointerCoords.length) {\n return;\n }\n\n const suggestedBindings = pointerCoords.reduce((acc, coords) => {\n const hoveredBindableElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(coords, this.scene);\n\n if (hoveredBindableElement != null && !(0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isLinearElementSimpleAndAlreadyBound)(linearElement, oppositeBindingBoundElement === null || oppositeBindingBoundElement === void 0 ? void 0 : oppositeBindingBoundElement.id, hoveredBindableElement)) {\n acc.push(hoveredBindableElement);\n }\n\n return acc;\n }, []);\n this.setState({\n suggestedBindings\n });\n };\n\n this.handleInteractiveCanvasRef = canvas => {\n var _a, _b, _c; // canvas is null when unmounting\n\n\n if (canvas !== null) {\n this.interactiveCanvas = canvas; // -----------------------------------------------------------------------\n // NOTE wheel, touchstart, touchend events must be registered outside\n // of react because react binds them them passively (so we can't prevent\n // default on them)\n\n this.interactiveCanvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.WHEEL, this.handleWheel);\n this.interactiveCanvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.TOUCH_START, this.onTouchStart);\n this.interactiveCanvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.TOUCH_END, this.onTouchEnd); // -----------------------------------------------------------------------\n } else {\n (_a = this.interactiveCanvas) === null || _a === void 0 ? void 0 : _a.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.WHEEL, this.handleWheel);\n (_b = this.interactiveCanvas) === null || _b === void 0 ? void 0 : _b.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.TOUCH_START, this.onTouchStart);\n (_c = this.interactiveCanvas) === null || _c === void 0 ? void 0 : _c.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.TOUCH_END, this.onTouchEnd);\n }\n };\n\n this.handleAppOnDrop = async event => {\n var _a, _b, _c, _d;\n\n if (this.props.onDrop) {\n try {\n if ((await this.props.onDrop(event)) === false) {\n return;\n }\n } catch (e) {\n console.error(e);\n }\n } // must be retrieved first, in the same frame\n\n\n const {\n file,\n fileHandle\n } = await (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.getFileFromEvent)(event);\n const {\n x: sceneX,\n y: sceneY\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)(event, this.state);\n\n try {\n if ((0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.isSupportedImageFile)(file)) {\n // first attempt to decode scene from the image if it's embedded\n // ---------------------------------------------------------------------\n if ((file === null || file === void 0 ? void 0 : file.type) === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.png || (file === null || file === void 0 ? void 0 : file.type) === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.svg) {\n try {\n const scene = await (0,_data__WEBPACK_IMPORTED_MODULE_13__.loadFromBlob)(file, this.state, this.scene.getElementsIncludingDeleted(), fileHandle);\n this.syncActionResult(Object.assign(Object.assign({}, scene), {\n appState: Object.assign(Object.assign({}, scene.appState || this.state), {\n isLoading: false\n }),\n replaceFiles: true,\n commitToHistory: true\n }));\n return;\n } catch (error) {\n if (error.name !== \"EncodingError\") {\n throw error;\n }\n }\n } // if no scene is embedded or we fail for whatever reason, fall back\n // to importing as regular image\n // ---------------------------------------------------------------------\n\n\n const imageElement = this.createImageElement({\n sceneX,\n sceneY\n });\n this.insertImageElement(imageElement, file);\n this.initializeImageDimensions(imageElement);\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({\n [imageElement.id]: true\n }, this.state)\n });\n return;\n }\n } catch (error) {\n return this.setState({\n isLoading: false,\n errorMessage: error.message\n });\n }\n\n const libraryJSON = event.dataTransfer.getData(_constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.excalidrawlib);\n\n if (libraryJSON && typeof libraryJSON === \"string\") {\n try {\n const libraryItems = (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.parseLibraryJSON)(libraryJSON);\n this.addElementsFromPasteOrLibrary({\n elements: (0,_data_library__WEBPACK_IMPORTED_MODULE_14__.distributeLibraryItemsOnSquareGrid)(libraryItems),\n position: event,\n files: null\n });\n } catch (error) {\n this.setState({\n errorMessage: error.message\n });\n }\n\n return;\n }\n\n if (file) {\n // atetmpt to parse an excalidraw/excalidrawlib file\n await this.loadFileToCanvas(file, fileHandle);\n }\n\n if ((_b = (_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.types) === null || _b === void 0 ? void 0 : _b.includes(\"text/plain\")) {\n const text = (_c = event.dataTransfer) === null || _c === void 0 ? void 0 : _c.getData(\"text\");\n\n if (text && (0,_element_embeddable__WEBPACK_IMPORTED_MODULE_34__.embeddableURLValidator)(text, this.props.validateEmbeddable) && (/^(http|https):\\/\\/[^\\s/$.?#].[^\\s]*$/.test(text) || ((_d = (0,_element_embeddable__WEBPACK_IMPORTED_MODULE_34__.getEmbedLink)(text)) === null || _d === void 0 ? void 0 : _d.type) === \"video\")) {\n const embeddable = this.insertEmbeddableElement({\n sceneX,\n sceneY,\n link: (0,_data_url__WEBPACK_IMPORTED_MODULE_47__.normalizeLink)(text)\n });\n\n if (embeddable) {\n this.setState({\n selectedElementIds: {\n [embeddable.id]: true\n }\n });\n }\n }\n }\n };\n\n this.loadFileToCanvas = async (file, fileHandle) => {\n file = await (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.normalizeFile)(file);\n\n try {\n const ret = await (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.loadSceneOrLibraryFromBlob)(file, this.state, this.scene.getElementsIncludingDeleted(), fileHandle);\n\n if (ret.type === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.excalidraw) {\n this.setState({\n isLoading: true\n });\n this.syncActionResult(Object.assign(Object.assign({}, ret.data), {\n appState: Object.assign(Object.assign({}, ret.data.appState || this.state), {\n isLoading: false\n }),\n replaceFiles: true,\n commitToHistory: true\n }));\n } else if (ret.type === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.excalidrawlib) {\n await this.library.updateLibrary({\n libraryItems: file,\n merge: true,\n openLibraryMenu: true\n }).catch(error => {\n console.error(error);\n this.setState({\n errorMessage: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.importLibraryError\")\n });\n });\n }\n } catch (error) {\n this.setState({\n isLoading: false,\n errorMessage: error.message\n });\n }\n };\n\n this.handleCanvasContextMenu = event => {\n event.preventDefault();\n\n if ((\"pointerType\" in event.nativeEvent && event.nativeEvent.pointerType === \"touch\" || \"pointerType\" in event.nativeEvent && event.nativeEvent.pointerType === \"pen\" && // always allow if user uses a pen secondary button\n event.button !== _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.SECONDARY) && this.state.activeTool.type !== \"selection\") {\n return;\n }\n\n const {\n x,\n y\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)(event, this.state);\n const element = this.getElementAtPosition(x, y, {\n preferSelected: true,\n includeLockedElements: true\n });\n const selectedElements = this.scene.getSelectedElements(this.state);\n const isHittignCommonBoundBox = this.isHittingCommonBoundingBoxOfSelectedElements({\n x,\n y\n }, selectedElements);\n const type = element || isHittignCommonBoundBox ? \"element\" : \"canvas\";\n const container = this.excalidrawContainerRef.current;\n const {\n top: offsetTop,\n left: offsetLeft\n } = container.getBoundingClientRect();\n const left = event.clientX - offsetLeft;\n const top = event.clientY - offsetTop;\n (0,_analytics__WEBPACK_IMPORTED_MODULE_9__.trackEvent)(\"contextMenu\", \"openContextMenu\", type);\n this.setState(Object.assign(Object.assign({}, element && !this.state.selectedElementIds[element.id] ? Object.assign(Object.assign(Object.assign({}, this.state), (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)({\n editingGroupId: this.state.editingGroupId,\n selectedElementIds: {\n [element.id]: true\n }\n }, this.scene.getNonDeletedElements(), this.state, this)), {\n selectedLinearElement: (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(element) ? new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(element, this.scene) : null\n }) : this.state), {\n showHyperlinkPopup: false\n }), () => {\n this.setState({\n contextMenu: {\n top,\n left,\n items: this.getContextMenuItems(type)\n }\n });\n });\n };\n\n this.maybeDragNewGenericElement = (pointerDownState, event) => {\n var _a, _b, _c, _d, _e;\n\n const draggingElement = this.state.draggingElement;\n const pointerCoords = pointerDownState.lastCoords;\n\n if (!draggingElement) {\n return;\n }\n\n if (draggingElement.type === \"selection\" && this.state.activeTool.type !== \"eraser\") {\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragNewElement)(draggingElement, this.state.activeTool.type, pointerDownState.origin.x, pointerDownState.origin.y, pointerCoords.x, pointerCoords.y, (0,_utils__WEBPACK_IMPORTED_MODULE_33__.distance)(pointerDownState.origin.x, pointerCoords.x), (0,_utils__WEBPACK_IMPORTED_MODULE_33__.distance)(pointerDownState.origin.y, pointerCoords.y), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldResizeFromCenter)(event));\n } else {\n let [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_28__.getGridPoint)(pointerCoords.x, pointerCoords.y, event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] ? null : this.state.gridSize);\n const image = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(draggingElement) && ((_a = this.imageCache.get(draggingElement.fileId)) === null || _a === void 0 ? void 0 : _a.image);\n const aspectRatio = image && !(image instanceof Promise) ? image.width / image.height : null;\n this.maybeCacheReferenceSnapPoints(event, [draggingElement]);\n const {\n snapOffset,\n snapLines\n } = (0,_snapping__WEBPACK_IMPORTED_MODULE_58__.snapNewElement)(draggingElement, this.state, event, {\n x: pointerDownState.originInGrid.x + ((_c = (_b = this.state.originSnapOffset) === null || _b === void 0 ? void 0 : _b.x) !== null && _c !== void 0 ? _c : 0),\n y: pointerDownState.originInGrid.y + ((_e = (_d = this.state.originSnapOffset) === null || _d === void 0 ? void 0 : _d.y) !== null && _e !== void 0 ? _e : 0)\n }, {\n x: gridX - pointerDownState.originInGrid.x,\n y: gridY - pointerDownState.originInGrid.y\n });\n gridX += snapOffset.x;\n gridY += snapOffset.y;\n this.setState({\n snapLines\n });\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragNewElement)(draggingElement, this.state.activeTool.type, pointerDownState.originInGrid.x, pointerDownState.originInGrid.y, gridX, gridY, (0,_utils__WEBPACK_IMPORTED_MODULE_33__.distance)(pointerDownState.originInGrid.x, gridX), (0,_utils__WEBPACK_IMPORTED_MODULE_33__.distance)(pointerDownState.originInGrid.y, gridY), (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(draggingElement) ? !(0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event) : (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldResizeFromCenter)(event), aspectRatio, this.state.originSnapOffset);\n this.maybeSuggestBindingForAll([draggingElement]); // highlight elements that are to be added to frames on frames creation\n\n if (this.state.activeTool.type === \"frame\") {\n this.setState({\n elementsToHighlight: (0,_frame__WEBPACK_IMPORTED_MODULE_51__.getElementsInResizingFrame)(this.scene.getNonDeletedElements(), draggingElement, this.state)\n });\n }\n }\n };\n\n this.maybeHandleResize = (pointerDownState, event) => {\n const selectedElements = this.scene.getSelectedElements(this.state);\n const selectedFrames = selectedElements.filter(element => element.type === \"frame\");\n const transformHandleType = pointerDownState.resize.handleType;\n\n if (selectedFrames.length > 0 && transformHandleType === \"rotation\") {\n return false;\n }\n\n this.setState({\n // TODO: rename this state field to \"isScaling\" to distinguish\n // it from the generic \"isResizing\" which includes scaling and\n // rotating\n isResizing: transformHandleType && transformHandleType !== \"rotation\",\n isRotating: transformHandleType === \"rotation\",\n activeEmbeddable: null\n });\n const pointerCoords = pointerDownState.lastCoords;\n let [resizeX, resizeY] = (0,_math__WEBPACK_IMPORTED_MODULE_28__.getGridPoint)(pointerCoords.x - pointerDownState.resize.offset.x, pointerCoords.y - pointerDownState.resize.offset.y, event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] ? null : this.state.gridSize);\n const frameElementsOffsetsMap = new Map();\n selectedFrames.forEach(frame => {\n const elementsInFrame = (0,_frame__WEBPACK_IMPORTED_MODULE_51__.getFrameElements)(this.scene.getNonDeletedElements(), frame.id);\n elementsInFrame.forEach(element => {\n frameElementsOffsetsMap.set(frame.id + element.id, {\n x: element.x - frame.x,\n y: element.y - frame.y\n });\n });\n }); // check needed for avoiding flickering when a key gets pressed\n // during dragging\n\n if (!this.state.selectedElementsAreBeingDragged) {\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_28__.getGridPoint)(pointerCoords.x, pointerCoords.y, event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] ? null : this.state.gridSize);\n const dragOffset = {\n x: gridX - pointerDownState.originInGrid.x,\n y: gridY - pointerDownState.originInGrid.y\n };\n const originalElements = [...pointerDownState.originalElements.values()];\n this.maybeCacheReferenceSnapPoints(event, selectedElements);\n const {\n snapOffset,\n snapLines\n } = (0,_snapping__WEBPACK_IMPORTED_MODULE_58__.snapResizingElements)(selectedElements, (0,_scene__WEBPACK_IMPORTED_MODULE_29__.getSelectedElements)(originalElements, this.state), this.state, event, dragOffset, transformHandleType);\n resizeX += snapOffset.x;\n resizeY += snapOffset.y;\n this.setState({\n snapLines\n });\n }\n\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.transformElements)(pointerDownState, transformHandleType, selectedElements, pointerDownState.resize.arrowDirection, (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldRotateWithDiscreteAngle)(event), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldResizeFromCenter)(event), selectedElements.length === 1 && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(selectedElements[0]) ? !(0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event) : (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event), resizeX, resizeY, pointerDownState.resize.center.x, pointerDownState.resize.center.y, this.state)) {\n this.maybeSuggestBindingForAll(selectedElements);\n const elementsToHighlight = new Set();\n selectedFrames.forEach(frame => {\n const elementsInFrame = (0,_frame__WEBPACK_IMPORTED_MODULE_51__.getFrameElements)(this.scene.getNonDeletedElements(), frame.id); // keep elements' positions relative to their frames on frames resizing\n\n if (transformHandleType) {\n if (transformHandleType.includes(\"w\")) {\n elementsInFrame.forEach(element => {\n var _a, _b;\n\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n x: frame.x + (((_a = frameElementsOffsetsMap.get(frame.id + element.id)) === null || _a === void 0 ? void 0 : _a.x) || 0),\n y: frame.y + (((_b = frameElementsOffsetsMap.get(frame.id + element.id)) === null || _b === void 0 ? void 0 : _b.y) || 0)\n });\n });\n }\n\n if (transformHandleType.includes(\"n\")) {\n elementsInFrame.forEach(element => {\n var _a, _b;\n\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n x: frame.x + (((_a = frameElementsOffsetsMap.get(frame.id + element.id)) === null || _a === void 0 ? void 0 : _a.x) || 0),\n y: frame.y + (((_b = frameElementsOffsetsMap.get(frame.id + element.id)) === null || _b === void 0 ? void 0 : _b.y) || 0)\n });\n });\n }\n }\n\n (0,_frame__WEBPACK_IMPORTED_MODULE_51__.getElementsInResizingFrame)(this.scene.getNonDeletedElements(), frame, this.state).forEach(element => elementsToHighlight.add(element));\n });\n this.setState({\n elementsToHighlight: [...elementsToHighlight]\n });\n return true;\n }\n\n return false;\n };\n\n this.getContextMenuItems = type => {\n const options = [];\n options.push(_actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsPng, _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsSvg); // canvas contextMenu\n // -------------------------------------------------------------------------\n\n if (type === \"canvas\") {\n if (this.state.viewModeEnabled) {\n return [...options, _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleGridMode, _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleZenMode, _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_38__.actionToggleViewMode, _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleStats, _actions_actionCanvas__WEBPACK_IMPORTED_MODULE_55__.actionToggleLaserPointer];\n }\n\n return [_actions_actionClipboard__WEBPACK_IMPORTED_MODULE_53__.actionPaste, _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR, _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsPng, _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsSvg, _actions__WEBPACK_IMPORTED_MODULE_5__.copyText, _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR, _actions__WEBPACK_IMPORTED_MODULE_5__.actionSelectAll, _actions_actionElementLock__WEBPACK_IMPORTED_MODULE_49__.actionUnlockAllElements, _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR, _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleGridMode, _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleObjectsSnapMode, _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleZenMode, _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_38__.actionToggleViewMode, _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleStats];\n } // element contextMenu\n // -------------------------------------------------------------------------\n\n\n options.push(_actions__WEBPACK_IMPORTED_MODULE_5__.copyText);\n\n if (this.state.viewModeEnabled) {\n return [_actions__WEBPACK_IMPORTED_MODULE_5__.actionCopy, ...options];\n }\n\n return [_actions__WEBPACK_IMPORTED_MODULE_5__.actionCut, _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopy, _actions_actionClipboard__WEBPACK_IMPORTED_MODULE_53__.actionPaste, _actions_actionFrame__WEBPACK_IMPORTED_MODULE_54__.actionSelectAllElementsInFrame, _actions_actionFrame__WEBPACK_IMPORTED_MODULE_54__.actionRemoveAllElementsFromFrame, _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR, ...options, _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR, _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyStyles, _actions__WEBPACK_IMPORTED_MODULE_5__.actionPasteStyles, _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR, _actions__WEBPACK_IMPORTED_MODULE_5__.actionGroup, _actions__WEBPACK_IMPORTED_MODULE_5__.actionUnbindText, _actions__WEBPACK_IMPORTED_MODULE_5__.actionBindText, _actions_actionBoundText__WEBPACK_IMPORTED_MODULE_59__.actionWrapTextInContainer, _actions__WEBPACK_IMPORTED_MODULE_5__.actionUngroup, _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR, _actions__WEBPACK_IMPORTED_MODULE_5__.actionAddToLibrary, _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR, _actions__WEBPACK_IMPORTED_MODULE_5__.actionSendBackward, _actions__WEBPACK_IMPORTED_MODULE_5__.actionBringForward, _actions__WEBPACK_IMPORTED_MODULE_5__.actionSendToBack, _actions__WEBPACK_IMPORTED_MODULE_5__.actionBringToFront, _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR, _actions__WEBPACK_IMPORTED_MODULE_5__.actionFlipHorizontal, _actions__WEBPACK_IMPORTED_MODULE_5__.actionFlipVertical, _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR, _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleLinearEditor, _actions__WEBPACK_IMPORTED_MODULE_5__.actionLink, _actions__WEBPACK_IMPORTED_MODULE_5__.actionDuplicateSelection, _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleElementLock, _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR, _actions__WEBPACK_IMPORTED_MODULE_5__.actionDeleteSelected];\n };\n\n this.handleWheel = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(event => {\n event.preventDefault();\n\n if (isPanning) {\n return;\n }\n\n const {\n deltaX,\n deltaY\n } = event; // note that event.ctrlKey is necessary to handle pinch zooming\n\n if ( //zsviczian\n (event.metaKey || event.ctrlKey) && !this.state.allowWheelZoom || !(event.metaKey || event.ctrlKey) && this.state.allowWheelZoom) {\n const sign = Math.sign(deltaY);\n const MAX_STEP = _constants__WEBPACK_IMPORTED_MODULE_12__.ZOOM_STEP * 100;\n const absDelta = Math.abs(deltaY);\n let delta = deltaY;\n\n if (absDelta > MAX_STEP) {\n delta = MAX_STEP * sign;\n }\n\n let newZoom = this.state.zoom.value - delta / 100; // increase zoom steps the more zoomed-in we are (applies to >100% only)\n\n newZoom += Math.log10(Math.max(1, this.state.zoom.value)) * -sign * // reduced amplification for small deltas (small movements on a trackpad)\n Math.min(1, absDelta / 20);\n this.translateCanvas(state => Object.assign(Object.assign({}, (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_31__.getStateForZoom)({\n viewportX: this.lastViewportPosition.x,\n viewportY: this.lastViewportPosition.y,\n nextZoom: (0,_scene__WEBPACK_IMPORTED_MODULE_29__.getNormalizedZoom)(newZoom)\n }, state)), {\n shouldCacheIgnoreZoom: true\n }));\n this.resetShouldCacheIgnoreZoomDebounced();\n return;\n } // scroll horizontally when shift pressed\n\n\n if (event.shiftKey) {\n this.translateCanvas(({\n zoom,\n scrollX\n }) => ({\n // on Mac, shift+wheel tends to result in deltaX\n scrollX: scrollX - (deltaY || deltaX) / zoom.value\n }));\n return;\n }\n\n this.translateCanvas(({\n zoom,\n scrollX,\n scrollY\n }) => ({\n scrollX: scrollX - deltaX / zoom.value,\n scrollY: scrollY - deltaY / zoom.value\n }));\n });\n\n this.savePointer = (x, y, button) => {\n var _a, _b;\n\n if (!x || !y) {\n return;\n }\n\n const {\n x: sceneX,\n y: sceneY\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)({\n clientX: x,\n clientY: y\n }, this.state);\n\n if (isNaN(sceneX) || isNaN(sceneY)) {// sometimes the pointer goes off screen\n }\n\n const pointer = {\n x: sceneX,\n y: sceneY,\n tool: this.state.activeTool.type === \"laser\" ? \"laser\" : \"pointer\"\n };\n (_b = (_a = this.props).onPointerUpdate) === null || _b === void 0 ? void 0 : _b.call(_a, {\n pointer,\n button,\n pointersMap: gesture.pointers\n });\n };\n\n this.resetShouldCacheIgnoreZoomDebounced = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.debounce)(() => {\n if (!this.unmounted) {\n this.setState({\n shouldCacheIgnoreZoom: false\n });\n }\n }, 300);\n\n this.updateDOMRect = cb => {\n var _a;\n\n if ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current) {\n const excalidrawContainer = this.excalidrawContainerRef.current;\n const {\n width,\n height,\n left: offsetLeft,\n top: offsetTop\n } = excalidrawContainer.getBoundingClientRect();\n const {\n width: currentWidth,\n height: currentHeight,\n offsetTop: currentOffsetTop,\n offsetLeft: currentOffsetLeft\n } = this.state;\n\n if (width === currentWidth && height === currentHeight && offsetLeft === currentOffsetLeft && offsetTop === currentOffsetTop) {\n if (cb) {\n cb();\n }\n\n return;\n } //zsviczian\n\n\n if (width === 0 || height === 0) {\n if (cb) {\n cb();\n }\n\n return;\n }\n\n this.setState({\n width,\n height,\n offsetLeft,\n offsetTop\n }, () => {\n cb && cb();\n });\n }\n };\n\n this.refresh = () => {\n this.setState(Object.assign({}, this.getCanvasOffsets()));\n };\n\n const defaultAppState = (0,_appState__WEBPACK_IMPORTED_MODULE_10__.getDefaultAppState)();\n const {\n excalidrawRef,\n viewModeEnabled = false,\n zenModeEnabled = false,\n gridModeEnabled = false,\n objectsSnapModeEnabled = false,\n theme = defaultAppState.theme,\n name = defaultAppState.name,\n initState //zsviczian\n\n } = props;\n this.state = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, defaultAppState), {\n theme,\n isLoading: true\n }), this.getCanvasOffsets()), {\n viewModeEnabled,\n zenModeEnabled,\n objectsSnapModeEnabled,\n gridSize: gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_12__.GRID_SIZE : null,\n name,\n width: window.innerWidth,\n height: window.innerHeight\n }), initState !== null && initState !== void 0 ? initState : {});\n this.id = (0,nanoid__WEBPACK_IMPORTED_MODULE_72__.nanoid)();\n this.library = new _data_library__WEBPACK_IMPORTED_MODULE_14__[\"default\"](this);\n this.scene = new _scene_Scene__WEBPACK_IMPORTED_MODULE_30__[\"default\"]();\n this.canvas = document.createElement(\"canvas\");\n this.rc = roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_3__[\"default\"].canvas(this.canvas);\n this.renderer = new _scene_Renderer__WEBPACK_IMPORTED_MODULE_65__.Renderer(this.scene);\n\n if (excalidrawRef) {\n const readyPromise = \"current\" in excalidrawRef && ((_a = excalidrawRef.current) === null || _a === void 0 ? void 0 : _a.readyPromise) || (0,_utils__WEBPACK_IMPORTED_MODULE_33__.resolvablePromise)();\n const api = {\n ready: true,\n readyPromise,\n updateScene: this.updateScene,\n updateLibrary: this.library.updateLibrary,\n addFiles: this.addFiles,\n resetScene: this.resetScene,\n getSceneElementsIncludingDeleted: this.getSceneElementsIncludingDeleted,\n history: {\n clear: this.resetHistory\n },\n scrollToContent: this.scrollToContent,\n zoomToFit: this.zoomToFit,\n startLineEditor: this.startLineEditor,\n getSceneElements: this.getSceneElements,\n getAppState: () => this.state,\n getFiles: () => this.files,\n refresh: this.refresh,\n setToast: this.setToast,\n updateContainerSize: this.updateContainerSize,\n id: this.id,\n setLocalFont: this.setLocalFont,\n selectElements: this.selectElements,\n sendBackward: this.sendBackward,\n bringForward: this.bringForward,\n sendToBack: this.sendToBack,\n bringToFront: this.bringToFront,\n setMobileModeAllowed: this.setMobileModeAllowed,\n setActiveTool: this.setActiveTool,\n setCursor: this.setCursor,\n resetCursor: this.resetCursor,\n updateFrameRendering: this.updateFrameRendering,\n toggleSidebar: this.toggleSidebar,\n getHTMLIFrameElement: id => this.getHTMLIFrameElement(id),\n onChange: cb => this.onChangeEmitter.on(cb),\n onPointerDown: cb => this.onPointerDownEmitter.on(cb),\n onPointerUp: cb => this.onPointerUpEmitter.on(cb)\n };\n\n if (typeof excalidrawRef === \"function\") {\n excalidrawRef(api);\n } else {\n excalidrawRef.current = api;\n }\n\n readyPromise.resolve(api);\n }\n\n this.excalidrawContainerValue = {\n container: this.excalidrawContainerRef.current,\n id: this.id\n };\n this.fonts = new _scene_Fonts__WEBPACK_IMPORTED_MODULE_50__.Fonts({\n scene: this.scene,\n onSceneUpdated: this.onSceneUpdated\n });\n this.history = new _history__WEBPACK_IMPORTED_MODULE_24__[\"default\"]();\n this.actionManager = new _actions_manager__WEBPACK_IMPORTED_MODULE_7__.ActionManager(this.syncActionResult, () => this.state, () => this.scene.getElementsIncludingDeleted(), this);\n this.actionManager.registerAll(_actions_register__WEBPACK_IMPORTED_MODULE_8__.actions);\n this.actionManager.registerAction((0,_actions_actionHistory__WEBPACK_IMPORTED_MODULE_6__.createUndoAction)(this.history));\n this.actionManager.registerAction((0,_actions_actionHistory__WEBPACK_IMPORTED_MODULE_6__.createRedoAction)(this.history));\n }\n\n onWindowMessage(event) {\n if (event.origin !== \"https://player.vimeo.com\" && event.origin !== \"https://www.youtube.com\") {\n return;\n }\n\n let data = null;\n\n try {\n data = JSON.parse(event.data);\n } catch (e) {}\n\n if (!data) {\n return;\n }\n\n switch (event.origin) {\n case \"https://player.vimeo.com\":\n //Allowing for multiple instances of Excalidraw running in the window\n if (data.method === \"paused\") {\n let source = null;\n const iframes = document.body.querySelectorAll(\"iframe.excalidraw__embeddable\");\n\n if (!iframes) {\n break;\n }\n\n for (const iframe of iframes) {\n if (iframe.contentWindow === event.source) {\n source = iframe.contentWindow;\n }\n }\n\n source === null || source === void 0 ? void 0 : source.postMessage(JSON.stringify({\n method: data.value ? \"play\" : \"pause\",\n value: true\n }), \"*\");\n }\n\n break;\n\n case \"https://www.youtube.com\":\n if (data.event === \"infoDelivery\" && data.info && data.id && typeof data.info.playerState === \"number\") {\n const id = data.id;\n const playerState = data.info.playerState;\n\n if (Object.values(_constants__WEBPACK_IMPORTED_MODULE_12__.YOUTUBE_STATES).includes(playerState)) {\n YOUTUBE_VIDEO_STATES.set(id, playerState);\n }\n }\n\n break;\n }\n }\n\n updateEmbeddableRef(id, ref) {\n if (ref) {\n this.iFrameRefs.set(id, ref);\n }\n }\n\n getHTMLIFrameElement(id) {\n return this.iFrameRefs.get(id);\n }\n\n handleEmbeddableCenterClick(element) {\n var _a, _b, _c, _d;\n\n if (((_a = this.state.activeEmbeddable) === null || _a === void 0 ? void 0 : _a.element) === element && ((_b = this.state.activeEmbeddable) === null || _b === void 0 ? void 0 : _b.state) === \"active\") {\n return;\n } // The delay serves two purposes\n // 1. To prevent first click propagating to iframe on mobile,\n // else the click will immediately start and stop the video\n // 2. If the user double clicks the frame center to activate it\n // without the delay youtube will immediately open the video\n // in fullscreen mode\n\n\n setTimeout(() => {\n this.setState({\n activeEmbeddable: {\n element,\n state: \"active\"\n },\n selectedElementIds: {\n [element.id]: true\n },\n draggingElement: null,\n selectionElement: null\n });\n }, 100);\n const iframe = this.getHTMLIFrameElement(element.id);\n\n if (!(iframe === null || iframe === void 0 ? void 0 : iframe.contentWindow)) {\n return;\n }\n\n if (iframe.src.includes(\"youtube\")) {\n const state = YOUTUBE_VIDEO_STATES.get(element.id);\n\n if (!state) {\n YOUTUBE_VIDEO_STATES.set(element.id, _constants__WEBPACK_IMPORTED_MODULE_12__.YOUTUBE_STATES.UNSTARTED);\n iframe.contentWindow.postMessage(JSON.stringify({\n event: \"listening\",\n id: element.id\n }), \"*\");\n }\n\n switch (state) {\n case _constants__WEBPACK_IMPORTED_MODULE_12__.YOUTUBE_STATES.PLAYING:\n case _constants__WEBPACK_IMPORTED_MODULE_12__.YOUTUBE_STATES.BUFFERING:\n (_c = iframe.contentWindow) === null || _c === void 0 ? void 0 : _c.postMessage(JSON.stringify({\n event: \"command\",\n func: \"pauseVideo\",\n args: \"\"\n }), \"*\");\n break;\n\n default:\n (_d = iframe.contentWindow) === null || _d === void 0 ? void 0 : _d.postMessage(JSON.stringify({\n event: \"command\",\n func: \"playVideo\",\n args: \"\"\n }), \"*\");\n }\n }\n\n if (iframe.src.includes(\"player.vimeo.com\")) {\n iframe.contentWindow.postMessage(JSON.stringify({\n method: \"paused\" //video play/pause in onWindowMessage handler\n\n }), \"*\");\n }\n }\n\n isEmbeddableCenter(el, event, sceneX, sceneY) {\n var _a, _b;\n\n return el && !event.altKey && !event.shiftKey && !event.metaKey && !event.ctrlKey && (((_a = this.state.activeEmbeddable) === null || _a === void 0 ? void 0 : _a.element) !== el || ((_b = this.state.activeEmbeddable) === null || _b === void 0 ? void 0 : _b.state) === \"hover\" || !this.state.activeEmbeddable) && sceneX >= el.x + el.width / 3 && sceneX <= el.x + 2 * el.width / 3 && sceneY >= el.y + el.height / 3 && sceneY <= el.y + 2 * el.height / 3;\n }\n\n renderEmbeddables() {\n const scale = this.state.zoom.value;\n const normalizedWidth = this.state.width;\n const normalizedHeight = this.state.height;\n const embeddableElements = this.scene.getNonDeletedElements().filter(el => (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isEmbeddableElement)(el) && !!el.validated);\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n children: embeddableElements.map(el => {\n var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;\n\n const {\n x,\n y\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.sceneCoordsToViewportCoords)({\n sceneX: el.x,\n sceneY: el.y\n }, this.state);\n const embedLink = (0,_element_embeddable__WEBPACK_IMPORTED_MODULE_34__.getEmbedLink)((0,_data_url__WEBPACK_IMPORTED_MODULE_47__.toValidURL)(el.link || \"\"));\n const isVisible = (0,_element_sizeHelpers__WEBPACK_IMPORTED_MODULE_27__.isElementInViewport)(el, normalizedWidth, normalizedHeight, this.state);\n const isActive = ((_a = this.state.activeEmbeddable) === null || _a === void 0 ? void 0 : _a.element) === el && ((_b = this.state.activeEmbeddable) === null || _b === void 0 ? void 0 : _b.state) === \"active\";\n const isHovered = ((_c = this.state.activeEmbeddable) === null || _c === void 0 ? void 0 : _c.element) === el && ((_d = this.state.activeEmbeddable) === null || _d === void 0 ? void 0 : _d.state) === \"hover\";\n const isWebview = //zsviczian\n this.props.renderWebview && (embedLink === null || embedLink === void 0 ? void 0 : embedLink.type) !== \"document\" && !((_f = (_e = embedLink === null || embedLink === void 0 ? void 0 : embedLink.link) === null || _e === void 0 ? void 0 : _e.startsWith) === null || _f === void 0 ? void 0 : _f.call(_e, \"https://player.vimeo.com\"));\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", Object.assign({\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_4__[\"default\"])(\"excalidraw__embeddable-container\", {\n \"is-hovered\": isHovered\n }),\n style: {\n transform: isVisible ? `translate(${x - this.state.offsetLeft}px, ${y - this.state.offsetTop}px) scale(${scale})` : \"none\",\n display: isVisible ? \"block\" : \"none\",\n opacity: el.opacity / 100,\n [\"--embeddable-radius\"]: `${(0,_math__WEBPACK_IMPORTED_MODULE_28__.getCornerRadius)(Math.min(el.width, el.height), el)}px`\n }\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"div\", Object.assign({\n //this is a hack that addresses isse with embedded excalidraw.com embeddable\n //https://github.com/excalidraw/excalidraw/pull/6691#issuecomment-1607383938\n\n /*ref={(ref) => {\r\n if (!this.excalidrawContainerRef.current) {\r\n return;\r\n }\r\n const container = this.excalidrawContainerRef.current;\r\n const sh = container.scrollHeight;\r\n const ch = container.clientHeight;\r\n if (sh !== ch) {\r\n container.style.height = `${sh}px`;\r\n setTimeout(() => {\r\n container.style.height = `100%`;\r\n });\r\n }\r\n }}*/\n className: \"excalidraw__embeddable-container__inner\",\n style: {\n width: isVisible ? `${el.width}px` : 0,\n height: isVisible ? `${el.height}px` : 0,\n transform: isVisible ? `rotate(${el.angle}rad)` : \"none\",\n pointerEvents: isActive ? _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_EVENTS.enabled : _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_EVENTS.disabled\n }\n }, {\n children: [isHovered && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", Object.assign({\n className: \"excalidraw__embeddable-hint\"\n }, {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"buttons.embeddableInteractionButton\")\n })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", Object.assign({\n className: \"excalidraw__embeddable__outer\",\n style: {\n padding: `${el.strokeWidth}px`\n }\n }, {\n children: (_j = (_h = (_g = this.props).renderEmbeddable) === null || _h === void 0 ? void 0 : _h.call(_g, el, this.state)) !== null && _j !== void 0 ? _j : isWebview ? (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"webview\", {\n ref: ref => this.updateEmbeddableRef(el.id, ref),\n className: \"excalidraw__embeddable\",\n src: (_k = embedLink === null || embedLink === void 0 ? void 0 : embedLink.link) !== null && _k !== void 0 ? _k : \"\",\n title: \"Excalidraw Embedded Content\",\n allowFullScreen: true\n }) : (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"iframe\", {\n ref: ref => this.updateEmbeddableRef(el.id, ref),\n className: \"excalidraw__embeddable\",\n srcDoc: (embedLink === null || embedLink === void 0 ? void 0 : embedLink.type) === \"document\" ? embedLink.srcdoc(this.state.theme) : undefined,\n src: (embedLink === null || embedLink === void 0 ? void 0 : embedLink.type) !== \"document\" ? (_l = embedLink === null || embedLink === void 0 ? void 0 : embedLink.link) !== null && _l !== void 0 ? _l : \"\" : undefined,\n // https://stackoverflow.com/q/18470015\n scrolling: \"no\",\n referrerPolicy: \"no-referrer-when-downgrade\",\n title: \"Excalidraw Embedded Content\",\n allow: \"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\",\n allowFullScreen: true,\n sandbox: \"allow-same-origin allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation allow-downloads\"\n })\n }))]\n }))\n }), el.id);\n })\n });\n }\n\n render() {\n var _a, _b, _c, _d, _e, _f;\n\n const selectedElements = this.scene.getSelectedElements(this.state);\n const {\n renderTopRightUI,\n renderCustomStats\n } = this.props;\n const versionNonce = this.scene.getVersionNonce();\n const {\n canvasElements,\n visibleElements\n } = this.renderer.getRenderableElements({\n versionNonce,\n zoom: this.state.zoom,\n offsetLeft: this.state.offsetLeft,\n offsetTop: this.state.offsetTop,\n scrollX: this.state.scrollX,\n scrollY: this.state.scrollY,\n height: this.state.height,\n width: this.state.width,\n editingElement: this.state.editingElement,\n pendingImageElementId: this.state.pendingImageElementId\n });\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", Object.assign({\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_4__[\"default\"])(\"excalidraw excalidraw-container\", {\n \"excalidraw--view-mode\": this.state.viewModeEnabled,\n \"excalidraw--mobile\": this.device.isMobile || !(this.state.viewModeEnabled || this.state.zenModeEnabled) && this.state.trayModeEnabled //zsviczian\n\n }),\n style: {\n [\"--ui-pointerEvents\"]: this.state.selectionElement || this.state.draggingElement || this.state.resizingElement || this.state.activeTool.type === \"laser\" && // technically we can just test on this once we make it more safe\n this.state.cursorButton === \"down\" || this.state.editingElement && !(0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement) ? _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_EVENTS.disabled : _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_EVENTS.enabled\n },\n ref: this.excalidrawContainerRef,\n onDrop: this.handleAppOnDrop,\n tabIndex: 0,\n onKeyDown: this.props.handleKeyboardGlobally ? undefined : this.onKeyDown\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(AppContext.Provider, Object.assign({\n value: this\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(AppPropsContext.Provider, Object.assign({\n value: this.props\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(ExcalidrawContainerContext.Provider, Object.assign({\n value: this.excalidrawContainerValue\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(DeviceContext.Provider, Object.assign({\n value: this.device\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(ExcalidrawSetAppStateContext.Provider, Object.assign({\n value: this.setAppState\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(ExcalidrawAppStateContext.Provider, Object.assign({\n value: this.state\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(ExcalidrawElementsContext.Provider, Object.assign({\n value: this.scene.getNonDeletedElements()\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(ExcalidrawActionManagerContext.Provider, Object.assign({\n value: this.actionManager\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(_LayerUI__WEBPACK_IMPORTED_MODULE_36__[\"default\"], Object.assign({\n canvas: this.canvas,\n appState: this.state,\n files: this.files,\n setAppState: this.setAppState,\n actionManager: this.actionManager,\n elements: this.scene.getNonDeletedElements(),\n onLockToggle: this.toggleLock,\n onPenModeToggle: this.togglePenMode,\n onHandToolToggle: this.onHandToolToggle,\n langCode: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.getLanguage)().code,\n renderTopRightUI: renderTopRightUI,\n renderCustomStats: renderCustomStats,\n showExitZenModeBtn: typeof ((_a = this.props) === null || _a === void 0 ? void 0 : _a.zenModeEnabled) === \"undefined\" && this.state.zenModeEnabled,\n UIOptions: this.props.UIOptions,\n onExportImage: this.onExportImage,\n renderWelcomeScreen: !this.state.isLoading && this.state.showWelcomeScreen && this.state.activeTool.type === \"selection\" && !this.state.zenModeEnabled && !this.scene.getElementsIncludingDeleted().length,\n app: this,\n isCollaborating: this.props.isCollaborating\n }, {\n children: [this.props.children, this.props.renderMermaid && this.state.activeTool.type === \"mermaid\" && //zsviczian\n (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_MermaidToExcalidraw__WEBPACK_IMPORTED_MODULE_67__[\"default\"], {\n selectedElements: this.scene.getSelectedElements(this.state)\n })]\n })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", {\n className: \"excalidraw-textEditorContainer\"\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", {\n className: \"excalidraw-contextMenuContainer\"\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", {\n className: \"excalidraw-eye-dropper-container\"\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_LaserTool_LaserTool__WEBPACK_IMPORTED_MODULE_68__.LaserToolOverlay, {\n manager: this.laserPathManager\n }), selectedElements.length === 1 && !this.state.contextMenu && this.state.showHyperlinkPopup && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_element_Hyperlink__WEBPACK_IMPORTED_MODULE_46__.Hyperlink, {\n element: selectedElements[0],\n setAppState: this.setAppState,\n onLinkOpen: this.props.onLinkOpen,\n setToast: this.setToast\n }, selectedElements[0].id), this.state.toast !== null && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Toast__WEBPACK_IMPORTED_MODULE_37__.Toast, {\n message: this.state.toast.message,\n onClose: () => this.setToast(null),\n duration: this.state.toast.duration,\n closable: this.state.toast.closable\n }), this.state.contextMenu && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_ContextMenu__WEBPACK_IMPORTED_MODULE_35__.ContextMenu, {\n items: this.state.contextMenu.items,\n top: this.state.contextMenu.top,\n left: this.state.contextMenu.left,\n actionManager: this.actionManager\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_canvases__WEBPACK_IMPORTED_MODULE_64__.StaticCanvas, {\n canvas: this.canvas,\n rc: this.rc,\n elements: canvasElements,\n visibleElements: visibleElements,\n versionNonce: versionNonce,\n selectionNonce: (_b = this.state.selectionElement) === null || _b === void 0 ? void 0 : _b.versionNonce,\n scale: window.devicePixelRatio,\n appState: this.state,\n renderConfig: {\n imageCache: this.imageCache,\n isExporting: false,\n renderGrid: true\n }\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_canvases__WEBPACK_IMPORTED_MODULE_64__.InteractiveCanvas, {\n containerRef: this.excalidrawContainerRef,\n canvas: this.interactiveCanvas,\n elements: canvasElements,\n visibleElements: visibleElements,\n selectedElements: selectedElements,\n versionNonce: versionNonce,\n selectionNonce: (_c = this.state.selectionElement) === null || _c === void 0 ? void 0 : _c.versionNonce,\n scale: window.devicePixelRatio,\n appState: this.state,\n renderInteractiveSceneCallback: this.renderInteractiveSceneCallback,\n handleCanvasRef: this.handleInteractiveCanvasRef,\n onContextMenu: this.handleCanvasContextMenu,\n onPointerMove: this.handleCanvasPointerMove,\n onPointerUp: this.handleCanvasPointerUp,\n onPointerCancel: this.removePointer,\n onTouchMove: this.handleTouchMove,\n onPointerDown: this.handleCanvasPointerDown,\n onDoubleClick: this.handleCanvasDoubleClick\n }), this.renderFrameNames(), ((_d = this.state.activeEmbeddable) === null || _d === void 0 ? void 0 : _d.state) === \"active\" && ( //zsviczian\n (_f = (_e = this.props).renderEmbeddableMenu) === null || _f === void 0 ? void 0 : _f.call(_e, this.state))]\n })), this.renderEmbeddables()]\n }))\n }))\n }))\n }))\n }))\n }))\n }))\n }));\n }\n\n async componentDidMount() {\n var _a, _b;\n\n this.unmounted = false;\n this.excalidrawContainerValue.container = this.excalidrawContainerRef.current;\n\n if (\"development\" === _constants__WEBPACK_IMPORTED_MODULE_12__.ENV.TEST || \"development\" !== \"production\") {\n const setState = this.setState.bind(this);\n Object.defineProperties(window.h, {\n state: {\n configurable: true,\n get: () => {\n return this.state;\n }\n },\n setState: {\n configurable: true,\n value: (...args) => {\n return this.setState(...args);\n }\n },\n app: {\n configurable: true,\n value: this\n },\n history: {\n configurable: true,\n value: this.history\n }\n });\n }\n\n this.scene.addCallback(this.onSceneUpdated);\n this.addEventListeners();\n\n if (this.props.autoFocus && this.excalidrawContainerRef.current) {\n this.focusContainer();\n }\n\n if (this.excalidrawContainerRef.current && // bounding rects don't work in tests so updating\n // the state on init would result in making the test enviro run\n // in mobile breakpoint (0 width/height), making everything fail\n !(0,_utils__WEBPACK_IMPORTED_MODULE_33__.isTestEnv)()) {\n this.refreshDeviceState(this.excalidrawContainerRef.current);\n }\n\n if (\"ResizeObserver\" in window && ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current)) {\n this.resizeObserver = new ResizeObserver(() => {\n // recompute device dimensions state\n // ---------------------------------------------------------------------\n this.refreshDeviceState(this.excalidrawContainerRef.current); // refresh offsets\n // ---------------------------------------------------------------------\n\n this.updateDOMRect();\n });\n (_b = this.resizeObserver) === null || _b === void 0 ? void 0 : _b.observe(this.excalidrawContainerRef.current);\n } else if (window.matchMedia) {\n const mdScreenQuery = window.matchMedia(`(max-width: ${_constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_PORTRAIT}px), (max-height: ${_constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_HEIGHT_LANDSCAPE}px) and (max-width: ${_constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_LANDSCAPE}px)`);\n const smScreenQuery = window.matchMedia(`(max-width: ${_constants__WEBPACK_IMPORTED_MODULE_12__.MQ_SM_MAX_WIDTH}px)`);\n const canDeviceFitSidebarMediaQuery = window.matchMedia(`(min-width: ${// NOTE this won't update if a different breakpoint is supplied\n // after mount\n this.props.UIOptions.dockedSidebarBreakpoint != null ? this.props.UIOptions.dockedSidebarBreakpoint : _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_RIGHT_SIDEBAR_MIN_WIDTH}px)`);\n\n const handler = () => {\n this.excalidrawContainerRef.current.getBoundingClientRect();\n this.device = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.updateObject)(this.device, {\n isSmScreen: smScreenQuery.matches,\n isMobile: mdScreenQuery.matches && this.allowMobileMode,\n canDeviceFitSidebar: canDeviceFitSidebarMediaQuery.matches\n });\n };\n\n mdScreenQuery.addListener(handler);\n\n this.detachIsMobileMqHandler = () => mdScreenQuery.removeListener(handler);\n }\n\n const searchParams = new URLSearchParams(window.location.search.slice(1));\n\n if (searchParams.has(\"web-share-target\")) {\n // Obtain a file that was shared via the Web Share Target API.\n this.restoreFileFromShare();\n } else {\n this.updateDOMRect(this.initializeScene);\n } // note that this check seems to always pass in localhost\n\n\n if ((0,_constants__WEBPACK_IMPORTED_MODULE_12__.isBrave)() && !(0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.isMeasureTextSupported)()) {\n this.setState({\n errorMessage: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_BraveMeasureTextError__WEBPACK_IMPORTED_MODULE_60__[\"default\"], {})\n });\n }\n }\n\n componentWillUnmount() {\n var _a;\n\n this.renderer.destroy();\n this.scene = new _scene_Scene__WEBPACK_IMPORTED_MODULE_30__[\"default\"]();\n this.renderer = new _scene_Renderer__WEBPACK_IMPORTED_MODULE_65__.Renderer(this.scene);\n this.files = {};\n this.imageCache.clear();\n (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();\n this.unmounted = true;\n this.removeEventListeners();\n this.scene.destroy();\n this.library.destroy();\n this.laserPathManager.destroy();\n this.onChangeEmitter.destroy();\n _scene_ShapeCache__WEBPACK_IMPORTED_MODULE_66__.ShapeCache.destroy();\n _snapping__WEBPACK_IMPORTED_MODULE_58__.SnapCache.destroy();\n clearTimeout(touchTimeout);\n _scene__WEBPACK_IMPORTED_MODULE_29__.isSomeElementSelected.clearCache();\n _groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements.clearCache();\n touchTimeout = 0;\n }\n\n removeEventListeners() {\n var _a, _b, _c, _d, _e;\n\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, this.removePointer);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.COPY, this.onCopy);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, this.pasteFromClipboard);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.CUT, this.onCut);\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.WHEEL, this.onWheel);\n (_b = this.nearestScrollableContainer) === null || _b === void 0 ? void 0 : _b.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.SCROLL, this.onScroll);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYDOWN, this.onKeyDown, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.MOUSE_MOVE, this.updateCurrentCursorPosition, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYUP, this.onKeyUp);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.RESIZE, this.onResize, false);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.UNLOAD, this.onUnload, false);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.BLUR, this.onBlur, false);\n (_c = this.excalidrawContainerRef.current) === null || _c === void 0 ? void 0 : _c.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.DRAG_OVER, this.disableEvent, false);\n (_d = this.excalidrawContainerRef.current) === null || _d === void 0 ? void 0 : _d.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.DROP, this.disableEvent, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_START, this.onGestureStart, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_CHANGE, this.onGestureChange, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_END, this.onGestureEnd, false);\n (_e = this.detachIsMobileMqHandler) === null || _e === void 0 ? void 0 : _e.call(this);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.MESSAGE, this.onWindowMessage, false);\n }\n\n addEventListeners() {\n var _a, _b, _c, _d, _e;\n\n this.removeEventListeners();\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.MESSAGE, this.onWindowMessage, false);\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, this.removePointer); // #3553\n\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.COPY, this.onCopy);\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.WHEEL, this.onWheel, {\n passive: false\n });\n\n if (this.props.handleKeyboardGlobally) {\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYDOWN, this.onKeyDown, false);\n }\n\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYUP, this.onKeyUp, {\n passive: true\n });\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.MOUSE_MOVE, this.updateCurrentCursorPosition); // rerender text elements on font load to fix #637 && #1553\n\n (_c = (_b = document.fonts) === null || _b === void 0 ? void 0 : _b.addEventListener) === null || _c === void 0 ? void 0 : _c.call(_b, \"loadingdone\", event => {\n const loadedFontFaces = event.fontfaces;\n this.fonts.onFontsLoaded(loadedFontFaces);\n }); // Safari-only desktop pinch zoom\n\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_START, this.onGestureStart, false);\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_CHANGE, this.onGestureChange, false);\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_END, this.onGestureEnd, false);\n\n if (this.state.viewModeEnabled) {\n return;\n }\n\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, this.pasteFromClipboard);\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.CUT, this.onCut);\n\n if (this.props.detectScroll) {\n this.nearestScrollableContainer = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.getNearestScrollableContainer)(this.excalidrawContainerRef.current);\n this.nearestScrollableContainer.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.SCROLL, this.onScroll);\n }\n\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.RESIZE, this.onResize, false);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.UNLOAD, this.onUnload, false);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.BLUR, this.onBlur, false);\n (_d = this.excalidrawContainerRef.current) === null || _d === void 0 ? void 0 : _d.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.DRAG_OVER, this.disableEvent, false);\n (_e = this.excalidrawContainerRef.current) === null || _e === void 0 ? void 0 : _e.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.DROP, this.disableEvent, false);\n }\n\n componentDidUpdate(prevProps, prevState) {\n var _a, _b, _c, _d, _e, _f;\n\n this.updateEmbeddables();\n\n if (!this.state.showWelcomeScreen && !this.scene.getElementsIncludingDeleted().length) {\n this.setState({\n showWelcomeScreen: true\n });\n }\n\n if (this.excalidrawContainerRef.current && prevProps.UIOptions.dockedSidebarBreakpoint !== this.props.UIOptions.dockedSidebarBreakpoint) {\n this.refreshDeviceState(this.excalidrawContainerRef.current);\n }\n\n if (prevState.scrollX !== this.state.scrollX || prevState.scrollY !== this.state.scrollY) {\n (_b = (_a = this.props) === null || _a === void 0 ? void 0 : _a.onScrollChange) === null || _b === void 0 ? void 0 : _b.call(_a, this.state.scrollX, this.state.scrollY);\n }\n\n if (Object.keys(this.state.selectedElementIds).length && (0,_appState__WEBPACK_IMPORTED_MODULE_10__.isEraserActive)(this.state)) {\n this.setState({\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_33__.updateActiveTool)(this.state, {\n type: \"selection\"\n })\n });\n }\n\n if (this.state.activeTool.type === \"eraser\" && prevState.theme !== this.state.theme) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setEraserCursor)(this.interactiveCanvas, this.state.theme);\n } // Hide hyperlink popup if shown when element type is not selection\n\n\n if (prevState.activeTool.type === \"selection\" && this.state.activeTool.type !== \"selection\" && this.state.showHyperlinkPopup) {\n this.setState({\n showHyperlinkPopup: false\n });\n }\n\n if (prevProps.langCode !== this.props.langCode) {\n this.updateLanguage();\n }\n\n if (prevProps.viewModeEnabled !== this.props.viewModeEnabled) {\n this.setState({\n viewModeEnabled: !!this.props.viewModeEnabled\n });\n }\n\n if (prevState.viewModeEnabled !== this.state.viewModeEnabled) {\n this.addEventListeners();\n this.deselectElements();\n }\n\n if (prevProps.zenModeEnabled !== this.props.zenModeEnabled) {\n this.setState({\n zenModeEnabled: !!this.props.zenModeEnabled\n });\n }\n\n if (prevProps.theme !== this.props.theme && this.props.theme) {\n this.setState({\n theme: this.props.theme\n });\n }\n\n if (prevProps.gridModeEnabled !== this.props.gridModeEnabled) {\n this.setState({\n gridSize: this.props.gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_12__.GRID_SIZE : null\n });\n }\n\n if (this.props.name && prevProps.name !== this.props.name) {\n this.setState({\n name: this.props.name\n });\n }\n\n (_c = this.excalidrawContainerRef.current) === null || _c === void 0 ? void 0 : _c.classList.toggle(\"theme--dark\", this.state.theme === \"dark\");\n\n if (this.state.editingLinearElement && !this.state.selectedElementIds[this.state.editingLinearElement.elementId]) {\n // defer so that the commitToHistory flag isn't reset via current update\n setTimeout(() => {\n // execute only if the condition still holds when the deferred callback\n // executes (it can be scheduled multiple times depending on how\n // many times the component renders)\n this.state.editingLinearElement && this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n });\n } // failsafe in case the state is being updated in incorrect order resulting\n // in the editingElement being now a deleted element\n\n\n if ((_d = this.state.editingElement) === null || _d === void 0 ? void 0 : _d.isDeleted) {\n this.setState({\n editingElement: null\n });\n }\n\n if (this.state.selectedLinearElement && !this.state.selectedElementIds[this.state.selectedLinearElement.elementId]) {\n // To make sure `selectedLinearElement` is in sync with `selectedElementIds`, however this shouldn't be needed once\n // we have a single API to update `selectedElementIds`\n this.setState({\n selectedLinearElement: null\n });\n }\n\n const {\n multiElement\n } = prevState;\n\n if (prevState.activeTool !== this.state.activeTool && multiElement != null && (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state) && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(multiElement, false)) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.maybeBindLinearElement)(multiElement, this.state, this.scene, (0,_utils__WEBPACK_IMPORTED_MODULE_33__.tupleToCoors)(_element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.getPointAtIndexGlobalCoordinates(multiElement, -1)));\n }\n\n this.history.record(this.state, this.scene.getElementsIncludingDeleted()); // Do not notify consumers if we're still loading the scene. Among other\n // potential issues, this fixes a case where the tab isn't focused during\n // init, which would trigger onChange with empty elements, which would then\n // override whatever is in localStorage currently.\n\n if (!this.state.isLoading) {\n (_f = (_e = this.props).onChange) === null || _f === void 0 ? void 0 : _f.call(_e, this.scene.getElementsIncludingDeleted(), this.state, this.files);\n this.onChangeEmitter.trigger(this.scene.getElementsIncludingDeleted(), this.state, this.files);\n }\n }\n\n static resetTapTwice() {\n didTapTwice = false;\n } // TODO rewrite this to paste both text & images at the same time if\n // pasted data contains both\n\n\n async addElementsFromMixedContentPaste(mixedContent, {\n isPlainPaste,\n sceneX,\n sceneY\n }) {\n if (!isPlainPaste && mixedContent.some(node => node.type === \"imageUrl\")) {\n const imageURLs = mixedContent.filter(node => node.type === \"imageUrl\").map(node => node.value);\n const responses = await Promise.all(imageURLs.map(async url => {\n try {\n return {\n file: await (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.ImageURLToFile)(url)\n };\n } catch (error) {\n return {\n errorMessage: error.message\n };\n }\n }));\n let y = sceneY;\n let firstImageYOffsetDone = false;\n const nextSelectedIds = {};\n\n for (const response of responses) {\n if (response.file) {\n const imageElement = this.createImageElement({\n sceneX,\n sceneY: y\n });\n const initializedImageElement = await this.insertImageElement(imageElement, response.file);\n\n if (initializedImageElement) {\n // vertically center first image in the batch\n if (!firstImageYOffsetDone) {\n firstImageYOffsetDone = true;\n y -= initializedImageElement.height / 2;\n } // hack to reset the `y` coord because we vertically center during\n // insertImageElement\n\n\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(initializedImageElement, {\n y\n }, false);\n y = imageElement.y + imageElement.height + 25;\n nextSelectedIds[imageElement.id] = true;\n }\n }\n }\n\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(nextSelectedIds, this.state)\n });\n const error = responses.find(response => !!response.errorMessage);\n\n if (error && error.errorMessage) {\n this.setState({\n errorMessage: error.errorMessage\n });\n }\n } else {\n const textNodes = mixedContent.filter(node => node.type === \"text\");\n\n if (textNodes.length) {\n this.addTextFromPaste(textNodes.map(node => node.value).join(\"\\n\\n\"), isPlainPaste);\n }\n }\n }\n\n addTextFromPaste(text, isPlainPaste = false) {\n const {\n x,\n y\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)({\n clientX: this.lastViewportPosition.x,\n clientY: this.lastViewportPosition.y\n }, this.state);\n const textElementProps = {\n x,\n y,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roundness: null,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n text,\n rawText: text,\n fontSize: this.state.currentItemFontSize,\n fontFamily: this.state.currentItemFontFamily,\n textAlign: this.state.currentItemTextAlign,\n verticalAlign: _constants__WEBPACK_IMPORTED_MODULE_12__.DEFAULT_VERTICAL_ALIGN,\n locked: false\n };\n const LINE_GAP = 10;\n let currentY = y;\n const lines = isPlainPaste ? [text] : text.split(\"\\n\");\n const textElements = lines.reduce((acc, line, idx) => {\n var _a;\n\n const text = line.trim();\n const lineHeight = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getDefaultLineHeight)(textElementProps.fontFamily);\n\n if (text.length) {\n const topLayerFrame = this.getTopLayerFrameAtSceneCoords({\n x,\n y: currentY\n });\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newTextElement)(Object.assign(Object.assign({}, textElementProps), {\n x,\n y: currentY,\n text,\n rawText: text,\n //zsviczian\n lineHeight,\n frameId: topLayerFrame ? topLayerFrame.id : null\n }));\n acc.push(element);\n currentY += element.height + LINE_GAP;\n } else {\n const prevLine = (_a = lines[idx - 1]) === null || _a === void 0 ? void 0 : _a.trim(); // add paragraph only if previous line was not empty, IOW don't add\n // more than one empty line\n\n if (prevLine) {\n currentY += (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getLineHeightInPx)(textElementProps.fontSize, lineHeight) + LINE_GAP;\n }\n }\n\n return acc;\n }, []);\n\n if (textElements.length === 0) {\n return;\n }\n\n const frameId = textElements[0].frameId;\n\n if (frameId) {\n this.scene.insertElementsAtIndex(textElements, this.scene.getElementIndex(frameId));\n } else {\n this.scene.replaceAllElements([...this.scene.getElementsIncludingDeleted(), ...textElements]);\n }\n\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(Object.fromEntries(textElements.map(el => [el.id, true])), this.state)\n });\n\n if (!isPlainPaste && textElements.length > 1 && PLAIN_PASTE_TOAST_SHOWN === false && !this.device.isMobile) {\n this.setToast({\n message: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"toast.pasteAsSingleElement\", {\n shortcut: (0,_utils__WEBPACK_IMPORTED_MODULE_33__.getShortcutKey)(\"CtrlOrCmd+Shift+V\")\n }),\n duration: 5000\n });\n PLAIN_PASTE_TOAST_SHOWN = true;\n }\n\n this.history.resumeRecording();\n }\n\n handleTextWysiwyg(element, {\n isExistingElement = false\n }) {\n const updateElement = (text, originalText, isDeleted, rawText, link) => {\n this.scene.replaceAllElements([...this.scene.getElementsIncludingDeleted().map(_element => {\n if (_element.id === element.id && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(_element)) {\n return (0,_element__WEBPACK_IMPORTED_MODULE_16__.updateTextElement)(_element, {\n text,\n isDeleted,\n originalText,\n rawText: rawText !== null && rawText !== void 0 ? rawText : originalText,\n link\n });\n }\n\n return _element;\n })]);\n };\n\n if (isExistingElement && this.props.onBeforeTextEdit) {\n const text = this.props.onBeforeTextEdit(element);\n\n if (text) {\n this.scene.replaceAllElements([...this.scene.getElementsIncludingDeleted().map(_element => {\n if (_element.id === element.id && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(_element)) {\n element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.updateTextElement)(_element, {\n text,\n isDeleted: false,\n originalText: text\n });\n return element;\n }\n\n return _element;\n })]);\n }\n }\n\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.textWysiwyg)({\n id: element.id,\n canvas: this.canvas,\n getViewportCoords: (x, y) => {\n const {\n x: viewportX,\n y: viewportY\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.sceneCoordsToViewportCoords)({\n sceneX: x,\n sceneY: y\n }, this.state);\n return [viewportX - this.state.offsetLeft, viewportY - this.state.offsetTop];\n },\n onChange: (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(text => {\n updateElement(text, text, false);\n\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isNonDeletedElement)(element)) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.updateBoundElements)(element);\n }\n }),\n onSubmit: (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(({\n text,\n viaKeyboard,\n originalText\n }) => {\n const isDeleted = !text.trim();\n const rawText = originalText; //should this be originalText??\n\n let link = undefined;\n\n if (this.props.onBeforeTextSubmit) {\n const [updatedText, updatedOriginalText, l] = this.props.onBeforeTextSubmit(element, text, originalText, isDeleted);\n text = updatedText !== null && updatedText !== void 0 ? updatedText : text;\n originalText = updatedOriginalText !== null && updatedOriginalText !== void 0 ? updatedOriginalText : originalText;\n link = l;\n }\n\n updateElement(text, originalText, isDeleted, rawText, link); // select the created text element only if submitting via keyboard\n // (when submitting via click it should act as signal to deselect)\n\n if (!isDeleted && viaKeyboard) {\n const elementIdToSelect = element.containerId ? element.containerId : element.id;\n this.setState(prevState => ({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(Object.assign(Object.assign({}, prevState.selectedElementIds), {\n [elementIdToSelect]: true\n }), prevState)\n }));\n }\n\n if (isDeleted) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDeletion)(this.scene.getNonDeletedElements(), [element]);\n }\n\n if (!isDeleted || isExistingElement) {\n this.history.resumeRecording();\n }\n\n this.setState({\n draggingElement: null,\n editingElement: null\n });\n\n if (this.state.activeTool.locked) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursorForShape)(this.interactiveCanvas, this.state);\n }\n\n this.focusContainer();\n }),\n element,\n excalidrawContainer: this.excalidrawContainerRef.current,\n app: this\n }); // deselect all other elements when inserting text\n\n this.deselectElements(); // do an initial update to re-initialize element position since we were\n // modifying element's x/y for sake of editor (case: syncing to remote)\n\n updateElement(element.text, element.originalText, false);\n }\n\n deselectElements() {\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({}, this.state),\n selectedGroupIds: {},\n editingGroupId: null,\n activeEmbeddable: null\n });\n }\n\n getTextElementAtPosition(x, y) {\n const element = this.getElementAtPosition(x, y, {\n includeBoundTextElement: true\n });\n\n if (element && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element) && !element.isDeleted) {\n return element;\n }\n\n return null;\n }\n\n getElementAtPosition(x, y, opts) {\n const allHitElements = this.getElementsAtPosition(x, y, opts === null || opts === void 0 ? void 0 : opts.includeBoundTextElement, opts === null || opts === void 0 ? void 0 : opts.includeLockedElements);\n\n if (allHitElements.length > 1) {\n if (opts === null || opts === void 0 ? void 0 : opts.preferSelected) {\n for (let index = allHitElements.length - 1; index > -1; index--) {\n if (this.state.selectedElementIds[allHitElements[index].id]) {\n return allHitElements[index];\n }\n }\n }\n\n const elementWithHighestZIndex = allHitElements[allHitElements.length - 1]; // If we're hitting element with highest z-index only on its bounding box\n // while also hitting other element figure, the latter should be considered.\n\n return (0,_element__WEBPACK_IMPORTED_MODULE_16__.isHittingElementBoundingBoxWithoutHittingElement)(elementWithHighestZIndex, this.state, this.frameNameBoundsCache, x, y) ? allHitElements[allHitElements.length - 2] : elementWithHighestZIndex;\n }\n\n if (allHitElements.length === 1) {\n return allHitElements[0];\n }\n\n return null;\n }\n\n getElementsAtPosition(x, y, includeBoundTextElement = false, includeLockedElements = false) {\n const elements = includeBoundTextElement && includeLockedElements ? this.scene.getNonDeletedElements() : this.scene.getNonDeletedElements().filter(element => (includeLockedElements || !element.locked) && (includeBoundTextElement || !((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element) && element.containerId)));\n return (0,_scene__WEBPACK_IMPORTED_MODULE_29__.getElementsAtPosition)(elements, element => (0,_element__WEBPACK_IMPORTED_MODULE_16__.hitTest)(element, this.state, this.frameNameBoundsCache, x, y)).filter(element => {\n // hitting a frame's element from outside the frame is not considered a hit\n const containingFrame = (0,_frame__WEBPACK_IMPORTED_MODULE_51__.getContainingFrame)(element);\n return containingFrame && this.state.frameRendering.enabled && this.state.frameRendering.clip ? (0,_frame__WEBPACK_IMPORTED_MODULE_51__.isCursorInFrame)({\n x,\n y\n }, containingFrame) : true;\n });\n }\n\n handleHoverSelectedLinearElement(linearElementEditor, scenePointerX, scenePointerY) {\n const element = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.getElement(linearElementEditor.elementId);\n const boundTextElement = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getBoundTextElement)(element);\n\n if (!element) {\n return;\n }\n\n if (this.state.selectedLinearElement) {\n let hoverPointIndex = -1;\n let segmentMidPointHoveredCoords = null;\n\n if ((0,_element_collision__WEBPACK_IMPORTED_MODULE_44__.isHittingElementNotConsideringBoundingBox)(element, this.state, this.frameNameBoundsCache, [scenePointerX, scenePointerY])) {\n hoverPointIndex = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.getPointIndexUnderCursor(element, this.state.zoom, scenePointerX, scenePointerY);\n segmentMidPointHoveredCoords = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.getSegmentMidpointHitCoords(linearElementEditor, {\n x: scenePointerX,\n y: scenePointerY\n }, this.state);\n\n if (hoverPointIndex >= 0 || segmentMidPointHoveredCoords) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n } else {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.MOVE);\n }\n } else if ((0,_element_transformHandles__WEBPACK_IMPORTED_MODULE_48__.shouldShowBoundingBox)([element], this.state) && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isHittingElementBoundingBoxWithoutHittingElement)(element, this.state, this.frameNameBoundsCache, scenePointerX, scenePointerY)) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.MOVE);\n } else if (boundTextElement && (0,_element__WEBPACK_IMPORTED_MODULE_16__.hitTest)(boundTextElement, this.state, this.frameNameBoundsCache, scenePointerX, scenePointerY)) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.MOVE);\n }\n\n if (this.state.selectedLinearElement.hoverPointIndex !== hoverPointIndex) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, this.state.selectedLinearElement), {\n hoverPointIndex\n })\n });\n }\n\n if (!_element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.arePointsEqual(this.state.selectedLinearElement.segmentMidPointHoveredCoords, segmentMidPointHoveredCoords)) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, this.state.selectedLinearElement), {\n segmentMidPointHoveredCoords\n })\n });\n }\n } else {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursor)(this.interactiveCanvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.AUTO);\n }\n }\n\n maybeCleanupAfterMissingPointerUp(event) {\n if (lastPointerUp !== null) {\n // Unfortunately, sometimes we don't get a pointerup after a pointerdown,\n // this can happen when a contextual menu or alert is triggered. In order to avoid\n // being in a weird state, we clean up on the next pointerdown\n lastPointerUp(event);\n }\n }\n\n updateGestureOnPointerDown(event) {\n gesture.pointers.set(event.pointerId, {\n x: event.clientX,\n y: event.clientY\n });\n\n if (gesture.pointers.size === 2) {\n gesture.lastCenter = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getCenter)(gesture.pointers);\n gesture.initialScale = this.state.zoom.value;\n gesture.initialDistance = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getDistance)(Array.from(gesture.pointers.values()));\n }\n }\n\n initialPointerDownState(event) {\n const origin = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)(event, this.state);\n const selectedElements = this.scene.getSelectedElements(this.state);\n const [minX, minY, maxX, maxY] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements);\n return {\n origin,\n withCmdOrCtrl: event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD],\n originInGrid: (0,_utils__WEBPACK_IMPORTED_MODULE_33__.tupleToCoors)((0,_math__WEBPACK_IMPORTED_MODULE_28__.getGridPoint)(origin.x, origin.y, event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] ? null : this.state.gridSize)),\n scrollbars: (0,_scene__WEBPACK_IMPORTED_MODULE_29__.isOverScrollBars)(currentScrollBars, event.clientX - this.state.offsetLeft, event.clientY - this.state.offsetTop),\n // we need to duplicate because we'll be updating this state\n lastCoords: Object.assign({}, origin),\n originalElements: this.scene.getNonDeletedElements().reduce((acc, element) => {\n acc.set(element.id, (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.deepCopyElement)(element));\n return acc;\n }, new Map()),\n resize: {\n handleType: false,\n isResizing: false,\n offset: {\n x: 0,\n y: 0\n },\n arrowDirection: \"origin\",\n center: {\n x: (maxX + minX) / 2,\n y: (maxY + minY) / 2\n }\n },\n hit: {\n element: null,\n allHitElements: [],\n wasAddedToSelection: false,\n hasBeenDuplicated: false,\n hasHitCommonBoundingBoxOfSelectedElements: this.isHittingCommonBoundingBoxOfSelectedElements(origin, selectedElements)\n },\n drag: {\n hasOccurred: false,\n offset: null\n },\n eventListeners: {\n onMove: null,\n onUp: null,\n onKeyUp: null,\n onKeyDown: null\n },\n boxSelection: {\n hasOccurred: false\n },\n elementIdsToErase: {}\n };\n } // Returns whether the event is a dragging a scrollbar\n\n\n handleDraggingScrollBar(event, pointerDownState) {\n if (!(pointerDownState.scrollbars.isOverEither && !this.state.multiElement)) {\n return false;\n }\n\n isDraggingScrollBar = true;\n pointerDownState.lastCoords.x = event.clientX;\n pointerDownState.lastCoords.y = event.clientY;\n const onPointerMove = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdatesThrottled)(event => {\n const target = event.target;\n\n if (!(target instanceof HTMLElement)) {\n return;\n }\n\n this.handlePointerMoveOverScrollbars(event, pointerDownState);\n });\n const onPointerUp = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(() => {\n isDraggingScrollBar = false;\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.setCursorForShape)(this.interactiveCanvas, this.state);\n lastPointerUp = null;\n this.setState({\n cursorButton: \"up\"\n });\n this.savePointer(event.clientX, event.clientY, \"up\");\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, onPointerUp);\n onPointerMove.flush();\n });\n lastPointerUp = onPointerUp;\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, onPointerUp);\n return true;\n }\n\n isASelectedElement(hitElement) {\n return hitElement != null && this.state.selectedElementIds[hitElement.id];\n }\n\n isHittingCommonBoundingBoxOfSelectedElements(point, selectedElements) {\n if (selectedElements.length < 2) {\n return false;\n } // How many pixels off the shape boundary we still consider a hit\n\n\n const threshold = 10 / this.state.zoom.value;\n const [x1, y1, x2, y2] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements);\n return point.x > x1 - threshold && point.x < x2 + threshold && point.y > y1 - threshold && point.y < y2 + threshold;\n }\n\n getCurrentItemRoundness(elementType) {\n return this.state.currentItemRoundness === \"round\" ? {\n type: (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isUsingAdaptiveRadius)(elementType) ? _constants__WEBPACK_IMPORTED_MODULE_12__.ROUNDNESS.ADAPTIVE_RADIUS : _constants__WEBPACK_IMPORTED_MODULE_12__.ROUNDNESS.PROPORTIONAL_RADIUS\n } : null;\n }\n\n maybeCacheReferenceSnapPoints(event, selectedElements, recomputeAnyways = false) {\n if ((0,_snapping__WEBPACK_IMPORTED_MODULE_58__.isSnappingEnabled)({\n event,\n appState: this.state,\n selectedElements\n }) && (recomputeAnyways || !_snapping__WEBPACK_IMPORTED_MODULE_58__.SnapCache.getReferenceSnapPoints())) {\n _snapping__WEBPACK_IMPORTED_MODULE_58__.SnapCache.setReferenceSnapPoints((0,_snapping__WEBPACK_IMPORTED_MODULE_58__.getReferenceSnapPoints)(this.scene.getNonDeletedElements(), selectedElements, this.state));\n }\n }\n\n maybeCacheVisibleGaps(event, selectedElements, recomputeAnyways = false) {\n if ((0,_snapping__WEBPACK_IMPORTED_MODULE_58__.isSnappingEnabled)({\n event,\n appState: this.state,\n selectedElements\n }) && (recomputeAnyways || !_snapping__WEBPACK_IMPORTED_MODULE_58__.SnapCache.getVisibleGaps())) {\n _snapping__WEBPACK_IMPORTED_MODULE_58__.SnapCache.setVisibleGaps((0,_snapping__WEBPACK_IMPORTED_MODULE_58__.getVisibleGaps)(this.scene.getNonDeletedElements(), selectedElements, this.state));\n }\n }\n\n onKeyDownFromPointerDownHandler(pointerDownState) {\n return (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(event => {\n if (this.maybeHandleResize(pointerDownState, event)) {\n return;\n }\n\n this.maybeDragNewGenericElement(pointerDownState, event);\n });\n }\n\n onKeyUpFromPointerDownHandler(pointerDownState) {\n return (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(event => {\n // Prevents focus from escaping excalidraw tab\n event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ALT && event.preventDefault();\n\n if (this.maybeHandleResize(pointerDownState, event)) {\n return;\n }\n\n this.maybeDragNewGenericElement(pointerDownState, event);\n });\n }\n\n onPointerMoveFromPointerDownHandler(pointerDownState) {\n return (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdatesThrottled)(event => {\n var _a, _b; // We need to initialize dragOffsetXY only after we've updated\n // `state.selectedElementIds` on pointerDown. Doing it here in pointerMove\n // event handler should hopefully ensure we're already working with\n // the updated state.\n\n\n if (pointerDownState.drag.offset === null) {\n pointerDownState.drag.offset = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.tupleToCoors)((0,_element__WEBPACK_IMPORTED_MODULE_16__.getDragOffsetXY)(this.scene.getSelectedElements(this.state), pointerDownState.origin.x, pointerDownState.origin.y));\n }\n\n const target = event.target;\n\n if (!(target instanceof HTMLElement)) {\n return;\n }\n\n if (this.handlePointerMoveOverScrollbars(event, pointerDownState)) {\n return;\n }\n\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)(event, this.state);\n\n if ((0,_appState__WEBPACK_IMPORTED_MODULE_10__.isEraserActive)(this.state)) {\n this.handleEraser(event, pointerDownState, pointerCoords);\n return;\n }\n\n if (this.state.activeTool.type === \"laser\") {\n this.laserPathManager.addPointToPath(pointerCoords.x, pointerCoords.y);\n }\n\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_28__.getGridPoint)(pointerCoords.x, pointerCoords.y, event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] ? null : this.state.gridSize); // for arrows/lines, don't start dragging until a given threshold\n // to ensure we don't create a 2-point arrow by mistake when\n // user clicks mouse in a way that it moves a tiny bit (thus\n // triggering pointermove)\n\n if (!pointerDownState.drag.hasOccurred && (this.state.activeTool.type === \"arrow\" || this.state.activeTool.type === \"line\")) {\n if ((0,_math__WEBPACK_IMPORTED_MODULE_28__.distance2d)(pointerCoords.x, pointerCoords.y, pointerDownState.origin.x, pointerDownState.origin.y) < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD) {\n return;\n }\n }\n\n if (pointerDownState.resize.isResizing) {\n pointerDownState.lastCoords.x = pointerCoords.x;\n pointerDownState.lastCoords.y = pointerCoords.y;\n\n if (this.maybeHandleResize(pointerDownState, event)) {\n return true;\n }\n }\n\n if (this.state.selectedLinearElement) {\n const linearElementEditor = this.state.editingLinearElement || this.state.selectedLinearElement;\n\n if (_element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.shouldAddMidpoint(this.state.selectedLinearElement, pointerCoords, this.state)) {\n const ret = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.addMidpoint(this.state.selectedLinearElement, pointerCoords, this.state, !event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]);\n\n if (!ret) {\n return;\n } // Since we are reading from previous state which is not possible with\n // automatic batching in React 18 hence using flush sync to synchronously\n // update the state. Check https://github.com/excalidraw/excalidraw/pull/5508 for more details.\n\n\n (0,react_dom__WEBPACK_IMPORTED_MODULE_2__.flushSync)(() => {\n if (this.state.selectedLinearElement) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, this.state.selectedLinearElement), {\n pointerDownState: ret.pointerDownState,\n selectedPointsIndices: ret.selectedPointsIndices\n })\n });\n }\n\n if (this.state.editingLinearElement) {\n this.setState({\n editingLinearElement: Object.assign(Object.assign({}, this.state.editingLinearElement), {\n pointerDownState: ret.pointerDownState,\n selectedPointsIndices: ret.selectedPointsIndices\n })\n });\n }\n });\n return;\n } else if (linearElementEditor.pointerDownState.segmentMidpoint.value !== null && !linearElementEditor.pointerDownState.segmentMidpoint.added) {\n return;\n }\n\n const didDrag = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointDragging(event, this.state, pointerCoords.x, pointerCoords.y, (element, pointsSceneCoords) => {\n this.maybeSuggestBindingsForLinearElementAtCoords(element, pointsSceneCoords);\n }, linearElementEditor);\n\n if (didDrag) {\n pointerDownState.lastCoords.x = pointerCoords.x;\n pointerDownState.lastCoords.y = pointerCoords.y;\n pointerDownState.drag.hasOccurred = true;\n\n if (this.state.editingLinearElement && !this.state.editingLinearElement.isDragging) {\n this.setState({\n editingLinearElement: Object.assign(Object.assign({}, this.state.editingLinearElement), {\n isDragging: true\n })\n });\n }\n\n if (!this.state.selectedLinearElement.isDragging) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, this.state.selectedLinearElement), {\n isDragging: true\n })\n });\n }\n\n return;\n }\n }\n\n const hasHitASelectedElement = pointerDownState.hit.allHitElements.some(element => this.isASelectedElement(element));\n const isSelectingPointsInLineEditor = this.state.editingLinearElement && event.shiftKey && this.state.editingLinearElement.elementId === ((_a = pointerDownState.hit.element) === null || _a === void 0 ? void 0 : _a.id);\n\n if ((hasHitASelectedElement || pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) && !isSelectingPointsInLineEditor) {\n const selectedElements = this.scene.getSelectedElements(this.state);\n\n if (selectedElements.every(element => element.locked)) {\n return;\n }\n\n const selectedElementsHasAFrame = selectedElements.find(e => (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isFrameElement)(e));\n const topLayerFrame = this.getTopLayerFrameAtSceneCoords(pointerCoords);\n this.setState({\n frameToHighlight: topLayerFrame && !selectedElementsHasAFrame ? topLayerFrame : null\n }); // Marking that click was used for dragging to check\n // if elements should be deselected on pointerup\n\n pointerDownState.drag.hasOccurred = true;\n this.setState({\n selectedElementsAreBeingDragged: true\n }); // prevent dragging even if we're no longer holding cmd/ctrl otherwise\n // it would have weird results (stuff jumping all over the screen)\n // Checking for editingElement to avoid jump while editing on mobile #6503\n\n if (selectedElements.length > 0 && !pointerDownState.withCmdOrCtrl && !this.state.editingElement && ((_b = this.state.activeEmbeddable) === null || _b === void 0 ? void 0 : _b.state) !== \"active\") {\n const dragOffset = {\n x: pointerCoords.x - pointerDownState.origin.x,\n y: pointerCoords.y - pointerDownState.origin.y\n };\n const originalElements = [...pointerDownState.originalElements.values()]; // We only drag in one direction if shift is pressed\n\n const lockDirection = event.shiftKey;\n\n if (lockDirection) {\n const distanceX = Math.abs(dragOffset.x);\n const distanceY = Math.abs(dragOffset.y);\n const lockX = lockDirection && distanceX < distanceY;\n const lockY = lockDirection && distanceX > distanceY;\n\n if (lockX) {\n dragOffset.x = 0;\n }\n\n if (lockY) {\n dragOffset.y = 0;\n }\n } // Snap cache *must* be synchronously popuplated before initial drag,\n // otherwise the first drag even will not snap, causing a jump before\n // it snaps to its position if previously snapped already.\n\n\n this.maybeCacheVisibleGaps(event, selectedElements);\n this.maybeCacheReferenceSnapPoints(event, selectedElements);\n const {\n snapOffset,\n snapLines\n } = (0,_snapping__WEBPACK_IMPORTED_MODULE_58__.snapDraggedElements)((0,_scene__WEBPACK_IMPORTED_MODULE_29__.getSelectedElements)(originalElements, this.state), dragOffset, this.state, event);\n this.setState({\n snapLines\n }); // when we're editing the name of a frame, we want the user to be\n // able to select and interact with the text input\n\n !this.state.editingFrame && (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragSelectedElements)(pointerDownState, selectedElements, dragOffset, this.state, this.scene, snapOffset, event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] ? null : this.state.gridSize);\n this.maybeSuggestBindingForAll(selectedElements); // We duplicate the selected element if alt is pressed on pointer move\n\n if (event.altKey && !pointerDownState.hit.hasBeenDuplicated) {\n // Move the currently selected elements to the top of the z index stack, and\n // put the duplicates where the selected elements used to be.\n // (the origin point where the dragging started)\n pointerDownState.hit.hasBeenDuplicated = true;\n const nextElements = [];\n const elementsToAppend = [];\n const groupIdMap = new Map();\n const oldIdToDuplicatedId = new Map();\n const hitElement = pointerDownState.hit.element;\n const selectedElementIds = new Set(this.scene.getSelectedElements({\n selectedElementIds: this.state.selectedElementIds,\n includeBoundTextElement: true,\n includeElementsInFrames: true\n }).map(element => element.id));\n const elements = this.scene.getElementsIncludingDeleted();\n\n for (const element of elements) {\n if (selectedElementIds.has(element.id) || // case: the state.selectedElementIds might not have been\n // updated yet by the time this mousemove event is fired\n element.id === (hitElement === null || hitElement === void 0 ? void 0 : hitElement.id) && pointerDownState.hit.wasAddedToSelection) {\n const duplicatedElement = (0,_element__WEBPACK_IMPORTED_MODULE_16__.duplicateElement)(this.state.editingGroupId, groupIdMap, element);\n const origElement = pointerDownState.originalElements.get(element.id);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(duplicatedElement, {\n x: origElement.x,\n y: origElement.y\n }); // put duplicated element to pointerDownState.originalElements\n // so that we can snap to the duplicated element without releasing\n\n pointerDownState.originalElements.set(duplicatedElement.id, duplicatedElement);\n nextElements.push(duplicatedElement);\n elementsToAppend.push(element);\n oldIdToDuplicatedId.set(element.id, duplicatedElement.id);\n } else {\n nextElements.push(element);\n }\n }\n\n const nextSceneElements = [...nextElements, ...elementsToAppend];\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.bindTextToShapeAfterDuplication)(nextElements, elementsToAppend, oldIdToDuplicatedId);\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDuplication)(nextSceneElements, elementsToAppend, oldIdToDuplicatedId, \"duplicatesServeAsOld\");\n (0,_frame__WEBPACK_IMPORTED_MODULE_51__.bindElementsToFramesAfterDuplication)(nextSceneElements, elementsToAppend, oldIdToDuplicatedId);\n this.scene.replaceAllElements(nextSceneElements);\n this.maybeCacheVisibleGaps(event, selectedElements, true);\n this.maybeCacheReferenceSnapPoints(event, selectedElements, true);\n }\n\n return;\n }\n } // It is very important to read this.state within each move event,\n // otherwise we would read a stale one!\n\n\n const draggingElement = this.state.draggingElement;\n\n if (!draggingElement) {\n return;\n }\n\n if (draggingElement.type === \"freedraw\") {\n const points = draggingElement.points;\n const dx = pointerCoords.x - draggingElement.x;\n const dy = pointerCoords.y - draggingElement.y;\n const lastPoint = points.length > 0 && points[points.length - 1];\n const discardPoint = lastPoint && lastPoint[0] === dx && lastPoint[1] === dy;\n\n if (!discardPoint) {\n const strokeOptions = this.state.currentStrokeOptions; //zsviczian\n\n const pressures = draggingElement.simulatePressure ? draggingElement.pressures : [//zsviczian\n ...draggingElement.pressures, (strokeOptions === null || strokeOptions === void 0 ? void 0 : strokeOptions.constantPressure) ? 1 : event.pressure];\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [...points, [dx, dy]],\n pressures\n });\n }\n } else if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(draggingElement)) {\n pointerDownState.drag.hasOccurred = true;\n this.setState({\n selectedElementsAreBeingDragged: true\n });\n const points = draggingElement.points;\n let dx = gridX - draggingElement.x;\n let dy = gridY - draggingElement.y;\n\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldRotateWithDiscreteAngle)(event) && points.length === 2) {\n ({\n width: dx,\n height: dy\n } = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getLockedLinearCursorAlignSize)(draggingElement.x, draggingElement.y, pointerCoords.x, pointerCoords.y));\n }\n\n if (points.length === 1) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [...points, [dx, dy]]\n });\n } else if (points.length === 2) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [...points.slice(0, -1), [dx, dy]]\n });\n }\n\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement, false)) {\n // When creating a linear element by dragging\n this.maybeSuggestBindingsForLinearElementAtCoords(draggingElement, [pointerCoords], this.state.startBoundElement);\n }\n } else {\n pointerDownState.lastCoords.x = pointerCoords.x;\n pointerDownState.lastCoords.y = pointerCoords.y;\n this.maybeDragNewGenericElement(pointerDownState, event);\n }\n\n if (this.state.activeTool.type === \"selection\") {\n pointerDownState.boxSelection.hasOccurred = true;\n const elements = this.scene.getNonDeletedElements(); // box-select line editor points\n\n if (this.state.editingLinearElement) {\n _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handleBoxSelection(event, this.state, this.setState.bind(this)); // regular box-select\n } else {\n let shouldReuseSelection = true;\n\n if (!event.shiftKey && (0,_scene__WEBPACK_IMPORTED_MODULE_29__.isSomeElementSelected)(elements, this.state)) {\n if (pointerDownState.withCmdOrCtrl && pointerDownState.hit.element) {\n this.setState(prevState => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), {\n selectedElementIds: {\n [pointerDownState.hit.element.id]: true\n }\n }), this.scene.getNonDeletedElements(), prevState, this));\n } else {\n shouldReuseSelection = false;\n }\n }\n\n const elementsWithinSelection = (0,_scene__WEBPACK_IMPORTED_MODULE_29__.getElementsWithinSelection)(elements, draggingElement);\n this.setState(prevState => {\n const nextSelectedElementIds = Object.assign(Object.assign({}, shouldReuseSelection && prevState.selectedElementIds), elementsWithinSelection.reduce((acc, element) => {\n acc[element.id] = true;\n return acc;\n }, {}));\n\n if (pointerDownState.hit.element) {\n // if using ctrl/cmd, select the hitElement only if we\n // haven't box-selected anything else\n if (!elementsWithinSelection.length) {\n nextSelectedElementIds[pointerDownState.hit.element.id] = true;\n } else {\n delete nextSelectedElementIds[pointerDownState.hit.element.id];\n }\n }\n\n prevState = !shouldReuseSelection ? Object.assign(Object.assign({}, prevState), {\n selectedGroupIds: {},\n editingGroupId: null\n }) : prevState;\n return Object.assign(Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)({\n editingGroupId: prevState.editingGroupId,\n selectedElementIds: nextSelectedElementIds\n }, this.scene.getNonDeletedElements(), prevState, this)), {\n // select linear element only when we haven't box-selected anything else\n selectedLinearElement: elementsWithinSelection.length === 1 && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(elementsWithinSelection[0]) ? new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(elementsWithinSelection[0], this.scene) : null,\n showHyperlinkPopup: elementsWithinSelection.length === 1 && (elementsWithinSelection[0].link || (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isEmbeddableElement)(elementsWithinSelection[0])) ? \"info\" : false\n });\n });\n }\n }\n });\n } // Returns whether the pointer move happened over either scrollbar\n\n\n handlePointerMoveOverScrollbars(event, pointerDownState) {\n if (pointerDownState.scrollbars.isOverHorizontal) {\n const x = event.clientX;\n const dx = x - pointerDownState.lastCoords.x;\n this.translateCanvas({\n scrollX: this.state.scrollX - dx / this.state.zoom.value\n });\n pointerDownState.lastCoords.x = x;\n return true;\n }\n\n if (pointerDownState.scrollbars.isOverVertical) {\n const y = event.clientY;\n const dy = y - pointerDownState.lastCoords.y;\n this.translateCanvas({\n scrollY: this.state.scrollY - dy / this.state.zoom.value\n });\n pointerDownState.lastCoords.y = y;\n return true;\n }\n\n return false;\n }\n\n onPointerUpFromPointerDownHandler(pointerDownState) {\n return (0,_utils__WEBPACK_IMPORTED_MODULE_33__.withBatchedUpdates)(childEvent => {\n var _a, _b, _c, _d, _e, _f;\n\n if (pointerDownState.eventListeners.onMove) {\n pointerDownState.eventListeners.onMove.flush();\n }\n\n const {\n draggingElement,\n resizingElement,\n multiElement,\n activeTool,\n isResizing,\n isRotating\n } = this.state;\n this.setState({\n isResizing: false,\n isRotating: false,\n resizingElement: null,\n selectionElement: null,\n frameToHighlight: null,\n elementsToHighlight: null,\n cursorButton: \"up\",\n // text elements are reset on finalize, and resetting on pointerup\n // may cause issues with double taps\n editingElement: multiElement || (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement) ? this.state.editingElement : null,\n snapLines: [],\n originSnapOffset: null\n });\n _snapping__WEBPACK_IMPORTED_MODULE_58__.SnapCache.setReferenceSnapPoints(null);\n _snapping__WEBPACK_IMPORTED_MODULE_58__.SnapCache.setVisibleGaps(null);\n this.savePointer(childEvent.clientX, childEvent.clientY, \"up\");\n this.setState({\n selectedElementsAreBeingDragged: false\n }); // Handle end of dragging a point of a linear element, might close a loop\n // and sets binding element\n\n if (this.state.editingLinearElement) {\n if (!pointerDownState.boxSelection.hasOccurred && ((_b = (_a = pointerDownState.hit) === null || _a === void 0 ? void 0 : _a.element) === null || _b === void 0 ? void 0 : _b.id) !== this.state.editingLinearElement.elementId) {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n } else {\n const editingLinearElement = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerUp(childEvent, this.state.editingLinearElement, this.state);\n\n if (editingLinearElement !== this.state.editingLinearElement) {\n this.setState({\n editingLinearElement,\n suggestedBindings: []\n });\n }\n }\n } else if (this.state.selectedLinearElement) {\n if (((_d = (_c = pointerDownState.hit) === null || _c === void 0 ? void 0 : _c.element) === null || _d === void 0 ? void 0 : _d.id) !== this.state.selectedLinearElement.elementId) {\n const selectedELements = this.scene.getSelectedElements(this.state); // set selectedLinearElement to null if there is more than one element selected since we don't want to show linear element handles\n\n if (selectedELements.length > 1) {\n this.setState({\n selectedLinearElement: null\n });\n }\n } else {\n const linearElementEditor = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerUp(childEvent, this.state.selectedLinearElement, this.state);\n const {\n startBindingElement,\n endBindingElement\n } = linearElementEditor;\n const element = this.scene.getElement(linearElementEditor.elementId);\n\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(element)) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.bindOrUnbindLinearElement)(element, startBindingElement, endBindingElement);\n }\n\n if (linearElementEditor !== this.state.selectedLinearElement) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, linearElementEditor), {\n selectedPointsIndices: null\n }),\n suggestedBindings: []\n });\n }\n }\n }\n\n lastPointerUp = null;\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, pointerDownState.eventListeners.onMove);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, pointerDownState.eventListeners.onUp);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYDOWN, pointerDownState.eventListeners.onKeyDown);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYUP, pointerDownState.eventListeners.onKeyUp);\n\n if (this.state.pendingImageElementId) {\n this.setState({\n pendingImageElementId: null\n });\n }\n\n this.onPointerUpEmitter.trigger(this.state.activeTool, pointerDownState, childEvent);\n\n if ((draggingElement === null || draggingElement === void 0 ? void 0 : draggingElement.type) === \"freedraw\") {\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)(childEvent, this.state);\n const points = draggingElement.points;\n let dx = pointerCoords.x - draggingElement.x;\n let dy = pointerCoords.y - draggingElement.y; // Allows dots to avoid being flagged as infinitely small\n\n if (dx === points[0][0] && dy === points[0][1]) {\n dy += 0.0001;\n dx += 0.0001;\n }\n\n const pressures = draggingElement.simulatePressure ? [] : [...draggingElement.pressures, childEvent.pressure];\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [...points, [dx, dy]],\n pressures,\n lastCommittedPoint: [dx, dy]\n });\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n return;\n }\n\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(draggingElement)) {\n const imageElement = draggingElement;\n\n try {\n this.initializeImageDimensions(imageElement);\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({\n [imageElement.id]: true\n }, this.state)\n }, () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n });\n } catch (error) {\n console.error(error);\n this.scene.replaceAllElements(this.scene.getElementsIncludingDeleted().filter(el => el.id !== imageElement.id));\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n }\n\n return;\n }\n\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(draggingElement)) {\n if (draggingElement.points.length > 1) {\n this.history.resumeRecording();\n }\n\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)(childEvent, this.state);\n\n if (!pointerDownState.drag.hasOccurred && draggingElement && !multiElement) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [...draggingElement.points, [pointerCoords.x - draggingElement.x, pointerCoords.y - draggingElement.y]]\n });\n this.setState({\n multiElement: draggingElement,\n editingElement: this.state.draggingElement\n });\n } else if (pointerDownState.drag.hasOccurred && !multiElement) {\n if ((0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state) && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement, false)) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.maybeBindLinearElement)(draggingElement, this.state, this.scene, pointerCoords);\n }\n\n this.setState({\n suggestedBindings: [],\n startBoundElement: null\n });\n\n if (!activeTool.locked) {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.resetCursor)(this.interactiveCanvas);\n this.setState(prevState => ({\n draggingElement: null,\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_33__.updateActiveTool)(this.state, {\n type: \"selection\"\n }),\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(Object.assign(Object.assign({}, prevState.selectedElementIds), {\n [draggingElement.id]: true\n }), prevState),\n selectedLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(draggingElement, this.scene)\n }));\n } else {\n this.setState(prevState => ({\n draggingElement: null\n }));\n }\n }\n\n return;\n }\n\n if (activeTool.type !== \"selection\" && draggingElement && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isInvisiblySmallElement)(draggingElement)) {\n // remove invisible element which was added in onPointerDown\n this.scene.replaceAllElements(this.scene.getElementsIncludingDeleted().filter(el => el.id !== draggingElement.id));\n this.setState({\n draggingElement: null\n });\n return;\n }\n\n if (draggingElement) {\n if (pointerDownState.drag.hasOccurred) {\n const sceneCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)(childEvent, this.state); // when editing the points of a linear element, we check if the\n // linear element still is in the frame afterwards\n // if not, the linear element will be removed from its frame (if any)\n\n if (this.state.selectedLinearElement && this.state.selectedLinearElement.isDragging) {\n const linearElement = this.scene.getElement(this.state.selectedLinearElement.elementId);\n\n if (linearElement === null || linearElement === void 0 ? void 0 : linearElement.frameId) {\n const frame = (0,_frame__WEBPACK_IMPORTED_MODULE_51__.getContainingFrame)(linearElement);\n\n if (frame && linearElement) {\n if (!(0,_frame__WEBPACK_IMPORTED_MODULE_51__.elementOverlapsWithFrame)(linearElement, frame)) {\n // remove the linear element from all groups\n // before removing it from the frame as well\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(linearElement, {\n groupIds: []\n });\n this.scene.replaceAllElements((0,_frame__WEBPACK_IMPORTED_MODULE_51__.removeElementsFromFrame)(this.scene.getElementsIncludingDeleted(), [linearElement], this.state));\n }\n }\n }\n } else {\n // update the relationships between selected elements and frames\n const topLayerFrame = this.getTopLayerFrameAtSceneCoords(sceneCoords);\n const selectedElements = this.scene.getSelectedElements(this.state);\n let nextElements = this.scene.getElementsIncludingDeleted();\n\n const updateGroupIdsAfterEditingGroup = elements => {\n if (elements.length > 0) {\n for (const element of elements) {\n const index = element.groupIds.indexOf(this.state.editingGroupId);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n groupIds: element.groupIds.slice(0, index)\n }, false);\n }\n\n nextElements.forEach(element => {\n if (element.groupIds.length && (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getElementsInGroup)(nextElements, element.groupIds[element.groupIds.length - 1]).length < 2) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n groupIds: []\n }, false);\n }\n });\n this.setState({\n editingGroupId: null\n });\n }\n };\n\n if (topLayerFrame && !this.state.selectedElementIds[topLayerFrame.id]) {\n const elementsToAdd = selectedElements.filter(element => element.frameId !== topLayerFrame.id && (0,_frame__WEBPACK_IMPORTED_MODULE_51__.isElementInFrame)(element, nextElements, this.state));\n\n if (this.state.editingGroupId) {\n updateGroupIdsAfterEditingGroup(elementsToAdd);\n }\n\n nextElements = (0,_frame__WEBPACK_IMPORTED_MODULE_51__.addElementsToFrame)(nextElements, elementsToAdd, topLayerFrame);\n } else if (!topLayerFrame) {\n if (this.state.editingGroupId) {\n const elementsToRemove = selectedElements.filter(element => element.frameId && !(0,_frame__WEBPACK_IMPORTED_MODULE_51__.isElementInFrame)(element, nextElements, this.state));\n updateGroupIdsAfterEditingGroup(elementsToRemove);\n }\n }\n\n nextElements = (0,_frame__WEBPACK_IMPORTED_MODULE_51__.updateFrameMembershipOfSelectedElements)(nextElements, this.state, this);\n this.scene.replaceAllElements(nextElements);\n }\n }\n\n if (draggingElement.type === \"frame\") {\n const elementsInsideFrame = (0,_frame__WEBPACK_IMPORTED_MODULE_51__.getElementsInNewFrame)(this.scene.getElementsIncludingDeleted(), draggingElement);\n this.scene.replaceAllElements((0,_frame__WEBPACK_IMPORTED_MODULE_51__.addElementsToFrame)(this.scene.getElementsIncludingDeleted(), elementsInsideFrame, draggingElement));\n }\n\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getNormalizedDimensions)(draggingElement));\n }\n\n if (resizingElement) {\n this.history.resumeRecording();\n }\n\n if (resizingElement && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isInvisiblySmallElement)(resizingElement)) {\n this.scene.replaceAllElements(this.scene.getElementsIncludingDeleted().filter(el => el.id !== resizingElement.id));\n } // handle frame membership for resizing frames and/or selected elements\n\n\n if (pointerDownState.resize.isResizing) {\n let nextElements = (0,_frame__WEBPACK_IMPORTED_MODULE_51__.updateFrameMembershipOfSelectedElements)(this.scene.getElementsIncludingDeleted(), this.state, this);\n const selectedFrames = this.scene.getSelectedElements(this.state).filter(element => element.type === \"frame\");\n\n for (const frame of selectedFrames) {\n nextElements = (0,_frame__WEBPACK_IMPORTED_MODULE_51__.replaceAllElementsInFrame)(nextElements, (0,_frame__WEBPACK_IMPORTED_MODULE_51__.getElementsInResizingFrame)(this.scene.getElementsIncludingDeleted(), frame, this.state), frame, this.state);\n }\n\n this.scene.replaceAllElements(nextElements);\n } // Code below handles selection when element(s) weren't\n // drag or added to selection on pointer down phase.\n\n\n const hitElement = pointerDownState.hit.element;\n\n if (((_e = this.state.selectedLinearElement) === null || _e === void 0 ? void 0 : _e.elementId) !== (hitElement === null || hitElement === void 0 ? void 0 : hitElement.id) && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(hitElement)) {\n const selectedELements = this.scene.getSelectedElements(this.state); // set selectedLinearElement when no other element selected except\n // the one we've hit\n\n if (selectedELements.length === 1) {\n this.setState({\n selectedLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(hitElement, this.scene)\n });\n }\n }\n\n if ((0,_appState__WEBPACK_IMPORTED_MODULE_10__.isEraserActive)(this.state)) {\n const draggedDistance = (0,_math__WEBPACK_IMPORTED_MODULE_28__.distance2d)(this.lastPointerDownEvent.clientX, this.lastPointerDownEvent.clientY, this.lastPointerUpEvent.clientX, this.lastPointerUpEvent.clientY);\n\n if (draggedDistance === 0) {\n const scenePointer = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.viewportCoordsToSceneCoords)({\n clientX: this.lastPointerUpEvent.clientX,\n clientY: this.lastPointerUpEvent.clientY\n }, this.state);\n const hitElements = this.getElementsAtPosition(scenePointer.x, scenePointer.y);\n hitElements.forEach(hitElement => pointerDownState.elementIdsToErase[hitElement.id] = {\n erase: true,\n opacity: hitElement.opacity\n });\n }\n\n this.eraseElements(pointerDownState);\n return;\n } else if (Object.keys(pointerDownState.elementIdsToErase).length) {\n this.restoreReadyToEraseElements(pointerDownState);\n }\n\n if (hitElement && !pointerDownState.drag.hasOccurred && !pointerDownState.hit.wasAddedToSelection && ( // if we're editing a line, pointerup shouldn't switch selection if\n // box selected\n !this.state.editingLinearElement || !pointerDownState.boxSelection.hasOccurred)) {\n // when inside line editor, shift selects points instead\n if (childEvent.shiftKey && !this.state.editingLinearElement) {\n if (this.state.selectedElementIds[hitElement.id]) {\n if ((0,_groups__WEBPACK_IMPORTED_MODULE_23__.isSelectedViaGroup)(this.state, hitElement)) {\n this.setState(_prevState => {\n const nextSelectedElementIds = Object.assign({}, _prevState.selectedElementIds); // We want to unselect all groups hitElement is part of\n // as well as all elements that are part of the groups\n // hitElement is part of\n\n for (const groupedElement of hitElement.groupIds.flatMap(groupId => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getElementsInGroup)(this.scene.getNonDeletedElements(), groupId))) {\n delete nextSelectedElementIds[groupedElement.id];\n }\n\n return {\n selectedGroupIds: Object.assign(Object.assign({}, _prevState.selectedElementIds), hitElement.groupIds.map(gId => ({\n [gId]: false\n })).reduce((prev, acc) => Object.assign(Object.assign({}, prev), acc), {})),\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(nextSelectedElementIds, _prevState)\n };\n }); // if not gragging a linear element point (outside editor)\n } else if (!((_f = this.state.selectedLinearElement) === null || _f === void 0 ? void 0 : _f.isDragging)) {\n // remove element from selection while\n // keeping prev elements selected\n this.setState(prevState => {\n const newSelectedElementIds = Object.assign({}, prevState.selectedElementIds);\n delete newSelectedElementIds[hitElement.id];\n const newSelectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_29__.getSelectedElements)(this.scene.getNonDeletedElements(), {\n selectedElementIds: newSelectedElementIds\n });\n return Object.assign(Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)({\n editingGroupId: prevState.editingGroupId,\n selectedElementIds: newSelectedElementIds\n }, this.scene.getNonDeletedElements(), prevState, this)), {\n // set selectedLinearElement only if thats the only element selected\n selectedLinearElement: newSelectedElements.length === 1 && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(newSelectedElements[0]) ? new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(newSelectedElements[0], this.scene) : prevState.selectedLinearElement\n });\n });\n }\n } else if (hitElement.frameId && this.state.selectedElementIds[hitElement.frameId]) {\n // when hitElement is part of a selected frame, deselect the frame\n // to avoid frame and containing elements selected simultaneously\n this.setState(prevState => {\n var _a, _b;\n\n const nextSelectedElementIds = Object.assign(Object.assign({}, prevState.selectedElementIds), {\n [hitElement.id]: true\n }); // deselect the frame\n\n delete nextSelectedElementIds[hitElement.frameId]; // deselect groups containing the frame\n\n ((_b = (_a = this.scene.getElement(hitElement.frameId)) === null || _a === void 0 ? void 0 : _a.groupIds) !== null && _b !== void 0 ? _b : []).flatMap(gid => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getElementsInGroup)(this.scene.getNonDeletedElements(), gid)).forEach(element => {\n delete nextSelectedElementIds[element.id];\n });\n return Object.assign(Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)({\n editingGroupId: prevState.editingGroupId,\n selectedElementIds: nextSelectedElementIds\n }, this.scene.getNonDeletedElements(), prevState, this)), {\n showHyperlinkPopup: hitElement.link || (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isEmbeddableElement)(hitElement) ? \"info\" : false\n });\n });\n } else {\n // add element to selection while keeping prev elements selected\n this.setState(_prevState => ({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(Object.assign(Object.assign({}, _prevState.selectedElementIds), {\n [hitElement.id]: true\n }), _prevState)\n }));\n }\n } else {\n this.setState(prevState => {\n var _a;\n\n return Object.assign(Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)({\n editingGroupId: prevState.editingGroupId,\n selectedElementIds: {\n [hitElement.id]: true\n }\n }, this.scene.getNonDeletedElements(), prevState, this)), {\n selectedLinearElement: (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(hitElement) && // Don't set `selectedLinearElement` if its same as the hitElement, this is mainly to prevent resetting the `hoverPointIndex` to -1.\n // Future we should update the API to take care of setting the correct `hoverPointIndex` when initialized\n ((_a = prevState.selectedLinearElement) === null || _a === void 0 ? void 0 : _a.elementId) !== hitElement.id ? new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(hitElement, this.scene) : prevState.selectedLinearElement\n });\n });\n }\n }\n\n if (!pointerDownState.drag.hasOccurred && !this.state.isResizing && (hitElement && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isHittingElementBoundingBoxWithoutHittingElement)(hitElement, this.state, this.frameNameBoundsCache, pointerDownState.origin.x, pointerDownState.origin.y) || !hitElement && pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements)) {\n if (this.state.editingLinearElement) {\n this.setState({\n editingLinearElement: null\n });\n } else {\n // Deselect selected elements\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({}, this.state),\n selectedGroupIds: {},\n editingGroupId: null,\n activeEmbeddable: null\n });\n }\n\n return;\n }\n\n if (!activeTool.locked && activeTool.type !== \"freedraw\" && draggingElement && draggingElement.type !== \"selection\") {\n this.setState(prevState => ({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)(Object.assign(Object.assign({}, prevState.selectedElementIds), {\n [draggingElement.id]: true\n }), prevState),\n showHyperlinkPopup: (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isEmbeddableElement)(draggingElement) && !draggingElement.link ? \"editor\" : prevState.showHyperlinkPopup\n }));\n }\n\n if (activeTool.type !== \"selection\" || (0,_scene__WEBPACK_IMPORTED_MODULE_29__.isSomeElementSelected)(this.scene.getNonDeletedElements(), this.state)) {\n this.history.resumeRecording();\n }\n\n if (pointerDownState.drag.hasOccurred || isResizing || isRotating) {\n ((0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state) ? _element_binding__WEBPACK_IMPORTED_MODULE_17__.bindOrUnbindSelectedElements : _element_binding__WEBPACK_IMPORTED_MODULE_17__.unbindLinearElements)(this.scene.getSelectedElements(this.state));\n }\n\n if (activeTool.type === \"laser\") {\n this.laserPathManager.endPath();\n return;\n }\n\n if (!activeTool.locked && activeTool.type !== \"freedraw\") {\n (0,_cursor__WEBPACK_IMPORTED_MODULE_70__.resetCursor)(this.interactiveCanvas);\n this.setState({\n draggingElement: null,\n suggestedBindings: [],\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_33__.updateActiveTool)(this.state, {\n type: \"selection\"\n })\n });\n } else {\n this.setState({\n draggingElement: null,\n suggestedBindings: []\n });\n }\n\n if (hitElement && this.lastPointerUpEvent && this.lastPointerDownEvent && this.lastPointerUpEvent.timeStamp - this.lastPointerDownEvent.timeStamp < 300 && gesture.pointers.size <= 1 && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isEmbeddableElement)(hitElement) && this.isEmbeddableCenter(hitElement, this.lastPointerUpEvent, pointerDownState.origin.x, pointerDownState.origin.y)) {\n this.handleEmbeddableCenterClick(hitElement);\n }\n });\n }\n\n maybeSuggestBindingForAll(selectedElements) {\n if (selectedElements.length > 50) {\n return;\n }\n\n const suggestedBindings = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getEligibleElementsForBinding)(selectedElements);\n this.setState({\n suggestedBindings\n });\n }\n\n setSelection(elements) {\n const selectedElementIds = {};\n const selectedGroupIds = {};\n elements.forEach(ele => {\n if (ele.groupIds.length) {\n selectedElementIds[ele.id] = true;\n ele.groupIds.forEach(id => {\n selectedGroupIds[id] = true;\n });\n } // exclude bound text elements as we don't mark them as selected when\n // container is selected unless in group\n else if (!(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(ele)) {\n selectedElementIds[ele.id] = true;\n }\n });\n this.setState({\n previousSelectedElementIds: this.state.selectedElementIds,\n selectedElementIds,\n selectedGroupIds\n });\n }\n\n clearSelection(hitElement) {\n this.setState(prevState => ({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({}, prevState),\n activeEmbeddable: null,\n selectedGroupIds: {},\n // Continue editing the same group if the user selected a different\n // element from it\n editingGroupId: prevState.editingGroupId && hitElement != null && (0,_groups__WEBPACK_IMPORTED_MODULE_23__.isElementInGroup)(hitElement, prevState.editingGroupId) ? prevState.editingGroupId : null\n }));\n this.setState({\n selectedElementIds: (0,_scene_selection__WEBPACK_IMPORTED_MODULE_52__.makeNextSelectedElementIds)({}, this.state),\n activeEmbeddable: null,\n previousSelectedElementIds: this.state.selectedElementIds\n });\n }\n\n getTextWysiwygSnappedToCenterPosition(x, y, appState, container) {\n if (container) {\n let elementCenterX = container.x + container.width / 2;\n let elementCenterY = container.y + container.height / 2;\n const elementCenter = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getContainerCenter)(container, appState);\n\n if (elementCenter) {\n elementCenterX = elementCenter.x;\n elementCenterY = elementCenter.y;\n }\n\n const distanceToCenter = Math.hypot(x - elementCenterX, y - elementCenterY);\n const isSnappedToCenter = distanceToCenter < _constants__WEBPACK_IMPORTED_MODULE_12__.TEXT_TO_CENTER_SNAP_THRESHOLD;\n\n if (isSnappedToCenter) {\n const {\n x: viewportX,\n y: viewportY\n } = (0,_utils__WEBPACK_IMPORTED_MODULE_33__.sceneCoordsToViewportCoords)({\n sceneX: elementCenterX,\n sceneY: elementCenterY\n }, appState);\n return {\n viewportX,\n viewportY,\n elementCenterX,\n elementCenterY\n };\n }\n }\n }\n\n getCanvasOffsets() {\n var _a;\n\n if ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current) {\n const excalidrawContainer = this.excalidrawContainerRef.current;\n const {\n left,\n top\n } = excalidrawContainer.getBoundingClientRect();\n return {\n offsetLeft: left,\n offsetTop: top\n };\n }\n\n return {\n offsetLeft: 0,\n offsetTop: 0\n };\n }\n\n async updateLanguage() {\n const currentLang = _i18n__WEBPACK_IMPORTED_MODULE_25__.languages.find(lang => lang.code === this.props.langCode) || _i18n__WEBPACK_IMPORTED_MODULE_25__.defaultLang;\n await (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.setLanguage)(currentLang);\n this.setAppState({});\n }\n\n}\n\nApp.defaultProps = {\n // needed for tests to pass since we directly render App in many tests\n UIOptions: _constants__WEBPACK_IMPORTED_MODULE_12__.DEFAULT_UI_OPTIONS\n};\n\nif (\"development\" === _constants__WEBPACK_IMPORTED_MODULE_12__.ENV.TEST || \"development\" !== \"production\") {\n window.h = window.h || {};\n Object.defineProperties(window.h, {\n elements: {\n configurable: true,\n\n get() {\n var _a;\n\n return (_a = this.app) === null || _a === void 0 ? void 0 : _a.scene.getElementsIncludingDeleted();\n },\n\n set(elements) {\n var _a;\n\n return (_a = this.app) === null || _a === void 0 ? void 0 : _a.scene.replaceAllElements(elements);\n }\n\n }\n });\n}\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (App);\n\n//# sourceURL=webpack://ExcalidrawLib/../../components/App.tsx?");
2307
2307
 
2308
2308
  /***/ }),
2309
2309
 
@@ -2468,7 +2468,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
2468
2468
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2469
2469
 
2470
2470
  "use strict";
2471
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"TopPicks\": () => (/* binding */ TopPicks)\n/* harmony export */ });\n/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react/jsx-runtime */ \"../../../node_modules/react/jsx-runtime.js\");\n/* harmony import */ var clsx__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! clsx */ \"../../../node_modules/clsx/dist/clsx.m.js\");\n/* harmony import */ var _colors__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../colors */ \"../../colors.ts\");\n\n\n\nconst TopPicks = ({\n onChange,\n type,\n activeColor,\n topPicks\n}) => {\n let colors;\n\n if (type === \"elementStroke\") {\n colors = _colors__WEBPACK_IMPORTED_MODULE_2__.DEFAULT_ELEMENT_STROKE_PICKS;\n }\n\n if (type === \"elementBackground\") {\n colors = _colors__WEBPACK_IMPORTED_MODULE_2__.DEFAULT_ELEMENT_BACKGROUND_PICKS;\n }\n\n if (type === \"canvasBackground\") {\n colors = _colors__WEBPACK_IMPORTED_MODULE_2__.DEFAULT_CANVAS_BACKGROUND_PICKS;\n } // this one can overwrite defaults\n\n\n if (topPicks) {\n colors = topPicks;\n }\n\n if (!colors) {\n console.error(\"Invalid type for TopPicks\");\n return null;\n }\n\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", Object.assign({\n className: \"color-picker__top-picks\"\n }, {\n children: colors.map(color => (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"button\", Object.assign({\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(\"color-picker__button\", {\n active: color === activeColor,\n \"is-transparent\": color === \"transparent\" || !color\n }),\n style: {\n \"--swatch-color\": color\n },\n type: \"button\",\n title: color,\n onClick: () => onChange(color)\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", {\n className: \"color-picker__button-outline\"\n })\n }), color))\n }));\n};\n\n//# sourceURL=webpack://ExcalidrawLib/../../components/ColorPicker/TopPicks.tsx?");
2471
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"TopPicks\": () => (/* binding */ TopPicks)\n/* harmony export */ });\n/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react/jsx-runtime */ \"../../../node_modules/react/jsx-runtime.js\");\n/* harmony import */ var clsx__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! clsx */ \"../../../node_modules/clsx/dist/clsx.m.js\");\n/* harmony import */ var _colors__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../colors */ \"../../colors.ts\");\n\n\n\nconst TopPicks = ({\n onChange,\n type,\n activeColor,\n topPicks\n}) => {\n let colors;\n\n if (type === \"elementStroke\") {\n colors = _colors__WEBPACK_IMPORTED_MODULE_2__.DEFAULT_ELEMENT_STROKE_PICKS;\n }\n\n if (type === \"elementBackground\") {\n colors = _colors__WEBPACK_IMPORTED_MODULE_2__.DEFAULT_ELEMENT_BACKGROUND_PICKS;\n }\n\n if (type === \"canvasBackground\") {\n colors = _colors__WEBPACK_IMPORTED_MODULE_2__.DEFAULT_CANVAS_BACKGROUND_PICKS;\n } // this one can overwrite defaults\n\n\n if (topPicks) {\n colors = topPicks;\n }\n\n if (!colors) {\n console.error(\"Invalid type for TopPicks\");\n return null;\n }\n\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", Object.assign({\n className: \"color-picker__top-picks\"\n }, {\n children: colors.map(color => (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"button\", Object.assign({\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(\"color-picker__button\", {\n active: color === activeColor,\n \"is-transparent\": color === \"transparent\" || !color\n }),\n style: {\n \"--swatch-color\": color\n },\n type: \"button\",\n title: color,\n onClick: () => onChange(color),\n \"data-testid\": `color-top-pick-${color}`\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", {\n className: \"color-picker__button-outline\"\n })\n }), color))\n }));\n};\n\n//# sourceURL=webpack://ExcalidrawLib/../../components/ColorPicker/TopPicks.tsx?");
2472
2472
 
2473
2473
  /***/ }),
2474
2474
 
@@ -2754,7 +2754,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
2754
2754
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2755
2755
 
2756
2756
  "use strict";
2757
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react/jsx-runtime */ \"../../../node_modules/react/jsx-runtime.js\");\n/* harmony import */ var clsx__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! clsx */ \"../../../node_modules/clsx/dist/clsx.m.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react */ \"react\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _element__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../element */ \"../../element/index.ts\");\n/* harmony import */ var _i18n__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../i18n */ \"../../i18n.ts\");\n/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../scene */ \"../../scene/index.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _Actions__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./Actions */ \"../../components/Actions.tsx\");\n/* harmony import */ var _ErrorDialog__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./ErrorDialog */ \"../../components/ErrorDialog.tsx\");\n/* harmony import */ var _ImageExportDialog__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./ImageExportDialog */ \"../../components/ImageExportDialog.tsx\");\n/* harmony import */ var _FixedSideContainer__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./FixedSideContainer */ \"../../components/FixedSideContainer.tsx\");\n/* harmony import */ var _HintViewer__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./HintViewer */ \"../../components/HintViewer.tsx\");\n/* harmony import */ var _Island__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./Island */ \"../../components/Island.tsx\");\n/* harmony import */ var _LoadingMessage__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./LoadingMessage */ \"../../components/LoadingMessage.tsx\");\n/* harmony import */ var _LockButton__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./LockButton */ \"../../components/LockButton.tsx\");\n/* harmony import */ var _MobileMenu__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./MobileMenu */ \"../../components/MobileMenu.tsx\");\n/* harmony import */ var _PasteChartDialog__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./PasteChartDialog */ \"../../components/PasteChartDialog.tsx\");\n/* harmony import */ var _Section__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./Section */ \"../../components/Section.tsx\");\n/* harmony import */ var _HelpDialog__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./HelpDialog */ \"../../components/HelpDialog.tsx\");\n/* harmony import */ var _Stack__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./Stack */ \"../../components/Stack.tsx\");\n/* harmony import */ var _UserList__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./UserList */ \"../../components/UserList.tsx\");\n/* harmony import */ var _JSONExportDialog__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./JSONExportDialog */ \"../../components/JSONExportDialog.tsx\");\n/* harmony import */ var _PenModeButton__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./PenModeButton */ \"../../components/PenModeButton.tsx\");\n/* harmony import */ var _analytics__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ../analytics */ \"../../analytics.ts\");\n/* harmony import */ var _components_App__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ../components/App */ \"../../components/App.tsx\");\n/* harmony import */ var _Stats__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./Stats */ \"../../components/Stats.tsx\");\n/* harmony import */ var _actions_actionToggleStats__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ../actions/actionToggleStats */ \"../../actions/actionToggleStats.tsx\");\n/* harmony import */ var _footer_Footer__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./footer/Footer */ \"../../components/footer/Footer.tsx\");\n/* harmony import */ var _Sidebar_Sidebar__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./Sidebar/Sidebar */ \"../../components/Sidebar/Sidebar.tsx\");\n/* harmony import */ var _jotai__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ../jotai */ \"../../jotai.ts\");\n/* harmony import */ var jotai__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(/*! jotai */ \"../../../node_modules/jotai/esm/index.mjs\");\n/* harmony import */ var _main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ./main-menu/MainMenu */ \"../../components/main-menu/MainMenu.tsx\");\n/* harmony import */ var _ActiveConfirmDialog__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ./ActiveConfirmDialog */ \"../../components/ActiveConfirmDialog.tsx\");\n/* harmony import */ var _OverwriteConfirm_OverwriteConfirm__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ./OverwriteConfirm/OverwriteConfirm */ \"../../components/OverwriteConfirm/OverwriteConfirm.tsx\");\n/* harmony import */ var _HandButton__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ./HandButton */ \"../../components/HandButton.tsx\");\n/* harmony import */ var _appState__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ../appState */ \"../../appState.ts\");\n/* harmony import */ var _context_tunnels__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ../context/tunnels */ \"../../context/tunnels.ts\");\n/* harmony import */ var _icons__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ./icons */ \"../../components/icons.tsx\");\n/* harmony import */ var _context_ui_appState__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! ../context/ui-appState */ \"../../context/ui-appState.ts\");\n/* harmony import */ var _DefaultSidebar__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(/*! ./DefaultSidebar */ \"../../components/DefaultSidebar.tsx\");\n/* harmony import */ var _EyeDropper__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(/*! ./EyeDropper */ \"../../components/EyeDropper.tsx\");\n/* harmony import */ var _LayerUI_scss__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(/*! ./LayerUI.scss */ \"../../components/LayerUI.scss\");\n/* harmony import */ var _Toolbar_scss__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(/*! ./Toolbar.scss */ \"../../components/Toolbar.scss\");\n/* harmony import */ var _element_mutateElement__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(/*! ../element/mutateElement */ \"../../element/mutateElement.ts\");\n/* harmony import */ var _scene_ShapeCache__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(/*! ../scene/ShapeCache */ \"../../scene/ShapeCache.ts\");\n/* harmony import */ var _scene_Scene__WEBPACK_IMPORTED_MODULE_45__ = __webpack_require__(/*! ../scene/Scene */ \"../../scene/Scene.ts\");\n/* harmony import */ var _LaserTool_LaserPointerButton__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(/*! ./LaserTool/LaserPointerButton */ \"../../components/LaserTool/LaserPointerButton.tsx\");\nvar __rest = undefined && undefined.__rest || function (s, e) {\n var t = {};\n\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];\n\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];\n }\n return t;\n};\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst DefaultMainMenu = ({\n UIOptions\n}) => {\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__[\"default\"], Object.assign({\n __fallback: true\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__[\"default\"].DefaultItems.LoadScene, {}), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__[\"default\"].DefaultItems.SaveToActiveFile, {}), UIOptions.canvasActions.export && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__[\"default\"].DefaultItems.Export, {}), UIOptions.canvasActions.saveAsImage && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__[\"default\"].DefaultItems.SaveAsImage, {}), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__[\"default\"].DefaultItems.Help, {}), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__[\"default\"].DefaultItems.ClearCanvas, {}), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__[\"default\"].Separator, {}), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__[\"default\"].Group, Object.assign({\n title: \"Excalidraw links\"\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__[\"default\"].DefaultItems.Socials, {})\n })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__[\"default\"].Separator, {}), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__[\"default\"].DefaultItems.ToggleTheme, {}), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__[\"default\"].DefaultItems.ChangeCanvasBackground, {})]\n }));\n};\n\nconst DefaultOverwriteConfirmDialog = () => {\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(_OverwriteConfirm_OverwriteConfirm__WEBPACK_IMPORTED_MODULE_33__.OverwriteConfirmDialog, Object.assign({\n __fallback: true\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_OverwriteConfirm_OverwriteConfirm__WEBPACK_IMPORTED_MODULE_33__.OverwriteConfirmDialog.Actions.SaveToDisk, {}), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_OverwriteConfirm_OverwriteConfirm__WEBPACK_IMPORTED_MODULE_33__.OverwriteConfirmDialog.Actions.ExportToImage, {})]\n }));\n};\n\nconst LayerUI = ({\n actionManager,\n appState,\n files,\n setAppState,\n elements,\n canvas,\n onLockToggle,\n onHandToolToggle,\n onPenModeToggle,\n showExitZenModeBtn,\n renderTopRightUI,\n renderCustomStats,\n UIOptions,\n onExportImage,\n renderWelcomeScreen,\n children,\n app,\n isCollaborating\n}) => {\n const device = (0,_components_App__WEBPACK_IMPORTED_MODULE_25__.useDevice)();\n const tunnels = (0,_context_tunnels__WEBPACK_IMPORTED_MODULE_36__.useInitializeTunnels)();\n const [eyeDropperState, setEyeDropperState] = (0,jotai__WEBPACK_IMPORTED_MODULE_47__.useAtom)(_EyeDropper__WEBPACK_IMPORTED_MODULE_40__.activeEyeDropperAtom, _jotai__WEBPACK_IMPORTED_MODULE_30__.jotaiScope);\n\n const renderJSONExportDialog = () => {\n if (!UIOptions.canvasActions.export) {\n return null;\n }\n\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_JSONExportDialog__WEBPACK_IMPORTED_MODULE_22__.JSONExportDialog, {\n elements: elements,\n appState: appState,\n files: files,\n actionManager: actionManager,\n exportOpts: UIOptions.canvasActions.export,\n canvas: canvas,\n setAppState: setAppState\n });\n };\n\n const renderImageExportDialog = () => {\n if (!UIOptions.canvasActions.saveAsImage) {\n return null;\n }\n\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_ImageExportDialog__WEBPACK_IMPORTED_MODULE_10__.ImageExportDialog, {\n elements: elements,\n appState: appState,\n files: files,\n actionManager: actionManager,\n onExportImage: onExportImage,\n onCloseRequest: () => setAppState({\n openDialog: null\n })\n });\n };\n\n const renderCanvasActions = () => (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"div\", Object.assign({\n style: {\n position: \"relative\"\n }\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(tunnels.MainMenuTunnel.Out, {}), renderWelcomeScreen && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(tunnels.WelcomeScreenMenuHintTunnel.Out, {})]\n }));\n\n const renderSelectedShapeActions = () => (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Section__WEBPACK_IMPORTED_MODULE_18__.Section, Object.assign({\n heading: \"selectedShapeActions\",\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(\"selected-shape-actions zen-mode-transition\", {\n \"transition-left\": appState.zenModeEnabled\n })\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Island__WEBPACK_IMPORTED_MODULE_13__.Island, Object.assign({\n className: _constants__WEBPACK_IMPORTED_MODULE_3__.CLASSES.SHAPE_ACTIONS_MENU,\n padding: 2,\n style: {\n // we want to make sure this doesn't overflow so subtracting the\n // approximate height of hamburgerMenu + footer\n maxHeight: `${appState.height - 166}px`\n }\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Actions__WEBPACK_IMPORTED_MODULE_8__.SelectedShapeActions, {\n appState: appState,\n elements: elements,\n renderAction: actionManager.renderAction\n })\n }))\n }));\n\n const renderFixedSideContainer = () => {\n var _a;\n\n const shouldRenderSelectedShapeActions = (0,_element__WEBPACK_IMPORTED_MODULE_4__.showSelectedShapeActions)(appState, elements);\n\n if (appState.viewModeEnabled) {\n return null;\n } //zsviczian\n\n\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_FixedSideContainer__WEBPACK_IMPORTED_MODULE_11__.FixedSideContainer, Object.assign({\n side: \"top\"\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"div\", Object.assign({\n className: \"App-menu App-menu_top\"\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(_Stack__WEBPACK_IMPORTED_MODULE_20__[\"default\"].Col, Object.assign({\n gap: 6,\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(\"App-menu_top__left\")\n }, {\n children: [renderCanvasActions(), shouldRenderSelectedShapeActions && renderSelectedShapeActions()]\n })), !appState.viewModeEnabled && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Section__WEBPACK_IMPORTED_MODULE_18__.Section, Object.assign({\n heading: \"shapes\",\n className: \"shapes-section\"\n }, {\n children: heading => (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"div\", Object.assign({\n style: {\n position: \"relative\"\n }\n }, {\n children: [renderWelcomeScreen && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(tunnels.WelcomeScreenToolbarHintTunnel.Out, {}), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Stack__WEBPACK_IMPORTED_MODULE_20__[\"default\"].Col, Object.assign({\n gap: 4,\n align: \"start\"\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(_Stack__WEBPACK_IMPORTED_MODULE_20__[\"default\"].Row, Object.assign({\n gap: 1,\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(\"App-toolbar-container\", {\n \"zen-mode\": appState.zenModeEnabled\n })\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(_Island__WEBPACK_IMPORTED_MODULE_13__.Island, Object.assign({\n padding: 1,\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(\"App-toolbar\", {\n \"zen-mode\": appState.zenModeEnabled\n })\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_HintViewer__WEBPACK_IMPORTED_MODULE_12__.HintViewer, {\n appState: appState,\n isMobile: device.isMobile || !(appState.viewModeEnabled || appState.zenModeEnabled) && appState.trayModeEnabled,\n device: device,\n app: app\n }), heading, (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(_Stack__WEBPACK_IMPORTED_MODULE_20__[\"default\"].Row, Object.assign({\n gap: 1\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_PenModeButton__WEBPACK_IMPORTED_MODULE_23__.PenModeButton, {\n zenModeEnabled: appState.zenModeEnabled,\n checked: appState.penMode,\n onChange: onPenModeToggle,\n title: (0,_i18n__WEBPACK_IMPORTED_MODULE_5__.t)(\"toolBar.penMode\"),\n penDetected: appState.penDetected\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_LockButton__WEBPACK_IMPORTED_MODULE_15__.LockButton, {\n checked: appState.activeTool.locked,\n onChange: onLockToggle,\n title: (0,_i18n__WEBPACK_IMPORTED_MODULE_5__.t)(\"toolBar.lock\")\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", {\n className: \"App-toolbar__divider\"\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_HandButton__WEBPACK_IMPORTED_MODULE_34__.HandButton, {\n checked: (0,_appState__WEBPACK_IMPORTED_MODULE_35__.isHandToolActive)(appState),\n onChange: () => onHandToolToggle(),\n title: (0,_i18n__WEBPACK_IMPORTED_MODULE_5__.t)(\"toolBar.hand\"),\n isMobile: true\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Actions__WEBPACK_IMPORTED_MODULE_8__.ShapesSwitcher, {\n appState: appState,\n activeTool: appState.activeTool,\n app: app\n })]\n }))]\n })), isCollaborating && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Island__WEBPACK_IMPORTED_MODULE_13__.Island, Object.assign({\n style: {\n marginLeft: 8,\n alignSelf: \"center\",\n height: \"fit-content\"\n }\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_LaserTool_LaserPointerButton__WEBPACK_IMPORTED_MODULE_46__.LaserPointerButton, {\n title: (0,_i18n__WEBPACK_IMPORTED_MODULE_5__.t)(\"toolBar.laser\"),\n checked: appState.activeTool.type === \"laser\",\n onChange: () => app.setActiveTool({\n type: \"laser\"\n }),\n isMobile: true\n })\n }))]\n }))\n }))]\n }))\n })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"div\", Object.assign({\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(\"layer-ui__wrapper__top-right zen-mode-transition\", {\n \"transition-right\": appState.zenModeEnabled\n })\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_UserList__WEBPACK_IMPORTED_MODULE_21__.UserList, {\n collaborators: appState.collaborators\n }), !appState.viewModeEnabled && ( //zsviczian\n renderTopRightUI === null || renderTopRightUI === void 0 ? void 0 : renderTopRightUI(device.isMobile, appState)), !appState.viewModeEnabled && ( // hide button when sidebar docked\n !isSidebarDocked || ((_a = appState.openSidebar) === null || _a === void 0 ? void 0 : _a.name) !== _constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_SIDEBAR.name) && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(tunnels.DefaultSidebarTriggerTunnel.Out, {})]\n }))]\n }))\n }));\n };\n\n const isTrayMode = !(appState.viewModeEnabled || appState.zenModeEnabled) && appState.trayModeEnabled; //zsviczian\n\n const isTrayModeOrMobile = device.isMobile || isTrayMode; //zsviczian\n\n const renderSidebars = () => {\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_DefaultSidebar__WEBPACK_IMPORTED_MODULE_39__.DefaultSidebar, {\n __fallback: true,\n onDock: docked => {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_24__.trackEvent)(\"sidebar\", `toggleDock (${docked ? \"dock\" : \"undock\"})`, `(${device.isMobile ? \"mobile\" : \"desktop\"})`);\n }\n });\n };\n\n const isSidebarDocked = (0,jotai__WEBPACK_IMPORTED_MODULE_47__.useAtomValue)(_Sidebar_Sidebar__WEBPACK_IMPORTED_MODULE_29__.isSidebarDockedAtom, _jotai__WEBPACK_IMPORTED_MODULE_30__.jotaiScope);\n\n const layerUIJSX = (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n children: [children, (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(DefaultMainMenu, {\n UIOptions: UIOptions\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_DefaultSidebar__WEBPACK_IMPORTED_MODULE_39__.DefaultSidebar.Trigger, {\n __fallback: true,\n icon: _icons__WEBPACK_IMPORTED_MODULE_37__.LibraryIcon,\n title: (0,_utils__WEBPACK_IMPORTED_MODULE_7__.capitalizeString)((0,_i18n__WEBPACK_IMPORTED_MODULE_5__.t)(\"toolBar.library\")),\n onToggle: open => {\n if (open) {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_24__.trackEvent)(\"sidebar\", `${_constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_SIDEBAR.name} (open)`, `button (${device.isMobile ? \"mobile\" : \"desktop\"})`);\n }\n },\n tab: _constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_SIDEBAR.defaultTab\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(DefaultOverwriteConfirmDialog, {}), appState.isLoading && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_LoadingMessage__WEBPACK_IMPORTED_MODULE_14__.LoadingMessage, {\n delay: 250\n }), appState.errorMessage && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_ErrorDialog__WEBPACK_IMPORTED_MODULE_9__.ErrorDialog, Object.assign({\n onClose: () => setAppState({\n errorMessage: null\n })\n }, {\n children: appState.errorMessage\n })), eyeDropperState && //!device.isMobile && //zsviczian\n (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_EyeDropper__WEBPACK_IMPORTED_MODULE_40__.EyeDropper, {\n colorPickerType: eyeDropperState.colorPickerType,\n onCancel: () => {\n setEyeDropperState(null);\n },\n onChange: (colorPickerType, color, selectedElements, {\n altKey\n }) => {\n var _a;\n\n if (colorPickerType !== \"elementBackground\" && colorPickerType !== \"elementStroke\") {\n return;\n }\n\n if (selectedElements.length) {\n for (const element of selectedElements) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_43__.mutateElement)(element, {\n [altKey && eyeDropperState.swapPreviewOnAlt ? colorPickerType === \"elementBackground\" ? \"strokeColor\" : \"backgroundColor\" : colorPickerType === \"elementBackground\" ? \"backgroundColor\" : \"strokeColor\"]: color\n }, false);\n _scene_ShapeCache__WEBPACK_IMPORTED_MODULE_44__.ShapeCache[\"delete\"](element);\n }\n\n (_a = _scene_Scene__WEBPACK_IMPORTED_MODULE_45__[\"default\"].getScene(selectedElements[0])) === null || _a === void 0 ? void 0 : _a.informMutation();\n } else if (colorPickerType === \"elementBackground\") {\n setAppState({\n currentItemBackgroundColor: color\n });\n } else {\n setAppState({\n currentItemStrokeColor: color\n });\n }\n },\n onSelect: (color, event) => {\n var _a;\n\n setEyeDropperState(state => {\n return (state === null || state === void 0 ? void 0 : state.keepOpenOnAlt) && event.altKey ? state : null;\n });\n (_a = eyeDropperState === null || eyeDropperState === void 0 ? void 0 : eyeDropperState.onSelect) === null || _a === void 0 ? void 0 : _a.call(eyeDropperState, color, event);\n }\n }), appState.openDialog === \"help\" && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_HelpDialog__WEBPACK_IMPORTED_MODULE_19__.HelpDialog, {\n onClose: () => {\n setAppState({\n openDialog: null\n });\n }\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_ActiveConfirmDialog__WEBPACK_IMPORTED_MODULE_32__.ActiveConfirmDialog, {}), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(tunnels.OverwriteConfirmDialogTunnel.Out, {}), renderImageExportDialog(), renderJSONExportDialog(), appState.pasteDialog.shown && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_PasteChartDialog__WEBPACK_IMPORTED_MODULE_17__.PasteChartDialog, {\n setAppState: setAppState,\n appState: appState,\n onClose: () => setAppState({\n pasteDialog: {\n shown: false,\n data: null\n }\n })\n }), (isTrayMode || device.isMobile) && //zsviczian Added isTrayMode condition\n (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_MobileMenu__WEBPACK_IMPORTED_MODULE_16__.MobileMenu, {\n app: app,\n appState: appState,\n elements: elements,\n actionManager: actionManager,\n renderJSONExportDialog: renderJSONExportDialog,\n renderImageExportDialog: renderImageExportDialog,\n setAppState: setAppState,\n onLockToggle: onLockToggle,\n onHandToolToggle: onHandToolToggle,\n onPenModeToggle: onPenModeToggle,\n renderTopRightUI: renderTopRightUI,\n renderCustomStats: renderCustomStats,\n renderSidebars: renderSidebars,\n device: device,\n renderWelcomeScreen: renderWelcomeScreen\n }), !isTrayModeOrMobile && //zsviczian changed from !device.isMobile\n (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"div\", Object.assign({\n className: \"layer-ui__wrapper\",\n style: appState.openSidebar && isSidebarDocked && device.canDeviceFitSidebar ? {\n width: `calc(100% - ${_constants__WEBPACK_IMPORTED_MODULE_3__.LIBRARY_SIDEBAR_WIDTH}px)`\n } : {}\n }, {\n children: [renderWelcomeScreen && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(tunnels.WelcomeScreenCenterTunnel.Out, {}), renderFixedSideContainer(), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_footer_Footer__WEBPACK_IMPORTED_MODULE_28__[\"default\"], {\n appState: appState,\n actionManager: actionManager,\n showExitZenModeBtn: showExitZenModeBtn,\n renderWelcomeScreen: renderWelcomeScreen\n }), appState.showStats && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Stats__WEBPACK_IMPORTED_MODULE_26__.Stats, {\n appState: appState,\n setAppState: setAppState,\n elements: elements,\n onClose: () => {\n actionManager.executeAction(_actions_actionToggleStats__WEBPACK_IMPORTED_MODULE_27__.actionToggleStats);\n },\n renderCustomStats: renderCustomStats\n }), appState.scrolledOutside && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"button\", Object.assign({\n className: \"scroll-back-to-content\",\n onClick: () => {\n setAppState(appState => Object.assign({}, (0,_scene__WEBPACK_IMPORTED_MODULE_6__.calculateScrollCenter)(elements, appState)));\n }\n }, {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_5__.t)(\"buttons.scrollBackToContent\")\n }))]\n })), renderSidebars()]\n })]\n });\n\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_context_ui_appState__WEBPACK_IMPORTED_MODULE_38__.UIAppStateContext.Provider, Object.assign({\n value: appState\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(jotai__WEBPACK_IMPORTED_MODULE_47__.Provider, Object.assign({\n scope: tunnels.jotaiScope\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_context_tunnels__WEBPACK_IMPORTED_MODULE_36__.TunnelsContext.Provider, Object.assign({\n value: tunnels\n }, {\n children: layerUIJSX\n }))\n }))\n }));\n};\n\nconst stripIrrelevantAppStateProps = appState => {\n const {\n suggestedBindings,\n startBoundElement,\n cursorButton,\n scrollX,\n scrollY\n } = appState,\n ret = __rest(appState, [\"suggestedBindings\", \"startBoundElement\", \"cursorButton\", \"scrollX\", \"scrollY\"]);\n\n return ret;\n};\n\nconst areEqual = (prevProps, nextProps) => {\n // short-circuit early\n if (prevProps.children !== nextProps.children) {\n return false;\n }\n\n const {\n canvas: _pC,\n appState: prevAppState\n } = prevProps,\n prev = __rest(prevProps, [\"canvas\", \"appState\"]);\n\n const {\n canvas: _nC,\n appState: nextAppState\n } = nextProps,\n next = __rest(nextProps, [\"canvas\", \"appState\"]);\n\n return (0,_utils__WEBPACK_IMPORTED_MODULE_7__.isShallowEqual)( // asserting AppState because we're being passed the whole AppState\n // but resolve to only the UI-relevant props\n stripIrrelevantAppStateProps(prevAppState), stripIrrelevantAppStateProps(nextAppState), {\n selectedElementIds: _utils__WEBPACK_IMPORTED_MODULE_7__.isShallowEqual,\n selectedGroupIds: _utils__WEBPACK_IMPORTED_MODULE_7__.isShallowEqual\n }) && (0,_utils__WEBPACK_IMPORTED_MODULE_7__.isShallowEqual)(prev, next);\n};\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (react__WEBPACK_IMPORTED_MODULE_2___default().memo(LayerUI, areEqual));\n\n//# sourceURL=webpack://ExcalidrawLib/../../components/LayerUI.tsx?");
2757
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react/jsx-runtime */ \"../../../node_modules/react/jsx-runtime.js\");\n/* harmony import */ var clsx__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! clsx */ \"../../../node_modules/clsx/dist/clsx.m.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react */ \"react\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _element__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../element */ \"../../element/index.ts\");\n/* harmony import */ var _i18n__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../i18n */ \"../../i18n.ts\");\n/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../scene */ \"../../scene/index.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _Actions__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./Actions */ \"../../components/Actions.tsx\");\n/* harmony import */ var _ErrorDialog__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./ErrorDialog */ \"../../components/ErrorDialog.tsx\");\n/* harmony import */ var _ImageExportDialog__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./ImageExportDialog */ \"../../components/ImageExportDialog.tsx\");\n/* harmony import */ var _FixedSideContainer__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./FixedSideContainer */ \"../../components/FixedSideContainer.tsx\");\n/* harmony import */ var _HintViewer__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./HintViewer */ \"../../components/HintViewer.tsx\");\n/* harmony import */ var _Island__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./Island */ \"../../components/Island.tsx\");\n/* harmony import */ var _LoadingMessage__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./LoadingMessage */ \"../../components/LoadingMessage.tsx\");\n/* harmony import */ var _LockButton__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./LockButton */ \"../../components/LockButton.tsx\");\n/* harmony import */ var _MobileMenu__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./MobileMenu */ \"../../components/MobileMenu.tsx\");\n/* harmony import */ var _PasteChartDialog__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./PasteChartDialog */ \"../../components/PasteChartDialog.tsx\");\n/* harmony import */ var _Section__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./Section */ \"../../components/Section.tsx\");\n/* harmony import */ var _HelpDialog__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./HelpDialog */ \"../../components/HelpDialog.tsx\");\n/* harmony import */ var _Stack__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./Stack */ \"../../components/Stack.tsx\");\n/* harmony import */ var _UserList__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./UserList */ \"../../components/UserList.tsx\");\n/* harmony import */ var _JSONExportDialog__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./JSONExportDialog */ \"../../components/JSONExportDialog.tsx\");\n/* harmony import */ var _PenModeButton__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./PenModeButton */ \"../../components/PenModeButton.tsx\");\n/* harmony import */ var _analytics__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ../analytics */ \"../../analytics.ts\");\n/* harmony import */ var _components_App__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ../components/App */ \"../../components/App.tsx\");\n/* harmony import */ var _Stats__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./Stats */ \"../../components/Stats.tsx\");\n/* harmony import */ var _actions_actionToggleStats__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ../actions/actionToggleStats */ \"../../actions/actionToggleStats.tsx\");\n/* harmony import */ var _footer_Footer__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./footer/Footer */ \"../../components/footer/Footer.tsx\");\n/* harmony import */ var _Sidebar_Sidebar__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./Sidebar/Sidebar */ \"../../components/Sidebar/Sidebar.tsx\");\n/* harmony import */ var _jotai__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ../jotai */ \"../../jotai.ts\");\n/* harmony import */ var jotai__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(/*! jotai */ \"../../../node_modules/jotai/esm/index.mjs\");\n/* harmony import */ var _main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ./main-menu/MainMenu */ \"../../components/main-menu/MainMenu.tsx\");\n/* harmony import */ var _ActiveConfirmDialog__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ./ActiveConfirmDialog */ \"../../components/ActiveConfirmDialog.tsx\");\n/* harmony import */ var _OverwriteConfirm_OverwriteConfirm__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ./OverwriteConfirm/OverwriteConfirm */ \"../../components/OverwriteConfirm/OverwriteConfirm.tsx\");\n/* harmony import */ var _HandButton__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ./HandButton */ \"../../components/HandButton.tsx\");\n/* harmony import */ var _appState__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ../appState */ \"../../appState.ts\");\n/* harmony import */ var _context_tunnels__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ../context/tunnels */ \"../../context/tunnels.ts\");\n/* harmony import */ var _icons__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ./icons */ \"../../components/icons.tsx\");\n/* harmony import */ var _context_ui_appState__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! ../context/ui-appState */ \"../../context/ui-appState.ts\");\n/* harmony import */ var _DefaultSidebar__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(/*! ./DefaultSidebar */ \"../../components/DefaultSidebar.tsx\");\n/* harmony import */ var _EyeDropper__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(/*! ./EyeDropper */ \"../../components/EyeDropper.tsx\");\n/* harmony import */ var _LayerUI_scss__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(/*! ./LayerUI.scss */ \"../../components/LayerUI.scss\");\n/* harmony import */ var _Toolbar_scss__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(/*! ./Toolbar.scss */ \"../../components/Toolbar.scss\");\n/* harmony import */ var _element_mutateElement__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(/*! ../element/mutateElement */ \"../../element/mutateElement.ts\");\n/* harmony import */ var _scene_ShapeCache__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(/*! ../scene/ShapeCache */ \"../../scene/ShapeCache.ts\");\n/* harmony import */ var _scene_Scene__WEBPACK_IMPORTED_MODULE_45__ = __webpack_require__(/*! ../scene/Scene */ \"../../scene/Scene.ts\");\n/* harmony import */ var _LaserTool_LaserPointerButton__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(/*! ./LaserTool/LaserPointerButton */ \"../../components/LaserTool/LaserPointerButton.tsx\");\nvar __rest = undefined && undefined.__rest || function (s, e) {\n var t = {};\n\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];\n\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];\n }\n return t;\n};\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst DefaultMainMenu = ({\n UIOptions\n}) => {\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__[\"default\"], Object.assign({\n __fallback: true\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__[\"default\"].DefaultItems.LoadScene, {}), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__[\"default\"].DefaultItems.SaveToActiveFile, {}), UIOptions.canvasActions.export && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__[\"default\"].DefaultItems.Export, {}), UIOptions.canvasActions.saveAsImage && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__[\"default\"].DefaultItems.SaveAsImage, {}), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__[\"default\"].DefaultItems.Help, {}), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__[\"default\"].DefaultItems.ClearCanvas, {}), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__[\"default\"].Separator, {}), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__[\"default\"].Group, Object.assign({\n title: \"Excalidraw links\"\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__[\"default\"].DefaultItems.Socials, {})\n })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__[\"default\"].Separator, {}), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__[\"default\"].DefaultItems.ToggleTheme, {}), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_31__[\"default\"].DefaultItems.ChangeCanvasBackground, {})]\n }));\n};\n\nconst DefaultOverwriteConfirmDialog = () => {\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(_OverwriteConfirm_OverwriteConfirm__WEBPACK_IMPORTED_MODULE_33__.OverwriteConfirmDialog, Object.assign({\n __fallback: true\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_OverwriteConfirm_OverwriteConfirm__WEBPACK_IMPORTED_MODULE_33__.OverwriteConfirmDialog.Actions.SaveToDisk, {}), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_OverwriteConfirm_OverwriteConfirm__WEBPACK_IMPORTED_MODULE_33__.OverwriteConfirmDialog.Actions.ExportToImage, {})]\n }));\n};\n\nconst LayerUI = ({\n actionManager,\n appState,\n files,\n setAppState,\n elements,\n canvas,\n onLockToggle,\n onHandToolToggle,\n onPenModeToggle,\n showExitZenModeBtn,\n renderTopRightUI,\n renderCustomStats,\n UIOptions,\n onExportImage,\n renderWelcomeScreen,\n children,\n app,\n isCollaborating\n}) => {\n const device = (0,_components_App__WEBPACK_IMPORTED_MODULE_25__.useDevice)();\n const tunnels = (0,_context_tunnels__WEBPACK_IMPORTED_MODULE_36__.useInitializeTunnels)();\n const [eyeDropperState, setEyeDropperState] = (0,jotai__WEBPACK_IMPORTED_MODULE_47__.useAtom)(_EyeDropper__WEBPACK_IMPORTED_MODULE_40__.activeEyeDropperAtom, _jotai__WEBPACK_IMPORTED_MODULE_30__.jotaiScope);\n\n const renderJSONExportDialog = () => {\n if (!UIOptions.canvasActions.export) {\n return null;\n }\n\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_JSONExportDialog__WEBPACK_IMPORTED_MODULE_22__.JSONExportDialog, {\n elements: elements,\n appState: appState,\n files: files,\n actionManager: actionManager,\n exportOpts: UIOptions.canvasActions.export,\n canvas: canvas,\n setAppState: setAppState\n });\n };\n\n const renderImageExportDialog = () => {\n if (!UIOptions.canvasActions.saveAsImage) {\n return null;\n }\n\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_ImageExportDialog__WEBPACK_IMPORTED_MODULE_10__.ImageExportDialog, {\n elements: elements,\n appState: appState,\n files: files,\n actionManager: actionManager,\n onExportImage: onExportImage,\n onCloseRequest: () => setAppState({\n openDialog: null\n })\n });\n };\n\n const renderCanvasActions = () => (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"div\", Object.assign({\n style: {\n position: \"relative\"\n }\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(tunnels.MainMenuTunnel.Out, {}), renderWelcomeScreen && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(tunnels.WelcomeScreenMenuHintTunnel.Out, {})]\n }));\n\n const renderSelectedShapeActions = () => (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Section__WEBPACK_IMPORTED_MODULE_18__.Section, Object.assign({\n heading: \"selectedShapeActions\",\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(\"selected-shape-actions zen-mode-transition\", {\n \"transition-left\": appState.zenModeEnabled\n })\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Island__WEBPACK_IMPORTED_MODULE_13__.Island, Object.assign({\n className: _constants__WEBPACK_IMPORTED_MODULE_3__.CLASSES.SHAPE_ACTIONS_MENU,\n padding: 2,\n style: {\n // we want to make sure this doesn't overflow so subtracting the\n // approximate height of hamburgerMenu + footer\n maxHeight: `${appState.height - 166}px`\n }\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Actions__WEBPACK_IMPORTED_MODULE_8__.SelectedShapeActions, {\n appState: appState,\n elements: elements,\n renderAction: actionManager.renderAction\n })\n }))\n }));\n\n const renderFixedSideContainer = () => {\n var _a;\n\n const shouldRenderSelectedShapeActions = (0,_element__WEBPACK_IMPORTED_MODULE_4__.showSelectedShapeActions)(appState, elements);\n\n if (appState.viewModeEnabled) {\n return null;\n } //zsviczian\n\n\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_FixedSideContainer__WEBPACK_IMPORTED_MODULE_11__.FixedSideContainer, Object.assign({\n side: \"top\"\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"div\", Object.assign({\n className: \"App-menu App-menu_top\"\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(_Stack__WEBPACK_IMPORTED_MODULE_20__[\"default\"].Col, Object.assign({\n gap: 6,\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(\"App-menu_top__left\")\n }, {\n children: [renderCanvasActions(), shouldRenderSelectedShapeActions && renderSelectedShapeActions()]\n })), !appState.viewModeEnabled && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Section__WEBPACK_IMPORTED_MODULE_18__.Section, Object.assign({\n heading: \"shapes\",\n className: \"shapes-section\"\n }, {\n children: heading => (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"div\", Object.assign({\n style: {\n position: \"relative\"\n }\n }, {\n children: [renderWelcomeScreen && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(tunnels.WelcomeScreenToolbarHintTunnel.Out, {}), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Stack__WEBPACK_IMPORTED_MODULE_20__[\"default\"].Col, Object.assign({\n gap: 4,\n align: \"start\"\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(_Stack__WEBPACK_IMPORTED_MODULE_20__[\"default\"].Row, Object.assign({\n gap: 1,\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(\"App-toolbar-container\", {\n \"zen-mode\": appState.zenModeEnabled\n })\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(_Island__WEBPACK_IMPORTED_MODULE_13__.Island, Object.assign({\n padding: 1,\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(\"App-toolbar\", {\n \"zen-mode\": appState.zenModeEnabled\n })\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_HintViewer__WEBPACK_IMPORTED_MODULE_12__.HintViewer, {\n appState: appState,\n isMobile: device.isMobile || !(appState.viewModeEnabled || appState.zenModeEnabled) && appState.trayModeEnabled,\n device: device,\n app: app\n }), heading, (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(_Stack__WEBPACK_IMPORTED_MODULE_20__[\"default\"].Row, Object.assign({\n gap: 1\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_PenModeButton__WEBPACK_IMPORTED_MODULE_23__.PenModeButton, {\n zenModeEnabled: appState.zenModeEnabled,\n checked: appState.penMode,\n onChange: onPenModeToggle,\n title: (0,_i18n__WEBPACK_IMPORTED_MODULE_5__.t)(\"toolBar.penMode\"),\n penDetected: appState.penDetected\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_LockButton__WEBPACK_IMPORTED_MODULE_15__.LockButton, {\n checked: appState.activeTool.locked,\n onChange: onLockToggle,\n title: (0,_i18n__WEBPACK_IMPORTED_MODULE_5__.t)(\"toolBar.lock\")\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", {\n className: \"App-toolbar__divider\"\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_HandButton__WEBPACK_IMPORTED_MODULE_34__.HandButton, {\n checked: (0,_appState__WEBPACK_IMPORTED_MODULE_35__.isHandToolActive)(appState),\n onChange: () => onHandToolToggle(),\n title: (0,_i18n__WEBPACK_IMPORTED_MODULE_5__.t)(\"toolBar.hand\"),\n isMobile: true\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Actions__WEBPACK_IMPORTED_MODULE_8__.ShapesSwitcher, {\n appState: appState,\n activeTool: appState.activeTool,\n app: app\n })]\n }))]\n })), isCollaborating && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Island__WEBPACK_IMPORTED_MODULE_13__.Island, Object.assign({\n style: {\n marginLeft: 8,\n alignSelf: \"center\",\n height: \"fit-content\"\n }\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_LaserTool_LaserPointerButton__WEBPACK_IMPORTED_MODULE_46__.LaserPointerButton, {\n title: (0,_i18n__WEBPACK_IMPORTED_MODULE_5__.t)(\"toolBar.laser\"),\n checked: appState.activeTool.type === \"laser\",\n onChange: () => app.setActiveTool({\n type: \"laser\"\n }),\n isMobile: true\n })\n }))]\n }))\n }))]\n }))\n })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"div\", Object.assign({\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(\"layer-ui__wrapper__top-right zen-mode-transition\", {\n \"transition-right\": appState.zenModeEnabled\n })\n }, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_UserList__WEBPACK_IMPORTED_MODULE_21__.UserList, {\n collaborators: appState.collaborators\n }), !appState.viewModeEnabled && ( //zsviczian\n renderTopRightUI === null || renderTopRightUI === void 0 ? void 0 : renderTopRightUI(device.isMobile, appState)), !appState.viewModeEnabled && ( // hide button when sidebar docked\n !isSidebarDocked || ((_a = appState.openSidebar) === null || _a === void 0 ? void 0 : _a.name) !== _constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_SIDEBAR.name) && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(tunnels.DefaultSidebarTriggerTunnel.Out, {})]\n }))]\n }))\n }));\n };\n\n const isTrayModeOrMobile = device.isMobile || !(appState.viewModeEnabled || appState.zenModeEnabled) && appState.trayModeEnabled; //zsviczian\n\n const renderSidebars = () => {\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_DefaultSidebar__WEBPACK_IMPORTED_MODULE_39__.DefaultSidebar, {\n __fallback: true,\n onDock: docked => {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_24__.trackEvent)(\"sidebar\", `toggleDock (${docked ? \"dock\" : \"undock\"})`, `(${device.isMobile ? \"mobile\" : \"desktop\"})`);\n }\n });\n };\n\n const isSidebarDocked = (0,jotai__WEBPACK_IMPORTED_MODULE_47__.useAtomValue)(_Sidebar_Sidebar__WEBPACK_IMPORTED_MODULE_29__.isSidebarDockedAtom, _jotai__WEBPACK_IMPORTED_MODULE_30__.jotaiScope);\n\n const layerUIJSX = (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n children: [children, (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(DefaultMainMenu, {\n UIOptions: UIOptions\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_DefaultSidebar__WEBPACK_IMPORTED_MODULE_39__.DefaultSidebar.Trigger, {\n __fallback: true,\n icon: _icons__WEBPACK_IMPORTED_MODULE_37__.LibraryIcon,\n title: (0,_utils__WEBPACK_IMPORTED_MODULE_7__.capitalizeString)((0,_i18n__WEBPACK_IMPORTED_MODULE_5__.t)(\"toolBar.library\")),\n onToggle: open => {\n if (open) {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_24__.trackEvent)(\"sidebar\", `${_constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_SIDEBAR.name} (open)`, `button (${device.isMobile ? \"mobile\" : \"desktop\"})`);\n }\n },\n tab: _constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_SIDEBAR.defaultTab\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(DefaultOverwriteConfirmDialog, {}), appState.isLoading && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_LoadingMessage__WEBPACK_IMPORTED_MODULE_14__.LoadingMessage, {\n delay: 250\n }), appState.errorMessage && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_ErrorDialog__WEBPACK_IMPORTED_MODULE_9__.ErrorDialog, Object.assign({\n onClose: () => setAppState({\n errorMessage: null\n })\n }, {\n children: appState.errorMessage\n })), eyeDropperState && //!device.isMobile && //zsviczian\n (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_EyeDropper__WEBPACK_IMPORTED_MODULE_40__.EyeDropper, {\n colorPickerType: eyeDropperState.colorPickerType,\n onCancel: () => {\n setEyeDropperState(null);\n },\n onChange: (colorPickerType, color, selectedElements, {\n altKey\n }) => {\n var _a;\n\n if (colorPickerType !== \"elementBackground\" && colorPickerType !== \"elementStroke\") {\n return;\n }\n\n if (selectedElements.length) {\n for (const element of selectedElements) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_43__.mutateElement)(element, {\n [altKey && eyeDropperState.swapPreviewOnAlt ? colorPickerType === \"elementBackground\" ? \"strokeColor\" : \"backgroundColor\" : colorPickerType === \"elementBackground\" ? \"backgroundColor\" : \"strokeColor\"]: color\n }, false);\n _scene_ShapeCache__WEBPACK_IMPORTED_MODULE_44__.ShapeCache[\"delete\"](element);\n }\n\n (_a = _scene_Scene__WEBPACK_IMPORTED_MODULE_45__[\"default\"].getScene(selectedElements[0])) === null || _a === void 0 ? void 0 : _a.informMutation();\n } else if (colorPickerType === \"elementBackground\") {\n setAppState({\n currentItemBackgroundColor: color\n });\n } else {\n setAppState({\n currentItemStrokeColor: color\n });\n }\n },\n onSelect: (color, event) => {\n var _a;\n\n setEyeDropperState(state => {\n return (state === null || state === void 0 ? void 0 : state.keepOpenOnAlt) && event.altKey ? state : null;\n });\n (_a = eyeDropperState === null || eyeDropperState === void 0 ? void 0 : eyeDropperState.onSelect) === null || _a === void 0 ? void 0 : _a.call(eyeDropperState, color, event);\n }\n }), appState.openDialog === \"help\" && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_HelpDialog__WEBPACK_IMPORTED_MODULE_19__.HelpDialog, {\n onClose: () => {\n setAppState({\n openDialog: null\n });\n }\n }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_ActiveConfirmDialog__WEBPACK_IMPORTED_MODULE_32__.ActiveConfirmDialog, {}), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(tunnels.OverwriteConfirmDialogTunnel.Out, {}), renderImageExportDialog(), renderJSONExportDialog(), appState.pasteDialog.shown && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_PasteChartDialog__WEBPACK_IMPORTED_MODULE_17__.PasteChartDialog, {\n setAppState: setAppState,\n appState: appState,\n onClose: () => setAppState({\n pasteDialog: {\n shown: false,\n data: null\n }\n })\n }), isTrayModeOrMobile && //zsviczian Added isTrayMode condition\n (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_MobileMenu__WEBPACK_IMPORTED_MODULE_16__.MobileMenu, {\n app: app,\n appState: appState,\n elements: elements,\n actionManager: actionManager,\n renderJSONExportDialog: renderJSONExportDialog,\n renderImageExportDialog: renderImageExportDialog,\n setAppState: setAppState,\n onLockToggle: onLockToggle,\n onHandToolToggle: onHandToolToggle,\n onPenModeToggle: onPenModeToggle,\n renderTopRightUI: renderTopRightUI,\n renderCustomStats: renderCustomStats,\n renderSidebars: renderSidebars,\n device: device,\n renderWelcomeScreen: renderWelcomeScreen\n }), !isTrayModeOrMobile && //zsviczian changed from !device.isMobile\n (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(\"div\", Object.assign({\n className: \"layer-ui__wrapper\",\n style: appState.openSidebar && isSidebarDocked && device.canDeviceFitSidebar ? {\n width: `calc(100% - ${_constants__WEBPACK_IMPORTED_MODULE_3__.LIBRARY_SIDEBAR_WIDTH}px)`\n } : {}\n }, {\n children: [renderWelcomeScreen && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(tunnels.WelcomeScreenCenterTunnel.Out, {}), renderFixedSideContainer(), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_footer_Footer__WEBPACK_IMPORTED_MODULE_28__[\"default\"], {\n appState: appState,\n actionManager: actionManager,\n showExitZenModeBtn: showExitZenModeBtn,\n renderWelcomeScreen: renderWelcomeScreen\n }), appState.showStats && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Stats__WEBPACK_IMPORTED_MODULE_26__.Stats, {\n appState: appState,\n setAppState: setAppState,\n elements: elements,\n onClose: () => {\n actionManager.executeAction(_actions_actionToggleStats__WEBPACK_IMPORTED_MODULE_27__.actionToggleStats);\n },\n renderCustomStats: renderCustomStats\n }), appState.scrolledOutside && (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"button\", Object.assign({\n className: \"scroll-back-to-content\",\n onClick: () => {\n setAppState(appState => Object.assign({}, (0,_scene__WEBPACK_IMPORTED_MODULE_6__.calculateScrollCenter)(elements, appState)));\n }\n }, {\n children: (0,_i18n__WEBPACK_IMPORTED_MODULE_5__.t)(\"buttons.scrollBackToContent\")\n }))]\n })), renderSidebars()]\n })]\n });\n\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_context_ui_appState__WEBPACK_IMPORTED_MODULE_38__.UIAppStateContext.Provider, Object.assign({\n value: appState\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(jotai__WEBPACK_IMPORTED_MODULE_47__.Provider, Object.assign({\n scope: tunnels.jotaiScope\n }, {\n children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_context_tunnels__WEBPACK_IMPORTED_MODULE_36__.TunnelsContext.Provider, Object.assign({\n value: tunnels\n }, {\n children: layerUIJSX\n }))\n }))\n }));\n};\n\nconst stripIrrelevantAppStateProps = appState => {\n const {\n suggestedBindings,\n startBoundElement,\n cursorButton,\n scrollX,\n scrollY\n } = appState,\n ret = __rest(appState, [\"suggestedBindings\", \"startBoundElement\", \"cursorButton\", \"scrollX\", \"scrollY\"]);\n\n return ret;\n};\n\nconst areEqual = (prevProps, nextProps) => {\n // short-circuit early\n if (prevProps.children !== nextProps.children) {\n return false;\n }\n\n const {\n canvas: _pC,\n appState: prevAppState\n } = prevProps,\n prev = __rest(prevProps, [\"canvas\", \"appState\"]);\n\n const {\n canvas: _nC,\n appState: nextAppState\n } = nextProps,\n next = __rest(nextProps, [\"canvas\", \"appState\"]);\n\n return (0,_utils__WEBPACK_IMPORTED_MODULE_7__.isShallowEqual)( // asserting AppState because we're being passed the whole AppState\n // but resolve to only the UI-relevant props\n stripIrrelevantAppStateProps(prevAppState), stripIrrelevantAppStateProps(nextAppState), {\n selectedElementIds: _utils__WEBPACK_IMPORTED_MODULE_7__.isShallowEqual,\n selectedGroupIds: _utils__WEBPACK_IMPORTED_MODULE_7__.isShallowEqual\n }) && (0,_utils__WEBPACK_IMPORTED_MODULE_7__.isShallowEqual)(prev, next);\n};\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (react__WEBPACK_IMPORTED_MODULE_2___default().memo(LayerUI, areEqual));\n\n//# sourceURL=webpack://ExcalidrawLib/../../components/LayerUI.tsx?");
2758
2758
 
2759
2759
  /***/ }),
2760
2760
 
@@ -3458,7 +3458,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
3458
3458
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3459
3459
 
3460
3460
  "use strict";
3461
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"ACTIVE_THRESHOLD\": () => (/* binding */ ACTIVE_THRESHOLD),\n/* harmony export */ \"APP_NAME\": () => (/* binding */ APP_NAME),\n/* harmony export */ \"ARROW_LABEL_FONT_SIZE_TO_MIN_WIDTH_RATIO\": () => (/* binding */ ARROW_LABEL_FONT_SIZE_TO_MIN_WIDTH_RATIO),\n/* harmony export */ \"ARROW_LABEL_WIDTH_FRACTION\": () => (/* binding */ ARROW_LABEL_WIDTH_FRACTION),\n/* harmony export */ \"BOUND_TEXT_PADDING\": () => (/* binding */ BOUND_TEXT_PADDING),\n/* harmony export */ \"CANVAS_ONLY_ACTIONS\": () => (/* binding */ CANVAS_ONLY_ACTIONS),\n/* harmony export */ \"CLASSES\": () => (/* binding */ CLASSES),\n/* harmony export */ \"COLOR_NAMES\": () => (/* binding */ COLOR_NAMES),\n/* harmony export */ \"CURSOR_TYPE\": () => (/* binding */ CURSOR_TYPE),\n/* harmony export */ \"DEFAULT_ADAPTIVE_RADIUS\": () => (/* binding */ DEFAULT_ADAPTIVE_RADIUS),\n/* harmony export */ \"DEFAULT_ELEMENT_PROPS\": () => (/* binding */ DEFAULT_ELEMENT_PROPS),\n/* harmony export */ \"DEFAULT_EXPORT_PADDING\": () => (/* binding */ DEFAULT_EXPORT_PADDING),\n/* harmony export */ \"DEFAULT_FONT_FAMILY\": () => (/* binding */ DEFAULT_FONT_FAMILY),\n/* harmony export */ \"DEFAULT_FONT_SIZE\": () => (/* binding */ DEFAULT_FONT_SIZE),\n/* harmony export */ \"DEFAULT_MAX_IMAGE_WIDTH_OR_HEIGHT\": () => (/* binding */ DEFAULT_MAX_IMAGE_WIDTH_OR_HEIGHT),\n/* harmony export */ \"DEFAULT_PROPORTIONAL_RADIUS\": () => (/* binding */ DEFAULT_PROPORTIONAL_RADIUS),\n/* harmony export */ \"DEFAULT_SIDEBAR\": () => (/* binding */ DEFAULT_SIDEBAR),\n/* harmony export */ \"DEFAULT_TEXT_ALIGN\": () => (/* binding */ DEFAULT_TEXT_ALIGN),\n/* harmony export */ \"DEFAULT_UI_OPTIONS\": () => (/* binding */ DEFAULT_UI_OPTIONS),\n/* harmony export */ \"DEFAULT_VERSION\": () => (/* binding */ DEFAULT_VERSION),\n/* harmony export */ \"DEFAULT_VERTICAL_ALIGN\": () => (/* binding */ DEFAULT_VERTICAL_ALIGN),\n/* harmony export */ \"DRAGGING_THRESHOLD\": () => (/* binding */ DRAGGING_THRESHOLD),\n/* harmony export */ \"ELEMENT_READY_TO_ERASE_OPACITY\": () => (/* binding */ ELEMENT_READY_TO_ERASE_OPACITY),\n/* harmony export */ \"ELEMENT_SHIFT_TRANSLATE_AMOUNT\": () => (/* binding */ ELEMENT_SHIFT_TRANSLATE_AMOUNT),\n/* harmony export */ \"ELEMENT_TRANSLATE_AMOUNT\": () => (/* binding */ ELEMENT_TRANSLATE_AMOUNT),\n/* harmony export */ \"ENCRYPTION_KEY_BITS\": () => (/* binding */ ENCRYPTION_KEY_BITS),\n/* harmony export */ \"ENV\": () => (/* binding */ ENV),\n/* harmony export */ \"EVENT\": () => (/* binding */ EVENT),\n/* harmony export */ \"EXPORT_DATA_TYPES\": () => (/* binding */ EXPORT_DATA_TYPES),\n/* harmony export */ \"EXPORT_IMAGE_TYPES\": () => (/* binding */ EXPORT_IMAGE_TYPES),\n/* harmony export */ \"EXPORT_SCALES\": () => (/* binding */ EXPORT_SCALES),\n/* harmony export */ \"EXPORT_SOURCE\": () => (/* binding */ EXPORT_SOURCE),\n/* harmony export */ \"FONT_FAMILY\": () => (/* binding */ FONT_FAMILY),\n/* harmony export */ \"FRAME_STYLE\": () => (/* binding */ FRAME_STYLE),\n/* harmony export */ \"GRID_SIZE\": () => (/* binding */ GRID_SIZE),\n/* harmony export */ \"HYPERLINK_TOOLTIP_DELAY\": () => (/* binding */ HYPERLINK_TOOLTIP_DELAY),\n/* harmony export */ \"IDLE_THRESHOLD\": () => (/* binding */ IDLE_THRESHOLD),\n/* harmony export */ \"IMAGE_MIME_TYPES\": () => (/* binding */ IMAGE_MIME_TYPES),\n/* harmony export */ \"IMAGE_RENDER_TIMEOUT\": () => (/* binding */ IMAGE_RENDER_TIMEOUT),\n/* harmony export */ \"LIBRARY_DISABLED_TYPES\": () => (/* binding */ LIBRARY_DISABLED_TYPES),\n/* harmony export */ \"LIBRARY_SIDEBAR_TAB\": () => (/* binding */ LIBRARY_SIDEBAR_TAB),\n/* harmony export */ \"LIBRARY_SIDEBAR_WIDTH\": () => (/* binding */ LIBRARY_SIDEBAR_WIDTH),\n/* harmony export */ \"LINE_CONFIRM_THRESHOLD\": () => (/* binding */ LINE_CONFIRM_THRESHOLD),\n/* harmony export */ \"MAX_ALLOWED_FILE_BYTES\": () => (/* binding */ MAX_ALLOWED_FILE_BYTES),\n/* harmony export */ \"MAX_DECIMALS_FOR_SVG_EXPORT\": () => (/* binding */ MAX_DECIMALS_FOR_SVG_EXPORT),\n/* harmony export */ \"MIME_TYPES\": () => (/* binding */ MIME_TYPES),\n/* harmony export */ \"MIN_FONT_SIZE\": () => (/* binding */ MIN_FONT_SIZE),\n/* harmony export */ \"MIN_ZOOM\": () => (/* binding */ MIN_ZOOM),\n/* harmony export */ \"MQ_MAX_HEIGHT_LANDSCAPE\": () => (/* binding */ MQ_MAX_HEIGHT_LANDSCAPE),\n/* harmony export */ \"MQ_MAX_WIDTH_LANDSCAPE\": () => (/* binding */ MQ_MAX_WIDTH_LANDSCAPE),\n/* harmony export */ \"MQ_MAX_WIDTH_PORTRAIT\": () => (/* binding */ MQ_MAX_WIDTH_PORTRAIT),\n/* harmony export */ \"MQ_RIGHT_SIDEBAR_MIN_WIDTH\": () => (/* binding */ MQ_RIGHT_SIDEBAR_MIN_WIDTH),\n/* harmony export */ \"MQ_SM_MAX_WIDTH\": () => (/* binding */ MQ_SM_MAX_WIDTH),\n/* harmony export */ \"POINTER_BUTTON\": () => (/* binding */ POINTER_BUTTON),\n/* harmony export */ \"POINTER_EVENTS\": () => (/* binding */ POINTER_EVENTS),\n/* harmony export */ \"PRECEDING_ELEMENT_KEY\": () => (/* binding */ PRECEDING_ELEMENT_KEY),\n/* harmony export */ \"ROUGHNESS\": () => (/* binding */ ROUGHNESS),\n/* harmony export */ \"ROUNDNESS\": () => (/* binding */ ROUNDNESS),\n/* harmony export */ \"SCROLL_TIMEOUT\": () => (/* binding */ SCROLL_TIMEOUT),\n/* harmony export */ \"SHIFT_LOCKING_ANGLE\": () => (/* binding */ SHIFT_LOCKING_ANGLE),\n/* harmony export */ \"SVG_NS\": () => (/* binding */ SVG_NS),\n/* harmony export */ \"TAP_TWICE_TIMEOUT\": () => (/* binding */ TAP_TWICE_TIMEOUT),\n/* harmony export */ \"TEXT_ALIGN\": () => (/* binding */ TEXT_ALIGN),\n/* harmony export */ \"TEXT_TO_CENTER_SNAP_THRESHOLD\": () => (/* binding */ TEXT_TO_CENTER_SNAP_THRESHOLD),\n/* harmony export */ \"THEME\": () => (/* binding */ THEME),\n/* harmony export */ \"THEME_FILTER\": () => (/* binding */ THEME_FILTER),\n/* harmony export */ \"TITLE_TIMEOUT\": () => (/* binding */ TITLE_TIMEOUT),\n/* harmony export */ \"TOUCH_CTX_MENU_TIMEOUT\": () => (/* binding */ TOUCH_CTX_MENU_TIMEOUT),\n/* harmony export */ \"URL_HASH_KEYS\": () => (/* binding */ URL_HASH_KEYS),\n/* harmony export */ \"URL_QUERY_KEYS\": () => (/* binding */ URL_QUERY_KEYS),\n/* harmony export */ \"VERSIONS\": () => (/* binding */ VERSIONS),\n/* harmony export */ \"VERSION_TIMEOUT\": () => (/* binding */ VERSION_TIMEOUT),\n/* harmony export */ \"VERTICAL_ALIGN\": () => (/* binding */ VERTICAL_ALIGN),\n/* harmony export */ \"WINDOWS_EMOJI_FALLBACK_FONT\": () => (/* binding */ WINDOWS_EMOJI_FALLBACK_FONT),\n/* harmony export */ \"YOUTUBE_STATES\": () => (/* binding */ YOUTUBE_STATES),\n/* harmony export */ \"ZOOM_STEP\": () => (/* binding */ ZOOM_STEP),\n/* harmony export */ \"isAndroid\": () => (/* binding */ isAndroid),\n/* harmony export */ \"isBrave\": () => (/* binding */ isBrave),\n/* harmony export */ \"isChrome\": () => (/* binding */ isChrome),\n/* harmony export */ \"isDarwin\": () => (/* binding */ isDarwin),\n/* harmony export */ \"isFirefox\": () => (/* binding */ isFirefox),\n/* harmony export */ \"isSafari\": () => (/* binding */ isSafari),\n/* harmony export */ \"isWindows\": () => (/* binding */ isWindows)\n/* harmony export */ });\n/* harmony import */ var _css_variables_module_scss__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./css/variables.module.scss */ \"../../css/variables.module.scss\");\n/* harmony import */ var _colors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./colors */ \"../../colors.ts\");\n\n\nconst isDarwin = /Mac|iPod|iPhone|iPad/.test(navigator.platform);\nconst isWindows = /^Win/.test(navigator.platform);\nconst isAndroid = /\\b(android)\\b/i.test(navigator.userAgent);\nconst isFirefox = \"netscape\" in window && navigator.userAgent.indexOf(\"rv:\") > 1 && navigator.userAgent.indexOf(\"Gecko\") > 1;\nconst isChrome = navigator.userAgent.indexOf(\"Chrome\") !== -1;\nconst isSafari = !isChrome && navigator.userAgent.indexOf(\"Safari\") !== -1; // keeping function so it can be mocked in test\n\nconst isBrave = () => {\n var _a, _b;\n\n return ((_b = (_a = navigator.brave) === null || _a === void 0 ? void 0 : _a.isBrave) === null || _b === void 0 ? void 0 : _b.name) === \"isBrave\";\n};\nconst APP_NAME = \"Excalidraw\";\nconst DRAGGING_THRESHOLD = 10; // px\n\nconst LINE_CONFIRM_THRESHOLD = 8; // px\n\nconst ELEMENT_SHIFT_TRANSLATE_AMOUNT = 5;\nconst ELEMENT_TRANSLATE_AMOUNT = 1;\nconst TEXT_TO_CENTER_SNAP_THRESHOLD = 30;\nconst SHIFT_LOCKING_ANGLE = Math.PI / 12;\nconst CURSOR_TYPE = {\n TEXT: \"text\",\n CROSSHAIR: \"crosshair\",\n GRABBING: \"grabbing\",\n GRAB: \"grab\",\n POINTER: \"pointer\",\n MOVE: \"move\",\n AUTO: \"\"\n};\nconst POINTER_BUTTON = {\n MAIN: 0,\n WHEEL: 1,\n SECONDARY: 2,\n TOUCH: -1\n};\nconst POINTER_EVENTS = {\n enabled: \"all\",\n disabled: \"none\",\n // asserted as any so it can be freely assigned to React Element\n // \"pointerEnvets\" CSS prop\n inheritFromUI: \"var(--ui-pointerEvents)\"\n};\nvar EVENT;\n\n(function (EVENT) {\n EVENT[\"COPY\"] = \"copy\";\n EVENT[\"PASTE\"] = \"paste\";\n EVENT[\"CUT\"] = \"cut\";\n EVENT[\"KEYDOWN\"] = \"keydown\";\n EVENT[\"KEYUP\"] = \"keyup\";\n EVENT[\"MOUSE_MOVE\"] = \"mousemove\";\n EVENT[\"RESIZE\"] = \"resize\";\n EVENT[\"UNLOAD\"] = \"unload\";\n EVENT[\"FOCUS\"] = \"focus\";\n EVENT[\"BLUR\"] = \"blur\";\n EVENT[\"DRAG_OVER\"] = \"dragover\";\n EVENT[\"DROP\"] = \"drop\";\n EVENT[\"GESTURE_END\"] = \"gestureend\";\n EVENT[\"BEFORE_UNLOAD\"] = \"beforeunload\";\n EVENT[\"GESTURE_START\"] = \"gesturestart\";\n EVENT[\"GESTURE_CHANGE\"] = \"gesturechange\";\n EVENT[\"POINTER_MOVE\"] = \"pointermove\";\n EVENT[\"POINTER_DOWN\"] = \"pointerdown\";\n EVENT[\"POINTER_UP\"] = \"pointerup\";\n EVENT[\"STATE_CHANGE\"] = \"statechange\";\n EVENT[\"WHEEL\"] = \"wheel\";\n EVENT[\"TOUCH_START\"] = \"touchstart\";\n EVENT[\"TOUCH_END\"] = \"touchend\";\n EVENT[\"HASHCHANGE\"] = \"hashchange\";\n EVENT[\"VISIBILITY_CHANGE\"] = \"visibilitychange\";\n EVENT[\"SCROLL\"] = \"scroll\"; // custom events\n\n EVENT[\"EXCALIDRAW_LINK\"] = \"excalidraw-link\";\n EVENT[\"MENU_ITEM_SELECT\"] = \"menu.itemSelect\";\n EVENT[\"MESSAGE\"] = \"message\";\n})(EVENT || (EVENT = {}));\n\nconst YOUTUBE_STATES = {\n UNSTARTED: -1,\n ENDED: 0,\n PLAYING: 1,\n PAUSED: 2,\n BUFFERING: 3,\n CUED: 5\n};\nconst ENV = {\n TEST: \"test\",\n DEVELOPMENT: \"development\"\n};\nconst CLASSES = {\n SHAPE_ACTIONS_MENU: \"App-menu__left\",\n SHAPE_ACTIONS_MOBILE_MENU: \"App-mobile-menu\",\n MOBILE_TOOLBAR: \"App-toolbar-content\" //zsviczian\n\n}; // 1-based in case we ever do `if(element.fontFamily)`\n\nconst FONT_FAMILY = {\n Virgil: 1,\n Helvetica: 2,\n Cascadia: 3,\n LocalFont: 4\n};\nconst THEME = {\n LIGHT: \"light\",\n DARK: \"dark\"\n};\nconst FRAME_STYLE = {\n strokeColor: \"#bbb\",\n strokeWidth: 1,\n strokeStyle: \"solid\",\n fillStyle: \"solid\",\n roughness: 0,\n roundness: null,\n backgroundColor: \"transparent\",\n radius: 8\n};\nconst WINDOWS_EMOJI_FALLBACK_FONT = \"Segoe UI Emoji\";\nconst MIN_FONT_SIZE = 1;\nconst DEFAULT_FONT_SIZE = 20;\nconst DEFAULT_FONT_FAMILY = FONT_FAMILY.Virgil;\nconst DEFAULT_TEXT_ALIGN = \"left\";\nconst DEFAULT_VERTICAL_ALIGN = \"top\";\nconst DEFAULT_VERSION = \"{version}\";\nconst CANVAS_ONLY_ACTIONS = [\"selectAll\"];\nconst GRID_SIZE = 20; // TODO make it configurable?\n\nconst IMAGE_MIME_TYPES = {\n svg: \"image/svg+xml\",\n png: \"image/png\",\n jpg: \"image/jpeg\",\n gif: \"image/gif\",\n webp: \"image/webp\",\n bmp: \"image/bmp\",\n ico: \"image/x-icon\",\n avif: \"image/avif\",\n jfif: \"image/jfif\"\n};\nconst MIME_TYPES = Object.assign({\n json: \"application/json\",\n // excalidraw data\n excalidraw: \"application/vnd.excalidraw+json\",\n excalidrawlib: \"application/vnd.excalidrawlib+json\",\n // image-encoded excalidraw data\n \"excalidraw.svg\": \"image/svg+xml\",\n \"excalidraw.png\": \"image/png\",\n // binary\n binary: \"application/octet-stream\"\n}, IMAGE_MIME_TYPES);\nconst EXPORT_IMAGE_TYPES = {\n png: \"png\",\n svg: \"svg\",\n clipboard: \"clipboard\"\n};\nconst EXPORT_DATA_TYPES = {\n excalidraw: \"excalidraw\",\n excalidrawClipboard: \"excalidraw/clipboard\",\n excalidrawLibrary: \"excalidrawlib\",\n excalidrawClipboardWithAPI: \"excalidraw-api/clipboard\"\n};\nconst EXPORT_SOURCE = window.EXCALIDRAW_EXPORT_SOURCE || window.location.origin; // time in milliseconds\n\nconst IMAGE_RENDER_TIMEOUT = 500;\nconst TAP_TWICE_TIMEOUT = 300;\nconst TOUCH_CTX_MENU_TIMEOUT = 500;\nconst TITLE_TIMEOUT = 10000;\nconst VERSION_TIMEOUT = 30000;\nconst SCROLL_TIMEOUT = 100;\nconst ZOOM_STEP = 0.05; //zsviczian\n\nconst MIN_ZOOM = 0.1;\nconst HYPERLINK_TOOLTIP_DELAY = 300; // Report a user inactive after IDLE_THRESHOLD milliseconds\n\nconst IDLE_THRESHOLD = 60000; // Report a user active each ACTIVE_THRESHOLD milliseconds\n\nconst ACTIVE_THRESHOLD = 3000;\nconst THEME_FILTER = _css_variables_module_scss__WEBPACK_IMPORTED_MODULE_0__[\"default\"].themeFilter;\nconst URL_QUERY_KEYS = {\n addLibrary: \"addLibrary\"\n};\nconst URL_HASH_KEYS = {\n addLibrary: \"addLibrary\"\n};\nconst DEFAULT_UI_OPTIONS = {\n canvasActions: {\n changeViewBackgroundColor: true,\n clearCanvas: true,\n export: {\n saveFileToDisk: true\n },\n loadScene: true,\n saveToActiveFile: true,\n toggleTheme: null,\n saveAsImage: true\n }\n}; // breakpoints\n// -----------------------------------------------------------------------------\n// sm screen\n\nconst MQ_SM_MAX_WIDTH = 640; // md screen\n\nconst MQ_MAX_WIDTH_PORTRAIT = 730;\nconst MQ_MAX_WIDTH_LANDSCAPE = 1000;\nconst MQ_MAX_HEIGHT_LANDSCAPE = 500; // sidebar\n\nconst MQ_RIGHT_SIDEBAR_MIN_WIDTH = 1229; // -----------------------------------------------------------------------------\n\nconst LIBRARY_SIDEBAR_WIDTH = parseInt(_css_variables_module_scss__WEBPACK_IMPORTED_MODULE_0__[\"default\"].rightSidebarWidth);\nconst MAX_DECIMALS_FOR_SVG_EXPORT = 2;\nconst EXPORT_SCALES = [1, 2, 3];\nconst DEFAULT_EXPORT_PADDING = 10; // px\n\nconst DEFAULT_MAX_IMAGE_WIDTH_OR_HEIGHT = 1440;\nconst MAX_ALLOWED_FILE_BYTES = 20 * 1024 * 1024;\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\nconst ENCRYPTION_KEY_BITS = 128;\nconst VERSIONS = {\n excalidraw: 2,\n excalidrawLibrary: 2\n};\nconst BOUND_TEXT_PADDING = 5;\nconst ARROW_LABEL_WIDTH_FRACTION = 0.7;\nconst ARROW_LABEL_FONT_SIZE_TO_MIN_WIDTH_RATIO = 11;\nconst VERTICAL_ALIGN = {\n TOP: \"top\",\n MIDDLE: \"middle\",\n BOTTOM: \"bottom\"\n};\nconst TEXT_ALIGN = {\n LEFT: \"left\",\n CENTER: \"center\",\n RIGHT: \"right\"\n};\nconst ELEMENT_READY_TO_ERASE_OPACITY = 20; // Radius represented as 25% of element's largest side (width/height).\n// Used for LEGACY and PROPORTIONAL_RADIUS algorithms, or when the element is\n// below the cutoff size.\n\nconst DEFAULT_PROPORTIONAL_RADIUS = 0.25; // Fixed radius for the ADAPTIVE_RADIUS algorithm. In pixels.\n\nconst DEFAULT_ADAPTIVE_RADIUS = 32; // roundness type (algorithm)\n\nconst ROUNDNESS = {\n // Used for legacy rounding (rectangles), which currently works the same\n // as PROPORTIONAL_RADIUS, but we need to differentiate for UI purposes and\n // forwards-compat.\n LEGACY: 1,\n // Used for linear elements & diamonds\n PROPORTIONAL_RADIUS: 2,\n // Current default algorithm for rectangles, using fixed pixel radius.\n // It's working similarly to a regular border-radius, but attemps to make\n // radius visually similar across differnt element sizes, especially\n // very large and very small elements.\n //\n // NOTE right now we don't allow configuration and use a constant radius\n // (see DEFAULT_ADAPTIVE_RADIUS constant)\n ADAPTIVE_RADIUS: 3\n};\n/** key containt id of precedeing elemnt id we use in reconciliation during\r\n * collaboration */\n\nconst PRECEDING_ELEMENT_KEY = \"__precedingElement__\"; //zsviczian\n\nconst COLOR_NAMES = {\n aliceblue: \"#f0f8ff\",\n antiquewhite: \"#faebd7\",\n aqua: \"#00ffff\",\n aquamarine: \"#7fffd4\",\n azure: \"#f0ffff\",\n beige: \"#f5f5dc\",\n bisque: \"#ffe4c4\",\n black: \"#000000\",\n blanchedalmond: \"#ffebcd\",\n blue: \"#0000ff\",\n blueviolet: \"#8a2be2\",\n brown: \"#a52a2a\",\n burlywood: \"#deb887\",\n cadetblue: \"#5f9ea0\",\n chartreuse: \"#7fff00\",\n chocolate: \"#d2691e\",\n coral: \"#ff7f50\",\n cornflowerblue: \"#6495ed\",\n cornsilk: \"#fff8dc\",\n crimson: \"#dc143c\",\n cyan: \"#00ffff\",\n darkblue: \"#00008b\",\n darkcyan: \"#008b8b\",\n darkgoldenrod: \"#b8860b\",\n darkgray: \"#a9a9a9\",\n darkgreen: \"#006400\",\n darkkhaki: \"#bdb76b\",\n darkmagenta: \"#8b008b\",\n darkolivegreen: \"#556b2f\",\n darkorange: \"#ff8c00\",\n darkorchid: \"#9932cc\",\n darkred: \"#8b0000\",\n darksalmon: \"#e9967a\",\n darkseagreen: \"#8fbc8f\",\n darkslateblue: \"#483d8b\",\n darkslategray: \"#2f4f4f\",\n darkturquoise: \"#00ced1\",\n darkviolet: \"#9400d3\",\n deeppink: \"#ff1493\",\n deepskyblue: \"#00bfff\",\n dimgray: \"#696969\",\n dodgerblue: \"#1e90ff\",\n firebrick: \"#b22222\",\n floralwhite: \"#fffaf0\",\n forestgreen: \"#228b22\",\n fuchsia: \"#ff00ff\",\n gainsboro: \"#dcdcdc\",\n ghostwhite: \"#f8f8ff\",\n gold: \"#ffd700\",\n goldenrod: \"#daa520\",\n gray: \"#808080\",\n green: \"#008000\",\n greenyellow: \"#adff2f\",\n honeydew: \"#f0fff0\",\n hotpink: \"#ff69b4\",\n indianred: \"#cd5c5c\",\n indigo: \"#4b0082\",\n ivory: \"#fffff0\",\n khaki: \"#f0e68c\",\n lavender: \"#e6e6fa\",\n lavenderblush: \"#fff0f5\",\n lawngreen: \"#7cfc00\",\n lemonchiffon: \"#fffacd\",\n lightblue: \"#add8e6\",\n lightcoral: \"#f08080\",\n lightcyan: \"#e0ffff\",\n lightgoldenrodyellow: \"#fafad2\",\n lightgrey: \"#d3d3d3\",\n lightgreen: \"#90ee90\",\n lightpink: \"#ffb6c1\",\n lightsalmon: \"#ffa07a\",\n lightseagreen: \"#20b2aa\",\n lightskyblue: \"#87cefa\",\n lightslategray: \"#778899\",\n lightsteelblue: \"#b0c4de\",\n lightyellow: \"#ffffe0\",\n lime: \"#00ff00\",\n limegreen: \"#32cd32\",\n linen: \"#faf0e6\",\n magenta: \"#ff00ff\",\n maroon: \"#800000\",\n mediumaquamarine: \"#66cdaa\",\n mediumblue: \"#0000cd\",\n mediumorchid: \"#ba55d3\",\n mediumpurple: \"#9370d8\",\n mediumseagreen: \"#3cb371\",\n mediumslateblue: \"#7b68ee\",\n mediumspringgreen: \"#00fa9a\",\n mediumturquoise: \"#48d1cc\",\n mediumvioletred: \"#c71585\",\n midnightblue: \"#191970\",\n mintcream: \"#f5fffa\",\n mistyrose: \"#ffe4e1\",\n moccasin: \"#ffe4b5\",\n navajowhite: \"#ffdead\",\n navy: \"#000080\",\n oldlace: \"#fdf5e6\",\n olive: \"#808000\",\n olivedrab: \"#6b8e23\",\n orange: \"#ffa500\",\n orangered: \"#ff4500\",\n orchid: \"#da70d6\",\n palegoldenrod: \"#eee8aa\",\n palegreen: \"#98fb98\",\n paleturquoise: \"#afeeee\",\n palevioletred: \"#d87093\",\n papayawhip: \"#ffefd5\",\n peachpuff: \"#ffdab9\",\n peru: \"#cd853f\",\n pink: \"#ffc0cb\",\n plum: \"#dda0dd\",\n powderblue: \"#b0e0e6\",\n purple: \"#800080\",\n rebeccapurple: \"#663399\",\n red: \"#ff0000\",\n rosybrown: \"#bc8f8f\",\n royalblue: \"#4169e1\",\n saddlebrown: \"#8b4513\",\n salmon: \"#fa8072\",\n sandybrown: \"#f4a460\",\n seagreen: \"#2e8b57\",\n seashell: \"#fff5ee\",\n sienna: \"#a0522d\",\n silver: \"#c0c0c0\",\n skyblue: \"#87ceeb\",\n slateblue: \"#6a5acd\",\n slategray: \"#708090\",\n snow: \"#fffafa\",\n springgreen: \"#00ff7f\",\n steelblue: \"#4682b4\",\n tan: \"#d2b48c\",\n teal: \"#008080\",\n thistle: \"#d8bfd8\",\n tomato: \"#ff6347\",\n turquoise: \"#40e0d0\",\n violet: \"#ee82ee\",\n wheat: \"#f5deb3\",\n white: \"#ffffff\",\n whitesmoke: \"#f5f5f5\",\n yellow: \"#ffff00\",\n yellowgreen: \"#9acd32\"\n};\nconst ROUGHNESS = {\n architect: 0,\n artist: 1,\n cartoonist: 2\n};\nconst DEFAULT_ELEMENT_PROPS = {\n strokeColor: _colors__WEBPACK_IMPORTED_MODULE_1__.COLOR_PALETTE.black,\n backgroundColor: _colors__WEBPACK_IMPORTED_MODULE_1__.COLOR_PALETTE.transparent,\n fillStyle: \"solid\",\n strokeWidth: 2,\n strokeStyle: \"solid\",\n roughness: ROUGHNESS.artist,\n opacity: 100,\n locked: false\n};\nconst LIBRARY_SIDEBAR_TAB = \"library\";\nconst DEFAULT_SIDEBAR = {\n name: \"default\",\n defaultTab: LIBRARY_SIDEBAR_TAB\n};\nconst LIBRARY_DISABLED_TYPES = new Set([\"embeddable\", \"image\"]);\n\n//# sourceURL=webpack://ExcalidrawLib/../../constants.ts?");
3461
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"ACTIVE_THRESHOLD\": () => (/* binding */ ACTIVE_THRESHOLD),\n/* harmony export */ \"APP_NAME\": () => (/* binding */ APP_NAME),\n/* harmony export */ \"ARROW_LABEL_FONT_SIZE_TO_MIN_WIDTH_RATIO\": () => (/* binding */ ARROW_LABEL_FONT_SIZE_TO_MIN_WIDTH_RATIO),\n/* harmony export */ \"ARROW_LABEL_WIDTH_FRACTION\": () => (/* binding */ ARROW_LABEL_WIDTH_FRACTION),\n/* harmony export */ \"BOUND_TEXT_PADDING\": () => (/* binding */ BOUND_TEXT_PADDING),\n/* harmony export */ \"CANVAS_ONLY_ACTIONS\": () => (/* binding */ CANVAS_ONLY_ACTIONS),\n/* harmony export */ \"CLASSES\": () => (/* binding */ CLASSES),\n/* harmony export */ \"COLOR_NAMES\": () => (/* binding */ COLOR_NAMES),\n/* harmony export */ \"CURSOR_TYPE\": () => (/* binding */ CURSOR_TYPE),\n/* harmony export */ \"DEFAULT_ADAPTIVE_RADIUS\": () => (/* binding */ DEFAULT_ADAPTIVE_RADIUS),\n/* harmony export */ \"DEFAULT_ELEMENT_PROPS\": () => (/* binding */ DEFAULT_ELEMENT_PROPS),\n/* harmony export */ \"DEFAULT_EXPORT_PADDING\": () => (/* binding */ DEFAULT_EXPORT_PADDING),\n/* harmony export */ \"DEFAULT_FONT_FAMILY\": () => (/* binding */ DEFAULT_FONT_FAMILY),\n/* harmony export */ \"DEFAULT_FONT_SIZE\": () => (/* binding */ DEFAULT_FONT_SIZE),\n/* harmony export */ \"DEFAULT_MAX_IMAGE_WIDTH_OR_HEIGHT\": () => (/* binding */ DEFAULT_MAX_IMAGE_WIDTH_OR_HEIGHT),\n/* harmony export */ \"DEFAULT_PROPORTIONAL_RADIUS\": () => (/* binding */ DEFAULT_PROPORTIONAL_RADIUS),\n/* harmony export */ \"DEFAULT_SIDEBAR\": () => (/* binding */ DEFAULT_SIDEBAR),\n/* harmony export */ \"DEFAULT_TEXT_ALIGN\": () => (/* binding */ DEFAULT_TEXT_ALIGN),\n/* harmony export */ \"DEFAULT_UI_OPTIONS\": () => (/* binding */ DEFAULT_UI_OPTIONS),\n/* harmony export */ \"DEFAULT_VERSION\": () => (/* binding */ DEFAULT_VERSION),\n/* harmony export */ \"DEFAULT_VERTICAL_ALIGN\": () => (/* binding */ DEFAULT_VERTICAL_ALIGN),\n/* harmony export */ \"DRAGGING_THRESHOLD\": () => (/* binding */ DRAGGING_THRESHOLD),\n/* harmony export */ \"ELEMENT_READY_TO_ERASE_OPACITY\": () => (/* binding */ ELEMENT_READY_TO_ERASE_OPACITY),\n/* harmony export */ \"ELEMENT_SHIFT_TRANSLATE_AMOUNT\": () => (/* binding */ ELEMENT_SHIFT_TRANSLATE_AMOUNT),\n/* harmony export */ \"ELEMENT_TRANSLATE_AMOUNT\": () => (/* binding */ ELEMENT_TRANSLATE_AMOUNT),\n/* harmony export */ \"ENCRYPTION_KEY_BITS\": () => (/* binding */ ENCRYPTION_KEY_BITS),\n/* harmony export */ \"ENV\": () => (/* binding */ ENV),\n/* harmony export */ \"EVENT\": () => (/* binding */ EVENT),\n/* harmony export */ \"EXPORT_DATA_TYPES\": () => (/* binding */ EXPORT_DATA_TYPES),\n/* harmony export */ \"EXPORT_IMAGE_TYPES\": () => (/* binding */ EXPORT_IMAGE_TYPES),\n/* harmony export */ \"EXPORT_SCALES\": () => (/* binding */ EXPORT_SCALES),\n/* harmony export */ \"EXPORT_SOURCE\": () => (/* binding */ EXPORT_SOURCE),\n/* harmony export */ \"FONT_FAMILY\": () => (/* binding */ FONT_FAMILY),\n/* harmony export */ \"FRAME_STYLE\": () => (/* binding */ FRAME_STYLE),\n/* harmony export */ \"GRID_SIZE\": () => (/* binding */ GRID_SIZE),\n/* harmony export */ \"HYPERLINK_TOOLTIP_DELAY\": () => (/* binding */ HYPERLINK_TOOLTIP_DELAY),\n/* harmony export */ \"IDLE_THRESHOLD\": () => (/* binding */ IDLE_THRESHOLD),\n/* harmony export */ \"IMAGE_MIME_TYPES\": () => (/* binding */ IMAGE_MIME_TYPES),\n/* harmony export */ \"IMAGE_RENDER_TIMEOUT\": () => (/* binding */ IMAGE_RENDER_TIMEOUT),\n/* harmony export */ \"LIBRARY_DISABLED_TYPES\": () => (/* binding */ LIBRARY_DISABLED_TYPES),\n/* harmony export */ \"LIBRARY_SIDEBAR_TAB\": () => (/* binding */ LIBRARY_SIDEBAR_TAB),\n/* harmony export */ \"LIBRARY_SIDEBAR_WIDTH\": () => (/* binding */ LIBRARY_SIDEBAR_WIDTH),\n/* harmony export */ \"LINE_CONFIRM_THRESHOLD\": () => (/* binding */ LINE_CONFIRM_THRESHOLD),\n/* harmony export */ \"MAX_ALLOWED_FILE_BYTES\": () => (/* binding */ MAX_ALLOWED_FILE_BYTES),\n/* harmony export */ \"MAX_DECIMALS_FOR_SVG_EXPORT\": () => (/* binding */ MAX_DECIMALS_FOR_SVG_EXPORT),\n/* harmony export */ \"MIME_TYPES\": () => (/* binding */ MIME_TYPES),\n/* harmony export */ \"MIN_FONT_SIZE\": () => (/* binding */ MIN_FONT_SIZE),\n/* harmony export */ \"MIN_ZOOM\": () => (/* binding */ MIN_ZOOM),\n/* harmony export */ \"MQ_MAX_HEIGHT_LANDSCAPE\": () => (/* binding */ MQ_MAX_HEIGHT_LANDSCAPE),\n/* harmony export */ \"MQ_MAX_WIDTH_LANDSCAPE\": () => (/* binding */ MQ_MAX_WIDTH_LANDSCAPE),\n/* harmony export */ \"MQ_MAX_WIDTH_PORTRAIT\": () => (/* binding */ MQ_MAX_WIDTH_PORTRAIT),\n/* harmony export */ \"MQ_RIGHT_SIDEBAR_MIN_WIDTH\": () => (/* binding */ MQ_RIGHT_SIDEBAR_MIN_WIDTH),\n/* harmony export */ \"MQ_SM_MAX_WIDTH\": () => (/* binding */ MQ_SM_MAX_WIDTH),\n/* harmony export */ \"POINTER_BUTTON\": () => (/* binding */ POINTER_BUTTON),\n/* harmony export */ \"POINTER_EVENTS\": () => (/* binding */ POINTER_EVENTS),\n/* harmony export */ \"PRECEDING_ELEMENT_KEY\": () => (/* binding */ PRECEDING_ELEMENT_KEY),\n/* harmony export */ \"ROUGHNESS\": () => (/* binding */ ROUGHNESS),\n/* harmony export */ \"ROUNDNESS\": () => (/* binding */ ROUNDNESS),\n/* harmony export */ \"SCROLL_TIMEOUT\": () => (/* binding */ SCROLL_TIMEOUT),\n/* harmony export */ \"SHIFT_LOCKING_ANGLE\": () => (/* binding */ SHIFT_LOCKING_ANGLE),\n/* harmony export */ \"STROKE_WIDTH\": () => (/* binding */ STROKE_WIDTH),\n/* harmony export */ \"SVG_NS\": () => (/* binding */ SVG_NS),\n/* harmony export */ \"TAP_TWICE_TIMEOUT\": () => (/* binding */ TAP_TWICE_TIMEOUT),\n/* harmony export */ \"TEXT_ALIGN\": () => (/* binding */ TEXT_ALIGN),\n/* harmony export */ \"TEXT_TO_CENTER_SNAP_THRESHOLD\": () => (/* binding */ TEXT_TO_CENTER_SNAP_THRESHOLD),\n/* harmony export */ \"THEME\": () => (/* binding */ THEME),\n/* harmony export */ \"THEME_FILTER\": () => (/* binding */ THEME_FILTER),\n/* harmony export */ \"TITLE_TIMEOUT\": () => (/* binding */ TITLE_TIMEOUT),\n/* harmony export */ \"TOUCH_CTX_MENU_TIMEOUT\": () => (/* binding */ TOUCH_CTX_MENU_TIMEOUT),\n/* harmony export */ \"URL_HASH_KEYS\": () => (/* binding */ URL_HASH_KEYS),\n/* harmony export */ \"URL_QUERY_KEYS\": () => (/* binding */ URL_QUERY_KEYS),\n/* harmony export */ \"VERSIONS\": () => (/* binding */ VERSIONS),\n/* harmony export */ \"VERSION_TIMEOUT\": () => (/* binding */ VERSION_TIMEOUT),\n/* harmony export */ \"VERTICAL_ALIGN\": () => (/* binding */ VERTICAL_ALIGN),\n/* harmony export */ \"WINDOWS_EMOJI_FALLBACK_FONT\": () => (/* binding */ WINDOWS_EMOJI_FALLBACK_FONT),\n/* harmony export */ \"YOUTUBE_STATES\": () => (/* binding */ YOUTUBE_STATES),\n/* harmony export */ \"ZOOM_STEP\": () => (/* binding */ ZOOM_STEP),\n/* harmony export */ \"isAndroid\": () => (/* binding */ isAndroid),\n/* harmony export */ \"isBrave\": () => (/* binding */ isBrave),\n/* harmony export */ \"isChrome\": () => (/* binding */ isChrome),\n/* harmony export */ \"isDarwin\": () => (/* binding */ isDarwin),\n/* harmony export */ \"isFirefox\": () => (/* binding */ isFirefox),\n/* harmony export */ \"isSafari\": () => (/* binding */ isSafari),\n/* harmony export */ \"isWindows\": () => (/* binding */ isWindows)\n/* harmony export */ });\n/* harmony import */ var _css_variables_module_scss__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./css/variables.module.scss */ \"../../css/variables.module.scss\");\n/* harmony import */ var _colors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./colors */ \"../../colors.ts\");\n\n\nconst isDarwin = /Mac|iPod|iPhone|iPad/.test(navigator.platform);\nconst isWindows = /^Win/.test(navigator.platform);\nconst isAndroid = /\\b(android)\\b/i.test(navigator.userAgent);\nconst isFirefox = \"netscape\" in window && navigator.userAgent.indexOf(\"rv:\") > 1 && navigator.userAgent.indexOf(\"Gecko\") > 1;\nconst isChrome = navigator.userAgent.indexOf(\"Chrome\") !== -1;\nconst isSafari = !isChrome && navigator.userAgent.indexOf(\"Safari\") !== -1; // keeping function so it can be mocked in test\n\nconst isBrave = () => {\n var _a, _b;\n\n return ((_b = (_a = navigator.brave) === null || _a === void 0 ? void 0 : _a.isBrave) === null || _b === void 0 ? void 0 : _b.name) === \"isBrave\";\n};\nconst APP_NAME = \"Excalidraw\";\nconst DRAGGING_THRESHOLD = 10; // px\n\nconst LINE_CONFIRM_THRESHOLD = 8; // px\n\nconst ELEMENT_SHIFT_TRANSLATE_AMOUNT = 5;\nconst ELEMENT_TRANSLATE_AMOUNT = 1;\nconst TEXT_TO_CENTER_SNAP_THRESHOLD = 30;\nconst SHIFT_LOCKING_ANGLE = Math.PI / 12;\nconst CURSOR_TYPE = {\n TEXT: \"text\",\n CROSSHAIR: \"crosshair\",\n GRABBING: \"grabbing\",\n GRAB: \"grab\",\n POINTER: \"pointer\",\n MOVE: \"move\",\n AUTO: \"\"\n};\nconst POINTER_BUTTON = {\n MAIN: 0,\n WHEEL: 1,\n SECONDARY: 2,\n TOUCH: -1\n};\nconst POINTER_EVENTS = {\n enabled: \"all\",\n disabled: \"none\",\n // asserted as any so it can be freely assigned to React Element\n // \"pointerEnvets\" CSS prop\n inheritFromUI: \"var(--ui-pointerEvents)\"\n};\nvar EVENT;\n\n(function (EVENT) {\n EVENT[\"COPY\"] = \"copy\";\n EVENT[\"PASTE\"] = \"paste\";\n EVENT[\"CUT\"] = \"cut\";\n EVENT[\"KEYDOWN\"] = \"keydown\";\n EVENT[\"KEYUP\"] = \"keyup\";\n EVENT[\"MOUSE_MOVE\"] = \"mousemove\";\n EVENT[\"RESIZE\"] = \"resize\";\n EVENT[\"UNLOAD\"] = \"unload\";\n EVENT[\"FOCUS\"] = \"focus\";\n EVENT[\"BLUR\"] = \"blur\";\n EVENT[\"DRAG_OVER\"] = \"dragover\";\n EVENT[\"DROP\"] = \"drop\";\n EVENT[\"GESTURE_END\"] = \"gestureend\";\n EVENT[\"BEFORE_UNLOAD\"] = \"beforeunload\";\n EVENT[\"GESTURE_START\"] = \"gesturestart\";\n EVENT[\"GESTURE_CHANGE\"] = \"gesturechange\";\n EVENT[\"POINTER_MOVE\"] = \"pointermove\";\n EVENT[\"POINTER_DOWN\"] = \"pointerdown\";\n EVENT[\"POINTER_UP\"] = \"pointerup\";\n EVENT[\"STATE_CHANGE\"] = \"statechange\";\n EVENT[\"WHEEL\"] = \"wheel\";\n EVENT[\"TOUCH_START\"] = \"touchstart\";\n EVENT[\"TOUCH_END\"] = \"touchend\";\n EVENT[\"HASHCHANGE\"] = \"hashchange\";\n EVENT[\"VISIBILITY_CHANGE\"] = \"visibilitychange\";\n EVENT[\"SCROLL\"] = \"scroll\"; // custom events\n\n EVENT[\"EXCALIDRAW_LINK\"] = \"excalidraw-link\";\n EVENT[\"MENU_ITEM_SELECT\"] = \"menu.itemSelect\";\n EVENT[\"MESSAGE\"] = \"message\";\n})(EVENT || (EVENT = {}));\n\nconst YOUTUBE_STATES = {\n UNSTARTED: -1,\n ENDED: 0,\n PLAYING: 1,\n PAUSED: 2,\n BUFFERING: 3,\n CUED: 5\n};\nconst ENV = {\n TEST: \"test\",\n DEVELOPMENT: \"development\"\n};\nconst CLASSES = {\n SHAPE_ACTIONS_MENU: \"App-menu__left\",\n SHAPE_ACTIONS_MOBILE_MENU: \"App-mobile-menu\",\n MOBILE_TOOLBAR: \"App-toolbar-content\" //zsviczian\n\n}; // 1-based in case we ever do `if(element.fontFamily)`\n\nconst FONT_FAMILY = {\n Virgil: 1,\n Helvetica: 2,\n Cascadia: 3,\n LocalFont: 4\n};\nconst THEME = {\n LIGHT: \"light\",\n DARK: \"dark\"\n};\nconst FRAME_STYLE = {\n strokeColor: \"#bbb\",\n strokeWidth: 1,\n strokeStyle: \"solid\",\n fillStyle: \"solid\",\n roughness: 0,\n roundness: null,\n backgroundColor: \"transparent\",\n radius: 8\n};\nconst WINDOWS_EMOJI_FALLBACK_FONT = \"Segoe UI Emoji\";\nconst MIN_FONT_SIZE = 1;\nconst DEFAULT_FONT_SIZE = 20;\nconst DEFAULT_FONT_FAMILY = FONT_FAMILY.Virgil;\nconst DEFAULT_TEXT_ALIGN = \"left\";\nconst DEFAULT_VERTICAL_ALIGN = \"top\";\nconst DEFAULT_VERSION = \"{version}\";\nconst CANVAS_ONLY_ACTIONS = [\"selectAll\"];\nconst GRID_SIZE = 20; // TODO make it configurable?\n\nconst IMAGE_MIME_TYPES = {\n svg: \"image/svg+xml\",\n png: \"image/png\",\n jpg: \"image/jpeg\",\n gif: \"image/gif\",\n webp: \"image/webp\",\n bmp: \"image/bmp\",\n ico: \"image/x-icon\",\n avif: \"image/avif\",\n jfif: \"image/jfif\"\n};\nconst MIME_TYPES = Object.assign({\n json: \"application/json\",\n // excalidraw data\n excalidraw: \"application/vnd.excalidraw+json\",\n excalidrawlib: \"application/vnd.excalidrawlib+json\",\n // image-encoded excalidraw data\n \"excalidraw.svg\": \"image/svg+xml\",\n \"excalidraw.png\": \"image/png\",\n // binary\n binary: \"application/octet-stream\"\n}, IMAGE_MIME_TYPES);\nconst EXPORT_IMAGE_TYPES = {\n png: \"png\",\n svg: \"svg\",\n clipboard: \"clipboard\"\n};\nconst EXPORT_DATA_TYPES = {\n excalidraw: \"excalidraw\",\n excalidrawClipboard: \"excalidraw/clipboard\",\n excalidrawLibrary: \"excalidrawlib\",\n excalidrawClipboardWithAPI: \"excalidraw-api/clipboard\"\n};\nconst EXPORT_SOURCE = window.EXCALIDRAW_EXPORT_SOURCE || window.location.origin; // time in milliseconds\n\nconst IMAGE_RENDER_TIMEOUT = 500;\nconst TAP_TWICE_TIMEOUT = 300;\nconst TOUCH_CTX_MENU_TIMEOUT = 500;\nconst TITLE_TIMEOUT = 10000;\nconst VERSION_TIMEOUT = 30000;\nconst SCROLL_TIMEOUT = 100;\nconst ZOOM_STEP = 0.05; //zsviczian\n\nconst MIN_ZOOM = 0.1;\nconst HYPERLINK_TOOLTIP_DELAY = 300; // Report a user inactive after IDLE_THRESHOLD milliseconds\n\nconst IDLE_THRESHOLD = 60000; // Report a user active each ACTIVE_THRESHOLD milliseconds\n\nconst ACTIVE_THRESHOLD = 3000;\nconst THEME_FILTER = _css_variables_module_scss__WEBPACK_IMPORTED_MODULE_0__[\"default\"].themeFilter;\nconst URL_QUERY_KEYS = {\n addLibrary: \"addLibrary\"\n};\nconst URL_HASH_KEYS = {\n addLibrary: \"addLibrary\"\n};\nconst DEFAULT_UI_OPTIONS = {\n canvasActions: {\n changeViewBackgroundColor: true,\n clearCanvas: true,\n export: {\n saveFileToDisk: true\n },\n loadScene: true,\n saveToActiveFile: true,\n toggleTheme: null,\n saveAsImage: true\n }\n}; // breakpoints\n// -----------------------------------------------------------------------------\n// sm screen\n\nconst MQ_SM_MAX_WIDTH = 640; // md screen\n\nconst MQ_MAX_WIDTH_PORTRAIT = 730;\nconst MQ_MAX_WIDTH_LANDSCAPE = 1000;\nconst MQ_MAX_HEIGHT_LANDSCAPE = 500; // sidebar\n\nconst MQ_RIGHT_SIDEBAR_MIN_WIDTH = 1229; // -----------------------------------------------------------------------------\n\nconst LIBRARY_SIDEBAR_WIDTH = parseInt(_css_variables_module_scss__WEBPACK_IMPORTED_MODULE_0__[\"default\"].rightSidebarWidth);\nconst MAX_DECIMALS_FOR_SVG_EXPORT = 2;\nconst EXPORT_SCALES = [1, 2, 3];\nconst DEFAULT_EXPORT_PADDING = 10; // px\n\nconst DEFAULT_MAX_IMAGE_WIDTH_OR_HEIGHT = 1440;\nconst MAX_ALLOWED_FILE_BYTES = 20 * 1024 * 1024;\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\nconst ENCRYPTION_KEY_BITS = 128;\nconst VERSIONS = {\n excalidraw: 2,\n excalidrawLibrary: 2\n};\nconst BOUND_TEXT_PADDING = 5;\nconst ARROW_LABEL_WIDTH_FRACTION = 0.7;\nconst ARROW_LABEL_FONT_SIZE_TO_MIN_WIDTH_RATIO = 11;\nconst VERTICAL_ALIGN = {\n TOP: \"top\",\n MIDDLE: \"middle\",\n BOTTOM: \"bottom\"\n};\nconst TEXT_ALIGN = {\n LEFT: \"left\",\n CENTER: \"center\",\n RIGHT: \"right\"\n};\nconst ELEMENT_READY_TO_ERASE_OPACITY = 20; // Radius represented as 25% of element's largest side (width/height).\n// Used for LEGACY and PROPORTIONAL_RADIUS algorithms, or when the element is\n// below the cutoff size.\n\nconst DEFAULT_PROPORTIONAL_RADIUS = 0.25; // Fixed radius for the ADAPTIVE_RADIUS algorithm. In pixels.\n\nconst DEFAULT_ADAPTIVE_RADIUS = 32; // roundness type (algorithm)\n\nconst ROUNDNESS = {\n // Used for legacy rounding (rectangles), which currently works the same\n // as PROPORTIONAL_RADIUS, but we need to differentiate for UI purposes and\n // forwards-compat.\n LEGACY: 1,\n // Used for linear elements & diamonds\n PROPORTIONAL_RADIUS: 2,\n // Current default algorithm for rectangles, using fixed pixel radius.\n // It's working similarly to a regular border-radius, but attemps to make\n // radius visually similar across differnt element sizes, especially\n // very large and very small elements.\n //\n // NOTE right now we don't allow configuration and use a constant radius\n // (see DEFAULT_ADAPTIVE_RADIUS constant)\n ADAPTIVE_RADIUS: 3\n};\n/** key containt id of precedeing elemnt id we use in reconciliation during\r\n * collaboration */\n\nconst PRECEDING_ELEMENT_KEY = \"__precedingElement__\"; //zsviczian\n\nconst COLOR_NAMES = {\n aliceblue: \"#f0f8ff\",\n antiquewhite: \"#faebd7\",\n aqua: \"#00ffff\",\n aquamarine: \"#7fffd4\",\n azure: \"#f0ffff\",\n beige: \"#f5f5dc\",\n bisque: \"#ffe4c4\",\n black: \"#000000\",\n blanchedalmond: \"#ffebcd\",\n blue: \"#0000ff\",\n blueviolet: \"#8a2be2\",\n brown: \"#a52a2a\",\n burlywood: \"#deb887\",\n cadetblue: \"#5f9ea0\",\n chartreuse: \"#7fff00\",\n chocolate: \"#d2691e\",\n coral: \"#ff7f50\",\n cornflowerblue: \"#6495ed\",\n cornsilk: \"#fff8dc\",\n crimson: \"#dc143c\",\n cyan: \"#00ffff\",\n darkblue: \"#00008b\",\n darkcyan: \"#008b8b\",\n darkgoldenrod: \"#b8860b\",\n darkgray: \"#a9a9a9\",\n darkgreen: \"#006400\",\n darkkhaki: \"#bdb76b\",\n darkmagenta: \"#8b008b\",\n darkolivegreen: \"#556b2f\",\n darkorange: \"#ff8c00\",\n darkorchid: \"#9932cc\",\n darkred: \"#8b0000\",\n darksalmon: \"#e9967a\",\n darkseagreen: \"#8fbc8f\",\n darkslateblue: \"#483d8b\",\n darkslategray: \"#2f4f4f\",\n darkturquoise: \"#00ced1\",\n darkviolet: \"#9400d3\",\n deeppink: \"#ff1493\",\n deepskyblue: \"#00bfff\",\n dimgray: \"#696969\",\n dodgerblue: \"#1e90ff\",\n firebrick: \"#b22222\",\n floralwhite: \"#fffaf0\",\n forestgreen: \"#228b22\",\n fuchsia: \"#ff00ff\",\n gainsboro: \"#dcdcdc\",\n ghostwhite: \"#f8f8ff\",\n gold: \"#ffd700\",\n goldenrod: \"#daa520\",\n gray: \"#808080\",\n green: \"#008000\",\n greenyellow: \"#adff2f\",\n honeydew: \"#f0fff0\",\n hotpink: \"#ff69b4\",\n indianred: \"#cd5c5c\",\n indigo: \"#4b0082\",\n ivory: \"#fffff0\",\n khaki: \"#f0e68c\",\n lavender: \"#e6e6fa\",\n lavenderblush: \"#fff0f5\",\n lawngreen: \"#7cfc00\",\n lemonchiffon: \"#fffacd\",\n lightblue: \"#add8e6\",\n lightcoral: \"#f08080\",\n lightcyan: \"#e0ffff\",\n lightgoldenrodyellow: \"#fafad2\",\n lightgrey: \"#d3d3d3\",\n lightgreen: \"#90ee90\",\n lightpink: \"#ffb6c1\",\n lightsalmon: \"#ffa07a\",\n lightseagreen: \"#20b2aa\",\n lightskyblue: \"#87cefa\",\n lightslategray: \"#778899\",\n lightsteelblue: \"#b0c4de\",\n lightyellow: \"#ffffe0\",\n lime: \"#00ff00\",\n limegreen: \"#32cd32\",\n linen: \"#faf0e6\",\n magenta: \"#ff00ff\",\n maroon: \"#800000\",\n mediumaquamarine: \"#66cdaa\",\n mediumblue: \"#0000cd\",\n mediumorchid: \"#ba55d3\",\n mediumpurple: \"#9370d8\",\n mediumseagreen: \"#3cb371\",\n mediumslateblue: \"#7b68ee\",\n mediumspringgreen: \"#00fa9a\",\n mediumturquoise: \"#48d1cc\",\n mediumvioletred: \"#c71585\",\n midnightblue: \"#191970\",\n mintcream: \"#f5fffa\",\n mistyrose: \"#ffe4e1\",\n moccasin: \"#ffe4b5\",\n navajowhite: \"#ffdead\",\n navy: \"#000080\",\n oldlace: \"#fdf5e6\",\n olive: \"#808000\",\n olivedrab: \"#6b8e23\",\n orange: \"#ffa500\",\n orangered: \"#ff4500\",\n orchid: \"#da70d6\",\n palegoldenrod: \"#eee8aa\",\n palegreen: \"#98fb98\",\n paleturquoise: \"#afeeee\",\n palevioletred: \"#d87093\",\n papayawhip: \"#ffefd5\",\n peachpuff: \"#ffdab9\",\n peru: \"#cd853f\",\n pink: \"#ffc0cb\",\n plum: \"#dda0dd\",\n powderblue: \"#b0e0e6\",\n purple: \"#800080\",\n rebeccapurple: \"#663399\",\n red: \"#ff0000\",\n rosybrown: \"#bc8f8f\",\n royalblue: \"#4169e1\",\n saddlebrown: \"#8b4513\",\n salmon: \"#fa8072\",\n sandybrown: \"#f4a460\",\n seagreen: \"#2e8b57\",\n seashell: \"#fff5ee\",\n sienna: \"#a0522d\",\n silver: \"#c0c0c0\",\n skyblue: \"#87ceeb\",\n slateblue: \"#6a5acd\",\n slategray: \"#708090\",\n snow: \"#fffafa\",\n springgreen: \"#00ff7f\",\n steelblue: \"#4682b4\",\n tan: \"#d2b48c\",\n teal: \"#008080\",\n thistle: \"#d8bfd8\",\n tomato: \"#ff6347\",\n turquoise: \"#40e0d0\",\n violet: \"#ee82ee\",\n wheat: \"#f5deb3\",\n white: \"#ffffff\",\n whitesmoke: \"#f5f5f5\",\n yellow: \"#ffff00\",\n yellowgreen: \"#9acd32\"\n};\nconst ROUGHNESS = {\n architect: 0,\n artist: 1,\n cartoonist: 2\n};\nconst STROKE_WIDTH = {\n thin: 1,\n bold: 2,\n extraBold: 4\n};\nconst DEFAULT_ELEMENT_PROPS = {\n strokeColor: _colors__WEBPACK_IMPORTED_MODULE_1__.COLOR_PALETTE.black,\n backgroundColor: _colors__WEBPACK_IMPORTED_MODULE_1__.COLOR_PALETTE.transparent,\n fillStyle: \"solid\",\n strokeWidth: 2,\n strokeStyle: \"solid\",\n roughness: ROUGHNESS.artist,\n opacity: 100,\n locked: false\n};\nconst LIBRARY_SIDEBAR_TAB = \"library\";\nconst DEFAULT_SIDEBAR = {\n name: \"default\",\n defaultTab: LIBRARY_SIDEBAR_TAB\n};\nconst LIBRARY_DISABLED_TYPES = new Set([\"embeddable\", \"image\"]);\n\n//# sourceURL=webpack://ExcalidrawLib/../../constants.ts?");
3462
3462
 
3463
3463
  /***/ }),
3464
3464
 
@@ -3601,7 +3601,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
3601
3601
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3602
3602
 
3603
3603
  "use strict";
3604
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"AllowedExcalidrawActiveTools\": () => (/* binding */ AllowedExcalidrawActiveTools),\n/* harmony export */ \"restore\": () => (/* binding */ restore),\n/* harmony export */ \"restoreAppState\": () => (/* binding */ restoreAppState),\n/* harmony export */ \"restoreElements\": () => (/* binding */ restoreElements),\n/* harmony export */ \"restoreLibraryItems\": () => (/* binding */ restoreLibraryItems)\n/* harmony export */ });\n/* harmony import */ var _element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../element */ \"../../element/index.ts\");\n/* harmony import */ var _element_typeChecks__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../element/typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var _random__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../random */ \"../../random.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _appState__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../appState */ \"../../appState.ts\");\n/* harmony import */ var _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../element/linearElementEditor */ \"../../element/linearElementEditor.ts\");\n/* harmony import */ var _element_mutateElement__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../element/mutateElement */ \"../../element/mutateElement.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _element_textElement__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../element/textElement */ \"../../element/textElement.ts\");\n/* harmony import */ var _url__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./url */ \"../../data/url.ts\");\n/* harmony import */ var _frame__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../frame */ \"../../frame.ts\");\n\n\n\n\n\n\n\n\n\n\n\n\nconst AllowedExcalidrawActiveTools = {\n selection: true,\n text: true,\n rectangle: true,\n diamond: true,\n ellipse: true,\n line: true,\n image: true,\n arrow: true,\n freedraw: true,\n eraser: false,\n custom: true,\n frame: true,\n embeddable: true,\n hand: true,\n mermaid: true,\n laser: false\n};\n\nconst getFontFamilyByName = fontFamilyName => {\n if (Object.keys(_constants__WEBPACK_IMPORTED_MODULE_3__.FONT_FAMILY).includes(fontFamilyName)) {\n return _constants__WEBPACK_IMPORTED_MODULE_3__.FONT_FAMILY[fontFamilyName];\n }\n\n return _constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_FONT_FAMILY;\n};\n\nconst repairBinding = binding => {\n if (!binding) {\n return null;\n }\n\n return Object.assign(Object.assign({}, binding), {\n focus: binding.focus || 0\n });\n};\n\nconst restoreElementWithProperties = (element, extra) => {\n var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;\n\n const base = {\n type: extra.type || element.type,\n // all elements must have version > 0 so getSceneVersion() will pick up\n // newly added elements\n version: element.version || 1,\n versionNonce: (_a = element.versionNonce) !== null && _a !== void 0 ? _a : 0,\n isDeleted: (_b = element.isDeleted) !== null && _b !== void 0 ? _b : false,\n id: element.id || (0,_random__WEBPACK_IMPORTED_MODULE_2__.randomId)(),\n fillStyle: element.fillStyle || _constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_ELEMENT_PROPS.fillStyle,\n strokeWidth: element.strokeWidth || _constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_ELEMENT_PROPS.strokeWidth,\n strokeStyle: (_c = element.strokeStyle) !== null && _c !== void 0 ? _c : _constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_ELEMENT_PROPS.strokeStyle,\n roughness: (_d = element.roughness) !== null && _d !== void 0 ? _d : _constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_ELEMENT_PROPS.roughness,\n opacity: element.opacity == null ? _constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_ELEMENT_PROPS.opacity : element.opacity,\n angle: element.angle || 0,\n x: (_f = (_e = extra.x) !== null && _e !== void 0 ? _e : element.x) !== null && _f !== void 0 ? _f : 0,\n y: (_h = (_g = extra.y) !== null && _g !== void 0 ? _g : element.y) !== null && _h !== void 0 ? _h : 0,\n strokeColor: element.strokeColor || _constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_ELEMENT_PROPS.strokeColor,\n backgroundColor: element.backgroundColor || _constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_ELEMENT_PROPS.backgroundColor,\n width: element.width || 0,\n height: element.height || 0,\n seed: (_j = element.seed) !== null && _j !== void 0 ? _j : 1,\n groupIds: (_k = element.groupIds) !== null && _k !== void 0 ? _k : [],\n frameId: (_l = element.frameId) !== null && _l !== void 0 ? _l : null,\n roundness: element.roundness ? element.roundness : element.strokeSharpness === \"round\" ? {\n // for old elements that would now use adaptive radius algo,\n // use legacy algo instead\n type: (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isUsingAdaptiveRadius)(element.type) ? _constants__WEBPACK_IMPORTED_MODULE_3__.ROUNDNESS.LEGACY : _constants__WEBPACK_IMPORTED_MODULE_3__.ROUNDNESS.PROPORTIONAL_RADIUS\n } : null,\n boundElements: element.boundElementIds ? element.boundElementIds.map(id => ({\n type: \"arrow\",\n id\n })) : (_m = element.boundElements) !== null && _m !== void 0 ? _m : [],\n updated: (_o = element.updated) !== null && _o !== void 0 ? _o : (0,_utils__WEBPACK_IMPORTED_MODULE_7__.getUpdatedTimestamp)(),\n link: element.link ? (0,_url__WEBPACK_IMPORTED_MODULE_9__.normalizeLink)(element.link) : null,\n locked: (_p = element.locked) !== null && _p !== void 0 ? _p : false\n };\n\n if (\"customData\" in element) {\n base.customData = element.customData;\n }\n\n if (_constants__WEBPACK_IMPORTED_MODULE_3__.PRECEDING_ELEMENT_KEY in element) {\n base[_constants__WEBPACK_IMPORTED_MODULE_3__.PRECEDING_ELEMENT_KEY] = element[_constants__WEBPACK_IMPORTED_MODULE_3__.PRECEDING_ELEMENT_KEY];\n }\n\n return Object.assign(Object.assign(Object.assign({}, base), (0,_element__WEBPACK_IMPORTED_MODULE_0__.getNormalizedDimensions)(base)), extra);\n};\n\nconst restoreElement = (element, refreshDimensions = false) => {\n var _a, _b, _c;\n\n switch (element.type) {\n case \"text\":\n let fontSize = element.fontSize;\n let fontFamily = element.fontFamily;\n\n if (\"font\" in element) {\n const [fontPx, _fontFamily] = element.font.split(\" \");\n fontSize = parseFloat(fontPx);\n fontFamily = getFontFamilyByName(_fontFamily);\n }\n\n const text = typeof element.text === \"string\" && element.text || \"\"; // line-height might not be specified either when creating elements\n // programmatically, or when importing old diagrams.\n // For the latter we want to detect the original line height which\n // will likely differ from our per-font fixed line height we now use,\n // to maintain backward compatibility.\n\n const lineHeight = element.lineHeight || (element.height ? // detect line-height from current element height and font-size\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_8__.detectLineHeight)(element) : // no element height likely means programmatic use, so default\n // to a fixed line height\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_8__.getDefaultLineHeight)(element.fontFamily));\n const baseline = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_8__.measureBaseline)(element.text, (0,_utils__WEBPACK_IMPORTED_MODULE_7__.getFontString)(element), lineHeight);\n element = restoreElementWithProperties(element, {\n fontSize,\n fontFamily,\n text,\n rawText: (_a = element.rawText) !== null && _a !== void 0 ? _a : \"\",\n textAlign: element.textAlign || _constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_TEXT_ALIGN,\n verticalAlign: element.verticalAlign || _constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_VERTICAL_ALIGN,\n containerId: (_b = element.containerId) !== null && _b !== void 0 ? _b : null,\n originalText: element.originalText || text,\n lineHeight,\n baseline\n }); // if empty text, mark as deleted. We keep in array\n // for data integrity purposes (collab etc.)\n\n if (!text && !element.isDeleted) {\n element = Object.assign(Object.assign({}, element), {\n originalText: text,\n isDeleted: true\n });\n element = (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_6__.bumpVersion)(element);\n }\n\n if (refreshDimensions) {\n element = Object.assign(Object.assign({}, element), (0,_element__WEBPACK_IMPORTED_MODULE_0__.refreshTextDimensions)(element));\n }\n\n return element;\n\n case \"freedraw\":\n {\n return restoreElementWithProperties(element, {\n points: element.points,\n lastCommittedPoint: null,\n simulatePressure: element.simulatePressure,\n pressures: element.pressures\n });\n }\n\n case \"image\":\n return restoreElementWithProperties(element, {\n status: element.status || \"pending\",\n fileId: element.fileId,\n scale: element.scale || [1, 1]\n });\n\n case \"line\": // @ts-ignore LEGACY type\n // eslint-disable-next-line no-fallthrough\n\n case \"draw\":\n case \"arrow\":\n {\n const {\n startArrowhead = null,\n endArrowhead = element.type === \"arrow\" ? \"arrow\" : null\n } = element;\n let x = element.x;\n let y = element.y;\n let points = // migrate old arrow model to new one\n !Array.isArray(element.points) || element.points.length < 2 ? [[0, 0], [element.width, element.height]] : element.points;\n\n if (points[0][0] !== 0 || points[0][1] !== 0) {\n ({\n points,\n x,\n y\n } = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_5__.LinearElementEditor.getNormalizedPoints(element));\n }\n\n return restoreElementWithProperties(element, {\n type: element.type === \"draw\" ? \"line\" : element.type,\n startBinding: repairBinding(element.startBinding),\n endBinding: repairBinding(element.endBinding),\n lastCommittedPoint: null,\n startArrowhead,\n endArrowhead,\n points,\n x,\n y\n });\n }\n // generic elements\n\n case \"ellipse\":\n return restoreElementWithProperties(element, {});\n\n case \"rectangle\":\n return restoreElementWithProperties(element, {});\n\n case \"diamond\":\n return restoreElementWithProperties(element, {});\n\n case \"embeddable\":\n return restoreElementWithProperties(element, {\n validated: null\n });\n\n case \"frame\":\n return restoreElementWithProperties(element, {\n name: (_c = element.name) !== null && _c !== void 0 ? _c : null\n });\n // Don't use default case so as to catch a missing an element type case.\n // We also don't want to throw, but instead return void so we filter\n // out these unsupported elements from the restored array.\n }\n\n return null;\n};\n/**\r\n * Repairs contaienr element's boundElements array by removing duplicates and\r\n * fixing containerId of bound elements if not present. Also removes any\r\n * bound elements that do not exist in the elements array.\r\n *\r\n * NOTE mutates elements.\r\n */\n\n\nconst repairContainerElement = (container, elementsMap) => {\n if (container.boundElements) {\n // copy because we're not cloning on restore, and we don't want to mutate upstream\n const boundElements = container.boundElements.slice(); // dedupe bindings & fix boundElement.containerId if not set already\n\n const boundIds = new Set();\n container.boundElements = boundElements.reduce((acc, binding) => {\n const boundElement = elementsMap.get(binding.id);\n\n if (boundElement && !boundIds.has(binding.id)) {\n boundIds.add(binding.id);\n\n if (boundElement.isDeleted) {\n return acc;\n }\n\n acc.push(binding);\n\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isTextElement)(boundElement) && // being slightly conservative here, preserving existing containerId\n // if defined, lest boundElements is stale\n !boundElement.containerId) {\n boundElement.containerId = container.id;\n }\n }\n\n return acc;\n }, []);\n }\n};\n/**\r\n * Repairs target bound element's container's boundElements array,\r\n * or removes contaienrId if container does not exist.\r\n *\r\n * NOTE mutates elements.\r\n */\n\n\nconst repairBoundElement = (boundElement, elementsMap) => {\n const container = boundElement.containerId ? elementsMap.get(boundElement.containerId) : null;\n\n if (!container) {\n boundElement.containerId = null;\n return;\n }\n\n if (boundElement.isDeleted) {\n return;\n }\n\n if (container.boundElements && !container.boundElements.find(binding => binding.id === boundElement.id)) {\n // copy because we're not cloning on restore, and we don't want to mutate upstream\n const boundElements = (container.boundElements || (container.boundElements = [])).slice();\n boundElements.push({\n type: \"text\",\n id: boundElement.id\n });\n container.boundElements = boundElements;\n }\n};\n/**\r\n * resets `frameId` if no longer applicable.\r\n *\r\n * NOTE mutates elements.\r\n */\n\n\nconst repairFrameMembership = (element, elementsMap) => {\n if (!element.frameId) {\n return;\n }\n\n if (!(0,_frame__WEBPACK_IMPORTED_MODULE_10__.isValidFrameChild)(element) || // target frame not exists\n !elementsMap.get(element.frameId)) {\n element.frameId = null;\n }\n};\n\nconst restoreElements = (elements,\n/** NOTE doesn't serve for reconciliation */\nlocalElements, opts) => {\n // used to detect duplicate top-level element ids\n const existingIds = new Set();\n const localElementsMap = localElements ? (0,_utils__WEBPACK_IMPORTED_MODULE_7__.arrayToMap)(localElements) : null;\n const restoredElements = (elements || []).reduce((elements, element) => {\n // filtering out selection, which is legacy, no longer kept in elements,\n // and causing issues if retained\n if (element.type !== \"selection\" && !(0,_element__WEBPACK_IMPORTED_MODULE_0__.isInvisiblySmallElement)(element)) {\n let migratedElement = restoreElement(element, opts === null || opts === void 0 ? void 0 : opts.refreshDimensions);\n\n if (migratedElement) {\n const localElement = localElementsMap === null || localElementsMap === void 0 ? void 0 : localElementsMap.get(element.id);\n\n if (localElement && localElement.version > migratedElement.version) {\n migratedElement = (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_6__.bumpVersion)(migratedElement, localElement.version);\n }\n\n if (existingIds.has(migratedElement.id)) {\n migratedElement = Object.assign(Object.assign({}, migratedElement), {\n id: (0,_random__WEBPACK_IMPORTED_MODULE_2__.randomId)()\n });\n }\n\n existingIds.add(migratedElement.id);\n elements.push(migratedElement);\n }\n }\n\n return elements;\n }, []);\n\n if (!(opts === null || opts === void 0 ? void 0 : opts.repairBindings)) {\n return restoredElements;\n } // repair binding. Mutates elements.\n\n\n const restoredElementsMap = (0,_utils__WEBPACK_IMPORTED_MODULE_7__.arrayToMap)(restoredElements);\n\n for (const element of restoredElements) {\n // repair frame membership *after* bindings we do in restoreElement()\n // since we rely on bindings to be correct\n if (element.frameId) {\n repairFrameMembership(element, restoredElementsMap);\n }\n\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isTextElement)(element) && element.containerId) {\n repairBoundElement(element, restoredElementsMap);\n } else if (element.boundElements) {\n repairContainerElement(element, restoredElementsMap);\n }\n }\n\n return restoredElements;\n};\n\nconst coalesceAppStateValue = (key, appState, defaultAppState) => {\n const value = appState[key]; // NOTE the value! assertion is needed in TS 4.5.5 (fixed in newer versions)\n\n return value !== undefined ? value : defaultAppState[key];\n};\n\nconst LegacyAppStateMigrations = {\n isSidebarDocked: (appState, defaultAppState) => {\n var _a;\n\n return [\"defaultSidebarDockedPreference\", (_a = appState.isSidebarDocked) !== null && _a !== void 0 ? _a : coalesceAppStateValue(\"defaultSidebarDockedPreference\", appState, defaultAppState)];\n }\n};\nconst restoreAppState = (appState, localAppState) => {\n var _a, _b, _c, _d;\n\n appState = appState || {};\n const defaultAppState = (0,_appState__WEBPACK_IMPORTED_MODULE_4__.getDefaultAppState)();\n const nextAppState = {}; // first, migrate all legacy AppState properties to new ones. We do it\n // in one go before migrate the rest of the properties in case the new ones\n // depend on checking any other key (i.e. they are coupled)\n\n for (const legacyKey of Object.keys(LegacyAppStateMigrations)) {\n if (legacyKey in appState) {\n const [nextKey, nextValue] = LegacyAppStateMigrations[legacyKey](appState, defaultAppState);\n nextAppState[nextKey] = nextValue;\n }\n }\n\n for (const [key, defaultValue] of Object.entries(defaultAppState)) {\n // if AppState contains a legacy key, prefer that one and migrate its\n // value to the new one\n const suppliedValue = appState[key];\n const localValue = localAppState ? localAppState[key] : undefined;\n nextAppState[key] = suppliedValue !== undefined ? suppliedValue : localValue !== undefined ? localValue : defaultValue;\n }\n\n return Object.assign(Object.assign({}, nextAppState), {\n cursorButton: (localAppState === null || localAppState === void 0 ? void 0 : localAppState.cursorButton) || \"up\",\n // reset on fresh restore so as to hide the UI button if penMode not active\n penDetected: (_a = localAppState === null || localAppState === void 0 ? void 0 : localAppState.penDetected) !== null && _a !== void 0 ? _a : appState.penMode ? (_b = appState.penDetected) !== null && _b !== void 0 ? _b : false : false,\n activeTool: Object.assign(Object.assign({}, (0,_utils__WEBPACK_IMPORTED_MODULE_7__.updateActiveTool)(defaultAppState, nextAppState.activeTool.type && AllowedExcalidrawActiveTools[nextAppState.activeTool.type] ? nextAppState.activeTool : {\n type: \"selection\"\n })), {\n lastActiveTool: null,\n locked: (_c = nextAppState.activeTool.locked) !== null && _c !== void 0 ? _c : false\n }),\n // Migrates from previous version where appState.zoom was a number\n zoom: typeof appState.zoom === \"number\" ? {\n value: appState.zoom\n } : ((_d = appState.zoom) === null || _d === void 0 ? void 0 : _d.value) ? appState.zoom : defaultAppState.zoom,\n openSidebar: // string (legacy)\n typeof appState.openSidebar === \"string\" ? {\n name: _constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_SIDEBAR.name\n } : nextAppState.openSidebar\n });\n};\nconst restore = (data,\n/**\r\n * Local AppState (`this.state` or initial state from localStorage) so that we\r\n * don't overwrite local state with default values (when values not\r\n * explicitly specified).\r\n * Supply `null` if you can't get access to it.\r\n */\nlocalAppState, localElements, elementsConfig) => {\n return {\n elements: restoreElements(data === null || data === void 0 ? void 0 : data.elements, localElements, elementsConfig),\n appState: restoreAppState(data === null || data === void 0 ? void 0 : data.appState, localAppState || null),\n files: (data === null || data === void 0 ? void 0 : data.files) || {}\n };\n};\n\nconst restoreLibraryItem = libraryItem => {\n const elements = restoreElements((0,_element__WEBPACK_IMPORTED_MODULE_0__.getNonDeletedElements)(libraryItem.elements), null);\n return elements.length ? Object.assign(Object.assign({}, libraryItem), {\n elements\n }) : null;\n};\n\nconst restoreLibraryItems = (libraryItems = [], defaultStatus) => {\n const restoredItems = [];\n\n for (const item of libraryItems) {\n // migrate older libraries\n if (Array.isArray(item)) {\n const restoredItem = restoreLibraryItem({\n status: defaultStatus,\n elements: item,\n id: (0,_random__WEBPACK_IMPORTED_MODULE_2__.randomId)(),\n created: Date.now()\n });\n\n if (restoredItem) {\n restoredItems.push(restoredItem);\n }\n } else {\n const _item = item;\n const restoredItem = restoreLibraryItem(Object.assign(Object.assign({}, _item), {\n id: _item.id || (0,_random__WEBPACK_IMPORTED_MODULE_2__.randomId)(),\n status: _item.status || defaultStatus,\n created: _item.created || Date.now()\n }));\n\n if (restoredItem) {\n restoredItems.push(restoredItem);\n }\n }\n }\n\n return restoredItems;\n};\n\n//# sourceURL=webpack://ExcalidrawLib/../../data/restore.ts?");
3604
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"AllowedExcalidrawActiveTools\": () => (/* binding */ AllowedExcalidrawActiveTools),\n/* harmony export */ \"restore\": () => (/* binding */ restore),\n/* harmony export */ \"restoreAppState\": () => (/* binding */ restoreAppState),\n/* harmony export */ \"restoreElements\": () => (/* binding */ restoreElements),\n/* harmony export */ \"restoreLibraryItems\": () => (/* binding */ restoreLibraryItems)\n/* harmony export */ });\n/* harmony import */ var _element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../element */ \"../../element/index.ts\");\n/* harmony import */ var _element_typeChecks__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../element/typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var _random__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../random */ \"../../random.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _appState__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../appState */ \"../../appState.ts\");\n/* harmony import */ var _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../element/linearElementEditor */ \"../../element/linearElementEditor.ts\");\n/* harmony import */ var _element_mutateElement__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../element/mutateElement */ \"../../element/mutateElement.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _element_textElement__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../element/textElement */ \"../../element/textElement.ts\");\n/* harmony import */ var _url__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./url */ \"../../data/url.ts\");\n\n\n\n\n\n\n\n\n\n\n\nconst AllowedExcalidrawActiveTools = {\n selection: true,\n text: true,\n rectangle: true,\n diamond: true,\n ellipse: true,\n line: true,\n image: true,\n arrow: true,\n freedraw: true,\n eraser: false,\n custom: true,\n frame: true,\n embeddable: true,\n hand: true,\n mermaid: true,\n laser: false\n};\n\nconst getFontFamilyByName = fontFamilyName => {\n if (Object.keys(_constants__WEBPACK_IMPORTED_MODULE_3__.FONT_FAMILY).includes(fontFamilyName)) {\n return _constants__WEBPACK_IMPORTED_MODULE_3__.FONT_FAMILY[fontFamilyName];\n }\n\n return _constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_FONT_FAMILY;\n};\n\nconst repairBinding = binding => {\n if (!binding) {\n return null;\n }\n\n return Object.assign(Object.assign({}, binding), {\n focus: binding.focus || 0\n });\n};\n\nconst restoreElementWithProperties = (element, extra) => {\n var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;\n\n const base = {\n type: extra.type || element.type,\n // all elements must have version > 0 so getSceneVersion() will pick up\n // newly added elements\n version: element.version || 1,\n versionNonce: (_a = element.versionNonce) !== null && _a !== void 0 ? _a : 0,\n isDeleted: (_b = element.isDeleted) !== null && _b !== void 0 ? _b : false,\n id: element.id || (0,_random__WEBPACK_IMPORTED_MODULE_2__.randomId)(),\n fillStyle: element.fillStyle || _constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_ELEMENT_PROPS.fillStyle,\n strokeWidth: element.strokeWidth || _constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_ELEMENT_PROPS.strokeWidth,\n strokeStyle: (_c = element.strokeStyle) !== null && _c !== void 0 ? _c : _constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_ELEMENT_PROPS.strokeStyle,\n roughness: (_d = element.roughness) !== null && _d !== void 0 ? _d : _constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_ELEMENT_PROPS.roughness,\n opacity: element.opacity == null ? _constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_ELEMENT_PROPS.opacity : element.opacity,\n angle: element.angle || 0,\n x: (_f = (_e = extra.x) !== null && _e !== void 0 ? _e : element.x) !== null && _f !== void 0 ? _f : 0,\n y: (_h = (_g = extra.y) !== null && _g !== void 0 ? _g : element.y) !== null && _h !== void 0 ? _h : 0,\n strokeColor: element.strokeColor || _constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_ELEMENT_PROPS.strokeColor,\n backgroundColor: element.backgroundColor || _constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_ELEMENT_PROPS.backgroundColor,\n width: element.width || 0,\n height: element.height || 0,\n seed: (_j = element.seed) !== null && _j !== void 0 ? _j : 1,\n groupIds: (_k = element.groupIds) !== null && _k !== void 0 ? _k : [],\n frameId: (_l = element.frameId) !== null && _l !== void 0 ? _l : null,\n roundness: element.roundness ? element.roundness : element.strokeSharpness === \"round\" ? {\n // for old elements that would now use adaptive radius algo,\n // use legacy algo instead\n type: (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isUsingAdaptiveRadius)(element.type) ? _constants__WEBPACK_IMPORTED_MODULE_3__.ROUNDNESS.LEGACY : _constants__WEBPACK_IMPORTED_MODULE_3__.ROUNDNESS.PROPORTIONAL_RADIUS\n } : null,\n boundElements: element.boundElementIds ? element.boundElementIds.map(id => ({\n type: \"arrow\",\n id\n })) : (_m = element.boundElements) !== null && _m !== void 0 ? _m : [],\n updated: (_o = element.updated) !== null && _o !== void 0 ? _o : (0,_utils__WEBPACK_IMPORTED_MODULE_7__.getUpdatedTimestamp)(),\n link: element.link ? (0,_url__WEBPACK_IMPORTED_MODULE_9__.normalizeLink)(element.link) : null,\n locked: (_p = element.locked) !== null && _p !== void 0 ? _p : false\n };\n\n if (\"customData\" in element) {\n base.customData = element.customData;\n }\n\n if (_constants__WEBPACK_IMPORTED_MODULE_3__.PRECEDING_ELEMENT_KEY in element) {\n base[_constants__WEBPACK_IMPORTED_MODULE_3__.PRECEDING_ELEMENT_KEY] = element[_constants__WEBPACK_IMPORTED_MODULE_3__.PRECEDING_ELEMENT_KEY];\n }\n\n return Object.assign(Object.assign(Object.assign({}, base), (0,_element__WEBPACK_IMPORTED_MODULE_0__.getNormalizedDimensions)(base)), extra);\n};\n\nconst restoreElement = (element, refreshDimensions = false) => {\n var _a, _b, _c;\n\n switch (element.type) {\n case \"text\":\n let fontSize = element.fontSize;\n let fontFamily = element.fontFamily;\n\n if (\"font\" in element) {\n const [fontPx, _fontFamily] = element.font.split(\" \");\n fontSize = parseFloat(fontPx);\n fontFamily = getFontFamilyByName(_fontFamily);\n }\n\n const text = typeof element.text === \"string\" && element.text || \"\"; // line-height might not be specified either when creating elements\n // programmatically, or when importing old diagrams.\n // For the latter we want to detect the original line height which\n // will likely differ from our per-font fixed line height we now use,\n // to maintain backward compatibility.\n\n const lineHeight = element.lineHeight || (element.height ? // detect line-height from current element height and font-size\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_8__.detectLineHeight)(element) : // no element height likely means programmatic use, so default\n // to a fixed line height\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_8__.getDefaultLineHeight)(element.fontFamily));\n const baseline = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_8__.measureBaseline)(element.text, (0,_utils__WEBPACK_IMPORTED_MODULE_7__.getFontString)(element), lineHeight);\n element = restoreElementWithProperties(element, {\n fontSize,\n fontFamily,\n text,\n rawText: (_a = element.rawText) !== null && _a !== void 0 ? _a : \"\",\n textAlign: element.textAlign || _constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_TEXT_ALIGN,\n verticalAlign: element.verticalAlign || _constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_VERTICAL_ALIGN,\n containerId: (_b = element.containerId) !== null && _b !== void 0 ? _b : null,\n originalText: element.originalText || text,\n lineHeight,\n baseline\n }); // if empty text, mark as deleted. We keep in array\n // for data integrity purposes (collab etc.)\n\n if (!text && !element.isDeleted) {\n element = Object.assign(Object.assign({}, element), {\n originalText: text,\n isDeleted: true\n });\n element = (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_6__.bumpVersion)(element);\n }\n\n if (refreshDimensions) {\n element = Object.assign(Object.assign({}, element), (0,_element__WEBPACK_IMPORTED_MODULE_0__.refreshTextDimensions)(element));\n }\n\n return element;\n\n case \"freedraw\":\n {\n return restoreElementWithProperties(element, {\n points: element.points,\n lastCommittedPoint: null,\n simulatePressure: element.simulatePressure,\n pressures: element.pressures\n });\n }\n\n case \"image\":\n return restoreElementWithProperties(element, {\n status: element.status || \"pending\",\n fileId: element.fileId,\n scale: element.scale || [1, 1]\n });\n\n case \"line\": // @ts-ignore LEGACY type\n // eslint-disable-next-line no-fallthrough\n\n case \"draw\":\n case \"arrow\":\n {\n const {\n startArrowhead = null,\n endArrowhead = element.type === \"arrow\" ? \"arrow\" : null\n } = element;\n let x = element.x;\n let y = element.y;\n let points = // migrate old arrow model to new one\n !Array.isArray(element.points) || element.points.length < 2 ? [[0, 0], [element.width, element.height]] : element.points;\n\n if (points[0][0] !== 0 || points[0][1] !== 0) {\n ({\n points,\n x,\n y\n } = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_5__.LinearElementEditor.getNormalizedPoints(element));\n }\n\n return restoreElementWithProperties(element, {\n type: element.type === \"draw\" ? \"line\" : element.type,\n startBinding: repairBinding(element.startBinding),\n endBinding: repairBinding(element.endBinding),\n lastCommittedPoint: null,\n startArrowhead,\n endArrowhead,\n points,\n x,\n y\n });\n }\n // generic elements\n\n case \"ellipse\":\n return restoreElementWithProperties(element, {});\n\n case \"rectangle\":\n return restoreElementWithProperties(element, {});\n\n case \"diamond\":\n return restoreElementWithProperties(element, {});\n\n case \"embeddable\":\n return restoreElementWithProperties(element, {\n validated: null\n });\n\n case \"frame\":\n return restoreElementWithProperties(element, {\n name: (_c = element.name) !== null && _c !== void 0 ? _c : null\n });\n // Don't use default case so as to catch a missing an element type case.\n // We also don't want to throw, but instead return void so we filter\n // out these unsupported elements from the restored array.\n }\n\n return null;\n};\n/**\r\n * Repairs contaienr element's boundElements array by removing duplicates and\r\n * fixing containerId of bound elements if not present. Also removes any\r\n * bound elements that do not exist in the elements array.\r\n *\r\n * NOTE mutates elements.\r\n */\n\n\nconst repairContainerElement = (container, elementsMap) => {\n if (container.boundElements) {\n // copy because we're not cloning on restore, and we don't want to mutate upstream\n const boundElements = container.boundElements.slice(); // dedupe bindings & fix boundElement.containerId if not set already\n\n const boundIds = new Set();\n container.boundElements = boundElements.reduce((acc, binding) => {\n const boundElement = elementsMap.get(binding.id);\n\n if (boundElement && !boundIds.has(binding.id)) {\n boundIds.add(binding.id);\n\n if (boundElement.isDeleted) {\n return acc;\n }\n\n acc.push(binding);\n\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isTextElement)(boundElement) && // being slightly conservative here, preserving existing containerId\n // if defined, lest boundElements is stale\n !boundElement.containerId) {\n boundElement.containerId = container.id;\n }\n }\n\n return acc;\n }, []);\n }\n};\n/**\r\n * Repairs target bound element's container's boundElements array,\r\n * or removes contaienrId if container does not exist.\r\n *\r\n * NOTE mutates elements.\r\n */\n\n\nconst repairBoundElement = (boundElement, elementsMap) => {\n const container = boundElement.containerId ? elementsMap.get(boundElement.containerId) : null;\n\n if (!container) {\n boundElement.containerId = null;\n return;\n }\n\n if (boundElement.isDeleted) {\n return;\n }\n\n if (container.boundElements && !container.boundElements.find(binding => binding.id === boundElement.id)) {\n // copy because we're not cloning on restore, and we don't want to mutate upstream\n const boundElements = (container.boundElements || (container.boundElements = [])).slice();\n boundElements.push({\n type: \"text\",\n id: boundElement.id\n });\n container.boundElements = boundElements;\n }\n};\n/**\r\n * Remove an element's frameId if its containing frame is non-existent\r\n *\r\n * NOTE mutates elements.\r\n */\n\n\nconst repairFrameMembership = (element, elementsMap) => {\n if (element.frameId) {\n const containingFrame = elementsMap.get(element.frameId);\n\n if (!containingFrame) {\n element.frameId = null;\n }\n }\n};\n\nconst restoreElements = (elements,\n/** NOTE doesn't serve for reconciliation */\nlocalElements, opts) => {\n // used to detect duplicate top-level element ids\n const existingIds = new Set();\n const localElementsMap = localElements ? (0,_utils__WEBPACK_IMPORTED_MODULE_7__.arrayToMap)(localElements) : null;\n const restoredElements = (elements || []).reduce((elements, element) => {\n // filtering out selection, which is legacy, no longer kept in elements,\n // and causing issues if retained\n if (element.type !== \"selection\" && !(0,_element__WEBPACK_IMPORTED_MODULE_0__.isInvisiblySmallElement)(element)) {\n let migratedElement = restoreElement(element, opts === null || opts === void 0 ? void 0 : opts.refreshDimensions);\n\n if (migratedElement) {\n const localElement = localElementsMap === null || localElementsMap === void 0 ? void 0 : localElementsMap.get(element.id);\n\n if (localElement && localElement.version > migratedElement.version) {\n migratedElement = (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_6__.bumpVersion)(migratedElement, localElement.version);\n }\n\n if (existingIds.has(migratedElement.id)) {\n migratedElement = Object.assign(Object.assign({}, migratedElement), {\n id: (0,_random__WEBPACK_IMPORTED_MODULE_2__.randomId)()\n });\n }\n\n existingIds.add(migratedElement.id);\n elements.push(migratedElement);\n }\n }\n\n return elements;\n }, []);\n\n if (!(opts === null || opts === void 0 ? void 0 : opts.repairBindings)) {\n return restoredElements;\n } // repair binding. Mutates elements.\n\n\n const restoredElementsMap = (0,_utils__WEBPACK_IMPORTED_MODULE_7__.arrayToMap)(restoredElements);\n\n for (const element of restoredElements) {\n if (element.frameId) {\n repairFrameMembership(element, restoredElementsMap);\n }\n\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isTextElement)(element) && element.containerId) {\n repairBoundElement(element, restoredElementsMap);\n } else if (element.boundElements) {\n repairContainerElement(element, restoredElementsMap);\n }\n }\n\n return restoredElements;\n};\n\nconst coalesceAppStateValue = (key, appState, defaultAppState) => {\n const value = appState[key]; // NOTE the value! assertion is needed in TS 4.5.5 (fixed in newer versions)\n\n return value !== undefined ? value : defaultAppState[key];\n};\n\nconst LegacyAppStateMigrations = {\n isSidebarDocked: (appState, defaultAppState) => {\n var _a;\n\n return [\"defaultSidebarDockedPreference\", (_a = appState.isSidebarDocked) !== null && _a !== void 0 ? _a : coalesceAppStateValue(\"defaultSidebarDockedPreference\", appState, defaultAppState)];\n }\n};\nconst restoreAppState = (appState, localAppState) => {\n var _a, _b, _c, _d;\n\n appState = appState || {};\n const defaultAppState = (0,_appState__WEBPACK_IMPORTED_MODULE_4__.getDefaultAppState)();\n const nextAppState = {}; // first, migrate all legacy AppState properties to new ones. We do it\n // in one go before migrate the rest of the properties in case the new ones\n // depend on checking any other key (i.e. they are coupled)\n\n for (const legacyKey of Object.keys(LegacyAppStateMigrations)) {\n if (legacyKey in appState) {\n const [nextKey, nextValue] = LegacyAppStateMigrations[legacyKey](appState, defaultAppState);\n nextAppState[nextKey] = nextValue;\n }\n }\n\n for (const [key, defaultValue] of Object.entries(defaultAppState)) {\n // if AppState contains a legacy key, prefer that one and migrate its\n // value to the new one\n const suppliedValue = appState[key];\n const localValue = localAppState ? localAppState[key] : undefined;\n nextAppState[key] = suppliedValue !== undefined ? suppliedValue : localValue !== undefined ? localValue : defaultValue;\n }\n\n return Object.assign(Object.assign({}, nextAppState), {\n cursorButton: (localAppState === null || localAppState === void 0 ? void 0 : localAppState.cursorButton) || \"up\",\n // reset on fresh restore so as to hide the UI button if penMode not active\n penDetected: (_a = localAppState === null || localAppState === void 0 ? void 0 : localAppState.penDetected) !== null && _a !== void 0 ? _a : appState.penMode ? (_b = appState.penDetected) !== null && _b !== void 0 ? _b : false : false,\n activeTool: Object.assign(Object.assign({}, (0,_utils__WEBPACK_IMPORTED_MODULE_7__.updateActiveTool)(defaultAppState, nextAppState.activeTool.type && AllowedExcalidrawActiveTools[nextAppState.activeTool.type] ? nextAppState.activeTool : {\n type: \"selection\"\n })), {\n lastActiveTool: null,\n locked: (_c = nextAppState.activeTool.locked) !== null && _c !== void 0 ? _c : false\n }),\n // Migrates from previous version where appState.zoom was a number\n zoom: typeof appState.zoom === \"number\" ? {\n value: appState.zoom\n } : ((_d = appState.zoom) === null || _d === void 0 ? void 0 : _d.value) ? appState.zoom : defaultAppState.zoom,\n openSidebar: // string (legacy)\n typeof appState.openSidebar === \"string\" ? {\n name: _constants__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_SIDEBAR.name\n } : nextAppState.openSidebar\n });\n};\nconst restore = (data,\n/**\r\n * Local AppState (`this.state` or initial state from localStorage) so that we\r\n * don't overwrite local state with default values (when values not\r\n * explicitly specified).\r\n * Supply `null` if you can't get access to it.\r\n */\nlocalAppState, localElements, elementsConfig) => {\n return {\n elements: restoreElements(data === null || data === void 0 ? void 0 : data.elements, localElements, elementsConfig),\n appState: restoreAppState(data === null || data === void 0 ? void 0 : data.appState, localAppState || null),\n files: (data === null || data === void 0 ? void 0 : data.files) || {}\n };\n};\n\nconst restoreLibraryItem = libraryItem => {\n const elements = restoreElements((0,_element__WEBPACK_IMPORTED_MODULE_0__.getNonDeletedElements)(libraryItem.elements), null);\n return elements.length ? Object.assign(Object.assign({}, libraryItem), {\n elements\n }) : null;\n};\n\nconst restoreLibraryItems = (libraryItems = [], defaultStatus) => {\n const restoredItems = [];\n\n for (const item of libraryItems) {\n // migrate older libraries\n if (Array.isArray(item)) {\n const restoredItem = restoreLibraryItem({\n status: defaultStatus,\n elements: item,\n id: (0,_random__WEBPACK_IMPORTED_MODULE_2__.randomId)(),\n created: Date.now()\n });\n\n if (restoredItem) {\n restoredItems.push(restoredItem);\n }\n } else {\n const _item = item;\n const restoredItem = restoreLibraryItem(Object.assign(Object.assign({}, _item), {\n id: _item.id || (0,_random__WEBPACK_IMPORTED_MODULE_2__.randomId)(),\n status: _item.status || defaultStatus,\n created: _item.created || Date.now()\n }));\n\n if (restoredItem) {\n restoredItems.push(restoredItem);\n }\n }\n }\n\n return restoredItems;\n};\n\n//# sourceURL=webpack://ExcalidrawLib/../../data/restore.ts?");
3605
3605
 
3606
3606
  /***/ }),
3607
3607
 
@@ -3656,7 +3656,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
3656
3656
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3657
3657
 
3658
3658
  "use strict";
3659
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"bindLinearElement\": () => (/* binding */ bindLinearElement),\n/* harmony export */ \"bindOrUnbindLinearElement\": () => (/* binding */ bindOrUnbindLinearElement),\n/* harmony export */ \"bindOrUnbindSelectedElements\": () => (/* binding */ bindOrUnbindSelectedElements),\n/* harmony export */ \"fixBindingsAfterDeletion\": () => (/* binding */ fixBindingsAfterDeletion),\n/* harmony export */ \"fixBindingsAfterDuplication\": () => (/* binding */ fixBindingsAfterDuplication),\n/* harmony export */ \"getEligibleElementsForBinding\": () => (/* binding */ getEligibleElementsForBinding),\n/* harmony export */ \"getHoveredElementForBinding\": () => (/* binding */ getHoveredElementForBinding),\n/* harmony export */ \"isBindingEnabled\": () => (/* binding */ isBindingEnabled),\n/* harmony export */ \"isLinearElementSimpleAndAlreadyBound\": () => (/* binding */ isLinearElementSimpleAndAlreadyBound),\n/* harmony export */ \"maybeBindLinearElement\": () => (/* binding */ maybeBindLinearElement),\n/* harmony export */ \"shouldEnableBindingForPointerEvent\": () => (/* binding */ shouldEnableBindingForPointerEvent),\n/* harmony export */ \"unbindLinearElements\": () => (/* binding */ unbindLinearElements),\n/* harmony export */ \"updateBoundElements\": () => (/* binding */ updateBoundElements)\n/* harmony export */ });\n/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../scene */ \"../../scene/index.ts\");\n/* harmony import */ var _typeChecks__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var _collision__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./collision */ \"../../element/collision.ts\");\n/* harmony import */ var _mutateElement__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./mutateElement */ \"../../element/mutateElement.ts\");\n/* harmony import */ var _scene_Scene__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../scene/Scene */ \"../../scene/Scene.ts\");\n/* harmony import */ var _linearElementEditor__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./linearElementEditor */ \"../../element/linearElementEditor.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _keys__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../keys */ \"../../keys.ts\");\n/* harmony import */ var _textElement__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./textElement */ \"../../element/textElement.ts\");\n/* harmony import */ var _frame__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../frame */ \"../../frame.ts\");\n\n\n\n\n\n\n\n\n\n\nconst shouldEnableBindingForPointerEvent = event => {\n return !event[_keys__WEBPACK_IMPORTED_MODULE_7__.KEYS.CTRL_OR_CMD];\n};\nconst isBindingEnabled = appState => {\n return appState.invertBindingBehaviour //zsviczian\n ? !appState.isBindingEnabled : appState.isBindingEnabled;\n};\n\nconst getNonDeletedElements = (scene, ids) => {\n const result = [];\n ids.forEach(id => {\n const element = scene.getNonDeletedElement(id);\n\n if (element != null) {\n result.push(element);\n }\n });\n return result;\n};\n\nconst bindOrUnbindLinearElement = (linearElement, startBindingElement, endBindingElement) => {\n const boundToElementIds = new Set();\n const unboundFromElementIds = new Set();\n bindOrUnbindLinearElementEdge(linearElement, startBindingElement, endBindingElement, \"start\", boundToElementIds, unboundFromElementIds);\n bindOrUnbindLinearElementEdge(linearElement, endBindingElement, startBindingElement, \"end\", boundToElementIds, unboundFromElementIds);\n const onlyUnbound = Array.from(unboundFromElementIds).filter(id => !boundToElementIds.has(id));\n getNonDeletedElements(_scene_Scene__WEBPACK_IMPORTED_MODULE_4__[\"default\"].getScene(linearElement), onlyUnbound).forEach(element => {\n var _a;\n\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(element, {\n boundElements: (_a = element.boundElements) === null || _a === void 0 ? void 0 : _a.filter(element => element.type !== \"arrow\" || element.id !== linearElement.id)\n });\n });\n};\n\nconst bindOrUnbindLinearElementEdge = (linearElement, bindableElement, otherEdgeBindableElement, startOrEnd, // Is mutated\nboundToElementIds, // Is mutated\nunboundFromElementIds) => {\n if (bindableElement !== \"keep\") {\n if (bindableElement != null) {\n // Don't bind if we're trying to bind or are already bound to the same\n // element on the other edge already (\"start\" edge takes precedence).\n if (otherEdgeBindableElement == null || (otherEdgeBindableElement === \"keep\" ? !isLinearElementSimpleAndAlreadyBoundOnOppositeEdge(linearElement, bindableElement, startOrEnd) : startOrEnd === \"start\" || otherEdgeBindableElement.id !== bindableElement.id)) {\n bindLinearElement(linearElement, bindableElement, startOrEnd);\n boundToElementIds.add(bindableElement.id);\n }\n } else {\n const unbound = unbindLinearElement(linearElement, startOrEnd);\n\n if (unbound != null) {\n unboundFromElementIds.add(unbound);\n }\n }\n }\n};\n\nconst bindOrUnbindSelectedElements = elements => {\n elements.forEach(element => {\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isBindingElement)(element)) {\n bindOrUnbindLinearElement(element, getElligibleElementForBindingElement(element, \"start\"), getElligibleElementForBindingElement(element, \"end\"));\n } else if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isBindableElement)(element)) {\n maybeBindBindableElement(element);\n }\n });\n};\n\nconst maybeBindBindableElement = bindableElement => {\n getElligibleElementsForBindableElementAndWhere(bindableElement).forEach(([linearElement, where]) => bindOrUnbindLinearElement(linearElement, where === \"end\" ? \"keep\" : bindableElement, where === \"start\" ? \"keep\" : bindableElement));\n};\n\nconst maybeBindLinearElement = (linearElement, appState, scene, pointerCoords) => {\n if (appState.startBoundElement != null) {\n bindLinearElement(linearElement, appState.startBoundElement, \"start\");\n }\n\n const hoveredElement = getHoveredElementForBinding(pointerCoords, scene);\n\n if (hoveredElement != null && !isLinearElementSimpleAndAlreadyBoundOnOppositeEdge(linearElement, hoveredElement, \"end\")) {\n bindLinearElement(linearElement, hoveredElement, \"end\");\n }\n};\nconst bindLinearElement = (linearElement, hoveredElement, startOrEnd) => {\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(linearElement, {\n [startOrEnd === \"start\" ? \"startBinding\" : \"endBinding\"]: Object.assign({\n elementId: hoveredElement.id\n }, calculateFocusAndGap(linearElement, hoveredElement, startOrEnd))\n });\n const boundElementsMap = (0,_utils__WEBPACK_IMPORTED_MODULE_6__.arrayToMap)(hoveredElement.boundElements || []);\n\n if (!boundElementsMap.has(linearElement.id)) {\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(hoveredElement, {\n boundElements: (hoveredElement.boundElements || []).concat({\n id: linearElement.id,\n type: \"arrow\"\n })\n });\n }\n\n if (linearElement.frameId && !(0,_frame__WEBPACK_IMPORTED_MODULE_9__.isValidFrameChild)(linearElement)) {\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(linearElement, {\n frameId: null\n }, false);\n }\n}; // Don't bind both ends of a simple segment\n\nconst isLinearElementSimpleAndAlreadyBoundOnOppositeEdge = (linearElement, bindableElement, startOrEnd) => {\n const otherBinding = linearElement[startOrEnd === \"start\" ? \"endBinding\" : \"startBinding\"];\n return isLinearElementSimpleAndAlreadyBound(linearElement, otherBinding === null || otherBinding === void 0 ? void 0 : otherBinding.elementId, bindableElement);\n};\n\nconst isLinearElementSimpleAndAlreadyBound = (linearElement, alreadyBoundToId, bindableElement) => {\n return alreadyBoundToId === bindableElement.id && linearElement.points.length < 3;\n};\nconst unbindLinearElements = elements => {\n elements.forEach(element => {\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isBindingElement)(element)) {\n bindOrUnbindLinearElement(element, null, null);\n }\n });\n};\n\nconst unbindLinearElement = (linearElement, startOrEnd) => {\n const field = startOrEnd === \"start\" ? \"startBinding\" : \"endBinding\";\n const binding = linearElement[field];\n\n if (binding == null) {\n return null;\n }\n\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(linearElement, {\n [field]: null\n });\n return binding.elementId;\n};\n\nconst getHoveredElementForBinding = (pointerCoords, scene) => {\n const hoveredElement = (0,_scene__WEBPACK_IMPORTED_MODULE_0__.getElementAtPosition)(scene.getNonDeletedElements(), element => (0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isBindableElement)(element, false) && (0,_collision__WEBPACK_IMPORTED_MODULE_2__.bindingBorderTest)(element, pointerCoords));\n return hoveredElement;\n};\n\nconst calculateFocusAndGap = (linearElement, hoveredElement, startOrEnd) => {\n const direction = startOrEnd === \"start\" ? -1 : 1;\n const edgePointIndex = direction === -1 ? 0 : linearElement.points.length - 1;\n const adjacentPointIndex = edgePointIndex - direction;\n const edgePoint = _linearElementEditor__WEBPACK_IMPORTED_MODULE_5__.LinearElementEditor.getPointAtIndexGlobalCoordinates(linearElement, edgePointIndex);\n const adjacentPoint = _linearElementEditor__WEBPACK_IMPORTED_MODULE_5__.LinearElementEditor.getPointAtIndexGlobalCoordinates(linearElement, adjacentPointIndex);\n return {\n focus: (0,_collision__WEBPACK_IMPORTED_MODULE_2__.determineFocusDistance)(hoveredElement, adjacentPoint, edgePoint),\n gap: Math.max(1, (0,_collision__WEBPACK_IMPORTED_MODULE_2__.distanceToBindableElement)(hoveredElement, edgePoint))\n };\n}; // Supports translating, rotating and scaling `changedElement` with bound\n// linear elements.\n// Because scaling involves moving the focus points as well, it is\n// done before the `changedElement` is updated, and the `newSize` is passed\n// in explicitly.\n\n\nconst updateBoundElements = (changedElement, options) => {\n var _a;\n\n const boundLinearElements = ((_a = changedElement.boundElements) !== null && _a !== void 0 ? _a : []).filter(el => el.type === \"arrow\");\n\n if (boundLinearElements.length === 0) {\n return;\n }\n\n const {\n newSize,\n simultaneouslyUpdated\n } = options !== null && options !== void 0 ? options : {};\n const simultaneouslyUpdatedElementIds = getSimultaneouslyUpdatedElementIds(simultaneouslyUpdated);\n getNonDeletedElements(_scene_Scene__WEBPACK_IMPORTED_MODULE_4__[\"default\"].getScene(changedElement), boundLinearElements.map(el => el.id)).forEach(element => {\n if (!(0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isLinearElement)(element)) {\n return;\n }\n\n const bindableElement = changedElement; // In case the boundElements are stale\n\n if (!doesNeedUpdate(element, bindableElement)) {\n return;\n }\n\n const startBinding = maybeCalculateNewGapWhenScaling(bindableElement, element.startBinding, newSize);\n const endBinding = maybeCalculateNewGapWhenScaling(bindableElement, element.endBinding, newSize); // `linearElement` is being moved/scaled already, just update the binding\n\n if (simultaneouslyUpdatedElementIds.has(element.id)) {\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(element, {\n startBinding,\n endBinding\n });\n return;\n }\n\n updateBoundPoint(element, \"start\", startBinding, changedElement);\n updateBoundPoint(element, \"end\", endBinding, changedElement);\n const boundText = (0,_textElement__WEBPACK_IMPORTED_MODULE_8__.getBoundTextElement)(element);\n\n if (boundText) {\n (0,_textElement__WEBPACK_IMPORTED_MODULE_8__.handleBindTextResize)(element, false);\n }\n });\n};\n\nconst doesNeedUpdate = (boundElement, changedElement) => {\n var _a, _b;\n\n return ((_a = boundElement.startBinding) === null || _a === void 0 ? void 0 : _a.elementId) === changedElement.id || ((_b = boundElement.endBinding) === null || _b === void 0 ? void 0 : _b.elementId) === changedElement.id;\n};\n\nconst getSimultaneouslyUpdatedElementIds = simultaneouslyUpdated => {\n return new Set((simultaneouslyUpdated || []).map(element => element.id));\n};\n\nconst updateBoundPoint = (linearElement, startOrEnd, binding, changedElement) => {\n if (binding == null || // We only need to update the other end if this is a 2 point line element\n binding.elementId !== changedElement.id && linearElement.points.length > 2) {\n return;\n }\n\n const bindingElement = _scene_Scene__WEBPACK_IMPORTED_MODULE_4__[\"default\"].getScene(linearElement).getElement(binding.elementId);\n\n if (bindingElement == null) {\n // We're not cleaning up after deleted elements atm., so handle this case\n return;\n }\n\n const direction = startOrEnd === \"start\" ? -1 : 1;\n const edgePointIndex = direction === -1 ? 0 : linearElement.points.length - 1;\n const adjacentPointIndex = edgePointIndex - direction;\n const adjacentPoint = _linearElementEditor__WEBPACK_IMPORTED_MODULE_5__.LinearElementEditor.getPointAtIndexGlobalCoordinates(linearElement, adjacentPointIndex);\n const focusPointAbsolute = (0,_collision__WEBPACK_IMPORTED_MODULE_2__.determineFocusPoint)(bindingElement, binding.focus, adjacentPoint);\n let newEdgePoint; // The linear element was not originally pointing inside the bound shape,\n // we can point directly at the focus point\n\n if (binding.gap === 0) {\n newEdgePoint = focusPointAbsolute;\n } else {\n const intersections = (0,_collision__WEBPACK_IMPORTED_MODULE_2__.intersectElementWithLine)(bindingElement, adjacentPoint, focusPointAbsolute, binding.gap);\n\n if (intersections.length === 0) {\n // This should never happen, since focusPoint should always be\n // inside the element, but just in case, bail out\n newEdgePoint = focusPointAbsolute;\n } else {\n // Guaranteed to intersect because focusPoint is always inside the shape\n newEdgePoint = intersections[0];\n }\n }\n\n _linearElementEditor__WEBPACK_IMPORTED_MODULE_5__.LinearElementEditor.movePoints(linearElement, [{\n index: edgePointIndex,\n point: _linearElementEditor__WEBPACK_IMPORTED_MODULE_5__.LinearElementEditor.pointFromAbsoluteCoords(linearElement, newEdgePoint)\n }], {\n [startOrEnd === \"start\" ? \"startBinding\" : \"endBinding\"]: binding\n });\n};\n\nconst maybeCalculateNewGapWhenScaling = (changedElement, currentBinding, newSize) => {\n if (currentBinding == null || newSize == null) {\n return currentBinding;\n }\n\n const {\n gap,\n focus,\n elementId\n } = currentBinding;\n const {\n width: newWidth,\n height: newHeight\n } = newSize;\n const {\n width,\n height\n } = changedElement;\n const newGap = Math.max(1, Math.min((0,_collision__WEBPACK_IMPORTED_MODULE_2__.maxBindingGap)(changedElement, newWidth, newHeight), gap * (newWidth < newHeight ? newWidth / width : newHeight / height)));\n return {\n elementId,\n gap: newGap,\n focus\n };\n}; // TODO: this is a bottleneck, optimise\n\n\nconst getEligibleElementsForBinding = elements => {\n const includedElementIds = new Set(elements.map(({\n id\n }) => id));\n return elements.flatMap(element => (0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isBindingElement)(element, false) ? getElligibleElementsForBindingElement(element).filter(element => !includedElementIds.has(element.id)) : (0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isBindableElement)(element, false) ? getElligibleElementsForBindableElementAndWhere(element).filter(binding => !includedElementIds.has(binding[0].id)) : []);\n};\n\nconst getElligibleElementsForBindingElement = linearElement => {\n return [getElligibleElementForBindingElement(linearElement, \"start\"), getElligibleElementForBindingElement(linearElement, \"end\")].filter(element => element != null);\n};\n\nconst getElligibleElementForBindingElement = (linearElement, startOrEnd) => {\n return getHoveredElementForBinding(getLinearElementEdgeCoors(linearElement, startOrEnd), _scene_Scene__WEBPACK_IMPORTED_MODULE_4__[\"default\"].getScene(linearElement));\n};\n\nconst getLinearElementEdgeCoors = (linearElement, startOrEnd) => {\n const index = startOrEnd === \"start\" ? 0 : -1;\n return (0,_utils__WEBPACK_IMPORTED_MODULE_6__.tupleToCoors)(_linearElementEditor__WEBPACK_IMPORTED_MODULE_5__.LinearElementEditor.getPointAtIndexGlobalCoordinates(linearElement, index));\n};\n\nconst getElligibleElementsForBindableElementAndWhere = bindableElement => {\n return _scene_Scene__WEBPACK_IMPORTED_MODULE_4__[\"default\"].getScene(bindableElement).getNonDeletedElements().map(element => {\n if (!(0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isBindingElement)(element, false)) {\n return null;\n }\n\n const canBindStart = isLinearElementEligibleForNewBindingByBindable(element, \"start\", bindableElement);\n const canBindEnd = isLinearElementEligibleForNewBindingByBindable(element, \"end\", bindableElement);\n\n if (!canBindStart && !canBindEnd) {\n return null;\n }\n\n return [element, canBindStart && canBindEnd ? \"both\" : canBindStart ? \"start\" : \"end\", bindableElement];\n }).filter(maybeElement => maybeElement != null);\n};\n\nconst isLinearElementEligibleForNewBindingByBindable = (linearElement, startOrEnd, bindableElement) => {\n const existingBinding = linearElement[startOrEnd === \"start\" ? \"startBinding\" : \"endBinding\"];\n return existingBinding == null && !isLinearElementSimpleAndAlreadyBoundOnOppositeEdge(linearElement, bindableElement, startOrEnd) && (0,_collision__WEBPACK_IMPORTED_MODULE_2__.bindingBorderTest)(bindableElement, getLinearElementEdgeCoors(linearElement, startOrEnd));\n}; // We need to:\n// 1: Update elements not selected to point to duplicated elements\n// 2: Update duplicated elements to point to other duplicated elements\n\n\nconst fixBindingsAfterDuplication = (sceneElements, oldElements, oldIdToDuplicatedId, // There are three copying mechanisms: Copy-paste, duplication and alt-drag.\n// Only when alt-dragging the new \"duplicates\" act as the \"old\", while\n// the \"old\" elements act as the \"new copy\" - essentially working reverse\n// to the other two.\nduplicatesServeAsOld) => {\n // First collect all the binding/bindable elements, so we only update\n // each once, regardless of whether they were duplicated or not.\n const allBoundElementIds = new Set();\n const allBindableElementIds = new Set();\n const shouldReverseRoles = duplicatesServeAsOld === \"duplicatesServeAsOld\";\n oldElements.forEach(oldElement => {\n const {\n boundElements\n } = oldElement;\n\n if (boundElements != null && boundElements.length > 0) {\n boundElements.forEach(boundElement => {\n if (shouldReverseRoles && !oldIdToDuplicatedId.has(boundElement.id)) {\n allBoundElementIds.add(boundElement.id);\n }\n });\n allBindableElementIds.add(oldIdToDuplicatedId.get(oldElement.id));\n }\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isBindingElement)(oldElement)) {\n if (oldElement.startBinding != null) {\n const {\n elementId\n } = oldElement.startBinding;\n\n if (shouldReverseRoles && !oldIdToDuplicatedId.has(elementId)) {\n allBindableElementIds.add(elementId);\n }\n }\n\n if (oldElement.endBinding != null) {\n const {\n elementId\n } = oldElement.endBinding;\n\n if (shouldReverseRoles && !oldIdToDuplicatedId.has(elementId)) {\n allBindableElementIds.add(elementId);\n }\n }\n\n if (oldElement.startBinding != null || oldElement.endBinding != null) {\n allBoundElementIds.add(oldIdToDuplicatedId.get(oldElement.id));\n }\n }\n }); // Update the linear elements\n\n sceneElements.filter(({\n id\n }) => allBoundElementIds.has(id)).forEach(element => {\n const {\n startBinding,\n endBinding\n } = element;\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(element, {\n startBinding: newBindingAfterDuplication(startBinding, oldIdToDuplicatedId),\n endBinding: newBindingAfterDuplication(endBinding, oldIdToDuplicatedId)\n });\n }); // Update the bindable shapes\n\n sceneElements.filter(({\n id\n }) => allBindableElementIds.has(id)).forEach(bindableElement => {\n const {\n boundElements\n } = bindableElement;\n\n if (boundElements != null && boundElements.length > 0) {\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(bindableElement, {\n boundElements: boundElements.map(boundElement => oldIdToDuplicatedId.has(boundElement.id) ? {\n id: oldIdToDuplicatedId.get(boundElement.id),\n type: boundElement.type\n } : boundElement)\n });\n }\n });\n};\n\nconst newBindingAfterDuplication = (binding, oldIdToDuplicatedId) => {\n var _a;\n\n if (binding == null) {\n return null;\n }\n\n const {\n elementId,\n focus,\n gap\n } = binding;\n return {\n focus,\n gap,\n elementId: (_a = oldIdToDuplicatedId.get(elementId)) !== null && _a !== void 0 ? _a : elementId\n };\n};\n\nconst fixBindingsAfterDeletion = (sceneElements, deletedElements) => {\n const deletedElementIds = new Set(deletedElements.map(element => element.id)); // non-deleted which bindings need to be updated\n\n const affectedElements = new Set();\n deletedElements.forEach(deletedElement => {\n var _a;\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isBindableElement)(deletedElement)) {\n (_a = deletedElement.boundElements) === null || _a === void 0 ? void 0 : _a.forEach(element => {\n if (!deletedElementIds.has(element.id)) {\n affectedElements.add(element.id);\n }\n });\n } else if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isBindingElement)(deletedElement)) {\n if (deletedElement.startBinding) {\n affectedElements.add(deletedElement.startBinding.elementId);\n }\n\n if (deletedElement.endBinding) {\n affectedElements.add(deletedElement.endBinding.elementId);\n }\n }\n });\n sceneElements.filter(({\n id\n }) => affectedElements.has(id)).forEach(element => {\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isBindableElement)(element)) {\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(element, {\n boundElements: newBoundElementsAfterDeletion(element.boundElements, deletedElementIds)\n });\n } else if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isBindingElement)(element)) {\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(element, {\n startBinding: newBindingAfterDeletion(element.startBinding, deletedElementIds),\n endBinding: newBindingAfterDeletion(element.endBinding, deletedElementIds)\n });\n }\n });\n};\n\nconst newBindingAfterDeletion = (binding, deletedElementIds) => {\n if (binding == null || deletedElementIds.has(binding.elementId)) {\n return null;\n }\n\n return binding;\n};\n\nconst newBoundElementsAfterDeletion = (boundElements, deletedElementIds) => {\n if (!boundElements) {\n return null;\n }\n\n return boundElements.filter(ele => !deletedElementIds.has(ele.id));\n};\n\n//# sourceURL=webpack://ExcalidrawLib/../../element/binding.ts?");
3659
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"bindLinearElement\": () => (/* binding */ bindLinearElement),\n/* harmony export */ \"bindOrUnbindLinearElement\": () => (/* binding */ bindOrUnbindLinearElement),\n/* harmony export */ \"bindOrUnbindSelectedElements\": () => (/* binding */ bindOrUnbindSelectedElements),\n/* harmony export */ \"fixBindingsAfterDeletion\": () => (/* binding */ fixBindingsAfterDeletion),\n/* harmony export */ \"fixBindingsAfterDuplication\": () => (/* binding */ fixBindingsAfterDuplication),\n/* harmony export */ \"getEligibleElementsForBinding\": () => (/* binding */ getEligibleElementsForBinding),\n/* harmony export */ \"getHoveredElementForBinding\": () => (/* binding */ getHoveredElementForBinding),\n/* harmony export */ \"isBindingEnabled\": () => (/* binding */ isBindingEnabled),\n/* harmony export */ \"isLinearElementSimpleAndAlreadyBound\": () => (/* binding */ isLinearElementSimpleAndAlreadyBound),\n/* harmony export */ \"maybeBindLinearElement\": () => (/* binding */ maybeBindLinearElement),\n/* harmony export */ \"shouldEnableBindingForPointerEvent\": () => (/* binding */ shouldEnableBindingForPointerEvent),\n/* harmony export */ \"unbindLinearElements\": () => (/* binding */ unbindLinearElements),\n/* harmony export */ \"updateBoundElements\": () => (/* binding */ updateBoundElements)\n/* harmony export */ });\n/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../scene */ \"../../scene/index.ts\");\n/* harmony import */ var _typeChecks__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var _collision__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./collision */ \"../../element/collision.ts\");\n/* harmony import */ var _mutateElement__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./mutateElement */ \"../../element/mutateElement.ts\");\n/* harmony import */ var _scene_Scene__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../scene/Scene */ \"../../scene/Scene.ts\");\n/* harmony import */ var _linearElementEditor__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./linearElementEditor */ \"../../element/linearElementEditor.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _keys__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../keys */ \"../../keys.ts\");\n/* harmony import */ var _textElement__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./textElement */ \"../../element/textElement.ts\");\n\n\n\n\n\n\n\n\n\nconst shouldEnableBindingForPointerEvent = event => {\n return !event[_keys__WEBPACK_IMPORTED_MODULE_7__.KEYS.CTRL_OR_CMD];\n};\nconst isBindingEnabled = appState => {\n return appState.invertBindingBehaviour //zsviczian\n ? !appState.isBindingEnabled : appState.isBindingEnabled;\n};\n\nconst getNonDeletedElements = (scene, ids) => {\n const result = [];\n ids.forEach(id => {\n const element = scene.getNonDeletedElement(id);\n\n if (element != null) {\n result.push(element);\n }\n });\n return result;\n};\n\nconst bindOrUnbindLinearElement = (linearElement, startBindingElement, endBindingElement) => {\n const boundToElementIds = new Set();\n const unboundFromElementIds = new Set();\n bindOrUnbindLinearElementEdge(linearElement, startBindingElement, endBindingElement, \"start\", boundToElementIds, unboundFromElementIds);\n bindOrUnbindLinearElementEdge(linearElement, endBindingElement, startBindingElement, \"end\", boundToElementIds, unboundFromElementIds);\n const onlyUnbound = Array.from(unboundFromElementIds).filter(id => !boundToElementIds.has(id));\n getNonDeletedElements(_scene_Scene__WEBPACK_IMPORTED_MODULE_4__[\"default\"].getScene(linearElement), onlyUnbound).forEach(element => {\n var _a;\n\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(element, {\n boundElements: (_a = element.boundElements) === null || _a === void 0 ? void 0 : _a.filter(element => element.type !== \"arrow\" || element.id !== linearElement.id)\n });\n });\n};\n\nconst bindOrUnbindLinearElementEdge = (linearElement, bindableElement, otherEdgeBindableElement, startOrEnd, // Is mutated\nboundToElementIds, // Is mutated\nunboundFromElementIds) => {\n if (bindableElement !== \"keep\") {\n if (bindableElement != null) {\n // Don't bind if we're trying to bind or are already bound to the same\n // element on the other edge already (\"start\" edge takes precedence).\n if (otherEdgeBindableElement == null || (otherEdgeBindableElement === \"keep\" ? !isLinearElementSimpleAndAlreadyBoundOnOppositeEdge(linearElement, bindableElement, startOrEnd) : startOrEnd === \"start\" || otherEdgeBindableElement.id !== bindableElement.id)) {\n bindLinearElement(linearElement, bindableElement, startOrEnd);\n boundToElementIds.add(bindableElement.id);\n }\n } else {\n const unbound = unbindLinearElement(linearElement, startOrEnd);\n\n if (unbound != null) {\n unboundFromElementIds.add(unbound);\n }\n }\n }\n};\n\nconst bindOrUnbindSelectedElements = elements => {\n elements.forEach(element => {\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isBindingElement)(element)) {\n bindOrUnbindLinearElement(element, getElligibleElementForBindingElement(element, \"start\"), getElligibleElementForBindingElement(element, \"end\"));\n } else if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isBindableElement)(element)) {\n maybeBindBindableElement(element);\n }\n });\n};\n\nconst maybeBindBindableElement = bindableElement => {\n getElligibleElementsForBindableElementAndWhere(bindableElement).forEach(([linearElement, where]) => bindOrUnbindLinearElement(linearElement, where === \"end\" ? \"keep\" : bindableElement, where === \"start\" ? \"keep\" : bindableElement));\n};\n\nconst maybeBindLinearElement = (linearElement, appState, scene, pointerCoords) => {\n if (appState.startBoundElement != null) {\n bindLinearElement(linearElement, appState.startBoundElement, \"start\");\n }\n\n const hoveredElement = getHoveredElementForBinding(pointerCoords, scene);\n\n if (hoveredElement != null && !isLinearElementSimpleAndAlreadyBoundOnOppositeEdge(linearElement, hoveredElement, \"end\")) {\n bindLinearElement(linearElement, hoveredElement, \"end\");\n }\n};\nconst bindLinearElement = (linearElement, hoveredElement, startOrEnd) => {\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(linearElement, {\n [startOrEnd === \"start\" ? \"startBinding\" : \"endBinding\"]: Object.assign({\n elementId: hoveredElement.id\n }, calculateFocusAndGap(linearElement, hoveredElement, startOrEnd))\n });\n const boundElementsMap = (0,_utils__WEBPACK_IMPORTED_MODULE_6__.arrayToMap)(hoveredElement.boundElements || []);\n\n if (!boundElementsMap.has(linearElement.id)) {\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(hoveredElement, {\n boundElements: (hoveredElement.boundElements || []).concat({\n id: linearElement.id,\n type: \"arrow\"\n })\n });\n }\n}; // Don't bind both ends of a simple segment\n\nconst isLinearElementSimpleAndAlreadyBoundOnOppositeEdge = (linearElement, bindableElement, startOrEnd) => {\n const otherBinding = linearElement[startOrEnd === \"start\" ? \"endBinding\" : \"startBinding\"];\n return isLinearElementSimpleAndAlreadyBound(linearElement, otherBinding === null || otherBinding === void 0 ? void 0 : otherBinding.elementId, bindableElement);\n};\n\nconst isLinearElementSimpleAndAlreadyBound = (linearElement, alreadyBoundToId, bindableElement) => {\n return alreadyBoundToId === bindableElement.id && linearElement.points.length < 3;\n};\nconst unbindLinearElements = elements => {\n elements.forEach(element => {\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isBindingElement)(element)) {\n bindOrUnbindLinearElement(element, null, null);\n }\n });\n};\n\nconst unbindLinearElement = (linearElement, startOrEnd) => {\n const field = startOrEnd === \"start\" ? \"startBinding\" : \"endBinding\";\n const binding = linearElement[field];\n\n if (binding == null) {\n return null;\n }\n\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(linearElement, {\n [field]: null\n });\n return binding.elementId;\n};\n\nconst getHoveredElementForBinding = (pointerCoords, scene) => {\n const hoveredElement = (0,_scene__WEBPACK_IMPORTED_MODULE_0__.getElementAtPosition)(scene.getNonDeletedElements(), element => (0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isBindableElement)(element, false) && (0,_collision__WEBPACK_IMPORTED_MODULE_2__.bindingBorderTest)(element, pointerCoords));\n return hoveredElement;\n};\n\nconst calculateFocusAndGap = (linearElement, hoveredElement, startOrEnd) => {\n const direction = startOrEnd === \"start\" ? -1 : 1;\n const edgePointIndex = direction === -1 ? 0 : linearElement.points.length - 1;\n const adjacentPointIndex = edgePointIndex - direction;\n const edgePoint = _linearElementEditor__WEBPACK_IMPORTED_MODULE_5__.LinearElementEditor.getPointAtIndexGlobalCoordinates(linearElement, edgePointIndex);\n const adjacentPoint = _linearElementEditor__WEBPACK_IMPORTED_MODULE_5__.LinearElementEditor.getPointAtIndexGlobalCoordinates(linearElement, adjacentPointIndex);\n return {\n focus: (0,_collision__WEBPACK_IMPORTED_MODULE_2__.determineFocusDistance)(hoveredElement, adjacentPoint, edgePoint),\n gap: Math.max(1, (0,_collision__WEBPACK_IMPORTED_MODULE_2__.distanceToBindableElement)(hoveredElement, edgePoint))\n };\n}; // Supports translating, rotating and scaling `changedElement` with bound\n// linear elements.\n// Because scaling involves moving the focus points as well, it is\n// done before the `changedElement` is updated, and the `newSize` is passed\n// in explicitly.\n\n\nconst updateBoundElements = (changedElement, options) => {\n var _a;\n\n const boundLinearElements = ((_a = changedElement.boundElements) !== null && _a !== void 0 ? _a : []).filter(el => el.type === \"arrow\");\n\n if (boundLinearElements.length === 0) {\n return;\n }\n\n const {\n newSize,\n simultaneouslyUpdated\n } = options !== null && options !== void 0 ? options : {};\n const simultaneouslyUpdatedElementIds = getSimultaneouslyUpdatedElementIds(simultaneouslyUpdated);\n getNonDeletedElements(_scene_Scene__WEBPACK_IMPORTED_MODULE_4__[\"default\"].getScene(changedElement), boundLinearElements.map(el => el.id)).forEach(element => {\n if (!(0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isLinearElement)(element)) {\n return;\n }\n\n const bindableElement = changedElement; // In case the boundElements are stale\n\n if (!doesNeedUpdate(element, bindableElement)) {\n return;\n }\n\n const startBinding = maybeCalculateNewGapWhenScaling(bindableElement, element.startBinding, newSize);\n const endBinding = maybeCalculateNewGapWhenScaling(bindableElement, element.endBinding, newSize); // `linearElement` is being moved/scaled already, just update the binding\n\n if (simultaneouslyUpdatedElementIds.has(element.id)) {\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(element, {\n startBinding,\n endBinding\n });\n return;\n }\n\n updateBoundPoint(element, \"start\", startBinding, changedElement);\n updateBoundPoint(element, \"end\", endBinding, changedElement);\n const boundText = (0,_textElement__WEBPACK_IMPORTED_MODULE_8__.getBoundTextElement)(element);\n\n if (boundText) {\n (0,_textElement__WEBPACK_IMPORTED_MODULE_8__.handleBindTextResize)(element, false);\n }\n });\n};\n\nconst doesNeedUpdate = (boundElement, changedElement) => {\n var _a, _b;\n\n return ((_a = boundElement.startBinding) === null || _a === void 0 ? void 0 : _a.elementId) === changedElement.id || ((_b = boundElement.endBinding) === null || _b === void 0 ? void 0 : _b.elementId) === changedElement.id;\n};\n\nconst getSimultaneouslyUpdatedElementIds = simultaneouslyUpdated => {\n return new Set((simultaneouslyUpdated || []).map(element => element.id));\n};\n\nconst updateBoundPoint = (linearElement, startOrEnd, binding, changedElement) => {\n if (binding == null || // We only need to update the other end if this is a 2 point line element\n binding.elementId !== changedElement.id && linearElement.points.length > 2) {\n return;\n }\n\n const bindingElement = _scene_Scene__WEBPACK_IMPORTED_MODULE_4__[\"default\"].getScene(linearElement).getElement(binding.elementId);\n\n if (bindingElement == null) {\n // We're not cleaning up after deleted elements atm., so handle this case\n return;\n }\n\n const direction = startOrEnd === \"start\" ? -1 : 1;\n const edgePointIndex = direction === -1 ? 0 : linearElement.points.length - 1;\n const adjacentPointIndex = edgePointIndex - direction;\n const adjacentPoint = _linearElementEditor__WEBPACK_IMPORTED_MODULE_5__.LinearElementEditor.getPointAtIndexGlobalCoordinates(linearElement, adjacentPointIndex);\n const focusPointAbsolute = (0,_collision__WEBPACK_IMPORTED_MODULE_2__.determineFocusPoint)(bindingElement, binding.focus, adjacentPoint);\n let newEdgePoint; // The linear element was not originally pointing inside the bound shape,\n // we can point directly at the focus point\n\n if (binding.gap === 0) {\n newEdgePoint = focusPointAbsolute;\n } else {\n const intersections = (0,_collision__WEBPACK_IMPORTED_MODULE_2__.intersectElementWithLine)(bindingElement, adjacentPoint, focusPointAbsolute, binding.gap);\n\n if (intersections.length === 0) {\n // This should never happen, since focusPoint should always be\n // inside the element, but just in case, bail out\n newEdgePoint = focusPointAbsolute;\n } else {\n // Guaranteed to intersect because focusPoint is always inside the shape\n newEdgePoint = intersections[0];\n }\n }\n\n _linearElementEditor__WEBPACK_IMPORTED_MODULE_5__.LinearElementEditor.movePoints(linearElement, [{\n index: edgePointIndex,\n point: _linearElementEditor__WEBPACK_IMPORTED_MODULE_5__.LinearElementEditor.pointFromAbsoluteCoords(linearElement, newEdgePoint)\n }], {\n [startOrEnd === \"start\" ? \"startBinding\" : \"endBinding\"]: binding\n });\n};\n\nconst maybeCalculateNewGapWhenScaling = (changedElement, currentBinding, newSize) => {\n if (currentBinding == null || newSize == null) {\n return currentBinding;\n }\n\n const {\n gap,\n focus,\n elementId\n } = currentBinding;\n const {\n width: newWidth,\n height: newHeight\n } = newSize;\n const {\n width,\n height\n } = changedElement;\n const newGap = Math.max(1, Math.min((0,_collision__WEBPACK_IMPORTED_MODULE_2__.maxBindingGap)(changedElement, newWidth, newHeight), gap * (newWidth < newHeight ? newWidth / width : newHeight / height)));\n return {\n elementId,\n gap: newGap,\n focus\n };\n}; // TODO: this is a bottleneck, optimise\n\n\nconst getEligibleElementsForBinding = elements => {\n const includedElementIds = new Set(elements.map(({\n id\n }) => id));\n return elements.flatMap(element => (0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isBindingElement)(element, false) ? getElligibleElementsForBindingElement(element).filter(element => !includedElementIds.has(element.id)) : (0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isBindableElement)(element, false) ? getElligibleElementsForBindableElementAndWhere(element).filter(binding => !includedElementIds.has(binding[0].id)) : []);\n};\n\nconst getElligibleElementsForBindingElement = linearElement => {\n return [getElligibleElementForBindingElement(linearElement, \"start\"), getElligibleElementForBindingElement(linearElement, \"end\")].filter(element => element != null);\n};\n\nconst getElligibleElementForBindingElement = (linearElement, startOrEnd) => {\n return getHoveredElementForBinding(getLinearElementEdgeCoors(linearElement, startOrEnd), _scene_Scene__WEBPACK_IMPORTED_MODULE_4__[\"default\"].getScene(linearElement));\n};\n\nconst getLinearElementEdgeCoors = (linearElement, startOrEnd) => {\n const index = startOrEnd === \"start\" ? 0 : -1;\n return (0,_utils__WEBPACK_IMPORTED_MODULE_6__.tupleToCoors)(_linearElementEditor__WEBPACK_IMPORTED_MODULE_5__.LinearElementEditor.getPointAtIndexGlobalCoordinates(linearElement, index));\n};\n\nconst getElligibleElementsForBindableElementAndWhere = bindableElement => {\n return _scene_Scene__WEBPACK_IMPORTED_MODULE_4__[\"default\"].getScene(bindableElement).getNonDeletedElements().map(element => {\n if (!(0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isBindingElement)(element, false)) {\n return null;\n }\n\n const canBindStart = isLinearElementEligibleForNewBindingByBindable(element, \"start\", bindableElement);\n const canBindEnd = isLinearElementEligibleForNewBindingByBindable(element, \"end\", bindableElement);\n\n if (!canBindStart && !canBindEnd) {\n return null;\n }\n\n return [element, canBindStart && canBindEnd ? \"both\" : canBindStart ? \"start\" : \"end\", bindableElement];\n }).filter(maybeElement => maybeElement != null);\n};\n\nconst isLinearElementEligibleForNewBindingByBindable = (linearElement, startOrEnd, bindableElement) => {\n const existingBinding = linearElement[startOrEnd === \"start\" ? \"startBinding\" : \"endBinding\"];\n return existingBinding == null && !isLinearElementSimpleAndAlreadyBoundOnOppositeEdge(linearElement, bindableElement, startOrEnd) && (0,_collision__WEBPACK_IMPORTED_MODULE_2__.bindingBorderTest)(bindableElement, getLinearElementEdgeCoors(linearElement, startOrEnd));\n}; // We need to:\n// 1: Update elements not selected to point to duplicated elements\n// 2: Update duplicated elements to point to other duplicated elements\n\n\nconst fixBindingsAfterDuplication = (sceneElements, oldElements, oldIdToDuplicatedId, // There are three copying mechanisms: Copy-paste, duplication and alt-drag.\n// Only when alt-dragging the new \"duplicates\" act as the \"old\", while\n// the \"old\" elements act as the \"new copy\" - essentially working reverse\n// to the other two.\nduplicatesServeAsOld) => {\n // First collect all the binding/bindable elements, so we only update\n // each once, regardless of whether they were duplicated or not.\n const allBoundElementIds = new Set();\n const allBindableElementIds = new Set();\n const shouldReverseRoles = duplicatesServeAsOld === \"duplicatesServeAsOld\";\n oldElements.forEach(oldElement => {\n const {\n boundElements\n } = oldElement;\n\n if (boundElements != null && boundElements.length > 0) {\n boundElements.forEach(boundElement => {\n if (shouldReverseRoles && !oldIdToDuplicatedId.has(boundElement.id)) {\n allBoundElementIds.add(boundElement.id);\n }\n });\n allBindableElementIds.add(oldIdToDuplicatedId.get(oldElement.id));\n }\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isBindingElement)(oldElement)) {\n if (oldElement.startBinding != null) {\n const {\n elementId\n } = oldElement.startBinding;\n\n if (shouldReverseRoles && !oldIdToDuplicatedId.has(elementId)) {\n allBindableElementIds.add(elementId);\n }\n }\n\n if (oldElement.endBinding != null) {\n const {\n elementId\n } = oldElement.endBinding;\n\n if (shouldReverseRoles && !oldIdToDuplicatedId.has(elementId)) {\n allBindableElementIds.add(elementId);\n }\n }\n\n if (oldElement.startBinding != null || oldElement.endBinding != null) {\n allBoundElementIds.add(oldIdToDuplicatedId.get(oldElement.id));\n }\n }\n }); // Update the linear elements\n\n sceneElements.filter(({\n id\n }) => allBoundElementIds.has(id)).forEach(element => {\n const {\n startBinding,\n endBinding\n } = element;\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(element, {\n startBinding: newBindingAfterDuplication(startBinding, oldIdToDuplicatedId),\n endBinding: newBindingAfterDuplication(endBinding, oldIdToDuplicatedId)\n });\n }); // Update the bindable shapes\n\n sceneElements.filter(({\n id\n }) => allBindableElementIds.has(id)).forEach(bindableElement => {\n const {\n boundElements\n } = bindableElement;\n\n if (boundElements != null && boundElements.length > 0) {\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(bindableElement, {\n boundElements: boundElements.map(boundElement => oldIdToDuplicatedId.has(boundElement.id) ? {\n id: oldIdToDuplicatedId.get(boundElement.id),\n type: boundElement.type\n } : boundElement)\n });\n }\n });\n};\n\nconst newBindingAfterDuplication = (binding, oldIdToDuplicatedId) => {\n var _a;\n\n if (binding == null) {\n return null;\n }\n\n const {\n elementId,\n focus,\n gap\n } = binding;\n return {\n focus,\n gap,\n elementId: (_a = oldIdToDuplicatedId.get(elementId)) !== null && _a !== void 0 ? _a : elementId\n };\n};\n\nconst fixBindingsAfterDeletion = (sceneElements, deletedElements) => {\n const deletedElementIds = new Set(deletedElements.map(element => element.id)); // non-deleted which bindings need to be updated\n\n const affectedElements = new Set();\n deletedElements.forEach(deletedElement => {\n var _a;\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isBindableElement)(deletedElement)) {\n (_a = deletedElement.boundElements) === null || _a === void 0 ? void 0 : _a.forEach(element => {\n if (!deletedElementIds.has(element.id)) {\n affectedElements.add(element.id);\n }\n });\n } else if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isBindingElement)(deletedElement)) {\n if (deletedElement.startBinding) {\n affectedElements.add(deletedElement.startBinding.elementId);\n }\n\n if (deletedElement.endBinding) {\n affectedElements.add(deletedElement.endBinding.elementId);\n }\n }\n });\n sceneElements.filter(({\n id\n }) => affectedElements.has(id)).forEach(element => {\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isBindableElement)(element)) {\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(element, {\n boundElements: newBoundElementsAfterDeletion(element.boundElements, deletedElementIds)\n });\n } else if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isBindingElement)(element)) {\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(element, {\n startBinding: newBindingAfterDeletion(element.startBinding, deletedElementIds),\n endBinding: newBindingAfterDeletion(element.endBinding, deletedElementIds)\n });\n }\n });\n};\n\nconst newBindingAfterDeletion = (binding, deletedElementIds) => {\n if (binding == null || deletedElementIds.has(binding.elementId)) {\n return null;\n }\n\n return binding;\n};\n\nconst newBoundElementsAfterDeletion = (boundElements, deletedElementIds) => {\n if (!boundElements) {\n return null;\n }\n\n return boundElements.filter(ele => !deletedElementIds.has(ele.id));\n};\n\n//# sourceURL=webpack://ExcalidrawLib/../../element/binding.ts?");
3660
3660
 
3661
3661
  /***/ }),
3662
3662
 
@@ -3678,7 +3678,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
3678
3678
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3679
3679
 
3680
3680
  "use strict";
3681
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"bindingBorderTest\": () => (/* binding */ bindingBorderTest),\n/* harmony export */ \"determineFocusDistance\": () => (/* binding */ determineFocusDistance),\n/* harmony export */ \"determineFocusPoint\": () => (/* binding */ determineFocusPoint),\n/* harmony export */ \"distanceToBindableElement\": () => (/* binding */ distanceToBindableElement),\n/* harmony export */ \"findFocusPointForEllipse\": () => (/* binding */ findFocusPointForEllipse),\n/* harmony export */ \"findFocusPointForRectangulars\": () => (/* binding */ findFocusPointForRectangulars),\n/* harmony export */ \"getCircleIntersections\": () => (/* binding */ getCircleIntersections),\n/* harmony export */ \"hitTest\": () => (/* binding */ hitTest),\n/* harmony export */ \"intersectElementWithLine\": () => (/* binding */ intersectElementWithLine),\n/* harmony export */ \"isHittingElementBoundingBoxWithoutHittingElement\": () => (/* binding */ isHittingElementBoundingBoxWithoutHittingElement),\n/* harmony export */ \"isHittingElementNotConsideringBoundingBox\": () => (/* binding */ isHittingElementNotConsideringBoundingBox),\n/* harmony export */ \"isPointHittingElementBoundingBox\": () => (/* binding */ isPointHittingElementBoundingBox),\n/* harmony export */ \"maxBindingGap\": () => (/* binding */ maxBindingGap),\n/* harmony export */ \"pointInAbsoluteCoords\": () => (/* binding */ pointInAbsoluteCoords)\n/* harmony export */ });\n/* harmony import */ var _ga__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../ga */ \"../../ga.ts\");\n/* harmony import */ var _gapoints__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../gapoints */ \"../../gapoints.ts\");\n/* harmony import */ var _gadirections__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../gadirections */ \"../../gadirections.ts\");\n/* harmony import */ var _galines__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../galines */ \"../../galines.ts\");\n/* harmony import */ var _gatransforms__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../gatransforms */ \"../../gatransforms.ts\");\n/* harmony import */ var _math__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../math */ \"../../math.ts\");\n/* harmony import */ var points_on_curve__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! points-on-curve */ \"../../../node_modules/points-on-curve/lib/index.js\");\n/* harmony import */ var _bounds__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./bounds */ \"../../element/bounds.ts\");\n/* harmony import */ var _typeChecks__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var ___WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! . */ \"../../element/index.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _transformHandles__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./transformHandles */ \"../../element/transformHandles.ts\");\n/* harmony import */ var _textElement__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./textElement */ \"../../element/textElement.ts\");\n/* harmony import */ var _scene_ShapeCache__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../scene/ShapeCache */ \"../../scene/ShapeCache.ts\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst isElementDraggableFromInside = element => {\n if (element.type === \"arrow\") {\n return false;\n }\n\n if (element.type === \"freedraw\") {\n return true;\n }\n\n const isDraggableFromInside = !(0,_utils__WEBPACK_IMPORTED_MODULE_10__.isTransparent)(element.backgroundColor) || (0,_typeChecks__WEBPACK_IMPORTED_MODULE_8__.hasBoundTextElement)(element) || (0,_typeChecks__WEBPACK_IMPORTED_MODULE_8__.isEmbeddableElement)(element);\n\n if (element.type === \"line\") {\n return isDraggableFromInside && (0,_math__WEBPACK_IMPORTED_MODULE_5__.isPathALoop)(element.points);\n }\n\n return isDraggableFromInside || (0,_typeChecks__WEBPACK_IMPORTED_MODULE_8__.isImageElement)(element);\n};\n\nconst hitTest = (element, appState, frameNameBoundsCache, x, y) => {\n // How many pixels off the shape boundary we still consider a hit\n const threshold = 10 / appState.zoom.value;\n const point = [x, y];\n\n if (isElementSelected(appState, element) && (0,_transformHandles__WEBPACK_IMPORTED_MODULE_11__.shouldShowBoundingBox)([element], appState)) {\n return isPointHittingElementBoundingBox(element, point, threshold, frameNameBoundsCache);\n }\n\n const boundTextElement = (0,_textElement__WEBPACK_IMPORTED_MODULE_12__.getBoundTextElement)(element);\n\n if (boundTextElement) {\n const isHittingBoundTextElement = hitTest(boundTextElement, appState, frameNameBoundsCache, x, y);\n\n if (isHittingBoundTextElement) {\n return true;\n }\n }\n\n return isHittingElementNotConsideringBoundingBox(element, appState, frameNameBoundsCache, point);\n};\nconst isHittingElementBoundingBoxWithoutHittingElement = (element, appState, frameNameBoundsCache, x, y) => {\n const threshold = 10 / appState.zoom.value; // So that bound text element hit is considered within bounding box of container even if its outside actual bounding box of element\n // eg for linear elements text can be outside the element bounding box\n\n const boundTextElement = (0,_textElement__WEBPACK_IMPORTED_MODULE_12__.getBoundTextElement)(element);\n\n if (boundTextElement && hitTest(boundTextElement, appState, frameNameBoundsCache, x, y)) {\n return false;\n }\n\n return !isHittingElementNotConsideringBoundingBox(element, appState, frameNameBoundsCache, [x, y]) && isPointHittingElementBoundingBox(element, [x, y], threshold, frameNameBoundsCache);\n};\nconst isHittingElementNotConsideringBoundingBox = (element, appState, frameNameBoundsCache, point) => {\n const threshold = 10 / appState.zoom.value;\n const check = (0,___WEBPACK_IMPORTED_MODULE_9__.isTextElement)(element) ? isStrictlyInside : isElementDraggableFromInside(element) ? isInsideCheck : isNearCheck;\n return hitTestPointAgainstElement({\n element,\n point,\n threshold,\n check,\n frameNameBoundsCache\n });\n};\n\nconst isElementSelected = (appState, element) => appState.selectedElementIds[element.id];\n\nconst isPointHittingElementBoundingBox = (element, [x, y], threshold, frameNameBoundsCache) => {\n // frames needs be checked differently so as to be able to drag it\n // by its frame, whether it has been selected or not\n // this logic here is not ideal\n // TODO: refactor it later...\n if (element.type === \"frame\") {\n return hitTestPointAgainstElement({\n element,\n point: [x, y],\n threshold,\n check: isInsideCheck,\n frameNameBoundsCache\n });\n }\n\n const [x1, y1, x2, y2] = (0,_bounds__WEBPACK_IMPORTED_MODULE_7__.getElementAbsoluteCoords)(element);\n const elementCenterX = (x1 + x2) / 2;\n const elementCenterY = (y1 + y2) / 2; // reverse rotate to take element's angle into account.\n\n const [rotatedX, rotatedY] = (0,_math__WEBPACK_IMPORTED_MODULE_5__.rotate)(x, y, elementCenterX, elementCenterY, -element.angle);\n return rotatedX > x1 - threshold && rotatedX < x2 + threshold && rotatedY > y1 - threshold && rotatedY < y2 + threshold;\n};\nconst bindingBorderTest = (element, {\n x,\n y\n}) => {\n const threshold = maxBindingGap(element, element.width, element.height);\n const check = isOutsideCheck;\n const point = [x, y];\n return hitTestPointAgainstElement({\n element,\n point,\n threshold,\n check,\n frameNameBoundsCache: null\n });\n};\nconst maxBindingGap = (element, elementWidth, elementHeight) => {\n // Aligns diamonds with rectangles\n const shapeRatio = element.type === \"diamond\" ? 1 / Math.sqrt(2) : 1;\n const smallerDimension = shapeRatio * Math.min(elementWidth, elementHeight); // We make the bindable boundary bigger for bigger elements\n\n return Math.max(16, Math.min(0.25 * smallerDimension, 32));\n};\n\nconst hitTestPointAgainstElement = args => {\n var _a;\n\n switch (args.element.type) {\n case \"rectangle\":\n case \"embeddable\":\n case \"image\":\n case \"text\":\n case \"diamond\":\n case \"ellipse\":\n const distance = distanceToBindableElement(args.element, args.point);\n return args.check(distance, args.threshold);\n\n case \"freedraw\":\n {\n if (!args.check(distanceToRectangle(args.element, args.point), args.threshold)) {\n return false;\n }\n\n return hitTestFreeDrawElement(args.element, args.point, args.threshold);\n }\n\n case \"arrow\":\n case \"line\":\n return hitTestLinear(args);\n\n case \"selection\":\n console.warn(\"This should not happen, we need to investigate why it does.\");\n return false;\n\n case \"frame\":\n {\n // check distance to frame element first\n if (args.check(distanceToBindableElement(args.element, args.point), args.threshold)) {\n return true;\n }\n\n const frameNameBounds = (_a = args.frameNameBoundsCache) === null || _a === void 0 ? void 0 : _a.get(args.element);\n\n if (frameNameBounds) {\n return args.check(distanceToRectangleBox(frameNameBounds, args.point), args.threshold);\n }\n\n return false;\n }\n }\n};\n\nconst distanceToBindableElement = (element, point) => {\n switch (element.type) {\n case \"rectangle\":\n case \"image\":\n case \"text\":\n case \"embeddable\":\n case \"frame\":\n return distanceToRectangle(element, point);\n\n case \"diamond\":\n return distanceToDiamond(element, point);\n\n case \"ellipse\":\n return distanceToEllipse(element, point);\n }\n};\n\nconst isStrictlyInside = (distance, threshold) => {\n return distance < 0;\n};\n\nconst isInsideCheck = (distance, threshold) => {\n return distance < threshold;\n};\n\nconst isNearCheck = (distance, threshold) => {\n return Math.abs(distance) < threshold;\n};\n\nconst isOutsideCheck = (distance, threshold) => {\n return 0 <= distance && distance < threshold;\n};\n\nconst distanceToRectangle = (element, point) => {\n const [, pointRel, hwidth, hheight] = pointRelativeToElement(element, point);\n return Math.max(_gapoints__WEBPACK_IMPORTED_MODULE_1__.distanceToLine(pointRel, _galines__WEBPACK_IMPORTED_MODULE_3__.equation(0, 1, -hheight)), _gapoints__WEBPACK_IMPORTED_MODULE_1__.distanceToLine(pointRel, _galines__WEBPACK_IMPORTED_MODULE_3__.equation(1, 0, -hwidth)));\n};\n\nconst distanceToRectangleBox = (box, point) => {\n const [, pointRel, hwidth, hheight] = pointRelativeToDivElement(point, box);\n return Math.max(_gapoints__WEBPACK_IMPORTED_MODULE_1__.distanceToLine(pointRel, _galines__WEBPACK_IMPORTED_MODULE_3__.equation(0, 1, -hheight)), _gapoints__WEBPACK_IMPORTED_MODULE_1__.distanceToLine(pointRel, _galines__WEBPACK_IMPORTED_MODULE_3__.equation(1, 0, -hwidth)));\n};\n\nconst distanceToDiamond = (element, point) => {\n const [, pointRel, hwidth, hheight] = pointRelativeToElement(element, point);\n const side = _galines__WEBPACK_IMPORTED_MODULE_3__.equation(hheight, hwidth, -hheight * hwidth);\n return _gapoints__WEBPACK_IMPORTED_MODULE_1__.distanceToLine(pointRel, side);\n};\n\nconst distanceToEllipse = (element, point) => {\n const [pointRel, tangent] = ellipseParamsForTest(element, point);\n return -_galines__WEBPACK_IMPORTED_MODULE_3__.sign(tangent) * _gapoints__WEBPACK_IMPORTED_MODULE_1__.distanceToLine(pointRel, tangent);\n};\n\nconst ellipseParamsForTest = (element, point) => {\n const [, pointRel, hwidth, hheight] = pointRelativeToElement(element, point);\n const [px, py] = _gapoints__WEBPACK_IMPORTED_MODULE_1__.toTuple(pointRel); // We're working in positive quadrant, so start with `t = 45deg`, `tx=cos(t)`\n\n let tx = 0.707;\n let ty = 0.707;\n const a = hwidth;\n const b = hheight; // This is a numerical method to find the params tx, ty at which\n // the ellipse has the closest point to the given point\n\n [0, 1, 2, 3].forEach(_ => {\n const xx = a * tx;\n const yy = b * ty;\n const ex = (a * a - b * b) * tx ** 3 / a;\n const ey = (b * b - a * a) * ty ** 3 / b;\n const rx = xx - ex;\n const ry = yy - ey;\n const qx = px - ex;\n const qy = py - ey;\n const r = Math.hypot(ry, rx);\n const q = Math.hypot(qy, qx);\n tx = Math.min(1, Math.max(0, (qx * r / q + ex) / a));\n ty = Math.min(1, Math.max(0, (qy * r / q + ey) / b));\n const t = Math.hypot(ty, tx);\n tx /= t;\n ty /= t;\n });\n const closestPoint = _ga__WEBPACK_IMPORTED_MODULE_0__.point(a * tx, b * ty);\n const tangent = _galines__WEBPACK_IMPORTED_MODULE_3__.orthogonalThrough(pointRel, closestPoint);\n return [pointRel, tangent];\n};\n\nconst hitTestFreeDrawElement = (element, point, threshold) => {\n // Check point-distance-to-line-segment for every segment in the\n // element's points (its input points, not its outline points).\n // This is... okay? It's plenty fast, but the GA library may\n // have a faster option.\n let x;\n let y;\n\n if (element.angle === 0) {\n x = point[0] - element.x;\n y = point[1] - element.y;\n } else {\n // Counter-rotate the point around center before testing\n const [minX, minY, maxX, maxY] = (0,_bounds__WEBPACK_IMPORTED_MODULE_7__.getElementAbsoluteCoords)(element);\n const rotatedPoint = (0,_math__WEBPACK_IMPORTED_MODULE_5__.rotatePoint)(point, [minX + (maxX - minX) / 2, minY + (maxY - minY) / 2], -element.angle);\n x = rotatedPoint[0] - element.x;\n y = rotatedPoint[1] - element.y;\n }\n\n let [A, B] = element.points;\n let P; // For freedraw dots\n\n if ((0,_math__WEBPACK_IMPORTED_MODULE_5__.distance2d)(A[0], A[1], x, y) < threshold || (0,_math__WEBPACK_IMPORTED_MODULE_5__.distance2d)(B[0], B[1], x, y) < threshold) {\n return true;\n } // For freedraw lines\n\n\n for (let i = 0; i < element.points.length; i++) {\n const delta = [B[0] - A[0], B[1] - A[1]];\n const length = Math.hypot(delta[1], delta[0]);\n const U = [delta[0] / length, delta[1] / length];\n const C = [x - A[0], y - A[1]];\n const d = (C[0] * U[0] + C[1] * U[1]) / Math.hypot(U[1], U[0]);\n P = [A[0] + U[0] * d, A[1] + U[1] * d];\n const da = (0,_math__WEBPACK_IMPORTED_MODULE_5__.distance2d)(P[0], P[1], A[0], A[1]);\n const db = (0,_math__WEBPACK_IMPORTED_MODULE_5__.distance2d)(P[0], P[1], B[0], B[1]);\n P = db < da && da > length ? B : da < db && db > length ? A : P;\n\n if (Math.hypot(y - P[1], x - P[0]) < threshold) {\n return true;\n }\n\n A = B;\n B = element.points[i + 1];\n }\n\n const shape = _scene_ShapeCache__WEBPACK_IMPORTED_MODULE_13__.ShapeCache.get(element); // for filled freedraw shapes, support\n // selecting from inside\n\n if (shape && shape.sets.length) {\n return hitTestCurveInside(shape, x, y, \"round\");\n }\n\n return false;\n};\n\nconst hitTestLinear = args => {\n const {\n element,\n threshold\n } = args;\n\n if (!_scene_ShapeCache__WEBPACK_IMPORTED_MODULE_13__.ShapeCache.get(element)) {\n return false;\n }\n\n const [point, pointAbs, hwidth, hheight] = pointRelativeToElement(args.element, args.point);\n const side1 = _galines__WEBPACK_IMPORTED_MODULE_3__.equation(0, 1, -hheight);\n const side2 = _galines__WEBPACK_IMPORTED_MODULE_3__.equation(1, 0, -hwidth);\n\n if (!isInsideCheck(_gapoints__WEBPACK_IMPORTED_MODULE_1__.distanceToLine(pointAbs, side1), threshold) || !isInsideCheck(_gapoints__WEBPACK_IMPORTED_MODULE_1__.distanceToLine(pointAbs, side2), threshold)) {\n return false;\n }\n\n const [relX, relY] = _gapoints__WEBPACK_IMPORTED_MODULE_1__.toTuple(point);\n const shape = _scene_ShapeCache__WEBPACK_IMPORTED_MODULE_13__.ShapeCache.get(element);\n\n if (!shape) {\n return false;\n }\n\n if (args.check === isInsideCheck) {\n const hit = shape.some(subshape => hitTestCurveInside(subshape, relX, relY, element.roundness ? \"round\" : \"sharp\"));\n\n if (hit) {\n return true;\n }\n } // hit test all \"subshapes\" of the linear element\n\n\n return shape.some(subshape => hitTestRoughShape(subshape, relX, relY, threshold));\n}; // Returns:\n// 1. the point relative to the elements (x, y) position\n// 2. the point relative to the element's center with positive (x, y)\n// 3. half element width\n// 4. half element height\n//\n// Note that for linear elements the (x, y) position is not at the\n// top right corner of their boundary.\n//\n// Rectangles, diamonds and ellipses are symmetrical over axes,\n// and other elements have a rectangular boundary,\n// so we only need to perform hit tests for the positive quadrant.\n\n\nconst pointRelativeToElement = (element, pointTuple) => {\n const point = _gapoints__WEBPACK_IMPORTED_MODULE_1__.from(pointTuple);\n const [x1, y1, x2, y2] = (0,_bounds__WEBPACK_IMPORTED_MODULE_7__.getElementAbsoluteCoords)(element);\n const center = coordsCenter(x1, y1, x2, y2); // GA has angle orientation opposite to `rotate`\n\n const rotate = _gatransforms__WEBPACK_IMPORTED_MODULE_4__.rotation(center, element.angle);\n const pointRotated = _gatransforms__WEBPACK_IMPORTED_MODULE_4__.apply(rotate, point);\n const pointRelToCenter = _ga__WEBPACK_IMPORTED_MODULE_0__.sub(pointRotated, _gadirections__WEBPACK_IMPORTED_MODULE_2__.from(center));\n const pointRelToCenterAbs = _gapoints__WEBPACK_IMPORTED_MODULE_1__.abs(pointRelToCenter);\n const elementPos = _ga__WEBPACK_IMPORTED_MODULE_0__.offset(element.x, element.y);\n const pointRelToPos = _ga__WEBPACK_IMPORTED_MODULE_0__.sub(pointRotated, elementPos);\n const halfWidth = (x2 - x1) / 2;\n const halfHeight = (y2 - y1) / 2;\n return [pointRelToPos, pointRelToCenterAbs, halfWidth, halfHeight];\n};\n\nconst pointRelativeToDivElement = (pointTuple, rectangle) => {\n const point = _gapoints__WEBPACK_IMPORTED_MODULE_1__.from(pointTuple);\n const [x1, y1, x2, y2] = (0,_bounds__WEBPACK_IMPORTED_MODULE_7__.getRectangleBoxAbsoluteCoords)(rectangle);\n const center = coordsCenter(x1, y1, x2, y2);\n const rotate = _gatransforms__WEBPACK_IMPORTED_MODULE_4__.rotation(center, rectangle.angle);\n const pointRotated = _gatransforms__WEBPACK_IMPORTED_MODULE_4__.apply(rotate, point);\n const pointRelToCenter = _ga__WEBPACK_IMPORTED_MODULE_0__.sub(pointRotated, _gadirections__WEBPACK_IMPORTED_MODULE_2__.from(center));\n const pointRelToCenterAbs = _gapoints__WEBPACK_IMPORTED_MODULE_1__.abs(pointRelToCenter);\n const elementPos = _ga__WEBPACK_IMPORTED_MODULE_0__.offset(rectangle.x, rectangle.y);\n const pointRelToPos = _ga__WEBPACK_IMPORTED_MODULE_0__.sub(pointRotated, elementPos);\n const halfWidth = (x2 - x1) / 2;\n const halfHeight = (y2 - y1) / 2;\n return [pointRelToPos, pointRelToCenterAbs, halfWidth, halfHeight];\n}; // Returns point in absolute coordinates\n\n\nconst pointInAbsoluteCoords = (element, // Point relative to the element position\npoint) => {\n const [x, y] = point;\n const [x1, y1, x2, y2] = (0,_bounds__WEBPACK_IMPORTED_MODULE_7__.getElementAbsoluteCoords)(element);\n const cx = (x2 - x1) / 2;\n const cy = (y2 - y1) / 2;\n const [rotatedX, rotatedY] = (0,_math__WEBPACK_IMPORTED_MODULE_5__.rotate)(x, y, cx, cy, element.angle);\n return [element.x + rotatedX, element.y + rotatedY];\n};\n\nconst relativizationToElementCenter = element => {\n const [x1, y1, x2, y2] = (0,_bounds__WEBPACK_IMPORTED_MODULE_7__.getElementAbsoluteCoords)(element);\n const center = coordsCenter(x1, y1, x2, y2); // GA has angle orientation opposite to `rotate`\n\n const rotate = _gatransforms__WEBPACK_IMPORTED_MODULE_4__.rotation(center, element.angle);\n const translate = _ga__WEBPACK_IMPORTED_MODULE_0__.reverse(_gatransforms__WEBPACK_IMPORTED_MODULE_4__.translation(_gadirections__WEBPACK_IMPORTED_MODULE_2__.from(center)));\n return _gatransforms__WEBPACK_IMPORTED_MODULE_4__.compose(rotate, translate);\n};\n\nconst coordsCenter = (x1, y1, x2, y2) => {\n return _ga__WEBPACK_IMPORTED_MODULE_0__.point((x1 + x2) / 2, (y1 + y2) / 2);\n}; // The focus distance is the oriented ratio between the size of\n// the `element` and the \"focus image\" of the element on which\n// all focus points lie, so it's a number between -1 and 1.\n// The line going through `a` and `b` is a tangent to the \"focus image\"\n// of the element.\n\n\nconst determineFocusDistance = (element, // Point on the line, in absolute coordinates\na, // Another point on the line, in absolute coordinates (closer to element)\nb) => {\n const relateToCenter = relativizationToElementCenter(element);\n const aRel = _gatransforms__WEBPACK_IMPORTED_MODULE_4__.apply(relateToCenter, _gapoints__WEBPACK_IMPORTED_MODULE_1__.from(a));\n const bRel = _gatransforms__WEBPACK_IMPORTED_MODULE_4__.apply(relateToCenter, _gapoints__WEBPACK_IMPORTED_MODULE_1__.from(b));\n const line = _galines__WEBPACK_IMPORTED_MODULE_3__.through(aRel, bRel);\n const q = element.height / element.width;\n const hwidth = element.width / 2;\n const hheight = element.height / 2;\n const n = line[2];\n const m = line[3];\n const c = line[1];\n const mabs = Math.abs(m);\n const nabs = Math.abs(n);\n let ret;\n\n switch (element.type) {\n case \"rectangle\":\n case \"image\":\n case \"text\":\n case \"embeddable\":\n case \"frame\":\n ret = c / (hwidth * (nabs + q * mabs));\n break;\n\n case \"diamond\":\n ret = mabs < nabs ? c / (nabs * hwidth) : c / (mabs * hheight);\n break;\n\n case \"ellipse\":\n ret = c / (hwidth * Math.sqrt(n ** 2 + q ** 2 * m ** 2));\n break;\n }\n\n return ret || 0;\n};\nconst determineFocusPoint = (element, // The oriented, relative distance from the center of `element` of the\n// returned focusPoint\nfocus, adjecentPoint) => {\n if (focus === 0) {\n const [x1, y1, x2, y2] = (0,_bounds__WEBPACK_IMPORTED_MODULE_7__.getElementAbsoluteCoords)(element);\n const center = coordsCenter(x1, y1, x2, y2);\n return _gapoints__WEBPACK_IMPORTED_MODULE_1__.toTuple(center);\n }\n\n const relateToCenter = relativizationToElementCenter(element);\n const adjecentPointRel = _gatransforms__WEBPACK_IMPORTED_MODULE_4__.apply(relateToCenter, _gapoints__WEBPACK_IMPORTED_MODULE_1__.from(adjecentPoint));\n const reverseRelateToCenter = _ga__WEBPACK_IMPORTED_MODULE_0__.reverse(relateToCenter);\n let point;\n\n switch (element.type) {\n case \"rectangle\":\n case \"image\":\n case \"text\":\n case \"diamond\":\n case \"embeddable\":\n case \"frame\":\n point = findFocusPointForRectangulars(element, focus, adjecentPointRel);\n break;\n\n case \"ellipse\":\n point = findFocusPointForEllipse(element, focus, adjecentPointRel);\n break;\n }\n\n return _gapoints__WEBPACK_IMPORTED_MODULE_1__.toTuple(_gatransforms__WEBPACK_IMPORTED_MODULE_4__.apply(reverseRelateToCenter, point));\n}; // Returns 2 or 0 intersection points between line going through `a` and `b`\n// and the `element`, in ascending order of distance from `a`.\n\nconst intersectElementWithLine = (element, // Point on the line, in absolute coordinates\na, // Another point on the line, in absolute coordinates\nb, // If given, the element is inflated by this value\ngap = 0) => {\n const relateToCenter = relativizationToElementCenter(element);\n const aRel = _gatransforms__WEBPACK_IMPORTED_MODULE_4__.apply(relateToCenter, _gapoints__WEBPACK_IMPORTED_MODULE_1__.from(a));\n const bRel = _gatransforms__WEBPACK_IMPORTED_MODULE_4__.apply(relateToCenter, _gapoints__WEBPACK_IMPORTED_MODULE_1__.from(b));\n const line = _galines__WEBPACK_IMPORTED_MODULE_3__.through(aRel, bRel);\n const reverseRelateToCenter = _ga__WEBPACK_IMPORTED_MODULE_0__.reverse(relateToCenter);\n const intersections = getSortedElementLineIntersections(element, line, aRel, gap);\n return intersections.map(point => _gapoints__WEBPACK_IMPORTED_MODULE_1__.toTuple(_gatransforms__WEBPACK_IMPORTED_MODULE_4__.apply(reverseRelateToCenter, point)));\n};\n\nconst getSortedElementLineIntersections = (element, // Relative to element center\nline, // Relative to element center\nnearPoint, gap = 0) => {\n let intersections;\n\n switch (element.type) {\n case \"rectangle\":\n case \"image\":\n case \"text\":\n case \"diamond\":\n case \"embeddable\":\n case \"frame\":\n const corners = getCorners(element);\n intersections = corners.flatMap((point, i) => {\n const edge = [point, corners[(i + 1) % 4]];\n return intersectSegment(line, offsetSegment(edge, gap));\n }).concat(corners.flatMap(point => getCircleIntersections(point, gap, line)));\n break;\n\n case \"ellipse\":\n intersections = getEllipseIntersections(element, gap, line);\n break;\n }\n\n if (intersections.length < 2) {\n // Ignore the \"edge\" case of only intersecting with a single corner\n return [];\n }\n\n const sortedIntersections = intersections.sort((i1, i2) => _gapoints__WEBPACK_IMPORTED_MODULE_1__.distance(i1, nearPoint) - _gapoints__WEBPACK_IMPORTED_MODULE_1__.distance(i2, nearPoint));\n return [sortedIntersections[0], sortedIntersections[sortedIntersections.length - 1]];\n};\n\nconst getCorners = (element, scale = 1) => {\n const hx = scale * element.width / 2;\n const hy = scale * element.height / 2;\n\n switch (element.type) {\n case \"rectangle\":\n case \"image\":\n case \"text\":\n case \"embeddable\":\n case \"frame\":\n return [_ga__WEBPACK_IMPORTED_MODULE_0__.point(hx, hy), _ga__WEBPACK_IMPORTED_MODULE_0__.point(hx, -hy), _ga__WEBPACK_IMPORTED_MODULE_0__.point(-hx, -hy), _ga__WEBPACK_IMPORTED_MODULE_0__.point(-hx, hy)];\n\n case \"diamond\":\n return [_ga__WEBPACK_IMPORTED_MODULE_0__.point(0, hy), _ga__WEBPACK_IMPORTED_MODULE_0__.point(hx, 0), _ga__WEBPACK_IMPORTED_MODULE_0__.point(0, -hy), _ga__WEBPACK_IMPORTED_MODULE_0__.point(-hx, 0)];\n }\n}; // Returns intersection of `line` with `segment`, with `segment` moved by\n// `gap` in its polar direction.\n// If intersection coincides with second segment point returns empty array.\n\n\nconst intersectSegment = (line, segment) => {\n const [a, b] = segment;\n const aDist = _gapoints__WEBPACK_IMPORTED_MODULE_1__.distanceToLine(a, line);\n const bDist = _gapoints__WEBPACK_IMPORTED_MODULE_1__.distanceToLine(b, line);\n\n if (aDist * bDist >= 0) {\n // The intersection is outside segment `(a, b)`\n return [];\n }\n\n return [_gapoints__WEBPACK_IMPORTED_MODULE_1__.intersect(line, _galines__WEBPACK_IMPORTED_MODULE_3__.through(a, b))];\n};\n\nconst offsetSegment = (segment, distance) => {\n const [a, b] = segment;\n const offset = _gatransforms__WEBPACK_IMPORTED_MODULE_4__.translationOrthogonal(_gadirections__WEBPACK_IMPORTED_MODULE_2__.fromTo(a, b), distance);\n return [_gatransforms__WEBPACK_IMPORTED_MODULE_4__.apply(offset, a), _gatransforms__WEBPACK_IMPORTED_MODULE_4__.apply(offset, b)];\n};\n\nconst getEllipseIntersections = (element, gap, line) => {\n const a = element.width / 2 + gap;\n const b = element.height / 2 + gap;\n const m = line[2];\n const n = line[3];\n const c = line[1];\n const squares = a * a * m * m + b * b * n * n;\n const discr = squares - c * c;\n\n if (squares === 0 || discr <= 0) {\n return [];\n }\n\n const discrRoot = Math.sqrt(discr);\n const xn = -a * a * m * c;\n const yn = -b * b * n * c;\n return [_ga__WEBPACK_IMPORTED_MODULE_0__.point((xn + a * b * n * discrRoot) / squares, (yn - a * b * m * discrRoot) / squares), _ga__WEBPACK_IMPORTED_MODULE_0__.point((xn - a * b * n * discrRoot) / squares, (yn + a * b * m * discrRoot) / squares)];\n};\n\nconst getCircleIntersections = (center, radius, line) => {\n if (radius === 0) {\n return _gapoints__WEBPACK_IMPORTED_MODULE_1__.distanceToLine(line, center) === 0 ? [center] : [];\n }\n\n const m = line[2];\n const n = line[3];\n const c = line[1];\n const [a, b] = _gapoints__WEBPACK_IMPORTED_MODULE_1__.toTuple(center);\n const r = radius;\n const squares = m * m + n * n;\n const discr = r * r * squares - (m * a + n * b + c) ** 2;\n\n if (squares === 0 || discr <= 0) {\n return [];\n }\n\n const discrRoot = Math.sqrt(discr);\n const xn = a * n * n - b * m * n - m * c;\n const yn = b * m * m - a * m * n - n * c;\n return [_ga__WEBPACK_IMPORTED_MODULE_0__.point((xn + n * discrRoot) / squares, (yn - m * discrRoot) / squares), _ga__WEBPACK_IMPORTED_MODULE_0__.point((xn - n * discrRoot) / squares, (yn + m * discrRoot) / squares)];\n}; // The focus point is the tangent point of the \"focus image\" of the\n// `element`, where the tangent goes through `point`.\n\nconst findFocusPointForEllipse = (ellipse, // Between -1 and 1 (not 0) the relative size of the \"focus image\" of\n// the element on which the focus point lies\nrelativeDistance, // The point for which we're trying to find the focus point, relative\n// to the ellipse center.\npoint) => {\n const relativeDistanceAbs = Math.abs(relativeDistance);\n const a = ellipse.width * relativeDistanceAbs / 2;\n const b = ellipse.height * relativeDistanceAbs / 2;\n const orientation = Math.sign(relativeDistance);\n const [px, pyo] = _gapoints__WEBPACK_IMPORTED_MODULE_1__.toTuple(point); // The calculation below can't handle py = 0\n\n const py = pyo === 0 ? 0.0001 : pyo;\n const squares = px ** 2 * b ** 2 + py ** 2 * a ** 2; // Tangent mx + ny + 1 = 0\n\n const m = (-px * b ** 2 + orientation * py * Math.sqrt(Math.max(0, squares - a ** 2 * b ** 2))) / squares;\n let n = (-m * px - 1) / py;\n\n if (n === 0) {\n // if zero {-0, 0}, fall back to a same-sign value in the similar range\n n = (Object.is(n, -0) ? -1 : 1) * 0.01;\n }\n\n const x = -(a ** 2 * m) / (n ** 2 * b ** 2 + m ** 2 * a ** 2);\n return _ga__WEBPACK_IMPORTED_MODULE_0__.point(x, (-m * x - 1) / (n === 0 ? 0.0001 : n)); //zsviczian https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/1054\n};\nconst findFocusPointForRectangulars = (element, // Between -1 and 1 for how far away should the focus point be relative\n// to the size of the element. Sign determines orientation.\nrelativeDistance, // The point for which we're trying to find the focus point, relative\n// to the element center.\npoint) => {\n const relativeDistanceAbs = Math.abs(relativeDistance);\n const orientation = Math.sign(relativeDistance);\n const corners = getCorners(element, relativeDistanceAbs);\n let maxDistance = 0;\n let tangentPoint = null;\n corners.forEach(corner => {\n const distance = orientation * _galines__WEBPACK_IMPORTED_MODULE_3__.through(point, corner)[1];\n\n if (distance > maxDistance) {\n maxDistance = distance;\n tangentPoint = corner;\n }\n });\n return tangentPoint;\n};\n\nconst pointInBezierEquation = (p0, p1, p2, p3, [mx, my], lineThreshold) => {\n // B(t) = p0 * (1-t)^3 + 3p1 * t * (1-t)^2 + 3p2 * t^2 * (1-t) + p3 * t^3\n const equation = (t, idx) => Math.pow(1 - t, 3) * p3[idx] + 3 * t * Math.pow(1 - t, 2) * p2[idx] + 3 * Math.pow(t, 2) * (1 - t) * p1[idx] + p0[idx] * Math.pow(t, 3); // go through t in increments of 0.01\n\n\n let t = 0;\n\n while (t <= 1.0) {\n const tx = equation(t, 0);\n const ty = equation(t, 1);\n const diff = Math.sqrt(Math.pow(tx - mx, 2) + Math.pow(ty - my, 2));\n\n if (diff < lineThreshold) {\n return true;\n }\n\n t += 0.01;\n }\n\n return false;\n};\n\nconst hitTestCurveInside = (drawable, x, y, roundness) => {\n const ops = (0,_bounds__WEBPACK_IMPORTED_MODULE_7__.getCurvePathOps)(drawable);\n const points = [];\n let odd = false; // select one line out of double lines\n\n for (const operation of ops) {\n if (operation.op === \"move\") {\n odd = !odd;\n\n if (odd) {\n points.push([operation.data[0], operation.data[1]]);\n }\n } else if (operation.op === \"bcurveTo\") {\n if (odd) {\n points.push([operation.data[0], operation.data[1]]);\n points.push([operation.data[2], operation.data[3]]);\n points.push([operation.data[4], operation.data[5]]);\n }\n } else if (operation.op === \"lineTo\") {\n if (odd) {\n points.push([operation.data[0], operation.data[1]]);\n }\n }\n }\n\n if (points.length >= 4) {\n if (roundness === \"sharp\") {\n return (0,_math__WEBPACK_IMPORTED_MODULE_5__.isPointInPolygon)(points, x, y);\n }\n\n const polygonPoints = (0,points_on_curve__WEBPACK_IMPORTED_MODULE_6__.pointsOnBezierCurves)(points, 10, 5);\n return (0,_math__WEBPACK_IMPORTED_MODULE_5__.isPointInPolygon)(polygonPoints, x, y);\n }\n\n return false;\n};\n\nconst hitTestRoughShape = (drawable, x, y, lineThreshold) => {\n // read operations from first opSet\n const ops = (0,_bounds__WEBPACK_IMPORTED_MODULE_7__.getCurvePathOps)(drawable); // set start position as (0,0) just in case\n // move operation does not exist (unlikely but it is worth safekeeping it)\n\n let currentP = [0, 0];\n return ops.some(({\n op,\n data\n }, idx) => {\n // There are only four operation types:\n // move, bcurveTo, lineTo, and curveTo\n if (op === \"move\") {\n // change starting point\n currentP = data; // move operation does not draw anything; so, it always\n // returns false\n } else if (op === \"bcurveTo\") {\n // create points from bezier curve\n // bezier curve stores data as a flattened array of three positions\n // [x1, y1, x2, y2, x3, y3]\n const p1 = [data[0], data[1]];\n const p2 = [data[2], data[3]];\n const p3 = [data[4], data[5]];\n const p0 = currentP;\n currentP = p3; // check if points are on the curve\n // cubic bezier curves require four parameters\n // the first parameter is the last stored position (p0)\n\n const retVal = pointInBezierEquation(p0, p1, p2, p3, [x, y], lineThreshold); // set end point of bezier curve as the new starting point for\n // upcoming operations as each operation is based on the last drawn\n // position of the previous operation\n\n return retVal;\n } else if (op === \"lineTo\") {\n return hitTestCurveInside(drawable, x, y, \"sharp\");\n } else if (op === \"qcurveTo\") {\n // TODO: Implement this\n console.warn(\"qcurveTo is not implemented yet\");\n }\n\n return false;\n });\n};\n\n//# sourceURL=webpack://ExcalidrawLib/../../element/collision.ts?");
3681
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"bindingBorderTest\": () => (/* binding */ bindingBorderTest),\n/* harmony export */ \"determineFocusDistance\": () => (/* binding */ determineFocusDistance),\n/* harmony export */ \"determineFocusPoint\": () => (/* binding */ determineFocusPoint),\n/* harmony export */ \"distanceToBindableElement\": () => (/* binding */ distanceToBindableElement),\n/* harmony export */ \"findFocusPointForEllipse\": () => (/* binding */ findFocusPointForEllipse),\n/* harmony export */ \"findFocusPointForRectangulars\": () => (/* binding */ findFocusPointForRectangulars),\n/* harmony export */ \"getCircleIntersections\": () => (/* binding */ getCircleIntersections),\n/* harmony export */ \"hitTest\": () => (/* binding */ hitTest),\n/* harmony export */ \"intersectElementWithLine\": () => (/* binding */ intersectElementWithLine),\n/* harmony export */ \"isHittingElementBoundingBoxWithoutHittingElement\": () => (/* binding */ isHittingElementBoundingBoxWithoutHittingElement),\n/* harmony export */ \"isHittingElementNotConsideringBoundingBox\": () => (/* binding */ isHittingElementNotConsideringBoundingBox),\n/* harmony export */ \"isPointHittingElementBoundingBox\": () => (/* binding */ isPointHittingElementBoundingBox),\n/* harmony export */ \"maxBindingGap\": () => (/* binding */ maxBindingGap),\n/* harmony export */ \"pointInAbsoluteCoords\": () => (/* binding */ pointInAbsoluteCoords)\n/* harmony export */ });\n/* harmony import */ var _ga__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../ga */ \"../../ga.ts\");\n/* harmony import */ var _gapoints__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../gapoints */ \"../../gapoints.ts\");\n/* harmony import */ var _gadirections__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../gadirections */ \"../../gadirections.ts\");\n/* harmony import */ var _galines__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../galines */ \"../../galines.ts\");\n/* harmony import */ var _gatransforms__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../gatransforms */ \"../../gatransforms.ts\");\n/* harmony import */ var _math__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../math */ \"../../math.ts\");\n/* harmony import */ var points_on_curve__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! points-on-curve */ \"../../../node_modules/points-on-curve/lib/index.js\");\n/* harmony import */ var _bounds__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./bounds */ \"../../element/bounds.ts\");\n/* harmony import */ var _typeChecks__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var ___WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! . */ \"../../element/index.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _transformHandles__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./transformHandles */ \"../../element/transformHandles.ts\");\n/* harmony import */ var _textElement__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./textElement */ \"../../element/textElement.ts\");\n/* harmony import */ var _scene_ShapeCache__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../scene/ShapeCache */ \"../../scene/ShapeCache.ts\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst isElementDraggableFromInside = element => {\n if (element.type === \"arrow\") {\n return false;\n }\n\n if (element.type === \"freedraw\") {\n return true;\n }\n\n const isDraggableFromInside = !(0,_utils__WEBPACK_IMPORTED_MODULE_10__.isTransparent)(element.backgroundColor) || (0,_typeChecks__WEBPACK_IMPORTED_MODULE_8__.hasBoundTextElement)(element) || (0,_typeChecks__WEBPACK_IMPORTED_MODULE_8__.isEmbeddableElement)(element);\n\n if (element.type === \"line\") {\n return isDraggableFromInside && (0,_math__WEBPACK_IMPORTED_MODULE_5__.isPathALoop)(element.points);\n }\n\n return isDraggableFromInside || (0,_typeChecks__WEBPACK_IMPORTED_MODULE_8__.isImageElement)(element);\n};\n\nconst hitTest = (element, appState, frameNameBoundsCache, x, y) => {\n // How many pixels off the shape boundary we still consider a hit\n const threshold = 10 / appState.zoom.value;\n const point = [x, y];\n\n if (isElementSelected(appState, element) && (0,_transformHandles__WEBPACK_IMPORTED_MODULE_11__.shouldShowBoundingBox)([element], appState)) {\n return isPointHittingElementBoundingBox(element, point, threshold, frameNameBoundsCache);\n }\n\n const boundTextElement = (0,_textElement__WEBPACK_IMPORTED_MODULE_12__.getBoundTextElement)(element);\n\n if (boundTextElement) {\n const isHittingBoundTextElement = hitTest(boundTextElement, appState, frameNameBoundsCache, x, y);\n\n if (isHittingBoundTextElement) {\n return true;\n }\n }\n\n return isHittingElementNotConsideringBoundingBox(element, appState, frameNameBoundsCache, point);\n};\nconst isHittingElementBoundingBoxWithoutHittingElement = (element, appState, frameNameBoundsCache, x, y) => {\n const threshold = 10 / appState.zoom.value; // So that bound text element hit is considered within bounding box of container even if its outside actual bounding box of element\n // eg for linear elements text can be outside the element bounding box\n\n const boundTextElement = (0,_textElement__WEBPACK_IMPORTED_MODULE_12__.getBoundTextElement)(element);\n\n if (boundTextElement && hitTest(boundTextElement, appState, frameNameBoundsCache, x, y)) {\n return false;\n }\n\n return !isHittingElementNotConsideringBoundingBox(element, appState, frameNameBoundsCache, [x, y]) && isPointHittingElementBoundingBox(element, [x, y], threshold, frameNameBoundsCache);\n};\nconst isHittingElementNotConsideringBoundingBox = (element, appState, frameNameBoundsCache, point) => {\n const threshold = 10 / appState.zoom.value;\n const check = (0,___WEBPACK_IMPORTED_MODULE_9__.isTextElement)(element) ? isStrictlyInside : isElementDraggableFromInside(element) ? isInsideCheck : isNearCheck;\n return hitTestPointAgainstElement({\n element,\n point,\n threshold,\n check,\n frameNameBoundsCache\n });\n};\n\nconst isElementSelected = (appState, element) => appState.selectedElementIds[element.id];\n\nconst isPointHittingElementBoundingBox = (element, [x, y], threshold, frameNameBoundsCache) => {\n // frames needs be checked differently so as to be able to drag it\n // by its frame, whether it has been selected or not\n // this logic here is not ideal\n // TODO: refactor it later...\n if (element.type === \"frame\") {\n return hitTestPointAgainstElement({\n element,\n point: [x, y],\n threshold,\n check: isInsideCheck,\n frameNameBoundsCache\n });\n }\n\n const [x1, y1, x2, y2] = (0,_bounds__WEBPACK_IMPORTED_MODULE_7__.getElementAbsoluteCoords)(element);\n const elementCenterX = (x1 + x2) / 2;\n const elementCenterY = (y1 + y2) / 2; // reverse rotate to take element's angle into account.\n\n const [rotatedX, rotatedY] = (0,_math__WEBPACK_IMPORTED_MODULE_5__.rotate)(x, y, elementCenterX, elementCenterY, -element.angle);\n return rotatedX > x1 - threshold && rotatedX < x2 + threshold && rotatedY > y1 - threshold && rotatedY < y2 + threshold;\n};\nconst bindingBorderTest = (element, {\n x,\n y\n}) => {\n const threshold = maxBindingGap(element, element.width, element.height);\n const check = isOutsideCheck;\n const point = [x, y];\n return hitTestPointAgainstElement({\n element,\n point,\n threshold,\n check,\n frameNameBoundsCache: null\n });\n};\nconst maxBindingGap = (element, elementWidth, elementHeight) => {\n // Aligns diamonds with rectangles\n const shapeRatio = element.type === \"diamond\" ? 1 / Math.sqrt(2) : 1;\n const smallerDimension = shapeRatio * Math.min(elementWidth, elementHeight); // We make the bindable boundary bigger for bigger elements\n\n return Math.max(16, Math.min(0.25 * smallerDimension, 32));\n};\n\nconst hitTestPointAgainstElement = args => {\n var _a;\n\n switch (args.element.type) {\n case \"rectangle\":\n case \"embeddable\":\n case \"image\":\n case \"text\":\n case \"diamond\":\n case \"ellipse\":\n const distance = distanceToBindableElement(args.element, args.point);\n return args.check(distance, args.threshold);\n\n case \"freedraw\":\n {\n if (!args.check(distanceToRectangle(args.element, args.point), args.threshold)) {\n return false;\n }\n\n return hitTestFreeDrawElement(args.element, args.point, args.threshold);\n }\n\n case \"arrow\":\n case \"line\":\n return hitTestLinear(args);\n\n case \"selection\":\n console.warn(\"This should not happen, we need to investigate why it does.\");\n return false;\n\n case \"frame\":\n {\n // check distance to frame element first\n if (args.check(distanceToBindableElement(args.element, args.point), args.threshold)) {\n return true;\n }\n\n const frameNameBounds = (_a = args.frameNameBoundsCache) === null || _a === void 0 ? void 0 : _a.get(args.element);\n\n if (frameNameBounds) {\n return args.check(distanceToRectangleBox(frameNameBounds, args.point), args.threshold);\n }\n\n return false;\n }\n }\n};\n\nconst distanceToBindableElement = (element, point) => {\n switch (element.type) {\n case \"rectangle\":\n case \"image\":\n case \"text\":\n case \"embeddable\":\n case \"frame\":\n return distanceToRectangle(element, point);\n\n case \"diamond\":\n return distanceToDiamond(element, point);\n\n case \"ellipse\":\n return distanceToEllipse(element, point);\n }\n};\n\nconst isStrictlyInside = (distance, threshold) => {\n return distance < 0;\n};\n\nconst isInsideCheck = (distance, threshold) => {\n return distance < threshold;\n};\n\nconst isNearCheck = (distance, threshold) => {\n return Math.abs(distance) < threshold;\n};\n\nconst isOutsideCheck = (distance, threshold) => {\n return 0 <= distance && distance < threshold;\n};\n\nconst distanceToRectangle = (element, point) => {\n const [, pointRel, hwidth, hheight] = pointRelativeToElement(element, point);\n return Math.max(_gapoints__WEBPACK_IMPORTED_MODULE_1__.distanceToLine(pointRel, _galines__WEBPACK_IMPORTED_MODULE_3__.equation(0, 1, -hheight)), _gapoints__WEBPACK_IMPORTED_MODULE_1__.distanceToLine(pointRel, _galines__WEBPACK_IMPORTED_MODULE_3__.equation(1, 0, -hwidth)));\n};\n\nconst distanceToRectangleBox = (box, point) => {\n const [, pointRel, hwidth, hheight] = pointRelativeToDivElement(point, box);\n return Math.max(_gapoints__WEBPACK_IMPORTED_MODULE_1__.distanceToLine(pointRel, _galines__WEBPACK_IMPORTED_MODULE_3__.equation(0, 1, -hheight)), _gapoints__WEBPACK_IMPORTED_MODULE_1__.distanceToLine(pointRel, _galines__WEBPACK_IMPORTED_MODULE_3__.equation(1, 0, -hwidth)));\n};\n\nconst distanceToDiamond = (element, point) => {\n const [, pointRel, hwidth, hheight] = pointRelativeToElement(element, point);\n const side = _galines__WEBPACK_IMPORTED_MODULE_3__.equation(hheight, hwidth, -hheight * hwidth);\n return _gapoints__WEBPACK_IMPORTED_MODULE_1__.distanceToLine(pointRel, side);\n};\n\nconst distanceToEllipse = (element, point) => {\n const [pointRel, tangent] = ellipseParamsForTest(element, point);\n return -_galines__WEBPACK_IMPORTED_MODULE_3__.sign(tangent) * _gapoints__WEBPACK_IMPORTED_MODULE_1__.distanceToLine(pointRel, tangent);\n};\n\nconst ellipseParamsForTest = (element, point) => {\n const [, pointRel, hwidth, hheight] = pointRelativeToElement(element, point);\n const [px, py] = _gapoints__WEBPACK_IMPORTED_MODULE_1__.toTuple(pointRel); // We're working in positive quadrant, so start with `t = 45deg`, `tx=cos(t)`\n\n let tx = 0.707;\n let ty = 0.707;\n const a = hwidth;\n const b = hheight; // This is a numerical method to find the params tx, ty at which\n // the ellipse has the closest point to the given point\n\n [0, 1, 2, 3].forEach(_ => {\n const xx = a * tx;\n const yy = b * ty;\n const ex = (a * a - b * b) * tx ** 3 / a;\n const ey = (b * b - a * a) * ty ** 3 / b;\n const rx = xx - ex;\n const ry = yy - ey;\n const qx = px - ex;\n const qy = py - ey;\n const r = Math.hypot(ry, rx);\n const q = Math.hypot(qy, qx);\n tx = Math.min(1, Math.max(0, (qx * r / q + ex) / a));\n ty = Math.min(1, Math.max(0, (qy * r / q + ey) / b));\n const t = Math.hypot(ty, tx);\n tx /= t;\n ty /= t;\n });\n const closestPoint = _ga__WEBPACK_IMPORTED_MODULE_0__.point(a * tx, b * ty);\n const tangent = _galines__WEBPACK_IMPORTED_MODULE_3__.orthogonalThrough(pointRel, closestPoint);\n return [pointRel, tangent];\n};\n\nconst hitTestFreeDrawElement = (element, point, threshold) => {\n // Check point-distance-to-line-segment for every segment in the\n // element's points (its input points, not its outline points).\n // This is... okay? It's plenty fast, but the GA library may\n // have a faster option.\n let x;\n let y;\n\n if (element.angle === 0) {\n x = point[0] - element.x;\n y = point[1] - element.y;\n } else {\n // Counter-rotate the point around center before testing\n const [minX, minY, maxX, maxY] = (0,_bounds__WEBPACK_IMPORTED_MODULE_7__.getElementAbsoluteCoords)(element);\n const rotatedPoint = (0,_math__WEBPACK_IMPORTED_MODULE_5__.rotatePoint)(point, [minX + (maxX - minX) / 2, minY + (maxY - minY) / 2], -element.angle);\n x = rotatedPoint[0] - element.x;\n y = rotatedPoint[1] - element.y;\n }\n\n let [A, B] = element.points;\n let P; // For freedraw dots\n\n if ((0,_math__WEBPACK_IMPORTED_MODULE_5__.distance2d)(A[0], A[1], x, y) < threshold || (0,_math__WEBPACK_IMPORTED_MODULE_5__.distance2d)(B[0], B[1], x, y) < threshold) {\n return true;\n } // For freedraw lines\n\n\n for (let i = 0; i < element.points.length; i++) {\n const delta = [B[0] - A[0], B[1] - A[1]];\n const length = Math.hypot(delta[1], delta[0]);\n const U = [delta[0] / length, delta[1] / length];\n const C = [x - A[0], y - A[1]];\n const d = (C[0] * U[0] + C[1] * U[1]) / Math.hypot(U[1], U[0]);\n P = [A[0] + U[0] * d, A[1] + U[1] * d];\n const da = (0,_math__WEBPACK_IMPORTED_MODULE_5__.distance2d)(P[0], P[1], A[0], A[1]);\n const db = (0,_math__WEBPACK_IMPORTED_MODULE_5__.distance2d)(P[0], P[1], B[0], B[1]);\n P = db < da && da > length ? B : da < db && db > length ? A : P;\n\n if (Math.hypot(y - P[1], x - P[0]) < threshold) {\n return true;\n }\n\n A = B;\n B = element.points[i + 1];\n }\n\n const shape = _scene_ShapeCache__WEBPACK_IMPORTED_MODULE_13__.ShapeCache.get(element); // for filled freedraw shapes, support\n // selecting from inside\n\n if (shape && shape.sets.length) {\n return element.fillStyle === \"solid\" ? hitTestCurveInside(shape, x, y, \"round\") : hitTestRoughShape(shape, x, y, threshold);\n }\n\n return false;\n};\n\nconst hitTestLinear = args => {\n const {\n element,\n threshold\n } = args;\n\n if (!_scene_ShapeCache__WEBPACK_IMPORTED_MODULE_13__.ShapeCache.get(element)) {\n return false;\n }\n\n const [point, pointAbs, hwidth, hheight] = pointRelativeToElement(args.element, args.point);\n const side1 = _galines__WEBPACK_IMPORTED_MODULE_3__.equation(0, 1, -hheight);\n const side2 = _galines__WEBPACK_IMPORTED_MODULE_3__.equation(1, 0, -hwidth);\n\n if (!isInsideCheck(_gapoints__WEBPACK_IMPORTED_MODULE_1__.distanceToLine(pointAbs, side1), threshold) || !isInsideCheck(_gapoints__WEBPACK_IMPORTED_MODULE_1__.distanceToLine(pointAbs, side2), threshold)) {\n return false;\n }\n\n const [relX, relY] = _gapoints__WEBPACK_IMPORTED_MODULE_1__.toTuple(point);\n const shape = _scene_ShapeCache__WEBPACK_IMPORTED_MODULE_13__.ShapeCache.get(element);\n\n if (!shape) {\n return false;\n }\n\n if (args.check === isInsideCheck) {\n const hit = shape.some(subshape => hitTestCurveInside(subshape, relX, relY, element.roundness ? \"round\" : \"sharp\"));\n\n if (hit) {\n return true;\n }\n } // hit test all \"subshapes\" of the linear element\n\n\n return shape.some(subshape => hitTestRoughShape(subshape, relX, relY, threshold));\n}; // Returns:\n// 1. the point relative to the elements (x, y) position\n// 2. the point relative to the element's center with positive (x, y)\n// 3. half element width\n// 4. half element height\n//\n// Note that for linear elements the (x, y) position is not at the\n// top right corner of their boundary.\n//\n// Rectangles, diamonds and ellipses are symmetrical over axes,\n// and other elements have a rectangular boundary,\n// so we only need to perform hit tests for the positive quadrant.\n\n\nconst pointRelativeToElement = (element, pointTuple) => {\n const point = _gapoints__WEBPACK_IMPORTED_MODULE_1__.from(pointTuple);\n const [x1, y1, x2, y2] = (0,_bounds__WEBPACK_IMPORTED_MODULE_7__.getElementAbsoluteCoords)(element);\n const center = coordsCenter(x1, y1, x2, y2); // GA has angle orientation opposite to `rotate`\n\n const rotate = _gatransforms__WEBPACK_IMPORTED_MODULE_4__.rotation(center, element.angle);\n const pointRotated = _gatransforms__WEBPACK_IMPORTED_MODULE_4__.apply(rotate, point);\n const pointRelToCenter = _ga__WEBPACK_IMPORTED_MODULE_0__.sub(pointRotated, _gadirections__WEBPACK_IMPORTED_MODULE_2__.from(center));\n const pointRelToCenterAbs = _gapoints__WEBPACK_IMPORTED_MODULE_1__.abs(pointRelToCenter);\n const elementPos = _ga__WEBPACK_IMPORTED_MODULE_0__.offset(element.x, element.y);\n const pointRelToPos = _ga__WEBPACK_IMPORTED_MODULE_0__.sub(pointRotated, elementPos);\n const halfWidth = (x2 - x1) / 2;\n const halfHeight = (y2 - y1) / 2;\n return [pointRelToPos, pointRelToCenterAbs, halfWidth, halfHeight];\n};\n\nconst pointRelativeToDivElement = (pointTuple, rectangle) => {\n const point = _gapoints__WEBPACK_IMPORTED_MODULE_1__.from(pointTuple);\n const [x1, y1, x2, y2] = (0,_bounds__WEBPACK_IMPORTED_MODULE_7__.getRectangleBoxAbsoluteCoords)(rectangle);\n const center = coordsCenter(x1, y1, x2, y2);\n const rotate = _gatransforms__WEBPACK_IMPORTED_MODULE_4__.rotation(center, rectangle.angle);\n const pointRotated = _gatransforms__WEBPACK_IMPORTED_MODULE_4__.apply(rotate, point);\n const pointRelToCenter = _ga__WEBPACK_IMPORTED_MODULE_0__.sub(pointRotated, _gadirections__WEBPACK_IMPORTED_MODULE_2__.from(center));\n const pointRelToCenterAbs = _gapoints__WEBPACK_IMPORTED_MODULE_1__.abs(pointRelToCenter);\n const elementPos = _ga__WEBPACK_IMPORTED_MODULE_0__.offset(rectangle.x, rectangle.y);\n const pointRelToPos = _ga__WEBPACK_IMPORTED_MODULE_0__.sub(pointRotated, elementPos);\n const halfWidth = (x2 - x1) / 2;\n const halfHeight = (y2 - y1) / 2;\n return [pointRelToPos, pointRelToCenterAbs, halfWidth, halfHeight];\n}; // Returns point in absolute coordinates\n\n\nconst pointInAbsoluteCoords = (element, // Point relative to the element position\npoint) => {\n const [x, y] = point;\n const [x1, y1, x2, y2] = (0,_bounds__WEBPACK_IMPORTED_MODULE_7__.getElementAbsoluteCoords)(element);\n const cx = (x2 - x1) / 2;\n const cy = (y2 - y1) / 2;\n const [rotatedX, rotatedY] = (0,_math__WEBPACK_IMPORTED_MODULE_5__.rotate)(x, y, cx, cy, element.angle);\n return [element.x + rotatedX, element.y + rotatedY];\n};\n\nconst relativizationToElementCenter = element => {\n const [x1, y1, x2, y2] = (0,_bounds__WEBPACK_IMPORTED_MODULE_7__.getElementAbsoluteCoords)(element);\n const center = coordsCenter(x1, y1, x2, y2); // GA has angle orientation opposite to `rotate`\n\n const rotate = _gatransforms__WEBPACK_IMPORTED_MODULE_4__.rotation(center, element.angle);\n const translate = _ga__WEBPACK_IMPORTED_MODULE_0__.reverse(_gatransforms__WEBPACK_IMPORTED_MODULE_4__.translation(_gadirections__WEBPACK_IMPORTED_MODULE_2__.from(center)));\n return _gatransforms__WEBPACK_IMPORTED_MODULE_4__.compose(rotate, translate);\n};\n\nconst coordsCenter = (x1, y1, x2, y2) => {\n return _ga__WEBPACK_IMPORTED_MODULE_0__.point((x1 + x2) / 2, (y1 + y2) / 2);\n}; // The focus distance is the oriented ratio between the size of\n// the `element` and the \"focus image\" of the element on which\n// all focus points lie, so it's a number between -1 and 1.\n// The line going through `a` and `b` is a tangent to the \"focus image\"\n// of the element.\n\n\nconst determineFocusDistance = (element, // Point on the line, in absolute coordinates\na, // Another point on the line, in absolute coordinates (closer to element)\nb) => {\n const relateToCenter = relativizationToElementCenter(element);\n const aRel = _gatransforms__WEBPACK_IMPORTED_MODULE_4__.apply(relateToCenter, _gapoints__WEBPACK_IMPORTED_MODULE_1__.from(a));\n const bRel = _gatransforms__WEBPACK_IMPORTED_MODULE_4__.apply(relateToCenter, _gapoints__WEBPACK_IMPORTED_MODULE_1__.from(b));\n const line = _galines__WEBPACK_IMPORTED_MODULE_3__.through(aRel, bRel);\n const q = element.height / element.width;\n const hwidth = element.width / 2;\n const hheight = element.height / 2;\n const n = line[2];\n const m = line[3];\n const c = line[1];\n const mabs = Math.abs(m);\n const nabs = Math.abs(n);\n let ret;\n\n switch (element.type) {\n case \"rectangle\":\n case \"image\":\n case \"text\":\n case \"embeddable\":\n case \"frame\":\n ret = c / (hwidth * (nabs + q * mabs));\n break;\n\n case \"diamond\":\n ret = mabs < nabs ? c / (nabs * hwidth) : c / (mabs * hheight);\n break;\n\n case \"ellipse\":\n ret = c / (hwidth * Math.sqrt(n ** 2 + q ** 2 * m ** 2));\n break;\n }\n\n return ret || 0;\n};\nconst determineFocusPoint = (element, // The oriented, relative distance from the center of `element` of the\n// returned focusPoint\nfocus, adjecentPoint) => {\n if (focus === 0) {\n const [x1, y1, x2, y2] = (0,_bounds__WEBPACK_IMPORTED_MODULE_7__.getElementAbsoluteCoords)(element);\n const center = coordsCenter(x1, y1, x2, y2);\n return _gapoints__WEBPACK_IMPORTED_MODULE_1__.toTuple(center);\n }\n\n const relateToCenter = relativizationToElementCenter(element);\n const adjecentPointRel = _gatransforms__WEBPACK_IMPORTED_MODULE_4__.apply(relateToCenter, _gapoints__WEBPACK_IMPORTED_MODULE_1__.from(adjecentPoint));\n const reverseRelateToCenter = _ga__WEBPACK_IMPORTED_MODULE_0__.reverse(relateToCenter);\n let point;\n\n switch (element.type) {\n case \"rectangle\":\n case \"image\":\n case \"text\":\n case \"diamond\":\n case \"embeddable\":\n case \"frame\":\n point = findFocusPointForRectangulars(element, focus, adjecentPointRel);\n break;\n\n case \"ellipse\":\n point = findFocusPointForEllipse(element, focus, adjecentPointRel);\n break;\n }\n\n return _gapoints__WEBPACK_IMPORTED_MODULE_1__.toTuple(_gatransforms__WEBPACK_IMPORTED_MODULE_4__.apply(reverseRelateToCenter, point));\n}; // Returns 2 or 0 intersection points between line going through `a` and `b`\n// and the `element`, in ascending order of distance from `a`.\n\nconst intersectElementWithLine = (element, // Point on the line, in absolute coordinates\na, // Another point on the line, in absolute coordinates\nb, // If given, the element is inflated by this value\ngap = 0) => {\n const relateToCenter = relativizationToElementCenter(element);\n const aRel = _gatransforms__WEBPACK_IMPORTED_MODULE_4__.apply(relateToCenter, _gapoints__WEBPACK_IMPORTED_MODULE_1__.from(a));\n const bRel = _gatransforms__WEBPACK_IMPORTED_MODULE_4__.apply(relateToCenter, _gapoints__WEBPACK_IMPORTED_MODULE_1__.from(b));\n const line = _galines__WEBPACK_IMPORTED_MODULE_3__.through(aRel, bRel);\n const reverseRelateToCenter = _ga__WEBPACK_IMPORTED_MODULE_0__.reverse(relateToCenter);\n const intersections = getSortedElementLineIntersections(element, line, aRel, gap);\n return intersections.map(point => _gapoints__WEBPACK_IMPORTED_MODULE_1__.toTuple(_gatransforms__WEBPACK_IMPORTED_MODULE_4__.apply(reverseRelateToCenter, point)));\n};\n\nconst getSortedElementLineIntersections = (element, // Relative to element center\nline, // Relative to element center\nnearPoint, gap = 0) => {\n let intersections;\n\n switch (element.type) {\n case \"rectangle\":\n case \"image\":\n case \"text\":\n case \"diamond\":\n case \"embeddable\":\n case \"frame\":\n const corners = getCorners(element);\n intersections = corners.flatMap((point, i) => {\n const edge = [point, corners[(i + 1) % 4]];\n return intersectSegment(line, offsetSegment(edge, gap));\n }).concat(corners.flatMap(point => getCircleIntersections(point, gap, line)));\n break;\n\n case \"ellipse\":\n intersections = getEllipseIntersections(element, gap, line);\n break;\n }\n\n if (intersections.length < 2) {\n // Ignore the \"edge\" case of only intersecting with a single corner\n return [];\n }\n\n const sortedIntersections = intersections.sort((i1, i2) => _gapoints__WEBPACK_IMPORTED_MODULE_1__.distance(i1, nearPoint) - _gapoints__WEBPACK_IMPORTED_MODULE_1__.distance(i2, nearPoint));\n return [sortedIntersections[0], sortedIntersections[sortedIntersections.length - 1]];\n};\n\nconst getCorners = (element, scale = 1) => {\n const hx = scale * element.width / 2;\n const hy = scale * element.height / 2;\n\n switch (element.type) {\n case \"rectangle\":\n case \"image\":\n case \"text\":\n case \"embeddable\":\n case \"frame\":\n return [_ga__WEBPACK_IMPORTED_MODULE_0__.point(hx, hy), _ga__WEBPACK_IMPORTED_MODULE_0__.point(hx, -hy), _ga__WEBPACK_IMPORTED_MODULE_0__.point(-hx, -hy), _ga__WEBPACK_IMPORTED_MODULE_0__.point(-hx, hy)];\n\n case \"diamond\":\n return [_ga__WEBPACK_IMPORTED_MODULE_0__.point(0, hy), _ga__WEBPACK_IMPORTED_MODULE_0__.point(hx, 0), _ga__WEBPACK_IMPORTED_MODULE_0__.point(0, -hy), _ga__WEBPACK_IMPORTED_MODULE_0__.point(-hx, 0)];\n }\n}; // Returns intersection of `line` with `segment`, with `segment` moved by\n// `gap` in its polar direction.\n// If intersection coincides with second segment point returns empty array.\n\n\nconst intersectSegment = (line, segment) => {\n const [a, b] = segment;\n const aDist = _gapoints__WEBPACK_IMPORTED_MODULE_1__.distanceToLine(a, line);\n const bDist = _gapoints__WEBPACK_IMPORTED_MODULE_1__.distanceToLine(b, line);\n\n if (aDist * bDist >= 0) {\n // The intersection is outside segment `(a, b)`\n return [];\n }\n\n return [_gapoints__WEBPACK_IMPORTED_MODULE_1__.intersect(line, _galines__WEBPACK_IMPORTED_MODULE_3__.through(a, b))];\n};\n\nconst offsetSegment = (segment, distance) => {\n const [a, b] = segment;\n const offset = _gatransforms__WEBPACK_IMPORTED_MODULE_4__.translationOrthogonal(_gadirections__WEBPACK_IMPORTED_MODULE_2__.fromTo(a, b), distance);\n return [_gatransforms__WEBPACK_IMPORTED_MODULE_4__.apply(offset, a), _gatransforms__WEBPACK_IMPORTED_MODULE_4__.apply(offset, b)];\n};\n\nconst getEllipseIntersections = (element, gap, line) => {\n const a = element.width / 2 + gap;\n const b = element.height / 2 + gap;\n const m = line[2];\n const n = line[3];\n const c = line[1];\n const squares = a * a * m * m + b * b * n * n;\n const discr = squares - c * c;\n\n if (squares === 0 || discr <= 0) {\n return [];\n }\n\n const discrRoot = Math.sqrt(discr);\n const xn = -a * a * m * c;\n const yn = -b * b * n * c;\n return [_ga__WEBPACK_IMPORTED_MODULE_0__.point((xn + a * b * n * discrRoot) / squares, (yn - a * b * m * discrRoot) / squares), _ga__WEBPACK_IMPORTED_MODULE_0__.point((xn - a * b * n * discrRoot) / squares, (yn + a * b * m * discrRoot) / squares)];\n};\n\nconst getCircleIntersections = (center, radius, line) => {\n if (radius === 0) {\n return _gapoints__WEBPACK_IMPORTED_MODULE_1__.distanceToLine(line, center) === 0 ? [center] : [];\n }\n\n const m = line[2];\n const n = line[3];\n const c = line[1];\n const [a, b] = _gapoints__WEBPACK_IMPORTED_MODULE_1__.toTuple(center);\n const r = radius;\n const squares = m * m + n * n;\n const discr = r * r * squares - (m * a + n * b + c) ** 2;\n\n if (squares === 0 || discr <= 0) {\n return [];\n }\n\n const discrRoot = Math.sqrt(discr);\n const xn = a * n * n - b * m * n - m * c;\n const yn = b * m * m - a * m * n - n * c;\n return [_ga__WEBPACK_IMPORTED_MODULE_0__.point((xn + n * discrRoot) / squares, (yn - m * discrRoot) / squares), _ga__WEBPACK_IMPORTED_MODULE_0__.point((xn - n * discrRoot) / squares, (yn + m * discrRoot) / squares)];\n}; // The focus point is the tangent point of the \"focus image\" of the\n// `element`, where the tangent goes through `point`.\n\nconst findFocusPointForEllipse = (ellipse, // Between -1 and 1 (not 0) the relative size of the \"focus image\" of\n// the element on which the focus point lies\nrelativeDistance, // The point for which we're trying to find the focus point, relative\n// to the ellipse center.\npoint) => {\n const relativeDistanceAbs = Math.abs(relativeDistance);\n const a = ellipse.width * relativeDistanceAbs / 2;\n const b = ellipse.height * relativeDistanceAbs / 2;\n const orientation = Math.sign(relativeDistance);\n const [px, pyo] = _gapoints__WEBPACK_IMPORTED_MODULE_1__.toTuple(point); // The calculation below can't handle py = 0\n\n const py = pyo === 0 ? 0.0001 : pyo;\n const squares = px ** 2 * b ** 2 + py ** 2 * a ** 2; // Tangent mx + ny + 1 = 0\n\n const m = (-px * b ** 2 + orientation * py * Math.sqrt(Math.max(0, squares - a ** 2 * b ** 2))) / squares;\n let n = (-m * px - 1) / py;\n\n if (n === 0) {\n // if zero {-0, 0}, fall back to a same-sign value in the similar range\n n = (Object.is(n, -0) ? -1 : 1) * 0.01;\n }\n\n const x = -(a ** 2 * m) / (n ** 2 * b ** 2 + m ** 2 * a ** 2);\n return _ga__WEBPACK_IMPORTED_MODULE_0__.point(x, (-m * x - 1) / (n === 0 ? 0.0001 : n)); //zsviczian https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/1054\n};\nconst findFocusPointForRectangulars = (element, // Between -1 and 1 for how far away should the focus point be relative\n// to the size of the element. Sign determines orientation.\nrelativeDistance, // The point for which we're trying to find the focus point, relative\n// to the element center.\npoint) => {\n const relativeDistanceAbs = Math.abs(relativeDistance);\n const orientation = Math.sign(relativeDistance);\n const corners = getCorners(element, relativeDistanceAbs);\n let maxDistance = 0;\n let tangentPoint = null;\n corners.forEach(corner => {\n const distance = orientation * _galines__WEBPACK_IMPORTED_MODULE_3__.through(point, corner)[1];\n\n if (distance > maxDistance) {\n maxDistance = distance;\n tangentPoint = corner;\n }\n });\n return tangentPoint;\n};\n\nconst pointInBezierEquation = (p0, p1, p2, p3, [mx, my], lineThreshold) => {\n // B(t) = p0 * (1-t)^3 + 3p1 * t * (1-t)^2 + 3p2 * t^2 * (1-t) + p3 * t^3\n const equation = (t, idx) => Math.pow(1 - t, 3) * p3[idx] + 3 * t * Math.pow(1 - t, 2) * p2[idx] + 3 * Math.pow(t, 2) * (1 - t) * p1[idx] + p0[idx] * Math.pow(t, 3); // go through t in increments of 0.01\n\n\n let t = 0;\n\n while (t <= 1.0) {\n const tx = equation(t, 0);\n const ty = equation(t, 1);\n const diff = Math.sqrt(Math.pow(tx - mx, 2) + Math.pow(ty - my, 2));\n\n if (diff < lineThreshold) {\n return true;\n }\n\n t += 0.01;\n }\n\n return false;\n};\n\nconst hitTestCurveInside = (drawable, x, y, roundness) => {\n const ops = (0,_bounds__WEBPACK_IMPORTED_MODULE_7__.getCurvePathOps)(drawable);\n const points = [];\n let odd = false; // select one line out of double lines\n\n for (const operation of ops) {\n if (operation.op === \"move\") {\n odd = !odd;\n\n if (odd) {\n points.push([operation.data[0], operation.data[1]]);\n }\n } else if (operation.op === \"bcurveTo\") {\n if (odd) {\n points.push([operation.data[0], operation.data[1]]);\n points.push([operation.data[2], operation.data[3]]);\n points.push([operation.data[4], operation.data[5]]);\n }\n } else if (operation.op === \"lineTo\") {\n if (odd) {\n points.push([operation.data[0], operation.data[1]]);\n }\n }\n }\n\n if (points.length >= 4) {\n if (roundness === \"sharp\") {\n return (0,_math__WEBPACK_IMPORTED_MODULE_5__.isPointInPolygon)(points, x, y);\n }\n\n const polygonPoints = (0,points_on_curve__WEBPACK_IMPORTED_MODULE_6__.pointsOnBezierCurves)(points, 10, 5);\n return (0,_math__WEBPACK_IMPORTED_MODULE_5__.isPointInPolygon)(polygonPoints, x, y);\n }\n\n return false;\n};\n\nconst hitTestRoughShape = (drawable, x, y, lineThreshold) => {\n // read operations from first opSet\n const ops = (0,_bounds__WEBPACK_IMPORTED_MODULE_7__.getCurvePathOps)(drawable); // set start position as (0,0) just in case\n // move operation does not exist (unlikely but it is worth safekeeping it)\n\n let currentP = [0, 0];\n return ops.some(({\n op,\n data\n }, idx) => {\n // There are only four operation types:\n // move, bcurveTo, lineTo, and curveTo\n if (op === \"move\") {\n // change starting point\n currentP = data; // move operation does not draw anything; so, it always\n // returns false\n } else if (op === \"bcurveTo\") {\n // create points from bezier curve\n // bezier curve stores data as a flattened array of three positions\n // [x1, y1, x2, y2, x3, y3]\n const p1 = [data[0], data[1]];\n const p2 = [data[2], data[3]];\n const p3 = [data[4], data[5]];\n const p0 = currentP;\n currentP = p3; // check if points are on the curve\n // cubic bezier curves require four parameters\n // the first parameter is the last stored position (p0)\n\n const retVal = pointInBezierEquation(p0, p1, p2, p3, [x, y], lineThreshold); // set end point of bezier curve as the new starting point for\n // upcoming operations as each operation is based on the last drawn\n // position of the previous operation\n\n return retVal;\n } else if (op === \"lineTo\") {\n return hitTestCurveInside(drawable, x, y, \"sharp\");\n } else if (op === \"qcurveTo\") {\n // TODO: Implement this\n console.warn(\"qcurveTo is not implemented yet\");\n }\n\n return false;\n });\n};\n\n//# sourceURL=webpack://ExcalidrawLib/../../element/collision.ts?");
3682
3682
 
3683
3683
  /***/ }),
3684
3684
 
@@ -3887,7 +3887,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
3887
3887
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3888
3888
 
3889
3889
  "use strict";
3890
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"addElementsToFrame\": () => (/* binding */ addElementsToFrame),\n/* harmony export */ \"bindElementsToFramesAfterDuplication\": () => (/* binding */ bindElementsToFramesAfterDuplication),\n/* harmony export */ \"elementOverlapsWithFrame\": () => (/* binding */ elementOverlapsWithFrame),\n/* harmony export */ \"elementsAreInFrameBounds\": () => (/* binding */ elementsAreInFrameBounds),\n/* harmony export */ \"getContainingFrame\": () => (/* binding */ getContainingFrame),\n/* harmony export */ \"getElementsCompletelyInFrame\": () => (/* binding */ getElementsCompletelyInFrame),\n/* harmony export */ \"getElementsInNewFrame\": () => (/* binding */ getElementsInNewFrame),\n/* harmony export */ \"getElementsInResizingFrame\": () => (/* binding */ getElementsInResizingFrame),\n/* harmony export */ \"getElementsIntersectingFrame\": () => (/* binding */ getElementsIntersectingFrame),\n/* harmony export */ \"getFrameElements\": () => (/* binding */ getFrameElements),\n/* harmony export */ \"getTargetFrame\": () => (/* binding */ getTargetFrame),\n/* harmony export */ \"groupByFrames\": () => (/* binding */ groupByFrames),\n/* harmony export */ \"groupsAreAtLeastIntersectingTheFrame\": () => (/* binding */ groupsAreAtLeastIntersectingTheFrame),\n/* harmony export */ \"groupsAreCompletelyOutOfFrame\": () => (/* binding */ groupsAreCompletelyOutOfFrame),\n/* harmony export */ \"isCursorInFrame\": () => (/* binding */ isCursorInFrame),\n/* harmony export */ \"isElementContainingFrame\": () => (/* binding */ isElementContainingFrame),\n/* harmony export */ \"isElementInFrame\": () => (/* binding */ isElementInFrame),\n/* harmony export */ \"isValidFrameChild\": () => (/* binding */ isValidFrameChild),\n/* harmony export */ \"omitGroupsContainingFrames\": () => (/* binding */ omitGroupsContainingFrames),\n/* harmony export */ \"removeAllElementsFromFrame\": () => (/* binding */ removeAllElementsFromFrame),\n/* harmony export */ \"removeElementsFromFrame\": () => (/* binding */ removeElementsFromFrame),\n/* harmony export */ \"replaceAllElementsInFrame\": () => (/* binding */ replaceAllElementsInFrame),\n/* harmony export */ \"updateFrameMembershipOfSelectedElements\": () => (/* binding */ updateFrameMembershipOfSelectedElements)\n/* harmony export */ });\n/* harmony import */ var _element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./element */ \"../../element/index.ts\");\n/* harmony import */ var _math__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./math */ \"../../math.ts\");\n/* harmony import */ var _element_textElement__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./element/textElement */ \"../../element/textElement.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./utils */ \"../../utils.ts\");\n/* harmony import */ var _element_mutateElement__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./element/mutateElement */ \"../../element/mutateElement.ts\");\n/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./scene */ \"../../scene/index.ts\");\n/* harmony import */ var _zindex__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./zindex */ \"../../zindex.ts\");\n/* harmony import */ var _groups__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./groups */ \"../../groups.ts\");\n/* harmony import */ var _scene_Scene__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./scene/Scene */ \"../../scene/Scene.ts\");\n/* harmony import */ var _element_bounds__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./element/bounds */ \"../../element/bounds.ts\");\n\n\n\n\n\n\n\n\n\n\n // --------------------------- Frame State ------------------------------------\n\nconst bindElementsToFramesAfterDuplication = (nextElements, oldElements, oldIdToDuplicatedId) => {\n const nextElementMap = (0,_utils__WEBPACK_IMPORTED_MODULE_3__.arrayToMap)(nextElements);\n\n for (const element of oldElements) {\n if (element.frameId) {\n // use its frameId to get the new frameId\n const nextElementId = oldIdToDuplicatedId.get(element.id);\n const nextFrameId = oldIdToDuplicatedId.get(element.frameId);\n\n if (nextElementId) {\n const nextElement = nextElementMap.get(nextElementId);\n\n if (nextElement) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_4__.mutateElement)(nextElement, {\n frameId: nextFrameId !== null && nextFrameId !== void 0 ? nextFrameId : element.frameId\n }, false);\n }\n }\n }\n }\n}; // --------------------------- Frame Geometry ---------------------------------\n\nclass Point {\n constructor(x, y) {\n this.x = x;\n this.y = y;\n }\n\n}\n\nclass LineSegment {\n constructor(pointA, pointB) {\n this.first = pointA;\n this.second = pointB;\n }\n\n getBoundingBox() {\n return [new Point(Math.min(this.first.x, this.second.x), Math.min(this.first.y, this.second.y)), new Point(Math.max(this.first.x, this.second.x), Math.max(this.first.y, this.second.y))];\n }\n\n} // https://martin-thoma.com/how-to-check-if-two-line-segments-intersect/\n\n\nclass FrameGeometry {\n static crossProduct(a, b) {\n return a.x * b.y - b.x * a.y;\n }\n\n static doBoundingBoxesIntersect(a, b) {\n return a[0].x <= b[1].x && a[1].x >= b[0].x && a[0].y <= b[1].y && a[1].y >= b[0].y;\n }\n\n static isPointOnLine(a, b) {\n const aTmp = new LineSegment(new Point(0, 0), new Point(a.second.x - a.first.x, a.second.y - a.first.y));\n const bTmp = new Point(b.x - a.first.x, b.y - a.first.y);\n const r = this.crossProduct(aTmp.second, bTmp);\n return Math.abs(r) < this.EPSILON;\n }\n\n static isPointRightOfLine(a, b) {\n const aTmp = new LineSegment(new Point(0, 0), new Point(a.second.x - a.first.x, a.second.y - a.first.y));\n const bTmp = new Point(b.x - a.first.x, b.y - a.first.y);\n return this.crossProduct(aTmp.second, bTmp) < 0;\n }\n\n static lineSegmentTouchesOrCrossesLine(a, b) {\n return this.isPointOnLine(a, b.first) || this.isPointOnLine(a, b.second) || (this.isPointRightOfLine(a, b.first) ? !this.isPointRightOfLine(a, b.second) : this.isPointRightOfLine(a, b.second));\n }\n\n static doLineSegmentsIntersect(a, b) {\n const aSegment = new LineSegment(new Point(a[0][0], a[0][1]), new Point(a[1][0], a[1][1]));\n const bSegment = new LineSegment(new Point(b[0][0], b[0][1]), new Point(b[1][0], b[1][1]));\n const box1 = aSegment.getBoundingBox();\n const box2 = bSegment.getBoundingBox();\n return this.doBoundingBoxesIntersect(box1, box2) && this.lineSegmentTouchesOrCrossesLine(aSegment, bSegment) && this.lineSegmentTouchesOrCrossesLine(bSegment, aSegment);\n }\n\n static isElementIntersectingFrame(element, frame) {\n const frameLineSegments = (0,_element_bounds__WEBPACK_IMPORTED_MODULE_9__.getElementLineSegments)(frame);\n const elementLineSegments = (0,_element_bounds__WEBPACK_IMPORTED_MODULE_9__.getElementLineSegments)(element);\n const intersecting = frameLineSegments.some(frameLineSegment => elementLineSegments.some(elementLineSegment => this.doLineSegmentsIntersect(frameLineSegment, elementLineSegment)));\n return intersecting;\n }\n\n}\n\nFrameGeometry.EPSILON = 0.000001;\nconst getElementsCompletelyInFrame = (elements, frame) => omitGroupsContainingFrames((0,_scene__WEBPACK_IMPORTED_MODULE_5__.getElementsWithinSelection)(elements, frame, false)).filter(element => element.type !== \"frame\" && !element.frameId || element.frameId === frame.id);\nconst isElementContainingFrame = (elements, element, frame) => {\n return (0,_scene__WEBPACK_IMPORTED_MODULE_5__.getElementsWithinSelection)(elements, element).some(e => e.id === frame.id);\n};\nconst getElementsIntersectingFrame = (elements, frame) => elements.filter(element => FrameGeometry.isElementIntersectingFrame(element, frame));\nconst elementsAreInFrameBounds = (elements, frame) => {\n const [selectionX1, selectionY1, selectionX2, selectionY2] = (0,_element__WEBPACK_IMPORTED_MODULE_0__.getElementAbsoluteCoords)(frame);\n const [elementX1, elementY1, elementX2, elementY2] = (0,_element__WEBPACK_IMPORTED_MODULE_0__.getCommonBounds)(elements);\n return selectionX1 <= elementX1 && selectionY1 <= elementY1 && selectionX2 >= elementX2 && selectionY2 >= elementY2;\n};\nconst elementOverlapsWithFrame = (element, frame) => {\n return elementsAreInFrameBounds([element], frame) || FrameGeometry.isElementIntersectingFrame(element, frame) || isElementContainingFrame([frame], element, frame);\n};\nconst isCursorInFrame = (cursorCoords, frame) => {\n const [fx1, fy1, fx2, fy2] = (0,_element__WEBPACK_IMPORTED_MODULE_0__.getElementAbsoluteCoords)(frame);\n return (0,_math__WEBPACK_IMPORTED_MODULE_1__.isPointWithinBounds)([fx1, fy1], [cursorCoords.x, cursorCoords.y], [fx2, fy2]);\n};\nconst groupsAreAtLeastIntersectingTheFrame = (elements, groupIds, frame) => {\n const elementsInGroup = groupIds.flatMap(groupId => (0,_groups__WEBPACK_IMPORTED_MODULE_7__.getElementsInGroup)(elements, groupId));\n\n if (elementsInGroup.length === 0) {\n return true;\n }\n\n return !!elementsInGroup.find(element => elementsAreInFrameBounds([element], frame) || FrameGeometry.isElementIntersectingFrame(element, frame));\n};\nconst groupsAreCompletelyOutOfFrame = (elements, groupIds, frame) => {\n const elementsInGroup = groupIds.flatMap(groupId => (0,_groups__WEBPACK_IMPORTED_MODULE_7__.getElementsInGroup)(elements, groupId));\n\n if (elementsInGroup.length === 0) {\n return true;\n }\n\n return elementsInGroup.find(element => elementsAreInFrameBounds([element], frame) || FrameGeometry.isElementIntersectingFrame(element, frame)) === undefined;\n}; // --------------------------- Frame Utils ------------------------------------\n\n/**\r\n * Returns a map of frameId to frame elements. Includes empty frames.\r\n */\n\nconst groupByFrames = elements => {\n const frameElementsMap = new Map();\n\n for (const element of elements) {\n const frameId = (0,_element__WEBPACK_IMPORTED_MODULE_0__.isFrameElement)(element) ? element.id : element.frameId;\n\n if (frameId && !frameElementsMap.has(frameId)) {\n frameElementsMap.set(frameId, getFrameElements(elements, frameId));\n }\n }\n\n return frameElementsMap;\n};\nconst getFrameElements = (allElements, frameId, opts) => {\n return allElements.filter(element => {\n var _a, _b;\n\n if (element.frameId === frameId) {\n return true;\n }\n\n if ((opts === null || opts === void 0 ? void 0 : opts.includeBoundArrows) && element.type === \"arrow\") {\n const bindingId = (_a = element.startBinding) === null || _a === void 0 ? void 0 : _a.elementId;\n\n if (bindingId) {\n const boundElement = (_b = _scene_Scene__WEBPACK_IMPORTED_MODULE_8__[\"default\"].getScene(element)) === null || _b === void 0 ? void 0 : _b.getElement(bindingId);\n\n if ((boundElement === null || boundElement === void 0 ? void 0 : boundElement.frameId) === frameId) {\n return true;\n }\n }\n }\n\n return false;\n });\n};\nconst getElementsInResizingFrame = (allElements, frame, appState) => {\n const prevElementsInFrame = getFrameElements(allElements, frame.id);\n const nextElementsInFrame = new Set(prevElementsInFrame);\n const elementsCompletelyInFrame = new Set([...getElementsCompletelyInFrame(allElements, frame), ...prevElementsInFrame.filter(element => isElementContainingFrame(allElements, element, frame))]);\n const elementsNotCompletelyInFrame = prevElementsInFrame.filter(element => !elementsCompletelyInFrame.has(element)); // for elements that are completely in the frame\n // if they are part of some groups, then those groups are still\n // considered to belong to the frame\n\n const groupsToKeep = new Set(Array.from(elementsCompletelyInFrame).flatMap(element => element.groupIds));\n\n for (const element of elementsNotCompletelyInFrame) {\n if (!FrameGeometry.isElementIntersectingFrame(element, frame)) {\n if (element.groupIds.length === 0) {\n nextElementsInFrame.delete(element);\n }\n } else if (element.groupIds.length > 0) {\n // group element intersects with the frame, we should keep the groups\n // that this element is part of\n for (const id of element.groupIds) {\n groupsToKeep.add(id);\n }\n }\n }\n\n for (const element of elementsNotCompletelyInFrame) {\n if (element.groupIds.length > 0) {\n let shouldRemoveElement = true;\n\n for (const id of element.groupIds) {\n if (groupsToKeep.has(id)) {\n shouldRemoveElement = false;\n }\n }\n\n if (shouldRemoveElement) {\n nextElementsInFrame.delete(element);\n }\n }\n }\n\n const individualElementsCompletelyInFrame = Array.from(elementsCompletelyInFrame).filter(element => element.groupIds.length === 0);\n\n for (const element of individualElementsCompletelyInFrame) {\n nextElementsInFrame.add(element);\n }\n\n const newGroupElementsCompletelyInFrame = Array.from(elementsCompletelyInFrame).filter(element => element.groupIds.length > 0);\n const groupIds = (0,_groups__WEBPACK_IMPORTED_MODULE_7__.selectGroupsFromGivenElements)(newGroupElementsCompletelyInFrame, appState); // new group elements\n\n for (const [id, isSelected] of Object.entries(groupIds)) {\n if (isSelected) {\n const elementsInGroup = (0,_groups__WEBPACK_IMPORTED_MODULE_7__.getElementsInGroup)(allElements, id);\n\n if (elementsAreInFrameBounds(elementsInGroup, frame)) {\n for (const element of elementsInGroup) {\n nextElementsInFrame.add(element);\n }\n }\n }\n }\n\n return [...nextElementsInFrame].filter(element => {\n return !((0,_element__WEBPACK_IMPORTED_MODULE_0__.isTextElement)(element) && element.containerId);\n });\n};\nconst getElementsInNewFrame = (allElements, frame) => {\n return omitGroupsContainingFrames(allElements, getElementsCompletelyInFrame(allElements, frame));\n};\nconst getContainingFrame = (element,\n/**\r\n * Optionally an elements map, in case the elements aren't in the Scene yet.\r\n * Takes precedence over Scene elements, even if the element exists\r\n * in Scene elements and not the supplied elements map.\r\n */\nelementsMap) => {\n var _a;\n\n if (element.frameId) {\n if (elementsMap) {\n return elementsMap.get(element.frameId) || null;\n }\n\n return ((_a = _scene_Scene__WEBPACK_IMPORTED_MODULE_8__[\"default\"].getScene(element)) === null || _a === void 0 ? void 0 : _a.getElement(element.frameId)) || null;\n }\n\n return null;\n};\nconst isValidFrameChild = element => {\n return element.type !== \"frame\" && ( // arrows that are bound to elements cannot be frame children\n element.type !== \"arrow\" || !element.startBinding && !element.endBinding);\n}; // --------------------------- Frame Operations -------------------------------\n\n/**\r\n * Retains (or repairs for target frame) the ordering invriant where children\r\n * elements come right before the parent frame:\r\n * [el, el, child, child, frame, el]\r\n */\n\nconst addElementsToFrame = (allElements, elementsToAdd, frame) => {\n var _a;\n\n const {\n allElementsIndexMap,\n currTargetFrameChildrenMap\n } = allElements.reduce((acc, element, index) => {\n acc.allElementsIndexMap.set(element.id, index);\n\n if (element.frameId === frame.id) {\n acc.currTargetFrameChildrenMap.set(element.id, true);\n }\n\n return acc;\n }, {\n allElementsIndexMap: new Map(),\n currTargetFrameChildrenMap: new Map()\n });\n const suppliedElementsToAddSet = new Set(elementsToAdd.map(el => el.id));\n const finalElementsToAdd = []; // - add bound text elements if not already in the array\n // - filter out elements that are already in the frame\n\n for (const element of omitGroupsContainingFrames(allElements, elementsToAdd)) {\n if (!currTargetFrameChildrenMap.has(element.id)) {\n if (!isValidFrameChild(element)) {\n continue;\n }\n\n finalElementsToAdd.push(element);\n }\n\n const boundTextElement = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_2__.getBoundTextElement)(element);\n\n if (boundTextElement && !suppliedElementsToAddSet.has(boundTextElement.id) && !currTargetFrameChildrenMap.has(boundTextElement.id)) {\n finalElementsToAdd.push(boundTextElement);\n }\n }\n\n const finalElementsToAddSet = new Set(finalElementsToAdd.map(el => el.id));\n const nextElements = [];\n const processedElements = new Set();\n\n for (const element of allElements) {\n if (processedElements.has(element.id)) {\n continue;\n }\n\n processedElements.add(element.id);\n\n if (finalElementsToAddSet.has(element.id) || element.frameId && element.frameId === frame.id) {\n // will be added in bulk once we process target frame\n continue;\n } // target frame\n\n\n if (element.id === frame.id) {\n const currFrameChildren = getFrameElements(allElements, frame.id);\n currFrameChildren.forEach(child => {\n processedElements.add(child.id);\n }); // if not found, add all children on top by assigning the lowest index\n\n const targetFrameIndex = (_a = allElementsIndexMap.get(frame.id)) !== null && _a !== void 0 ? _a : -1;\n const {\n newChildren_left,\n newChildren_right\n } = finalElementsToAdd.reduce((acc, element) => {\n var _a; // if index not found, add on top of current frame children\n\n\n const elementIndex = (_a = allElementsIndexMap.get(element.id)) !== null && _a !== void 0 ? _a : Infinity;\n\n if (elementIndex < targetFrameIndex) {\n acc.newChildren_left.push(element);\n } else {\n acc.newChildren_right.push(element);\n }\n\n return acc;\n }, {\n newChildren_left: [],\n newChildren_right: []\n });\n nextElements.push(...newChildren_left, ...currFrameChildren, ...newChildren_right, element);\n continue;\n }\n\n nextElements.push(element);\n }\n\n for (const element of finalElementsToAdd) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_4__.mutateElement)(element, {\n frameId: frame.id\n }, false);\n }\n\n return nextElements;\n};\nconst removeElementsFromFrame = (allElements, elementsToRemove, appState) => {\n const _elementsToRemove = [];\n\n for (const element of elementsToRemove) {\n if (element.frameId) {\n _elementsToRemove.push(element);\n\n const boundTextElement = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_2__.getBoundTextElement)(element);\n\n if (boundTextElement) {\n _elementsToRemove.push(boundTextElement);\n }\n }\n }\n\n for (const element of _elementsToRemove) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_4__.mutateElement)(element, {\n frameId: null\n }, false);\n }\n\n const nextElements = (0,_zindex__WEBPACK_IMPORTED_MODULE_6__.moveOneRight)(allElements, appState, Array.from(_elementsToRemove));\n return nextElements;\n};\nconst removeAllElementsFromFrame = (allElements, frame, appState) => {\n const elementsInFrame = getFrameElements(allElements, frame.id);\n return removeElementsFromFrame(allElements, elementsInFrame, appState);\n};\nconst replaceAllElementsInFrame = (allElements, nextElementsInFrame, frame, appState) => {\n return addElementsToFrame(removeAllElementsFromFrame(allElements, frame, appState), nextElementsInFrame, frame);\n};\n/** does not mutate elements, but returns new ones */\n\nconst updateFrameMembershipOfSelectedElements = (allElements, appState, app) => {\n const selectedElements = app.scene.getSelectedElements({\n selectedElementIds: appState.selectedElementIds,\n // supplying elements explicitly in case we're passed non-state elements\n elements: allElements\n });\n const elementsToFilter = new Set(selectedElements);\n\n if (appState.editingGroupId) {\n for (const element of selectedElements) {\n if (element.groupIds.length === 0) {\n elementsToFilter.add(element);\n } else {\n element.groupIds.flatMap(gid => (0,_groups__WEBPACK_IMPORTED_MODULE_7__.getElementsInGroup)(allElements, gid)).forEach(element => elementsToFilter.add(element));\n }\n }\n }\n\n const elementsToRemove = new Set();\n elementsToFilter.forEach(element => {\n if (element.frameId && !(0,_element__WEBPACK_IMPORTED_MODULE_0__.isFrameElement)(element) && !isElementInFrame(element, allElements, appState)) {\n elementsToRemove.add(element);\n }\n });\n return elementsToRemove.size > 0 ? removeElementsFromFrame(allElements, [...elementsToRemove], appState) : allElements;\n};\n/**\r\n * filters out elements that are inside groups that contain a frame element\r\n * anywhere in the group tree\r\n */\n\nconst omitGroupsContainingFrames = (allElements,\n/** subset of elements you want to filter. Optional perf optimization so we\r\n * don't have to filter all elements unnecessarily\r\n */\nselectedElements) => {\n const uniqueGroupIds = new Set();\n\n for (const el of selectedElements || allElements) {\n const topMostGroupId = el.groupIds[el.groupIds.length - 1];\n\n if (topMostGroupId) {\n uniqueGroupIds.add(topMostGroupId);\n }\n }\n\n const rejectedGroupIds = new Set();\n\n for (const groupId of uniqueGroupIds) {\n if ((0,_groups__WEBPACK_IMPORTED_MODULE_7__.getElementsInGroup)(allElements, groupId).some(el => (0,_element__WEBPACK_IMPORTED_MODULE_0__.isFrameElement)(el))) {\n rejectedGroupIds.add(groupId);\n }\n }\n\n return (selectedElements || allElements).filter(el => !rejectedGroupIds.has(el.groupIds[el.groupIds.length - 1]));\n};\n/**\r\n * depending on the appState, return target frame, which is the frame the given element\r\n * is going to be added to or remove from\r\n */\n\nconst getTargetFrame = (element, appState) => {\n const _element = (0,_element__WEBPACK_IMPORTED_MODULE_0__.isTextElement)(element) ? (0,_element_textElement__WEBPACK_IMPORTED_MODULE_2__.getContainerElement)(element) || element : element;\n\n return appState.selectedElementIds[_element.id] && appState.selectedElementsAreBeingDragged ? appState.frameToHighlight : getContainingFrame(_element);\n}; // TODO: this a huge bottleneck for large scenes, optimise\n// given an element, return if the element is in some frame\n\nconst isElementInFrame = (element, allElements, appState) => {\n const frame = getTargetFrame(element, appState);\n\n const _element = (0,_element__WEBPACK_IMPORTED_MODULE_0__.isTextElement)(element) ? (0,_element_textElement__WEBPACK_IMPORTED_MODULE_2__.getContainerElement)(element) || element : element;\n\n if (frame) {\n // Perf improvement:\n // For an element that's already in a frame, if it's not being dragged\n // then there is no need to refer to geometry (which, yes, is slow) to check if it's in a frame.\n // It has to be in its containing frame.\n if (!appState.selectedElementIds[element.id] || !appState.selectedElementsAreBeingDragged) {\n return true;\n }\n\n if (_element.groupIds.length === 0) {\n return elementOverlapsWithFrame(_element, frame);\n }\n\n const allElementsInGroup = new Set(_element.groupIds.flatMap(gid => (0,_groups__WEBPACK_IMPORTED_MODULE_7__.getElementsInGroup)(allElements, gid)));\n\n if (appState.editingGroupId && appState.selectedElementsAreBeingDragged) {\n const selectedElements = new Set((0,_scene__WEBPACK_IMPORTED_MODULE_5__.getSelectedElements)(allElements, appState));\n const editingGroupOverlapsFrame = appState.frameToHighlight !== null;\n\n if (editingGroupOverlapsFrame) {\n return true;\n }\n\n selectedElements.forEach(selectedElement => {\n allElementsInGroup.delete(selectedElement);\n });\n }\n\n for (const elementInGroup of allElementsInGroup) {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_0__.isFrameElement)(elementInGroup)) {\n return false;\n }\n }\n\n for (const elementInGroup of allElementsInGroup) {\n if (elementOverlapsWithFrame(elementInGroup, frame)) {\n return true;\n }\n }\n }\n\n return false;\n};\n\n//# sourceURL=webpack://ExcalidrawLib/../../frame.ts?");
3890
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"addElementsToFrame\": () => (/* binding */ addElementsToFrame),\n/* harmony export */ \"bindElementsToFramesAfterDuplication\": () => (/* binding */ bindElementsToFramesAfterDuplication),\n/* harmony export */ \"elementOverlapsWithFrame\": () => (/* binding */ elementOverlapsWithFrame),\n/* harmony export */ \"elementsAreInFrameBounds\": () => (/* binding */ elementsAreInFrameBounds),\n/* harmony export */ \"getContainingFrame\": () => (/* binding */ getContainingFrame),\n/* harmony export */ \"getElementsCompletelyInFrame\": () => (/* binding */ getElementsCompletelyInFrame),\n/* harmony export */ \"getElementsInNewFrame\": () => (/* binding */ getElementsInNewFrame),\n/* harmony export */ \"getElementsInResizingFrame\": () => (/* binding */ getElementsInResizingFrame),\n/* harmony export */ \"getElementsIntersectingFrame\": () => (/* binding */ getElementsIntersectingFrame),\n/* harmony export */ \"getFrameElements\": () => (/* binding */ getFrameElements),\n/* harmony export */ \"getTargetFrame\": () => (/* binding */ getTargetFrame),\n/* harmony export */ \"groupByFrames\": () => (/* binding */ groupByFrames),\n/* harmony export */ \"groupsAreAtLeastIntersectingTheFrame\": () => (/* binding */ groupsAreAtLeastIntersectingTheFrame),\n/* harmony export */ \"groupsAreCompletelyOutOfFrame\": () => (/* binding */ groupsAreCompletelyOutOfFrame),\n/* harmony export */ \"isCursorInFrame\": () => (/* binding */ isCursorInFrame),\n/* harmony export */ \"isElementContainingFrame\": () => (/* binding */ isElementContainingFrame),\n/* harmony export */ \"isElementInFrame\": () => (/* binding */ isElementInFrame),\n/* harmony export */ \"omitGroupsContainingFrames\": () => (/* binding */ omitGroupsContainingFrames),\n/* harmony export */ \"removeAllElementsFromFrame\": () => (/* binding */ removeAllElementsFromFrame),\n/* harmony export */ \"removeElementsFromFrame\": () => (/* binding */ removeElementsFromFrame),\n/* harmony export */ \"replaceAllElementsInFrame\": () => (/* binding */ replaceAllElementsInFrame),\n/* harmony export */ \"updateFrameMembershipOfSelectedElements\": () => (/* binding */ updateFrameMembershipOfSelectedElements)\n/* harmony export */ });\n/* harmony import */ var _element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./element */ \"../../element/index.ts\");\n/* harmony import */ var _math__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./math */ \"../../math.ts\");\n/* harmony import */ var _element_textElement__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./element/textElement */ \"../../element/textElement.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./utils */ \"../../utils.ts\");\n/* harmony import */ var _element_mutateElement__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./element/mutateElement */ \"../../element/mutateElement.ts\");\n/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./scene */ \"../../scene/index.ts\");\n/* harmony import */ var _zindex__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./zindex */ \"../../zindex.ts\");\n/* harmony import */ var _groups__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./groups */ \"../../groups.ts\");\n/* harmony import */ var _scene_Scene__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./scene/Scene */ \"../../scene/Scene.ts\");\n/* harmony import */ var _element_bounds__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./element/bounds */ \"../../element/bounds.ts\");\n\n\n\n\n\n\n\n\n\n\n // --------------------------- Frame State ------------------------------------\n\nconst bindElementsToFramesAfterDuplication = (nextElements, oldElements, oldIdToDuplicatedId) => {\n const nextElementMap = (0,_utils__WEBPACK_IMPORTED_MODULE_3__.arrayToMap)(nextElements);\n\n for (const element of oldElements) {\n if (element.frameId) {\n // use its frameId to get the new frameId\n const nextElementId = oldIdToDuplicatedId.get(element.id);\n const nextFrameId = oldIdToDuplicatedId.get(element.frameId);\n\n if (nextElementId) {\n const nextElement = nextElementMap.get(nextElementId);\n\n if (nextElement) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_4__.mutateElement)(nextElement, {\n frameId: nextFrameId !== null && nextFrameId !== void 0 ? nextFrameId : element.frameId\n }, false);\n }\n }\n }\n }\n}; // --------------------------- Frame Geometry ---------------------------------\n\nclass Point {\n constructor(x, y) {\n this.x = x;\n this.y = y;\n }\n\n}\n\nclass LineSegment {\n constructor(pointA, pointB) {\n this.first = pointA;\n this.second = pointB;\n }\n\n getBoundingBox() {\n return [new Point(Math.min(this.first.x, this.second.x), Math.min(this.first.y, this.second.y)), new Point(Math.max(this.first.x, this.second.x), Math.max(this.first.y, this.second.y))];\n }\n\n} // https://martin-thoma.com/how-to-check-if-two-line-segments-intersect/\n\n\nclass FrameGeometry {\n static crossProduct(a, b) {\n return a.x * b.y - b.x * a.y;\n }\n\n static doBoundingBoxesIntersect(a, b) {\n return a[0].x <= b[1].x && a[1].x >= b[0].x && a[0].y <= b[1].y && a[1].y >= b[0].y;\n }\n\n static isPointOnLine(a, b) {\n const aTmp = new LineSegment(new Point(0, 0), new Point(a.second.x - a.first.x, a.second.y - a.first.y));\n const bTmp = new Point(b.x - a.first.x, b.y - a.first.y);\n const r = this.crossProduct(aTmp.second, bTmp);\n return Math.abs(r) < this.EPSILON;\n }\n\n static isPointRightOfLine(a, b) {\n const aTmp = new LineSegment(new Point(0, 0), new Point(a.second.x - a.first.x, a.second.y - a.first.y));\n const bTmp = new Point(b.x - a.first.x, b.y - a.first.y);\n return this.crossProduct(aTmp.second, bTmp) < 0;\n }\n\n static lineSegmentTouchesOrCrossesLine(a, b) {\n return this.isPointOnLine(a, b.first) || this.isPointOnLine(a, b.second) || (this.isPointRightOfLine(a, b.first) ? !this.isPointRightOfLine(a, b.second) : this.isPointRightOfLine(a, b.second));\n }\n\n static doLineSegmentsIntersect(a, b) {\n const aSegment = new LineSegment(new Point(a[0][0], a[0][1]), new Point(a[1][0], a[1][1]));\n const bSegment = new LineSegment(new Point(b[0][0], b[0][1]), new Point(b[1][0], b[1][1]));\n const box1 = aSegment.getBoundingBox();\n const box2 = bSegment.getBoundingBox();\n return this.doBoundingBoxesIntersect(box1, box2) && this.lineSegmentTouchesOrCrossesLine(aSegment, bSegment) && this.lineSegmentTouchesOrCrossesLine(bSegment, aSegment);\n }\n\n static isElementIntersectingFrame(element, frame) {\n const frameLineSegments = (0,_element_bounds__WEBPACK_IMPORTED_MODULE_9__.getElementLineSegments)(frame);\n const elementLineSegments = (0,_element_bounds__WEBPACK_IMPORTED_MODULE_9__.getElementLineSegments)(element);\n const intersecting = frameLineSegments.some(frameLineSegment => elementLineSegments.some(elementLineSegment => this.doLineSegmentsIntersect(frameLineSegment, elementLineSegment)));\n return intersecting;\n }\n\n}\n\nFrameGeometry.EPSILON = 0.000001;\nconst getElementsCompletelyInFrame = (elements, frame) => omitGroupsContainingFrames((0,_scene__WEBPACK_IMPORTED_MODULE_5__.getElementsWithinSelection)(elements, frame, false)).filter(element => element.type !== \"frame\" && !element.frameId || element.frameId === frame.id);\nconst isElementContainingFrame = (elements, element, frame) => {\n return (0,_scene__WEBPACK_IMPORTED_MODULE_5__.getElementsWithinSelection)(elements, element).some(e => e.id === frame.id);\n};\nconst getElementsIntersectingFrame = (elements, frame) => elements.filter(element => FrameGeometry.isElementIntersectingFrame(element, frame));\nconst elementsAreInFrameBounds = (elements, frame) => {\n const [selectionX1, selectionY1, selectionX2, selectionY2] = (0,_element__WEBPACK_IMPORTED_MODULE_0__.getElementAbsoluteCoords)(frame);\n const [elementX1, elementY1, elementX2, elementY2] = (0,_element__WEBPACK_IMPORTED_MODULE_0__.getCommonBounds)(elements);\n return selectionX1 <= elementX1 && selectionY1 <= elementY1 && selectionX2 >= elementX2 && selectionY2 >= elementY2;\n};\nconst elementOverlapsWithFrame = (element, frame) => {\n return elementsAreInFrameBounds([element], frame) || FrameGeometry.isElementIntersectingFrame(element, frame) || isElementContainingFrame([frame], element, frame);\n};\nconst isCursorInFrame = (cursorCoords, frame) => {\n const [fx1, fy1, fx2, fy2] = (0,_element__WEBPACK_IMPORTED_MODULE_0__.getElementAbsoluteCoords)(frame);\n return (0,_math__WEBPACK_IMPORTED_MODULE_1__.isPointWithinBounds)([fx1, fy1], [cursorCoords.x, cursorCoords.y], [fx2, fy2]);\n};\nconst groupsAreAtLeastIntersectingTheFrame = (elements, groupIds, frame) => {\n const elementsInGroup = groupIds.flatMap(groupId => (0,_groups__WEBPACK_IMPORTED_MODULE_7__.getElementsInGroup)(elements, groupId));\n\n if (elementsInGroup.length === 0) {\n return true;\n }\n\n return !!elementsInGroup.find(element => elementsAreInFrameBounds([element], frame) || FrameGeometry.isElementIntersectingFrame(element, frame));\n};\nconst groupsAreCompletelyOutOfFrame = (elements, groupIds, frame) => {\n const elementsInGroup = groupIds.flatMap(groupId => (0,_groups__WEBPACK_IMPORTED_MODULE_7__.getElementsInGroup)(elements, groupId));\n\n if (elementsInGroup.length === 0) {\n return true;\n }\n\n return elementsInGroup.find(element => elementsAreInFrameBounds([element], frame) || FrameGeometry.isElementIntersectingFrame(element, frame)) === undefined;\n}; // --------------------------- Frame Utils ------------------------------------\n\n/**\r\n * Returns a map of frameId to frame elements. Includes empty frames.\r\n */\n\nconst groupByFrames = elements => {\n const frameElementsMap = new Map();\n\n for (const element of elements) {\n const frameId = (0,_element__WEBPACK_IMPORTED_MODULE_0__.isFrameElement)(element) ? element.id : element.frameId;\n\n if (frameId && !frameElementsMap.has(frameId)) {\n frameElementsMap.set(frameId, getFrameElements(elements, frameId));\n }\n }\n\n return frameElementsMap;\n};\nconst getFrameElements = (allElements, frameId) => allElements.filter(element => element.frameId === frameId);\nconst getElementsInResizingFrame = (allElements, frame, appState) => {\n const prevElementsInFrame = getFrameElements(allElements, frame.id);\n const nextElementsInFrame = new Set(prevElementsInFrame);\n const elementsCompletelyInFrame = new Set([...getElementsCompletelyInFrame(allElements, frame), ...prevElementsInFrame.filter(element => isElementContainingFrame(allElements, element, frame))]);\n const elementsNotCompletelyInFrame = prevElementsInFrame.filter(element => !elementsCompletelyInFrame.has(element)); // for elements that are completely in the frame\n // if they are part of some groups, then those groups are still\n // considered to belong to the frame\n\n const groupsToKeep = new Set(Array.from(elementsCompletelyInFrame).flatMap(element => element.groupIds));\n\n for (const element of elementsNotCompletelyInFrame) {\n if (!FrameGeometry.isElementIntersectingFrame(element, frame)) {\n if (element.groupIds.length === 0) {\n nextElementsInFrame.delete(element);\n }\n } else if (element.groupIds.length > 0) {\n // group element intersects with the frame, we should keep the groups\n // that this element is part of\n for (const id of element.groupIds) {\n groupsToKeep.add(id);\n }\n }\n }\n\n for (const element of elementsNotCompletelyInFrame) {\n if (element.groupIds.length > 0) {\n let shouldRemoveElement = true;\n\n for (const id of element.groupIds) {\n if (groupsToKeep.has(id)) {\n shouldRemoveElement = false;\n }\n }\n\n if (shouldRemoveElement) {\n nextElementsInFrame.delete(element);\n }\n }\n }\n\n const individualElementsCompletelyInFrame = Array.from(elementsCompletelyInFrame).filter(element => element.groupIds.length === 0);\n\n for (const element of individualElementsCompletelyInFrame) {\n nextElementsInFrame.add(element);\n }\n\n const newGroupElementsCompletelyInFrame = Array.from(elementsCompletelyInFrame).filter(element => element.groupIds.length > 0);\n const groupIds = (0,_groups__WEBPACK_IMPORTED_MODULE_7__.selectGroupsFromGivenElements)(newGroupElementsCompletelyInFrame, appState); // new group elements\n\n for (const [id, isSelected] of Object.entries(groupIds)) {\n if (isSelected) {\n const elementsInGroup = (0,_groups__WEBPACK_IMPORTED_MODULE_7__.getElementsInGroup)(allElements, id);\n\n if (elementsAreInFrameBounds(elementsInGroup, frame)) {\n for (const element of elementsInGroup) {\n nextElementsInFrame.add(element);\n }\n }\n }\n }\n\n return [...nextElementsInFrame].filter(element => {\n return !((0,_element__WEBPACK_IMPORTED_MODULE_0__.isTextElement)(element) && element.containerId);\n });\n};\nconst getElementsInNewFrame = (allElements, frame) => {\n return omitGroupsContainingFrames(allElements, getElementsCompletelyInFrame(allElements, frame));\n};\nconst getContainingFrame = (element,\n/**\r\n * Optionally an elements map, in case the elements aren't in the Scene yet.\r\n * Takes precedence over Scene elements, even if the element exists\r\n * in Scene elements and not the supplied elements map.\r\n */\nelementsMap) => {\n var _a;\n\n if (element.frameId) {\n if (elementsMap) {\n return elementsMap.get(element.frameId) || null;\n }\n\n return ((_a = _scene_Scene__WEBPACK_IMPORTED_MODULE_8__[\"default\"].getScene(element)) === null || _a === void 0 ? void 0 : _a.getElement(element.frameId)) || null;\n }\n\n return null;\n}; // --------------------------- Frame Operations -------------------------------\n\n/**\r\n * Retains (or repairs for target frame) the ordering invriant where children\r\n * elements come right before the parent frame:\r\n * [el, el, child, child, frame, el]\r\n */\n\nconst addElementsToFrame = (allElements, elementsToAdd, frame) => {\n var _a;\n\n const {\n allElementsIndexMap,\n currTargetFrameChildrenMap\n } = allElements.reduce((acc, element, index) => {\n acc.allElementsIndexMap.set(element.id, index);\n\n if (element.frameId === frame.id) {\n acc.currTargetFrameChildrenMap.set(element.id, true);\n }\n\n return acc;\n }, {\n allElementsIndexMap: new Map(),\n currTargetFrameChildrenMap: new Map()\n });\n const suppliedElementsToAddSet = new Set(elementsToAdd.map(el => el.id));\n const finalElementsToAdd = []; // - add bound text elements if not already in the array\n // - filter out elements that are already in the frame\n\n for (const element of omitGroupsContainingFrames(allElements, elementsToAdd)) {\n if (!currTargetFrameChildrenMap.has(element.id)) {\n finalElementsToAdd.push(element);\n }\n\n const boundTextElement = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_2__.getBoundTextElement)(element);\n\n if (boundTextElement && !suppliedElementsToAddSet.has(boundTextElement.id) && !currTargetFrameChildrenMap.has(boundTextElement.id)) {\n finalElementsToAdd.push(boundTextElement);\n }\n }\n\n const finalElementsToAddSet = new Set(finalElementsToAdd.map(el => el.id));\n const nextElements = [];\n const processedElements = new Set();\n\n for (const element of allElements) {\n if (processedElements.has(element.id)) {\n continue;\n }\n\n processedElements.add(element.id);\n\n if (finalElementsToAddSet.has(element.id) || element.frameId && element.frameId === frame.id) {\n // will be added in bulk once we process target frame\n continue;\n } // target frame\n\n\n if (element.id === frame.id) {\n const currFrameChildren = getFrameElements(allElements, frame.id);\n currFrameChildren.forEach(child => {\n processedElements.add(child.id);\n }); // if not found, add all children on top by assigning the lowest index\n\n const targetFrameIndex = (_a = allElementsIndexMap.get(frame.id)) !== null && _a !== void 0 ? _a : -1;\n const {\n newChildren_left,\n newChildren_right\n } = finalElementsToAdd.reduce((acc, element) => {\n var _a; // if index not found, add on top of current frame children\n\n\n const elementIndex = (_a = allElementsIndexMap.get(element.id)) !== null && _a !== void 0 ? _a : Infinity;\n\n if (elementIndex < targetFrameIndex) {\n acc.newChildren_left.push(element);\n } else {\n acc.newChildren_right.push(element);\n }\n\n return acc;\n }, {\n newChildren_left: [],\n newChildren_right: []\n });\n nextElements.push(...newChildren_left, ...currFrameChildren, ...newChildren_right, element);\n continue;\n }\n\n nextElements.push(element);\n }\n\n for (const element of finalElementsToAdd) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_4__.mutateElement)(element, {\n frameId: frame.id\n }, false);\n }\n\n return nextElements;\n};\nconst removeElementsFromFrame = (allElements, elementsToRemove, appState) => {\n const _elementsToRemove = [];\n\n for (const element of elementsToRemove) {\n if (element.frameId) {\n _elementsToRemove.push(element);\n\n const boundTextElement = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_2__.getBoundTextElement)(element);\n\n if (boundTextElement) {\n _elementsToRemove.push(boundTextElement);\n }\n }\n }\n\n for (const element of _elementsToRemove) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_4__.mutateElement)(element, {\n frameId: null\n }, false);\n }\n\n const nextElements = (0,_zindex__WEBPACK_IMPORTED_MODULE_6__.moveOneRight)(allElements, appState, Array.from(_elementsToRemove));\n return nextElements;\n};\nconst removeAllElementsFromFrame = (allElements, frame, appState) => {\n const elementsInFrame = getFrameElements(allElements, frame.id);\n return removeElementsFromFrame(allElements, elementsInFrame, appState);\n};\nconst replaceAllElementsInFrame = (allElements, nextElementsInFrame, frame, appState) => {\n return addElementsToFrame(removeAllElementsFromFrame(allElements, frame, appState), nextElementsInFrame, frame);\n};\n/** does not mutate elements, but returns new ones */\n\nconst updateFrameMembershipOfSelectedElements = (allElements, appState, app) => {\n const selectedElements = app.scene.getSelectedElements({\n selectedElementIds: appState.selectedElementIds,\n // supplying elements explicitly in case we're passed non-state elements\n elements: allElements\n });\n const elementsToFilter = new Set(selectedElements);\n\n if (appState.editingGroupId) {\n for (const element of selectedElements) {\n if (element.groupIds.length === 0) {\n elementsToFilter.add(element);\n } else {\n element.groupIds.flatMap(gid => (0,_groups__WEBPACK_IMPORTED_MODULE_7__.getElementsInGroup)(allElements, gid)).forEach(element => elementsToFilter.add(element));\n }\n }\n }\n\n const elementsToRemove = new Set();\n elementsToFilter.forEach(element => {\n if (element.frameId && !(0,_element__WEBPACK_IMPORTED_MODULE_0__.isFrameElement)(element) && !isElementInFrame(element, allElements, appState)) {\n elementsToRemove.add(element);\n }\n });\n return elementsToRemove.size > 0 ? removeElementsFromFrame(allElements, [...elementsToRemove], appState) : allElements;\n};\n/**\r\n * filters out elements that are inside groups that contain a frame element\r\n * anywhere in the group tree\r\n */\n\nconst omitGroupsContainingFrames = (allElements,\n/** subset of elements you want to filter. Optional perf optimization so we\r\n * don't have to filter all elements unnecessarily\r\n */\nselectedElements) => {\n const uniqueGroupIds = new Set();\n\n for (const el of selectedElements || allElements) {\n const topMostGroupId = el.groupIds[el.groupIds.length - 1];\n\n if (topMostGroupId) {\n uniqueGroupIds.add(topMostGroupId);\n }\n }\n\n const rejectedGroupIds = new Set();\n\n for (const groupId of uniqueGroupIds) {\n if ((0,_groups__WEBPACK_IMPORTED_MODULE_7__.getElementsInGroup)(allElements, groupId).some(el => (0,_element__WEBPACK_IMPORTED_MODULE_0__.isFrameElement)(el))) {\n rejectedGroupIds.add(groupId);\n }\n }\n\n return (selectedElements || allElements).filter(el => !rejectedGroupIds.has(el.groupIds[el.groupIds.length - 1]));\n};\n/**\r\n * depending on the appState, return target frame, which is the frame the given element\r\n * is going to be added to or remove from\r\n */\n\nconst getTargetFrame = (element, appState) => {\n const _element = (0,_element__WEBPACK_IMPORTED_MODULE_0__.isTextElement)(element) ? (0,_element_textElement__WEBPACK_IMPORTED_MODULE_2__.getContainerElement)(element) || element : element;\n\n return appState.selectedElementIds[_element.id] && appState.selectedElementsAreBeingDragged ? appState.frameToHighlight : getContainingFrame(_element);\n}; // TODO: this a huge bottleneck for large scenes, optimise\n// given an element, return if the element is in some frame\n\nconst isElementInFrame = (element, allElements, appState) => {\n const frame = getTargetFrame(element, appState);\n\n const _element = (0,_element__WEBPACK_IMPORTED_MODULE_0__.isTextElement)(element) ? (0,_element_textElement__WEBPACK_IMPORTED_MODULE_2__.getContainerElement)(element) || element : element;\n\n if (frame) {\n // Perf improvement:\n // For an element that's already in a frame, if it's not being dragged\n // then there is no need to refer to geometry (which, yes, is slow) to check if it's in a frame.\n // It has to be in its containing frame.\n if (!appState.selectedElementIds[element.id] || !appState.selectedElementsAreBeingDragged) {\n return true;\n }\n\n if (_element.groupIds.length === 0) {\n return elementOverlapsWithFrame(_element, frame);\n }\n\n const allElementsInGroup = new Set(_element.groupIds.flatMap(gid => (0,_groups__WEBPACK_IMPORTED_MODULE_7__.getElementsInGroup)(allElements, gid)));\n\n if (appState.editingGroupId && appState.selectedElementsAreBeingDragged) {\n const selectedElements = new Set((0,_scene__WEBPACK_IMPORTED_MODULE_5__.getSelectedElements)(allElements, appState));\n const editingGroupOverlapsFrame = appState.frameToHighlight !== null;\n\n if (editingGroupOverlapsFrame) {\n return true;\n }\n\n selectedElements.forEach(selectedElement => {\n allElementsInGroup.delete(selectedElement);\n });\n }\n\n for (const elementInGroup of allElementsInGroup) {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_0__.isFrameElement)(elementInGroup)) {\n return false;\n }\n }\n\n for (const elementInGroup of allElementsInGroup) {\n if (elementOverlapsWithFrame(elementInGroup, frame)) {\n return true;\n }\n }\n }\n\n return false;\n};\n\n//# sourceURL=webpack://ExcalidrawLib/../../frame.ts?");
3891
3891
 
3892
3892
  /***/ }),
3893
3893
 
@@ -4129,7 +4129,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
4129
4129
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
4130
4130
 
4131
4131
  "use strict";
4132
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../constants */ \"../../constants.ts\");\n\n\nif (\"development\" !== _constants__WEBPACK_IMPORTED_MODULE_0__.ENV.TEST) {\n /* eslint-disable */\n\n /* global __webpack_public_path__:writable */\n __webpack_require__.p = window.EXCALIDRAW_ASSET_PATH || `https://unpkg.com/${\"@zsviczian/excalidraw\"}@${\"0.16.1-obsidian-4\"}/dist/`;\n}\n\n//# sourceURL=webpack://ExcalidrawLib/./publicPath.js?");
4132
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../constants */ \"../../constants.ts\");\n\n\nif (\"development\" !== _constants__WEBPACK_IMPORTED_MODULE_0__.ENV.TEST) {\n /* eslint-disable */\n\n /* global __webpack_public_path__:writable */\n __webpack_require__.p = window.EXCALIDRAW_ASSET_PATH || `https://unpkg.com/${\"@zsviczian/excalidraw\"}@${\"0.16.1-obsidian-5\"}/dist/`;\n}\n\n//# sourceURL=webpack://ExcalidrawLib/./publicPath.js?");
4133
4133
 
4134
4134
  /***/ }),
4135
4135
 
@@ -4206,7 +4206,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
4206
4206
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
4207
4207
 
4208
4208
  "use strict";
4209
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"DEFAULT_SPACING\": () => (/* binding */ DEFAULT_SPACING),\n/* harmony export */ \"cancelRender\": () => (/* binding */ cancelRender),\n/* harmony export */ \"renderInteractiveScene\": () => (/* binding */ renderInteractiveScene),\n/* harmony export */ \"renderSceneToSvg\": () => (/* binding */ renderSceneToSvg),\n/* harmony export */ \"renderStaticScene\": () => (/* binding */ renderStaticScene)\n/* harmony export */ });\n/* harmony import */ var open_color__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! open-color */ \"../../../node_modules/open-color/open-color.json\");\n/* harmony import */ var _element__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../element */ \"../../element/index.ts\");\n/* harmony import */ var _roundRect__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./roundRect */ \"../../renderer/roundRect.ts\");\n/* harmony import */ var _scene_scrollbars__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../scene/scrollbars */ \"../../scene/scrollbars.ts\");\n/* harmony import */ var _renderElement__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./renderElement */ \"../../renderer/renderElement.ts\");\n/* harmony import */ var _clients__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../clients */ \"../../clients.ts\");\n/* harmony import */ var _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../element/linearElementEditor */ \"../../element/linearElementEditor.ts\");\n/* harmony import */ var _groups__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../groups */ \"../../groups.ts\");\n/* harmony import */ var _element_collision__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../element/collision */ \"../../element/collision.ts\");\n/* harmony import */ var _element_transformHandles__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../element/transformHandles */ \"../../element/transformHandles.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _types__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../types */ \"../../types.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _element_Hyperlink__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../element/Hyperlink */ \"../../element/Hyperlink.tsx\");\n/* harmony import */ var _renderSnaps__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./renderSnaps */ \"../../renderer/renderSnaps.ts\");\n/* harmony import */ var _element_typeChecks__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../element/typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var _element_embeddable__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../element/embeddable */ \"../../element/embeddable.ts\");\n/* harmony import */ var _frame__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../frame */ \"../../frame.ts\");\n/* harmony import */ var canvas_roundrect_polyfill__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! canvas-roundrect-polyfill */ \"../../../node_modules/canvas-roundrect-polyfill/roundRect.js\");\n/* harmony import */ var canvas_roundrect_polyfill__WEBPACK_IMPORTED_MODULE_18___default = /*#__PURE__*/__webpack_require__.n(canvas_roundrect_polyfill__WEBPACK_IMPORTED_MODULE_18__);\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst DEFAULT_SPACING = 2;\n\nconst strokeRectWithRotation = (context, x, y, width, height, cx, cy, angle, fill = false,\n/** should account for zoom */\nradius = 0) => {\n context.save();\n context.translate(cx, cy);\n context.rotate(angle);\n\n if (fill) {\n context.fillRect(x - cx, y - cy, width, height);\n }\n\n if (radius && context.roundRect) {\n context.beginPath();\n context.roundRect(x - cx, y - cy, width, height, radius);\n context.stroke();\n context.closePath();\n } else {\n context.strokeRect(x - cx, y - cy, width, height);\n }\n\n context.restore();\n};\n\nconst strokeDiamondWithRotation = (context, width, height, cx, cy, angle) => {\n context.save();\n context.translate(cx, cy);\n context.rotate(angle);\n context.beginPath();\n context.moveTo(0, height / 2);\n context.lineTo(width / 2, 0);\n context.lineTo(0, -height / 2);\n context.lineTo(-width / 2, 0);\n context.closePath();\n context.stroke();\n context.restore();\n};\n\nconst strokeEllipseWithRotation = (context, width, height, cx, cy, angle) => {\n context.beginPath();\n context.ellipse(cx, cy, width / 2, height / 2, angle, 0, Math.PI * 2);\n context.stroke();\n};\n\nconst fillCircle = (context, cx, cy, radius, stroke = true) => {\n context.beginPath();\n context.arc(cx, cy, radius, 0, Math.PI * 2);\n context.fill();\n\n if (stroke) {\n context.stroke();\n }\n};\n\nconst strokeGrid = (context, gridSize, scrollX, scrollY, zoom, width, height, GridLineColor) => {\n var _a;\n\n const BOLD_LINE_FREQUENCY = (_a = GridLineColor === null || GridLineColor === void 0 ? void 0 : GridLineColor.MajorGridFrequency) !== null && _a !== void 0 ? _a : 5; //zsviczian\n\n /*enum GridLineColor {\r\n Bold = \"#cccccc\",\r\n Regular = \"#e5e5e5\",\r\n }*/\n\n const offsetX = -Math.round(zoom.value / gridSize) * gridSize + scrollX % gridSize;\n const offsetY = -Math.round(zoom.value / gridSize) * gridSize + scrollY % gridSize;\n const lineWidth = Math.min(1 / zoom.value, 1);\n const spaceWidth = 1 / zoom.value;\n const lineDash = [lineWidth * 3, spaceWidth + (lineWidth + spaceWidth)];\n context.save();\n context.lineWidth = lineWidth;\n\n for (let x = offsetX; x < offsetX + width + gridSize * 2; x += gridSize) {\n const isBold = Math.round(x - scrollX) % (BOLD_LINE_FREQUENCY * gridSize) === 0;\n context.beginPath();\n context.setLineDash(isBold ? [] : lineDash);\n context.strokeStyle = isBold ? GridLineColor.Bold : GridLineColor.Regular;\n context.moveTo(x, offsetY - gridSize);\n context.lineTo(x, offsetY + height + gridSize * 2);\n context.stroke();\n }\n\n for (let y = offsetY; y < offsetY + height + gridSize * 2; y += gridSize) {\n const isBold = Math.round(y - scrollY) % (BOLD_LINE_FREQUENCY * gridSize) === 0;\n context.beginPath();\n context.setLineDash(isBold ? [] : lineDash);\n context.strokeStyle = isBold ? GridLineColor.Bold : GridLineColor.Regular;\n context.moveTo(offsetX - gridSize, y);\n context.lineTo(offsetX + width + gridSize * 2, y);\n context.stroke();\n }\n\n context.restore();\n};\n\nconst renderSingleLinearPoint = (context, appState, point, radius, isSelected, isPhantomPoint = false) => {\n context.strokeStyle = \"#5e5ad8\";\n context.setLineDash([]);\n context.fillStyle = \"rgba(255, 255, 255, 0.9)\";\n\n if (isSelected) {\n context.fillStyle = \"rgba(134, 131, 226, 0.9)\";\n } else if (isPhantomPoint) {\n context.fillStyle = \"rgba(177, 151, 252, 0.7)\";\n }\n\n fillCircle(context, point[0], point[1], radius / appState.zoom.value, !isPhantomPoint);\n};\n\nconst renderLinearPointHandles = (context, appState, element) => {\n if (!appState.selectedLinearElement) {\n return;\n }\n\n context.save();\n context.translate(appState.scrollX, appState.scrollY);\n context.lineWidth = 1 / appState.zoom.value;\n const points = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointsGlobalCoordinates(element);\n const {\n POINT_HANDLE_SIZE\n } = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor;\n const radius = appState.editingLinearElement ? POINT_HANDLE_SIZE : POINT_HANDLE_SIZE / 2;\n points.forEach((point, idx) => {\n var _a, _b;\n\n const isSelected = !!((_b = (_a = appState.editingLinearElement) === null || _a === void 0 ? void 0 : _a.selectedPointsIndices) === null || _b === void 0 ? void 0 : _b.includes(idx));\n renderSingleLinearPoint(context, appState, point, radius, isSelected);\n }); //Rendering segment mid points\n\n const midPoints = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getEditorMidPoints(element, appState).filter(midPoint => midPoint !== null);\n midPoints.forEach(segmentMidPoint => {\n var _a;\n\n if (((_a = appState === null || appState === void 0 ? void 0 : appState.selectedLinearElement) === null || _a === void 0 ? void 0 : _a.segmentMidPointHoveredCoords) && _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.arePointsEqual(segmentMidPoint, appState.selectedLinearElement.segmentMidPointHoveredCoords)) {\n // The order of renderingSingleLinearPoint and highLight points is different\n // inside vs outside editor as hover states are different,\n // in editor when hovered the original point is not visible as hover state fully covers it whereas outside the\n // editor original point is visible and hover state is just an outer circle.\n if (appState.editingLinearElement) {\n renderSingleLinearPoint(context, appState, segmentMidPoint, radius, false);\n highlightPoint(segmentMidPoint, context, appState);\n } else {\n highlightPoint(segmentMidPoint, context, appState);\n renderSingleLinearPoint(context, appState, segmentMidPoint, radius, false);\n }\n } else if (appState.editingLinearElement || points.length === 2) {\n renderSingleLinearPoint(context, appState, segmentMidPoint, POINT_HANDLE_SIZE / 2, false, true);\n }\n });\n context.restore();\n};\n\nconst highlightPoint = (point, context, appState) => {\n context.fillStyle = \"rgba(105, 101, 219, 0.4)\";\n fillCircle(context, point[0], point[1], _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.POINT_HANDLE_SIZE / appState.zoom.value, false);\n};\n\nconst renderLinearElementPointHighlight = (context, appState) => {\n var _a, _b;\n\n const {\n elementId,\n hoverPointIndex\n } = appState.selectedLinearElement;\n\n if ((_b = (_a = appState.editingLinearElement) === null || _a === void 0 ? void 0 : _a.selectedPointsIndices) === null || _b === void 0 ? void 0 : _b.includes(hoverPointIndex)) {\n return;\n }\n\n const element = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getElement(elementId);\n\n if (!element) {\n return;\n }\n\n const point = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointAtIndexGlobalCoordinates(element, hoverPointIndex);\n context.save();\n context.translate(appState.scrollX, appState.scrollY);\n highlightPoint(point, context, appState);\n context.restore();\n};\n\nconst frameClip = (frame, context, renderConfig, appState) => {\n context.translate(frame.x + appState.scrollX, frame.y + appState.scrollY);\n context.beginPath();\n\n if (context.roundRect && !renderConfig.isExporting) {\n context.roundRect(0, 0, frame.width, frame.height, _constants__WEBPACK_IMPORTED_MODULE_12__.FRAME_STYLE.radius / appState.zoom.value);\n } else {\n context.rect(0, 0, frame.width, frame.height);\n }\n\n context.clip();\n context.translate(-(frame.x + appState.scrollX), -(frame.y + appState.scrollY));\n};\n\nconst getNormalizedCanvasDimensions = (canvas, scale) => {\n // When doing calculations based on canvas width we should used normalized one\n return [canvas.width / scale, canvas.height / scale];\n};\n\nconst bootstrapCanvas = ({\n canvas,\n scale,\n normalizedWidth,\n normalizedHeight,\n theme,\n isExporting,\n viewBackgroundColor\n}) => {\n const context = canvas.getContext(\"2d\");\n context.setTransform(1, 0, 0, 1, 0, 0);\n context.scale(scale, scale);\n\n if (isExporting && theme === \"dark\") {\n context.filter = _constants__WEBPACK_IMPORTED_MODULE_12__.THEME_FILTER;\n } // Paint background\n\n\n if (typeof viewBackgroundColor === \"string\") {\n const hasTransparence = viewBackgroundColor === \"transparent\" || viewBackgroundColor.length === 5 || // #RGBA\n viewBackgroundColor.length === 9 || // #RRGGBBA\n /(hsla|rgba)\\(/.test(viewBackgroundColor);\n\n if (hasTransparence) {\n context.clearRect(0, 0, normalizedWidth, normalizedHeight);\n }\n\n context.save();\n context.fillStyle = viewBackgroundColor;\n context.fillRect(0, 0, normalizedWidth, normalizedHeight);\n context.restore();\n } else {\n context.clearRect(0, 0, normalizedWidth, normalizedHeight);\n }\n\n return context;\n};\n\nconst _renderInteractiveScene = ({\n canvas,\n elements,\n visibleElements,\n selectedElements,\n scale,\n appState,\n renderConfig\n}) => {\n var _a, _b;\n\n if (canvas === null) {\n return {\n atLeastOneVisibleElement: false,\n elements\n };\n }\n\n const [normalizedWidth, normalizedHeight] = getNormalizedCanvasDimensions(canvas, scale);\n const context = bootstrapCanvas({\n canvas,\n scale,\n normalizedWidth,\n normalizedHeight\n }); // Apply zoom\n\n context.save();\n context.scale(appState.zoom.value, appState.zoom.value);\n let editingLinearElement = undefined;\n visibleElements.forEach(element => {\n var _a; // Getting the element using LinearElementEditor during collab mismatches version - being one head of visible elements due to\n // ShapeCache returns empty hence making sure that we get the\n // correct element from visible elements\n\n\n if (((_a = appState.editingLinearElement) === null || _a === void 0 ? void 0 : _a.elementId) === element.id) {\n if (element) {\n editingLinearElement = element;\n }\n }\n });\n\n if (editingLinearElement) {\n renderLinearPointHandles(context, appState, editingLinearElement);\n } // Paint selection element\n\n\n if (appState.selectionElement) {\n try {\n (0,_renderElement__WEBPACK_IMPORTED_MODULE_4__.renderSelectionElement)(appState.selectionElement, context, appState);\n } catch (error) {\n console.error(error);\n }\n }\n\n if (appState.isBindingEnabled) {\n appState.suggestedBindings.filter(binding => binding != null).forEach(suggestedBinding => {\n renderBindingHighlight(context, appState, suggestedBinding);\n });\n }\n\n if (appState.frameToHighlight) {\n renderFrameHighlight(context, appState, appState.frameToHighlight);\n }\n\n if (appState.elementsToHighlight) {\n renderElementsBoxHighlight(context, appState, appState.elementsToHighlight);\n }\n\n const isFrameSelected = selectedElements.some(element => (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_15__.isFrameElement)(element)); // Getting the element using LinearElementEditor during collab mismatches version - being one head of visible elements due to\n // ShapeCache returns empty hence making sure that we get the\n // correct element from visible elements\n\n if (selectedElements.length === 1 && ((_a = appState.editingLinearElement) === null || _a === void 0 ? void 0 : _a.elementId) === selectedElements[0].id) {\n renderLinearPointHandles(context, appState, selectedElements[0]);\n }\n\n if (appState.selectedLinearElement && appState.selectedLinearElement.hoverPointIndex >= 0) {\n renderLinearElementPointHighlight(context, appState);\n } // Paint selected elements\n\n\n if (!appState.multiElement && !appState.editingLinearElement) {\n const showBoundingBox = (0,_element_transformHandles__WEBPACK_IMPORTED_MODULE_9__.shouldShowBoundingBox)(selectedElements, appState);\n const isSingleLinearElementSelected = selectedElements.length === 1 && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_15__.isLinearElement)(selectedElements[0]); // render selected linear element points\n\n if (isSingleLinearElementSelected && ((_b = appState.selectedLinearElement) === null || _b === void 0 ? void 0 : _b.elementId) === selectedElements[0].id && !selectedElements[0].locked) {\n renderLinearPointHandles(context, appState, selectedElements[0]);\n }\n\n const selectionColor = renderConfig.selectionColor || open_color__WEBPACK_IMPORTED_MODULE_0__.black;\n\n if (showBoundingBox) {\n // Optimisation for finding quickly relevant element ids\n const locallySelectedIds = selectedElements.reduce((acc, element) => {\n acc[element.id] = true;\n return acc;\n }, {});\n const selections = elements.reduce((acc, element) => {\n var _a;\n\n const selectionColors = []; // local user\n\n if (locallySelectedIds[element.id] && !(0,_groups__WEBPACK_IMPORTED_MODULE_7__.isSelectedViaGroup)(appState, element)) {\n selectionColors.push(selectionColor);\n } // remote users\n\n\n if (renderConfig.remoteSelectedElementIds[element.id]) {\n selectionColors.push(...renderConfig.remoteSelectedElementIds[element.id].map(socketId => {\n const background = (0,_clients__WEBPACK_IMPORTED_MODULE_5__.getClientColor)(socketId);\n return background;\n }));\n }\n\n if (selectionColors.length) {\n const [elementX1, elementY1, elementX2, elementY2, cx, cy] = (0,_element__WEBPACK_IMPORTED_MODULE_1__.getElementAbsoluteCoords)(element, true);\n acc.push({\n angle: element.angle,\n elementX1,\n elementY1,\n elementX2,\n elementY2,\n selectionColors,\n dashed: !!renderConfig.remoteSelectedElementIds[element.id],\n cx,\n cy,\n activeEmbeddable: ((_a = appState.activeEmbeddable) === null || _a === void 0 ? void 0 : _a.element) === element && appState.activeEmbeddable.state === \"active\"\n });\n }\n\n return acc;\n }, []);\n\n const addSelectionForGroupId = groupId => {\n const groupElements = (0,_groups__WEBPACK_IMPORTED_MODULE_7__.getElementsInGroup)(elements, groupId);\n const [elementX1, elementY1, elementX2, elementY2] = (0,_element__WEBPACK_IMPORTED_MODULE_1__.getCommonBounds)(groupElements);\n selections.push({\n angle: 0,\n elementX1,\n elementX2,\n elementY1,\n elementY2,\n selectionColors: [open_color__WEBPACK_IMPORTED_MODULE_0__.black],\n dashed: true,\n cx: elementX1 + (elementX2 - elementX1) / 2,\n cy: elementY1 + (elementY2 - elementY1) / 2,\n activeEmbeddable: false\n });\n };\n\n for (const groupId of (0,_groups__WEBPACK_IMPORTED_MODULE_7__.getSelectedGroupIds)(appState)) {\n // TODO: support multiplayer selected group IDs\n addSelectionForGroupId(groupId);\n }\n\n if (appState.editingGroupId) {\n addSelectionForGroupId(appState.editingGroupId);\n }\n\n selections.forEach(selection => renderSelectionBorder(context, appState, selection));\n } // Paint resize transformHandles\n\n\n context.save();\n context.translate(appState.scrollX, appState.scrollY);\n\n if (selectedElements.length === 1) {\n context.fillStyle = open_color__WEBPACK_IMPORTED_MODULE_0__.white;\n const transformHandles = (0,_element__WEBPACK_IMPORTED_MODULE_1__.getTransformHandles)(selectedElements[0], appState.zoom, \"mouse\");\n\n if (!appState.viewModeEnabled && showBoundingBox) {\n renderTransformHandles(context, renderConfig, appState, transformHandles, selectedElements[0].angle);\n }\n } else if (selectedElements.length > 1 && !appState.isRotating) {\n const dashedLinePadding = DEFAULT_SPACING * 2 / appState.zoom.value;\n context.fillStyle = open_color__WEBPACK_IMPORTED_MODULE_0__.white;\n const [x1, y1, x2, y2] = (0,_element__WEBPACK_IMPORTED_MODULE_1__.getCommonBounds)(selectedElements);\n const initialLineDash = context.getLineDash();\n context.setLineDash([2 / appState.zoom.value]);\n const lineWidth = context.lineWidth;\n context.lineWidth = 1 / appState.zoom.value;\n context.strokeStyle = selectionColor;\n strokeRectWithRotation(context, x1 - dashedLinePadding, y1 - dashedLinePadding, x2 - x1 + dashedLinePadding * 2, y2 - y1 + dashedLinePadding * 2, (x1 + x2) / 2, (y1 + y2) / 2, 0);\n context.lineWidth = lineWidth;\n context.setLineDash(initialLineDash);\n const transformHandles = (0,_element__WEBPACK_IMPORTED_MODULE_1__.getTransformHandlesFromCoords)([x1, y1, x2, y2, (x1 + x2) / 2, (y1 + y2) / 2], 0, appState.zoom, \"mouse\", isFrameSelected ? _element_transformHandles__WEBPACK_IMPORTED_MODULE_9__.OMIT_SIDES_FOR_FRAME : _element__WEBPACK_IMPORTED_MODULE_1__.OMIT_SIDES_FOR_MULTIPLE_ELEMENTS);\n\n if (selectedElements.some(element => !element.locked)) {\n renderTransformHandles(context, renderConfig, appState, transformHandles, 0);\n }\n }\n\n context.restore();\n }\n\n (0,_renderSnaps__WEBPACK_IMPORTED_MODULE_14__.renderSnaps)(context, appState); // Reset zoom\n\n context.restore(); // Paint remote pointers\n\n for (const clientId in renderConfig.remotePointerViewportCoords) {\n let {\n x,\n y\n } = renderConfig.remotePointerViewportCoords[clientId];\n x -= appState.offsetLeft;\n y -= appState.offsetTop;\n const width = 11;\n const height = 14;\n const isOutOfBounds = x < 0 || x > normalizedWidth - width || y < 0 || y > normalizedHeight - height;\n x = Math.max(x, 0);\n x = Math.min(x, normalizedWidth - width);\n y = Math.max(y, 0);\n y = Math.min(y, normalizedHeight - height);\n const background = (0,_clients__WEBPACK_IMPORTED_MODULE_5__.getClientColor)(clientId);\n context.save();\n context.strokeStyle = background;\n context.fillStyle = background;\n const userState = renderConfig.remotePointerUserStates[clientId];\n const isInactive = isOutOfBounds || userState === _types__WEBPACK_IMPORTED_MODULE_11__.UserIdleState.IDLE || userState === _types__WEBPACK_IMPORTED_MODULE_11__.UserIdleState.AWAY;\n\n if (isInactive) {\n context.globalAlpha = 0.3;\n }\n\n if (renderConfig.remotePointerButton && renderConfig.remotePointerButton[clientId] === \"down\") {\n context.beginPath();\n context.arc(x, y, 15, 0, 2 * Math.PI, false);\n context.lineWidth = 3;\n context.strokeStyle = \"#ffffff88\";\n context.stroke();\n context.closePath();\n context.beginPath();\n context.arc(x, y, 15, 0, 2 * Math.PI, false);\n context.lineWidth = 1;\n context.strokeStyle = background;\n context.stroke();\n context.closePath();\n } // Background (white outline) for arrow\n\n\n context.fillStyle = open_color__WEBPACK_IMPORTED_MODULE_0__.white;\n context.strokeStyle = open_color__WEBPACK_IMPORTED_MODULE_0__.white;\n context.lineWidth = 6;\n context.lineJoin = \"round\";\n context.beginPath();\n context.moveTo(x, y);\n context.lineTo(x + 0, y + 14);\n context.lineTo(x + 4, y + 9);\n context.lineTo(x + 11, y + 8);\n context.closePath();\n context.stroke();\n context.fill(); // Arrow\n\n context.fillStyle = background;\n context.strokeStyle = background;\n context.lineWidth = 2;\n context.lineJoin = \"round\";\n context.beginPath();\n\n if (isInactive) {\n context.moveTo(x - 1, y - 1);\n context.lineTo(x - 1, y + 15);\n context.lineTo(x + 5, y + 10);\n context.lineTo(x + 12, y + 9);\n context.closePath();\n context.fill();\n } else {\n context.moveTo(x, y);\n context.lineTo(x + 0, y + 14);\n context.lineTo(x + 4, y + 9);\n context.lineTo(x + 11, y + 8);\n context.closePath();\n context.fill();\n context.stroke();\n }\n\n const username = renderConfig.remotePointerUsernames[clientId] || \"\";\n\n if (!isOutOfBounds && username) {\n context.font = \"600 12px sans-serif\"; // font has to be set before context.measureText()\n\n const offsetX = x + width / 2;\n const offsetY = y + height + 2;\n const paddingHorizontal = 5;\n const paddingVertical = 3;\n const measure = context.measureText(username);\n const measureHeight = measure.actualBoundingBoxDescent + measure.actualBoundingBoxAscent;\n const finalHeight = Math.max(measureHeight, 12);\n const boxX = offsetX - 1;\n const boxY = offsetY - 1;\n const boxWidth = measure.width + 2 + paddingHorizontal * 2 + 2;\n const boxHeight = finalHeight + 2 + paddingVertical * 2 + 2;\n\n if (context.roundRect) {\n context.beginPath();\n context.roundRect(boxX, boxY, boxWidth, boxHeight, 8);\n context.fillStyle = background;\n context.fill();\n context.strokeStyle = open_color__WEBPACK_IMPORTED_MODULE_0__.white;\n context.stroke();\n } else {\n (0,_roundRect__WEBPACK_IMPORTED_MODULE_2__.roundRect)(context, boxX, boxY, boxWidth, boxHeight, 8, open_color__WEBPACK_IMPORTED_MODULE_0__.white);\n }\n\n context.fillStyle = open_color__WEBPACK_IMPORTED_MODULE_0__.black;\n context.fillText(username, offsetX + paddingHorizontal + 1, offsetY + paddingVertical + measure.actualBoundingBoxAscent + Math.floor((finalHeight - measureHeight) / 2) + 2);\n }\n\n context.restore();\n context.closePath();\n } // Paint scrollbars\n\n\n let scrollBars;\n\n if (renderConfig.renderScrollbars) {\n scrollBars = (0,_scene_scrollbars__WEBPACK_IMPORTED_MODULE_3__.getScrollBars)(elements, normalizedWidth, normalizedHeight, appState);\n context.save();\n context.fillStyle = _scene_scrollbars__WEBPACK_IMPORTED_MODULE_3__.SCROLLBAR_COLOR;\n context.strokeStyle = \"rgba(255,255,255,0.8)\";\n [scrollBars.horizontal, scrollBars.vertical].forEach(scrollBar => {\n if (scrollBar) {\n (0,_roundRect__WEBPACK_IMPORTED_MODULE_2__.roundRect)(context, scrollBar.x, scrollBar.y, scrollBar.width, scrollBar.height, _scene_scrollbars__WEBPACK_IMPORTED_MODULE_3__.SCROLLBAR_WIDTH / 2);\n }\n });\n context.restore();\n }\n\n return {\n scrollBars,\n atLeastOneVisibleElement: visibleElements.length > 0,\n elements\n };\n};\n\nconst _renderStaticScene = ({\n canvas,\n rc,\n elements,\n visibleElements,\n scale,\n appState,\n renderConfig\n}) => {\n if (canvas === null) {\n return;\n }\n\n const {\n renderGrid = true,\n isExporting\n } = renderConfig;\n const [normalizedWidth, normalizedHeight] = getNormalizedCanvasDimensions(canvas, scale);\n const context = bootstrapCanvas({\n canvas,\n scale,\n normalizedWidth,\n normalizedHeight,\n theme: appState.theme,\n isExporting,\n viewBackgroundColor: appState.viewBackgroundColor\n }); // Apply zoom\n\n context.scale(appState.zoom.value, appState.zoom.value); // Grid\n\n if (renderGrid && appState.gridSize) {\n strokeGrid(context, appState.gridSize, appState.scrollX, appState.scrollY, appState.zoom, normalizedWidth / appState.zoom.value, normalizedHeight / appState.zoom.value, appState.gridColor);\n }\n\n const groupsToBeAddedToFrame = new Set();\n visibleElements.forEach(element => {\n if (element.groupIds.length > 0 && appState.frameToHighlight && appState.selectedElementIds[element.id] && ((0,_frame__WEBPACK_IMPORTED_MODULE_17__.elementOverlapsWithFrame)(element, appState.frameToHighlight) || element.groupIds.find(groupId => groupsToBeAddedToFrame.has(groupId)))) {\n element.groupIds.forEach(groupId => groupsToBeAddedToFrame.add(groupId));\n }\n }); // Paint visible elements\n\n visibleElements.filter(el => !(0,_element_embeddable__WEBPACK_IMPORTED_MODULE_16__.isEmbeddableOrFrameLabel)(el)).forEach(element => {\n var _a;\n\n try {\n // - when exporting the whole canvas, we DO NOT apply clipping\n // - when we are exporting a particular frame, apply clipping\n // if the containing frame is not selected, apply clipping\n const frameId = element.frameId || ((_a = appState.frameToHighlight) === null || _a === void 0 ? void 0 : _a.id);\n\n if (frameId && (renderConfig.isExporting && (0,_utils__WEBPACK_IMPORTED_MODULE_10__.isOnlyExportingSingleFrame)(elements) || !renderConfig.isExporting && appState.frameRendering.enabled && appState.frameRendering.clip)) {\n context.save();\n const frame = (0,_frame__WEBPACK_IMPORTED_MODULE_17__.getTargetFrame)(element, appState); // TODO do we need to check isElementInFrame here?\n\n if (frame && (0,_frame__WEBPACK_IMPORTED_MODULE_17__.isElementInFrame)(element, elements, appState)) {\n // do not clip arrows\n if (!(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_15__.isArrowElement)(element)) {\n frameClip(frame, context, renderConfig, appState);\n }\n }\n\n (0,_renderElement__WEBPACK_IMPORTED_MODULE_4__.renderElement)(element, rc, context, renderConfig, appState);\n context.restore();\n } else {\n (0,_renderElement__WEBPACK_IMPORTED_MODULE_4__.renderElement)(element, rc, context, renderConfig, appState);\n }\n\n if (!isExporting) {\n renderLinkIcon(element, context, appState);\n }\n } catch (error) {\n console.error(error);\n }\n }); // render embeddables on top\n\n visibleElements.filter(el => (0,_element_embeddable__WEBPACK_IMPORTED_MODULE_16__.isEmbeddableOrFrameLabel)(el)).forEach(element => {\n var _a;\n\n try {\n const render = () => {\n (0,_renderElement__WEBPACK_IMPORTED_MODULE_4__.renderElement)(element, rc, context, renderConfig, appState);\n\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_15__.isEmbeddableElement)(element) && (isExporting || !element.validated) && element.width && element.height) {\n const label = (0,_element_embeddable__WEBPACK_IMPORTED_MODULE_16__.createPlaceholderEmbeddableLabel)(element);\n (0,_renderElement__WEBPACK_IMPORTED_MODULE_4__.renderElement)(label, rc, context, renderConfig, appState);\n }\n\n if (!isExporting) {\n renderLinkIcon(element, context, appState);\n }\n }; // - when exporting the whole canvas, we DO NOT apply clipping\n // - when we are exporting a particular frame, apply clipping\n // if the containing frame is not selected, apply clipping\n\n\n const frameId = element.frameId || ((_a = appState.frameToHighlight) === null || _a === void 0 ? void 0 : _a.id);\n\n if (frameId && (renderConfig.isExporting && (0,_utils__WEBPACK_IMPORTED_MODULE_10__.isOnlyExportingSingleFrame)(elements) || !renderConfig.isExporting && appState.frameRendering.enabled && appState.frameRendering.clip)) {\n context.save();\n const frame = (0,_frame__WEBPACK_IMPORTED_MODULE_17__.getTargetFrame)(element, appState);\n\n if (frame && (0,_frame__WEBPACK_IMPORTED_MODULE_17__.isElementInFrame)(element, elements, appState)) {\n frameClip(frame, context, renderConfig, appState);\n }\n\n render();\n context.restore();\n } else {\n render();\n }\n } catch (error) {\n console.error(error);\n }\n });\n};\n/** throttled to animation framerate */\n\n\nconst renderInteractiveSceneThrottled = (0,_utils__WEBPACK_IMPORTED_MODULE_10__.throttleRAF)(config => {\n var _a;\n\n const ret = _renderInteractiveScene(config);\n\n (_a = config.callback) === null || _a === void 0 ? void 0 : _a.call(config, ret);\n}, {\n trailing: true\n});\n/**\r\n * Interactive scene is the ui-canvas where we render boundinb boxes, selections\r\n * and other ui stuff.\r\n */\n\nconst renderInteractiveScene = (renderConfig, throttle) => {\n if (throttle) {\n renderInteractiveSceneThrottled(renderConfig);\n return undefined;\n }\n\n const ret = _renderInteractiveScene(renderConfig);\n\n renderConfig.callback(ret);\n return ret;\n};\n/** throttled to animation framerate */\n\nconst renderStaticSceneThrottled = (0,_utils__WEBPACK_IMPORTED_MODULE_10__.throttleRAF)(config => {\n _renderStaticScene(config);\n}, {\n trailing: true\n});\n/**\r\n * Static scene is the non-ui canvas where we render elements.\r\n */\n\nconst renderStaticScene = (renderConfig, throttle) => {\n if (throttle) {\n renderStaticSceneThrottled(renderConfig);\n return;\n }\n\n _renderStaticScene(renderConfig);\n};\nconst cancelRender = () => {\n renderInteractiveSceneThrottled.cancel();\n renderStaticSceneThrottled.cancel();\n};\n\nconst renderTransformHandles = (context, renderConfig, appState, transformHandles, angle) => {\n Object.keys(transformHandles).forEach(key => {\n const transformHandle = transformHandles[key];\n\n if (transformHandle !== undefined) {\n const [x, y, width, height] = transformHandle;\n context.save();\n context.lineWidth = 1 / appState.zoom.value;\n\n if (renderConfig.selectionColor) {\n context.strokeStyle = renderConfig.selectionColor;\n }\n\n if (key === \"rotation\") {\n fillCircle(context, x + width / 2, y + height / 2, width / 2); // prefer round corners if roundRect API is available\n } else if (context.roundRect) {\n context.beginPath();\n context.roundRect(x, y, width, height, 2 / appState.zoom.value);\n context.fill();\n context.stroke();\n } else {\n strokeRectWithRotation(context, x, y, width, height, x + width / 2, y + height / 2, angle, true);\n }\n\n context.restore();\n }\n });\n};\n\nconst renderSelectionBorder = (context, appState, elementProperties, padding = DEFAULT_SPACING * 2) => {\n const {\n angle,\n elementX1,\n elementY1,\n elementX2,\n elementY2,\n selectionColors,\n cx,\n cy,\n dashed,\n activeEmbeddable\n } = elementProperties;\n const elementWidth = elementX2 - elementX1;\n const elementHeight = elementY2 - elementY1;\n const linePadding = padding / appState.zoom.value;\n const lineWidth = 8 / appState.zoom.value;\n const spaceWidth = 4 / appState.zoom.value;\n context.save();\n context.translate(appState.scrollX, appState.scrollY);\n context.lineWidth = (activeEmbeddable ? 4 : 1) / appState.zoom.value;\n const count = selectionColors.length;\n\n for (let index = 0; index < count; ++index) {\n context.strokeStyle = selectionColors[index];\n\n if (dashed) {\n context.setLineDash([lineWidth, spaceWidth + (lineWidth + spaceWidth) * (count - 1)]);\n }\n\n context.lineDashOffset = (lineWidth + spaceWidth) * index;\n strokeRectWithRotation(context, elementX1 - linePadding, elementY1 - linePadding, elementWidth + linePadding * 2, elementHeight + linePadding * 2, cx, cy, angle);\n }\n\n context.restore();\n};\n\nconst renderBindingHighlight = (context, appState, suggestedBinding) => {\n const renderHighlight = Array.isArray(suggestedBinding) ? renderBindingHighlightForSuggestedPointBinding : renderBindingHighlightForBindableElement;\n context.save();\n context.translate(appState.scrollX, appState.scrollY);\n renderHighlight(context, suggestedBinding);\n context.restore();\n};\n\nconst renderBindingHighlightForBindableElement = (context, element) => {\n const [x1, y1, x2, y2] = (0,_element__WEBPACK_IMPORTED_MODULE_1__.getElementAbsoluteCoords)(element);\n const width = x2 - x1;\n const height = y2 - y1;\n const threshold = (0,_element_collision__WEBPACK_IMPORTED_MODULE_8__.maxBindingGap)(element, width, height); // So that we don't overlap the element itself\n\n const strokeOffset = 4;\n context.strokeStyle = \"rgba(128,128,128,.1)\"; //zsviczian\n\n context.lineWidth = threshold - strokeOffset;\n const padding = strokeOffset / 2 + threshold / 2;\n\n switch (element.type) {\n case \"rectangle\":\n case \"text\":\n case \"image\":\n case \"embeddable\":\n case \"frame\":\n strokeRectWithRotation(context, x1 - padding, y1 - padding, width + padding * 2, height + padding * 2, x1 + width / 2, y1 + height / 2, element.angle);\n break;\n\n case \"diamond\":\n const side = Math.hypot(width, height);\n const wPadding = padding * side / height;\n const hPadding = padding * side / width;\n strokeDiamondWithRotation(context, width + wPadding * 2, height + hPadding * 2, x1 + width / 2, y1 + height / 2, element.angle);\n break;\n\n case \"ellipse\":\n strokeEllipseWithRotation(context, width + padding * 2, height + padding * 2, x1 + width / 2, y1 + height / 2, element.angle);\n break;\n }\n};\n\nconst renderFrameHighlight = (context, appState, frame) => {\n const [x1, y1, x2, y2] = (0,_element__WEBPACK_IMPORTED_MODULE_1__.getElementAbsoluteCoords)(frame);\n const width = x2 - x1;\n const height = y2 - y1;\n context.strokeStyle = \"rgb(0,118,255)\";\n context.lineWidth = _constants__WEBPACK_IMPORTED_MODULE_12__.FRAME_STYLE.strokeWidth * 2 / appState.zoom.value;\n context.save();\n context.translate(appState.scrollX, appState.scrollY);\n strokeRectWithRotation(context, x1, y1, width, height, x1 + width / 2, y1 + height / 2, frame.angle, false, _constants__WEBPACK_IMPORTED_MODULE_12__.FRAME_STYLE.radius / appState.zoom.value);\n context.restore();\n};\n\nconst renderElementsBoxHighlight = (context, appState, elements) => {\n const individualElements = elements.filter(element => element.groupIds.length === 0);\n const elementsInGroups = elements.filter(element => element.groupIds.length > 0);\n\n const getSelectionFromElements = elements => {\n const [elementX1, elementY1, elementX2, elementY2] = (0,_element__WEBPACK_IMPORTED_MODULE_1__.getCommonBounds)(elements);\n return {\n angle: 0,\n elementX1,\n elementX2,\n elementY1,\n elementY2,\n selectionColors: [\"rgb(0,118,255)\"],\n dashed: false,\n cx: elementX1 + (elementX2 - elementX1) / 2,\n cy: elementY1 + (elementY2 - elementY1) / 2,\n activeEmbeddable: false\n };\n };\n\n const getSelectionForGroupId = groupId => {\n const groupElements = (0,_groups__WEBPACK_IMPORTED_MODULE_7__.getElementsInGroup)(elements, groupId);\n return getSelectionFromElements(groupElements);\n };\n\n Object.entries((0,_groups__WEBPACK_IMPORTED_MODULE_7__.selectGroupsFromGivenElements)(elementsInGroups, appState)).filter(([id, isSelected]) => isSelected).map(([id, isSelected]) => id).map(groupId => getSelectionForGroupId(groupId)).concat(individualElements.map(element => getSelectionFromElements([element]))).forEach(selection => renderSelectionBorder(context, appState, selection));\n};\n\nconst renderBindingHighlightForSuggestedPointBinding = (context, suggestedBinding) => {\n const [element, startOrEnd, bindableElement] = suggestedBinding;\n const threshold = (0,_element_collision__WEBPACK_IMPORTED_MODULE_8__.maxBindingGap)(bindableElement, bindableElement.width, bindableElement.height);\n context.strokeStyle = \"rgba(0,0,0,0)\";\n context.fillStyle = \"rgba(128,128,128,.1)\"; //zsviczian \"rgba(0,0,0,.05)\";\n\n const pointIndices = startOrEnd === \"both\" ? [0, -1] : startOrEnd === \"start\" ? [0] : [-1];\n pointIndices.forEach(index => {\n const [x, y] = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointAtIndexGlobalCoordinates(element, index);\n fillCircle(context, x, y, threshold);\n });\n};\n\nlet linkCanvasCache;\n\nconst renderLinkIcon = (element, context, appState) => {\n if (element.link && !appState.selectedElementIds[element.id]) {\n const [x1, y1, x2, y2] = (0,_element__WEBPACK_IMPORTED_MODULE_1__.getElementAbsoluteCoords)(element);\n const [x, y, width, height] = (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_13__.getLinkHandleFromCoords)([x1, y1, x2, y2], element.angle, appState);\n const centerX = x + width / 2;\n const centerY = y + height / 2;\n context.save();\n context.translate(appState.scrollX + centerX, appState.scrollY + centerY);\n context.rotate(element.angle);\n\n if (!linkCanvasCache || linkCanvasCache.zoom !== appState.zoom.value) {\n linkCanvasCache = document.createElement(\"canvas\");\n linkCanvasCache.zoom = appState.zoom.value;\n linkCanvasCache.width = width * window.devicePixelRatio * appState.zoom.value;\n linkCanvasCache.height = height * window.devicePixelRatio * appState.zoom.value;\n const linkCanvasCacheContext = linkCanvasCache.getContext(\"2d\");\n linkCanvasCacheContext.scale(window.devicePixelRatio * appState.zoom.value, window.devicePixelRatio * appState.zoom.value);\n /*linkCanvasCacheContext.fillStyle = \"#fff\"; //zsviczian\r\n linkCanvasCacheContext.fillRect(0, 0, width, height);*/\n //zsviczian\n //linkCanvasCacheContext.globalAlpha = appState.linkOpacity; //zsviczian\n\n linkCanvasCacheContext.drawImage(_element_Hyperlink__WEBPACK_IMPORTED_MODULE_13__.EXTERNAL_LINK_IMG, 0, 0, width, height);\n linkCanvasCacheContext.restore();\n context.globalAlpha = appState.linkOpacity; //zsviczian\n\n context.drawImage(linkCanvasCache, x - centerX, y - centerY, width, height);\n } else {\n context.globalAlpha = appState.linkOpacity; //zsviczian\n\n context.drawImage(linkCanvasCache, x - centerX, y - centerY, width, height);\n }\n\n context.restore();\n }\n}; // This should be only called for exporting purposes\n\n\nconst renderSceneToSvg = (elements, rsvg, svgRoot, files, {\n offsetX = 0,\n offsetY = 0,\n exportWithDarkMode = false,\n exportingFrameId = null,\n renderEmbeddables\n} = {}) => {\n if (!svgRoot) {\n return;\n } // render elements\n\n\n elements.filter(el => !(0,_element_embeddable__WEBPACK_IMPORTED_MODULE_16__.isEmbeddableOrFrameLabel)(el)).forEach(element => {\n if (!element.isDeleted) {\n try {\n (0,_renderElement__WEBPACK_IMPORTED_MODULE_4__.renderElementToSvg)(element, rsvg, svgRoot, files, element.x + offsetX, element.y + offsetY, exportWithDarkMode, exportingFrameId, renderEmbeddables);\n } catch (error) {\n console.error(error);\n }\n }\n }); // render embeddables on top\n\n elements.filter(el => (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_15__.isEmbeddableElement)(el)).forEach(element => {\n if (!element.isDeleted) {\n try {\n (0,_renderElement__WEBPACK_IMPORTED_MODULE_4__.renderElementToSvg)(element, rsvg, svgRoot, files, element.x + offsetX, element.y + offsetY, exportWithDarkMode, exportingFrameId, renderEmbeddables);\n } catch (error) {\n console.error(error);\n }\n }\n });\n};\n\n//# sourceURL=webpack://ExcalidrawLib/../../renderer/renderScene.ts?");
4209
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"DEFAULT_SPACING\": () => (/* binding */ DEFAULT_SPACING),\n/* harmony export */ \"cancelRender\": () => (/* binding */ cancelRender),\n/* harmony export */ \"renderInteractiveScene\": () => (/* binding */ renderInteractiveScene),\n/* harmony export */ \"renderSceneToSvg\": () => (/* binding */ renderSceneToSvg),\n/* harmony export */ \"renderStaticScene\": () => (/* binding */ renderStaticScene)\n/* harmony export */ });\n/* harmony import */ var open_color__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! open-color */ \"../../../node_modules/open-color/open-color.json\");\n/* harmony import */ var _element__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../element */ \"../../element/index.ts\");\n/* harmony import */ var _roundRect__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./roundRect */ \"../../renderer/roundRect.ts\");\n/* harmony import */ var _scene_scrollbars__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../scene/scrollbars */ \"../../scene/scrollbars.ts\");\n/* harmony import */ var _renderElement__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./renderElement */ \"../../renderer/renderElement.ts\");\n/* harmony import */ var _clients__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../clients */ \"../../clients.ts\");\n/* harmony import */ var _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../element/linearElementEditor */ \"../../element/linearElementEditor.ts\");\n/* harmony import */ var _groups__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../groups */ \"../../groups.ts\");\n/* harmony import */ var _element_collision__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../element/collision */ \"../../element/collision.ts\");\n/* harmony import */ var _element_transformHandles__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../element/transformHandles */ \"../../element/transformHandles.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _types__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../types */ \"../../types.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _element_Hyperlink__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../element/Hyperlink */ \"../../element/Hyperlink.tsx\");\n/* harmony import */ var _renderSnaps__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./renderSnaps */ \"../../renderer/renderSnaps.ts\");\n/* harmony import */ var _element_typeChecks__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../element/typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var _element_embeddable__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../element/embeddable */ \"../../element/embeddable.ts\");\n/* harmony import */ var _frame__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../frame */ \"../../frame.ts\");\n/* harmony import */ var canvas_roundrect_polyfill__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! canvas-roundrect-polyfill */ \"../../../node_modules/canvas-roundrect-polyfill/roundRect.js\");\n/* harmony import */ var canvas_roundrect_polyfill__WEBPACK_IMPORTED_MODULE_18___default = /*#__PURE__*/__webpack_require__.n(canvas_roundrect_polyfill__WEBPACK_IMPORTED_MODULE_18__);\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst DEFAULT_SPACING = 2;\n\nconst strokeRectWithRotation = (context, x, y, width, height, cx, cy, angle, fill = false,\n/** should account for zoom */\nradius = 0) => {\n context.save();\n context.translate(cx, cy);\n context.rotate(angle);\n\n if (fill) {\n context.fillRect(x - cx, y - cy, width, height);\n }\n\n if (radius && context.roundRect) {\n context.beginPath();\n context.roundRect(x - cx, y - cy, width, height, radius);\n context.stroke();\n context.closePath();\n } else {\n context.strokeRect(x - cx, y - cy, width, height);\n }\n\n context.restore();\n};\n\nconst strokeDiamondWithRotation = (context, width, height, cx, cy, angle) => {\n context.save();\n context.translate(cx, cy);\n context.rotate(angle);\n context.beginPath();\n context.moveTo(0, height / 2);\n context.lineTo(width / 2, 0);\n context.lineTo(0, -height / 2);\n context.lineTo(-width / 2, 0);\n context.closePath();\n context.stroke();\n context.restore();\n};\n\nconst strokeEllipseWithRotation = (context, width, height, cx, cy, angle) => {\n context.beginPath();\n context.ellipse(cx, cy, width / 2, height / 2, angle, 0, Math.PI * 2);\n context.stroke();\n};\n\nconst fillCircle = (context, cx, cy, radius, stroke = true) => {\n context.beginPath();\n context.arc(cx, cy, radius, 0, Math.PI * 2);\n context.fill();\n\n if (stroke) {\n context.stroke();\n }\n};\n\nconst strokeGrid = (context, gridSize, scrollX, scrollY, zoom, width, height, GridLineColor) => {\n var _a;\n\n const BOLD_LINE_FREQUENCY = (_a = GridLineColor === null || GridLineColor === void 0 ? void 0 : GridLineColor.MajorGridFrequency) !== null && _a !== void 0 ? _a : 5; //zsviczian\n\n /*enum GridLineColor {\r\n Bold = \"#cccccc\",\r\n Regular = \"#e5e5e5\",\r\n }*/\n\n const offsetX = -Math.round(zoom.value / gridSize) * gridSize + scrollX % gridSize;\n const offsetY = -Math.round(zoom.value / gridSize) * gridSize + scrollY % gridSize;\n const lineWidth = Math.min(1 / zoom.value, 1);\n const spaceWidth = 1 / zoom.value;\n const lineDash = [lineWidth * 3, spaceWidth + (lineWidth + spaceWidth)];\n context.save();\n context.lineWidth = lineWidth;\n\n for (let x = offsetX; x < offsetX + width + gridSize * 2; x += gridSize) {\n const isBold = Math.round(x - scrollX) % (BOLD_LINE_FREQUENCY * gridSize) === 0;\n context.beginPath();\n context.setLineDash(isBold ? [] : lineDash);\n context.strokeStyle = isBold ? GridLineColor.Bold : GridLineColor.Regular;\n context.moveTo(x, offsetY - gridSize);\n context.lineTo(x, offsetY + height + gridSize * 2);\n context.stroke();\n }\n\n for (let y = offsetY; y < offsetY + height + gridSize * 2; y += gridSize) {\n const isBold = Math.round(y - scrollY) % (BOLD_LINE_FREQUENCY * gridSize) === 0;\n context.beginPath();\n context.setLineDash(isBold ? [] : lineDash);\n context.strokeStyle = isBold ? GridLineColor.Bold : GridLineColor.Regular;\n context.moveTo(offsetX - gridSize, y);\n context.lineTo(offsetX + width + gridSize * 2, y);\n context.stroke();\n }\n\n context.restore();\n};\n\nconst renderSingleLinearPoint = (context, appState, point, radius, isSelected, isPhantomPoint = false) => {\n context.strokeStyle = \"#5e5ad8\";\n context.setLineDash([]);\n context.fillStyle = \"rgba(255, 255, 255, 0.9)\";\n\n if (isSelected) {\n context.fillStyle = \"rgba(134, 131, 226, 0.9)\";\n } else if (isPhantomPoint) {\n context.fillStyle = \"rgba(177, 151, 252, 0.7)\";\n }\n\n fillCircle(context, point[0], point[1], radius / appState.zoom.value, !isPhantomPoint);\n};\n\nconst renderLinearPointHandles = (context, appState, element) => {\n if (!appState.selectedLinearElement) {\n return;\n }\n\n context.save();\n context.translate(appState.scrollX, appState.scrollY);\n context.lineWidth = 1 / appState.zoom.value;\n const points = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointsGlobalCoordinates(element);\n const {\n POINT_HANDLE_SIZE\n } = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor;\n const radius = appState.editingLinearElement ? POINT_HANDLE_SIZE : POINT_HANDLE_SIZE / 2;\n points.forEach((point, idx) => {\n var _a, _b;\n\n const isSelected = !!((_b = (_a = appState.editingLinearElement) === null || _a === void 0 ? void 0 : _a.selectedPointsIndices) === null || _b === void 0 ? void 0 : _b.includes(idx));\n renderSingleLinearPoint(context, appState, point, radius, isSelected);\n }); //Rendering segment mid points\n\n const midPoints = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getEditorMidPoints(element, appState).filter(midPoint => midPoint !== null);\n midPoints.forEach(segmentMidPoint => {\n var _a;\n\n if (((_a = appState === null || appState === void 0 ? void 0 : appState.selectedLinearElement) === null || _a === void 0 ? void 0 : _a.segmentMidPointHoveredCoords) && _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.arePointsEqual(segmentMidPoint, appState.selectedLinearElement.segmentMidPointHoveredCoords)) {\n // The order of renderingSingleLinearPoint and highLight points is different\n // inside vs outside editor as hover states are different,\n // in editor when hovered the original point is not visible as hover state fully covers it whereas outside the\n // editor original point is visible and hover state is just an outer circle.\n if (appState.editingLinearElement) {\n renderSingleLinearPoint(context, appState, segmentMidPoint, radius, false);\n highlightPoint(segmentMidPoint, context, appState);\n } else {\n highlightPoint(segmentMidPoint, context, appState);\n renderSingleLinearPoint(context, appState, segmentMidPoint, radius, false);\n }\n } else if (appState.editingLinearElement || points.length === 2) {\n renderSingleLinearPoint(context, appState, segmentMidPoint, POINT_HANDLE_SIZE / 2, false, true);\n }\n });\n context.restore();\n};\n\nconst highlightPoint = (point, context, appState) => {\n context.fillStyle = \"rgba(105, 101, 219, 0.4)\";\n fillCircle(context, point[0], point[1], _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.POINT_HANDLE_SIZE / appState.zoom.value, false);\n};\n\nconst renderLinearElementPointHighlight = (context, appState) => {\n var _a, _b;\n\n const {\n elementId,\n hoverPointIndex\n } = appState.selectedLinearElement;\n\n if ((_b = (_a = appState.editingLinearElement) === null || _a === void 0 ? void 0 : _a.selectedPointsIndices) === null || _b === void 0 ? void 0 : _b.includes(hoverPointIndex)) {\n return;\n }\n\n const element = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getElement(elementId);\n\n if (!element) {\n return;\n }\n\n const point = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointAtIndexGlobalCoordinates(element, hoverPointIndex);\n context.save();\n context.translate(appState.scrollX, appState.scrollY);\n highlightPoint(point, context, appState);\n context.restore();\n};\n\nconst frameClip = (frame, context, renderConfig, appState) => {\n context.translate(frame.x + appState.scrollX, frame.y + appState.scrollY);\n context.beginPath();\n\n if (context.roundRect && !renderConfig.isExporting) {\n context.roundRect(0, 0, frame.width, frame.height, _constants__WEBPACK_IMPORTED_MODULE_12__.FRAME_STYLE.radius / appState.zoom.value);\n } else {\n context.rect(0, 0, frame.width, frame.height);\n }\n\n context.clip();\n context.translate(-(frame.x + appState.scrollX), -(frame.y + appState.scrollY));\n};\n\nconst getNormalizedCanvasDimensions = (canvas, scale) => {\n // When doing calculations based on canvas width we should used normalized one\n return [canvas.width / scale, canvas.height / scale];\n};\n\nconst bootstrapCanvas = ({\n canvas,\n scale,\n normalizedWidth,\n normalizedHeight,\n theme,\n isExporting,\n viewBackgroundColor\n}) => {\n const context = canvas.getContext(\"2d\");\n context.setTransform(1, 0, 0, 1, 0, 0);\n context.scale(scale, scale);\n\n if (isExporting && theme === \"dark\") {\n context.filter = _constants__WEBPACK_IMPORTED_MODULE_12__.THEME_FILTER;\n } // Paint background\n\n\n if (typeof viewBackgroundColor === \"string\") {\n const hasTransparence = viewBackgroundColor === \"transparent\" || viewBackgroundColor.length === 5 || // #RGBA\n viewBackgroundColor.length === 9 || // #RRGGBBA\n /(hsla|rgba)\\(/.test(viewBackgroundColor);\n\n if (hasTransparence) {\n context.clearRect(0, 0, normalizedWidth, normalizedHeight);\n }\n\n context.save();\n context.fillStyle = viewBackgroundColor;\n context.fillRect(0, 0, normalizedWidth, normalizedHeight);\n context.restore();\n } else {\n context.clearRect(0, 0, normalizedWidth, normalizedHeight);\n }\n\n return context;\n};\n\nconst _renderInteractiveScene = ({\n canvas,\n elements,\n visibleElements,\n selectedElements,\n scale,\n appState,\n renderConfig\n}) => {\n var _a, _b;\n\n if (canvas === null) {\n return {\n atLeastOneVisibleElement: false,\n elements\n };\n }\n\n const [normalizedWidth, normalizedHeight] = getNormalizedCanvasDimensions(canvas, scale);\n const context = bootstrapCanvas({\n canvas,\n scale,\n normalizedWidth,\n normalizedHeight\n }); // Apply zoom\n\n context.save();\n context.scale(appState.zoom.value, appState.zoom.value);\n let editingLinearElement = undefined;\n visibleElements.forEach(element => {\n var _a; // Getting the element using LinearElementEditor during collab mismatches version - being one head of visible elements due to\n // ShapeCache returns empty hence making sure that we get the\n // correct element from visible elements\n\n\n if (((_a = appState.editingLinearElement) === null || _a === void 0 ? void 0 : _a.elementId) === element.id) {\n if (element) {\n editingLinearElement = element;\n }\n }\n });\n\n if (editingLinearElement) {\n renderLinearPointHandles(context, appState, editingLinearElement);\n } // Paint selection element\n\n\n if (appState.selectionElement) {\n try {\n (0,_renderElement__WEBPACK_IMPORTED_MODULE_4__.renderSelectionElement)(appState.selectionElement, context, appState);\n } catch (error) {\n console.error(error);\n }\n }\n\n if (appState.isBindingEnabled) {\n appState.suggestedBindings.filter(binding => binding != null).forEach(suggestedBinding => {\n renderBindingHighlight(context, appState, suggestedBinding);\n });\n }\n\n if (appState.frameToHighlight) {\n renderFrameHighlight(context, appState, appState.frameToHighlight);\n }\n\n if (appState.elementsToHighlight) {\n renderElementsBoxHighlight(context, appState, appState.elementsToHighlight);\n }\n\n const isFrameSelected = selectedElements.some(element => (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_15__.isFrameElement)(element)); // Getting the element using LinearElementEditor during collab mismatches version - being one head of visible elements due to\n // ShapeCache returns empty hence making sure that we get the\n // correct element from visible elements\n\n if (selectedElements.length === 1 && ((_a = appState.editingLinearElement) === null || _a === void 0 ? void 0 : _a.elementId) === selectedElements[0].id) {\n renderLinearPointHandles(context, appState, selectedElements[0]);\n }\n\n if (appState.selectedLinearElement && appState.selectedLinearElement.hoverPointIndex >= 0) {\n renderLinearElementPointHighlight(context, appState);\n } // Paint selected elements\n\n\n if (!appState.multiElement && !appState.editingLinearElement) {\n const showBoundingBox = (0,_element_transformHandles__WEBPACK_IMPORTED_MODULE_9__.shouldShowBoundingBox)(selectedElements, appState);\n const isSingleLinearElementSelected = selectedElements.length === 1 && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_15__.isLinearElement)(selectedElements[0]); // render selected linear element points\n\n if (isSingleLinearElementSelected && ((_b = appState.selectedLinearElement) === null || _b === void 0 ? void 0 : _b.elementId) === selectedElements[0].id && !selectedElements[0].locked) {\n renderLinearPointHandles(context, appState, selectedElements[0]);\n }\n\n const selectionColor = renderConfig.selectionColor || open_color__WEBPACK_IMPORTED_MODULE_0__.black;\n\n if (showBoundingBox) {\n // Optimisation for finding quickly relevant element ids\n const locallySelectedIds = selectedElements.reduce((acc, element) => {\n acc[element.id] = true;\n return acc;\n }, {});\n const selections = elements.reduce((acc, element) => {\n var _a;\n\n const selectionColors = []; // local user\n\n if (locallySelectedIds[element.id] && !(0,_groups__WEBPACK_IMPORTED_MODULE_7__.isSelectedViaGroup)(appState, element)) {\n selectionColors.push(selectionColor);\n } // remote users\n\n\n if (renderConfig.remoteSelectedElementIds[element.id]) {\n selectionColors.push(...renderConfig.remoteSelectedElementIds[element.id].map(socketId => {\n const background = (0,_clients__WEBPACK_IMPORTED_MODULE_5__.getClientColor)(socketId);\n return background;\n }));\n }\n\n if (selectionColors.length) {\n const [elementX1, elementY1, elementX2, elementY2, cx, cy] = (0,_element__WEBPACK_IMPORTED_MODULE_1__.getElementAbsoluteCoords)(element, true);\n acc.push({\n angle: element.angle,\n elementX1,\n elementY1,\n elementX2,\n elementY2,\n selectionColors,\n dashed: !!renderConfig.remoteSelectedElementIds[element.id],\n cx,\n cy,\n activeEmbeddable: ((_a = appState.activeEmbeddable) === null || _a === void 0 ? void 0 : _a.element) === element && appState.activeEmbeddable.state === \"active\"\n });\n }\n\n return acc;\n }, []);\n\n const addSelectionForGroupId = groupId => {\n const groupElements = (0,_groups__WEBPACK_IMPORTED_MODULE_7__.getElementsInGroup)(elements, groupId);\n const [elementX1, elementY1, elementX2, elementY2] = (0,_element__WEBPACK_IMPORTED_MODULE_1__.getCommonBounds)(groupElements);\n selections.push({\n angle: 0,\n elementX1,\n elementX2,\n elementY1,\n elementY2,\n selectionColors: [open_color__WEBPACK_IMPORTED_MODULE_0__.black],\n dashed: true,\n cx: elementX1 + (elementX2 - elementX1) / 2,\n cy: elementY1 + (elementY2 - elementY1) / 2,\n activeEmbeddable: false\n });\n };\n\n for (const groupId of (0,_groups__WEBPACK_IMPORTED_MODULE_7__.getSelectedGroupIds)(appState)) {\n // TODO: support multiplayer selected group IDs\n addSelectionForGroupId(groupId);\n }\n\n if (appState.editingGroupId) {\n addSelectionForGroupId(appState.editingGroupId);\n }\n\n selections.forEach(selection => renderSelectionBorder(context, appState, selection));\n } // Paint resize transformHandles\n\n\n context.save();\n context.translate(appState.scrollX, appState.scrollY);\n\n if (selectedElements.length === 1) {\n context.fillStyle = open_color__WEBPACK_IMPORTED_MODULE_0__.white;\n const transformHandles = (0,_element__WEBPACK_IMPORTED_MODULE_1__.getTransformHandles)(selectedElements[0], appState.zoom, \"mouse\");\n\n if (!appState.viewModeEnabled && showBoundingBox) {\n renderTransformHandles(context, renderConfig, appState, transformHandles, selectedElements[0].angle);\n }\n } else if (selectedElements.length > 1 && !appState.isRotating) {\n const dashedLinePadding = DEFAULT_SPACING * 2 / appState.zoom.value;\n context.fillStyle = open_color__WEBPACK_IMPORTED_MODULE_0__.white;\n const [x1, y1, x2, y2] = (0,_element__WEBPACK_IMPORTED_MODULE_1__.getCommonBounds)(selectedElements);\n const initialLineDash = context.getLineDash();\n context.setLineDash([2 / appState.zoom.value]);\n const lineWidth = context.lineWidth;\n context.lineWidth = 1 / appState.zoom.value;\n context.strokeStyle = selectionColor;\n strokeRectWithRotation(context, x1 - dashedLinePadding, y1 - dashedLinePadding, x2 - x1 + dashedLinePadding * 2, y2 - y1 + dashedLinePadding * 2, (x1 + x2) / 2, (y1 + y2) / 2, 0);\n context.lineWidth = lineWidth;\n context.setLineDash(initialLineDash);\n const transformHandles = (0,_element__WEBPACK_IMPORTED_MODULE_1__.getTransformHandlesFromCoords)([x1, y1, x2, y2, (x1 + x2) / 2, (y1 + y2) / 2], 0, appState.zoom, \"mouse\", isFrameSelected ? _element_transformHandles__WEBPACK_IMPORTED_MODULE_9__.OMIT_SIDES_FOR_FRAME : _element__WEBPACK_IMPORTED_MODULE_1__.OMIT_SIDES_FOR_MULTIPLE_ELEMENTS);\n\n if (selectedElements.some(element => !element.locked)) {\n renderTransformHandles(context, renderConfig, appState, transformHandles, 0);\n }\n }\n\n context.restore();\n }\n\n (0,_renderSnaps__WEBPACK_IMPORTED_MODULE_14__.renderSnaps)(context, appState); // Reset zoom\n\n context.restore(); // Paint remote pointers\n\n for (const clientId in renderConfig.remotePointerViewportCoords) {\n let {\n x,\n y\n } = renderConfig.remotePointerViewportCoords[clientId];\n x -= appState.offsetLeft;\n y -= appState.offsetTop;\n const width = 11;\n const height = 14;\n const isOutOfBounds = x < 0 || x > normalizedWidth - width || y < 0 || y > normalizedHeight - height;\n x = Math.max(x, 0);\n x = Math.min(x, normalizedWidth - width);\n y = Math.max(y, 0);\n y = Math.min(y, normalizedHeight - height);\n const background = (0,_clients__WEBPACK_IMPORTED_MODULE_5__.getClientColor)(clientId);\n context.save();\n context.strokeStyle = background;\n context.fillStyle = background;\n const userState = renderConfig.remotePointerUserStates[clientId];\n const isInactive = isOutOfBounds || userState === _types__WEBPACK_IMPORTED_MODULE_11__.UserIdleState.IDLE || userState === _types__WEBPACK_IMPORTED_MODULE_11__.UserIdleState.AWAY;\n\n if (isInactive) {\n context.globalAlpha = 0.3;\n }\n\n if (renderConfig.remotePointerButton && renderConfig.remotePointerButton[clientId] === \"down\") {\n context.beginPath();\n context.arc(x, y, 15, 0, 2 * Math.PI, false);\n context.lineWidth = 3;\n context.strokeStyle = \"#ffffff88\";\n context.stroke();\n context.closePath();\n context.beginPath();\n context.arc(x, y, 15, 0, 2 * Math.PI, false);\n context.lineWidth = 1;\n context.strokeStyle = background;\n context.stroke();\n context.closePath();\n } // Background (white outline) for arrow\n\n\n context.fillStyle = open_color__WEBPACK_IMPORTED_MODULE_0__.white;\n context.strokeStyle = open_color__WEBPACK_IMPORTED_MODULE_0__.white;\n context.lineWidth = 6;\n context.lineJoin = \"round\";\n context.beginPath();\n context.moveTo(x, y);\n context.lineTo(x + 0, y + 14);\n context.lineTo(x + 4, y + 9);\n context.lineTo(x + 11, y + 8);\n context.closePath();\n context.stroke();\n context.fill(); // Arrow\n\n context.fillStyle = background;\n context.strokeStyle = background;\n context.lineWidth = 2;\n context.lineJoin = \"round\";\n context.beginPath();\n\n if (isInactive) {\n context.moveTo(x - 1, y - 1);\n context.lineTo(x - 1, y + 15);\n context.lineTo(x + 5, y + 10);\n context.lineTo(x + 12, y + 9);\n context.closePath();\n context.fill();\n } else {\n context.moveTo(x, y);\n context.lineTo(x + 0, y + 14);\n context.lineTo(x + 4, y + 9);\n context.lineTo(x + 11, y + 8);\n context.closePath();\n context.fill();\n context.stroke();\n }\n\n const username = renderConfig.remotePointerUsernames[clientId] || \"\";\n\n if (!isOutOfBounds && username) {\n context.font = \"600 12px sans-serif\"; // font has to be set before context.measureText()\n\n const offsetX = x + width / 2;\n const offsetY = y + height + 2;\n const paddingHorizontal = 5;\n const paddingVertical = 3;\n const measure = context.measureText(username);\n const measureHeight = measure.actualBoundingBoxDescent + measure.actualBoundingBoxAscent;\n const finalHeight = Math.max(measureHeight, 12);\n const boxX = offsetX - 1;\n const boxY = offsetY - 1;\n const boxWidth = measure.width + 2 + paddingHorizontal * 2 + 2;\n const boxHeight = finalHeight + 2 + paddingVertical * 2 + 2;\n\n if (context.roundRect) {\n context.beginPath();\n context.roundRect(boxX, boxY, boxWidth, boxHeight, 8);\n context.fillStyle = background;\n context.fill();\n context.strokeStyle = open_color__WEBPACK_IMPORTED_MODULE_0__.white;\n context.stroke();\n } else {\n (0,_roundRect__WEBPACK_IMPORTED_MODULE_2__.roundRect)(context, boxX, boxY, boxWidth, boxHeight, 8, open_color__WEBPACK_IMPORTED_MODULE_0__.white);\n }\n\n context.fillStyle = open_color__WEBPACK_IMPORTED_MODULE_0__.black;\n context.fillText(username, offsetX + paddingHorizontal + 1, offsetY + paddingVertical + measure.actualBoundingBoxAscent + Math.floor((finalHeight - measureHeight) / 2) + 2);\n }\n\n context.restore();\n context.closePath();\n } // Paint scrollbars\n\n\n let scrollBars;\n\n if (renderConfig.renderScrollbars) {\n scrollBars = (0,_scene_scrollbars__WEBPACK_IMPORTED_MODULE_3__.getScrollBars)(elements, normalizedWidth, normalizedHeight, appState);\n context.save();\n context.fillStyle = _scene_scrollbars__WEBPACK_IMPORTED_MODULE_3__.SCROLLBAR_COLOR;\n context.strokeStyle = \"rgba(255,255,255,0.8)\";\n [scrollBars.horizontal, scrollBars.vertical].forEach(scrollBar => {\n if (scrollBar) {\n (0,_roundRect__WEBPACK_IMPORTED_MODULE_2__.roundRect)(context, scrollBar.x, scrollBar.y, scrollBar.width, scrollBar.height, _scene_scrollbars__WEBPACK_IMPORTED_MODULE_3__.SCROLLBAR_WIDTH / 2);\n }\n });\n context.restore();\n }\n\n return {\n scrollBars,\n atLeastOneVisibleElement: visibleElements.length > 0,\n elements\n };\n};\n\nconst _renderStaticScene = ({\n canvas,\n rc,\n elements,\n visibleElements,\n scale,\n appState,\n renderConfig\n}) => {\n if (canvas === null) {\n return;\n }\n\n const {\n renderGrid = true,\n isExporting\n } = renderConfig;\n const [normalizedWidth, normalizedHeight] = getNormalizedCanvasDimensions(canvas, scale);\n const context = bootstrapCanvas({\n canvas,\n scale,\n normalizedWidth,\n normalizedHeight,\n theme: appState.theme,\n isExporting,\n viewBackgroundColor: appState.viewBackgroundColor\n }); // Apply zoom\n\n context.scale(appState.zoom.value, appState.zoom.value); // Grid\n\n if (renderGrid && appState.gridSize) {\n strokeGrid(context, appState.gridSize, appState.scrollX, appState.scrollY, appState.zoom, normalizedWidth / appState.zoom.value, normalizedHeight / appState.zoom.value, appState.gridColor);\n }\n\n const groupsToBeAddedToFrame = new Set();\n visibleElements.forEach(element => {\n if (element.groupIds.length > 0 && appState.frameToHighlight && appState.selectedElementIds[element.id] && ((0,_frame__WEBPACK_IMPORTED_MODULE_17__.elementOverlapsWithFrame)(element, appState.frameToHighlight) || element.groupIds.find(groupId => groupsToBeAddedToFrame.has(groupId)))) {\n element.groupIds.forEach(groupId => groupsToBeAddedToFrame.add(groupId));\n }\n }); // Paint visible elements\n\n visibleElements.filter(el => !(0,_element_embeddable__WEBPACK_IMPORTED_MODULE_16__.isEmbeddableOrFrameLabel)(el)).forEach(element => {\n var _a;\n\n try {\n // - when exporting the whole canvas, we DO NOT apply clipping\n // - when we are exporting a particular frame, apply clipping\n // if the containing frame is not selected, apply clipping\n const frameId = element.frameId || ((_a = appState.frameToHighlight) === null || _a === void 0 ? void 0 : _a.id);\n\n if (frameId && (renderConfig.isExporting && (0,_utils__WEBPACK_IMPORTED_MODULE_10__.isOnlyExportingSingleFrame)(elements) || !renderConfig.isExporting && appState.frameRendering.enabled && appState.frameRendering.clip)) {\n context.save();\n const frame = (0,_frame__WEBPACK_IMPORTED_MODULE_17__.getTargetFrame)(element, appState); // TODO do we need to check isElementInFrame here?\n\n if (frame && (0,_frame__WEBPACK_IMPORTED_MODULE_17__.isElementInFrame)(element, elements, appState)) {\n frameClip(frame, context, renderConfig, appState);\n }\n\n (0,_renderElement__WEBPACK_IMPORTED_MODULE_4__.renderElement)(element, rc, context, renderConfig, appState);\n context.restore();\n } else {\n (0,_renderElement__WEBPACK_IMPORTED_MODULE_4__.renderElement)(element, rc, context, renderConfig, appState);\n }\n\n if (!isExporting) {\n renderLinkIcon(element, context, appState);\n }\n } catch (error) {\n console.error(error);\n }\n }); // render embeddables on top\n\n visibleElements.filter(el => (0,_element_embeddable__WEBPACK_IMPORTED_MODULE_16__.isEmbeddableOrFrameLabel)(el)).forEach(element => {\n var _a;\n\n try {\n const render = () => {\n (0,_renderElement__WEBPACK_IMPORTED_MODULE_4__.renderElement)(element, rc, context, renderConfig, appState);\n\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_15__.isEmbeddableElement)(element) && (isExporting || !element.validated) && element.width && element.height) {\n const label = (0,_element_embeddable__WEBPACK_IMPORTED_MODULE_16__.createPlaceholderEmbeddableLabel)(element);\n (0,_renderElement__WEBPACK_IMPORTED_MODULE_4__.renderElement)(label, rc, context, renderConfig, appState);\n }\n\n if (!isExporting) {\n renderLinkIcon(element, context, appState);\n }\n }; // - when exporting the whole canvas, we DO NOT apply clipping\n // - when we are exporting a particular frame, apply clipping\n // if the containing frame is not selected, apply clipping\n\n\n const frameId = element.frameId || ((_a = appState.frameToHighlight) === null || _a === void 0 ? void 0 : _a.id);\n\n if (frameId && (renderConfig.isExporting && (0,_utils__WEBPACK_IMPORTED_MODULE_10__.isOnlyExportingSingleFrame)(elements) || !renderConfig.isExporting && appState.frameRendering.enabled && appState.frameRendering.clip)) {\n context.save();\n const frame = (0,_frame__WEBPACK_IMPORTED_MODULE_17__.getTargetFrame)(element, appState);\n\n if (frame && (0,_frame__WEBPACK_IMPORTED_MODULE_17__.isElementInFrame)(element, elements, appState)) {\n frameClip(frame, context, renderConfig, appState);\n }\n\n render();\n context.restore();\n } else {\n render();\n }\n } catch (error) {\n console.error(error);\n }\n });\n};\n/** throttled to animation framerate */\n\n\nconst renderInteractiveSceneThrottled = (0,_utils__WEBPACK_IMPORTED_MODULE_10__.throttleRAF)(config => {\n var _a;\n\n const ret = _renderInteractiveScene(config);\n\n (_a = config.callback) === null || _a === void 0 ? void 0 : _a.call(config, ret);\n}, {\n trailing: true\n});\n/**\r\n * Interactive scene is the ui-canvas where we render boundinb boxes, selections\r\n * and other ui stuff.\r\n */\n\nconst renderInteractiveScene = (renderConfig, throttle) => {\n if (throttle) {\n renderInteractiveSceneThrottled(renderConfig);\n return undefined;\n }\n\n const ret = _renderInteractiveScene(renderConfig);\n\n renderConfig.callback(ret);\n return ret;\n};\n/** throttled to animation framerate */\n\nconst renderStaticSceneThrottled = (0,_utils__WEBPACK_IMPORTED_MODULE_10__.throttleRAF)(config => {\n _renderStaticScene(config);\n}, {\n trailing: true\n});\n/**\r\n * Static scene is the non-ui canvas where we render elements.\r\n */\n\nconst renderStaticScene = (renderConfig, throttle) => {\n if (throttle) {\n renderStaticSceneThrottled(renderConfig);\n return;\n }\n\n _renderStaticScene(renderConfig);\n};\nconst cancelRender = () => {\n renderInteractiveSceneThrottled.cancel();\n renderStaticSceneThrottled.cancel();\n};\n\nconst renderTransformHandles = (context, renderConfig, appState, transformHandles, angle) => {\n Object.keys(transformHandles).forEach(key => {\n const transformHandle = transformHandles[key];\n\n if (transformHandle !== undefined) {\n const [x, y, width, height] = transformHandle;\n context.save();\n context.lineWidth = 1 / appState.zoom.value;\n\n if (renderConfig.selectionColor) {\n context.strokeStyle = renderConfig.selectionColor;\n }\n\n if (key === \"rotation\") {\n fillCircle(context, x + width / 2, y + height / 2, width / 2); // prefer round corners if roundRect API is available\n } else if (context.roundRect) {\n context.beginPath();\n context.roundRect(x, y, width, height, 2 / appState.zoom.value);\n context.fill();\n context.stroke();\n } else {\n strokeRectWithRotation(context, x, y, width, height, x + width / 2, y + height / 2, angle, true);\n }\n\n context.restore();\n }\n });\n};\n\nconst renderSelectionBorder = (context, appState, elementProperties, padding = DEFAULT_SPACING * 2) => {\n const {\n angle,\n elementX1,\n elementY1,\n elementX2,\n elementY2,\n selectionColors,\n cx,\n cy,\n dashed,\n activeEmbeddable\n } = elementProperties;\n const elementWidth = elementX2 - elementX1;\n const elementHeight = elementY2 - elementY1;\n const linePadding = padding / appState.zoom.value;\n const lineWidth = 8 / appState.zoom.value;\n const spaceWidth = 4 / appState.zoom.value;\n context.save();\n context.translate(appState.scrollX, appState.scrollY);\n context.lineWidth = (activeEmbeddable ? 4 : 1) / appState.zoom.value;\n const count = selectionColors.length;\n\n for (let index = 0; index < count; ++index) {\n context.strokeStyle = selectionColors[index];\n\n if (dashed) {\n context.setLineDash([lineWidth, spaceWidth + (lineWidth + spaceWidth) * (count - 1)]);\n }\n\n context.lineDashOffset = (lineWidth + spaceWidth) * index;\n strokeRectWithRotation(context, elementX1 - linePadding, elementY1 - linePadding, elementWidth + linePadding * 2, elementHeight + linePadding * 2, cx, cy, angle);\n }\n\n context.restore();\n};\n\nconst renderBindingHighlight = (context, appState, suggestedBinding) => {\n const renderHighlight = Array.isArray(suggestedBinding) ? renderBindingHighlightForSuggestedPointBinding : renderBindingHighlightForBindableElement;\n context.save();\n context.translate(appState.scrollX, appState.scrollY);\n renderHighlight(context, suggestedBinding);\n context.restore();\n};\n\nconst renderBindingHighlightForBindableElement = (context, element) => {\n const [x1, y1, x2, y2] = (0,_element__WEBPACK_IMPORTED_MODULE_1__.getElementAbsoluteCoords)(element);\n const width = x2 - x1;\n const height = y2 - y1;\n const threshold = (0,_element_collision__WEBPACK_IMPORTED_MODULE_8__.maxBindingGap)(element, width, height); // So that we don't overlap the element itself\n\n const strokeOffset = 4;\n context.strokeStyle = \"rgba(128,128,128,.1)\"; //zsviczian\n\n context.lineWidth = threshold - strokeOffset;\n const padding = strokeOffset / 2 + threshold / 2;\n\n switch (element.type) {\n case \"rectangle\":\n case \"text\":\n case \"image\":\n case \"embeddable\":\n case \"frame\":\n strokeRectWithRotation(context, x1 - padding, y1 - padding, width + padding * 2, height + padding * 2, x1 + width / 2, y1 + height / 2, element.angle);\n break;\n\n case \"diamond\":\n const side = Math.hypot(width, height);\n const wPadding = padding * side / height;\n const hPadding = padding * side / width;\n strokeDiamondWithRotation(context, width + wPadding * 2, height + hPadding * 2, x1 + width / 2, y1 + height / 2, element.angle);\n break;\n\n case \"ellipse\":\n strokeEllipseWithRotation(context, width + padding * 2, height + padding * 2, x1 + width / 2, y1 + height / 2, element.angle);\n break;\n }\n};\n\nconst renderFrameHighlight = (context, appState, frame) => {\n const [x1, y1, x2, y2] = (0,_element__WEBPACK_IMPORTED_MODULE_1__.getElementAbsoluteCoords)(frame);\n const width = x2 - x1;\n const height = y2 - y1;\n context.strokeStyle = \"rgb(0,118,255)\";\n context.lineWidth = _constants__WEBPACK_IMPORTED_MODULE_12__.FRAME_STYLE.strokeWidth * 2 / appState.zoom.value;\n context.save();\n context.translate(appState.scrollX, appState.scrollY);\n strokeRectWithRotation(context, x1, y1, width, height, x1 + width / 2, y1 + height / 2, frame.angle, false, _constants__WEBPACK_IMPORTED_MODULE_12__.FRAME_STYLE.radius / appState.zoom.value);\n context.restore();\n};\n\nconst renderElementsBoxHighlight = (context, appState, elements) => {\n const individualElements = elements.filter(element => element.groupIds.length === 0);\n const elementsInGroups = elements.filter(element => element.groupIds.length > 0);\n\n const getSelectionFromElements = elements => {\n const [elementX1, elementY1, elementX2, elementY2] = (0,_element__WEBPACK_IMPORTED_MODULE_1__.getCommonBounds)(elements);\n return {\n angle: 0,\n elementX1,\n elementX2,\n elementY1,\n elementY2,\n selectionColors: [\"rgb(0,118,255)\"],\n dashed: false,\n cx: elementX1 + (elementX2 - elementX1) / 2,\n cy: elementY1 + (elementY2 - elementY1) / 2,\n activeEmbeddable: false\n };\n };\n\n const getSelectionForGroupId = groupId => {\n const groupElements = (0,_groups__WEBPACK_IMPORTED_MODULE_7__.getElementsInGroup)(elements, groupId);\n return getSelectionFromElements(groupElements);\n };\n\n Object.entries((0,_groups__WEBPACK_IMPORTED_MODULE_7__.selectGroupsFromGivenElements)(elementsInGroups, appState)).filter(([id, isSelected]) => isSelected).map(([id, isSelected]) => id).map(groupId => getSelectionForGroupId(groupId)).concat(individualElements.map(element => getSelectionFromElements([element]))).forEach(selection => renderSelectionBorder(context, appState, selection));\n};\n\nconst renderBindingHighlightForSuggestedPointBinding = (context, suggestedBinding) => {\n const [element, startOrEnd, bindableElement] = suggestedBinding;\n const threshold = (0,_element_collision__WEBPACK_IMPORTED_MODULE_8__.maxBindingGap)(bindableElement, bindableElement.width, bindableElement.height);\n context.strokeStyle = \"rgba(0,0,0,0)\";\n context.fillStyle = \"rgba(128,128,128,.1)\"; //zsviczian \"rgba(0,0,0,.05)\";\n\n const pointIndices = startOrEnd === \"both\" ? [0, -1] : startOrEnd === \"start\" ? [0] : [-1];\n pointIndices.forEach(index => {\n const [x, y] = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointAtIndexGlobalCoordinates(element, index);\n fillCircle(context, x, y, threshold);\n });\n};\n\nlet linkCanvasCache;\n\nconst renderLinkIcon = (element, context, appState) => {\n if (element.link && !appState.selectedElementIds[element.id]) {\n const [x1, y1, x2, y2] = (0,_element__WEBPACK_IMPORTED_MODULE_1__.getElementAbsoluteCoords)(element);\n const [x, y, width, height] = (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_13__.getLinkHandleFromCoords)([x1, y1, x2, y2], element.angle, appState);\n const centerX = x + width / 2;\n const centerY = y + height / 2;\n context.save();\n context.translate(appState.scrollX + centerX, appState.scrollY + centerY);\n context.rotate(element.angle);\n\n if (!linkCanvasCache || linkCanvasCache.zoom !== appState.zoom.value) {\n linkCanvasCache = document.createElement(\"canvas\");\n linkCanvasCache.zoom = appState.zoom.value;\n linkCanvasCache.width = width * window.devicePixelRatio * appState.zoom.value;\n linkCanvasCache.height = height * window.devicePixelRatio * appState.zoom.value;\n const linkCanvasCacheContext = linkCanvasCache.getContext(\"2d\");\n linkCanvasCacheContext.scale(window.devicePixelRatio * appState.zoom.value, window.devicePixelRatio * appState.zoom.value);\n /*linkCanvasCacheContext.fillStyle = \"#fff\"; //zsviczian\r\n linkCanvasCacheContext.fillRect(0, 0, width, height);*/\n //zsviczian\n //linkCanvasCacheContext.globalAlpha = appState.linkOpacity; //zsviczian\n\n linkCanvasCacheContext.drawImage(_element_Hyperlink__WEBPACK_IMPORTED_MODULE_13__.EXTERNAL_LINK_IMG, 0, 0, width, height);\n linkCanvasCacheContext.restore();\n context.globalAlpha = appState.linkOpacity; //zsviczian\n\n context.drawImage(linkCanvasCache, x - centerX, y - centerY, width, height);\n } else {\n context.globalAlpha = appState.linkOpacity; //zsviczian\n\n context.drawImage(linkCanvasCache, x - centerX, y - centerY, width, height);\n }\n\n context.restore();\n }\n}; // This should be only called for exporting purposes\n\n\nconst renderSceneToSvg = (elements, rsvg, svgRoot, files, {\n offsetX = 0,\n offsetY = 0,\n exportWithDarkMode = false,\n exportingFrameId = null,\n renderEmbeddables\n} = {}) => {\n if (!svgRoot) {\n return;\n } // render elements\n\n\n elements.filter(el => !(0,_element_embeddable__WEBPACK_IMPORTED_MODULE_16__.isEmbeddableOrFrameLabel)(el)).forEach(element => {\n if (!element.isDeleted) {\n try {\n (0,_renderElement__WEBPACK_IMPORTED_MODULE_4__.renderElementToSvg)(element, rsvg, svgRoot, files, element.x + offsetX, element.y + offsetY, exportWithDarkMode, exportingFrameId, renderEmbeddables);\n } catch (error) {\n console.error(error);\n }\n }\n }); // render embeddables on top\n\n elements.filter(el => (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_15__.isEmbeddableElement)(el)).forEach(element => {\n if (!element.isDeleted) {\n try {\n (0,_renderElement__WEBPACK_IMPORTED_MODULE_4__.renderElementToSvg)(element, rsvg, svgRoot, files, element.x + offsetX, element.y + offsetY, exportWithDarkMode, exportingFrameId, renderEmbeddables);\n } catch (error) {\n console.error(error);\n }\n }\n });\n};\n\n//# sourceURL=webpack://ExcalidrawLib/../../renderer/renderScene.ts?");
4210
4210
 
4211
4211
  /***/ }),
4212
4212
 
@@ -4294,7 +4294,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
4294
4294
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
4295
4295
 
4296
4296
  "use strict";
4297
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"canChangeRoundness\": () => (/* binding */ canChangeRoundness),\n/* harmony export */ \"canHaveArrowheads\": () => (/* binding */ canHaveArrowheads),\n/* harmony export */ \"getElementAtPosition\": () => (/* binding */ getElementAtPosition),\n/* harmony export */ \"getElementsAtPosition\": () => (/* binding */ getElementsAtPosition),\n/* harmony export */ \"hasBackground\": () => (/* binding */ hasBackground),\n/* harmony export */ \"hasStrokeColor\": () => (/* binding */ hasStrokeColor),\n/* harmony export */ \"hasStrokeStyle\": () => (/* binding */ hasStrokeStyle),\n/* harmony export */ \"hasStrokeWidth\": () => (/* binding */ hasStrokeWidth),\n/* harmony export */ \"hasText\": () => (/* binding */ hasText)\n/* harmony export */ });\n/* harmony import */ var _element_typeChecks__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../element/typeChecks */ \"../../element/typeChecks.ts\");\n\nconst hasBackground = type => type === \"rectangle\" || type === \"embeddable\" || type === \"ellipse\" || type === \"diamond\" || type === \"line\" || type === \"freedraw\";\nconst hasStrokeColor = type => type !== \"image\" && type !== \"frame\";\nconst hasStrokeWidth = type => type === \"rectangle\" || type === \"embeddable\" || type === \"ellipse\" || type === \"diamond\" || type === \"freedraw\" || type === \"arrow\" || type === \"line\";\nconst hasStrokeStyle = type => type === \"rectangle\" || type === \"embeddable\" || type === \"ellipse\" || type === \"diamond\" || type === \"arrow\" || type === \"line\";\nconst canChangeRoundness = type => type === \"rectangle\" || type === \"embeddable\" || type === \"arrow\" || type === \"line\" || type === \"diamond\";\nconst hasText = type => type === \"text\";\nconst canHaveArrowheads = type => type === \"arrow\";\nconst getElementAtPosition = (elements, isAtPositionFn) => {\n let hitElement = null; // We need to to hit testing from front (end of the array) to back (beginning of the array)\n // because array is ordered from lower z-index to highest and we want element z-index\n // with higher z-index\n\n for (let index = elements.length - 1; index >= 0; --index) {\n const element = elements[index];\n\n if (element.isDeleted) {\n continue;\n }\n\n if (isAtPositionFn(element)) {\n hitElement = element;\n break;\n }\n }\n\n return hitElement;\n};\nconst getElementsAtPosition = (elements, isAtPositionFn) => {\n const embeddables = []; // The parameter elements comes ordered from lower z-index to higher.\n // We want to preserve that order on the returned array.\n // Exception being embeddables which should be on top of everything else in\n // terms of hit testing.\n\n const elsAtPos = elements.filter(element => {\n const hit = !element.isDeleted && isAtPositionFn(element);\n\n if (hit) {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_0__.isEmbeddableElement)(element)) {\n embeddables.push(element);\n return false;\n }\n\n return true;\n }\n\n return false;\n });\n return elsAtPos.concat(embeddables);\n};\n\n//# sourceURL=webpack://ExcalidrawLib/../../scene/comparisons.ts?");
4297
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"canChangeRoundness\": () => (/* binding */ canChangeRoundness),\n/* harmony export */ \"canHaveArrowheads\": () => (/* binding */ canHaveArrowheads),\n/* harmony export */ \"getElementAtPosition\": () => (/* binding */ getElementAtPosition),\n/* harmony export */ \"getElementsAtPosition\": () => (/* binding */ getElementsAtPosition),\n/* harmony export */ \"hasBackground\": () => (/* binding */ hasBackground),\n/* harmony export */ \"hasStrokeColor\": () => (/* binding */ hasStrokeColor),\n/* harmony export */ \"hasStrokeStyle\": () => (/* binding */ hasStrokeStyle),\n/* harmony export */ \"hasStrokeWidth\": () => (/* binding */ hasStrokeWidth)\n/* harmony export */ });\n/* harmony import */ var _element_typeChecks__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../element/typeChecks */ \"../../element/typeChecks.ts\");\n\nconst hasBackground = type => type === \"rectangle\" || type === \"embeddable\" || type === \"ellipse\" || type === \"diamond\" || type === \"line\" || type === \"freedraw\";\nconst hasStrokeColor = type => type !== \"image\" && type !== \"frame\";\nconst hasStrokeWidth = type => type === \"rectangle\" || type === \"embeddable\" || type === \"ellipse\" || type === \"diamond\" || type === \"freedraw\" || type === \"arrow\" || type === \"line\";\nconst hasStrokeStyle = type => type === \"rectangle\" || type === \"embeddable\" || type === \"ellipse\" || type === \"diamond\" || type === \"arrow\" || type === \"line\";\nconst canChangeRoundness = type => type === \"rectangle\" || type === \"embeddable\" || type === \"arrow\" || type === \"line\" || type === \"diamond\";\nconst canHaveArrowheads = type => type === \"arrow\";\nconst getElementAtPosition = (elements, isAtPositionFn) => {\n let hitElement = null; // We need to to hit testing from front (end of the array) to back (beginning of the array)\n // because array is ordered from lower z-index to highest and we want element z-index\n // with higher z-index\n\n for (let index = elements.length - 1; index >= 0; --index) {\n const element = elements[index];\n\n if (element.isDeleted) {\n continue;\n }\n\n if (isAtPositionFn(element)) {\n hitElement = element;\n break;\n }\n }\n\n return hitElement;\n};\nconst getElementsAtPosition = (elements, isAtPositionFn) => {\n const embeddables = []; // The parameter elements comes ordered from lower z-index to higher.\n // We want to preserve that order on the returned array.\n // Exception being embeddables which should be on top of everything else in\n // terms of hit testing.\n\n const elsAtPos = elements.filter(element => {\n const hit = !element.isDeleted && isAtPositionFn(element);\n\n if (hit) {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_0__.isEmbeddableElement)(element)) {\n embeddables.push(element);\n return false;\n }\n\n return true;\n }\n\n return false;\n });\n return elsAtPos.concat(embeddables);\n};\n\n//# sourceURL=webpack://ExcalidrawLib/../../scene/comparisons.ts?");
4298
4298
 
4299
4299
  /***/ }),
4300
4300
 
@@ -4316,7 +4316,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
4316
4316
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
4317
4317
 
4318
4318
  "use strict";
4319
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"calculateScrollCenter\": () => (/* reexport safe */ _scroll__WEBPACK_IMPORTED_MODULE_2__.calculateScrollCenter),\n/* harmony export */ \"canChangeRoundness\": () => (/* reexport safe */ _comparisons__WEBPACK_IMPORTED_MODULE_3__.canChangeRoundness),\n/* harmony export */ \"canHaveArrowheads\": () => (/* reexport safe */ _comparisons__WEBPACK_IMPORTED_MODULE_3__.canHaveArrowheads),\n/* harmony export */ \"getCommonAttributeOfSelectedElements\": () => (/* reexport safe */ _selection__WEBPACK_IMPORTED_MODULE_1__.getCommonAttributeOfSelectedElements),\n/* harmony export */ \"getElementAtPosition\": () => (/* reexport safe */ _comparisons__WEBPACK_IMPORTED_MODULE_3__.getElementAtPosition),\n/* harmony export */ \"getElementsAtPosition\": () => (/* reexport safe */ _comparisons__WEBPACK_IMPORTED_MODULE_3__.getElementsAtPosition),\n/* harmony export */ \"getElementsWithinSelection\": () => (/* reexport safe */ _selection__WEBPACK_IMPORTED_MODULE_1__.getElementsWithinSelection),\n/* harmony export */ \"getNormalizedZoom\": () => (/* reexport safe */ _zoom__WEBPACK_IMPORTED_MODULE_4__.getNormalizedZoom),\n/* harmony export */ \"getSelectedElements\": () => (/* reexport safe */ _selection__WEBPACK_IMPORTED_MODULE_1__.getSelectedElements),\n/* harmony export */ \"getTargetElements\": () => (/* reexport safe */ _selection__WEBPACK_IMPORTED_MODULE_1__.getTargetElements),\n/* harmony export */ \"hasBackground\": () => (/* reexport safe */ _comparisons__WEBPACK_IMPORTED_MODULE_3__.hasBackground),\n/* harmony export */ \"hasStrokeStyle\": () => (/* reexport safe */ _comparisons__WEBPACK_IMPORTED_MODULE_3__.hasStrokeStyle),\n/* harmony export */ \"hasStrokeWidth\": () => (/* reexport safe */ _comparisons__WEBPACK_IMPORTED_MODULE_3__.hasStrokeWidth),\n/* harmony export */ \"hasText\": () => (/* reexport safe */ _comparisons__WEBPACK_IMPORTED_MODULE_3__.hasText),\n/* harmony export */ \"isOverScrollBars\": () => (/* reexport safe */ _scrollbars__WEBPACK_IMPORTED_MODULE_0__.isOverScrollBars),\n/* harmony export */ \"isSomeElementSelected\": () => (/* reexport safe */ _selection__WEBPACK_IMPORTED_MODULE_1__.isSomeElementSelected)\n/* harmony export */ });\n/* harmony import */ var _scrollbars__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./scrollbars */ \"../../scene/scrollbars.ts\");\n/* harmony import */ var _selection__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./selection */ \"../../scene/selection.ts\");\n/* harmony import */ var _scroll__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./scroll */ \"../../scene/scroll.ts\");\n/* harmony import */ var _comparisons__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./comparisons */ \"../../scene/comparisons.ts\");\n/* harmony import */ var _zoom__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./zoom */ \"../../scene/zoom.ts\");\n\n\n\n\n\n\n//# sourceURL=webpack://ExcalidrawLib/../../scene/index.ts?");
4319
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"calculateScrollCenter\": () => (/* reexport safe */ _scroll__WEBPACK_IMPORTED_MODULE_2__.calculateScrollCenter),\n/* harmony export */ \"canChangeRoundness\": () => (/* reexport safe */ _comparisons__WEBPACK_IMPORTED_MODULE_3__.canChangeRoundness),\n/* harmony export */ \"canHaveArrowheads\": () => (/* reexport safe */ _comparisons__WEBPACK_IMPORTED_MODULE_3__.canHaveArrowheads),\n/* harmony export */ \"getCommonAttributeOfSelectedElements\": () => (/* reexport safe */ _selection__WEBPACK_IMPORTED_MODULE_1__.getCommonAttributeOfSelectedElements),\n/* harmony export */ \"getElementAtPosition\": () => (/* reexport safe */ _comparisons__WEBPACK_IMPORTED_MODULE_3__.getElementAtPosition),\n/* harmony export */ \"getElementsAtPosition\": () => (/* reexport safe */ _comparisons__WEBPACK_IMPORTED_MODULE_3__.getElementsAtPosition),\n/* harmony export */ \"getElementsWithinSelection\": () => (/* reexport safe */ _selection__WEBPACK_IMPORTED_MODULE_1__.getElementsWithinSelection),\n/* harmony export */ \"getNormalizedZoom\": () => (/* reexport safe */ _zoom__WEBPACK_IMPORTED_MODULE_4__.getNormalizedZoom),\n/* harmony export */ \"getSelectedElements\": () => (/* reexport safe */ _selection__WEBPACK_IMPORTED_MODULE_1__.getSelectedElements),\n/* harmony export */ \"getTargetElements\": () => (/* reexport safe */ _selection__WEBPACK_IMPORTED_MODULE_1__.getTargetElements),\n/* harmony export */ \"hasBackground\": () => (/* reexport safe */ _comparisons__WEBPACK_IMPORTED_MODULE_3__.hasBackground),\n/* harmony export */ \"hasStrokeStyle\": () => (/* reexport safe */ _comparisons__WEBPACK_IMPORTED_MODULE_3__.hasStrokeStyle),\n/* harmony export */ \"hasStrokeWidth\": () => (/* reexport safe */ _comparisons__WEBPACK_IMPORTED_MODULE_3__.hasStrokeWidth),\n/* harmony export */ \"isOverScrollBars\": () => (/* reexport safe */ _scrollbars__WEBPACK_IMPORTED_MODULE_0__.isOverScrollBars),\n/* harmony export */ \"isSomeElementSelected\": () => (/* reexport safe */ _selection__WEBPACK_IMPORTED_MODULE_1__.isSomeElementSelected)\n/* harmony export */ });\n/* harmony import */ var _scrollbars__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./scrollbars */ \"../../scene/scrollbars.ts\");\n/* harmony import */ var _selection__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./selection */ \"../../scene/selection.ts\");\n/* harmony import */ var _scroll__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./scroll */ \"../../scene/scroll.ts\");\n/* harmony import */ var _comparisons__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./comparisons */ \"../../scene/comparisons.ts\");\n/* harmony import */ var _zoom__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./zoom */ \"../../scene/zoom.ts\");\n\n\n\n\n\n\n//# sourceURL=webpack://ExcalidrawLib/../../scene/index.ts?");
4320
4320
 
4321
4321
  /***/ }),
4322
4322