@zsviczian/excalidraw 0.18.0-54 → 0.18.0-55

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.
@@ -8363,7 +8363,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
8363
8363
  /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
8364
8364
 
8365
8365
  "use strict";
8366
- 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\n\nlet FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM, isTTY=true;\nif (typeof process !== 'undefined') {\n\t({ FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM } = ({\"MODE\":\"development\",\"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_PLUS_LP\":\"https://plus.excalidraw.com\",\"VITE_APP_PLUS_APP\":\"http://localhost:3000\",\"VITE_APP_AI_BACKEND\":\"http://localhost:3015\",\"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_DISABLE_LIVE_RELOAD\":\"\",\"VITE_APP_ENABLE_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_APP_ENABLE_PWA\":\"false\",\"VITE_APP_PLUS_EXPORT_PUBLIC_KEY\":\"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm2g5T+Rub6Kbf1Mf57t0\\n7r2zeHuVg4dla3r5ryXMswtzz6x767octl6oLThn33mQsPSy3GKglFZoCTXJR4ij\\nba8SxB04sL/N8eRrKja7TFWjCVtRwTTfyy771NYYNFVJclkxHyE5qw4m27crHF1y\\nUNWEjuqNMi/lwAErS9fFa2oJlWyT8U7zzv/5kQREkxZI6y9v0AF3qcbsy2731FnD\\ns9ChJvOUW9toIab2gsIdrKW8ZNpu084ZFVKb6LNjvIXI1Se4oMTHeszXzNptzlot\\nkdxxjOoaQMAyfljFSot1F1FlU6MQlag7UnFGvFjRHN1JI5q4K+n3a67DX+TMyRqS\\nHQIDAQAB\",\"VITE_APP_DISABLE_PREVENT_UNLOAD\":\"\",\"VITE_PKG_NAME\":\"@zsviczian/excalidraw\",\"VITE_PKG_VERSION\":\"0.18.0-53\",\"VITE_IS_EXCALIDRAW_NPM_PACKAGE\":true}) || 0);\n\tisTTY = process.stdout && process.stdout.isTTY;\n}\n\nconst $ = {\n\tenabled: !NODE_DISABLE_COLORS && NO_COLOR == null && TERM !== 'dumb' && (\n\t\tFORCE_COLOR != null && FORCE_COLOR !== '0' || isTTY\n\t),\n\n\t// modifiers\n\treset: init(0, 0),\n\tbold: init(1, 22),\n\tdim: init(2, 22),\n\titalic: init(3, 23),\n\tunderline: init(4, 24),\n\tinverse: init(7, 27),\n\thidden: init(8, 28),\n\tstrikethrough: init(9, 29),\n\n\t// colors\n\tblack: init(30, 39),\n\tred: init(31, 39),\n\tgreen: init(32, 39),\n\tyellow: init(33, 39),\n\tblue: init(34, 39),\n\tmagenta: init(35, 39),\n\tcyan: init(36, 39),\n\twhite: init(37, 39),\n\tgray: init(90, 39),\n\tgrey: init(90, 39),\n\n\t// background colors\n\tbgBlack: init(40, 49),\n\tbgRed: init(41, 49),\n\tbgGreen: init(42, 49),\n\tbgYellow: init(43, 49),\n\tbgBlue: init(44, 49),\n\tbgMagenta: init(45, 49),\n\tbgCyan: init(46, 49),\n\tbgWhite: init(47, 49)\n};\n\nfunction run(arr, str) {\n\tlet i=0, tmp, beg='', end='';\n\tfor (; i < arr.length; i++) {\n\t\ttmp = arr[i];\n\t\tbeg += tmp.open;\n\t\tend += tmp.close;\n\t\tif (!!~str.indexOf(tmp.close)) {\n\t\t\tstr = str.replace(tmp.rgx, tmp.close + tmp.open);\n\t\t}\n\t}\n\treturn beg + str + end;\n}\n\nfunction chain(has, keys) {\n\tlet ctx = { has, keys };\n\n\tctx.reset = $.reset.bind(ctx);\n\tctx.bold = $.bold.bind(ctx);\n\tctx.dim = $.dim.bind(ctx);\n\tctx.italic = $.italic.bind(ctx);\n\tctx.underline = $.underline.bind(ctx);\n\tctx.inverse = $.inverse.bind(ctx);\n\tctx.hidden = $.hidden.bind(ctx);\n\tctx.strikethrough = $.strikethrough.bind(ctx);\n\n\tctx.black = $.black.bind(ctx);\n\tctx.red = $.red.bind(ctx);\n\tctx.green = $.green.bind(ctx);\n\tctx.yellow = $.yellow.bind(ctx);\n\tctx.blue = $.blue.bind(ctx);\n\tctx.magenta = $.magenta.bind(ctx);\n\tctx.cyan = $.cyan.bind(ctx);\n\tctx.white = $.white.bind(ctx);\n\tctx.gray = $.gray.bind(ctx);\n\tctx.grey = $.grey.bind(ctx);\n\n\tctx.bgBlack = $.bgBlack.bind(ctx);\n\tctx.bgRed = $.bgRed.bind(ctx);\n\tctx.bgGreen = $.bgGreen.bind(ctx);\n\tctx.bgYellow = $.bgYellow.bind(ctx);\n\tctx.bgBlue = $.bgBlue.bind(ctx);\n\tctx.bgMagenta = $.bgMagenta.bind(ctx);\n\tctx.bgCyan = $.bgCyan.bind(ctx);\n\tctx.bgWhite = $.bgWhite.bind(ctx);\n\n\treturn ctx;\n}\n\nfunction init(open, close) {\n\tlet blk = {\n\t\topen: `\\x1b[${open}m`,\n\t\tclose: `\\x1b[${close}m`,\n\t\trgx: new RegExp(`\\\\x1b\\\\[${close}m`, 'g')\n\t};\n\treturn function (txt) {\n\t\tif (this !== void 0 && this.has !== void 0) {\n\t\t\t!!~this.has.indexOf(open) || (this.has.push(open),this.keys.push(blk));\n\t\t\treturn txt === void 0 ? this : $.enabled ? run(this.keys, txt+'') : txt+'';\n\t\t}\n\t\treturn txt === void 0 ? chain([open], [blk]) : $.enabled ? run([blk], txt+'') : txt+'';\n\t};\n}\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ($);\n\n\n//# sourceURL=webpack://ExcalidrawLib/../../node_modules/kleur/index.mjs?");
8366
+ 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\n\nlet FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM, isTTY=true;\nif (typeof process !== 'undefined') {\n\t({ FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM } = ({\"MODE\":\"development\",\"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_PLUS_LP\":\"https://plus.excalidraw.com\",\"VITE_APP_PLUS_APP\":\"http://localhost:3000\",\"VITE_APP_AI_BACKEND\":\"http://localhost:3015\",\"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_DISABLE_LIVE_RELOAD\":\"\",\"VITE_APP_ENABLE_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_APP_ENABLE_PWA\":\"false\",\"VITE_APP_PLUS_EXPORT_PUBLIC_KEY\":\"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm2g5T+Rub6Kbf1Mf57t0\\n7r2zeHuVg4dla3r5ryXMswtzz6x767octl6oLThn33mQsPSy3GKglFZoCTXJR4ij\\nba8SxB04sL/N8eRrKja7TFWjCVtRwTTfyy771NYYNFVJclkxHyE5qw4m27crHF1y\\nUNWEjuqNMi/lwAErS9fFa2oJlWyT8U7zzv/5kQREkxZI6y9v0AF3qcbsy2731FnD\\ns9ChJvOUW9toIab2gsIdrKW8ZNpu084ZFVKb6LNjvIXI1Se4oMTHeszXzNptzlot\\nkdxxjOoaQMAyfljFSot1F1FlU6MQlag7UnFGvFjRHN1JI5q4K+n3a67DX+TMyRqS\\nHQIDAQAB\",\"VITE_APP_DISABLE_PREVENT_UNLOAD\":\"\",\"VITE_PKG_NAME\":\"@zsviczian/excalidraw\",\"VITE_PKG_VERSION\":\"0.18.0-54\",\"VITE_IS_EXCALIDRAW_NPM_PACKAGE\":true}) || 0);\n\tisTTY = process.stdout && process.stdout.isTTY;\n}\n\nconst $ = {\n\tenabled: !NODE_DISABLE_COLORS && NO_COLOR == null && TERM !== 'dumb' && (\n\t\tFORCE_COLOR != null && FORCE_COLOR !== '0' || isTTY\n\t),\n\n\t// modifiers\n\treset: init(0, 0),\n\tbold: init(1, 22),\n\tdim: init(2, 22),\n\titalic: init(3, 23),\n\tunderline: init(4, 24),\n\tinverse: init(7, 27),\n\thidden: init(8, 28),\n\tstrikethrough: init(9, 29),\n\n\t// colors\n\tblack: init(30, 39),\n\tred: init(31, 39),\n\tgreen: init(32, 39),\n\tyellow: init(33, 39),\n\tblue: init(34, 39),\n\tmagenta: init(35, 39),\n\tcyan: init(36, 39),\n\twhite: init(37, 39),\n\tgray: init(90, 39),\n\tgrey: init(90, 39),\n\n\t// background colors\n\tbgBlack: init(40, 49),\n\tbgRed: init(41, 49),\n\tbgGreen: init(42, 49),\n\tbgYellow: init(43, 49),\n\tbgBlue: init(44, 49),\n\tbgMagenta: init(45, 49),\n\tbgCyan: init(46, 49),\n\tbgWhite: init(47, 49)\n};\n\nfunction run(arr, str) {\n\tlet i=0, tmp, beg='', end='';\n\tfor (; i < arr.length; i++) {\n\t\ttmp = arr[i];\n\t\tbeg += tmp.open;\n\t\tend += tmp.close;\n\t\tif (!!~str.indexOf(tmp.close)) {\n\t\t\tstr = str.replace(tmp.rgx, tmp.close + tmp.open);\n\t\t}\n\t}\n\treturn beg + str + end;\n}\n\nfunction chain(has, keys) {\n\tlet ctx = { has, keys };\n\n\tctx.reset = $.reset.bind(ctx);\n\tctx.bold = $.bold.bind(ctx);\n\tctx.dim = $.dim.bind(ctx);\n\tctx.italic = $.italic.bind(ctx);\n\tctx.underline = $.underline.bind(ctx);\n\tctx.inverse = $.inverse.bind(ctx);\n\tctx.hidden = $.hidden.bind(ctx);\n\tctx.strikethrough = $.strikethrough.bind(ctx);\n\n\tctx.black = $.black.bind(ctx);\n\tctx.red = $.red.bind(ctx);\n\tctx.green = $.green.bind(ctx);\n\tctx.yellow = $.yellow.bind(ctx);\n\tctx.blue = $.blue.bind(ctx);\n\tctx.magenta = $.magenta.bind(ctx);\n\tctx.cyan = $.cyan.bind(ctx);\n\tctx.white = $.white.bind(ctx);\n\tctx.gray = $.gray.bind(ctx);\n\tctx.grey = $.grey.bind(ctx);\n\n\tctx.bgBlack = $.bgBlack.bind(ctx);\n\tctx.bgRed = $.bgRed.bind(ctx);\n\tctx.bgGreen = $.bgGreen.bind(ctx);\n\tctx.bgYellow = $.bgYellow.bind(ctx);\n\tctx.bgBlue = $.bgBlue.bind(ctx);\n\tctx.bgMagenta = $.bgMagenta.bind(ctx);\n\tctx.bgCyan = $.bgCyan.bind(ctx);\n\tctx.bgWhite = $.bgWhite.bind(ctx);\n\n\treturn ctx;\n}\n\nfunction init(open, close) {\n\tlet blk = {\n\t\topen: `\\x1b[${open}m`,\n\t\tclose: `\\x1b[${close}m`,\n\t\trgx: new RegExp(`\\\\x1b\\\\[${close}m`, 'g')\n\t};\n\treturn function (txt) {\n\t\tif (this !== void 0 && this.has !== void 0) {\n\t\t\t!!~this.has.indexOf(open) || (this.has.push(open),this.keys.push(blk));\n\t\t\treturn txt === void 0 ? this : $.enabled ? run(this.keys, txt+'') : txt+'';\n\t\t}\n\t\treturn txt === void 0 ? chain([open], [blk]) : $.enabled ? run([blk], txt+'') : txt+'';\n\t};\n}\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ($);\n\n\n//# sourceURL=webpack://ExcalidrawLib/../../node_modules/kleur/index.mjs?");
8367
8367
 
8368
8368
  /***/ }),
8369
8369
 
@@ -11978,7 +11978,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
11978
11978
  \**********************************************************************/
11979
11979
  /***/ ((module, exports, __webpack_require__) => {
11980
11980
 
11981
- eval("/* eslint-env browser */\n\n/**\n * This is the web browser implementation of `debug()`.\n */\n\nexports.formatArgs = formatArgs;\nexports.save = save;\nexports.load = load;\nexports.useColors = useColors;\nexports.storage = localstorage();\nexports.destroy = (() => {\n\tlet warned = false;\n\n\treturn () => {\n\t\tif (!warned) {\n\t\t\twarned = true;\n\t\t\tconsole.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');\n\t\t}\n\t};\n})();\n\n/**\n * Colors.\n */\n\nexports.colors = [\n\t'#0000CC',\n\t'#0000FF',\n\t'#0033CC',\n\t'#0033FF',\n\t'#0066CC',\n\t'#0066FF',\n\t'#0099CC',\n\t'#0099FF',\n\t'#00CC00',\n\t'#00CC33',\n\t'#00CC66',\n\t'#00CC99',\n\t'#00CCCC',\n\t'#00CCFF',\n\t'#3300CC',\n\t'#3300FF',\n\t'#3333CC',\n\t'#3333FF',\n\t'#3366CC',\n\t'#3366FF',\n\t'#3399CC',\n\t'#3399FF',\n\t'#33CC00',\n\t'#33CC33',\n\t'#33CC66',\n\t'#33CC99',\n\t'#33CCCC',\n\t'#33CCFF',\n\t'#6600CC',\n\t'#6600FF',\n\t'#6633CC',\n\t'#6633FF',\n\t'#66CC00',\n\t'#66CC33',\n\t'#9900CC',\n\t'#9900FF',\n\t'#9933CC',\n\t'#9933FF',\n\t'#99CC00',\n\t'#99CC33',\n\t'#CC0000',\n\t'#CC0033',\n\t'#CC0066',\n\t'#CC0099',\n\t'#CC00CC',\n\t'#CC00FF',\n\t'#CC3300',\n\t'#CC3333',\n\t'#CC3366',\n\t'#CC3399',\n\t'#CC33CC',\n\t'#CC33FF',\n\t'#CC6600',\n\t'#CC6633',\n\t'#CC9900',\n\t'#CC9933',\n\t'#CCCC00',\n\t'#CCCC33',\n\t'#FF0000',\n\t'#FF0033',\n\t'#FF0066',\n\t'#FF0099',\n\t'#FF00CC',\n\t'#FF00FF',\n\t'#FF3300',\n\t'#FF3333',\n\t'#FF3366',\n\t'#FF3399',\n\t'#FF33CC',\n\t'#FF33FF',\n\t'#FF6600',\n\t'#FF6633',\n\t'#FF9900',\n\t'#FF9933',\n\t'#FFCC00',\n\t'#FFCC33'\n];\n\n/**\n * Currently only WebKit-based Web Inspectors, Firefox >= v31,\n * and the Firebug extension (any Firefox version) are known\n * to support \"%c\" CSS customizations.\n *\n * TODO: add a `localStorage` variable to explicitly enable/disable colors\n */\n\n// eslint-disable-next-line complexity\nfunction useColors() {\n\t// NB: In an Electron preload script, document will be defined but not fully\n\t// initialized. Since we know we're in Chrome, we'll just detect this case\n\t// explicitly\n\tif (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {\n\t\treturn true;\n\t}\n\n\t// Internet Explorer and Edge do not support colors.\n\tif (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\\/(\\d+)/)) {\n\t\treturn false;\n\t}\n\n\tlet m;\n\n\t// Is webkit? http://stackoverflow.com/a/16459606/376773\n\t// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632\n\t// eslint-disable-next-line no-return-assign\n\treturn (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||\n\t\t// Is firebug? http://stackoverflow.com/a/398120/376773\n\t\t(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||\n\t\t// Is firefox >= v31?\n\t\t// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages\n\t\t(typeof navigator !== 'undefined' && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\\/(\\d+)/)) && parseInt(m[1], 10) >= 31) ||\n\t\t// Double check webkit in userAgent just in case we are in a worker\n\t\t(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\\/(\\d+)/));\n}\n\n/**\n * Colorize log arguments if enabled.\n *\n * @api public\n */\n\nfunction formatArgs(args) {\n\targs[0] = (this.useColors ? '%c' : '') +\n\t\tthis.namespace +\n\t\t(this.useColors ? ' %c' : ' ') +\n\t\targs[0] +\n\t\t(this.useColors ? '%c ' : ' ') +\n\t\t'+' + module.exports.humanize(this.diff);\n\n\tif (!this.useColors) {\n\t\treturn;\n\t}\n\n\tconst c = 'color: ' + this.color;\n\targs.splice(1, 0, c, 'color: inherit');\n\n\t// The final \"%c\" is somewhat tricky, because there could be other\n\t// arguments passed either before or after the %c, so we need to\n\t// figure out the correct index to insert the CSS into\n\tlet index = 0;\n\tlet lastC = 0;\n\targs[0].replace(/%[a-zA-Z%]/g, match => {\n\t\tif (match === '%%') {\n\t\t\treturn;\n\t\t}\n\t\tindex++;\n\t\tif (match === '%c') {\n\t\t\t// We only are interested in the *last* %c\n\t\t\t// (the user may have provided their own)\n\t\t\tlastC = index;\n\t\t}\n\t});\n\n\targs.splice(lastC, 0, c);\n}\n\n/**\n * Invokes `console.debug()` when available.\n * No-op when `console.debug` is not a \"function\".\n * If `console.debug` is not available, falls back\n * to `console.log`.\n *\n * @api public\n */\nexports.log = console.debug || console.log || (() => {});\n\n/**\n * Save `namespaces`.\n *\n * @param {String} namespaces\n * @api private\n */\nfunction save(namespaces) {\n\ttry {\n\t\tif (namespaces) {\n\t\t\texports.storage.setItem('debug', namespaces);\n\t\t} else {\n\t\t\texports.storage.removeItem('debug');\n\t\t}\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n}\n\n/**\n * Load `namespaces`.\n *\n * @return {String} returns the previously persisted debug modes\n * @api private\n */\nfunction load() {\n\tlet r;\n\ttry {\n\t\tr = exports.storage.getItem('debug');\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n\n\t// If debug isn't set in LS, and we're in Electron, try to load $DEBUG\n\tif (!r && typeof process !== 'undefined' && 'env' in process) {\n\t\tr = ({\"MODE\":\"development\",\"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_PLUS_LP\":\"https://plus.excalidraw.com\",\"VITE_APP_PLUS_APP\":\"http://localhost:3000\",\"VITE_APP_AI_BACKEND\":\"http://localhost:3015\",\"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_DISABLE_LIVE_RELOAD\":\"\",\"VITE_APP_ENABLE_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_APP_ENABLE_PWA\":\"false\",\"VITE_APP_PLUS_EXPORT_PUBLIC_KEY\":\"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm2g5T+Rub6Kbf1Mf57t0\\n7r2zeHuVg4dla3r5ryXMswtzz6x767octl6oLThn33mQsPSy3GKglFZoCTXJR4ij\\nba8SxB04sL/N8eRrKja7TFWjCVtRwTTfyy771NYYNFVJclkxHyE5qw4m27crHF1y\\nUNWEjuqNMi/lwAErS9fFa2oJlWyT8U7zzv/5kQREkxZI6y9v0AF3qcbsy2731FnD\\ns9ChJvOUW9toIab2gsIdrKW8ZNpu084ZFVKb6LNjvIXI1Se4oMTHeszXzNptzlot\\nkdxxjOoaQMAyfljFSot1F1FlU6MQlag7UnFGvFjRHN1JI5q4K+n3a67DX+TMyRqS\\nHQIDAQAB\",\"VITE_APP_DISABLE_PREVENT_UNLOAD\":\"\",\"VITE_PKG_NAME\":\"@zsviczian/excalidraw\",\"VITE_PKG_VERSION\":\"0.18.0-53\",\"VITE_IS_EXCALIDRAW_NPM_PACKAGE\":true}).DEBUG;\n\t}\n\n\treturn r;\n}\n\n/**\n * Localstorage attempts to return the localstorage.\n *\n * This is necessary because safari throws\n * when a user disables cookies/localstorage\n * and you attempt to access it.\n *\n * @return {LocalStorage}\n * @api private\n */\n\nfunction localstorage() {\n\ttry {\n\t\t// TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context\n\t\t// The Browser also has localStorage in the global context.\n\t\treturn localStorage;\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n}\n\nmodule.exports = __webpack_require__(/*! ./common */ \"../../node_modules/micromark/node_modules/debug/src/common.js\")(exports);\n\nconst {formatters} = module.exports;\n\n/**\n * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.\n */\n\nformatters.j = function (v) {\n\ttry {\n\t\treturn JSON.stringify(v);\n\t} catch (error) {\n\t\treturn '[UnexpectedJSONParseError]: ' + error.message;\n\t}\n};\n\n\n//# sourceURL=webpack://ExcalidrawLib/../../node_modules/micromark/node_modules/debug/src/browser.js?");
11981
+ eval("/* eslint-env browser */\n\n/**\n * This is the web browser implementation of `debug()`.\n */\n\nexports.formatArgs = formatArgs;\nexports.save = save;\nexports.load = load;\nexports.useColors = useColors;\nexports.storage = localstorage();\nexports.destroy = (() => {\n\tlet warned = false;\n\n\treturn () => {\n\t\tif (!warned) {\n\t\t\twarned = true;\n\t\t\tconsole.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');\n\t\t}\n\t};\n})();\n\n/**\n * Colors.\n */\n\nexports.colors = [\n\t'#0000CC',\n\t'#0000FF',\n\t'#0033CC',\n\t'#0033FF',\n\t'#0066CC',\n\t'#0066FF',\n\t'#0099CC',\n\t'#0099FF',\n\t'#00CC00',\n\t'#00CC33',\n\t'#00CC66',\n\t'#00CC99',\n\t'#00CCCC',\n\t'#00CCFF',\n\t'#3300CC',\n\t'#3300FF',\n\t'#3333CC',\n\t'#3333FF',\n\t'#3366CC',\n\t'#3366FF',\n\t'#3399CC',\n\t'#3399FF',\n\t'#33CC00',\n\t'#33CC33',\n\t'#33CC66',\n\t'#33CC99',\n\t'#33CCCC',\n\t'#33CCFF',\n\t'#6600CC',\n\t'#6600FF',\n\t'#6633CC',\n\t'#6633FF',\n\t'#66CC00',\n\t'#66CC33',\n\t'#9900CC',\n\t'#9900FF',\n\t'#9933CC',\n\t'#9933FF',\n\t'#99CC00',\n\t'#99CC33',\n\t'#CC0000',\n\t'#CC0033',\n\t'#CC0066',\n\t'#CC0099',\n\t'#CC00CC',\n\t'#CC00FF',\n\t'#CC3300',\n\t'#CC3333',\n\t'#CC3366',\n\t'#CC3399',\n\t'#CC33CC',\n\t'#CC33FF',\n\t'#CC6600',\n\t'#CC6633',\n\t'#CC9900',\n\t'#CC9933',\n\t'#CCCC00',\n\t'#CCCC33',\n\t'#FF0000',\n\t'#FF0033',\n\t'#FF0066',\n\t'#FF0099',\n\t'#FF00CC',\n\t'#FF00FF',\n\t'#FF3300',\n\t'#FF3333',\n\t'#FF3366',\n\t'#FF3399',\n\t'#FF33CC',\n\t'#FF33FF',\n\t'#FF6600',\n\t'#FF6633',\n\t'#FF9900',\n\t'#FF9933',\n\t'#FFCC00',\n\t'#FFCC33'\n];\n\n/**\n * Currently only WebKit-based Web Inspectors, Firefox >= v31,\n * and the Firebug extension (any Firefox version) are known\n * to support \"%c\" CSS customizations.\n *\n * TODO: add a `localStorage` variable to explicitly enable/disable colors\n */\n\n// eslint-disable-next-line complexity\nfunction useColors() {\n\t// NB: In an Electron preload script, document will be defined but not fully\n\t// initialized. Since we know we're in Chrome, we'll just detect this case\n\t// explicitly\n\tif (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {\n\t\treturn true;\n\t}\n\n\t// Internet Explorer and Edge do not support colors.\n\tif (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\\/(\\d+)/)) {\n\t\treturn false;\n\t}\n\n\tlet m;\n\n\t// Is webkit? http://stackoverflow.com/a/16459606/376773\n\t// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632\n\t// eslint-disable-next-line no-return-assign\n\treturn (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||\n\t\t// Is firebug? http://stackoverflow.com/a/398120/376773\n\t\t(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||\n\t\t// Is firefox >= v31?\n\t\t// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages\n\t\t(typeof navigator !== 'undefined' && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\\/(\\d+)/)) && parseInt(m[1], 10) >= 31) ||\n\t\t// Double check webkit in userAgent just in case we are in a worker\n\t\t(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\\/(\\d+)/));\n}\n\n/**\n * Colorize log arguments if enabled.\n *\n * @api public\n */\n\nfunction formatArgs(args) {\n\targs[0] = (this.useColors ? '%c' : '') +\n\t\tthis.namespace +\n\t\t(this.useColors ? ' %c' : ' ') +\n\t\targs[0] +\n\t\t(this.useColors ? '%c ' : ' ') +\n\t\t'+' + module.exports.humanize(this.diff);\n\n\tif (!this.useColors) {\n\t\treturn;\n\t}\n\n\tconst c = 'color: ' + this.color;\n\targs.splice(1, 0, c, 'color: inherit');\n\n\t// The final \"%c\" is somewhat tricky, because there could be other\n\t// arguments passed either before or after the %c, so we need to\n\t// figure out the correct index to insert the CSS into\n\tlet index = 0;\n\tlet lastC = 0;\n\targs[0].replace(/%[a-zA-Z%]/g, match => {\n\t\tif (match === '%%') {\n\t\t\treturn;\n\t\t}\n\t\tindex++;\n\t\tif (match === '%c') {\n\t\t\t// We only are interested in the *last* %c\n\t\t\t// (the user may have provided their own)\n\t\t\tlastC = index;\n\t\t}\n\t});\n\n\targs.splice(lastC, 0, c);\n}\n\n/**\n * Invokes `console.debug()` when available.\n * No-op when `console.debug` is not a \"function\".\n * If `console.debug` is not available, falls back\n * to `console.log`.\n *\n * @api public\n */\nexports.log = console.debug || console.log || (() => {});\n\n/**\n * Save `namespaces`.\n *\n * @param {String} namespaces\n * @api private\n */\nfunction save(namespaces) {\n\ttry {\n\t\tif (namespaces) {\n\t\t\texports.storage.setItem('debug', namespaces);\n\t\t} else {\n\t\t\texports.storage.removeItem('debug');\n\t\t}\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n}\n\n/**\n * Load `namespaces`.\n *\n * @return {String} returns the previously persisted debug modes\n * @api private\n */\nfunction load() {\n\tlet r;\n\ttry {\n\t\tr = exports.storage.getItem('debug');\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n\n\t// If debug isn't set in LS, and we're in Electron, try to load $DEBUG\n\tif (!r && typeof process !== 'undefined' && 'env' in process) {\n\t\tr = ({\"MODE\":\"development\",\"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_PLUS_LP\":\"https://plus.excalidraw.com\",\"VITE_APP_PLUS_APP\":\"http://localhost:3000\",\"VITE_APP_AI_BACKEND\":\"http://localhost:3015\",\"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_DISABLE_LIVE_RELOAD\":\"\",\"VITE_APP_ENABLE_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_APP_ENABLE_PWA\":\"false\",\"VITE_APP_PLUS_EXPORT_PUBLIC_KEY\":\"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm2g5T+Rub6Kbf1Mf57t0\\n7r2zeHuVg4dla3r5ryXMswtzz6x767octl6oLThn33mQsPSy3GKglFZoCTXJR4ij\\nba8SxB04sL/N8eRrKja7TFWjCVtRwTTfyy771NYYNFVJclkxHyE5qw4m27crHF1y\\nUNWEjuqNMi/lwAErS9fFa2oJlWyT8U7zzv/5kQREkxZI6y9v0AF3qcbsy2731FnD\\ns9ChJvOUW9toIab2gsIdrKW8ZNpu084ZFVKb6LNjvIXI1Se4oMTHeszXzNptzlot\\nkdxxjOoaQMAyfljFSot1F1FlU6MQlag7UnFGvFjRHN1JI5q4K+n3a67DX+TMyRqS\\nHQIDAQAB\",\"VITE_APP_DISABLE_PREVENT_UNLOAD\":\"\",\"VITE_PKG_NAME\":\"@zsviczian/excalidraw\",\"VITE_PKG_VERSION\":\"0.18.0-54\",\"VITE_IS_EXCALIDRAW_NPM_PACKAGE\":true}).DEBUG;\n\t}\n\n\treturn r;\n}\n\n/**\n * Localstorage attempts to return the localstorage.\n *\n * This is necessary because safari throws\n * when a user disables cookies/localstorage\n * and you attempt to access it.\n *\n * @return {LocalStorage}\n * @api private\n */\n\nfunction localstorage() {\n\ttry {\n\t\t// TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context\n\t\t// The Browser also has localStorage in the global context.\n\t\treturn localStorage;\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n}\n\nmodule.exports = __webpack_require__(/*! ./common */ \"../../node_modules/micromark/node_modules/debug/src/common.js\")(exports);\n\nconst {formatters} = module.exports;\n\n/**\n * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.\n */\n\nformatters.j = function (v) {\n\ttry {\n\t\treturn JSON.stringify(v);\n\t} catch (error) {\n\t\treturn '[UnexpectedJSONParseError]: ' + error.message;\n\t}\n};\n\n\n//# sourceURL=webpack://ExcalidrawLib/../../node_modules/micromark/node_modules/debug/src/browser.js?");
11982
11982
 
11983
11983
  /***/ }),
11984
11984
 
@@ -13091,7 +13091,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
13091
13091
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
13092
13092
 
13093
13093
  "use strict";
13094
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ addEventListener: () => (/* binding */ addEventListener),\n/* harmony export */ allowFullScreen: () => (/* binding */ allowFullScreen),\n/* harmony export */ arrayToList: () => (/* binding */ arrayToList),\n/* harmony export */ arrayToMap: () => (/* binding */ arrayToMap),\n/* harmony export */ arrayToMapWithIndex: () => (/* binding */ arrayToMapWithIndex),\n/* harmony export */ arrayToObject: () => (/* binding */ arrayToObject),\n/* harmony export */ assertNever: () => (/* binding */ assertNever),\n/* harmony export */ bytesToHexString: () => (/* binding */ bytesToHexString),\n/* harmony export */ capitalizeString: () => (/* binding */ capitalizeString),\n/* harmony export */ castArray: () => (/* binding */ castArray),\n/* harmony export */ chunk: () => (/* binding */ chunk),\n/* harmony export */ cloneJSON: () => (/* binding */ cloneJSON),\n/* harmony export */ composeEventHandlers: () => (/* binding */ composeEventHandlers),\n/* harmony export */ debounce: () => (/* binding */ debounce),\n/* harmony export */ distance: () => (/* binding */ distance),\n/* harmony export */ easeOut: () => (/* binding */ easeOut),\n/* harmony export */ easeToValuesRAF: () => (/* binding */ easeToValuesRAF),\n/* harmony export */ escapeDoubleQuotes: () => (/* binding */ escapeDoubleQuotes),\n/* harmony export */ exitFullScreen: () => (/* binding */ exitFullScreen),\n/* harmony export */ findIndex: () => (/* binding */ findIndex),\n/* harmony export */ findLastIndex: () => (/* binding */ findLastIndex),\n/* harmony export */ focusNearestParent: () => (/* binding */ focusNearestParent),\n/* harmony export */ getDateTime: () => (/* binding */ getDateTime),\n/* harmony export */ getFeatureFlag: () => (/* binding */ getFeatureFlag),\n/* harmony export */ getFontFamilyString: () => (/* binding */ getFontFamilyString),\n/* harmony export */ getFontString: () => (/* binding */ getFontString),\n/* harmony export */ getFrame: () => (/* binding */ getFrame),\n/* harmony export */ getGlobalCSSVariable: () => (/* binding */ getGlobalCSSVariable),\n/* harmony export */ getNearestScrollableContainer: () => (/* binding */ getNearestScrollableContainer),\n/* harmony export */ getSvgPathFromStroke: () => (/* binding */ getSvgPathFromStroke),\n/* harmony export */ getUpdatedTimestamp: () => (/* binding */ getUpdatedTimestamp),\n/* harmony export */ getVersion: () => (/* binding */ getVersion),\n/* harmony export */ invariant: () => (/* binding */ invariant),\n/* harmony export */ isAnyTrue: () => (/* binding */ isAnyTrue),\n/* harmony export */ isDevEnv: () => (/* binding */ isDevEnv),\n/* harmony export */ isFullScreen: () => (/* binding */ isFullScreen),\n/* harmony export */ isInputLike: () => (/* binding */ isInputLike),\n/* harmony export */ isInteractive: () => (/* binding */ isInteractive),\n/* harmony export */ isMemberOf: () => (/* binding */ isMemberOf),\n/* harmony export */ isPrimitive: () => (/* binding */ isPrimitive),\n/* harmony export */ isProdEnv: () => (/* binding */ isProdEnv),\n/* harmony export */ isPromiseLike: () => (/* binding */ isPromiseLike),\n/* harmony export */ isRTL: () => (/* binding */ isRTL),\n/* harmony export */ isReadonlyArray: () => (/* binding */ isReadonlyArray),\n/* harmony export */ isRunningInIframe: () => (/* binding */ isRunningInIframe),\n/* harmony export */ isSelectionLikeTool: () => (/* binding */ isSelectionLikeTool),\n/* harmony export */ isServerEnv: () => (/* binding */ isServerEnv),\n/* harmony export */ isShallowEqual: () => (/* binding */ isShallowEqual),\n/* harmony export */ isTestEnv: () => (/* binding */ isTestEnv),\n/* harmony export */ isToolIcon: () => (/* binding */ isToolIcon),\n/* harmony export */ isTransparent: () => (/* binding */ isTransparent),\n/* harmony export */ isWritableElement: () => (/* binding */ isWritableElement),\n/* harmony export */ mapFind: () => (/* binding */ mapFind),\n/* harmony export */ memoize: () => (/* binding */ memoize),\n/* harmony export */ muteFSAbortError: () => (/* binding */ muteFSAbortError),\n/* harmony export */ nFormatter: () => (/* binding */ nFormatter),\n/* harmony export */ nextAnimationFrame: () => (/* binding */ nextAnimationFrame),\n/* harmony export */ normalizeEOL: () => (/* binding */ normalizeEOL),\n/* harmony export */ preventUnload: () => (/* binding */ preventUnload),\n/* harmony export */ promiseTry: () => (/* binding */ promiseTry),\n/* harmony export */ queryFocusableElements: () => (/* binding */ queryFocusableElements),\n/* harmony export */ reduceToCommonValue: () => (/* binding */ reduceToCommonValue),\n/* harmony export */ removeSelection: () => (/* binding */ removeSelection),\n/* harmony export */ resolvablePromise: () => (/* binding */ resolvablePromise),\n/* harmony export */ safelyParseJSON: () => (/* binding */ safelyParseJSON),\n/* harmony export */ sceneCoordsToViewportCoords: () => (/* binding */ sceneCoordsToViewportCoords),\n/* harmony export */ selectNode: () => (/* binding */ selectNode),\n/* harmony export */ setDateTimeForTests: () => (/* binding */ setDateTimeForTests),\n/* harmony export */ setFeatureFlag: () => (/* binding */ setFeatureFlag),\n/* harmony export */ sizeOf: () => (/* binding */ sizeOf),\n/* harmony export */ supportsEmoji: () => (/* binding */ supportsEmoji),\n/* harmony export */ throttleRAF: () => (/* binding */ throttleRAF),\n/* harmony export */ toArray: () => (/* binding */ toArray),\n/* harmony export */ toBrandedType: () => (/* binding */ toBrandedType),\n/* harmony export */ toIterable: () => (/* binding */ toIterable),\n/* harmony export */ tupleToCoors: () => (/* binding */ tupleToCoors),\n/* harmony export */ updateActiveTool: () => (/* binding */ updateActiveTool),\n/* harmony export */ updateObject: () => (/* binding */ updateObject),\n/* harmony export */ updateStable: () => (/* binding */ updateStable),\n/* harmony export */ viewportCoordsToSceneCoords: () => (/* binding */ viewportCoordsToSceneCoords),\n/* harmony export */ wrapEvent: () => (/* binding */ wrapEvent)\n/* harmony export */ });\n/* harmony import */ var _excalidraw_math__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @excalidraw/math */ \"../math/src/index.ts\");\n/* harmony import */ var _colors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./colors */ \"../common/src/colors.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./constants */ \"../common/src/constants.ts\");\n\n\n\nlet mockDateTime = null;\nconst setDateTimeForTests = dateTime => {\n mockDateTime = dateTime;\n};\nconst getDateTime = () => {\n if (mockDateTime) {\n return mockDateTime;\n }\n\n const date = new Date();\n const year = date.getFullYear();\n const month = `${date.getMonth() + 1}`.padStart(2, \"0\");\n const day = `${date.getDate()}`.padStart(2, \"0\");\n const hr = `${date.getHours()}`.padStart(2, \"0\");\n const min = `${date.getMinutes()}`.padStart(2, \"0\");\n return `${year}-${month}-${day}-${hr}${min}`;\n};\nconst capitalizeString = str => str.charAt(0).toUpperCase() + str.slice(1);\nconst isToolIcon = target => target instanceof HTMLElement && target.className.includes(\"ToolIcon\");\nconst isInputLike = target => target instanceof HTMLElement && target.dataset.type === \"wysiwyg\" || target instanceof HTMLBRElement || // newline in wysiwyg\ntarget instanceof HTMLInputElement || target instanceof HTMLTextAreaElement || target instanceof HTMLSelectElement;\nconst isInteractive = target => {\n return isInputLike(target) || target instanceof Element && !!target.closest(\"label, button\");\n};\nconst isWritableElement = target => target instanceof HTMLElement && target.dataset.type === \"wysiwyg\" || target instanceof HTMLBRElement || // newline in wysiwyg\ntarget instanceof HTMLTextAreaElement || target instanceof HTMLInputElement && (target.type === \"text\" || target.type === \"number\" || target.type === \"password\" || target.type === \"search\");\nconst getFontFamilyString = ({\n fontFamily\n}) => {\n for (const [fontFamilyString, id] of Object.entries(_constants__WEBPACK_IMPORTED_MODULE_2__.FONT_FAMILY)) {\n if (id === fontFamily) {\n return `${fontFamilyString}${(0,_constants__WEBPACK_IMPORTED_MODULE_2__.getFontFamilyFallbacks)(id).map(x => `, ${x}`).join(\"\")}`;\n }\n }\n\n return _constants__WEBPACK_IMPORTED_MODULE_2__.WINDOWS_EMOJI_FALLBACK_FONT;\n};\n/** returns fontSize+fontFamily string for assignment to DOM elements */\n\nconst getFontString = ({\n fontSize,\n fontFamily\n}) => {\n return `${fontSize}px ${getFontFamilyString({\n fontFamily\n })}`;\n};\n/** executes callback in the frame that's after the current one */\n\nconst nextAnimationFrame = async cb => {\n requestAnimationFrame(() => requestAnimationFrame(cb));\n};\nconst debounce = (fn, timeout) => {\n let handle = 0;\n let lastArgs = null;\n\n const ret = (...args) => {\n lastArgs = args;\n clearTimeout(handle);\n handle = window.setTimeout(() => {\n lastArgs = null;\n fn(...args);\n }, timeout);\n };\n\n ret.flush = () => {\n clearTimeout(handle);\n\n if (lastArgs) {\n const _lastArgs = lastArgs;\n lastArgs = null;\n fn(..._lastArgs);\n }\n };\n\n ret.cancel = () => {\n lastArgs = null;\n clearTimeout(handle);\n };\n\n return ret;\n}; // throttle callback to execute once per animation frame\n\nconst throttleRAF = (fn, opts) => {\n let timerId = null;\n let lastArgs = null;\n let lastArgsTrailing = null;\n\n const scheduleFunc = args => {\n timerId = window.requestAnimationFrame(() => {\n timerId = null;\n fn(...args);\n lastArgs = null;\n\n if (lastArgsTrailing) {\n lastArgs = lastArgsTrailing;\n lastArgsTrailing = null;\n scheduleFunc(lastArgs);\n }\n });\n };\n\n const ret = (...args) => {\n if (isTestEnv()) {\n fn(...args);\n return;\n }\n\n lastArgs = args;\n\n if (timerId === null) {\n scheduleFunc(lastArgs);\n } else if (opts === null || opts === void 0 ? void 0 : opts.trailing) {\n lastArgsTrailing = args;\n }\n };\n\n ret.flush = () => {\n if (timerId !== null) {\n cancelAnimationFrame(timerId);\n timerId = null;\n }\n\n if (lastArgs) {\n fn(...(lastArgsTrailing || lastArgs));\n lastArgs = lastArgsTrailing = null;\n }\n };\n\n ret.cancel = () => {\n lastArgs = lastArgsTrailing = null;\n\n if (timerId !== null) {\n cancelAnimationFrame(timerId);\n timerId = null;\n }\n };\n\n return ret;\n};\n/**\r\n * Exponential ease-out method\r\n *\r\n * @param {number} k - The value to be tweened.\r\n * @returns {number} The tweened value.\r\n */\n\nconst easeOut = k => {\n return 1 - Math.pow(1 - k, 4);\n};\n\nconst easeOutInterpolate = (from, to, progress) => {\n return (to - from) * easeOut(progress) + from;\n};\n/**\r\n * Animates values from `fromValues` to `toValues` using the requestAnimationFrame API.\r\n * Executes the `onStep` callback on each step with the interpolated values.\r\n * Returns a function that can be called to cancel the animation.\r\n *\r\n * @example\r\n * // Example usage:\r\n * const fromValues = { x: 0, y: 0 };\r\n * const toValues = { x: 100, y: 200 };\r\n * const onStep = ({x, y}) => {\r\n * setState(x, y)\r\n * };\r\n * const onCancel = () => {\r\n * console.log(\"Animation canceled\");\r\n * };\r\n *\r\n * const cancelAnimation = easeToValuesRAF({\r\n * fromValues,\r\n * toValues,\r\n * onStep,\r\n * onCancel,\r\n * });\r\n *\r\n * // To cancel the animation:\r\n * cancelAnimation();\r\n */\n\n\nconst easeToValuesRAF = ({\n fromValues,\n toValues,\n onStep,\n duration = 250,\n interpolateValue,\n onStart,\n onEnd,\n onCancel\n}) => {\n let canceled = false;\n let frameId = 0;\n let startTime;\n\n function step(timestamp) {\n if (canceled) {\n return;\n }\n\n if (startTime === undefined) {\n startTime = timestamp;\n onStart === null || onStart === void 0 ? void 0 : onStart();\n }\n\n const elapsed = Math.min(timestamp - startTime, duration);\n const factor = easeOut(elapsed / duration);\n const newValues = {};\n Object.keys(fromValues).forEach(key => {\n const _key = key;\n const result = (toValues[_key] - fromValues[_key]) * factor + fromValues[_key];\n newValues[_key] = result;\n });\n onStep(newValues);\n\n if (elapsed < duration) {\n const progress = elapsed / duration;\n const newValues = {};\n Object.keys(fromValues).forEach(key => {\n const _key = key;\n const startValue = fromValues[_key];\n const endValue = toValues[_key];\n let result;\n result = interpolateValue ? interpolateValue(startValue, endValue, progress, _key) : easeOutInterpolate(startValue, endValue, progress);\n\n if (result == null) {\n result = easeOutInterpolate(startValue, endValue, progress);\n }\n\n newValues[_key] = result;\n });\n onStep(newValues);\n frameId = window.requestAnimationFrame(step);\n } else {\n onStep(toValues);\n onEnd === null || onEnd === void 0 ? void 0 : onEnd();\n }\n }\n\n frameId = window.requestAnimationFrame(step);\n return () => {\n onCancel === null || onCancel === void 0 ? void 0 : onCancel();\n canceled = true;\n window.cancelAnimationFrame(frameId);\n };\n}; // https://github.com/lodash/lodash/blob/es/chunk.js\n\nconst chunk = (array, size) => {\n if (!array.length || size < 1) {\n return [];\n }\n\n let index = 0;\n let resIndex = 0;\n const result = Array(Math.ceil(array.length / size));\n\n while (index < array.length) {\n result[resIndex++] = array.slice(index, index += size);\n }\n\n return result;\n};\nconst selectNode = node => {\n const selection = window.getSelection();\n\n if (selection) {\n const range = document.createRange();\n range.selectNodeContents(node);\n selection.removeAllRanges();\n selection.addRange(range);\n }\n};\nconst removeSelection = () => {\n const selection = window.getSelection();\n\n if (selection) {\n selection.removeAllRanges();\n }\n};\nconst distance = (x, y) => Math.abs(x - y);\nconst isSelectionLikeTool = type => {\n return type === \"selection\" || type === \"lasso\";\n};\nconst updateActiveTool = (appState, data) => {\n var _a, _b, _c;\n\n if (data.type === \"custom\") {\n return Object.assign(Object.assign({}, appState.activeTool), {\n type: \"custom\",\n customType: data.customType,\n locked: (_a = data.locked) !== null && _a !== void 0 ? _a : appState.activeTool.locked\n });\n }\n\n return Object.assign(Object.assign({}, appState.activeTool), {\n lastActiveTool: data.lastActiveToolBeforeEraser === undefined ? appState.activeTool.lastActiveTool : data.lastActiveToolBeforeEraser,\n type: data.type,\n customType: null,\n locked: (_b = data.locked) !== null && _b !== void 0 ? _b : appState.activeTool.locked,\n fromSelection: (_c = data.fromSelection) !== null && _c !== void 0 ? _c : false\n });\n};\nconst isFullScreen = () => {\n var _a;\n\n return ((_a = document.fullscreenElement) === null || _a === void 0 ? void 0 : _a.nodeName) === \"HTML\";\n};\nconst allowFullScreen = () => document.documentElement.requestFullscreen();\nconst exitFullScreen = () => document.exitFullscreen();\nconst viewportCoordsToSceneCoords = ({\n clientX,\n clientY\n}, {\n zoom,\n offsetLeft,\n offsetTop,\n scrollX,\n scrollY\n}) => {\n const x = (clientX - offsetLeft) / zoom.value - scrollX;\n const y = (clientY - offsetTop) / zoom.value - scrollY;\n return {\n x,\n y\n };\n};\nconst sceneCoordsToViewportCoords = ({\n sceneX,\n sceneY\n}, {\n zoom,\n offsetLeft,\n offsetTop,\n scrollX,\n scrollY\n}) => {\n const x = (sceneX + scrollX) * zoom.value + offsetLeft;\n const y = (sceneY + scrollY) * zoom.value + offsetTop;\n return {\n x,\n y\n };\n};\nconst getGlobalCSSVariable = name => getComputedStyle(document.documentElement).getPropertyValue(`--${name}`);\nconst RS_LTR_CHARS = \"A-Za-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02B8\\u0300-\\u0590\\u0800-\\u1FFF\" + \"\\u2C00-\\uFB1C\\uFDFE-\\uFE6F\\uFEFD-\\uFFFF\";\nconst RS_RTL_CHARS = \"\\u0591-\\u07FF\\uFB1D-\\uFDFD\\uFE70-\\uFEFC\";\nconst RE_RTL_CHECK = new RegExp(`^[^${RS_LTR_CHARS}]*[${RS_RTL_CHARS}]`);\n/**\r\n * Checks whether first directional character is RTL. Meaning whether it starts\r\n * with RTL characters, or indeterminate (numbers etc.) characters followed by\r\n * RTL.\r\n * See https://github.com/excalidraw/excalidraw/pull/1722#discussion_r436340171\r\n */\n\nconst isRTL = text => RE_RTL_CHECK.test(text);\nconst tupleToCoors = xyTuple => {\n const [x, y] = xyTuple;\n return {\n x,\n y\n };\n};\n/** use as a rejectionHandler to mute filesystem Abort errors */\n\nconst muteFSAbortError = error => {\n if ((error === null || error === void 0 ? void 0 : error.name) === \"AbortError\") {\n console.warn(error);\n return;\n }\n\n throw error;\n};\nconst findIndex = (array, cb, fromIndex = 0) => {\n if (fromIndex < 0) {\n fromIndex = array.length + fromIndex;\n }\n\n fromIndex = Math.min(array.length, Math.max(fromIndex, 0));\n let index = fromIndex - 1;\n\n while (++index < array.length) {\n if (cb(array[index], index, array)) {\n return index;\n }\n }\n\n return -1;\n};\nconst findLastIndex = (array, cb, fromIndex = array.length - 1) => {\n if (fromIndex < 0) {\n fromIndex = array.length + fromIndex;\n }\n\n fromIndex = Math.min(array.length - 1, Math.max(fromIndex, 0));\n let index = fromIndex + 1;\n\n while (--index > -1) {\n if (cb(array[index], index, array)) {\n return index;\n }\n }\n\n return -1;\n};\n/** returns the first non-null mapped value */\n\nconst mapFind = (collection, iteratee) => {\n for (let idx = 0; idx < collection.length; idx++) {\n const result = iteratee(collection[idx], idx);\n\n if (result != null) {\n return result;\n }\n }\n\n return undefined;\n};\nconst isTransparent = color => {\n const isRGBTransparent = color.length === 5 && color.substr(4, 1) === \"0\";\n const isRRGGBBTransparent = color.length === 9 && color.substr(7, 2) === \"00\";\n return isRGBTransparent || isRRGGBBTransparent || color === _colors__WEBPACK_IMPORTED_MODULE_1__.COLOR_PALETTE.transparent;\n};\nconst resolvablePromise = () => {\n let resolve;\n let reject;\n const promise = new Promise((_resolve, _reject) => {\n resolve = _resolve;\n reject = _reject;\n });\n promise.resolve = resolve;\n promise.reject = reject;\n return promise;\n}; //https://stackoverflow.com/a/9462382/8418\n\nconst nFormatter = (num, digits) => {\n const si = [{\n value: 1,\n symbol: \"b\"\n }, {\n value: 1e3,\n symbol: \"k\"\n }, {\n value: 1e6,\n symbol: \"M\"\n }, {\n value: 1e9,\n symbol: \"G\"\n }];\n const rx = /\\.0+$|(\\.[0-9]*[1-9])0+$/;\n let index;\n\n for (index = si.length - 1; index > 0; index--) {\n if (num >= si[index].value) {\n break;\n }\n }\n\n return (num / si[index].value).toFixed(digits).replace(rx, \"$1\") + si[index].symbol;\n};\nconst getVersion = () => {\n var _a;\n\n return ((_a = document.querySelector('meta[name=\"version\"]')) === null || _a === void 0 ? void 0 : _a.content) || _constants__WEBPACK_IMPORTED_MODULE_2__.DEFAULT_VERSION;\n}; // Adapted from https://github.com/Modernizr/Modernizr/blob/master/feature-detects/emoji.js\n\nconst supportsEmoji = () => {\n const canvas = document.createElement(\"canvas\");\n const ctx = canvas.getContext(\"2d\");\n\n if (!ctx) {\n return false;\n }\n\n const offset = 12;\n ctx.fillStyle = \"#f00\";\n ctx.textBaseline = \"top\";\n ctx.font = \"32px Arial\"; // Modernizr used 🐨, but it is sort of supported on Windows 7.\n // Luckily 😀 isn't supported.\n\n ctx.fillText(\"😀\", 0, 0);\n return ctx.getImageData(offset, offset, 1, 1).data[0] !== 0;\n};\nconst getNearestScrollableContainer = element => {\n let parent = element.parentElement;\n\n while (parent) {\n if (parent === document.body) {\n return document;\n }\n\n const {\n overflowY\n } = window.getComputedStyle(parent);\n const hasScrollableContent = parent.scrollHeight > parent.clientHeight;\n\n if (hasScrollableContent && (overflowY === \"auto\" || overflowY === \"scroll\" || overflowY === \"overlay\")) {\n return parent;\n }\n\n parent = parent.parentElement;\n }\n\n return document;\n};\nconst focusNearestParent = element => {\n let parent = element.parentElement;\n\n while (parent) {\n if (parent.tabIndex > -1) {\n parent.focus();\n return;\n }\n\n parent = parent.parentElement;\n }\n};\nconst preventUnload = event => {\n event.preventDefault(); // NOTE: modern browsers no longer allow showing a custom message here\n\n event.returnValue = \"\";\n};\nconst bytesToHexString = bytes => {\n return Array.from(bytes).map(byte => `0${byte.toString(16)}`.slice(-2)).join(\"\");\n};\nconst getUpdatedTimestamp = () => isTestEnv() ? 1 : Date.now();\n/**\r\n * Transforms array of objects containing `id` attribute,\r\n * or array of ids (strings), into a Map, keyd by `id`.\r\n */\n\nconst arrayToMap = items => {\n if (items instanceof Map) {\n return items;\n }\n\n return items.reduce((acc, element) => {\n acc.set(typeof element === \"string\" ? element : element.id, element);\n return acc;\n }, new Map());\n};\nconst arrayToMapWithIndex = elements => elements.reduce((acc, element, idx) => {\n acc.set(element.id, [element, idx]);\n return acc;\n}, new Map());\n/**\r\n * Transform array into an object, use only when array order is irrelevant.\r\n */\n\nconst arrayToObject = (array, groupBy) => array.reduce((acc, value, idx) => {\n acc[groupBy ? groupBy(value) : idx] = value;\n return acc;\n}, {});\n/**\r\n * Creates a circular doubly linked list by adding `prev` and `next` props to the existing array nodes.\r\n */\n\nconst arrayToList = array => array.reduce((acc, curr, index) => {\n const node = Object.assign(Object.assign({}, curr), {\n prev: null,\n next: null\n }); // no-op for first item, we don't want circular references on a single item\n\n if (index !== 0) {\n const prevNode = acc[index - 1];\n node.prev = prevNode;\n prevNode.next = node;\n\n if (index === array.length - 1) {\n // make the references circular and connect head & tail\n const firstNode = acc[0];\n node.next = firstNode;\n firstNode.prev = node;\n }\n }\n\n acc.push(node);\n return acc;\n}, []);\n/**\r\n * Converts a readonly array or map into an iterable.\r\n * Useful for avoiding entry allocations when iterating object / map on each iteration.\r\n */\n\nconst toIterable = values => {\n return Array.isArray(values) ? values : values.values();\n};\n/**\r\n * Converts a readonly array or map into an array.\r\n */\n\nconst toArray = values => {\n return Array.isArray(values) ? values : Array.from(toIterable(values));\n};\nconst isTestEnv = () => \"development\" === _constants__WEBPACK_IMPORTED_MODULE_2__.ENV.TEST;\nconst isDevEnv = () => \"development\" === _constants__WEBPACK_IMPORTED_MODULE_2__.ENV.DEVELOPMENT;\nconst isProdEnv = () => \"development\" === _constants__WEBPACK_IMPORTED_MODULE_2__.ENV.PRODUCTION;\nconst isServerEnv = () => {\n var _a;\n\n return typeof process !== \"undefined\" && !!((_a = process === null || process === void 0 ? void 0 : ({\"MODE\":\"development\",\"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_PLUS_LP\":\"https://plus.excalidraw.com\",\"VITE_APP_PLUS_APP\":\"http://localhost:3000\",\"VITE_APP_AI_BACKEND\":\"http://localhost:3015\",\"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_DISABLE_LIVE_RELOAD\":\"\",\"VITE_APP_ENABLE_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_APP_ENABLE_PWA\":\"false\",\"VITE_APP_PLUS_EXPORT_PUBLIC_KEY\":\"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm2g5T+Rub6Kbf1Mf57t0\\n7r2zeHuVg4dla3r5ryXMswtzz6x767octl6oLThn33mQsPSy3GKglFZoCTXJR4ij\\nba8SxB04sL/N8eRrKja7TFWjCVtRwTTfyy771NYYNFVJclkxHyE5qw4m27crHF1y\\nUNWEjuqNMi/lwAErS9fFa2oJlWyT8U7zzv/5kQREkxZI6y9v0AF3qcbsy2731FnD\\ns9ChJvOUW9toIab2gsIdrKW8ZNpu084ZFVKb6LNjvIXI1Se4oMTHeszXzNptzlot\\nkdxxjOoaQMAyfljFSot1F1FlU6MQlag7UnFGvFjRHN1JI5q4K+n3a67DX+TMyRqS\\nHQIDAQAB\",\"VITE_APP_DISABLE_PREVENT_UNLOAD\":\"\",\"VITE_PKG_NAME\":\"@zsviczian/excalidraw\",\"VITE_PKG_VERSION\":\"0.18.0-53\",\"VITE_IS_EXCALIDRAW_NPM_PACKAGE\":true})) === null || _a === void 0 ? void 0 : _a.NODE_ENV);\n};\nconst wrapEvent = (name, nativeEvent) => {\n return new CustomEvent(name, {\n detail: {\n nativeEvent\n },\n cancelable: true\n });\n};\nconst updateObject = (obj, updates) => {\n let didChange = false;\n\n for (const key in updates) {\n const value = updates[key];\n\n if (typeof value !== \"undefined\") {\n if (obj[key] === value && ( // if object, always update because its attrs could have changed\n typeof value !== \"object\" || value === null)) {\n continue;\n }\n\n didChange = true;\n }\n }\n\n if (!didChange) {\n return obj;\n }\n\n return Object.assign(Object.assign({}, obj), updates);\n};\nconst isPrimitive = val => {\n const type = typeof val;\n return val == null || type !== \"object\" && type !== \"function\";\n};\nconst getFrame = () => {\n try {\n return window.self === window.top ? \"top\" : \"iframe\";\n } catch (error) {\n return \"iframe\";\n }\n};\nconst isRunningInIframe = () => getFrame() === \"iframe\";\nconst isPromiseLike = value => {\n return !!value && typeof value === \"object\" && \"then\" in value && \"catch\" in value && \"finally\" in value;\n};\nconst queryFocusableElements = container => {\n const focusableElements = container === null || container === void 0 ? void 0 : container.querySelectorAll(\"button, a, input, select, textarea, div[tabindex], label[tabindex]\");\n return focusableElements ? Array.from(focusableElements).filter(element => element.tabIndex > -1 && !element.disabled) : [];\n};\n/** use as a fallback after identity check (for perf reasons) */\n\nconst _defaultIsShallowComparatorFallback = (a, b) => {\n // consider two empty arrays equal\n if (Array.isArray(a) && Array.isArray(b) && a.length === 0 && b.length === 0) {\n return true;\n }\n\n return a === b;\n};\n/**\r\n * Returns whether object/array is shallow equal.\r\n * Considers empty object/arrays as equal (whether top-level or second-level).\r\n */\n\n\nconst isShallowEqual = (objA, objB, comparators, debug = false) => {\n const aKeys = Object.keys(objA);\n const bKeys = Object.keys(objB);\n\n if (aKeys.length !== bKeys.length) {\n if (debug) {\n console.warn(`%cisShallowEqual: objects don't have same properties ->`, \"color: #8B4000\", objA, objB);\n }\n\n return false;\n }\n\n if (comparators && Array.isArray(comparators)) {\n for (const key of comparators) {\n const ret = objA[key] === objB[key] || _defaultIsShallowComparatorFallback(objA[key], objB[key]);\n\n if (!ret) {\n if (debug) {\n console.warn(`%cisShallowEqual: ${key} not equal ->`, \"color: #8B4000\", objA[key], objB[key]);\n }\n\n return false;\n }\n }\n\n return true;\n }\n\n return aKeys.every(key => {\n const comparator = comparators === null || comparators === void 0 ? void 0 : comparators[key];\n const ret = comparator ? comparator(objA[key], objB[key]) : objA[key] === objB[key] || _defaultIsShallowComparatorFallback(objA[key], objB[key]);\n\n if (!ret && debug) {\n console.warn(`%cisShallowEqual: ${key} not equal ->`, \"color: #8B4000\", objA[key], objB[key]);\n }\n\n return ret;\n });\n}; // taken from Radix UI\n// https://github.com/radix-ui/primitives/blob/main/packages/core/primitive/src/primitive.tsx\n\nconst composeEventHandlers = (originalEventHandler, ourEventHandler, {\n checkForDefaultPrevented = true\n} = {}) => {\n return function handleEvent(event) {\n originalEventHandler === null || originalEventHandler === void 0 ? void 0 : originalEventHandler(event);\n\n if (!checkForDefaultPrevented || !(event === null || event === void 0 ? void 0 : event.defaultPrevented)) {\n return ourEventHandler === null || ourEventHandler === void 0 ? void 0 : ourEventHandler(event);\n }\n };\n};\n/**\r\n * supply `null` as message if non-never value is valid, you just need to\r\n * typecheck against it\r\n */\n\nconst assertNever = (value, message, softAssert) => {\n if (!message) {\n return value;\n }\n\n if (softAssert) {\n console.error(message);\n return value;\n }\n\n throw new Error(message);\n};\nfunction invariant(condition, message) {\n if (!condition) {\n throw new Error(message);\n }\n}\n/**\r\n * Memoizes on values of `opts` object (strict equality).\r\n */\n\nconst memoize = func => {\n let lastArgs;\n let lastResult;\n\n const ret = function (opts) {\n const currentArgs = Object.entries(opts);\n\n if (lastArgs) {\n let argsAreEqual = true;\n\n for (const [key, value] of currentArgs) {\n if (lastArgs.get(key) !== value) {\n argsAreEqual = false;\n break;\n }\n }\n\n if (argsAreEqual) {\n return lastResult;\n }\n }\n\n const result = func(opts);\n lastArgs = new Map(currentArgs);\n lastResult = result;\n return result;\n };\n\n ret.clear = () => {\n lastArgs = undefined;\n lastResult = undefined;\n };\n\n return ret;\n};\n/** Checks if value is inside given collection. Useful for type-safety. */\n\nconst isMemberOf = (\n/** Set/Map/Array/Object */\ncollection,\n/** value to look for */\nvalue) => {\n return collection instanceof Set || collection instanceof Map ? collection.has(value) : \"includes\" in collection ? collection.includes(value) : collection.hasOwnProperty(value);\n};\nconst cloneJSON = obj => JSON.parse(JSON.stringify(obj));\nconst updateStable = (prevValue, nextValue) => {\n if (isShallowEqual(prevValue, nextValue)) {\n return prevValue;\n }\n\n return nextValue;\n}; // implem\n\nfunction addEventListener(\n/**\r\n * allows for falsy values so you don't have to type check when adding\r\n * event listeners to optional elements\r\n */\ntarget, type, listener, options) {\n var _a;\n\n if (!target) {\n return () => {};\n }\n\n (_a = target === null || target === void 0 ? void 0 : target.addEventListener) === null || _a === void 0 ? void 0 : _a.call(target, type, listener, options);\n return () => {\n var _a;\n\n (_a = target === null || target === void 0 ? void 0 : target.removeEventListener) === null || _a === void 0 ? void 0 : _a.call(target, type, listener, options);\n };\n}\nfunction getSvgPathFromStroke(points, closed = true) {\n const len = points.length;\n\n if (len < 4) {\n return ``;\n }\n\n let a = points[0];\n let b = points[1];\n const c = points[2];\n let result = `M${a[0].toFixed(2)},${a[1].toFixed(2)} Q${b[0].toFixed(2)},${b[1].toFixed(2)} ${(0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_0__.average)(b[0], c[0]).toFixed(2)},${(0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_0__.average)(b[1], c[1]).toFixed(2)} T`;\n\n for (let i = 2, max = len - 1; i < max; i++) {\n a = points[i];\n b = points[i + 1];\n result += `${(0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_0__.average)(a[0], b[0]).toFixed(2)},${(0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_0__.average)(a[1], b[1]).toFixed(2)} `;\n }\n\n if (closed) {\n result += \"Z\";\n }\n\n return result;\n}\nconst normalizeEOL = str => {\n return str.replace(/\\r?\\n|\\r/g, \"\\n\");\n};\n/**\r\n * Makes type into a branded type, ensuring that value is assignable to\r\n * the base ubranded type. Optionally you can explicitly supply current value\r\n * type to combine both (useful for composite branded types. Make sure you\r\n * compose branded types which are not composite themselves.)\r\n */\n\nconst toBrandedType = value => {\n return value;\n}; // -----------------------------------------------------------------------------\n// Promise.try, adapted from https://github.com/sindresorhus/p-try\n\nconst promiseTry = async (fn, ...args) => {\n return new Promise(resolve => {\n resolve(fn(...args));\n });\n};\nconst isAnyTrue = (...args) => Math.max(...args.map(arg => arg ? 1 : 0)) > 0;\nconst safelyParseJSON = json => {\n try {\n return JSON.parse(json);\n } catch (_a) {\n return null;\n }\n};\n/**\r\n * use when you need to render unsafe string as HTML attribute, but MAKE SURE\r\n * the attribute is double-quoted when constructing the HTML string\r\n */\n\nconst escapeDoubleQuotes = str => {\n return str.replace(/\"/g, \"&quot;\");\n};\nconst castArray = value => Array.isArray(value) ? value : [value];\n/** hack for Array.isArray type guard not working with readonly value[] */\n\nconst isReadonlyArray = value => {\n return Array.isArray(value);\n};\nconst sizeOf = value => {\n return isReadonlyArray(value) ? value.length : value instanceof Map || value instanceof Set ? value.size : Object.keys(value).length;\n};\nconst reduceToCommonValue = (collection, getValue) => {\n if (sizeOf(collection) === 0) {\n return null;\n }\n\n const valueExtractor = getValue || (item => item);\n\n let commonValue = null;\n\n for (const item of collection) {\n const value = valueExtractor(item);\n\n if ((commonValue === null || commonValue === value) && value != null) {\n commonValue = value;\n } else {\n return null;\n }\n }\n\n return commonValue;\n};\nconst FEATURE_FLAGS_STORAGE_KEY = \"excalidraw-feature-flags\";\nconst DEFAULT_FEATURE_FLAGS = {\n COMPLEX_BINDINGS: false\n};\nlet featureFlags = null;\nconst getFeatureFlag = flag => {\n if (!featureFlags) {\n try {\n const serializedFlags = localStorage.getItem(FEATURE_FLAGS_STORAGE_KEY);\n\n if (serializedFlags) {\n const flags = JSON.parse(serializedFlags);\n featureFlags = flags !== null && flags !== void 0 ? flags : DEFAULT_FEATURE_FLAGS;\n }\n } catch (_a) {}\n }\n\n return (featureFlags || DEFAULT_FEATURE_FLAGS)[flag];\n};\nconst setFeatureFlag = (flag, value) => {\n try {\n featureFlags = Object.assign(Object.assign({}, featureFlags || DEFAULT_FEATURE_FLAGS), {\n [flag]: value\n });\n localStorage.setItem(FEATURE_FLAGS_STORAGE_KEY, JSON.stringify(featureFlags));\n } catch (e) {\n console.error(\"unable to set feature flag\", e);\n }\n};\n\n//# sourceURL=webpack://ExcalidrawLib/../common/src/utils.ts?");
13094
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ addEventListener: () => (/* binding */ addEventListener),\n/* harmony export */ allowFullScreen: () => (/* binding */ allowFullScreen),\n/* harmony export */ arrayToList: () => (/* binding */ arrayToList),\n/* harmony export */ arrayToMap: () => (/* binding */ arrayToMap),\n/* harmony export */ arrayToMapWithIndex: () => (/* binding */ arrayToMapWithIndex),\n/* harmony export */ arrayToObject: () => (/* binding */ arrayToObject),\n/* harmony export */ assertNever: () => (/* binding */ assertNever),\n/* harmony export */ bytesToHexString: () => (/* binding */ bytesToHexString),\n/* harmony export */ capitalizeString: () => (/* binding */ capitalizeString),\n/* harmony export */ castArray: () => (/* binding */ castArray),\n/* harmony export */ chunk: () => (/* binding */ chunk),\n/* harmony export */ cloneJSON: () => (/* binding */ cloneJSON),\n/* harmony export */ composeEventHandlers: () => (/* binding */ composeEventHandlers),\n/* harmony export */ debounce: () => (/* binding */ debounce),\n/* harmony export */ distance: () => (/* binding */ distance),\n/* harmony export */ easeOut: () => (/* binding */ easeOut),\n/* harmony export */ easeToValuesRAF: () => (/* binding */ easeToValuesRAF),\n/* harmony export */ escapeDoubleQuotes: () => (/* binding */ escapeDoubleQuotes),\n/* harmony export */ exitFullScreen: () => (/* binding */ exitFullScreen),\n/* harmony export */ findIndex: () => (/* binding */ findIndex),\n/* harmony export */ findLastIndex: () => (/* binding */ findLastIndex),\n/* harmony export */ focusNearestParent: () => (/* binding */ focusNearestParent),\n/* harmony export */ getDateTime: () => (/* binding */ getDateTime),\n/* harmony export */ getFeatureFlag: () => (/* binding */ getFeatureFlag),\n/* harmony export */ getFontFamilyString: () => (/* binding */ getFontFamilyString),\n/* harmony export */ getFontString: () => (/* binding */ getFontString),\n/* harmony export */ getFrame: () => (/* binding */ getFrame),\n/* harmony export */ getGlobalCSSVariable: () => (/* binding */ getGlobalCSSVariable),\n/* harmony export */ getNearestScrollableContainer: () => (/* binding */ getNearestScrollableContainer),\n/* harmony export */ getSvgPathFromStroke: () => (/* binding */ getSvgPathFromStroke),\n/* harmony export */ getUpdatedTimestamp: () => (/* binding */ getUpdatedTimestamp),\n/* harmony export */ getVersion: () => (/* binding */ getVersion),\n/* harmony export */ invariant: () => (/* binding */ invariant),\n/* harmony export */ isAnyTrue: () => (/* binding */ isAnyTrue),\n/* harmony export */ isDevEnv: () => (/* binding */ isDevEnv),\n/* harmony export */ isFullScreen: () => (/* binding */ isFullScreen),\n/* harmony export */ isInputLike: () => (/* binding */ isInputLike),\n/* harmony export */ isInteractive: () => (/* binding */ isInteractive),\n/* harmony export */ isMemberOf: () => (/* binding */ isMemberOf),\n/* harmony export */ isPrimitive: () => (/* binding */ isPrimitive),\n/* harmony export */ isProdEnv: () => (/* binding */ isProdEnv),\n/* harmony export */ isPromiseLike: () => (/* binding */ isPromiseLike),\n/* harmony export */ isRTL: () => (/* binding */ isRTL),\n/* harmony export */ isReadonlyArray: () => (/* binding */ isReadonlyArray),\n/* harmony export */ isRunningInIframe: () => (/* binding */ isRunningInIframe),\n/* harmony export */ isSelectionLikeTool: () => (/* binding */ isSelectionLikeTool),\n/* harmony export */ isServerEnv: () => (/* binding */ isServerEnv),\n/* harmony export */ isShallowEqual: () => (/* binding */ isShallowEqual),\n/* harmony export */ isTestEnv: () => (/* binding */ isTestEnv),\n/* harmony export */ isToolIcon: () => (/* binding */ isToolIcon),\n/* harmony export */ isTransparent: () => (/* binding */ isTransparent),\n/* harmony export */ isWritableElement: () => (/* binding */ isWritableElement),\n/* harmony export */ mapFind: () => (/* binding */ mapFind),\n/* harmony export */ memoize: () => (/* binding */ memoize),\n/* harmony export */ muteFSAbortError: () => (/* binding */ muteFSAbortError),\n/* harmony export */ nFormatter: () => (/* binding */ nFormatter),\n/* harmony export */ nextAnimationFrame: () => (/* binding */ nextAnimationFrame),\n/* harmony export */ normalizeEOL: () => (/* binding */ normalizeEOL),\n/* harmony export */ preventUnload: () => (/* binding */ preventUnload),\n/* harmony export */ promiseTry: () => (/* binding */ promiseTry),\n/* harmony export */ queryFocusableElements: () => (/* binding */ queryFocusableElements),\n/* harmony export */ reduceToCommonValue: () => (/* binding */ reduceToCommonValue),\n/* harmony export */ removeSelection: () => (/* binding */ removeSelection),\n/* harmony export */ resolvablePromise: () => (/* binding */ resolvablePromise),\n/* harmony export */ safelyParseJSON: () => (/* binding */ safelyParseJSON),\n/* harmony export */ sceneCoordsToViewportCoords: () => (/* binding */ sceneCoordsToViewportCoords),\n/* harmony export */ selectNode: () => (/* binding */ selectNode),\n/* harmony export */ setDateTimeForTests: () => (/* binding */ setDateTimeForTests),\n/* harmony export */ setFeatureFlag: () => (/* binding */ setFeatureFlag),\n/* harmony export */ sizeOf: () => (/* binding */ sizeOf),\n/* harmony export */ supportsEmoji: () => (/* binding */ supportsEmoji),\n/* harmony export */ throttleRAF: () => (/* binding */ throttleRAF),\n/* harmony export */ toArray: () => (/* binding */ toArray),\n/* harmony export */ toBrandedType: () => (/* binding */ toBrandedType),\n/* harmony export */ toIterable: () => (/* binding */ toIterable),\n/* harmony export */ tupleToCoors: () => (/* binding */ tupleToCoors),\n/* harmony export */ updateActiveTool: () => (/* binding */ updateActiveTool),\n/* harmony export */ updateObject: () => (/* binding */ updateObject),\n/* harmony export */ updateStable: () => (/* binding */ updateStable),\n/* harmony export */ viewportCoordsToSceneCoords: () => (/* binding */ viewportCoordsToSceneCoords),\n/* harmony export */ wrapEvent: () => (/* binding */ wrapEvent)\n/* harmony export */ });\n/* harmony import */ var _excalidraw_math__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @excalidraw/math */ \"../math/src/index.ts\");\n/* harmony import */ var _colors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./colors */ \"../common/src/colors.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./constants */ \"../common/src/constants.ts\");\n\n\n\nlet mockDateTime = null;\nconst setDateTimeForTests = dateTime => {\n mockDateTime = dateTime;\n};\nconst getDateTime = () => {\n if (mockDateTime) {\n return mockDateTime;\n }\n\n const date = new Date();\n const year = date.getFullYear();\n const month = `${date.getMonth() + 1}`.padStart(2, \"0\");\n const day = `${date.getDate()}`.padStart(2, \"0\");\n const hr = `${date.getHours()}`.padStart(2, \"0\");\n const min = `${date.getMinutes()}`.padStart(2, \"0\");\n return `${year}-${month}-${day}-${hr}${min}`;\n};\nconst capitalizeString = str => str.charAt(0).toUpperCase() + str.slice(1);\nconst isToolIcon = target => target instanceof HTMLElement && target.className.includes(\"ToolIcon\");\nconst isInputLike = target => target instanceof HTMLElement && target.dataset.type === \"wysiwyg\" || target instanceof HTMLBRElement || // newline in wysiwyg\ntarget instanceof HTMLInputElement || target instanceof HTMLTextAreaElement || target instanceof HTMLSelectElement;\nconst isInteractive = target => {\n return isInputLike(target) || target instanceof Element && !!target.closest(\"label, button\");\n};\nconst isWritableElement = target => target instanceof HTMLElement && target.dataset.type === \"wysiwyg\" || target instanceof HTMLBRElement || // newline in wysiwyg\ntarget instanceof HTMLTextAreaElement || target instanceof HTMLInputElement && (target.type === \"text\" || target.type === \"number\" || target.type === \"password\" || target.type === \"search\");\nconst getFontFamilyString = ({\n fontFamily\n}) => {\n for (const [fontFamilyString, id] of Object.entries(_constants__WEBPACK_IMPORTED_MODULE_2__.FONT_FAMILY)) {\n if (id === fontFamily) {\n return `${fontFamilyString}${(0,_constants__WEBPACK_IMPORTED_MODULE_2__.getFontFamilyFallbacks)(id).map(x => `, ${x}`).join(\"\")}`;\n }\n }\n\n return _constants__WEBPACK_IMPORTED_MODULE_2__.WINDOWS_EMOJI_FALLBACK_FONT;\n};\n/** returns fontSize+fontFamily string for assignment to DOM elements */\n\nconst getFontString = ({\n fontSize,\n fontFamily\n}) => {\n return `${fontSize}px ${getFontFamilyString({\n fontFamily\n })}`;\n};\n/** executes callback in the frame that's after the current one */\n\nconst nextAnimationFrame = async cb => {\n requestAnimationFrame(() => requestAnimationFrame(cb));\n};\nconst debounce = (fn, timeout) => {\n let handle = 0;\n let lastArgs = null;\n\n const ret = (...args) => {\n lastArgs = args;\n clearTimeout(handle);\n handle = window.setTimeout(() => {\n lastArgs = null;\n fn(...args);\n }, timeout);\n };\n\n ret.flush = () => {\n clearTimeout(handle);\n\n if (lastArgs) {\n const _lastArgs = lastArgs;\n lastArgs = null;\n fn(..._lastArgs);\n }\n };\n\n ret.cancel = () => {\n lastArgs = null;\n clearTimeout(handle);\n };\n\n return ret;\n}; // throttle callback to execute once per animation frame\n\nconst throttleRAF = (fn, opts) => {\n let timerId = null;\n let lastArgs = null;\n let lastArgsTrailing = null;\n\n const scheduleFunc = args => {\n timerId = window.requestAnimationFrame(() => {\n timerId = null;\n fn(...args);\n lastArgs = null;\n\n if (lastArgsTrailing) {\n lastArgs = lastArgsTrailing;\n lastArgsTrailing = null;\n scheduleFunc(lastArgs);\n }\n });\n };\n\n const ret = (...args) => {\n if (isTestEnv()) {\n fn(...args);\n return;\n }\n\n lastArgs = args;\n\n if (timerId === null) {\n scheduleFunc(lastArgs);\n } else if (opts === null || opts === void 0 ? void 0 : opts.trailing) {\n lastArgsTrailing = args;\n }\n };\n\n ret.flush = () => {\n if (timerId !== null) {\n cancelAnimationFrame(timerId);\n timerId = null;\n }\n\n if (lastArgs) {\n fn(...(lastArgsTrailing || lastArgs));\n lastArgs = lastArgsTrailing = null;\n }\n };\n\n ret.cancel = () => {\n lastArgs = lastArgsTrailing = null;\n\n if (timerId !== null) {\n cancelAnimationFrame(timerId);\n timerId = null;\n }\n };\n\n return ret;\n};\n/**\r\n * Exponential ease-out method\r\n *\r\n * @param {number} k - The value to be tweened.\r\n * @returns {number} The tweened value.\r\n */\n\nconst easeOut = k => {\n return 1 - Math.pow(1 - k, 4);\n};\n\nconst easeOutInterpolate = (from, to, progress) => {\n return (to - from) * easeOut(progress) + from;\n};\n/**\r\n * Animates values from `fromValues` to `toValues` using the requestAnimationFrame API.\r\n * Executes the `onStep` callback on each step with the interpolated values.\r\n * Returns a function that can be called to cancel the animation.\r\n *\r\n * @example\r\n * // Example usage:\r\n * const fromValues = { x: 0, y: 0 };\r\n * const toValues = { x: 100, y: 200 };\r\n * const onStep = ({x, y}) => {\r\n * setState(x, y)\r\n * };\r\n * const onCancel = () => {\r\n * console.log(\"Animation canceled\");\r\n * };\r\n *\r\n * const cancelAnimation = easeToValuesRAF({\r\n * fromValues,\r\n * toValues,\r\n * onStep,\r\n * onCancel,\r\n * });\r\n *\r\n * // To cancel the animation:\r\n * cancelAnimation();\r\n */\n\n\nconst easeToValuesRAF = ({\n fromValues,\n toValues,\n onStep,\n duration = 250,\n interpolateValue,\n onStart,\n onEnd,\n onCancel\n}) => {\n let canceled = false;\n let frameId = 0;\n let startTime;\n\n function step(timestamp) {\n if (canceled) {\n return;\n }\n\n if (startTime === undefined) {\n startTime = timestamp;\n onStart === null || onStart === void 0 ? void 0 : onStart();\n }\n\n const elapsed = Math.min(timestamp - startTime, duration);\n const factor = easeOut(elapsed / duration);\n const newValues = {};\n Object.keys(fromValues).forEach(key => {\n const _key = key;\n const result = (toValues[_key] - fromValues[_key]) * factor + fromValues[_key];\n newValues[_key] = result;\n });\n onStep(newValues);\n\n if (elapsed < duration) {\n const progress = elapsed / duration;\n const newValues = {};\n Object.keys(fromValues).forEach(key => {\n const _key = key;\n const startValue = fromValues[_key];\n const endValue = toValues[_key];\n let result;\n result = interpolateValue ? interpolateValue(startValue, endValue, progress, _key) : easeOutInterpolate(startValue, endValue, progress);\n\n if (result == null) {\n result = easeOutInterpolate(startValue, endValue, progress);\n }\n\n newValues[_key] = result;\n });\n onStep(newValues);\n frameId = window.requestAnimationFrame(step);\n } else {\n onStep(toValues);\n onEnd === null || onEnd === void 0 ? void 0 : onEnd();\n }\n }\n\n frameId = window.requestAnimationFrame(step);\n return () => {\n onCancel === null || onCancel === void 0 ? void 0 : onCancel();\n canceled = true;\n window.cancelAnimationFrame(frameId);\n };\n}; // https://github.com/lodash/lodash/blob/es/chunk.js\n\nconst chunk = (array, size) => {\n if (!array.length || size < 1) {\n return [];\n }\n\n let index = 0;\n let resIndex = 0;\n const result = Array(Math.ceil(array.length / size));\n\n while (index < array.length) {\n result[resIndex++] = array.slice(index, index += size);\n }\n\n return result;\n};\nconst selectNode = node => {\n const selection = window.getSelection();\n\n if (selection) {\n const range = document.createRange();\n range.selectNodeContents(node);\n selection.removeAllRanges();\n selection.addRange(range);\n }\n};\nconst removeSelection = () => {\n const selection = window.getSelection();\n\n if (selection) {\n selection.removeAllRanges();\n }\n};\nconst distance = (x, y) => Math.abs(x - y);\nconst isSelectionLikeTool = type => {\n return type === \"selection\" || type === \"lasso\";\n};\nconst updateActiveTool = (appState, data) => {\n var _a, _b, _c;\n\n if (data.type === \"custom\") {\n return Object.assign(Object.assign({}, appState.activeTool), {\n type: \"custom\",\n customType: data.customType,\n locked: (_a = data.locked) !== null && _a !== void 0 ? _a : appState.activeTool.locked\n });\n }\n\n return Object.assign(Object.assign({}, appState.activeTool), {\n lastActiveTool: data.lastActiveToolBeforeEraser === undefined ? appState.activeTool.lastActiveTool : data.lastActiveToolBeforeEraser,\n type: data.type,\n customType: null,\n locked: (_b = data.locked) !== null && _b !== void 0 ? _b : appState.activeTool.locked,\n fromSelection: (_c = data.fromSelection) !== null && _c !== void 0 ? _c : false\n });\n};\nconst isFullScreen = () => {\n var _a;\n\n return ((_a = document.fullscreenElement) === null || _a === void 0 ? void 0 : _a.nodeName) === \"HTML\";\n};\nconst allowFullScreen = () => document.documentElement.requestFullscreen();\nconst exitFullScreen = () => document.exitFullscreen();\nconst viewportCoordsToSceneCoords = ({\n clientX,\n clientY\n}, {\n zoom,\n offsetLeft,\n offsetTop,\n scrollX,\n scrollY\n}) => {\n const x = (clientX - offsetLeft) / zoom.value - scrollX;\n const y = (clientY - offsetTop) / zoom.value - scrollY;\n return {\n x,\n y\n };\n};\nconst sceneCoordsToViewportCoords = ({\n sceneX,\n sceneY\n}, {\n zoom,\n offsetLeft,\n offsetTop,\n scrollX,\n scrollY\n}) => {\n const x = (sceneX + scrollX) * zoom.value + offsetLeft;\n const y = (sceneY + scrollY) * zoom.value + offsetTop;\n return {\n x,\n y\n };\n};\nconst getGlobalCSSVariable = name => getComputedStyle(document.documentElement).getPropertyValue(`--${name}`);\nconst RS_LTR_CHARS = \"A-Za-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02B8\\u0300-\\u0590\\u0800-\\u1FFF\" + \"\\u2C00-\\uFB1C\\uFDFE-\\uFE6F\\uFEFD-\\uFFFF\";\nconst RS_RTL_CHARS = \"\\u0591-\\u07FF\\uFB1D-\\uFDFD\\uFE70-\\uFEFC\";\nconst RE_RTL_CHECK = new RegExp(`^[^${RS_LTR_CHARS}]*[${RS_RTL_CHARS}]`);\n/**\r\n * Checks whether first directional character is RTL. Meaning whether it starts\r\n * with RTL characters, or indeterminate (numbers etc.) characters followed by\r\n * RTL.\r\n * See https://github.com/excalidraw/excalidraw/pull/1722#discussion_r436340171\r\n */\n\nconst isRTL = text => RE_RTL_CHECK.test(text);\nconst tupleToCoors = xyTuple => {\n const [x, y] = xyTuple;\n return {\n x,\n y\n };\n};\n/** use as a rejectionHandler to mute filesystem Abort errors */\n\nconst muteFSAbortError = error => {\n if ((error === null || error === void 0 ? void 0 : error.name) === \"AbortError\") {\n console.warn(error);\n return;\n }\n\n throw error;\n};\nconst findIndex = (array, cb, fromIndex = 0) => {\n if (fromIndex < 0) {\n fromIndex = array.length + fromIndex;\n }\n\n fromIndex = Math.min(array.length, Math.max(fromIndex, 0));\n let index = fromIndex - 1;\n\n while (++index < array.length) {\n if (cb(array[index], index, array)) {\n return index;\n }\n }\n\n return -1;\n};\nconst findLastIndex = (array, cb, fromIndex = array.length - 1) => {\n if (fromIndex < 0) {\n fromIndex = array.length + fromIndex;\n }\n\n fromIndex = Math.min(array.length - 1, Math.max(fromIndex, 0));\n let index = fromIndex + 1;\n\n while (--index > -1) {\n if (cb(array[index], index, array)) {\n return index;\n }\n }\n\n return -1;\n};\n/** returns the first non-null mapped value */\n\nconst mapFind = (collection, iteratee) => {\n for (let idx = 0; idx < collection.length; idx++) {\n const result = iteratee(collection[idx], idx);\n\n if (result != null) {\n return result;\n }\n }\n\n return undefined;\n};\nconst isTransparent = color => {\n const isRGBTransparent = color.length === 5 && color.substr(4, 1) === \"0\";\n const isRRGGBBTransparent = color.length === 9 && color.substr(7, 2) === \"00\";\n return isRGBTransparent || isRRGGBBTransparent || color === _colors__WEBPACK_IMPORTED_MODULE_1__.COLOR_PALETTE.transparent;\n};\nconst resolvablePromise = () => {\n let resolve;\n let reject;\n const promise = new Promise((_resolve, _reject) => {\n resolve = _resolve;\n reject = _reject;\n });\n promise.resolve = resolve;\n promise.reject = reject;\n return promise;\n}; //https://stackoverflow.com/a/9462382/8418\n\nconst nFormatter = (num, digits) => {\n const si = [{\n value: 1,\n symbol: \"b\"\n }, {\n value: 1e3,\n symbol: \"k\"\n }, {\n value: 1e6,\n symbol: \"M\"\n }, {\n value: 1e9,\n symbol: \"G\"\n }];\n const rx = /\\.0+$|(\\.[0-9]*[1-9])0+$/;\n let index;\n\n for (index = si.length - 1; index > 0; index--) {\n if (num >= si[index].value) {\n break;\n }\n }\n\n return (num / si[index].value).toFixed(digits).replace(rx, \"$1\") + si[index].symbol;\n};\nconst getVersion = () => {\n var _a;\n\n return ((_a = document.querySelector('meta[name=\"version\"]')) === null || _a === void 0 ? void 0 : _a.content) || _constants__WEBPACK_IMPORTED_MODULE_2__.DEFAULT_VERSION;\n}; // Adapted from https://github.com/Modernizr/Modernizr/blob/master/feature-detects/emoji.js\n\nconst supportsEmoji = () => {\n const canvas = document.createElement(\"canvas\");\n const ctx = canvas.getContext(\"2d\");\n\n if (!ctx) {\n return false;\n }\n\n const offset = 12;\n ctx.fillStyle = \"#f00\";\n ctx.textBaseline = \"top\";\n ctx.font = \"32px Arial\"; // Modernizr used 🐨, but it is sort of supported on Windows 7.\n // Luckily 😀 isn't supported.\n\n ctx.fillText(\"😀\", 0, 0);\n return ctx.getImageData(offset, offset, 1, 1).data[0] !== 0;\n};\nconst getNearestScrollableContainer = element => {\n let parent = element.parentElement;\n\n while (parent) {\n if (parent === document.body) {\n return document;\n }\n\n const {\n overflowY\n } = window.getComputedStyle(parent);\n const hasScrollableContent = parent.scrollHeight > parent.clientHeight;\n\n if (hasScrollableContent && (overflowY === \"auto\" || overflowY === \"scroll\" || overflowY === \"overlay\")) {\n return parent;\n }\n\n parent = parent.parentElement;\n }\n\n return document;\n};\nconst focusNearestParent = element => {\n let parent = element.parentElement;\n\n while (parent) {\n if (parent.tabIndex > -1) {\n parent.focus();\n return;\n }\n\n parent = parent.parentElement;\n }\n};\nconst preventUnload = event => {\n event.preventDefault(); // NOTE: modern browsers no longer allow showing a custom message here\n\n event.returnValue = \"\";\n};\nconst bytesToHexString = bytes => {\n return Array.from(bytes).map(byte => `0${byte.toString(16)}`.slice(-2)).join(\"\");\n};\nconst getUpdatedTimestamp = () => isTestEnv() ? 1 : Date.now();\n/**\r\n * Transforms array of objects containing `id` attribute,\r\n * or array of ids (strings), into a Map, keyd by `id`.\r\n */\n\nconst arrayToMap = items => {\n if (items instanceof Map) {\n return items;\n }\n\n return items.reduce((acc, element) => {\n acc.set(typeof element === \"string\" ? element : element.id, element);\n return acc;\n }, new Map());\n};\nconst arrayToMapWithIndex = elements => elements.reduce((acc, element, idx) => {\n acc.set(element.id, [element, idx]);\n return acc;\n}, new Map());\n/**\r\n * Transform array into an object, use only when array order is irrelevant.\r\n */\n\nconst arrayToObject = (array, groupBy) => array.reduce((acc, value, idx) => {\n acc[groupBy ? groupBy(value) : idx] = value;\n return acc;\n}, {});\n/**\r\n * Creates a circular doubly linked list by adding `prev` and `next` props to the existing array nodes.\r\n */\n\nconst arrayToList = array => array.reduce((acc, curr, index) => {\n const node = Object.assign(Object.assign({}, curr), {\n prev: null,\n next: null\n }); // no-op for first item, we don't want circular references on a single item\n\n if (index !== 0) {\n const prevNode = acc[index - 1];\n node.prev = prevNode;\n prevNode.next = node;\n\n if (index === array.length - 1) {\n // make the references circular and connect head & tail\n const firstNode = acc[0];\n node.next = firstNode;\n firstNode.prev = node;\n }\n }\n\n acc.push(node);\n return acc;\n}, []);\n/**\r\n * Converts a readonly array or map into an iterable.\r\n * Useful for avoiding entry allocations when iterating object / map on each iteration.\r\n */\n\nconst toIterable = values => {\n return Array.isArray(values) ? values : values.values();\n};\n/**\r\n * Converts a readonly array or map into an array.\r\n */\n\nconst toArray = values => {\n return Array.isArray(values) ? values : Array.from(toIterable(values));\n};\nconst isTestEnv = () => \"development\" === _constants__WEBPACK_IMPORTED_MODULE_2__.ENV.TEST;\nconst isDevEnv = () => \"development\" === _constants__WEBPACK_IMPORTED_MODULE_2__.ENV.DEVELOPMENT;\nconst isProdEnv = () => \"development\" === _constants__WEBPACK_IMPORTED_MODULE_2__.ENV.PRODUCTION;\nconst isServerEnv = () => {\n var _a;\n\n return typeof process !== \"undefined\" && !!((_a = process === null || process === void 0 ? void 0 : ({\"MODE\":\"development\",\"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_PLUS_LP\":\"https://plus.excalidraw.com\",\"VITE_APP_PLUS_APP\":\"http://localhost:3000\",\"VITE_APP_AI_BACKEND\":\"http://localhost:3015\",\"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_DISABLE_LIVE_RELOAD\":\"\",\"VITE_APP_ENABLE_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_APP_ENABLE_PWA\":\"false\",\"VITE_APP_PLUS_EXPORT_PUBLIC_KEY\":\"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm2g5T+Rub6Kbf1Mf57t0\\n7r2zeHuVg4dla3r5ryXMswtzz6x767octl6oLThn33mQsPSy3GKglFZoCTXJR4ij\\nba8SxB04sL/N8eRrKja7TFWjCVtRwTTfyy771NYYNFVJclkxHyE5qw4m27crHF1y\\nUNWEjuqNMi/lwAErS9fFa2oJlWyT8U7zzv/5kQREkxZI6y9v0AF3qcbsy2731FnD\\ns9ChJvOUW9toIab2gsIdrKW8ZNpu084ZFVKb6LNjvIXI1Se4oMTHeszXzNptzlot\\nkdxxjOoaQMAyfljFSot1F1FlU6MQlag7UnFGvFjRHN1JI5q4K+n3a67DX+TMyRqS\\nHQIDAQAB\",\"VITE_APP_DISABLE_PREVENT_UNLOAD\":\"\",\"VITE_PKG_NAME\":\"@zsviczian/excalidraw\",\"VITE_PKG_VERSION\":\"0.18.0-54\",\"VITE_IS_EXCALIDRAW_NPM_PACKAGE\":true})) === null || _a === void 0 ? void 0 : _a.NODE_ENV);\n};\nconst wrapEvent = (name, nativeEvent) => {\n return new CustomEvent(name, {\n detail: {\n nativeEvent\n },\n cancelable: true\n });\n};\nconst updateObject = (obj, updates) => {\n let didChange = false;\n\n for (const key in updates) {\n const value = updates[key];\n\n if (typeof value !== \"undefined\") {\n if (obj[key] === value && ( // if object, always update because its attrs could have changed\n typeof value !== \"object\" || value === null)) {\n continue;\n }\n\n didChange = true;\n }\n }\n\n if (!didChange) {\n return obj;\n }\n\n return Object.assign(Object.assign({}, obj), updates);\n};\nconst isPrimitive = val => {\n const type = typeof val;\n return val == null || type !== \"object\" && type !== \"function\";\n};\nconst getFrame = () => {\n try {\n return window.self === window.top ? \"top\" : \"iframe\";\n } catch (error) {\n return \"iframe\";\n }\n};\nconst isRunningInIframe = () => getFrame() === \"iframe\";\nconst isPromiseLike = value => {\n return !!value && typeof value === \"object\" && \"then\" in value && \"catch\" in value && \"finally\" in value;\n};\nconst queryFocusableElements = container => {\n const focusableElements = container === null || container === void 0 ? void 0 : container.querySelectorAll(\"button, a, input, select, textarea, div[tabindex], label[tabindex]\");\n return focusableElements ? Array.from(focusableElements).filter(element => element.tabIndex > -1 && !element.disabled) : [];\n};\n/** use as a fallback after identity check (for perf reasons) */\n\nconst _defaultIsShallowComparatorFallback = (a, b) => {\n // consider two empty arrays equal\n if (Array.isArray(a) && Array.isArray(b) && a.length === 0 && b.length === 0) {\n return true;\n }\n\n return a === b;\n};\n/**\r\n * Returns whether object/array is shallow equal.\r\n * Considers empty object/arrays as equal (whether top-level or second-level).\r\n */\n\n\nconst isShallowEqual = (objA, objB, comparators, debug = false) => {\n const aKeys = Object.keys(objA);\n const bKeys = Object.keys(objB);\n\n if (aKeys.length !== bKeys.length) {\n if (debug) {\n console.warn(`%cisShallowEqual: objects don't have same properties ->`, \"color: #8B4000\", objA, objB);\n }\n\n return false;\n }\n\n if (comparators && Array.isArray(comparators)) {\n for (const key of comparators) {\n const ret = objA[key] === objB[key] || _defaultIsShallowComparatorFallback(objA[key], objB[key]);\n\n if (!ret) {\n if (debug) {\n console.warn(`%cisShallowEqual: ${key} not equal ->`, \"color: #8B4000\", objA[key], objB[key]);\n }\n\n return false;\n }\n }\n\n return true;\n }\n\n return aKeys.every(key => {\n const comparator = comparators === null || comparators === void 0 ? void 0 : comparators[key];\n const ret = comparator ? comparator(objA[key], objB[key]) : objA[key] === objB[key] || _defaultIsShallowComparatorFallback(objA[key], objB[key]);\n\n if (!ret && debug) {\n console.warn(`%cisShallowEqual: ${key} not equal ->`, \"color: #8B4000\", objA[key], objB[key]);\n }\n\n return ret;\n });\n}; // taken from Radix UI\n// https://github.com/radix-ui/primitives/blob/main/packages/core/primitive/src/primitive.tsx\n\nconst composeEventHandlers = (originalEventHandler, ourEventHandler, {\n checkForDefaultPrevented = true\n} = {}) => {\n return function handleEvent(event) {\n originalEventHandler === null || originalEventHandler === void 0 ? void 0 : originalEventHandler(event);\n\n if (!checkForDefaultPrevented || !(event === null || event === void 0 ? void 0 : event.defaultPrevented)) {\n return ourEventHandler === null || ourEventHandler === void 0 ? void 0 : ourEventHandler(event);\n }\n };\n};\n/**\r\n * supply `null` as message if non-never value is valid, you just need to\r\n * typecheck against it\r\n */\n\nconst assertNever = (value, message, softAssert) => {\n if (!message) {\n return value;\n }\n\n if (softAssert) {\n console.error(message);\n return value;\n }\n\n throw new Error(message);\n};\nfunction invariant(condition, message) {\n if (!condition) {\n throw new Error(message);\n }\n}\n/**\r\n * Memoizes on values of `opts` object (strict equality).\r\n */\n\nconst memoize = func => {\n let lastArgs;\n let lastResult;\n\n const ret = function (opts) {\n const currentArgs = Object.entries(opts);\n\n if (lastArgs) {\n let argsAreEqual = true;\n\n for (const [key, value] of currentArgs) {\n if (lastArgs.get(key) !== value) {\n argsAreEqual = false;\n break;\n }\n }\n\n if (argsAreEqual) {\n return lastResult;\n }\n }\n\n const result = func(opts);\n lastArgs = new Map(currentArgs);\n lastResult = result;\n return result;\n };\n\n ret.clear = () => {\n lastArgs = undefined;\n lastResult = undefined;\n };\n\n return ret;\n};\n/** Checks if value is inside given collection. Useful for type-safety. */\n\nconst isMemberOf = (\n/** Set/Map/Array/Object */\ncollection,\n/** value to look for */\nvalue) => {\n return collection instanceof Set || collection instanceof Map ? collection.has(value) : \"includes\" in collection ? collection.includes(value) : collection.hasOwnProperty(value);\n};\nconst cloneJSON = obj => JSON.parse(JSON.stringify(obj));\nconst updateStable = (prevValue, nextValue) => {\n if (isShallowEqual(prevValue, nextValue)) {\n return prevValue;\n }\n\n return nextValue;\n}; // implem\n\nfunction addEventListener(\n/**\r\n * allows for falsy values so you don't have to type check when adding\r\n * event listeners to optional elements\r\n */\ntarget, type, listener, options) {\n var _a;\n\n if (!target) {\n return () => {};\n }\n\n (_a = target === null || target === void 0 ? void 0 : target.addEventListener) === null || _a === void 0 ? void 0 : _a.call(target, type, listener, options);\n return () => {\n var _a;\n\n (_a = target === null || target === void 0 ? void 0 : target.removeEventListener) === null || _a === void 0 ? void 0 : _a.call(target, type, listener, options);\n };\n}\nfunction getSvgPathFromStroke(points, closed = true) {\n const len = points.length;\n\n if (len < 4) {\n return ``;\n }\n\n let a = points[0];\n let b = points[1];\n const c = points[2];\n let result = `M${a[0].toFixed(2)},${a[1].toFixed(2)} Q${b[0].toFixed(2)},${b[1].toFixed(2)} ${(0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_0__.average)(b[0], c[0]).toFixed(2)},${(0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_0__.average)(b[1], c[1]).toFixed(2)} T`;\n\n for (let i = 2, max = len - 1; i < max; i++) {\n a = points[i];\n b = points[i + 1];\n result += `${(0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_0__.average)(a[0], b[0]).toFixed(2)},${(0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_0__.average)(a[1], b[1]).toFixed(2)} `;\n }\n\n if (closed) {\n result += \"Z\";\n }\n\n return result;\n}\nconst normalizeEOL = str => {\n return str.replace(/\\r?\\n|\\r/g, \"\\n\");\n};\n/**\r\n * Makes type into a branded type, ensuring that value is assignable to\r\n * the base ubranded type. Optionally you can explicitly supply current value\r\n * type to combine both (useful for composite branded types. Make sure you\r\n * compose branded types which are not composite themselves.)\r\n */\n\nconst toBrandedType = value => {\n return value;\n}; // -----------------------------------------------------------------------------\n// Promise.try, adapted from https://github.com/sindresorhus/p-try\n\nconst promiseTry = async (fn, ...args) => {\n return new Promise(resolve => {\n resolve(fn(...args));\n });\n};\nconst isAnyTrue = (...args) => Math.max(...args.map(arg => arg ? 1 : 0)) > 0;\nconst safelyParseJSON = json => {\n try {\n return JSON.parse(json);\n } catch (_a) {\n return null;\n }\n};\n/**\r\n * use when you need to render unsafe string as HTML attribute, but MAKE SURE\r\n * the attribute is double-quoted when constructing the HTML string\r\n */\n\nconst escapeDoubleQuotes = str => {\n return str.replace(/\"/g, \"&quot;\");\n};\nconst castArray = value => Array.isArray(value) ? value : [value];\n/** hack for Array.isArray type guard not working with readonly value[] */\n\nconst isReadonlyArray = value => {\n return Array.isArray(value);\n};\nconst sizeOf = value => {\n return isReadonlyArray(value) ? value.length : value instanceof Map || value instanceof Set ? value.size : Object.keys(value).length;\n};\nconst reduceToCommonValue = (collection, getValue) => {\n if (sizeOf(collection) === 0) {\n return null;\n }\n\n const valueExtractor = getValue || (item => item);\n\n let commonValue = null;\n\n for (const item of collection) {\n const value = valueExtractor(item);\n\n if ((commonValue === null || commonValue === value) && value != null) {\n commonValue = value;\n } else {\n return null;\n }\n }\n\n return commonValue;\n};\nconst FEATURE_FLAGS_STORAGE_KEY = \"excalidraw-feature-flags\";\nconst DEFAULT_FEATURE_FLAGS = {\n COMPLEX_BINDINGS: false\n};\nlet featureFlags = null;\nconst getFeatureFlag = flag => {\n if (!featureFlags) {\n try {\n const serializedFlags = localStorage.getItem(FEATURE_FLAGS_STORAGE_KEY);\n\n if (serializedFlags) {\n const flags = JSON.parse(serializedFlags);\n featureFlags = flags !== null && flags !== void 0 ? flags : DEFAULT_FEATURE_FLAGS;\n }\n } catch (_a) {}\n }\n\n return (featureFlags || DEFAULT_FEATURE_FLAGS)[flag];\n};\nconst setFeatureFlag = (flag, value) => {\n try {\n featureFlags = Object.assign(Object.assign({}, featureFlags || DEFAULT_FEATURE_FLAGS), {\n [flag]: value\n });\n localStorage.setItem(FEATURE_FLAGS_STORAGE_KEY, JSON.stringify(featureFlags));\n } catch (e) {\n console.error(\"unable to set feature flag\", e);\n }\n};\n\n//# sourceURL=webpack://ExcalidrawLib/../common/src/utils.ts?");
13095
13095
 
13096
13096
  /***/ }),
13097
13097
 
@@ -13135,7 +13135,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
13135
13135
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
13136
13136
 
13137
13137
  "use strict";
13138
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ BASE_BINDING_GAP: () => (/* binding */ BASE_BINDING_GAP),\n/* harmony export */ BASE_BINDING_GAP_ELBOW: () => (/* binding */ BASE_BINDING_GAP_ELBOW),\n/* harmony export */ BindableElement: () => (/* binding */ BindableElement),\n/* harmony export */ BoundElement: () => (/* binding */ BoundElement),\n/* harmony export */ avoidRectangularCorner: () => (/* binding */ avoidRectangularCorner),\n/* harmony export */ bindBindingElement: () => (/* binding */ bindBindingElement),\n/* harmony export */ bindOrUnbindBindingElement: () => (/* binding */ bindOrUnbindBindingElement),\n/* harmony export */ bindOrUnbindBindingElements: () => (/* binding */ bindOrUnbindBindingElements),\n/* harmony export */ bindPointToSnapToElementOutline: () => (/* binding */ bindPointToSnapToElementOutline),\n/* harmony export */ bindingProperties: () => (/* binding */ bindingProperties),\n/* harmony export */ calculateFixedPointForElbowArrowBinding: () => (/* binding */ calculateFixedPointForElbowArrowBinding),\n/* harmony export */ calculateFixedPointForNonElbowArrowBinding: () => (/* binding */ calculateFixedPointForNonElbowArrowBinding),\n/* harmony export */ fixBindingsAfterDeletion: () => (/* binding */ fixBindingsAfterDeletion),\n/* harmony export */ fixDuplicatedBindingsAfterDuplication: () => (/* binding */ fixDuplicatedBindingsAfterDuplication),\n/* harmony export */ getArrowLocalFixedPoints: () => (/* binding */ getArrowLocalFixedPoints),\n/* harmony export */ getBindingGap: () => (/* binding */ getBindingGap),\n/* harmony export */ getBindingStrategyForDraggingBindingElementEndpoints: () => (/* binding */ getBindingStrategyForDraggingBindingElementEndpoints),\n/* harmony export */ getGlobalFixedPointForBindableElement: () => (/* binding */ getGlobalFixedPointForBindableElement),\n/* harmony export */ getGlobalFixedPoints: () => (/* binding */ getGlobalFixedPoints),\n/* harmony export */ getHeadingForElbowArrowSnap: () => (/* binding */ getHeadingForElbowArrowSnap),\n/* harmony export */ isBindingEnabled: () => (/* binding */ isBindingEnabled),\n/* harmony export */ maxBindingDistance_simple: () => (/* binding */ maxBindingDistance_simple),\n/* harmony export */ normalizeFixedPoint: () => (/* binding */ normalizeFixedPoint),\n/* harmony export */ shouldEnableBindingForPointerEvent: () => (/* binding */ shouldEnableBindingForPointerEvent),\n/* harmony export */ unbindBindingElement: () => (/* binding */ unbindBindingElement),\n/* harmony export */ updateBindings: () => (/* binding */ updateBindings),\n/* harmony export */ updateBoundElements: () => (/* binding */ updateBoundElements),\n/* harmony export */ updateBoundPoint: () => (/* binding */ updateBoundPoint)\n/* harmony export */ });\n/* harmony import */ var _excalidraw_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @excalidraw/common */ \"../common/src/index.ts\");\n/* harmony import */ var _excalidraw_math__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @excalidraw/math */ \"../math/src/index.ts\");\n/* harmony import */ var _bounds__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./bounds */ \"../element/src/bounds.ts\");\n/* harmony import */ var _collision__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./collision */ \"../element/src/collision.ts\");\n/* harmony import */ var _distance__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./distance */ \"../element/src/distance.ts\");\n/* harmony import */ var _heading__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./heading */ \"../element/src/heading.ts\");\n/* harmony import */ var _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./linearElementEditor */ \"../element/src/linearElementEditor.ts\");\n/* harmony import */ var _mutateElement__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./mutateElement */ \"../element/src/mutateElement.ts\");\n/* harmony import */ var _textElement__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./textElement */ \"../element/src/textElement.ts\");\n/* harmony import */ var _typeChecks__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./typeChecks */ \"../element/src/typeChecks.ts\");\n/* harmony import */ var _elbowArrow__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./elbowArrow */ \"../element/src/elbowArrow.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./utils */ \"../element/src/utils.ts\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\r\n * gaps exclude element strokeWidth\r\n *\r\n * IMPORTANT: currently must be > 0 (this also applies to the computed gap)\r\n */\n\nconst BASE_BINDING_GAP = 10;\nconst BASE_BINDING_GAP_ELBOW = 5;\nconst getBindingGap = (bindTarget, opts) => {\n return (opts.elbowed ? BASE_BINDING_GAP_ELBOW : BASE_BINDING_GAP) + bindTarget.strokeWidth / 2;\n};\nconst maxBindingDistance_simple = zoom => {\n const BASE_BINDING_DISTANCE = Math.max(BASE_BINDING_GAP, 15);\n const zoomValue = (zoom === null || zoom === void 0 ? void 0 : zoom.value) && zoom.value < 1 ? zoom.value : 1;\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.clamp)( // reducing zoom impact so that the diff between binding distance and\n // binding gap is kept to minimum when possible\n BASE_BINDING_DISTANCE / (zoomValue * 1.5), BASE_BINDING_DISTANCE, BASE_BINDING_DISTANCE * 2);\n};\nconst shouldEnableBindingForPointerEvent = event => {\n return !event[_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.KEYS.CTRL_OR_CMD];\n};\nconst isBindingEnabled = appState => {\n return appState.invertBindingBehaviour //zsviczian\n ? !appState.isBindingEnabled : appState.isBindingEnabled;\n};\nconst bindOrUnbindBindingElement = (arrow, draggingPoints, scene, appState, opts) => {\n const {\n start,\n end\n } = getBindingStrategyForDraggingBindingElementEndpoints(arrow, draggingPoints, scene.getNonDeletedElementsMap(), scene.getNonDeletedElements(), appState, Object.assign(Object.assign({}, opts), {\n finalize: true\n }));\n bindOrUnbindBindingElementEdge(arrow, start, \"start\", scene);\n bindOrUnbindBindingElementEdge(arrow, end, \"end\", scene);\n\n if (start.focusPoint || end.focusPoint) {\n // If the strategy dictates a focus point override, then\n // update the arrow points to point to the focus point.\n const updates = new Map();\n\n if (start.focusPoint) {\n updates.set(0, {\n point: updateBoundPoint(arrow, \"startBinding\", arrow.startBinding, start.element, scene.getNonDeletedElementsMap()) || arrow.points[0]\n });\n }\n\n if (end.focusPoint) {\n updates.set(arrow.points.length - 1, {\n point: updateBoundPoint(arrow, \"endBinding\", arrow.endBinding, end.element, scene.getNonDeletedElementsMap()) || arrow.points[arrow.points.length - 1]\n });\n }\n\n _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.movePoints(arrow, scene, updates);\n }\n\n return {\n start,\n end\n };\n};\n\nconst bindOrUnbindBindingElementEdge = (arrow, {\n mode,\n element,\n focusPoint\n}, startOrEnd, scene) => {\n if (mode === null) {\n // null means break the binding\n unbindBindingElement(arrow, startOrEnd, scene);\n } else if (mode !== undefined) {\n bindBindingElement(arrow, element, mode, startOrEnd, scene, focusPoint);\n }\n};\n\nconst bindingStrategyForElbowArrowEndpointDragging = (arrow, draggingPoints, elementsMap, elements, zoom) => {\n (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.invariant)(draggingPoints.size === 1, \"Bound elbow arrows cannot be moved\");\n const update = draggingPoints.entries().next().value;\n (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.invariant)(update, \"There should be a position update for dragging an elbow arrow endpoint\");\n const [pointIdx, {\n point\n }] = update;\n const globalPoint = _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointGlobalCoordinates(arrow, point, elementsMap);\n const hit = (0,_collision__WEBPACK_IMPORTED_MODULE_3__.getHoveredElementForBinding)(globalPoint, elements, elementsMap, element => maxBindingDistance_simple(zoom));\n const current = hit ? {\n element: hit,\n mode: \"orbit\",\n focusPoint: _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointAtIndexGlobalCoordinates(arrow, pointIdx, elementsMap)\n } : {\n mode: null\n };\n const other = {\n mode: undefined\n };\n return pointIdx === 0 ? {\n start: current,\n end: other\n } : {\n start: other,\n end: current\n };\n};\n\nconst bindingStrategyForNewSimpleArrowEndpointDragging = (arrow, draggingPoints, elementsMap, elements, startDragged, endDragged, startIdx, endIdx, appState, globalBindMode, shiftKey) => {\n var _a, _b, _c;\n\n let start = {\n mode: undefined\n };\n let end = {\n mode: undefined\n };\n const isMultiPoint = arrow.points.length > 2;\n const point = _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointGlobalCoordinates(arrow, draggingPoints.get(startDragged ? startIdx : endIdx).point, elementsMap);\n const hit = (0,_collision__WEBPACK_IMPORTED_MODULE_3__.getHoveredElementForBinding)(point, elements, elementsMap); // With new arrows this handles the binding at arrow creation\n\n if (startDragged) {\n if (hit) {\n start = {\n element: hit,\n mode: \"inside\",\n focusPoint: point\n };\n } else {\n start = {\n mode: null\n };\n }\n\n return {\n start,\n end\n };\n } // With new arrows it represents the continuous dragging of the end point\n\n\n if (endDragged) {\n const origin = (_a = appState === null || appState === void 0 ? void 0 : appState.selectedLinearElement) === null || _a === void 0 ? void 0 : _a.initialState.origin; // Inside -> inside binding\n\n if (hit && ((_b = arrow.startBinding) === null || _b === void 0 ? void 0 : _b.elementId) === hit.id) {\n const center = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(hit.x + hit.width / 2, hit.y + hit.height / 2);\n return {\n start: isMultiPoint ? {\n mode: undefined\n } : {\n mode: \"inside\",\n element: hit,\n focusPoint: origin !== null && origin !== void 0 ? origin : center\n },\n end: isMultiPoint ? {\n mode: \"orbit\",\n element: hit,\n focusPoint: point\n } : {\n mode: \"inside\",\n element: hit,\n focusPoint: point\n }\n };\n } // Check and handle nested shapes\n\n\n if (hit && arrow.startBinding) {\n const startBinding = arrow.startBinding;\n const allHits = (0,_collision__WEBPACK_IMPORTED_MODULE_3__.getAllHoveredElementAtPoint)(point, elements, elementsMap);\n\n if (allHits.find(el => el.id === startBinding.elementId)) {\n const otherElement = elementsMap.get(arrow.startBinding.elementId);\n (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.invariant)(otherElement, \"Other element must be in the elements map\");\n return {\n start: isMultiPoint ? {\n mode: undefined\n } : {\n mode: otherElement.id !== hit.id ? \"orbit\" : \"inside\",\n element: otherElement,\n focusPoint: origin !== null && origin !== void 0 ? origin : (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(arrow.x, arrow.y)\n },\n end: {\n mode: \"orbit\",\n element: hit,\n focusPoint: point\n }\n };\n }\n } // Inside -> outside binding\n\n\n if (arrow.startBinding && arrow.startBinding.elementId !== (hit === null || hit === void 0 ? void 0 : hit.id)) {\n const otherElement = elementsMap.get(arrow.startBinding.elementId);\n (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.invariant)(otherElement, \"Other element must be in the elements map\");\n const otherIsInsideBinding = !!((_c = appState.selectedLinearElement) === null || _c === void 0 ? void 0 : _c.initialState.arrowStartIsInside);\n const other = {\n mode: otherIsInsideBinding ? \"inside\" : \"orbit\",\n element: otherElement,\n focusPoint: shiftKey ? (0,_bounds__WEBPACK_IMPORTED_MODULE_2__.elementCenterPoint)(otherElement, elementsMap) : origin !== null && origin !== void 0 ? origin : (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(arrow.x, arrow.y)\n }; // We are hovering another element with the end point\n\n const isNested = hit && (0,_collision__WEBPACK_IMPORTED_MODULE_3__.isBindableElementInsideOtherBindable)(otherElement, hit, elementsMap);\n let current;\n\n if (hit) {\n const isInsideBinding = globalBindMode === \"inside\" || globalBindMode === \"skip\";\n current = {\n mode: isInsideBinding && !isNested ? \"inside\" : \"orbit\",\n element: hit,\n focusPoint: isInsideBinding || isNested ? point : point\n };\n } else {\n current = {\n mode: null\n };\n }\n\n return {\n start: isMultiPoint ? {\n mode: undefined\n } : other,\n end: current\n };\n } // No start binding\n\n\n if (!arrow.startBinding) {\n if (hit) {\n const isInsideBinding = globalBindMode === \"inside\" || globalBindMode === \"skip\";\n end = {\n mode: isInsideBinding ? \"inside\" : \"orbit\",\n element: hit,\n focusPoint: point\n };\n } else {\n end = {\n mode: null\n };\n }\n\n return {\n start,\n end\n };\n }\n }\n\n (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.invariant)(false, \"New arrow creation should not reach here\");\n};\n\nconst bindingStrategyForSimpleArrowEndpointDragging_complex = (point, currentBinding, oppositeBinding, elementsMap, elements, globalBindMode, arrow, finalize) => {\n let current = {\n mode: undefined\n };\n let other = {\n mode: undefined\n };\n const isMultiPoint = arrow.points.length > 2;\n const hit = (0,_collision__WEBPACK_IMPORTED_MODULE_3__.getHoveredElementForBinding)(point, elements, elementsMap);\n const isOverlapping = oppositeBinding ? (0,_collision__WEBPACK_IMPORTED_MODULE_3__.getAllHoveredElementAtPoint)(point, elements, elementsMap).some(el => el.id === oppositeBinding.elementId) : false;\n const oppositeElement = oppositeBinding ? elementsMap.get(oppositeBinding.elementId) : null;\n const otherIsTransparent = isOverlapping && oppositeElement ? (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.isTransparent)(oppositeElement.backgroundColor) : false;\n const isNested = hit && oppositeElement && (0,_collision__WEBPACK_IMPORTED_MODULE_3__.isBindableElementInsideOtherBindable)(oppositeElement, hit, elementsMap); // If the global bind mode is in free binding mode, just bind\n // where the pointer is and keep the other end intact\n\n if (globalBindMode === \"inside\" || globalBindMode === \"skip\") {\n current = hit ? {\n element: !isOverlapping || !oppositeElement || otherIsTransparent ? hit : oppositeElement,\n focusPoint: point,\n mode: \"inside\"\n } : {\n mode: null\n };\n other = finalize && hit && hit.id === (oppositeBinding === null || oppositeBinding === void 0 ? void 0 : oppositeBinding.elementId) ? {\n mode: null\n } : other;\n return {\n current,\n other\n };\n } // Dragged point is outside of any bindable element\n // so we break any existing binding\n\n\n if (!hit) {\n return {\n current: {\n mode: null\n },\n other\n };\n } // Already inside binding over the same hit element should remain inside bound\n\n\n if (hit.id === (currentBinding === null || currentBinding === void 0 ? void 0 : currentBinding.elementId) && currentBinding.mode === \"inside\") {\n return {\n current: {\n mode: \"inside\",\n focusPoint: point,\n element: hit\n },\n other\n };\n } // The dragged point is inside the hovered bindable element\n\n\n if (oppositeBinding) {\n // The opposite binding is on the same element\n if (oppositeBinding.elementId === hit.id) {\n // The opposite binding is on the binding gap of the same element\n if (oppositeBinding.mode === \"orbit\") {\n current = {\n element: hit,\n mode: \"orbit\",\n focusPoint: point\n };\n other = {\n mode: finalize ? null : undefined\n };\n return {\n current,\n other: isMultiPoint ? {\n mode: undefined\n } : other\n };\n } // The opposite binding is inside the same element\n // eslint-disable-next-line no-else-return\n else {\n current = {\n element: hit,\n mode: \"inside\",\n focusPoint: point\n };\n return {\n current,\n other: isMultiPoint ? {\n mode: undefined\n } : other\n };\n }\n } // The opposite binding is on a different element (or nested)\n // eslint-disable-next-line no-else-return\n else {\n // Handle the nested element case\n if (isOverlapping && oppositeElement && !otherIsTransparent) {\n current = {\n element: oppositeElement,\n mode: \"inside\",\n focusPoint: point\n };\n } else {\n current = {\n element: hit,\n mode: \"orbit\",\n focusPoint: isNested ? point : point\n };\n }\n\n return {\n current,\n other: isMultiPoint ? {\n mode: undefined\n } : other\n };\n }\n } // The opposite binding is on a different element or no binding\n else {\n current = {\n element: hit,\n mode: \"orbit\",\n focusPoint: point\n };\n } // Must return as only one endpoint is dragged, therefore\n // the end binding strategy might accidentally gets overriden\n\n\n return {\n current,\n other: isMultiPoint ? {\n mode: undefined\n } : other\n };\n};\n\nconst getBindingStrategyForDraggingBindingElementEndpoints = (arrow, draggingPoints, elementsMap, elements, appState, opts) => {\n if ((0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.getFeatureFlag)(\"COMPLEX_BINDINGS\")) {\n return getBindingStrategyForDraggingBindingElementEndpoints_complex(arrow, draggingPoints, elementsMap, elements, appState, opts);\n }\n\n return getBindingStrategyForDraggingBindingElementEndpoints_simple(arrow, draggingPoints, elementsMap, elements, appState, opts);\n};\n\nconst getBindingStrategyForDraggingBindingElementEndpoints_simple = (arrow, draggingPoints, elementsMap, elements, appState, opts) => {\n var _a, _b, _c;\n\n const startIdx = 0;\n const endIdx = arrow.points.length - 1;\n const startDragged = draggingPoints.has(startIdx);\n const endDragged = draggingPoints.has(endIdx);\n let start = {\n mode: undefined\n };\n let end = {\n mode: undefined\n };\n (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.invariant)(arrow.points.length > 1, \"Do not attempt to bind linear elements with a single point\"); // If none of the ends are dragged, we don't change anything\n\n if (!startDragged && !endDragged) {\n return {\n start,\n end\n };\n } // If both ends are dragged, we don't bind to anything\n // and break existing bindings\n\n\n if (startDragged && endDragged) {\n return {\n start: {\n mode: null\n },\n end: {\n mode: null\n }\n };\n } // If binding is disabled and an endpoint is dragged,\n // we actively break the end binding\n\n\n if (!isBindingEnabled(appState)) {\n start = startDragged ? {\n mode: null\n } : start;\n end = endDragged ? {\n mode: null\n } : end;\n return {\n start,\n end\n };\n } // Handle simpler elbow arrow binding\n\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isElbowArrow)(arrow)) {\n return bindingStrategyForElbowArrowEndpointDragging(arrow, draggingPoints, elementsMap, elements, opts === null || opts === void 0 ? void 0 : opts.zoom);\n }\n\n const otherBinding = startDragged ? arrow.endBinding : arrow.startBinding;\n const localPoint = (_a = draggingPoints.get(startDragged ? startIdx : endIdx)) === null || _a === void 0 ? void 0 : _a.point;\n (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.invariant)(localPoint, `Local point must be defined for ${startDragged ? \"start\" : \"end\"} dragging`);\n const globalPoint = _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointGlobalCoordinates(arrow, localPoint, elementsMap);\n const hit = (0,_collision__WEBPACK_IMPORTED_MODULE_3__.getHoveredElementForBinding)(globalPoint, elements, elementsMap, e => maxBindingDistance_simple(appState.zoom));\n const pointInElement = hit && (0,_collision__WEBPACK_IMPORTED_MODULE_3__.isPointInElement)(globalPoint, hit, elementsMap);\n const otherBindableElement = otherBinding ? elementsMap.get(otherBinding.elementId) : undefined;\n const otherFocusPoint = otherBinding && otherBindableElement && getGlobalFixedPointForBindableElement(otherBinding.fixedPoint, otherBindableElement, elementsMap);\n const otherFocusPointIsInElement = otherBindableElement && otherFocusPoint && (0,_collision__WEBPACK_IMPORTED_MODULE_3__.isPointInElement)(otherFocusPoint, otherBindableElement, elementsMap); // Handle outside-outside binding to the same element\n\n if (otherBinding && otherBinding.elementId === (hit === null || hit === void 0 ? void 0 : hit.id)) {\n (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.invariant)(!(opts === null || opts === void 0 ? void 0 : opts.newArrow) || ((_b = appState.selectedLinearElement) === null || _b === void 0 ? void 0 : _b.initialState.origin), \"appState.selectedLinearElement.initialState.origin must be defined for new arrows\");\n return {\n start: {\n mode: \"inside\",\n element: hit,\n focusPoint: startDragged ? globalPoint : // NOTE: Can only affect the start point because new arrows always drag the end point\n (opts === null || opts === void 0 ? void 0 : opts.newArrow) ? appState.selectedLinearElement.initialState.origin : _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointAtIndexGlobalCoordinates(arrow, 0, elementsMap) // startFixedPoint,\n\n },\n end: {\n mode: \"inside\",\n element: hit,\n focusPoint: endDragged ? globalPoint : _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointAtIndexGlobalCoordinates(arrow, -1, elementsMap) // endFixedPoint\n\n }\n };\n } // Handle special alt key case to inside bind no matter what\n\n\n if (opts === null || opts === void 0 ? void 0 : opts.altKey) {\n return {\n start: startDragged ? hit ? {\n mode: \"inside\",\n element: hit,\n focusPoint: globalPoint\n } : {\n mode: null\n } : start,\n end: endDragged ? hit ? {\n mode: \"inside\",\n element: hit,\n focusPoint: globalPoint\n } : {\n mode: null\n } : end\n };\n } // Handle normal cases\n\n\n const current = hit ? pointInElement ? {\n mode: \"inside\",\n element: hit,\n focusPoint: globalPoint\n } : {\n mode: \"orbit\",\n element: hit,\n focusPoint: (0,_utils__WEBPACK_IMPORTED_MODULE_11__.projectFixedPointOntoDiagonal)(arrow, globalPoint, hit, startDragged ? \"start\" : \"end\", elementsMap) || globalPoint\n } : {\n mode: null\n };\n const other = otherBindableElement && !otherFocusPointIsInElement && ((_c = appState.selectedLinearElement) === null || _c === void 0 ? void 0 : _c.initialState.altFocusPoint) ? {\n mode: \"orbit\",\n element: otherBindableElement,\n focusPoint: appState.selectedLinearElement.initialState.altFocusPoint\n } : {\n mode: undefined\n };\n return {\n start: startDragged ? current : other,\n end: endDragged ? current : other\n };\n};\n\nconst getBindingStrategyForDraggingBindingElementEndpoints_complex = (arrow, draggingPoints, elementsMap, elements, appState, opts) => {\n var _a, _b;\n\n const globalBindMode = appState.bindMode || \"orbit\";\n const startIdx = 0;\n const endIdx = arrow.points.length - 1;\n const startDragged = draggingPoints.has(startIdx);\n const endDragged = draggingPoints.has(endIdx);\n let start = {\n mode: undefined\n };\n let end = {\n mode: undefined\n };\n (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.invariant)(arrow.points.length > 1, \"Do not attempt to bind linear elements with a single point\"); // If none of the ends are dragged, we don't change anything\n\n if (!startDragged && !endDragged) {\n return {\n start,\n end\n };\n } // If both ends are dragged, we don't bind to anything\n // and break existing bindings\n\n\n if (startDragged && endDragged) {\n return {\n start: {\n mode: null\n },\n end: {\n mode: null\n }\n };\n } // If binding is disabled and an endpoint is dragged,\n // we actively break the end binding\n\n\n if (!isBindingEnabled(appState)) {\n start = startDragged ? {\n mode: null\n } : start;\n end = endDragged ? {\n mode: null\n } : end;\n return {\n start,\n end\n };\n } // Handle simpler elbow arrow binding\n\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isElbowArrow)(arrow)) {\n return bindingStrategyForElbowArrowEndpointDragging(arrow, draggingPoints, elementsMap, elements);\n } // Handle new arrow creation separately, as it is special\n\n\n if (opts === null || opts === void 0 ? void 0 : opts.newArrow) {\n const {\n start,\n end\n } = bindingStrategyForNewSimpleArrowEndpointDragging(arrow, draggingPoints, elementsMap, elements, startDragged, endDragged, startIdx, endIdx, appState, globalBindMode, opts === null || opts === void 0 ? void 0 : opts.shiftKey);\n return {\n start,\n end\n };\n } // Only the start point is dragged\n\n\n if (startDragged) {\n const localPoint = (_a = draggingPoints.get(startIdx)) === null || _a === void 0 ? void 0 : _a.point;\n (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.invariant)(localPoint, \"Local point must be defined for start dragging\");\n const globalPoint = _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointGlobalCoordinates(arrow, localPoint, elementsMap);\n const {\n current,\n other\n } = bindingStrategyForSimpleArrowEndpointDragging_complex(globalPoint, arrow.startBinding, arrow.endBinding, elementsMap, elements, globalBindMode, arrow, opts === null || opts === void 0 ? void 0 : opts.finalize);\n return {\n start: current,\n end: other\n };\n } // Only the end point is dragged\n\n\n if (endDragged) {\n const localPoint = (_b = draggingPoints.get(endIdx)) === null || _b === void 0 ? void 0 : _b.point;\n (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.invariant)(localPoint, \"Local point must be defined for end dragging\");\n const globalPoint = _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointGlobalCoordinates(arrow, localPoint, elementsMap);\n const {\n current,\n other\n } = bindingStrategyForSimpleArrowEndpointDragging_complex(globalPoint, arrow.endBinding, arrow.startBinding, elementsMap, elements, globalBindMode, arrow, opts === null || opts === void 0 ? void 0 : opts.finalize);\n return {\n start: other,\n end: current\n };\n }\n\n return {\n start,\n end\n };\n};\n\nconst bindOrUnbindBindingElements = (selectedArrows, scene, appState) => {\n selectedArrows.forEach(arrow => {\n bindOrUnbindBindingElement(arrow, new Map(), // No dragging points in this case\n scene, appState);\n });\n};\nconst bindBindingElement = (arrow, hoveredElement, mode, startOrEnd, scene, focusPoint) => {\n const elementsMap = scene.getNonDeletedElementsMap();\n let binding;\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isElbowArrow)(arrow)) {\n binding = Object.assign({\n elementId: hoveredElement.id,\n mode: \"orbit\"\n }, calculateFixedPointForElbowArrowBinding(arrow, hoveredElement, startOrEnd, elementsMap));\n } else {\n binding = Object.assign({\n elementId: hoveredElement.id,\n mode\n }, calculateFixedPointForNonElbowArrowBinding(arrow, hoveredElement, startOrEnd, elementsMap, focusPoint));\n }\n\n scene.mutateElement(arrow, {\n [startOrEnd === \"start\" ? \"startBinding\" : \"endBinding\"]: binding\n });\n const boundElementsMap = (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.arrayToMap)(hoveredElement.boundElements || []);\n\n if (!boundElementsMap.has(arrow.id)) {\n scene.mutateElement(hoveredElement, {\n boundElements: (hoveredElement.boundElements || []).concat({\n id: arrow.id,\n type: \"arrow\"\n })\n });\n }\n};\nconst unbindBindingElement = (arrow, startOrEnd, scene) => {\n var _a;\n\n const field = startOrEnd === \"start\" ? \"startBinding\" : \"endBinding\";\n const binding = arrow[field];\n\n if (binding == null) {\n return null;\n }\n\n const oppositeBinding = arrow[startOrEnd === \"start\" ? \"endBinding\" : \"startBinding\"];\n\n if (!oppositeBinding || oppositeBinding.elementId !== binding.elementId) {\n // Only remove the record on the bound element if the other\n // end is not bound to the same element\n const boundElement = scene.getNonDeletedElementsMap().get(binding.elementId);\n scene.mutateElement(boundElement, {\n boundElements: (_a = boundElement.boundElements) === null || _a === void 0 ? void 0 : _a.filter(element => element.id !== arrow.id)\n });\n }\n\n scene.mutateElement(arrow, {\n [field]: null\n });\n return binding.elementId;\n}; // Supports translating, rotating and scaling `changedElement` with bound\n// linear elements.\n\nconst updateBoundElements = (changedElement, scene, options) => {\n if (!(0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isBindableElement)(changedElement)) {\n return;\n }\n\n const {\n simultaneouslyUpdated\n } = options !== null && options !== void 0 ? options : {};\n const simultaneouslyUpdatedElementIds = getSimultaneouslyUpdatedElementIds(simultaneouslyUpdated);\n let elementsMap = scene.getNonDeletedElementsMap();\n\n if (options === null || options === void 0 ? void 0 : options.changedElements) {\n elementsMap = new Map(elementsMap);\n options.changedElements.forEach(element => {\n elementsMap.set(element.id, element);\n });\n }\n\n boundElementsVisitor(elementsMap, changedElement, element => {\n if (!(0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isArrowElement)(element) || element.isDeleted) {\n return;\n } // In case the boundElements are stale\n\n\n if (!doesNeedUpdate(element, changedElement)) {\n return;\n } // Check for intersections before updating bound elements incase connected elements overlap\n\n\n const startBindingElement = element.startBinding ? elementsMap.get(element.startBinding.elementId) : null;\n const endBindingElement = element.endBinding ? // PERF: If the arrow is bound to the same element on both ends.\n (startBindingElement === null || startBindingElement === void 0 ? void 0 : startBindingElement.id) === element.endBinding.elementId ? startBindingElement : elementsMap.get(element.endBinding.elementId) : null; // `linearElement` is being moved/scaled already, just update the binding\n\n if (simultaneouslyUpdatedElementIds.has(element.id)) {\n return;\n }\n\n const updates = bindableElementsVisitor(elementsMap, element, (bindableElement, bindingProp) => {\n var _a, _b;\n\n if (bindableElement && (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isBindableElement)(bindableElement) && (bindingProp === \"startBinding\" || bindingProp === \"endBinding\") && (changedElement.id === ((_a = element[bindingProp]) === null || _a === void 0 ? void 0 : _a.elementId) || changedElement.id === ((_b = element[bindingProp === \"startBinding\" ? \"endBinding\" : \"startBinding\"]) === null || _b === void 0 ? void 0 : _b.elementId))) {\n const point = updateBoundPoint(element, bindingProp, element[bindingProp], bindableElement, elementsMap);\n\n if (point) {\n return [bindingProp === \"startBinding\" ? 0 : element.points.length - 1, {\n point\n }];\n }\n }\n\n return null;\n }).filter(update => update !== null);\n _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.movePoints(element, scene, new Map(updates), {\n moveMidPointsWithElement: !!startBindingElement && (startBindingElement === null || startBindingElement === void 0 ? void 0 : startBindingElement.id) === (endBindingElement === null || endBindingElement === void 0 ? void 0 : endBindingElement.id)\n });\n const boundText = (0,_textElement__WEBPACK_IMPORTED_MODULE_8__.getBoundTextElement)(element, elementsMap);\n\n if (boundText && !boundText.isDeleted) {\n (0,_textElement__WEBPACK_IMPORTED_MODULE_8__.handleBindTextResize)(element, scene, false);\n }\n });\n};\nconst updateBindings = (latestElement, scene, appState, options) => {\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isArrowElement)(latestElement)) {\n bindOrUnbindBindingElement(latestElement, new Map(), scene, appState);\n } else {\n updateBoundElements(latestElement, scene, Object.assign(Object.assign({}, options), {\n changedElements: new Map([[latestElement.id, latestElement]])\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 getHeadingForElbowArrowSnap = (p, otherPoint, bindableElement, aabb, origPoint, elementsMap, zoom) => {\n const otherPointHeading = (0,_heading__WEBPACK_IMPORTED_MODULE_5__.vectorToHeading)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorFromPoint)(otherPoint, p));\n\n if (!bindableElement || !aabb) {\n return otherPointHeading;\n }\n\n const distance = getDistanceForBinding(origPoint, bindableElement, elementsMap, zoom);\n\n if (!distance) {\n return (0,_heading__WEBPACK_IMPORTED_MODULE_5__.vectorToHeading)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorFromPoint)(p, (0,_bounds__WEBPACK_IMPORTED_MODULE_2__.elementCenterPoint)(bindableElement, elementsMap)));\n }\n\n return (0,_heading__WEBPACK_IMPORTED_MODULE_5__.headingForPointFromElement)(bindableElement, aabb, p);\n};\n\nconst getDistanceForBinding = (point, bindableElement, elementsMap, zoom) => {\n const distance = (0,_distance__WEBPACK_IMPORTED_MODULE_4__.distanceToElement)(bindableElement, elementsMap, point);\n const bindDistance = maxBindingDistance_simple(zoom);\n return distance > bindDistance ? null : distance;\n};\n\nconst bindPointToSnapToElementOutline = (arrowElement, bindableElement, startOrEnd, elementsMap, customIntersector) => {\n const elbowed = (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isElbowArrow)(arrowElement);\n const point = customIntersector && !elbowed ? customIntersector[0] : _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointAtIndexGlobalCoordinates(arrowElement, startOrEnd === \"start\" ? 0 : -1, elementsMap);\n\n if (arrowElement.points.length < 2) {\n // New arrow creation, so no snapping\n return point;\n }\n\n const edgePoint = (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isRectanguloidElement)(bindableElement) ? avoidRectangularCorner(arrowElement, bindableElement, elementsMap, point) : point;\n const adjacentPoint = customIntersector && !elbowed ? customIntersector[1] : _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointAtIndexGlobalCoordinates(arrowElement, startOrEnd === \"start\" ? 1 : -2, elementsMap);\n const bindingGap = getBindingGap(bindableElement, arrowElement);\n const aabb = (0,_bounds__WEBPACK_IMPORTED_MODULE_2__.aabbForElement)(bindableElement, elementsMap);\n const bindableCenter = (0,_bounds__WEBPACK_IMPORTED_MODULE_2__.getCenterForBounds)(aabb);\n let intersection = null;\n\n if (elbowed) {\n const isHorizontal = (0,_heading__WEBPACK_IMPORTED_MODULE_5__.headingIsHorizontal)((0,_heading__WEBPACK_IMPORTED_MODULE_5__.headingForPointFromElement)(bindableElement, aabb, point));\n const snapPoint = snapToMid(arrowElement, bindableElement, elementsMap, edgePoint);\n const otherPoint = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(isHorizontal ? bindableCenter[0] : snapPoint[0], !isHorizontal ? bindableCenter[1] : snapPoint[1]);\n const intersector = customIntersector !== null && customIntersector !== void 0 ? customIntersector : (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.lineSegment)(otherPoint, (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFromVector)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorScale)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorNormalize)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorFromPoint)(snapPoint, otherPoint)), Math.max(bindableElement.width, bindableElement.height) * 2), otherPoint));\n intersection = (0,_collision__WEBPACK_IMPORTED_MODULE_3__.intersectElementWithLineSegment)(bindableElement, elementsMap, intersector, bindingGap).sort(_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistanceSq)[0];\n\n if (!intersection) {\n const anotherPoint = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(!isHorizontal ? bindableCenter[0] : snapPoint[0], isHorizontal ? bindableCenter[1] : snapPoint[1]);\n const anotherIntersector = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.lineSegment)(anotherPoint, (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFromVector)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorScale)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorNormalize)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorFromPoint)(snapPoint, anotherPoint)), Math.max(bindableElement.width, bindableElement.height) * 2), anotherPoint));\n intersection = (0,_collision__WEBPACK_IMPORTED_MODULE_3__.intersectElementWithLineSegment)(bindableElement, elementsMap, anotherIntersector, BASE_BINDING_GAP_ELBOW).sort(_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistanceSq)[0];\n }\n } else {\n let intersector = customIntersector;\n\n if (!intersector) {\n const halfVector = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorScale)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorNormalize)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorFromPoint)(edgePoint, adjacentPoint)), (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistance)(edgePoint, adjacentPoint) + Math.max(bindableElement.width, bindableElement.height) + bindingGap * 2);\n intersector = customIntersector !== null && customIntersector !== void 0 ? customIntersector : (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.lineSegment)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFromVector)(halfVector, adjacentPoint), (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFromVector)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorScale)(halfVector, -1), adjacentPoint));\n }\n\n intersection = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistance)(edgePoint, adjacentPoint) < 1 ? edgePoint : (0,_collision__WEBPACK_IMPORTED_MODULE_3__.intersectElementWithLineSegment)(bindableElement, elementsMap, intersector, bindingGap).sort((g, h) => (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistanceSq)(g, adjacentPoint) - (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistanceSq)(h, adjacentPoint))[0];\n }\n\n if (!intersection || // Too close to determine vector from intersection to edgePoint\n (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistanceSq)(edgePoint, intersection) < _excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.PRECISION) {\n return edgePoint;\n }\n\n return intersection;\n};\nconst avoidRectangularCorner = (arrowElement, bindTarget, elementsMap, p) => {\n const center = (0,_bounds__WEBPACK_IMPORTED_MODULE_2__.elementCenterPoint)(bindTarget, elementsMap);\n const nonRotatedPoint = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)(p, center, -bindTarget.angle);\n const bindingGap = getBindingGap(bindTarget, arrowElement);\n\n if (nonRotatedPoint[0] < bindTarget.x && nonRotatedPoint[1] < bindTarget.y) {\n // Top left\n if (nonRotatedPoint[1] - bindTarget.y > -bindingGap) {\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(bindTarget.x - bindingGap, bindTarget.y), center, bindTarget.angle);\n }\n\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(bindTarget.x, bindTarget.y - bindingGap), center, bindTarget.angle);\n } else if (nonRotatedPoint[0] < bindTarget.x && nonRotatedPoint[1] > bindTarget.y + bindTarget.height) {\n // Bottom left\n if (nonRotatedPoint[0] - bindTarget.x > -bindingGap) {\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(bindTarget.x, bindTarget.y + bindTarget.height + bindingGap), center, bindTarget.angle);\n }\n\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(bindTarget.x - bindingGap, bindTarget.y + bindTarget.height), center, bindTarget.angle);\n } else if (nonRotatedPoint[0] > bindTarget.x + bindTarget.width && nonRotatedPoint[1] > bindTarget.y + bindTarget.height) {\n // Bottom right\n if (nonRotatedPoint[0] - bindTarget.x < bindTarget.width + bindingGap) {\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(bindTarget.x + bindTarget.width, bindTarget.y + bindTarget.height + bindingGap), center, bindTarget.angle);\n }\n\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(bindTarget.x + bindTarget.width + bindingGap, bindTarget.y + bindTarget.height), center, bindTarget.angle);\n } else if (nonRotatedPoint[0] > bindTarget.x + bindTarget.width && nonRotatedPoint[1] < bindTarget.y) {\n // Top right\n if (nonRotatedPoint[0] - bindTarget.x < bindTarget.width + bindingGap) {\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(bindTarget.x + bindTarget.width, bindTarget.y - bindingGap), center, bindTarget.angle);\n }\n\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(bindTarget.x + bindTarget.width + bindingGap, bindTarget.y), center, bindTarget.angle);\n }\n\n return p;\n};\n\nconst snapToMid = (arrowElement, bindTarget, elementsMap, p, tolerance = 0.05) => {\n const {\n x,\n y,\n width,\n height,\n angle\n } = bindTarget;\n const center = (0,_bounds__WEBPACK_IMPORTED_MODULE_2__.elementCenterPoint)(bindTarget, elementsMap, -0.1, -0.1);\n const nonRotated = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)(p, center, -angle);\n const bindingGap = getBindingGap(bindTarget, arrowElement); // snap-to-center point is adaptive to element size, but we don't want to go\n // above and below certain px distance\n\n const verticalThreshold = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.clamp)(tolerance * height, 5, 80);\n const horizontalThreshold = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.clamp)(tolerance * width, 5, 80); // Too close to the center makes it hard to resolve direction precisely\n\n if ((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistance)(center, nonRotated) < bindingGap) {\n return p;\n }\n\n if (nonRotated[0] <= x + width / 2 && nonRotated[1] > center[1] - verticalThreshold && nonRotated[1] < center[1] + verticalThreshold) {\n // LEFT\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(x - bindingGap, center[1]), center, angle);\n } else if (nonRotated[1] <= y + height / 2 && nonRotated[0] > center[0] - horizontalThreshold && nonRotated[0] < center[0] + horizontalThreshold) {\n // TOP\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(center[0], y - bindingGap), center, angle);\n } else if (nonRotated[0] >= x + width / 2 && nonRotated[1] > center[1] - verticalThreshold && nonRotated[1] < center[1] + verticalThreshold) {\n // RIGHT\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(x + width + bindingGap, center[1]), center, angle);\n } else if (nonRotated[1] >= y + height / 2 && nonRotated[0] > center[0] - horizontalThreshold && nonRotated[0] < center[0] + horizontalThreshold) {\n // DOWN\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(center[0], y + height + bindingGap), center, angle);\n } else if (bindTarget.type === \"diamond\") {\n const distance = bindingGap;\n const topLeft = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(x + width / 4 - distance, y + height / 4 - distance);\n const topRight = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(x + 3 * width / 4 + distance, y + height / 4 - distance);\n const bottomLeft = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(x + width / 4 - distance, y + 3 * height / 4 + distance);\n const bottomRight = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(x + 3 * width / 4 + distance, y + 3 * height / 4 + distance);\n\n if ((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistance)(topLeft, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)(topLeft, center, angle);\n }\n\n if ((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistance)(topRight, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)(topRight, center, angle);\n }\n\n if ((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistance)(bottomLeft, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)(bottomLeft, center, angle);\n }\n\n if ((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistance)(bottomRight, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)(bottomRight, center, angle);\n }\n }\n\n return p;\n};\n\nconst compareElementArea = (a, b) => b.width ** 2 + b.height ** 2 - (a.width ** 2 + a.height ** 2);\n\nconst updateBoundPoint = (arrow, startOrEnd, binding, bindableElement, elementsMap, customIntersector) => {\n if (binding == null || // We only need to update the other end if this is a 2 point line element\n binding.elementId !== bindableElement.id && arrow.points.length > 2) {\n return null;\n }\n\n const global = getGlobalFixedPointForBindableElement(normalizeFixedPoint(binding.fixedPoint), bindableElement, elementsMap);\n const pointIndex = startOrEnd === \"startBinding\" ? 0 : arrow.points.length - 1;\n const elbowed = (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isElbowArrow)(arrow);\n const otherBinding = startOrEnd === \"startBinding\" ? arrow.endBinding : arrow.startBinding;\n const otherBindableElement = otherBinding && elementsMap.get(otherBinding.elementId);\n const bounds = (0,_bounds__WEBPACK_IMPORTED_MODULE_2__.getElementBounds)(bindableElement, elementsMap);\n const otherBounds = otherBindableElement && (0,_bounds__WEBPACK_IMPORTED_MODULE_2__.getElementBounds)(otherBindableElement, elementsMap);\n const isLargerThanOther = otherBindableElement && compareElementArea(bindableElement, otherBindableElement) < ( // if both shapes the same size, pretend the other is larger\n startOrEnd === \"endBinding\" ? 1 : 0);\n const isOverlapping = otherBounds && (0,_bounds__WEBPACK_IMPORTED_MODULE_2__.doBoundsIntersect)(bounds, otherBounds); // GOAL: If the arrow becomes too short, we want to jump the arrow endpoints\n // to the exact focus points on the elements.\n // INTUITION: We're not interested in the exacts length of the arrow (which\n // will change if we change where we route it), we want to know the length of\n // the part which lies outside of both shapes and consider that as a trigger\n // to change where we point the arrow. Avoids jumping the arrow in and out\n // at every frame.\n\n let arrowTooShort = false;\n\n if (!isOverlapping && !elbowed && arrow.startBinding && arrow.endBinding && otherBindableElement && arrow.points.length === 2) {\n const startFocusPoint = getGlobalFixedPointForBindableElement(arrow.startBinding.fixedPoint, startOrEnd === \"startBinding\" ? bindableElement : otherBindableElement, elementsMap);\n const endFocusPoint = getGlobalFixedPointForBindableElement(arrow.endBinding.fixedPoint, startOrEnd === \"endBinding\" ? bindableElement : otherBindableElement, elementsMap);\n const segment = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.lineSegment)(startFocusPoint, endFocusPoint);\n const startIntersection = (0,_collision__WEBPACK_IMPORTED_MODULE_3__.intersectElementWithLineSegment)(startOrEnd === \"endBinding\" ? bindableElement : otherBindableElement, elementsMap, segment, 0, true);\n const endIntersection = (0,_collision__WEBPACK_IMPORTED_MODULE_3__.intersectElementWithLineSegment)(startOrEnd === \"startBinding\" ? bindableElement : otherBindableElement, elementsMap, segment, 0, true);\n\n if (startIntersection.length > 0 && endIntersection.length > 0) {\n const len = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistance)(startIntersection[0], endIntersection[0]);\n arrowTooShort = len < 40;\n }\n }\n\n const isNested = (arrowTooShort || isOverlapping) && isLargerThanOther;\n let _customIntersector = customIntersector;\n\n if (!elbowed && !_customIntersector) {\n const [x1, y1, x2, y2] = _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getElementAbsoluteCoords(arrow, elementsMap);\n const center = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)((x1 + x2) / 2, (y1 + y2) / 2);\n const edgePoint = (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isRectanguloidElement)(bindableElement) ? avoidRectangularCorner(arrow, bindableElement, elementsMap, global) : global;\n const adjacentPoint = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(arrow.x + arrow.points[pointIndex === 0 ? 1 : arrow.points.length - 2][0], arrow.y + arrow.points[pointIndex === 0 ? 1 : arrow.points.length - 2][1]), center, arrow.angle);\n const bindingGap = getBindingGap(bindableElement, arrow);\n const halfVector = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorScale)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorNormalize)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorFromPoint)(edgePoint, adjacentPoint)), (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistance)(edgePoint, adjacentPoint) + Math.max(bindableElement.width, bindableElement.height) + bindingGap * 2);\n _customIntersector = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.lineSegment)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFromVector)(halfVector, adjacentPoint), (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFromVector)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorScale)(halfVector, -1), adjacentPoint));\n }\n\n const maybeOutlineGlobal = binding.mode === \"orbit\" && bindableElement ? isNested ? global : bindPointToSnapToElementOutline(Object.assign(Object.assign({}, arrow), {\n points: [pointIndex === 0 ? _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.createPointAt(arrow, elementsMap, global[0], global[1], null) : arrow.points[0], ...arrow.points.slice(1, -1), pointIndex === arrow.points.length - 1 ? _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.createPointAt(arrow, elementsMap, global[0], global[1], null) : arrow.points[arrow.points.length - 1]]\n }), bindableElement, pointIndex === 0 ? \"start\" : \"end\", elementsMap, _customIntersector) : global;\n return _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.createPointAt(arrow, elementsMap, maybeOutlineGlobal[0], maybeOutlineGlobal[1], null);\n};\nconst calculateFixedPointForElbowArrowBinding = (linearElement, hoveredElement, startOrEnd, elementsMap) => {\n const bounds = [hoveredElement.x, hoveredElement.y, hoveredElement.x + hoveredElement.width, hoveredElement.y + hoveredElement.height];\n const snappedPoint = bindPointToSnapToElementOutline(linearElement, hoveredElement, startOrEnd, elementsMap);\n const globalMidPoint = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(bounds[0] + (bounds[2] - bounds[0]) / 2, bounds[1] + (bounds[3] - bounds[1]) / 2);\n const nonRotatedSnappedGlobalPoint = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)(snappedPoint, globalMidPoint, -hoveredElement.angle);\n return {\n fixedPoint: normalizeFixedPoint([(nonRotatedSnappedGlobalPoint[0] - hoveredElement.x) / hoveredElement.width, (nonRotatedSnappedGlobalPoint[1] - hoveredElement.y) / hoveredElement.height])\n };\n};\nconst calculateFixedPointForNonElbowArrowBinding = (linearElement, hoveredElement, startOrEnd, elementsMap, focusPoint) => {\n const edgePoint = focusPoint ? focusPoint : _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointAtIndexGlobalCoordinates(linearElement, startOrEnd === \"start\" ? 0 : -1, elementsMap); // Convert the global point to element-local coordinates\n\n const elementCenter = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(hoveredElement.x + hoveredElement.width / 2, hoveredElement.y + hoveredElement.height / 2); // Rotate the point to account for element rotation\n\n const nonRotatedPoint = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)(edgePoint, elementCenter, -hoveredElement.angle); // Calculate the ratio relative to the element's bounds\n\n const fixedPointX = (nonRotatedPoint[0] - hoveredElement.x) / hoveredElement.width;\n const fixedPointY = (nonRotatedPoint[1] - hoveredElement.y) / hoveredElement.height;\n return {\n fixedPoint: normalizeFixedPoint([fixedPointX, fixedPointY])\n };\n};\nconst fixDuplicatedBindingsAfterDuplication = (duplicatedElements, origIdToDuplicateId, duplicateElementsMap) => {\n var _a;\n\n for (const duplicateElement of duplicatedElements) {\n if (\"boundElements\" in duplicateElement && duplicateElement.boundElements) {\n Object.assign(duplicateElement, {\n boundElements: duplicateElement.boundElements.reduce((acc, binding) => {\n const newBindingId = origIdToDuplicateId.get(binding.id);\n\n if (newBindingId) {\n acc.push(Object.assign(Object.assign({}, binding), {\n id: newBindingId\n }));\n }\n\n return acc;\n }, [])\n });\n }\n\n if (\"containerId\" in duplicateElement && duplicateElement.containerId) {\n Object.assign(duplicateElement, {\n containerId: (_a = origIdToDuplicateId.get(duplicateElement.containerId)) !== null && _a !== void 0 ? _a : null\n });\n }\n\n if (\"endBinding\" in duplicateElement && duplicateElement.endBinding) {\n const newEndBindingId = origIdToDuplicateId.get(duplicateElement.endBinding.elementId);\n Object.assign(duplicateElement, {\n endBinding: newEndBindingId ? Object.assign(Object.assign({}, duplicateElement.endBinding), {\n elementId: newEndBindingId\n }) : null\n });\n }\n\n if (\"startBinding\" in duplicateElement && duplicateElement.startBinding) {\n const newEndBindingId = origIdToDuplicateId.get(duplicateElement.startBinding.elementId);\n Object.assign(duplicateElement, {\n startBinding: newEndBindingId ? Object.assign(Object.assign({}, duplicateElement.startBinding), {\n elementId: newEndBindingId\n }) : null\n });\n }\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isElbowArrow)(duplicateElement)) {\n Object.assign(duplicateElement, (0,_elbowArrow__WEBPACK_IMPORTED_MODULE_10__.updateElbowArrowPoints)(duplicateElement, duplicateElementsMap, {\n points: [duplicateElement.points[0], duplicateElement.points[duplicateElement.points.length - 1]]\n }));\n }\n }\n};\nconst fixBindingsAfterDeletion = (sceneElements, deletedElements) => {\n const elements = (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.arrayToMap)(sceneElements);\n\n for (const element of deletedElements) {\n BoundElement.unbindAffected(elements, element, (element, updates) => (0,_mutateElement__WEBPACK_IMPORTED_MODULE_7__.mutateElement)(element, elements, updates));\n BindableElement.unbindAffected(elements, element, (element, updates) => (0,_mutateElement__WEBPACK_IMPORTED_MODULE_7__.mutateElement)(element, elements, updates));\n }\n};\n\nconst newBoundElements = (boundElements, idsToRemove, elementsToAdd = []) => {\n if (!boundElements) {\n return null;\n }\n\n const nextBoundElements = boundElements.filter(boundElement => !idsToRemove.has(boundElement.id));\n nextBoundElements.push(...elementsToAdd.map(x => ({\n id: x.id,\n type: x.type\n })));\n return nextBoundElements;\n};\n\nconst bindingProperties = new Set([\"boundElements\", \"frameId\", \"containerId\", \"startBinding\", \"endBinding\"]);\n/**\r\n * Tries to visit each bound element (does not have to be found).\r\n */\n\nconst boundElementsVisitor = (elements, element, visit) => {\n var _a, _b;\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isBindableElement)(element)) {\n // create new instance so that possible mutations won't play a role in visiting order\n const boundElements = (_b = (_a = element.boundElements) === null || _a === void 0 ? void 0 : _a.slice()) !== null && _b !== void 0 ? _b : []; // last added text should be the one we keep (~previous are duplicates)\n\n boundElements.forEach(({\n id\n }) => {\n visit(elements.get(id), \"boundElements\", id);\n });\n }\n};\n/**\r\n * Tries to visit each bindable element (does not have to be found).\r\n */\n\n\nconst bindableElementsVisitor = (elements, element, visit) => {\n const result = [];\n\n if (element.frameId) {\n const id = element.frameId;\n result.push(visit(elements.get(id), \"frameId\", id));\n }\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isBoundToContainer)(element)) {\n const id = element.containerId;\n result.push(visit(elements.get(id), \"containerId\", id));\n }\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isArrowElement)(element)) {\n if (element.startBinding) {\n const id = element.startBinding.elementId;\n result.push(visit(elements.get(id), \"startBinding\", id));\n }\n\n if (element.endBinding) {\n const id = element.endBinding.elementId;\n result.push(visit(elements.get(id), \"endBinding\", id));\n }\n }\n\n return result;\n};\n/**\r\n * Bound element containing bindings to `frameId`, `containerId`, `startBinding` or `endBinding`.\r\n */\n\n\nclass BoundElement {\n /**\r\n * Unbind the affected non deleted bindable elements (removing element from `boundElements`).\r\n * - iterates non deleted bindable elements (`containerId` | `startBinding.elementId` | `endBinding.elementId`) of the current element\r\n * - prepares updates to unbind each bindable element's `boundElements` from the current element\r\n */\n static unbindAffected(elements, boundElement, updateElementWith) {\n if (!boundElement) {\n return;\n }\n\n bindableElementsVisitor(elements, boundElement, bindableElement => {\n // bindable element is deleted, this is fine\n if (!bindableElement || bindableElement.isDeleted) {\n return;\n }\n\n boundElementsVisitor(elements, bindableElement, (_, __, boundElementId) => {\n if (boundElementId === boundElement.id) {\n updateElementWith(bindableElement, {\n boundElements: newBoundElements(bindableElement.boundElements, new Set([boundElementId]))\n });\n }\n });\n });\n }\n\n}\n/**\r\n * Rebind the next affected non deleted bindable elements (adding element to `boundElements`).\r\n * - iterates non deleted bindable elements (`containerId` | `startBinding.elementId` | `endBinding.elementId`) of the current element\r\n * - prepares updates to rebind each bindable element's `boundElements` to the current element\r\n *\r\n * NOTE: rebind expects that affected elements were previously unbound with `BoundElement.unbindAffected`\r\n */\n\nBoundElement.rebindAffected = (elements, boundElement, updateElementWith) => {\n // don't try to rebind element that is deleted\n if (!boundElement || boundElement.isDeleted) {\n return;\n }\n\n bindableElementsVisitor(elements, boundElement, (bindableElement, bindingProp) => {\n var _a, _b; // unbind from bindable elements, as bindings from non deleted elements into deleted elements are incorrect\n\n\n if (!bindableElement || bindableElement.isDeleted) {\n updateElementWith(boundElement, {\n [bindingProp]: null\n });\n return;\n } // frame bindings are unidirectional, there is nothing to rebind\n\n\n if (bindingProp === \"frameId\") {\n return;\n }\n\n if ((_a = bindableElement.boundElements) === null || _a === void 0 ? void 0 : _a.find(x => x.id === boundElement.id)) {\n return;\n }\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isArrowElement)(boundElement)) {\n // rebind if not found!\n updateElementWith(bindableElement, {\n boundElements: newBoundElements(bindableElement.boundElements, new Set(), new Array(boundElement))\n });\n }\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(boundElement)) {\n if (!((_b = bindableElement.boundElements) === null || _b === void 0 ? void 0 : _b.find(x => x.type === \"text\"))) {\n // rebind only if there is no other text bound already\n updateElementWith(bindableElement, {\n boundElements: newBoundElements(bindableElement.boundElements, new Set(), new Array(boundElement))\n });\n } else {\n // unbind otherwise\n updateElementWith(boundElement, {\n [bindingProp]: null\n });\n }\n }\n });\n};\n/**\r\n * Bindable element containing bindings to `boundElements`.\r\n */\n\n\nclass BindableElement {\n /**\r\n * Unbind the affected non deleted bound elements (resetting `containerId`, `startBinding`, `endBinding` to `null`).\r\n * - iterates through non deleted `boundElements` of the current element\r\n * - prepares updates to unbind each bound element from the current element\r\n */\n static unbindAffected(elements, bindableElement, updateElementWith) {\n if (!bindableElement) {\n return;\n }\n\n boundElementsVisitor(elements, bindableElement, boundElement => {\n // bound element is deleted, this is fine\n if (!boundElement || boundElement.isDeleted) {\n return;\n }\n\n bindableElementsVisitor(elements, boundElement, (_, bindingProp, bindableElementId) => {\n // making sure there is an element to be unbound\n if (bindableElementId === bindableElement.id) {\n updateElementWith(boundElement, {\n [bindingProp]: null\n });\n }\n });\n });\n }\n\n}\n/**\r\n * Rebind the affected non deleted bound elements (for now setting only `containerId`, as we cannot rebind arrows atm).\r\n * - iterates through non deleted `boundElements` of the current element\r\n * - prepares updates to rebind each bound element to the current element or unbind it from `boundElements` in case of conflicts\r\n *\r\n * NOTE: rebind expects that affected elements were previously unbound with `BindaleElement.unbindAffected`\r\n */\n\nBindableElement.rebindAffected = (elements, bindableElement, updateElementWith) => {\n // don't try to rebind element that is deleted (i.e. updated as deleted)\n if (!bindableElement || bindableElement.isDeleted) {\n return;\n }\n\n boundElementsVisitor(elements, bindableElement, (boundElement, _, boundElementId) => {\n var _a, _b, _c; // unbind from bindable elements, as bindings from non deleted elements into deleted elements are incorrect\n\n\n if (!boundElement || boundElement.isDeleted) {\n updateElementWith(bindableElement, {\n boundElements: newBoundElements(bindableElement.boundElements, new Set([boundElementId]))\n });\n return;\n }\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(boundElement)) {\n const boundElements = (_b = (_a = bindableElement.boundElements) === null || _a === void 0 ? void 0 : _a.slice()) !== null && _b !== void 0 ? _b : []; // check if this is the last element in the array, if not, there is an previously bound text which should be unbound\n\n if (((_c = boundElements.reverse().find(x => x.type === \"text\")) === null || _c === void 0 ? void 0 : _c.id) === boundElement.id) {\n if (boundElement.containerId !== bindableElement.id) {\n // rebind if not bound already!\n updateElementWith(boundElement, {\n containerId: bindableElement.id\n });\n }\n } else {\n if (boundElement.containerId !== null) {\n // unbind if not unbound already\n updateElementWith(boundElement, {\n containerId: null\n });\n } // unbind from boundElements as the element got bound to some other element in the meantime\n\n\n updateElementWith(bindableElement, {\n boundElements: newBoundElements(bindableElement.boundElements, new Set([boundElement.id]))\n });\n }\n }\n });\n};\n\nconst getGlobalFixedPointForBindableElement = (fixedPointRatio, element, elementsMap) => {\n const [fixedX, fixedY] = normalizeFixedPoint(fixedPointRatio);\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(element.x + element.width * fixedX, element.y + element.height * fixedY), (0,_bounds__WEBPACK_IMPORTED_MODULE_2__.elementCenterPoint)(element, elementsMap), element.angle);\n};\nconst getGlobalFixedPoints = (arrow, elementsMap) => {\n const startElement = arrow.startBinding && elementsMap.get(arrow.startBinding.elementId);\n const endElement = arrow.endBinding && elementsMap.get(arrow.endBinding.elementId);\n const startPoint = startElement && arrow.startBinding ? getGlobalFixedPointForBindableElement(arrow.startBinding.fixedPoint, startElement, elementsMap) : (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(arrow.x + arrow.points[0][0], arrow.y + arrow.points[0][1]);\n const endPoint = endElement && arrow.endBinding ? getGlobalFixedPointForBindableElement(arrow.endBinding.fixedPoint, endElement, elementsMap) : (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(arrow.x + arrow.points[arrow.points.length - 1][0], arrow.y + arrow.points[arrow.points.length - 1][1]);\n return [startPoint, endPoint];\n};\nconst getArrowLocalFixedPoints = (arrow, elementsMap) => {\n const [startPoint, endPoint] = getGlobalFixedPoints(arrow, elementsMap);\n return [_linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.pointFromAbsoluteCoords(arrow, startPoint, elementsMap), _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.pointFromAbsoluteCoords(arrow, endPoint, elementsMap)];\n};\nconst normalizeFixedPoint = fixedPoint => {\n // Do not allow a precise 0.5 for fixed point ratio\n // to avoid jumping arrow heading due to floating point imprecision\n if (fixedPoint && (Math.abs(fixedPoint[0] - 0.5) < 0.0001 || Math.abs(fixedPoint[1] - 0.5) < 0.0001)) {\n return fixedPoint.map(ratio => Math.abs(ratio - 0.5) < 0.0001 ? 0.5001 : ratio);\n }\n\n return fixedPoint;\n};\n\n//# sourceURL=webpack://ExcalidrawLib/../element/src/binding.ts?");
13138
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ BASE_BINDING_GAP: () => (/* binding */ BASE_BINDING_GAP),\n/* harmony export */ BASE_BINDING_GAP_ELBOW: () => (/* binding */ BASE_BINDING_GAP_ELBOW),\n/* harmony export */ BindableElement: () => (/* binding */ BindableElement),\n/* harmony export */ BoundElement: () => (/* binding */ BoundElement),\n/* harmony export */ avoidRectangularCorner: () => (/* binding */ avoidRectangularCorner),\n/* harmony export */ bindBindingElement: () => (/* binding */ bindBindingElement),\n/* harmony export */ bindOrUnbindBindingElement: () => (/* binding */ bindOrUnbindBindingElement),\n/* harmony export */ bindOrUnbindBindingElements: () => (/* binding */ bindOrUnbindBindingElements),\n/* harmony export */ bindPointToSnapToElementOutline: () => (/* binding */ bindPointToSnapToElementOutline),\n/* harmony export */ bindingProperties: () => (/* binding */ bindingProperties),\n/* harmony export */ calculateFixedPointForElbowArrowBinding: () => (/* binding */ calculateFixedPointForElbowArrowBinding),\n/* harmony export */ calculateFixedPointForNonElbowArrowBinding: () => (/* binding */ calculateFixedPointForNonElbowArrowBinding),\n/* harmony export */ fixBindingsAfterDeletion: () => (/* binding */ fixBindingsAfterDeletion),\n/* harmony export */ fixDuplicatedBindingsAfterDuplication: () => (/* binding */ fixDuplicatedBindingsAfterDuplication),\n/* harmony export */ getArrowLocalFixedPoints: () => (/* binding */ getArrowLocalFixedPoints),\n/* harmony export */ getBindingGap: () => (/* binding */ getBindingGap),\n/* harmony export */ getBindingStrategyForDraggingBindingElementEndpoints: () => (/* binding */ getBindingStrategyForDraggingBindingElementEndpoints),\n/* harmony export */ getGlobalFixedPointForBindableElement: () => (/* binding */ getGlobalFixedPointForBindableElement),\n/* harmony export */ getGlobalFixedPoints: () => (/* binding */ getGlobalFixedPoints),\n/* harmony export */ getHeadingForElbowArrowSnap: () => (/* binding */ getHeadingForElbowArrowSnap),\n/* harmony export */ isBindingEnabled: () => (/* binding */ isBindingEnabled),\n/* harmony export */ maxBindingDistance_simple: () => (/* binding */ maxBindingDistance_simple),\n/* harmony export */ normalizeFixedPoint: () => (/* binding */ normalizeFixedPoint),\n/* harmony export */ shouldEnableBindingForPointerEvent: () => (/* binding */ shouldEnableBindingForPointerEvent),\n/* harmony export */ unbindBindingElement: () => (/* binding */ unbindBindingElement),\n/* harmony export */ updateBindings: () => (/* binding */ updateBindings),\n/* harmony export */ updateBoundElements: () => (/* binding */ updateBoundElements),\n/* harmony export */ updateBoundPoint: () => (/* binding */ updateBoundPoint)\n/* harmony export */ });\n/* harmony import */ var _excalidraw_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @excalidraw/common */ \"../common/src/index.ts\");\n/* harmony import */ var _excalidraw_math__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @excalidraw/math */ \"../math/src/index.ts\");\n/* harmony import */ var _bounds__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./bounds */ \"../element/src/bounds.ts\");\n/* harmony import */ var _collision__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./collision */ \"../element/src/collision.ts\");\n/* harmony import */ var _distance__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./distance */ \"../element/src/distance.ts\");\n/* harmony import */ var _heading__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./heading */ \"../element/src/heading.ts\");\n/* harmony import */ var _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./linearElementEditor */ \"../element/src/linearElementEditor.ts\");\n/* harmony import */ var _mutateElement__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./mutateElement */ \"../element/src/mutateElement.ts\");\n/* harmony import */ var _textElement__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./textElement */ \"../element/src/textElement.ts\");\n/* harmony import */ var _typeChecks__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./typeChecks */ \"../element/src/typeChecks.ts\");\n/* harmony import */ var _elbowArrow__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./elbowArrow */ \"../element/src/elbowArrow.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./utils */ \"../element/src/utils.ts\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\r\n * gaps exclude element strokeWidth\r\n *\r\n * IMPORTANT: currently must be > 0 (this also applies to the computed gap)\r\n */\n\nconst BASE_BINDING_GAP = 10;\nconst BASE_BINDING_GAP_ELBOW = 5;\nconst getBindingGap = (bindTarget, opts) => {\n return (opts.elbowed ? BASE_BINDING_GAP_ELBOW : BASE_BINDING_GAP) + bindTarget.strokeWidth / 2;\n};\nconst maxBindingDistance_simple = zoom => {\n const BASE_BINDING_DISTANCE = Math.max(BASE_BINDING_GAP, 15);\n const zoomValue = (zoom === null || zoom === void 0 ? void 0 : zoom.value) && zoom.value < 1 ? zoom.value : 1;\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.clamp)( // reducing zoom impact so that the diff between binding distance and\n // binding gap is kept to minimum when possible\n BASE_BINDING_DISTANCE / (zoomValue * 1.5), BASE_BINDING_DISTANCE, BASE_BINDING_DISTANCE * 2);\n};\nconst shouldEnableBindingForPointerEvent = event => {\n return !event[_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.KEYS.CTRL_OR_CMD];\n};\nconst isBindingEnabled = appState => {\n return appState.invertBindingBehaviour //zsviczian\n ? !appState.isBindingEnabled : appState.isBindingEnabled;\n};\nconst bindOrUnbindBindingElement = (arrow, draggingPoints, scene, appState, opts) => {\n const {\n start,\n end\n } = getBindingStrategyForDraggingBindingElementEndpoints(arrow, draggingPoints, scene.getNonDeletedElementsMap(), scene.getNonDeletedElements(), appState, Object.assign(Object.assign({}, opts), {\n finalize: true\n }));\n bindOrUnbindBindingElementEdge(arrow, start, \"start\", scene);\n bindOrUnbindBindingElementEdge(arrow, end, \"end\", scene);\n\n if (start.focusPoint || end.focusPoint) {\n // If the strategy dictates a focus point override, then\n // update the arrow points to point to the focus point.\n const updates = new Map();\n\n if (start.focusPoint) {\n updates.set(0, {\n point: updateBoundPoint(arrow, \"startBinding\", arrow.startBinding, start.element, scene.getNonDeletedElementsMap()) || arrow.points[0]\n });\n }\n\n if (end.focusPoint) {\n updates.set(arrow.points.length - 1, {\n point: updateBoundPoint(arrow, \"endBinding\", arrow.endBinding, end.element, scene.getNonDeletedElementsMap()) || arrow.points[arrow.points.length - 1]\n });\n }\n\n _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.movePoints(arrow, scene, updates);\n }\n\n return {\n start,\n end\n };\n};\n\nconst bindOrUnbindBindingElementEdge = (arrow, {\n mode,\n element,\n focusPoint\n}, startOrEnd, scene) => {\n if (mode === null) {\n // null means break the binding\n unbindBindingElement(arrow, startOrEnd, scene);\n } else if (mode !== undefined) {\n bindBindingElement(arrow, element, mode, startOrEnd, scene, focusPoint);\n }\n};\n\nconst bindingStrategyForElbowArrowEndpointDragging = (arrow, draggingPoints, elementsMap, elements, zoom) => {\n (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.invariant)(draggingPoints.size === 1, \"Bound elbow arrows cannot be moved\");\n const update = draggingPoints.entries().next().value;\n (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.invariant)(update, \"There should be a position update for dragging an elbow arrow endpoint\");\n const [pointIdx, {\n point\n }] = update;\n const globalPoint = _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointGlobalCoordinates(arrow, point, elementsMap);\n const hit = (0,_collision__WEBPACK_IMPORTED_MODULE_3__.getHoveredElementForBinding)(globalPoint, elements, elementsMap, element => maxBindingDistance_simple(zoom));\n const current = hit ? {\n element: hit,\n mode: \"orbit\",\n focusPoint: _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointAtIndexGlobalCoordinates(arrow, pointIdx, elementsMap)\n } : {\n mode: null\n };\n const other = {\n mode: undefined\n };\n return pointIdx === 0 ? {\n start: current,\n end: other\n } : {\n start: other,\n end: current\n };\n};\n\nconst bindingStrategyForNewSimpleArrowEndpointDragging = (arrow, draggingPoints, elementsMap, elements, startDragged, endDragged, startIdx, endIdx, appState, globalBindMode, shiftKey) => {\n var _a, _b, _c;\n\n let start = {\n mode: undefined\n };\n let end = {\n mode: undefined\n };\n const isMultiPoint = arrow.points.length > 2;\n const point = _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointGlobalCoordinates(arrow, draggingPoints.get(startDragged ? startIdx : endIdx).point, elementsMap);\n const hit = (0,_collision__WEBPACK_IMPORTED_MODULE_3__.getHoveredElementForBinding)(point, elements, elementsMap); // With new arrows this handles the binding at arrow creation\n\n if (startDragged) {\n if (hit) {\n start = {\n element: hit,\n mode: \"inside\",\n focusPoint: point\n };\n } else {\n start = {\n mode: null\n };\n }\n\n return {\n start,\n end\n };\n } // With new arrows it represents the continuous dragging of the end point\n\n\n if (endDragged) {\n const origin = (_a = appState === null || appState === void 0 ? void 0 : appState.selectedLinearElement) === null || _a === void 0 ? void 0 : _a.initialState.origin; // Inside -> inside binding\n\n if (hit && ((_b = arrow.startBinding) === null || _b === void 0 ? void 0 : _b.elementId) === hit.id) {\n const center = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(hit.x + hit.width / 2, hit.y + hit.height / 2);\n return {\n start: isMultiPoint ? {\n mode: undefined\n } : {\n mode: \"inside\",\n element: hit,\n focusPoint: origin !== null && origin !== void 0 ? origin : center\n },\n end: isMultiPoint ? {\n mode: \"orbit\",\n element: hit,\n focusPoint: point\n } : {\n mode: \"inside\",\n element: hit,\n focusPoint: point\n }\n };\n } // Check and handle nested shapes\n\n\n if (hit && arrow.startBinding) {\n const startBinding = arrow.startBinding;\n const allHits = (0,_collision__WEBPACK_IMPORTED_MODULE_3__.getAllHoveredElementAtPoint)(point, elements, elementsMap);\n\n if (allHits.find(el => el.id === startBinding.elementId)) {\n const otherElement = elementsMap.get(arrow.startBinding.elementId);\n (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.invariant)(otherElement, \"Other element must be in the elements map\");\n return {\n start: isMultiPoint ? {\n mode: undefined\n } : {\n mode: otherElement.id !== hit.id ? \"orbit\" : \"inside\",\n element: otherElement,\n focusPoint: origin !== null && origin !== void 0 ? origin : (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(arrow.x, arrow.y)\n },\n end: {\n mode: \"orbit\",\n element: hit,\n focusPoint: point\n }\n };\n }\n } // Inside -> outside binding\n\n\n if (arrow.startBinding && arrow.startBinding.elementId !== (hit === null || hit === void 0 ? void 0 : hit.id)) {\n const otherElement = elementsMap.get(arrow.startBinding.elementId);\n (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.invariant)(otherElement, \"Other element must be in the elements map\");\n const otherIsInsideBinding = !!((_c = appState.selectedLinearElement) === null || _c === void 0 ? void 0 : _c.initialState.arrowStartIsInside);\n const other = {\n mode: otherIsInsideBinding ? \"inside\" : \"orbit\",\n element: otherElement,\n focusPoint: shiftKey ? (0,_bounds__WEBPACK_IMPORTED_MODULE_2__.elementCenterPoint)(otherElement, elementsMap) : origin !== null && origin !== void 0 ? origin : (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(arrow.x, arrow.y)\n }; // We are hovering another element with the end point\n\n const isNested = hit && (0,_collision__WEBPACK_IMPORTED_MODULE_3__.isBindableElementInsideOtherBindable)(otherElement, hit, elementsMap);\n let current;\n\n if (hit) {\n const isInsideBinding = globalBindMode === \"inside\" || globalBindMode === \"skip\";\n current = {\n mode: isInsideBinding && !isNested ? \"inside\" : \"orbit\",\n element: hit,\n focusPoint: isInsideBinding || isNested ? point : point\n };\n } else {\n current = {\n mode: null\n };\n }\n\n return {\n start: isMultiPoint ? {\n mode: undefined\n } : other,\n end: current\n };\n } // No start binding\n\n\n if (!arrow.startBinding) {\n if (hit) {\n const isInsideBinding = globalBindMode === \"inside\" || globalBindMode === \"skip\";\n end = {\n mode: isInsideBinding ? \"inside\" : \"orbit\",\n element: hit,\n focusPoint: point\n };\n } else {\n end = {\n mode: null\n };\n }\n\n return {\n start,\n end\n };\n }\n }\n\n (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.invariant)(false, \"New arrow creation should not reach here\");\n};\n\nconst bindingStrategyForSimpleArrowEndpointDragging_complex = (point, currentBinding, oppositeBinding, elementsMap, elements, globalBindMode, arrow, finalize) => {\n let current = {\n mode: undefined\n };\n let other = {\n mode: undefined\n };\n const isMultiPoint = arrow.points.length > 2;\n const hit = (0,_collision__WEBPACK_IMPORTED_MODULE_3__.getHoveredElementForBinding)(point, elements, elementsMap);\n const isOverlapping = oppositeBinding ? (0,_collision__WEBPACK_IMPORTED_MODULE_3__.getAllHoveredElementAtPoint)(point, elements, elementsMap).some(el => el.id === oppositeBinding.elementId) : false;\n const oppositeElement = oppositeBinding ? elementsMap.get(oppositeBinding.elementId) : null;\n const otherIsTransparent = isOverlapping && oppositeElement ? (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.isTransparent)(oppositeElement.backgroundColor) : false;\n const isNested = hit && oppositeElement && (0,_collision__WEBPACK_IMPORTED_MODULE_3__.isBindableElementInsideOtherBindable)(oppositeElement, hit, elementsMap); // If the global bind mode is in free binding mode, just bind\n // where the pointer is and keep the other end intact\n\n if (globalBindMode === \"inside\" || globalBindMode === \"skip\") {\n current = hit ? {\n element: !isOverlapping || !oppositeElement || otherIsTransparent ? hit : oppositeElement,\n focusPoint: point,\n mode: \"inside\"\n } : {\n mode: null\n };\n other = finalize && hit && hit.id === (oppositeBinding === null || oppositeBinding === void 0 ? void 0 : oppositeBinding.elementId) ? {\n mode: null\n } : other;\n return {\n current,\n other\n };\n } // Dragged point is outside of any bindable element\n // so we break any existing binding\n\n\n if (!hit) {\n return {\n current: {\n mode: null\n },\n other\n };\n } // Already inside binding over the same hit element should remain inside bound\n\n\n if (hit.id === (currentBinding === null || currentBinding === void 0 ? void 0 : currentBinding.elementId) && currentBinding.mode === \"inside\") {\n return {\n current: {\n mode: \"inside\",\n focusPoint: point,\n element: hit\n },\n other\n };\n } // The dragged point is inside the hovered bindable element\n\n\n if (oppositeBinding) {\n // The opposite binding is on the same element\n if (oppositeBinding.elementId === hit.id) {\n // The opposite binding is on the binding gap of the same element\n if (oppositeBinding.mode === \"orbit\") {\n current = {\n element: hit,\n mode: \"orbit\",\n focusPoint: point\n };\n other = {\n mode: finalize ? null : undefined\n };\n return {\n current,\n other: isMultiPoint ? {\n mode: undefined\n } : other\n };\n } // The opposite binding is inside the same element\n // eslint-disable-next-line no-else-return\n else {\n current = {\n element: hit,\n mode: \"inside\",\n focusPoint: point\n };\n return {\n current,\n other: isMultiPoint ? {\n mode: undefined\n } : other\n };\n }\n } // The opposite binding is on a different element (or nested)\n // eslint-disable-next-line no-else-return\n else {\n // Handle the nested element case\n if (isOverlapping && oppositeElement && !otherIsTransparent) {\n current = {\n element: oppositeElement,\n mode: \"inside\",\n focusPoint: point\n };\n } else {\n current = {\n element: hit,\n mode: \"orbit\",\n focusPoint: isNested ? point : point\n };\n }\n\n return {\n current,\n other: isMultiPoint ? {\n mode: undefined\n } : other\n };\n }\n } // The opposite binding is on a different element or no binding\n else {\n current = {\n element: hit,\n mode: \"orbit\",\n focusPoint: point\n };\n } // Must return as only one endpoint is dragged, therefore\n // the end binding strategy might accidentally gets overriden\n\n\n return {\n current,\n other: isMultiPoint ? {\n mode: undefined\n } : other\n };\n};\n\nconst getBindingStrategyForDraggingBindingElementEndpoints = (arrow, draggingPoints, elementsMap, elements, appState, opts) => {\n if ((0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.getFeatureFlag)(\"COMPLEX_BINDINGS\")) {\n return getBindingStrategyForDraggingBindingElementEndpoints_complex(arrow, draggingPoints, elementsMap, elements, appState, opts);\n }\n\n return getBindingStrategyForDraggingBindingElementEndpoints_simple(arrow, draggingPoints, elementsMap, elements, appState, opts);\n};\n\nconst getBindingStrategyForDraggingBindingElementEndpoints_simple = (arrow, draggingPoints, elementsMap, elements, appState, opts) => {\n var _a, _b, _c;\n\n const startIdx = 0;\n const endIdx = arrow.points.length - 1;\n const startDragged = draggingPoints.has(startIdx);\n const endDragged = draggingPoints.has(endIdx);\n let start = {\n mode: undefined\n };\n let end = {\n mode: undefined\n };\n (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.invariant)(arrow.points.length > 1, \"Do not attempt to bind linear elements with a single point\"); // If none of the ends are dragged, we don't change anything\n\n if (!startDragged && !endDragged) {\n return {\n start,\n end\n };\n } // If both ends are dragged, we don't bind to anything\n // and break existing bindings\n\n\n if (startDragged && endDragged) {\n return {\n start: {\n mode: null\n },\n end: {\n mode: null\n }\n };\n } // If binding is disabled and an endpoint is dragged,\n // we actively break the end binding\n\n\n if (!isBindingEnabled(appState)) {\n start = startDragged ? {\n mode: null\n } : start;\n end = endDragged ? {\n mode: null\n } : end;\n return {\n start,\n end\n };\n } // Handle simpler elbow arrow binding\n\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isElbowArrow)(arrow)) {\n return bindingStrategyForElbowArrowEndpointDragging(arrow, draggingPoints, elementsMap, elements, opts === null || opts === void 0 ? void 0 : opts.zoom);\n }\n\n const otherBinding = startDragged ? arrow.endBinding : arrow.startBinding;\n const localPoint = (_a = draggingPoints.get(startDragged ? startIdx : endIdx)) === null || _a === void 0 ? void 0 : _a.point;\n (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.invariant)(localPoint, `Local point must be defined for ${startDragged ? \"start\" : \"end\"} dragging`);\n const globalPoint = _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointGlobalCoordinates(arrow, localPoint, elementsMap);\n const hit = (0,_collision__WEBPACK_IMPORTED_MODULE_3__.getHoveredElementForBinding)(globalPoint, elements, elementsMap, e => maxBindingDistance_simple(appState.zoom));\n const pointInElement = hit && (0,_collision__WEBPACK_IMPORTED_MODULE_3__.isPointInElement)(globalPoint, hit, elementsMap);\n const otherBindableElement = otherBinding ? elementsMap.get(otherBinding.elementId) : undefined;\n const otherFocusPoint = otherBinding && otherBindableElement && getGlobalFixedPointForBindableElement(otherBinding.fixedPoint, otherBindableElement, elementsMap);\n const otherFocusPointIsInElement = otherBindableElement && otherFocusPoint && (0,_collision__WEBPACK_IMPORTED_MODULE_3__.isPointInElement)(otherFocusPoint, otherBindableElement, elementsMap); // Handle outside-outside binding to the same element\n\n if (otherBinding && otherBinding.elementId === (hit === null || hit === void 0 ? void 0 : hit.id)) {\n (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.invariant)(!(opts === null || opts === void 0 ? void 0 : opts.newArrow) || ((_b = appState.selectedLinearElement) === null || _b === void 0 ? void 0 : _b.initialState.origin), \"appState.selectedLinearElement.initialState.origin must be defined for new arrows\");\n return {\n start: {\n mode: \"inside\",\n element: hit,\n focusPoint: startDragged ? globalPoint : // NOTE: Can only affect the start point because new arrows always drag the end point\n (opts === null || opts === void 0 ? void 0 : opts.newArrow) ? appState.selectedLinearElement.initialState.origin : _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointAtIndexGlobalCoordinates(arrow, 0, elementsMap) // startFixedPoint,\n\n },\n end: {\n mode: \"inside\",\n element: hit,\n focusPoint: endDragged ? globalPoint : _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointAtIndexGlobalCoordinates(arrow, -1, elementsMap) // endFixedPoint\n\n }\n };\n } // Handle special alt key case to inside bind no matter what\n\n\n if (opts === null || opts === void 0 ? void 0 : opts.altKey) {\n return {\n start: startDragged ? hit ? {\n mode: \"inside\",\n element: hit,\n focusPoint: globalPoint\n } : {\n mode: null\n } : start,\n end: endDragged ? hit ? {\n mode: \"inside\",\n element: hit,\n focusPoint: globalPoint\n } : {\n mode: null\n } : end\n };\n } // Handle normal cases\n\n\n const current = hit ? pointInElement ? {\n mode: \"inside\",\n element: hit,\n focusPoint: globalPoint\n } : {\n mode: \"orbit\",\n element: hit,\n focusPoint: (0,_utils__WEBPACK_IMPORTED_MODULE_11__.projectFixedPointOntoDiagonal)(arrow, globalPoint, hit, startDragged ? \"start\" : \"end\", elementsMap) || globalPoint\n } : {\n mode: null\n };\n const other = otherBindableElement && !otherFocusPointIsInElement && ((_c = appState.selectedLinearElement) === null || _c === void 0 ? void 0 : _c.initialState.altFocusPoint) ? {\n mode: \"orbit\",\n element: otherBindableElement,\n focusPoint: appState.selectedLinearElement.initialState.altFocusPoint\n } : {\n mode: undefined\n };\n return {\n start: startDragged ? current : other,\n end: endDragged ? current : other\n };\n};\n\nconst getBindingStrategyForDraggingBindingElementEndpoints_complex = (arrow, draggingPoints, elementsMap, elements, appState, opts) => {\n var _a, _b;\n\n const globalBindMode = appState.bindMode || \"orbit\";\n const startIdx = 0;\n const endIdx = arrow.points.length - 1;\n const startDragged = draggingPoints.has(startIdx);\n const endDragged = draggingPoints.has(endIdx);\n let start = {\n mode: undefined\n };\n let end = {\n mode: undefined\n };\n (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.invariant)(arrow.points.length > 1, \"Do not attempt to bind linear elements with a single point\"); // If none of the ends are dragged, we don't change anything\n\n if (!startDragged && !endDragged) {\n return {\n start,\n end\n };\n } // If both ends are dragged, we don't bind to anything\n // and break existing bindings\n\n\n if (startDragged && endDragged) {\n return {\n start: {\n mode: null\n },\n end: {\n mode: null\n }\n };\n } // If binding is disabled and an endpoint is dragged,\n // we actively break the end binding\n\n\n if (!isBindingEnabled(appState)) {\n start = startDragged ? {\n mode: null\n } : start;\n end = endDragged ? {\n mode: null\n } : end;\n return {\n start,\n end\n };\n } // Handle simpler elbow arrow binding\n\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isElbowArrow)(arrow)) {\n return bindingStrategyForElbowArrowEndpointDragging(arrow, draggingPoints, elementsMap, elements);\n } // Handle new arrow creation separately, as it is special\n\n\n if (opts === null || opts === void 0 ? void 0 : opts.newArrow) {\n const {\n start,\n end\n } = bindingStrategyForNewSimpleArrowEndpointDragging(arrow, draggingPoints, elementsMap, elements, startDragged, endDragged, startIdx, endIdx, appState, globalBindMode, opts === null || opts === void 0 ? void 0 : opts.shiftKey);\n return {\n start,\n end\n };\n } // Only the start point is dragged\n\n\n if (startDragged) {\n const localPoint = (_a = draggingPoints.get(startIdx)) === null || _a === void 0 ? void 0 : _a.point;\n (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.invariant)(localPoint, \"Local point must be defined for start dragging\");\n const globalPoint = _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointGlobalCoordinates(arrow, localPoint, elementsMap);\n const {\n current,\n other\n } = bindingStrategyForSimpleArrowEndpointDragging_complex(globalPoint, arrow.startBinding, arrow.endBinding, elementsMap, elements, globalBindMode, arrow, opts === null || opts === void 0 ? void 0 : opts.finalize);\n return {\n start: current,\n end: other\n };\n } // Only the end point is dragged\n\n\n if (endDragged) {\n const localPoint = (_b = draggingPoints.get(endIdx)) === null || _b === void 0 ? void 0 : _b.point;\n (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.invariant)(localPoint, \"Local point must be defined for end dragging\");\n const globalPoint = _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointGlobalCoordinates(arrow, localPoint, elementsMap);\n const {\n current,\n other\n } = bindingStrategyForSimpleArrowEndpointDragging_complex(globalPoint, arrow.endBinding, arrow.startBinding, elementsMap, elements, globalBindMode, arrow, opts === null || opts === void 0 ? void 0 : opts.finalize);\n return {\n start: other,\n end: current\n };\n }\n\n return {\n start,\n end\n };\n};\n\nconst bindOrUnbindBindingElements = (selectedArrows, scene, appState) => {\n selectedArrows.forEach(arrow => {\n bindOrUnbindBindingElement(arrow, new Map(), // No dragging points in this case\n scene, appState);\n });\n};\nconst bindBindingElement = (arrow, hoveredElement, mode, startOrEnd, scene, focusPoint) => {\n const elementsMap = scene.getNonDeletedElementsMap();\n let binding;\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isElbowArrow)(arrow)) {\n binding = Object.assign({\n elementId: hoveredElement.id,\n mode: \"orbit\"\n }, calculateFixedPointForElbowArrowBinding(arrow, hoveredElement, startOrEnd, elementsMap));\n } else {\n binding = Object.assign({\n elementId: hoveredElement.id,\n mode\n }, calculateFixedPointForNonElbowArrowBinding(arrow, hoveredElement, startOrEnd, elementsMap, focusPoint));\n }\n\n scene.mutateElement(arrow, {\n [startOrEnd === \"start\" ? \"startBinding\" : \"endBinding\"]: binding\n });\n const boundElementsMap = (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.arrayToMap)(hoveredElement.boundElements || []);\n\n if (!boundElementsMap.has(arrow.id)) {\n scene.mutateElement(hoveredElement, {\n boundElements: (hoveredElement.boundElements || []).concat({\n id: arrow.id,\n type: \"arrow\"\n })\n });\n }\n};\nconst unbindBindingElement = (arrow, startOrEnd, scene) => {\n var _a;\n\n const field = startOrEnd === \"start\" ? \"startBinding\" : \"endBinding\";\n const binding = arrow[field];\n\n if (binding == null) {\n return null;\n }\n\n const oppositeBinding = arrow[startOrEnd === \"start\" ? \"endBinding\" : \"startBinding\"];\n\n if (!oppositeBinding || oppositeBinding.elementId !== binding.elementId) {\n // Only remove the record on the bound element if the other\n // end is not bound to the same element\n const boundElement = scene.getNonDeletedElementsMap().get(binding.elementId);\n scene.mutateElement(boundElement, {\n boundElements: (_a = boundElement.boundElements) === null || _a === void 0 ? void 0 : _a.filter(element => element.id !== arrow.id)\n });\n }\n\n scene.mutateElement(arrow, {\n [field]: null\n });\n return binding.elementId;\n}; // Supports translating, rotating and scaling `changedElement` with bound\n// linear elements.\n\nconst updateBoundElements = (changedElement, scene, options) => {\n if (!(0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isBindableElement)(changedElement)) {\n return;\n }\n\n const {\n simultaneouslyUpdated\n } = options !== null && options !== void 0 ? options : {};\n const simultaneouslyUpdatedElementIds = getSimultaneouslyUpdatedElementIds(simultaneouslyUpdated);\n let elementsMap = scene.getNonDeletedElementsMap();\n\n if (options === null || options === void 0 ? void 0 : options.changedElements) {\n elementsMap = new Map(elementsMap);\n options.changedElements.forEach(element => {\n elementsMap.set(element.id, element);\n });\n }\n\n boundElementsVisitor(elementsMap, changedElement, element => {\n if (!(0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isArrowElement)(element) || element.isDeleted) {\n return;\n } // In case the boundElements are stale\n\n\n if (!doesNeedUpdate(element, changedElement)) {\n return;\n } // Check for intersections before updating bound elements incase connected elements overlap\n\n\n const startBindingElement = element.startBinding ? elementsMap.get(element.startBinding.elementId) : null;\n const endBindingElement = element.endBinding ? // PERF: If the arrow is bound to the same element on both ends.\n (startBindingElement === null || startBindingElement === void 0 ? void 0 : startBindingElement.id) === element.endBinding.elementId ? startBindingElement : elementsMap.get(element.endBinding.elementId) : null; // `linearElement` is being moved/scaled already, just update the binding\n\n if (simultaneouslyUpdatedElementIds.has(element.id)) {\n return;\n }\n\n const updates = bindableElementsVisitor(elementsMap, element, (bindableElement, bindingProp) => {\n var _a, _b;\n\n if (bindableElement && (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isBindableElement)(bindableElement) && (bindingProp === \"startBinding\" || bindingProp === \"endBinding\") && (changedElement.id === ((_a = element[bindingProp]) === null || _a === void 0 ? void 0 : _a.elementId) || changedElement.id === ((_b = element[bindingProp === \"startBinding\" ? \"endBinding\" : \"startBinding\"]) === null || _b === void 0 ? void 0 : _b.elementId))) {\n const point = updateBoundPoint(element, bindingProp, element[bindingProp], bindableElement, elementsMap);\n\n if (point) {\n return [bindingProp === \"startBinding\" ? 0 : element.points.length - 1, {\n point\n }];\n }\n }\n\n return null;\n }).filter(update => update !== null);\n _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.movePoints(element, scene, new Map(updates), {\n moveMidPointsWithElement: !!startBindingElement && (startBindingElement === null || startBindingElement === void 0 ? void 0 : startBindingElement.id) === (endBindingElement === null || endBindingElement === void 0 ? void 0 : endBindingElement.id)\n });\n const boundText = (0,_textElement__WEBPACK_IMPORTED_MODULE_8__.getBoundTextElement)(element, elementsMap);\n\n if (boundText && !boundText.isDeleted) {\n (0,_textElement__WEBPACK_IMPORTED_MODULE_8__.handleBindTextResize)(element, scene, false);\n }\n });\n};\nconst updateBindings = (latestElement, scene, appState, options) => {\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isArrowElement)(latestElement)) {\n bindOrUnbindBindingElement(latestElement, new Map(), scene, appState);\n } else {\n updateBoundElements(latestElement, scene, Object.assign(Object.assign({}, options), {\n changedElements: new Map([[latestElement.id, latestElement]])\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 getHeadingForElbowArrowSnap = (p, otherPoint, bindableElement, aabb, origPoint, elementsMap, zoom) => {\n const otherPointHeading = (0,_heading__WEBPACK_IMPORTED_MODULE_5__.vectorToHeading)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorFromPoint)(otherPoint, p));\n\n if (!bindableElement || !aabb) {\n return otherPointHeading;\n }\n\n const distance = getDistanceForBinding(origPoint, bindableElement, elementsMap, zoom);\n\n if (!distance) {\n return (0,_heading__WEBPACK_IMPORTED_MODULE_5__.vectorToHeading)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorFromPoint)(p, (0,_bounds__WEBPACK_IMPORTED_MODULE_2__.elementCenterPoint)(bindableElement, elementsMap)));\n }\n\n return (0,_heading__WEBPACK_IMPORTED_MODULE_5__.headingForPointFromElement)(bindableElement, aabb, p);\n};\n\nconst getDistanceForBinding = (point, bindableElement, elementsMap, zoom) => {\n const distance = (0,_distance__WEBPACK_IMPORTED_MODULE_4__.distanceToElement)(bindableElement, elementsMap, point);\n const bindDistance = maxBindingDistance_simple(zoom);\n return distance > bindDistance ? null : distance;\n};\n\nconst bindPointToSnapToElementOutline = (arrowElement, bindableElement, startOrEnd, elementsMap, customIntersector) => {\n const elbowed = (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isElbowArrow)(arrowElement);\n const point = _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointAtIndexGlobalCoordinates(arrowElement, startOrEnd === \"start\" ? 0 : -1, elementsMap);\n\n if (arrowElement.points.length < 2) {\n // New arrow creation, so no snapping\n return point;\n }\n\n const edgePoint = (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isRectanguloidElement)(bindableElement) && elbowed ? avoidRectangularCorner(arrowElement, bindableElement, elementsMap, point) : point;\n const adjacentPoint = customIntersector && !elbowed ? customIntersector[1] : _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointAtIndexGlobalCoordinates(arrowElement, startOrEnd === \"start\" ? 1 : -2, elementsMap);\n const bindingGap = getBindingGap(bindableElement, arrowElement);\n const aabb = (0,_bounds__WEBPACK_IMPORTED_MODULE_2__.aabbForElement)(bindableElement, elementsMap);\n const bindableCenter = (0,_bounds__WEBPACK_IMPORTED_MODULE_2__.getCenterForBounds)(aabb);\n let intersection = null;\n\n if (elbowed) {\n const isHorizontal = (0,_heading__WEBPACK_IMPORTED_MODULE_5__.headingIsHorizontal)((0,_heading__WEBPACK_IMPORTED_MODULE_5__.headingForPointFromElement)(bindableElement, aabb, point));\n const snapPoint = snapToMid(arrowElement, bindableElement, elementsMap, edgePoint);\n const otherPoint = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(isHorizontal ? bindableCenter[0] : snapPoint[0], !isHorizontal ? bindableCenter[1] : snapPoint[1]);\n const intersector = customIntersector !== null && customIntersector !== void 0 ? customIntersector : (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.lineSegment)(otherPoint, (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFromVector)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorScale)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorNormalize)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorFromPoint)(snapPoint, otherPoint)), Math.max(bindableElement.width, bindableElement.height) * 2), otherPoint));\n intersection = (0,_collision__WEBPACK_IMPORTED_MODULE_3__.intersectElementWithLineSegment)(bindableElement, elementsMap, intersector, bindingGap).sort(_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistanceSq)[0];\n\n if (!intersection) {\n const anotherPoint = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(!isHorizontal ? bindableCenter[0] : snapPoint[0], isHorizontal ? bindableCenter[1] : snapPoint[1]);\n const anotherIntersector = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.lineSegment)(anotherPoint, (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFromVector)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorScale)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorNormalize)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorFromPoint)(snapPoint, anotherPoint)), Math.max(bindableElement.width, bindableElement.height) * 2), anotherPoint));\n intersection = (0,_collision__WEBPACK_IMPORTED_MODULE_3__.intersectElementWithLineSegment)(bindableElement, elementsMap, anotherIntersector, BASE_BINDING_GAP_ELBOW).sort(_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistanceSq)[0];\n }\n } else {\n let intersector = customIntersector;\n\n if (!intersector) {\n const halfVector = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorScale)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorNormalize)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorFromPoint)(edgePoint, adjacentPoint)), (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistance)(edgePoint, adjacentPoint) + Math.max(bindableElement.width, bindableElement.height) + bindingGap * 2);\n intersector = customIntersector !== null && customIntersector !== void 0 ? customIntersector : (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.lineSegment)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFromVector)(halfVector, adjacentPoint), (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFromVector)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorScale)(halfVector, -1), adjacentPoint));\n }\n\n intersection = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistance)(edgePoint, adjacentPoint) < 1 ? edgePoint : (0,_collision__WEBPACK_IMPORTED_MODULE_3__.intersectElementWithLineSegment)(bindableElement, elementsMap, intersector, bindingGap).sort((g, h) => (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistanceSq)(g, adjacentPoint) - (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistanceSq)(h, adjacentPoint))[0];\n }\n\n if (!intersection || // Too close to determine vector from intersection to edgePoint\n (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistanceSq)(edgePoint, intersection) < _excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.PRECISION) {\n return edgePoint;\n }\n\n return intersection;\n};\nconst avoidRectangularCorner = (arrowElement, bindTarget, elementsMap, p) => {\n const center = (0,_bounds__WEBPACK_IMPORTED_MODULE_2__.elementCenterPoint)(bindTarget, elementsMap);\n const nonRotatedPoint = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)(p, center, -bindTarget.angle);\n const bindingGap = getBindingGap(bindTarget, arrowElement);\n\n if (nonRotatedPoint[0] < bindTarget.x && nonRotatedPoint[1] < bindTarget.y) {\n // Top left\n if (nonRotatedPoint[1] - bindTarget.y > -bindingGap) {\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(bindTarget.x - bindingGap, bindTarget.y), center, bindTarget.angle);\n }\n\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(bindTarget.x, bindTarget.y - bindingGap), center, bindTarget.angle);\n } else if (nonRotatedPoint[0] < bindTarget.x && nonRotatedPoint[1] > bindTarget.y + bindTarget.height) {\n // Bottom left\n if (nonRotatedPoint[0] - bindTarget.x > -bindingGap) {\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(bindTarget.x, bindTarget.y + bindTarget.height + bindingGap), center, bindTarget.angle);\n }\n\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(bindTarget.x - bindingGap, bindTarget.y + bindTarget.height), center, bindTarget.angle);\n } else if (nonRotatedPoint[0] > bindTarget.x + bindTarget.width && nonRotatedPoint[1] > bindTarget.y + bindTarget.height) {\n // Bottom right\n if (nonRotatedPoint[0] - bindTarget.x < bindTarget.width + bindingGap) {\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(bindTarget.x + bindTarget.width, bindTarget.y + bindTarget.height + bindingGap), center, bindTarget.angle);\n }\n\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(bindTarget.x + bindTarget.width + bindingGap, bindTarget.y + bindTarget.height), center, bindTarget.angle);\n } else if (nonRotatedPoint[0] > bindTarget.x + bindTarget.width && nonRotatedPoint[1] < bindTarget.y) {\n // Top right\n if (nonRotatedPoint[0] - bindTarget.x < bindTarget.width + bindingGap) {\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(bindTarget.x + bindTarget.width, bindTarget.y - bindingGap), center, bindTarget.angle);\n }\n\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(bindTarget.x + bindTarget.width + bindingGap, bindTarget.y), center, bindTarget.angle);\n }\n\n return p;\n};\n\nconst snapToMid = (arrowElement, bindTarget, elementsMap, p, tolerance = 0.05) => {\n const {\n x,\n y,\n width,\n height,\n angle\n } = bindTarget;\n const center = (0,_bounds__WEBPACK_IMPORTED_MODULE_2__.elementCenterPoint)(bindTarget, elementsMap, -0.1, -0.1);\n const nonRotated = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)(p, center, -angle);\n const bindingGap = getBindingGap(bindTarget, arrowElement); // snap-to-center point is adaptive to element size, but we don't want to go\n // above and below certain px distance\n\n const verticalThreshold = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.clamp)(tolerance * height, 5, 80);\n const horizontalThreshold = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.clamp)(tolerance * width, 5, 80); // Too close to the center makes it hard to resolve direction precisely\n\n if ((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistance)(center, nonRotated) < bindingGap) {\n return p;\n }\n\n if (nonRotated[0] <= x + width / 2 && nonRotated[1] > center[1] - verticalThreshold && nonRotated[1] < center[1] + verticalThreshold) {\n // LEFT\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(x - bindingGap, center[1]), center, angle);\n } else if (nonRotated[1] <= y + height / 2 && nonRotated[0] > center[0] - horizontalThreshold && nonRotated[0] < center[0] + horizontalThreshold) {\n // TOP\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(center[0], y - bindingGap), center, angle);\n } else if (nonRotated[0] >= x + width / 2 && nonRotated[1] > center[1] - verticalThreshold && nonRotated[1] < center[1] + verticalThreshold) {\n // RIGHT\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(x + width + bindingGap, center[1]), center, angle);\n } else if (nonRotated[1] >= y + height / 2 && nonRotated[0] > center[0] - horizontalThreshold && nonRotated[0] < center[0] + horizontalThreshold) {\n // DOWN\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(center[0], y + height + bindingGap), center, angle);\n } else if (bindTarget.type === \"diamond\") {\n const distance = bindingGap;\n const topLeft = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(x + width / 4 - distance, y + height / 4 - distance);\n const topRight = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(x + 3 * width / 4 + distance, y + height / 4 - distance);\n const bottomLeft = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(x + width / 4 - distance, y + 3 * height / 4 + distance);\n const bottomRight = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(x + 3 * width / 4 + distance, y + 3 * height / 4 + distance);\n\n if ((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistance)(topLeft, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)(topLeft, center, angle);\n }\n\n if ((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistance)(topRight, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)(topRight, center, angle);\n }\n\n if ((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistance)(bottomLeft, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)(bottomLeft, center, angle);\n }\n\n if ((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistance)(bottomRight, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)(bottomRight, center, angle);\n }\n }\n\n return p;\n};\n\nconst compareElementArea = (a, b) => b.width ** 2 + b.height ** 2 - (a.width ** 2 + a.height ** 2);\n\nconst updateBoundPoint = (arrow, startOrEnd, binding, bindableElement, elementsMap, customIntersector) => {\n if (binding == null || // We only need to update the other end if this is a 2 point line element\n binding.elementId !== bindableElement.id && arrow.points.length > 2) {\n return null;\n }\n\n const global = getGlobalFixedPointForBindableElement(normalizeFixedPoint(binding.fixedPoint), bindableElement, elementsMap);\n const pointIndex = startOrEnd === \"startBinding\" ? 0 : arrow.points.length - 1;\n const elbowed = (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isElbowArrow)(arrow);\n const otherBinding = startOrEnd === \"startBinding\" ? arrow.endBinding : arrow.startBinding;\n const otherBindableElement = otherBinding && elementsMap.get(otherBinding.elementId);\n const bounds = (0,_bounds__WEBPACK_IMPORTED_MODULE_2__.getElementBounds)(bindableElement, elementsMap);\n const otherBounds = otherBindableElement && (0,_bounds__WEBPACK_IMPORTED_MODULE_2__.getElementBounds)(otherBindableElement, elementsMap);\n const isLargerThanOther = otherBindableElement && compareElementArea(bindableElement, otherBindableElement) < ( // if both shapes the same size, pretend the other is larger\n startOrEnd === \"endBinding\" ? 1 : 0);\n const isOverlapping = otherBounds && (0,_bounds__WEBPACK_IMPORTED_MODULE_2__.doBoundsIntersect)(bounds, otherBounds); // GOAL: If the arrow becomes too short, we want to jump the arrow endpoints\n // to the exact focus points on the elements.\n // INTUITION: We're not interested in the exacts length of the arrow (which\n // will change if we change where we route it), we want to know the length of\n // the part which lies outside of both shapes and consider that as a trigger\n // to change where we point the arrow. Avoids jumping the arrow in and out\n // at every frame.\n\n let arrowTooShort = false;\n\n if (!isOverlapping && !elbowed && arrow.startBinding && arrow.endBinding && otherBindableElement && arrow.points.length === 2) {\n const startFocusPoint = getGlobalFixedPointForBindableElement(arrow.startBinding.fixedPoint, startOrEnd === \"startBinding\" ? bindableElement : otherBindableElement, elementsMap);\n const endFocusPoint = getGlobalFixedPointForBindableElement(arrow.endBinding.fixedPoint, startOrEnd === \"endBinding\" ? bindableElement : otherBindableElement, elementsMap);\n const segment = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.lineSegment)(startFocusPoint, endFocusPoint);\n const startIntersection = (0,_collision__WEBPACK_IMPORTED_MODULE_3__.intersectElementWithLineSegment)(startOrEnd === \"endBinding\" ? bindableElement : otherBindableElement, elementsMap, segment, 0, true);\n const endIntersection = (0,_collision__WEBPACK_IMPORTED_MODULE_3__.intersectElementWithLineSegment)(startOrEnd === \"startBinding\" ? bindableElement : otherBindableElement, elementsMap, segment, 0, true);\n\n if (startIntersection.length > 0 && endIntersection.length > 0) {\n const len = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistance)(startIntersection[0], endIntersection[0]);\n arrowTooShort = len < 40;\n }\n }\n\n const isNested = (arrowTooShort || isOverlapping) && isLargerThanOther;\n let _customIntersector = customIntersector;\n\n if (!elbowed && !_customIntersector) {\n const [x1, y1, x2, y2] = _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getElementAbsoluteCoords(arrow, elementsMap);\n const center = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)((x1 + x2) / 2, (y1 + y2) / 2);\n const edgePoint = (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isRectanguloidElement)(bindableElement) ? avoidRectangularCorner(arrow, bindableElement, elementsMap, global) : global;\n const adjacentPoint = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(arrow.x + arrow.points[pointIndex === 0 ? 1 : arrow.points.length - 2][0], arrow.y + arrow.points[pointIndex === 0 ? 1 : arrow.points.length - 2][1]), center, arrow.angle);\n const bindingGap = getBindingGap(bindableElement, arrow);\n const halfVector = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorScale)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorNormalize)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorFromPoint)(edgePoint, adjacentPoint)), (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointDistance)(edgePoint, adjacentPoint) + Math.max(bindableElement.width, bindableElement.height) + bindingGap * 2);\n _customIntersector = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.lineSegment)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFromVector)(halfVector, adjacentPoint), (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFromVector)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.vectorScale)(halfVector, -1), adjacentPoint));\n }\n\n const maybeOutlineGlobal = binding.mode === \"orbit\" && bindableElement ? isNested ? global : bindPointToSnapToElementOutline(Object.assign(Object.assign({}, arrow), {\n points: [pointIndex === 0 ? _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.createPointAt(arrow, elementsMap, global[0], global[1], null) : arrow.points[0], ...arrow.points.slice(1, -1), pointIndex === arrow.points.length - 1 ? _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.createPointAt(arrow, elementsMap, global[0], global[1], null) : arrow.points[arrow.points.length - 1]]\n }), bindableElement, pointIndex === 0 ? \"start\" : \"end\", elementsMap, _customIntersector) : global;\n return _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.createPointAt(arrow, elementsMap, maybeOutlineGlobal[0], maybeOutlineGlobal[1], null);\n};\nconst calculateFixedPointForElbowArrowBinding = (linearElement, hoveredElement, startOrEnd, elementsMap) => {\n const bounds = [hoveredElement.x, hoveredElement.y, hoveredElement.x + hoveredElement.width, hoveredElement.y + hoveredElement.height];\n const snappedPoint = bindPointToSnapToElementOutline(linearElement, hoveredElement, startOrEnd, elementsMap);\n const globalMidPoint = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(bounds[0] + (bounds[2] - bounds[0]) / 2, bounds[1] + (bounds[3] - bounds[1]) / 2);\n const nonRotatedSnappedGlobalPoint = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)(snappedPoint, globalMidPoint, -hoveredElement.angle);\n return {\n fixedPoint: normalizeFixedPoint([(nonRotatedSnappedGlobalPoint[0] - hoveredElement.x) / hoveredElement.width, (nonRotatedSnappedGlobalPoint[1] - hoveredElement.y) / hoveredElement.height])\n };\n};\nconst calculateFixedPointForNonElbowArrowBinding = (linearElement, hoveredElement, startOrEnd, elementsMap, focusPoint) => {\n const edgePoint = focusPoint ? focusPoint : _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getPointAtIndexGlobalCoordinates(linearElement, startOrEnd === \"start\" ? 0 : -1, elementsMap); // Convert the global point to element-local coordinates\n\n const elementCenter = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(hoveredElement.x + hoveredElement.width / 2, hoveredElement.y + hoveredElement.height / 2); // Rotate the point to account for element rotation\n\n const nonRotatedPoint = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)(edgePoint, elementCenter, -hoveredElement.angle); // Calculate the ratio relative to the element's bounds\n\n const fixedPointX = (nonRotatedPoint[0] - hoveredElement.x) / hoveredElement.width;\n const fixedPointY = (nonRotatedPoint[1] - hoveredElement.y) / hoveredElement.height;\n return {\n fixedPoint: normalizeFixedPoint([fixedPointX, fixedPointY])\n };\n};\nconst fixDuplicatedBindingsAfterDuplication = (duplicatedElements, origIdToDuplicateId, duplicateElementsMap) => {\n var _a;\n\n for (const duplicateElement of duplicatedElements) {\n if (\"boundElements\" in duplicateElement && duplicateElement.boundElements) {\n Object.assign(duplicateElement, {\n boundElements: duplicateElement.boundElements.reduce((acc, binding) => {\n const newBindingId = origIdToDuplicateId.get(binding.id);\n\n if (newBindingId) {\n acc.push(Object.assign(Object.assign({}, binding), {\n id: newBindingId\n }));\n }\n\n return acc;\n }, [])\n });\n }\n\n if (\"containerId\" in duplicateElement && duplicateElement.containerId) {\n Object.assign(duplicateElement, {\n containerId: (_a = origIdToDuplicateId.get(duplicateElement.containerId)) !== null && _a !== void 0 ? _a : null\n });\n }\n\n if (\"endBinding\" in duplicateElement && duplicateElement.endBinding) {\n const newEndBindingId = origIdToDuplicateId.get(duplicateElement.endBinding.elementId);\n Object.assign(duplicateElement, {\n endBinding: newEndBindingId ? Object.assign(Object.assign({}, duplicateElement.endBinding), {\n elementId: newEndBindingId\n }) : null\n });\n }\n\n if (\"startBinding\" in duplicateElement && duplicateElement.startBinding) {\n const newEndBindingId = origIdToDuplicateId.get(duplicateElement.startBinding.elementId);\n Object.assign(duplicateElement, {\n startBinding: newEndBindingId ? Object.assign(Object.assign({}, duplicateElement.startBinding), {\n elementId: newEndBindingId\n }) : null\n });\n }\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isElbowArrow)(duplicateElement)) {\n Object.assign(duplicateElement, (0,_elbowArrow__WEBPACK_IMPORTED_MODULE_10__.updateElbowArrowPoints)(duplicateElement, duplicateElementsMap, {\n points: [duplicateElement.points[0], duplicateElement.points[duplicateElement.points.length - 1]]\n }));\n }\n }\n};\nconst fixBindingsAfterDeletion = (sceneElements, deletedElements) => {\n const elements = (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.arrayToMap)(sceneElements);\n\n for (const element of deletedElements) {\n BoundElement.unbindAffected(elements, element, (element, updates) => (0,_mutateElement__WEBPACK_IMPORTED_MODULE_7__.mutateElement)(element, elements, updates));\n BindableElement.unbindAffected(elements, element, (element, updates) => (0,_mutateElement__WEBPACK_IMPORTED_MODULE_7__.mutateElement)(element, elements, updates));\n }\n};\n\nconst newBoundElements = (boundElements, idsToRemove, elementsToAdd = []) => {\n if (!boundElements) {\n return null;\n }\n\n const nextBoundElements = boundElements.filter(boundElement => !idsToRemove.has(boundElement.id));\n nextBoundElements.push(...elementsToAdd.map(x => ({\n id: x.id,\n type: x.type\n })));\n return nextBoundElements;\n};\n\nconst bindingProperties = new Set([\"boundElements\", \"frameId\", \"containerId\", \"startBinding\", \"endBinding\"]);\n/**\r\n * Tries to visit each bound element (does not have to be found).\r\n */\n\nconst boundElementsVisitor = (elements, element, visit) => {\n var _a, _b;\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isBindableElement)(element)) {\n // create new instance so that possible mutations won't play a role in visiting order\n const boundElements = (_b = (_a = element.boundElements) === null || _a === void 0 ? void 0 : _a.slice()) !== null && _b !== void 0 ? _b : []; // last added text should be the one we keep (~previous are duplicates)\n\n boundElements.forEach(({\n id\n }) => {\n visit(elements.get(id), \"boundElements\", id);\n });\n }\n};\n/**\r\n * Tries to visit each bindable element (does not have to be found).\r\n */\n\n\nconst bindableElementsVisitor = (elements, element, visit) => {\n const result = [];\n\n if (element.frameId) {\n const id = element.frameId;\n result.push(visit(elements.get(id), \"frameId\", id));\n }\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isBoundToContainer)(element)) {\n const id = element.containerId;\n result.push(visit(elements.get(id), \"containerId\", id));\n }\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isArrowElement)(element)) {\n if (element.startBinding) {\n const id = element.startBinding.elementId;\n result.push(visit(elements.get(id), \"startBinding\", id));\n }\n\n if (element.endBinding) {\n const id = element.endBinding.elementId;\n result.push(visit(elements.get(id), \"endBinding\", id));\n }\n }\n\n return result;\n};\n/**\r\n * Bound element containing bindings to `frameId`, `containerId`, `startBinding` or `endBinding`.\r\n */\n\n\nclass BoundElement {\n /**\r\n * Unbind the affected non deleted bindable elements (removing element from `boundElements`).\r\n * - iterates non deleted bindable elements (`containerId` | `startBinding.elementId` | `endBinding.elementId`) of the current element\r\n * - prepares updates to unbind each bindable element's `boundElements` from the current element\r\n */\n static unbindAffected(elements, boundElement, updateElementWith) {\n if (!boundElement) {\n return;\n }\n\n bindableElementsVisitor(elements, boundElement, bindableElement => {\n // bindable element is deleted, this is fine\n if (!bindableElement || bindableElement.isDeleted) {\n return;\n }\n\n boundElementsVisitor(elements, bindableElement, (_, __, boundElementId) => {\n if (boundElementId === boundElement.id) {\n updateElementWith(bindableElement, {\n boundElements: newBoundElements(bindableElement.boundElements, new Set([boundElementId]))\n });\n }\n });\n });\n }\n\n}\n/**\r\n * Rebind the next affected non deleted bindable elements (adding element to `boundElements`).\r\n * - iterates non deleted bindable elements (`containerId` | `startBinding.elementId` | `endBinding.elementId`) of the current element\r\n * - prepares updates to rebind each bindable element's `boundElements` to the current element\r\n *\r\n * NOTE: rebind expects that affected elements were previously unbound with `BoundElement.unbindAffected`\r\n */\n\nBoundElement.rebindAffected = (elements, boundElement, updateElementWith) => {\n // don't try to rebind element that is deleted\n if (!boundElement || boundElement.isDeleted) {\n return;\n }\n\n bindableElementsVisitor(elements, boundElement, (bindableElement, bindingProp) => {\n var _a, _b; // unbind from bindable elements, as bindings from non deleted elements into deleted elements are incorrect\n\n\n if (!bindableElement || bindableElement.isDeleted) {\n updateElementWith(boundElement, {\n [bindingProp]: null\n });\n return;\n } // frame bindings are unidirectional, there is nothing to rebind\n\n\n if (bindingProp === \"frameId\") {\n return;\n }\n\n if ((_a = bindableElement.boundElements) === null || _a === void 0 ? void 0 : _a.find(x => x.id === boundElement.id)) {\n return;\n }\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isArrowElement)(boundElement)) {\n // rebind if not found!\n updateElementWith(bindableElement, {\n boundElements: newBoundElements(bindableElement.boundElements, new Set(), new Array(boundElement))\n });\n }\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(boundElement)) {\n if (!((_b = bindableElement.boundElements) === null || _b === void 0 ? void 0 : _b.find(x => x.type === \"text\"))) {\n // rebind only if there is no other text bound already\n updateElementWith(bindableElement, {\n boundElements: newBoundElements(bindableElement.boundElements, new Set(), new Array(boundElement))\n });\n } else {\n // unbind otherwise\n updateElementWith(boundElement, {\n [bindingProp]: null\n });\n }\n }\n });\n};\n/**\r\n * Bindable element containing bindings to `boundElements`.\r\n */\n\n\nclass BindableElement {\n /**\r\n * Unbind the affected non deleted bound elements (resetting `containerId`, `startBinding`, `endBinding` to `null`).\r\n * - iterates through non deleted `boundElements` of the current element\r\n * - prepares updates to unbind each bound element from the current element\r\n */\n static unbindAffected(elements, bindableElement, updateElementWith) {\n if (!bindableElement) {\n return;\n }\n\n boundElementsVisitor(elements, bindableElement, boundElement => {\n // bound element is deleted, this is fine\n if (!boundElement || boundElement.isDeleted) {\n return;\n }\n\n bindableElementsVisitor(elements, boundElement, (_, bindingProp, bindableElementId) => {\n // making sure there is an element to be unbound\n if (bindableElementId === bindableElement.id) {\n updateElementWith(boundElement, {\n [bindingProp]: null\n });\n }\n });\n });\n }\n\n}\n/**\r\n * Rebind the affected non deleted bound elements (for now setting only `containerId`, as we cannot rebind arrows atm).\r\n * - iterates through non deleted `boundElements` of the current element\r\n * - prepares updates to rebind each bound element to the current element or unbind it from `boundElements` in case of conflicts\r\n *\r\n * NOTE: rebind expects that affected elements were previously unbound with `BindaleElement.unbindAffected`\r\n */\n\nBindableElement.rebindAffected = (elements, bindableElement, updateElementWith) => {\n // don't try to rebind element that is deleted (i.e. updated as deleted)\n if (!bindableElement || bindableElement.isDeleted) {\n return;\n }\n\n boundElementsVisitor(elements, bindableElement, (boundElement, _, boundElementId) => {\n var _a, _b, _c; // unbind from bindable elements, as bindings from non deleted elements into deleted elements are incorrect\n\n\n if (!boundElement || boundElement.isDeleted) {\n updateElementWith(bindableElement, {\n boundElements: newBoundElements(bindableElement.boundElements, new Set([boundElementId]))\n });\n return;\n }\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(boundElement)) {\n const boundElements = (_b = (_a = bindableElement.boundElements) === null || _a === void 0 ? void 0 : _a.slice()) !== null && _b !== void 0 ? _b : []; // check if this is the last element in the array, if not, there is an previously bound text which should be unbound\n\n if (((_c = boundElements.reverse().find(x => x.type === \"text\")) === null || _c === void 0 ? void 0 : _c.id) === boundElement.id) {\n if (boundElement.containerId !== bindableElement.id) {\n // rebind if not bound already!\n updateElementWith(boundElement, {\n containerId: bindableElement.id\n });\n }\n } else {\n if (boundElement.containerId !== null) {\n // unbind if not unbound already\n updateElementWith(boundElement, {\n containerId: null\n });\n } // unbind from boundElements as the element got bound to some other element in the meantime\n\n\n updateElementWith(bindableElement, {\n boundElements: newBoundElements(bindableElement.boundElements, new Set([boundElement.id]))\n });\n }\n }\n });\n};\n\nconst getGlobalFixedPointForBindableElement = (fixedPointRatio, element, elementsMap) => {\n const [fixedX, fixedY] = normalizeFixedPoint(fixedPointRatio);\n return (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(element.x + element.width * fixedX, element.y + element.height * fixedY), (0,_bounds__WEBPACK_IMPORTED_MODULE_2__.elementCenterPoint)(element, elementsMap), element.angle);\n};\nconst getGlobalFixedPoints = (arrow, elementsMap) => {\n const startElement = arrow.startBinding && elementsMap.get(arrow.startBinding.elementId);\n const endElement = arrow.endBinding && elementsMap.get(arrow.endBinding.elementId);\n const startPoint = startElement && arrow.startBinding ? getGlobalFixedPointForBindableElement(arrow.startBinding.fixedPoint, startElement, elementsMap) : (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(arrow.x + arrow.points[0][0], arrow.y + arrow.points[0][1]);\n const endPoint = endElement && arrow.endBinding ? getGlobalFixedPointForBindableElement(arrow.endBinding.fixedPoint, endElement, elementsMap) : (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_1__.pointFrom)(arrow.x + arrow.points[arrow.points.length - 1][0], arrow.y + arrow.points[arrow.points.length - 1][1]);\n return [startPoint, endPoint];\n};\nconst getArrowLocalFixedPoints = (arrow, elementsMap) => {\n const [startPoint, endPoint] = getGlobalFixedPoints(arrow, elementsMap);\n return [_linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.pointFromAbsoluteCoords(arrow, startPoint, elementsMap), _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.pointFromAbsoluteCoords(arrow, endPoint, elementsMap)];\n};\nconst normalizeFixedPoint = fixedPoint => {\n // Do not allow a precise 0.5 for fixed point ratio\n // to avoid jumping arrow heading due to floating point imprecision\n if (fixedPoint && (Math.abs(fixedPoint[0] - 0.5) < 0.0001 || Math.abs(fixedPoint[1] - 0.5) < 0.0001)) {\n return fixedPoint.map(ratio => Math.abs(ratio - 0.5) < 0.0001 ? 0.5001 : ratio);\n }\n\n return fixedPoint;\n};\n\n//# sourceURL=webpack://ExcalidrawLib/../element/src/binding.ts?");
13139
13139
 
13140
13140
  /***/ }),
13141
13141
 
@@ -13421,7 +13421,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
13421
13421
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
13422
13422
 
13423
13423
  "use strict";
13424
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ DEFAULT_LINK_SIZE: () => (/* binding */ DEFAULT_LINK_SIZE),\n/* harmony export */ IMAGE_INVERT_FILTER: () => (/* binding */ IMAGE_INVERT_FILTER),\n/* harmony export */ elementWithCanvasCache: () => (/* binding */ elementWithCanvasCache),\n/* harmony export */ generateFreeDrawShape: () => (/* binding */ generateFreeDrawShape),\n/* harmony export */ getFreeDrawPath2D: () => (/* binding */ getFreeDrawPath2D),\n/* harmony export */ getFreeDrawSvgPath: () => (/* binding */ getFreeDrawSvgPath),\n/* harmony export */ getFreedrawOutlineAsSegments: () => (/* binding */ getFreedrawOutlineAsSegments),\n/* harmony export */ getFreedrawOutlinePoints: () => (/* binding */ getFreedrawOutlinePoints),\n/* harmony export */ getRenderOpacity: () => (/* binding */ getRenderOpacity),\n/* harmony export */ pathsCache: () => (/* binding */ pathsCache),\n/* harmony export */ renderElement: () => (/* binding */ renderElement),\n/* harmony export */ renderSelectionElement: () => (/* binding */ renderSelectionElement)\n/* harmony export */ });\n/* harmony import */ var roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! roughjs/bin/rough */ \"../../node_modules/roughjs/bin/rough.js\");\n/* harmony import */ var perfect_freehand__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! perfect-freehand */ \"../../node_modules/perfect-freehand/dist/esm/index.js\");\n/* harmony import */ var _excalidraw_math__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @excalidraw/math */ \"../math/src/index.ts\");\n/* harmony import */ var _excalidraw_common__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @excalidraw/common */ \"../common/src/index.ts\");\n/* harmony import */ var _bounds__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./bounds */ \"../element/src/bounds.ts\");\n/* harmony import */ var _cropElement__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./cropElement */ \"../element/src/cropElement.ts\");\n/* harmony import */ var _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./linearElementEditor */ \"../element/src/linearElementEditor.ts\");\n/* harmony import */ var _textElement__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./textElement */ \"../element/src/textElement.ts\");\n/* harmony import */ var _textMeasurements__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./textMeasurements */ \"../element/src/textMeasurements.ts\");\n/* harmony import */ var _typeChecks__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @excalidraw/element/typeChecks */ \"../element/src/typeChecks.ts\");\n/* harmony import */ var _frame__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./frame */ \"../element/src/frame.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./utils */ \"../element/src/utils.ts\");\n/* harmony import */ var _shape__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./shape */ \"../element/src/shape.ts\");\n/* harmony import */ var _easingFunctions__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./easingFunctions */ \"../element/src/easingFunctions.ts\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n // using a stronger invert (100% vs our regular 93%) and saturate\n// as a temp hack to make images in dark theme look closer to original\n// color scheme (it's still not quite there and the colors look slightly\n// desatured, alas...)\n\nconst IMAGE_INVERT_FILTER = \"invert(100%) hue-rotate(180deg) saturate(1.25)\";\n\nconst isPendingImageElement = (element, renderConfig) => (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isInitializedImageElement)(element) && !renderConfig.imageCache.has(element.fileId);\n\nconst shouldResetImageFilter = (element, renderConfig, appState) => {\n var _a;\n\n return appState.theme === _excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.THEME.DARK && (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isInitializedImageElement)(element) && !isPendingImageElement(element, renderConfig) && ((_a = renderConfig.imageCache.get(element.fileId)) === null || _a === void 0 ? void 0 : _a.mimeType) !== _excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.MIME_TYPES.svg;\n};\n\nconst getCanvasPadding = element => {\n switch (element.type) {\n case \"freedraw\":\n return element.strokeWidth * 12;\n\n case \"text\":\n return element.fontSize / 2;\n\n case \"arrow\":\n if (element.endArrowhead || element.endArrowhead) {\n return 40;\n }\n\n return 20;\n\n default:\n return 20;\n }\n};\n\nconst getRenderOpacity = (element, containingFrame, elementsPendingErasure, pendingNodes, globalAlpha = 1) => {\n var _a; // multiplying frame opacity with element opacity to combine them\n // (e.g. frame 50% and element 50% opacity should result in 25% opacity)\n\n\n let opacity = ((_a = containingFrame === null || containingFrame === void 0 ? void 0 : containingFrame.opacity) !== null && _a !== void 0 ? _a : 100) * element.opacity / 10000 * globalAlpha; // if pending erasure, multiply again to combine further\n // (so that erasing always results in lower opacity than original)\n\n if (elementsPendingErasure.has(element.id) || pendingNodes && pendingNodes.some(node => node.id === element.id) || containingFrame && elementsPendingErasure.has(containingFrame.id)) {\n opacity *= _excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.ELEMENT_READY_TO_ERASE_OPACITY / 100;\n }\n\n return opacity;\n};\n\nconst cappedElementCanvasSize = (element, elementsMap, zoom) => {\n // these limits are ballpark, they depend on specific browsers and device.\n // We've chosen lower limits to be safe. We might want to change these limits\n // based on browser/device type, if we get reports of low quality rendering\n // on zoom.\n //\n // ~ safari mobile canvas area limit\n const AREA_LIMIT = (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.getAreaLimit)(); //zsviczian\n // ~ safari width/height limit based on developer.mozilla.org.\n\n const WIDTH_HEIGHT_LIMIT = (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.getWidthHeightLimit)(); //zsviczian\n\n const padding = getCanvasPadding(element);\n const [x1, y1, x2, y2] = (0,_bounds__WEBPACK_IMPORTED_MODULE_4__.getElementAbsoluteCoords)(element, elementsMap);\n const elementWidth = (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isLinearElement)(element) || (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isFreeDrawElement)(element) ? (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.distance)(x1, x2) : element.width;\n const elementHeight = (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isLinearElement)(element) || (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isFreeDrawElement)(element) ? (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.distance)(y1, y2) : element.height;\n let width = elementWidth * window.devicePixelRatio + padding * 2;\n let height = elementHeight * window.devicePixelRatio + padding * 2;\n let scale = zoom.value; // rescale to ensure width and height is within limits\n\n if (width * scale > WIDTH_HEIGHT_LIMIT || height * scale > WIDTH_HEIGHT_LIMIT) {\n scale = Math.min(WIDTH_HEIGHT_LIMIT / width, WIDTH_HEIGHT_LIMIT / height);\n } // rescale to ensure canvas area is within limits\n\n\n if (width * height * scale * scale > AREA_LIMIT) {\n scale = Math.sqrt(AREA_LIMIT / (width * height));\n }\n\n width = Math.floor(width * scale);\n height = Math.floor(height * scale);\n return {\n width,\n height,\n scale\n };\n};\n\nconst generateElementCanvas = (element, elementsMap, zoom, renderConfig, appState) => {\n var _a, _b;\n\n const canvas = document.createElement(\"canvas\");\n const context = canvas.getContext(\"2d\");\n const padding = getCanvasPadding(element);\n const {\n width,\n height,\n scale\n } = cappedElementCanvasSize(element, elementsMap, zoom);\n\n if (!width || !height) {\n return null;\n }\n\n canvas.width = width;\n canvas.height = height;\n let canvasOffsetX = -100;\n let canvasOffsetY = 0;\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isLinearElement)(element) || (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isFreeDrawElement)(element)) {\n const [x1, y1] = (0,_bounds__WEBPACK_IMPORTED_MODULE_4__.getElementAbsoluteCoords)(element, elementsMap);\n canvasOffsetX = element.x > x1 ? (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.distance)(element.x, x1) * window.devicePixelRatio * scale : 0;\n canvasOffsetY = element.y > y1 ? (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.distance)(element.y, y1) * window.devicePixelRatio * scale : 0;\n context.translate(canvasOffsetX, canvasOffsetY);\n }\n\n context.save();\n context.translate(padding * scale, padding * scale);\n context.scale(window.devicePixelRatio * scale, window.devicePixelRatio * scale);\n const rc = roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_0__[\"default\"].canvas(canvas); // in dark theme, revert the image color filter\n\n if (shouldResetImageFilter(element, renderConfig, appState)) {\n context.filter = IMAGE_INVERT_FILTER;\n }\n\n drawElementOnCanvas(element, rc, context, renderConfig);\n context.restore();\n const boundTextElement = (0,_textElement__WEBPACK_IMPORTED_MODULE_7__.getBoundTextElement)(element, elementsMap);\n const boundTextCanvas = document.createElement(\"canvas\");\n const boundTextCanvasContext = boundTextCanvas.getContext(\"2d\");\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isArrowElement)(element) && boundTextElement) {\n const [x1, y1, x2, y2] = (0,_bounds__WEBPACK_IMPORTED_MODULE_4__.getElementAbsoluteCoords)(element, elementsMap); // Take max dimensions of arrow canvas so that when canvas is rotated\n // the arrow doesn't get clipped\n\n const maxDim = Math.max((0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.distance)(x1, x2), (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.distance)(y1, y2));\n boundTextCanvas.width = maxDim * window.devicePixelRatio * scale + padding * scale * 10;\n boundTextCanvas.height = maxDim * window.devicePixelRatio * scale + padding * scale * 10;\n boundTextCanvasContext.translate(boundTextCanvas.width / 2, boundTextCanvas.height / 2);\n boundTextCanvasContext.rotate(element.angle);\n boundTextCanvasContext.drawImage(canvas, -canvas.width / 2, -canvas.height / 2, canvas.width, canvas.height);\n const [,,,, boundTextCx, boundTextCy] = (0,_bounds__WEBPACK_IMPORTED_MODULE_4__.getElementAbsoluteCoords)(boundTextElement, elementsMap);\n boundTextCanvasContext.rotate(-element.angle);\n const offsetX = (boundTextCanvas.width - canvas.width) / 2;\n const offsetY = (boundTextCanvas.height - canvas.height) / 2;\n const shiftX = boundTextCanvas.width / 2 - (boundTextCx - x1) * window.devicePixelRatio * scale - offsetX - padding * scale;\n const shiftY = boundTextCanvas.height / 2 - (boundTextCy - y1) * window.devicePixelRatio * scale - offsetY - padding * scale;\n boundTextCanvasContext.translate(-shiftX, -shiftY); // Clear the bound text area\n\n boundTextCanvasContext.clearRect(-(boundTextElement.width / 2 + _excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.BOUND_TEXT_PADDING) * window.devicePixelRatio * scale, -(boundTextElement.height / 2 + _excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.BOUND_TEXT_PADDING) * window.devicePixelRatio * scale, (boundTextElement.width + _excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.BOUND_TEXT_PADDING * 2) * window.devicePixelRatio * scale, (boundTextElement.height + _excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.BOUND_TEXT_PADDING * 2) * window.devicePixelRatio * scale);\n }\n\n return {\n element,\n canvas,\n theme: appState.theme,\n scale,\n zoomValue: zoom.value,\n canvasOffsetX,\n canvasOffsetY,\n boundTextElementVersion: ((_a = (0,_textElement__WEBPACK_IMPORTED_MODULE_7__.getBoundTextElement)(element, elementsMap)) === null || _a === void 0 ? void 0 : _a.version) || null,\n containingFrameOpacity: ((_b = (0,_frame__WEBPACK_IMPORTED_MODULE_10__.getContainingFrame)(element, elementsMap)) === null || _b === void 0 ? void 0 : _b.opacity) || 100,\n boundTextCanvas,\n angle: element.angle,\n imageCrop: (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isImageElement)(element) ? element.crop : null\n };\n};\n\nconst DEFAULT_LINK_SIZE = 14;\nconst IMAGE_PLACEHOLDER_IMG = typeof document !== \"undefined\" ? document.createElement(\"img\") : {\n src: \"\"\n}; // mock image element outside of browser\n\nIMAGE_PLACEHOLDER_IMG.src = `data:${_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.MIME_TYPES.svg},${encodeURIComponent(`<svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"fas\" data-icon=\"image\" class=\"svg-inline--fa fa-image fa-w-16\" role=\"img\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><path fill=\"#888\" d=\"M464 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48zM112 120c-30.928 0-56 25.072-56 56s25.072 56 56 56 56-25.072 56-56-25.072-56-56-56zM64 384h384V272l-87.515-87.515c-4.686-4.686-12.284-4.686-16.971 0L208 320l-55.515-55.515c-4.686-4.686-12.284-4.686-16.971 0L64 336v48z\"></path></svg>`)}`;\nconst IMAGE_ERROR_PLACEHOLDER_IMG = typeof document !== \"undefined\" ? document.createElement(\"img\") : {\n src: \"\"\n}; // mock image element outside of browser\n\nIMAGE_ERROR_PLACEHOLDER_IMG.src = `data:${_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.MIME_TYPES.svg},${encodeURIComponent(`<svg viewBox=\"0 0 668 668\" xmlns=\"http://www.w3.org/2000/svg\" xml:space=\"preserve\" style=\"fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2\"><path d=\"M464 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48ZM112 120c-30.928 0-56 25.072-56 56s25.072 56 56 56 56-25.072 56-56-25.072-56-56-56ZM64 384h384V272l-87.515-87.515c-4.686-4.686-12.284-4.686-16.971 0L208 320l-55.515-55.515c-4.686-4.686-12.284-4.686-16.971 0L64 336v48Z\" style=\"fill:#888;fill-rule:nonzero\" transform=\"matrix(.81709 0 0 .81709 124.825 145.825)\"/><path d=\"M256 8C119.034 8 8 119.033 8 256c0 136.967 111.034 248 248 248s248-111.034 248-248S392.967 8 256 8Zm130.108 117.892c65.448 65.448 70 165.481 20.677 235.637L150.47 105.216c70.204-49.356 170.226-44.735 235.638 20.676ZM125.892 386.108c-65.448-65.448-70-165.481-20.677-235.637L361.53 406.784c-70.203 49.356-170.226 44.736-235.638-20.676Z\" style=\"fill:#888;fill-rule:nonzero\" transform=\"matrix(.30366 0 0 .30366 506.822 60.065)\"/></svg>`)}`;\n\nconst drawImagePlaceholder = (element, context) => {\n context.fillStyle = \"#E7E7E7\";\n context.fillRect(0, 0, element.width, element.height);\n const imageMinWidthOrHeight = Math.min(element.width, element.height);\n const size = Math.min(imageMinWidthOrHeight, Math.min(imageMinWidthOrHeight * 0.4, 100));\n context.drawImage(element.status === \"error\" ? IMAGE_ERROR_PLACEHOLDER_IMG : IMAGE_PLACEHOLDER_IMG, element.width / 2 - size / 2, element.height / 2 - size / 2, size, size);\n};\n\nconst drawElementOnCanvas = (element, rc, context, renderConfig) => {\n var _a, _b, _c, _d;\n\n switch (element.type) {\n case \"rectangle\":\n case \"iframe\":\n case \"embeddable\":\n case \"diamond\":\n case \"ellipse\":\n {\n context.lineJoin = \"round\";\n context.lineCap = \"round\";\n rc.draw(_shape__WEBPACK_IMPORTED_MODULE_12__.ShapeCache.get(element));\n break;\n }\n\n case \"arrow\":\n case \"line\":\n {\n context.lineJoin = \"round\";\n context.lineCap = \"round\";\n _shape__WEBPACK_IMPORTED_MODULE_12__.ShapeCache.get(element).forEach(shape => {\n rc.draw(shape);\n });\n break;\n }\n\n case \"freedraw\":\n {\n // Draw directly to canvas\n context.save();\n context.fillStyle = element.strokeColor;\n const path = getFreeDrawPath2D(element);\n const fillShape = _shape__WEBPACK_IMPORTED_MODULE_12__.ShapeCache.get(element);\n\n if (fillShape) {\n rc.draw(fillShape);\n } //zsviczian\n\n\n if ((_b = (_a = element.customData) === null || _a === void 0 ? void 0 : _a.strokeOptions) === null || _b === void 0 ? void 0 : _b.hasOutline) {\n context.lineWidth = element.strokeWidth * ((_c = element.customData.strokeOptions.outlineWidth) !== null && _c !== void 0 ? _c : 1);\n context.strokeStyle = element.strokeColor;\n context.stroke(path);\n context.fillStyle = element.backgroundColor;\n } else {\n context.fillStyle = element.strokeColor;\n }\n\n context.fill(path);\n context.restore();\n break;\n }\n\n case \"image\":\n {\n const img = (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isInitializedImageElement)(element) ? (_d = renderConfig.imageCache.get(element.fileId)) === null || _d === void 0 ? void 0 : _d.image : undefined;\n\n if (img != null && !(img instanceof Promise)) {\n if (element.roundness && context.roundRect) {\n context.beginPath();\n context.roundRect(0, 0, element.width, element.height, (0,_utils__WEBPACK_IMPORTED_MODULE_11__.getCornerRadius)(Math.min(element.width, element.height), element));\n context.clip();\n }\n\n const {\n x,\n y,\n width,\n height\n } = element.crop ? element.crop : {\n x: 0,\n y: 0,\n width: img.naturalWidth,\n height: img.naturalHeight\n };\n context.drawImage(img, x, y, width, height, 0\n /* hardcoded for the selection box*/\n , 0, element.width, element.height);\n } else {\n drawImagePlaceholder(element, context);\n }\n\n break;\n }\n\n default:\n {\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(element)) {\n const rtl = (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.isRTL)(element.text);\n const shouldTemporarilyAttach = rtl && !context.canvas.isConnected;\n\n if (shouldTemporarilyAttach) {\n // to correctly render RTL text mixed with LTR, we have to append it\n // to the DOM\n document.body.appendChild(context.canvas);\n }\n\n context.canvas.setAttribute(\"dir\", rtl ? \"rtl\" : \"ltr\");\n context.save();\n context.font = (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.getFontString)(element);\n context.fillStyle = element.strokeColor;\n context.textAlign = element.textAlign; // Canvas does not support multiline text by default\n\n const lines = element.text.replace(/\\r\\n?/g, \"\\n\").split(\"\\n\");\n const horizontalOffset = element.textAlign === \"center\" ? element.width / 2 : element.textAlign === \"right\" ? element.width : 0;\n const lineHeightPx = (0,_textMeasurements__WEBPACK_IMPORTED_MODULE_8__.getLineHeightInPx)(element.fontSize, element.lineHeight);\n const verticalOffset = (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.getVerticalOffset)(element.fontFamily, element.fontSize, lineHeightPx);\n\n for (let index = 0; index < lines.length; index++) {\n context.fillText(lines[index], horizontalOffset, index * lineHeightPx + verticalOffset);\n }\n\n context.restore();\n\n if (shouldTemporarilyAttach) {\n context.canvas.remove();\n }\n } else {\n throw new Error(`Unimplemented type ${element.type}`);\n }\n }\n }\n};\n\nconst elementWithCanvasCache = new WeakMap();\n\nconst generateElementWithCanvas = (element, elementsMap, renderConfig, appState) => {\n var _a;\n\n const zoom = renderConfig ? appState.zoom : {\n value: 1\n };\n const prevElementWithCanvas = elementWithCanvasCache.get(element);\n const shouldRegenerateBecauseZoom = prevElementWithCanvas && prevElementWithCanvas.zoomValue !== zoom.value && !(appState === null || appState === void 0 ? void 0 : appState.shouldCacheIgnoreZoom);\n const boundTextElement = (0,_textElement__WEBPACK_IMPORTED_MODULE_7__.getBoundTextElement)(element, elementsMap);\n const boundTextElementVersion = (boundTextElement === null || boundTextElement === void 0 ? void 0 : boundTextElement.version) || null;\n const imageCrop = (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isImageElement)(element) ? element.crop : null;\n const containingFrameOpacity = ((_a = (0,_frame__WEBPACK_IMPORTED_MODULE_10__.getContainingFrame)(element, elementsMap)) === null || _a === void 0 ? void 0 : _a.opacity) || 100;\n\n if (!prevElementWithCanvas || shouldRegenerateBecauseZoom || prevElementWithCanvas.theme !== appState.theme || prevElementWithCanvas.boundTextElementVersion !== boundTextElementVersion || prevElementWithCanvas.imageCrop !== imageCrop || prevElementWithCanvas.containingFrameOpacity !== containingFrameOpacity || // since we rotate the canvas when copying from cached canvas, we don't\n // regenerate the cached canvas. But we need to in case of labels which are\n // cached alongside the arrow, and we want the labels to remain unrotated\n // with respect to the arrow.\n (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isArrowElement)(element) && boundTextElement && element.angle !== prevElementWithCanvas.angle) {\n const elementWithCanvas = generateElementCanvas(element, elementsMap, zoom, renderConfig, appState);\n\n if (!elementWithCanvas) {\n return null;\n }\n\n elementWithCanvasCache.set(element, elementWithCanvas);\n return elementWithCanvas;\n }\n\n return prevElementWithCanvas;\n};\n\nconst drawElementFromCanvas = (elementWithCanvas, context, renderConfig, appState, allElementsMap) => {\n const element = elementWithCanvas.element;\n const padding = getCanvasPadding(element);\n const zoom = elementWithCanvas.scale;\n const [x1, y1, x2, y2] = (0,_bounds__WEBPACK_IMPORTED_MODULE_4__.getElementAbsoluteCoords)(element, allElementsMap);\n const cx = ((x1 + x2) / 2 + appState.scrollX) * window.devicePixelRatio;\n const cy = ((y1 + y2) / 2 + appState.scrollY) * window.devicePixelRatio;\n context.save();\n context.scale(1 / window.devicePixelRatio, 1 / window.devicePixelRatio);\n const boundTextElement = (0,_textElement__WEBPACK_IMPORTED_MODULE_7__.getBoundTextElement)(element, allElementsMap);\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isArrowElement)(element) && boundTextElement) {\n const offsetX = (elementWithCanvas.boundTextCanvas.width - elementWithCanvas.canvas.width) / 2;\n const offsetY = (elementWithCanvas.boundTextCanvas.height - elementWithCanvas.canvas.height) / 2;\n context.translate(cx, cy);\n context.drawImage(elementWithCanvas.boundTextCanvas, -(x2 - x1) / 2 * window.devicePixelRatio - offsetX / zoom - padding, -(y2 - y1) / 2 * window.devicePixelRatio - offsetY / zoom - padding, elementWithCanvas.boundTextCanvas.width / zoom, elementWithCanvas.boundTextCanvas.height / zoom);\n } else {\n // we translate context to element center so that rotation and scale\n // originates from the element center\n context.translate(cx, cy);\n context.rotate(element.angle);\n\n if (\"scale\" in elementWithCanvas.element && !isPendingImageElement(element, renderConfig) && !(0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isIframeLikeElement)(element) //zsviczian\n ) {\n context.scale(elementWithCanvas.element.scale[0], elementWithCanvas.element.scale[1]);\n } // revert afterwards we don't have account for it during drawing\n\n\n context.translate(-cx, -cy);\n context.drawImage(elementWithCanvas.canvas, (x1 + appState.scrollX) * window.devicePixelRatio - padding * elementWithCanvas.scale / elementWithCanvas.scale, (y1 + appState.scrollY) * window.devicePixelRatio - padding * elementWithCanvas.scale / elementWithCanvas.scale, elementWithCanvas.canvas.width / elementWithCanvas.scale, elementWithCanvas.canvas.height / elementWithCanvas.scale);\n\n if (false) {}\n }\n\n context.restore(); // Clear the nested element we appended to the DOM\n};\n\nconst renderSelectionElement = (element, context, appState, selectionColor) => {\n context.save();\n context.translate(element.x + appState.scrollX, element.y + appState.scrollY);\n context.fillStyle = \"rgba(0, 0, 200, 0.04)\"; // render from 0.5px offset to get 1px wide line\n // https://stackoverflow.com/questions/7530593/html5-canvas-and-line-width/7531540#7531540\n // TODO can be be improved by offseting to the negative when user selects\n // from right to left\n\n const offset = 0.5 / appState.zoom.value;\n context.fillRect(offset, offset, element.width, element.height);\n context.lineWidth = 1 / appState.zoom.value;\n context.strokeStyle = selectionColor;\n context.strokeRect(offset, offset, element.width, element.height);\n context.restore();\n};\nconst renderElement = (element, elementsMap, allElementsMap, rc, context, renderConfig, appState) => {\n var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;\n\n const reduceAlphaForSelection = ((_a = appState.openDialog) === null || _a === void 0 ? void 0 : _a.name) === \"elementLinkSelector\" && !appState.selectedElementIds[element.id] && !appState.hoveredElementIds[element.id];\n context.globalAlpha = getRenderOpacity(element, (0,_frame__WEBPACK_IMPORTED_MODULE_10__.getContainingFrame)(element, elementsMap), renderConfig.elementsPendingErasure, renderConfig.pendingFlowchartNodes, reduceAlphaForSelection ? _excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_REDUCED_GLOBAL_ALPHA : 1);\n\n switch (element.type) {\n case \"magicframe\":\n case \"frame\":\n {\n if ( //zsviczian\n appState.frameRendering.enabled && appState.frameRendering.outline && !(!appState.frameRendering.markerEnabled && element.frameRole === \"marker\")) {\n context.save();\n context.translate(element.x + appState.scrollX, element.y + appState.scrollY);\n context.fillStyle = (_f = (_d = (_c = (_b = element.customData) === null || _b === void 0 ? void 0 : _b.frameColor) === null || _c === void 0 ? void 0 : _c.fill) !== null && _d !== void 0 ? _d : (_e = appState === null || appState === void 0 ? void 0 : appState.frameColor) === null || _e === void 0 ? void 0 : _e.fill) !== null && _f !== void 0 ? _f : \"rgba(0, 0, 200, 0.04)\"; //zsviczian\n\n context.lineWidth = _excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.FRAME_STYLE.strokeWidth / appState.zoom.value;\n context.strokeStyle = (_l = (_j = (_h = (_g = element.customData) === null || _g === void 0 ? void 0 : _g.frameColor) === null || _h === void 0 ? void 0 : _h.stroke) !== null && _j !== void 0 ? _j : (_k = appState === null || appState === void 0 ? void 0 : appState.frameColor) === null || _k === void 0 ? void 0 : _k.stroke) !== null && _l !== void 0 ? _l : _excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.FRAME_STYLE.strokeColor; //zsviczian\n // TODO change later to only affect AI frames\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isMagicFrameElement)(element)) {\n context.strokeStyle = appState.theme === _excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.THEME.LIGHT ? \"#7affd7\" : \"#1d8264\";\n } //zsviczian\n\n\n if (element.frameRole === \"marker\") {\n const dash = 8 / appState.zoom.value;\n const gap = 6 / appState.zoom.value;\n context.setLineDash([dash, gap]);\n }\n\n if (_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.FRAME_STYLE.radius && context.roundRect && element.frameRole !== \"marker\") {\n //zsviczian\n context.beginPath();\n context.roundRect(0, 0, element.width, element.height, _excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.FRAME_STYLE.radius / appState.zoom.value);\n context.stroke();\n context.closePath();\n } else {\n context.strokeRect(0, 0, element.width, element.height);\n }\n\n context.restore();\n }\n\n break;\n }\n\n case \"freedraw\":\n {\n // TODO investigate if we can do this in situ. Right now we need to call\n // beforehand because math helpers (such as getElementAbsoluteCoords)\n // rely on existing shapes\n _shape__WEBPACK_IMPORTED_MODULE_12__.ShapeCache.generateElementShape(element, null);\n\n if (renderConfig.isExporting) {\n const [x1, y1, x2, y2] = (0,_bounds__WEBPACK_IMPORTED_MODULE_4__.getElementAbsoluteCoords)(element, elementsMap);\n const cx = (x1 + x2) / 2 + appState.scrollX;\n const cy = (y1 + y2) / 2 + appState.scrollY;\n const shiftX = (x2 - x1) / 2 - (element.x - x1);\n const shiftY = (y2 - y1) / 2 - (element.y - y1);\n context.save();\n context.translate(cx, cy);\n context.rotate(element.angle);\n context.translate(-shiftX, -shiftY);\n drawElementOnCanvas(element, rc, context, renderConfig);\n context.restore();\n } else {\n const elementWithCanvas = generateElementWithCanvas(element, allElementsMap, renderConfig, appState);\n\n if (!elementWithCanvas) {\n return;\n }\n\n drawElementFromCanvas(elementWithCanvas, context, renderConfig, appState, allElementsMap);\n }\n\n break;\n }\n\n case \"rectangle\":\n case \"diamond\":\n case \"ellipse\":\n case \"line\":\n case \"arrow\":\n case \"image\":\n case \"text\":\n case \"iframe\":\n case \"embeddable\":\n {\n // TODO investigate if we can do this in situ. Right now we need to call\n // beforehand because math helpers (such as getElementAbsoluteCoords)\n // rely on existing shapes\n _shape__WEBPACK_IMPORTED_MODULE_12__.ShapeCache.generateElementShape(element, renderConfig);\n\n if (renderConfig.isExporting) {\n const [x1, y1, x2, y2] = (0,_bounds__WEBPACK_IMPORTED_MODULE_4__.getElementAbsoluteCoords)(element, elementsMap);\n const cx = (x1 + x2) / 2 + appState.scrollX;\n const cy = (y1 + y2) / 2 + appState.scrollY;\n let shiftX = (x2 - x1) / 2 - (element.x - x1);\n let shiftY = (y2 - y1) / 2 - (element.y - y1);\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(element)) {\n const container = (0,_textElement__WEBPACK_IMPORTED_MODULE_7__.getContainerElement)(element, elementsMap);\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isArrowElement)(container)) {\n const boundTextCoords = _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getBoundTextElementPosition(container, element, elementsMap);\n shiftX = (x2 - x1) / 2 - (boundTextCoords.x - x1);\n shiftY = (y2 - y1) / 2 - (boundTextCoords.y - y1);\n }\n }\n\n context.save();\n context.translate(cx, cy);\n\n if (shouldResetImageFilter(element, renderConfig, appState)) {\n context.filter = \"none\";\n }\n\n const boundTextElement = (0,_textElement__WEBPACK_IMPORTED_MODULE_7__.getBoundTextElement)(element, elementsMap);\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isArrowElement)(element) && boundTextElement) {\n const tempCanvas = document.createElement(\"canvas\");\n const tempCanvasContext = tempCanvas.getContext(\"2d\"); // Take max dimensions of arrow canvas so that when canvas is rotated\n // the arrow doesn't get clipped\n\n const maxDim = Math.max((0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.distance)(x1, x2), (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.distance)(y1, y2));\n const padding = getCanvasPadding(element);\n tempCanvas.width = maxDim * appState.exportScale + padding * 10 * appState.exportScale;\n tempCanvas.height = maxDim * appState.exportScale + padding * 10 * appState.exportScale;\n tempCanvasContext.translate(tempCanvas.width / 2, tempCanvas.height / 2);\n tempCanvasContext.scale(appState.exportScale, appState.exportScale); // Shift the canvas to left most point of the arrow\n\n shiftX = element.width / 2 - (element.x - x1);\n shiftY = element.height / 2 - (element.y - y1);\n tempCanvasContext.rotate(element.angle);\n const tempRc = roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_0__[\"default\"].canvas(tempCanvas);\n tempCanvasContext.translate(-shiftX, -shiftY);\n drawElementOnCanvas(element, tempRc, tempCanvasContext, renderConfig);\n tempCanvasContext.translate(shiftX, shiftY);\n tempCanvasContext.rotate(-element.angle); // Shift the canvas to center of bound text\n\n const [,,,, boundTextCx, boundTextCy] = (0,_bounds__WEBPACK_IMPORTED_MODULE_4__.getElementAbsoluteCoords)(boundTextElement, elementsMap);\n const boundTextShiftX = (x1 + x2) / 2 - boundTextCx;\n const boundTextShiftY = (y1 + y2) / 2 - boundTextCy;\n tempCanvasContext.translate(-boundTextShiftX, -boundTextShiftY); // Clear the bound text area\n\n tempCanvasContext.clearRect(-boundTextElement.width / 2, -boundTextElement.height / 2, boundTextElement.width, boundTextElement.height);\n context.scale(1 / appState.exportScale, 1 / appState.exportScale);\n context.drawImage(tempCanvas, -tempCanvas.width / 2, -tempCanvas.height / 2, tempCanvas.width, tempCanvas.height);\n } else {\n context.rotate(element.angle);\n\n if (element.type === \"image\") {\n // note: scale must be applied *after* rotating\n context.scale(element.scale[0], element.scale[1]);\n }\n\n context.translate(-shiftX, -shiftY);\n drawElementOnCanvas(element, rc, context, renderConfig);\n }\n\n context.restore(); // not exporting → optimized rendering (cache & render from element\n // canvases)\n } else {\n const elementWithCanvas = generateElementWithCanvas(element, allElementsMap, renderConfig, appState);\n\n if (!elementWithCanvas) {\n return;\n }\n\n const currentImageSmoothingStatus = context.imageSmoothingEnabled;\n\n if ( // do not disable smoothing during zoom as blurry shapes look better\n // on low resolution (while still zooming in) than sharp ones\n !(appState === null || appState === void 0 ? void 0 : appState.shouldCacheIgnoreZoom) && ( // angle is 0 -> always disable smoothing\n !element.angle || // or check if angle is a right angle in which case we can still\n // disable smoothing without adversely affecting the result\n // We need less-than comparison because of FP artihmetic\n (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_2__.isRightAngleRads)(element.angle))) {\n // Disabling smoothing makes output much sharper, especially for\n // text. Unless for non-right angles, where the aliasing is really\n // terrible on Chromium.\n //\n // Note that `context.imageSmoothingQuality=\"high\"` has almost\n // zero effect.\n //\n context.imageSmoothingEnabled = false;\n }\n\n if (element.id === appState.croppingElementId && (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isImageElement)(elementWithCanvas.element) && elementWithCanvas.element.crop !== null) {\n context.save();\n context.globalAlpha = 0.1;\n const uncroppedElementCanvas = generateElementCanvas((0,_cropElement__WEBPACK_IMPORTED_MODULE_5__.getUncroppedImageElement)(elementWithCanvas.element, elementsMap), allElementsMap, appState.zoom, renderConfig, appState);\n\n if (uncroppedElementCanvas) {\n drawElementFromCanvas(uncroppedElementCanvas, context, renderConfig, appState, allElementsMap);\n }\n\n context.restore();\n }\n\n drawElementFromCanvas(elementWithCanvas, context, renderConfig, appState, allElementsMap); // reset\n\n context.imageSmoothingEnabled = currentImageSmoothingStatus;\n }\n\n break;\n }\n\n default:\n {\n // @ts-ignore\n throw new Error(`Unimplemented type ${element.type}`);\n }\n }\n\n context.globalAlpha = 1;\n};\nconst pathsCache = new WeakMap([]);\nfunction generateFreeDrawShape(element) {\n const svgPathData = getFreeDrawSvgPath(element);\n const path = new Path2D(svgPathData);\n pathsCache.set(element, path);\n return path;\n}\nfunction getFreeDrawPath2D(element) {\n return pathsCache.get(element);\n}\nfunction getFreeDrawSvgPath(element) {\n return getSvgPathFromStroke(getFreedrawOutlinePoints(element));\n}\nfunction getFreedrawOutlineAsSegments(element, points, elementsMap) {\n const bounds = (0,_bounds__WEBPACK_IMPORTED_MODULE_4__.getElementBounds)(Object.assign(Object.assign({}, element), {\n angle: 0\n }), elementsMap);\n const center = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_2__.pointFrom)((bounds[0] + bounds[2]) / 2, (bounds[1] + bounds[3]) / 2);\n (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.invariant)(points.length >= 2, \"Freepath outline must have at least 2 points\");\n return points.slice(2).reduce((acc, curr) => {\n acc.push((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_2__.lineSegment)(acc[acc.length - 1][1], (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_2__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_2__.pointFrom)(curr[0] + element.x, curr[1] + element.y), center, element.angle)));\n return acc;\n }, [(0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_2__.lineSegment)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_2__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_2__.pointFrom)(points[0][0] + element.x, points[0][1] + element.y), center, element.angle), (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_2__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_2__.pointFrom)(points[1][0] + element.x, points[1][1] + element.y), center, element.angle))]);\n}\nfunction getFreedrawOutlinePoints(element) {\n var _a, _b, _c, _d, _e, _f, _g, _h; // If input points are empty (should they ever be?) return a dot\n\n\n const inputPoints = element.simulatePressure ? element.points : element.points.length ? element.points.map(([x, y], i) => [x, y, element.pressures[i]]) : [[0, 0, 0.5]]; // Consider changing the options for simulated pressure vs real pressure\n\n const customOptions = (_b = (_a = element.customData) === null || _a === void 0 ? void 0 : _a.strokeOptions) === null || _b === void 0 ? void 0 : _b.options; //zsviczian\n\n const options = customOptions //zsviczian\n ? Object.assign(Object.assign(Object.assign(Object.assign({}, customOptions), {\n simulatePressure: (_c = customOptions.simulatePressure) !== null && _c !== void 0 ? _c : element.simulatePressure,\n size: element.strokeWidth * 4.25,\n last: true,\n easing: (_d = _easingFunctions__WEBPACK_IMPORTED_MODULE_13__[\"default\"][customOptions.easing]) !== null && _d !== void 0 ? _d : t => t\n }), ((_e = customOptions.start) === null || _e === void 0 ? void 0 : _e.easing) ? {\n start: Object.assign(Object.assign({}, customOptions.start), {\n easing: (_f = _easingFunctions__WEBPACK_IMPORTED_MODULE_13__[\"default\"][customOptions.start.easing]) !== null && _f !== void 0 ? _f : t => t\n })\n } : {\n start: customOptions.start\n }), ((_g = customOptions.end) === null || _g === void 0 ? void 0 : _g.easing) ? {\n end: Object.assign(Object.assign({}, customOptions.end), {\n easing: (_h = _easingFunctions__WEBPACK_IMPORTED_MODULE_13__[\"default\"][customOptions.end.easing]) !== null && _h !== void 0 ? _h : t => t\n })\n } : {\n end: customOptions.end\n }) : {\n simulatePressure: element.simulatePressure,\n size: element.strokeWidth * 4.25,\n thinning: 0.6,\n smoothing: 0.5,\n streamline: 0.5,\n easing: _easingFunctions__WEBPACK_IMPORTED_MODULE_13__[\"default\"].easeOutSine,\n last: true\n };\n return (0,perfect_freehand__WEBPACK_IMPORTED_MODULE_1__.getStroke)(inputPoints, options);\n}\n\nfunction med(A, B) {\n return [(A[0] + B[0]) / 2, (A[1] + B[1]) / 2];\n} // Trim SVG path data so number are each two decimal points. This\n// improves SVG exports, and prevents rendering errors on points\n// with long decimals.\n\n\nconst TO_FIXED_PRECISION = /(\\s?[A-Z]?,?-?[0-9]*\\.[0-9]{0,2})(([0-9]|e|-)*)/g;\n\nfunction getSvgPathFromStroke(points) {\n if (!points.length) {\n return \"\";\n }\n\n const max = points.length - 1;\n return points.reduce((acc, point, i, arr) => {\n if (i === max) {\n acc.push(point, med(point, arr[0]), \"L\", arr[0], \"Z\");\n } else {\n acc.push(point, med(point, arr[i + 1]));\n }\n\n return acc;\n }, [\"M\", points[0], \"Q\"]).join(\" \").replace(TO_FIXED_PRECISION, \"$1\");\n}\n\n//# sourceURL=webpack://ExcalidrawLib/../element/src/renderElement.ts?");
13424
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ DEFAULT_LINK_SIZE: () => (/* binding */ DEFAULT_LINK_SIZE),\n/* harmony export */ IMAGE_INVERT_FILTER: () => (/* binding */ IMAGE_INVERT_FILTER),\n/* harmony export */ elementWithCanvasCache: () => (/* binding */ elementWithCanvasCache),\n/* harmony export */ generateFreeDrawShape: () => (/* binding */ generateFreeDrawShape),\n/* harmony export */ getFreeDrawPath2D: () => (/* binding */ getFreeDrawPath2D),\n/* harmony export */ getFreeDrawSvgPath: () => (/* binding */ getFreeDrawSvgPath),\n/* harmony export */ getFreedrawOutlineAsSegments: () => (/* binding */ getFreedrawOutlineAsSegments),\n/* harmony export */ getFreedrawOutlinePoints: () => (/* binding */ getFreedrawOutlinePoints),\n/* harmony export */ getRenderOpacity: () => (/* binding */ getRenderOpacity),\n/* harmony export */ pathsCache: () => (/* binding */ pathsCache),\n/* harmony export */ renderElement: () => (/* binding */ renderElement),\n/* harmony export */ renderSelectionElement: () => (/* binding */ renderSelectionElement)\n/* harmony export */ });\n/* harmony import */ var roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! roughjs/bin/rough */ \"../../node_modules/roughjs/bin/rough.js\");\n/* harmony import */ var perfect_freehand__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! perfect-freehand */ \"../../node_modules/perfect-freehand/dist/esm/index.js\");\n/* harmony import */ var _excalidraw_math__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @excalidraw/math */ \"../math/src/index.ts\");\n/* harmony import */ var _excalidraw_common__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @excalidraw/common */ \"../common/src/index.ts\");\n/* harmony import */ var _bounds__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./bounds */ \"../element/src/bounds.ts\");\n/* harmony import */ var _cropElement__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./cropElement */ \"../element/src/cropElement.ts\");\n/* harmony import */ var _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./linearElementEditor */ \"../element/src/linearElementEditor.ts\");\n/* harmony import */ var _textElement__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./textElement */ \"../element/src/textElement.ts\");\n/* harmony import */ var _textMeasurements__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./textMeasurements */ \"../element/src/textMeasurements.ts\");\n/* harmony import */ var _typeChecks__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @excalidraw/element/typeChecks */ \"../element/src/typeChecks.ts\");\n/* harmony import */ var _frame__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./frame */ \"../element/src/frame.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./utils */ \"../element/src/utils.ts\");\n/* harmony import */ var _shape__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./shape */ \"../element/src/shape.ts\");\n/* harmony import */ var _easingFunctions__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./easingFunctions */ \"../element/src/easingFunctions.ts\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n // using a stronger invert (100% vs our regular 93%) and saturate\n// as a temp hack to make images in dark theme look closer to original\n// color scheme (it's still not quite there and the colors look slightly\n// desatured, alas...)\n\nconst IMAGE_INVERT_FILTER = \"invert(100%) hue-rotate(180deg) saturate(1.25)\";\n\nconst isPendingImageElement = (element, renderConfig) => (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isInitializedImageElement)(element) && !renderConfig.imageCache.has(element.fileId);\n\nconst shouldResetImageFilter = (element, renderConfig, appState) => {\n var _a;\n\n return appState.theme === _excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.THEME.DARK && (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isInitializedImageElement)(element) && !isPendingImageElement(element, renderConfig) && ((_a = renderConfig.imageCache.get(element.fileId)) === null || _a === void 0 ? void 0 : _a.mimeType) !== _excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.MIME_TYPES.svg;\n};\n\nconst getCanvasPadding = element => {\n switch (element.type) {\n case \"freedraw\":\n return element.strokeWidth * 12;\n\n case \"text\":\n return element.fontSize / 2;\n\n case \"arrow\":\n if (element.endArrowhead || element.endArrowhead) {\n return 40;\n }\n\n return 20;\n\n default:\n return 20;\n }\n};\n\nconst getRenderOpacity = (element, containingFrame, elementsPendingErasure, pendingNodes, globalAlpha = 1) => {\n var _a; // multiplying frame opacity with element opacity to combine them\n // (e.g. frame 50% and element 50% opacity should result in 25% opacity)\n\n\n let opacity = ((_a = containingFrame === null || containingFrame === void 0 ? void 0 : containingFrame.opacity) !== null && _a !== void 0 ? _a : 100) * element.opacity / 10000 * globalAlpha; // if pending erasure, multiply again to combine further\n // (so that erasing always results in lower opacity than original)\n\n if (elementsPendingErasure.has(element.id) || pendingNodes && pendingNodes.some(node => node.id === element.id) || containingFrame && elementsPendingErasure.has(containingFrame.id)) {\n opacity *= _excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.ELEMENT_READY_TO_ERASE_OPACITY / 100;\n }\n\n return opacity;\n};\n\nconst cappedElementCanvasSize = (element, elementsMap, zoom) => {\n // these limits are ballpark, they depend on specific browsers and device.\n // We've chosen lower limits to be safe. We might want to change these limits\n // based on browser/device type, if we get reports of low quality rendering\n // on zoom.\n //\n // ~ safari mobile canvas area limit\n const AREA_LIMIT = (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.getAreaLimit)(); //zsviczian\n // ~ safari width/height limit based on developer.mozilla.org.\n\n const WIDTH_HEIGHT_LIMIT = (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.getWidthHeightLimit)(); //zsviczian\n\n const padding = getCanvasPadding(element);\n const [x1, y1, x2, y2] = (0,_bounds__WEBPACK_IMPORTED_MODULE_4__.getElementAbsoluteCoords)(element, elementsMap);\n const elementWidth = (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isLinearElement)(element) || (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isFreeDrawElement)(element) ? (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.distance)(x1, x2) : element.width;\n const elementHeight = (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isLinearElement)(element) || (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isFreeDrawElement)(element) ? (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.distance)(y1, y2) : element.height;\n let width = elementWidth * window.devicePixelRatio + padding * 2;\n let height = elementHeight * window.devicePixelRatio + padding * 2;\n let scale = zoom.value; // rescale to ensure width and height is within limits\n\n if (width * scale > WIDTH_HEIGHT_LIMIT || height * scale > WIDTH_HEIGHT_LIMIT) {\n scale = Math.min(WIDTH_HEIGHT_LIMIT / width, WIDTH_HEIGHT_LIMIT / height);\n } // rescale to ensure canvas area is within limits\n\n\n if (width * height * scale * scale > AREA_LIMIT) {\n scale = Math.sqrt(AREA_LIMIT / (width * height));\n }\n\n width = Math.floor(width * scale);\n height = Math.floor(height * scale);\n return {\n width,\n height,\n scale\n };\n};\n\nconst generateElementCanvas = (element, elementsMap, zoom, renderConfig, appState) => {\n var _a, _b;\n\n const canvas = document.createElement(\"canvas\");\n const context = canvas.getContext(\"2d\");\n const padding = getCanvasPadding(element);\n const {\n width,\n height,\n scale\n } = cappedElementCanvasSize(element, elementsMap, zoom);\n\n if (!width || !height) {\n return null;\n }\n\n canvas.width = width;\n canvas.height = height;\n let canvasOffsetX = -100;\n let canvasOffsetY = 0;\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isLinearElement)(element) || (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isFreeDrawElement)(element)) {\n const [x1, y1] = (0,_bounds__WEBPACK_IMPORTED_MODULE_4__.getElementAbsoluteCoords)(element, elementsMap);\n canvasOffsetX = element.x > x1 ? (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.distance)(element.x, x1) * window.devicePixelRatio * scale : 0;\n canvasOffsetY = element.y > y1 ? (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.distance)(element.y, y1) * window.devicePixelRatio * scale : 0;\n context.translate(canvasOffsetX, canvasOffsetY);\n }\n\n context.save();\n context.translate(padding * scale, padding * scale);\n context.scale(window.devicePixelRatio * scale, window.devicePixelRatio * scale);\n const rc = roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_0__[\"default\"].canvas(canvas); // in dark theme, revert the image color filter\n\n if (shouldResetImageFilter(element, renderConfig, appState)) {\n context.filter = IMAGE_INVERT_FILTER;\n }\n\n drawElementOnCanvas(element, rc, context, renderConfig);\n context.restore();\n const boundTextElement = (0,_textElement__WEBPACK_IMPORTED_MODULE_7__.getBoundTextElement)(element, elementsMap);\n const boundTextCanvas = document.createElement(\"canvas\");\n const boundTextCanvasContext = boundTextCanvas.getContext(\"2d\");\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isArrowElement)(element) && boundTextElement) {\n const [x1, y1, x2, y2] = (0,_bounds__WEBPACK_IMPORTED_MODULE_4__.getElementAbsoluteCoords)(element, elementsMap); // Take max dimensions of arrow canvas so that when canvas is rotated\n // the arrow doesn't get clipped\n\n const maxDim = Math.max((0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.distance)(x1, x2), (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.distance)(y1, y2));\n boundTextCanvas.width = maxDim * window.devicePixelRatio * scale + padding * scale * 10;\n boundTextCanvas.height = maxDim * window.devicePixelRatio * scale + padding * scale * 10;\n boundTextCanvasContext.translate(boundTextCanvas.width / 2, boundTextCanvas.height / 2);\n boundTextCanvasContext.rotate(element.angle);\n boundTextCanvasContext.drawImage(canvas, -canvas.width / 2, -canvas.height / 2, canvas.width, canvas.height);\n const [,,,, boundTextCx, boundTextCy] = (0,_bounds__WEBPACK_IMPORTED_MODULE_4__.getElementAbsoluteCoords)(boundTextElement, elementsMap);\n boundTextCanvasContext.rotate(-element.angle);\n const offsetX = (boundTextCanvas.width - canvas.width) / 2;\n const offsetY = (boundTextCanvas.height - canvas.height) / 2;\n const shiftX = boundTextCanvas.width / 2 - (boundTextCx - x1) * window.devicePixelRatio * scale - offsetX - padding * scale;\n const shiftY = boundTextCanvas.height / 2 - (boundTextCy - y1) * window.devicePixelRatio * scale - offsetY - padding * scale;\n boundTextCanvasContext.translate(-shiftX, -shiftY); // Clear the bound text area\n\n boundTextCanvasContext.clearRect(-(boundTextElement.width / 2 + _excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.BOUND_TEXT_PADDING) * window.devicePixelRatio * scale, -(boundTextElement.height / 2 + _excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.BOUND_TEXT_PADDING) * window.devicePixelRatio * scale, (boundTextElement.width + _excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.BOUND_TEXT_PADDING * 2) * window.devicePixelRatio * scale, (boundTextElement.height + _excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.BOUND_TEXT_PADDING * 2) * window.devicePixelRatio * scale);\n }\n\n return {\n element,\n canvas,\n theme: appState.theme,\n scale,\n zoomValue: zoom.value,\n canvasOffsetX,\n canvasOffsetY,\n boundTextElementVersion: ((_a = (0,_textElement__WEBPACK_IMPORTED_MODULE_7__.getBoundTextElement)(element, elementsMap)) === null || _a === void 0 ? void 0 : _a.version) || null,\n containingFrameOpacity: ((_b = (0,_frame__WEBPACK_IMPORTED_MODULE_10__.getContainingFrame)(element, elementsMap)) === null || _b === void 0 ? void 0 : _b.opacity) || 100,\n boundTextCanvas,\n angle: element.angle,\n imageCrop: (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isImageElement)(element) ? element.crop : null\n };\n};\n\nconst DEFAULT_LINK_SIZE = 14;\nconst IMAGE_PLACEHOLDER_IMG = typeof document !== \"undefined\" ? document.createElement(\"img\") : {\n src: \"\"\n}; // mock image element outside of browser\n\nIMAGE_PLACEHOLDER_IMG.src = `data:${_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.MIME_TYPES.svg},${encodeURIComponent(`<svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"fas\" data-icon=\"image\" class=\"svg-inline--fa fa-image fa-w-16\" role=\"img\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><path fill=\"#888\" d=\"M464 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48zM112 120c-30.928 0-56 25.072-56 56s25.072 56 56 56 56-25.072 56-56-25.072-56-56-56zM64 384h384V272l-87.515-87.515c-4.686-4.686-12.284-4.686-16.971 0L208 320l-55.515-55.515c-4.686-4.686-12.284-4.686-16.971 0L64 336v48z\"></path></svg>`)}`;\nconst IMAGE_ERROR_PLACEHOLDER_IMG = typeof document !== \"undefined\" ? document.createElement(\"img\") : {\n src: \"\"\n}; // mock image element outside of browser\n\nIMAGE_ERROR_PLACEHOLDER_IMG.src = `data:${_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.MIME_TYPES.svg},${encodeURIComponent(`<svg viewBox=\"0 0 668 668\" xmlns=\"http://www.w3.org/2000/svg\" xml:space=\"preserve\" style=\"fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2\"><path d=\"M464 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48ZM112 120c-30.928 0-56 25.072-56 56s25.072 56 56 56 56-25.072 56-56-25.072-56-56-56ZM64 384h384V272l-87.515-87.515c-4.686-4.686-12.284-4.686-16.971 0L208 320l-55.515-55.515c-4.686-4.686-12.284-4.686-16.971 0L64 336v48Z\" style=\"fill:#888;fill-rule:nonzero\" transform=\"matrix(.81709 0 0 .81709 124.825 145.825)\"/><path d=\"M256 8C119.034 8 8 119.033 8 256c0 136.967 111.034 248 248 248s248-111.034 248-248S392.967 8 256 8Zm130.108 117.892c65.448 65.448 70 165.481 20.677 235.637L150.47 105.216c70.204-49.356 170.226-44.735 235.638 20.676ZM125.892 386.108c-65.448-65.448-70-165.481-20.677-235.637L361.53 406.784c-70.203 49.356-170.226 44.736-235.638-20.676Z\" style=\"fill:#888;fill-rule:nonzero\" transform=\"matrix(.30366 0 0 .30366 506.822 60.065)\"/></svg>`)}`;\n\nconst drawImagePlaceholder = (element, context) => {\n context.fillStyle = \"#E7E7E7\";\n context.fillRect(0, 0, element.width, element.height);\n const imageMinWidthOrHeight = Math.min(element.width, element.height);\n const size = Math.min(imageMinWidthOrHeight, Math.min(imageMinWidthOrHeight * 0.4, 100));\n context.drawImage(element.status === \"error\" ? IMAGE_ERROR_PLACEHOLDER_IMG : IMAGE_PLACEHOLDER_IMG, element.width / 2 - size / 2, element.height / 2 - size / 2, size, size);\n};\n\nconst drawElementOnCanvas = (element, rc, context, renderConfig) => {\n var _a, _b, _c, _d;\n\n switch (element.type) {\n case \"rectangle\":\n case \"iframe\":\n case \"embeddable\":\n case \"diamond\":\n case \"ellipse\":\n {\n context.lineJoin = \"round\";\n context.lineCap = \"round\";\n rc.draw(_shape__WEBPACK_IMPORTED_MODULE_12__.ShapeCache.get(element));\n break;\n }\n\n case \"arrow\":\n case \"line\":\n {\n context.lineJoin = \"round\";\n context.lineCap = \"round\";\n _shape__WEBPACK_IMPORTED_MODULE_12__.ShapeCache.get(element).forEach(shape => {\n rc.draw(shape);\n });\n break;\n }\n\n case \"freedraw\":\n {\n // Draw directly to canvas\n context.save();\n context.fillStyle = element.strokeColor;\n const path = getFreeDrawPath2D(element);\n const fillShape = _shape__WEBPACK_IMPORTED_MODULE_12__.ShapeCache.get(element);\n\n if (fillShape) {\n rc.draw(fillShape);\n } //zsviczian\n\n\n if ((_b = (_a = element.customData) === null || _a === void 0 ? void 0 : _a.strokeOptions) === null || _b === void 0 ? void 0 : _b.hasOutline) {\n context.lineWidth = element.strokeWidth * ((_c = element.customData.strokeOptions.outlineWidth) !== null && _c !== void 0 ? _c : 1);\n context.strokeStyle = element.strokeColor;\n context.stroke(path);\n context.fillStyle = element.backgroundColor;\n } else {\n context.fillStyle = element.strokeColor;\n }\n\n context.fill(path);\n context.restore();\n break;\n }\n\n case \"image\":\n {\n const img = (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isInitializedImageElement)(element) ? (_d = renderConfig.imageCache.get(element.fileId)) === null || _d === void 0 ? void 0 : _d.image : undefined;\n\n if (img != null && !(img instanceof Promise)) {\n if (element.roundness && context.roundRect) {\n context.beginPath();\n context.roundRect(0, 0, element.width, element.height, (0,_utils__WEBPACK_IMPORTED_MODULE_11__.getCornerRadius)(Math.min(element.width, element.height), element));\n context.clip();\n }\n\n const {\n x,\n y,\n width,\n height\n } = element.crop ? element.crop : {\n x: 0,\n y: 0,\n width: img.naturalWidth,\n height: img.naturalHeight\n };\n context.drawImage(img, x, y, width, height, 0\n /* hardcoded for the selection box*/\n , 0, element.width, element.height);\n } else {\n drawImagePlaceholder(element, context);\n }\n\n break;\n }\n\n default:\n {\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(element)) {\n const rtl = (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.isRTL)(element.text);\n const shouldTemporarilyAttach = rtl && !context.canvas.isConnected;\n\n if (shouldTemporarilyAttach) {\n // to correctly render RTL text mixed with LTR, we have to append it\n // to the DOM\n document.body.appendChild(context.canvas);\n }\n\n context.canvas.setAttribute(\"dir\", rtl ? \"rtl\" : \"ltr\");\n context.save();\n context.font = (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.getFontString)(element);\n context.fillStyle = element.strokeColor;\n context.textAlign = element.textAlign; // Canvas does not support multiline text by default\n\n const lines = element.text.replace(/\\r\\n?/g, \"\\n\").split(\"\\n\");\n const horizontalOffset = element.textAlign === \"center\" ? element.width / 2 : element.textAlign === \"right\" ? element.width : 0;\n const lineHeightPx = (0,_textMeasurements__WEBPACK_IMPORTED_MODULE_8__.getLineHeightInPx)(element.fontSize, element.lineHeight);\n const verticalOffset = (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.getVerticalOffset)(element.fontFamily, element.fontSize, lineHeightPx);\n\n for (let index = 0; index < lines.length; index++) {\n context.fillText(lines[index], horizontalOffset, index * lineHeightPx + verticalOffset);\n }\n\n context.restore();\n\n if (shouldTemporarilyAttach) {\n context.canvas.remove();\n }\n } else {\n throw new Error(`Unimplemented type ${element.type}`);\n }\n }\n }\n};\n\nconst elementWithCanvasCache = new WeakMap();\n\nconst generateElementWithCanvas = (element, elementsMap, renderConfig, appState) => {\n var _a;\n\n const zoom = renderConfig ? appState.zoom : {\n value: 1\n };\n const prevElementWithCanvas = elementWithCanvasCache.get(element);\n const shouldRegenerateBecauseZoom = prevElementWithCanvas && prevElementWithCanvas.zoomValue !== zoom.value && !(appState === null || appState === void 0 ? void 0 : appState.shouldCacheIgnoreZoom);\n const boundTextElement = (0,_textElement__WEBPACK_IMPORTED_MODULE_7__.getBoundTextElement)(element, elementsMap);\n const boundTextElementVersion = (boundTextElement === null || boundTextElement === void 0 ? void 0 : boundTextElement.version) || null;\n const imageCrop = (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isImageElement)(element) ? element.crop : null;\n const containingFrameOpacity = ((_a = (0,_frame__WEBPACK_IMPORTED_MODULE_10__.getContainingFrame)(element, elementsMap)) === null || _a === void 0 ? void 0 : _a.opacity) || 100;\n\n if (!prevElementWithCanvas || shouldRegenerateBecauseZoom || prevElementWithCanvas.theme !== appState.theme || prevElementWithCanvas.boundTextElementVersion !== boundTextElementVersion || prevElementWithCanvas.imageCrop !== imageCrop || prevElementWithCanvas.containingFrameOpacity !== containingFrameOpacity || // since we rotate the canvas when copying from cached canvas, we don't\n // regenerate the cached canvas. But we need to in case of labels which are\n // cached alongside the arrow, and we want the labels to remain unrotated\n // with respect to the arrow.\n (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isArrowElement)(element) && boundTextElement && element.angle !== prevElementWithCanvas.angle) {\n const elementWithCanvas = generateElementCanvas(element, elementsMap, zoom, renderConfig, appState);\n\n if (!elementWithCanvas) {\n return null;\n }\n\n elementWithCanvasCache.set(element, elementWithCanvas);\n return elementWithCanvas;\n }\n\n return prevElementWithCanvas;\n};\n\nconst drawElementFromCanvas = (elementWithCanvas, context, renderConfig, appState, allElementsMap) => {\n const element = elementWithCanvas.element;\n const padding = getCanvasPadding(element);\n const zoom = elementWithCanvas.scale;\n const [x1, y1, x2, y2] = (0,_bounds__WEBPACK_IMPORTED_MODULE_4__.getElementAbsoluteCoords)(element, allElementsMap);\n const cx = ((x1 + x2) / 2 + appState.scrollX) * window.devicePixelRatio;\n const cy = ((y1 + y2) / 2 + appState.scrollY) * window.devicePixelRatio;\n context.save();\n context.scale(1 / window.devicePixelRatio, 1 / window.devicePixelRatio);\n const boundTextElement = (0,_textElement__WEBPACK_IMPORTED_MODULE_7__.getBoundTextElement)(element, allElementsMap);\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isArrowElement)(element) && boundTextElement) {\n const offsetX = (elementWithCanvas.boundTextCanvas.width - elementWithCanvas.canvas.width) / 2;\n const offsetY = (elementWithCanvas.boundTextCanvas.height - elementWithCanvas.canvas.height) / 2;\n context.translate(cx, cy);\n context.drawImage(elementWithCanvas.boundTextCanvas, -(x2 - x1) / 2 * window.devicePixelRatio - offsetX / zoom - padding, -(y2 - y1) / 2 * window.devicePixelRatio - offsetY / zoom - padding, elementWithCanvas.boundTextCanvas.width / zoom, elementWithCanvas.boundTextCanvas.height / zoom);\n } else {\n // we translate context to element center so that rotation and scale\n // originates from the element center\n context.translate(cx, cy);\n context.rotate(element.angle);\n\n if (\"scale\" in elementWithCanvas.element && !isPendingImageElement(element, renderConfig) && !(0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isIframeLikeElement)(element) //zsviczian\n ) {\n context.scale(elementWithCanvas.element.scale[0], elementWithCanvas.element.scale[1]);\n } // revert afterwards we don't have account for it during drawing\n\n\n context.translate(-cx, -cy);\n context.drawImage(elementWithCanvas.canvas, (x1 + appState.scrollX) * window.devicePixelRatio - padding * elementWithCanvas.scale / elementWithCanvas.scale, (y1 + appState.scrollY) * window.devicePixelRatio - padding * elementWithCanvas.scale / elementWithCanvas.scale, elementWithCanvas.canvas.width / elementWithCanvas.scale, elementWithCanvas.canvas.height / elementWithCanvas.scale);\n\n if (false) {}\n }\n\n context.restore(); // Clear the nested element we appended to the DOM\n};\n\nconst renderSelectionElement = (element, context, appState, selectionColor) => {\n var _a;\n\n context.save();\n context.translate(element.x + appState.scrollX, element.y + appState.scrollY);\n context.fillStyle = (_a = appState.gridColor.Bold) !== null && _a !== void 0 ? _a : \"rgba(0, 0, 200, 0.04)\"; //zsviczian\n // render from 0.5px offset to get 1px wide line\n // https://stackoverflow.com/questions/7530593/html5-canvas-and-line-width/7531540#7531540\n // TODO can be be improved by offseting to the negative when user selects\n // from right to left\n\n const offset = 0.5 / appState.zoom.value;\n context.fillRect(offset, offset, element.width, element.height);\n context.lineWidth = 1 / appState.zoom.value;\n context.strokeStyle = selectionColor;\n context.strokeRect(offset, offset, element.width, element.height);\n context.restore();\n};\nconst renderElement = (element, elementsMap, allElementsMap, rc, context, renderConfig, appState) => {\n var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;\n\n const reduceAlphaForSelection = ((_a = appState.openDialog) === null || _a === void 0 ? void 0 : _a.name) === \"elementLinkSelector\" && !appState.selectedElementIds[element.id] && !appState.hoveredElementIds[element.id];\n context.globalAlpha = getRenderOpacity(element, (0,_frame__WEBPACK_IMPORTED_MODULE_10__.getContainingFrame)(element, elementsMap), renderConfig.elementsPendingErasure, renderConfig.pendingFlowchartNodes, reduceAlphaForSelection ? _excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_REDUCED_GLOBAL_ALPHA : 1);\n\n switch (element.type) {\n case \"magicframe\":\n case \"frame\":\n {\n if ( //zsviczian\n appState.frameRendering.enabled && appState.frameRendering.outline && !(!appState.frameRendering.markerEnabled && element.frameRole === \"marker\")) {\n context.save();\n context.translate(element.x + appState.scrollX, element.y + appState.scrollY);\n context.fillStyle = (_f = (_d = (_c = (_b = element.customData) === null || _b === void 0 ? void 0 : _b.frameColor) === null || _c === void 0 ? void 0 : _c.fill) !== null && _d !== void 0 ? _d : (_e = appState === null || appState === void 0 ? void 0 : appState.frameColor) === null || _e === void 0 ? void 0 : _e.fill) !== null && _f !== void 0 ? _f : \"rgba(0, 0, 200, 0.04)\"; //zsviczian\n\n context.lineWidth = _excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.FRAME_STYLE.strokeWidth / appState.zoom.value;\n context.strokeStyle = (_l = (_j = (_h = (_g = element.customData) === null || _g === void 0 ? void 0 : _g.frameColor) === null || _h === void 0 ? void 0 : _h.stroke) !== null && _j !== void 0 ? _j : (_k = appState === null || appState === void 0 ? void 0 : appState.frameColor) === null || _k === void 0 ? void 0 : _k.stroke) !== null && _l !== void 0 ? _l : _excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.FRAME_STYLE.strokeColor; //zsviczian\n // TODO change later to only affect AI frames\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isMagicFrameElement)(element)) {\n context.strokeStyle = appState.theme === _excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.THEME.LIGHT ? \"#7affd7\" : \"#1d8264\";\n } //zsviczian\n\n\n if (element.frameRole === \"marker\") {\n const dash = 8 / appState.zoom.value;\n const gap = 6 / appState.zoom.value;\n context.setLineDash([dash, gap]);\n }\n\n if (_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.FRAME_STYLE.radius && context.roundRect && element.frameRole !== \"marker\") {\n //zsviczian\n context.beginPath();\n context.roundRect(0, 0, element.width, element.height, _excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.FRAME_STYLE.radius / appState.zoom.value);\n context.stroke();\n context.closePath();\n } else {\n context.strokeRect(0, 0, element.width, element.height);\n }\n\n context.restore();\n }\n\n break;\n }\n\n case \"freedraw\":\n {\n // TODO investigate if we can do this in situ. Right now we need to call\n // beforehand because math helpers (such as getElementAbsoluteCoords)\n // rely on existing shapes\n _shape__WEBPACK_IMPORTED_MODULE_12__.ShapeCache.generateElementShape(element, null);\n\n if (renderConfig.isExporting) {\n const [x1, y1, x2, y2] = (0,_bounds__WEBPACK_IMPORTED_MODULE_4__.getElementAbsoluteCoords)(element, elementsMap);\n const cx = (x1 + x2) / 2 + appState.scrollX;\n const cy = (y1 + y2) / 2 + appState.scrollY;\n const shiftX = (x2 - x1) / 2 - (element.x - x1);\n const shiftY = (y2 - y1) / 2 - (element.y - y1);\n context.save();\n context.translate(cx, cy);\n context.rotate(element.angle);\n context.translate(-shiftX, -shiftY);\n drawElementOnCanvas(element, rc, context, renderConfig);\n context.restore();\n } else {\n const elementWithCanvas = generateElementWithCanvas(element, allElementsMap, renderConfig, appState);\n\n if (!elementWithCanvas) {\n return;\n }\n\n drawElementFromCanvas(elementWithCanvas, context, renderConfig, appState, allElementsMap);\n }\n\n break;\n }\n\n case \"rectangle\":\n case \"diamond\":\n case \"ellipse\":\n case \"line\":\n case \"arrow\":\n case \"image\":\n case \"text\":\n case \"iframe\":\n case \"embeddable\":\n {\n // TODO investigate if we can do this in situ. Right now we need to call\n // beforehand because math helpers (such as getElementAbsoluteCoords)\n // rely on existing shapes\n _shape__WEBPACK_IMPORTED_MODULE_12__.ShapeCache.generateElementShape(element, renderConfig);\n\n if (renderConfig.isExporting) {\n const [x1, y1, x2, y2] = (0,_bounds__WEBPACK_IMPORTED_MODULE_4__.getElementAbsoluteCoords)(element, elementsMap);\n const cx = (x1 + x2) / 2 + appState.scrollX;\n const cy = (y1 + y2) / 2 + appState.scrollY;\n let shiftX = (x2 - x1) / 2 - (element.x - x1);\n let shiftY = (y2 - y1) / 2 - (element.y - y1);\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isTextElement)(element)) {\n const container = (0,_textElement__WEBPACK_IMPORTED_MODULE_7__.getContainerElement)(element, elementsMap);\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isArrowElement)(container)) {\n const boundTextCoords = _linearElementEditor__WEBPACK_IMPORTED_MODULE_6__.LinearElementEditor.getBoundTextElementPosition(container, element, elementsMap);\n shiftX = (x2 - x1) / 2 - (boundTextCoords.x - x1);\n shiftY = (y2 - y1) / 2 - (boundTextCoords.y - y1);\n }\n }\n\n context.save();\n context.translate(cx, cy);\n\n if (shouldResetImageFilter(element, renderConfig, appState)) {\n context.filter = \"none\";\n }\n\n const boundTextElement = (0,_textElement__WEBPACK_IMPORTED_MODULE_7__.getBoundTextElement)(element, elementsMap);\n\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isArrowElement)(element) && boundTextElement) {\n const tempCanvas = document.createElement(\"canvas\");\n const tempCanvasContext = tempCanvas.getContext(\"2d\"); // Take max dimensions of arrow canvas so that when canvas is rotated\n // the arrow doesn't get clipped\n\n const maxDim = Math.max((0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.distance)(x1, x2), (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.distance)(y1, y2));\n const padding = getCanvasPadding(element);\n tempCanvas.width = maxDim * appState.exportScale + padding * 10 * appState.exportScale;\n tempCanvas.height = maxDim * appState.exportScale + padding * 10 * appState.exportScale;\n tempCanvasContext.translate(tempCanvas.width / 2, tempCanvas.height / 2);\n tempCanvasContext.scale(appState.exportScale, appState.exportScale); // Shift the canvas to left most point of the arrow\n\n shiftX = element.width / 2 - (element.x - x1);\n shiftY = element.height / 2 - (element.y - y1);\n tempCanvasContext.rotate(element.angle);\n const tempRc = roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_0__[\"default\"].canvas(tempCanvas);\n tempCanvasContext.translate(-shiftX, -shiftY);\n drawElementOnCanvas(element, tempRc, tempCanvasContext, renderConfig);\n tempCanvasContext.translate(shiftX, shiftY);\n tempCanvasContext.rotate(-element.angle); // Shift the canvas to center of bound text\n\n const [,,,, boundTextCx, boundTextCy] = (0,_bounds__WEBPACK_IMPORTED_MODULE_4__.getElementAbsoluteCoords)(boundTextElement, elementsMap);\n const boundTextShiftX = (x1 + x2) / 2 - boundTextCx;\n const boundTextShiftY = (y1 + y2) / 2 - boundTextCy;\n tempCanvasContext.translate(-boundTextShiftX, -boundTextShiftY); // Clear the bound text area\n\n tempCanvasContext.clearRect(-boundTextElement.width / 2, -boundTextElement.height / 2, boundTextElement.width, boundTextElement.height);\n context.scale(1 / appState.exportScale, 1 / appState.exportScale);\n context.drawImage(tempCanvas, -tempCanvas.width / 2, -tempCanvas.height / 2, tempCanvas.width, tempCanvas.height);\n } else {\n context.rotate(element.angle);\n\n if (element.type === \"image\") {\n // note: scale must be applied *after* rotating\n context.scale(element.scale[0], element.scale[1]);\n }\n\n context.translate(-shiftX, -shiftY);\n drawElementOnCanvas(element, rc, context, renderConfig);\n }\n\n context.restore(); // not exporting → optimized rendering (cache & render from element\n // canvases)\n } else {\n const elementWithCanvas = generateElementWithCanvas(element, allElementsMap, renderConfig, appState);\n\n if (!elementWithCanvas) {\n return;\n }\n\n const currentImageSmoothingStatus = context.imageSmoothingEnabled;\n\n if ( // do not disable smoothing during zoom as blurry shapes look better\n // on low resolution (while still zooming in) than sharp ones\n !(appState === null || appState === void 0 ? void 0 : appState.shouldCacheIgnoreZoom) && ( // angle is 0 -> always disable smoothing\n !element.angle || // or check if angle is a right angle in which case we can still\n // disable smoothing without adversely affecting the result\n // We need less-than comparison because of FP artihmetic\n (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_2__.isRightAngleRads)(element.angle))) {\n // Disabling smoothing makes output much sharper, especially for\n // text. Unless for non-right angles, where the aliasing is really\n // terrible on Chromium.\n //\n // Note that `context.imageSmoothingQuality=\"high\"` has almost\n // zero effect.\n //\n context.imageSmoothingEnabled = false;\n }\n\n if (element.id === appState.croppingElementId && (0,_typeChecks__WEBPACK_IMPORTED_MODULE_9__.isImageElement)(elementWithCanvas.element) && elementWithCanvas.element.crop !== null) {\n context.save();\n context.globalAlpha = 0.1;\n const uncroppedElementCanvas = generateElementCanvas((0,_cropElement__WEBPACK_IMPORTED_MODULE_5__.getUncroppedImageElement)(elementWithCanvas.element, elementsMap), allElementsMap, appState.zoom, renderConfig, appState);\n\n if (uncroppedElementCanvas) {\n drawElementFromCanvas(uncroppedElementCanvas, context, renderConfig, appState, allElementsMap);\n }\n\n context.restore();\n }\n\n drawElementFromCanvas(elementWithCanvas, context, renderConfig, appState, allElementsMap); // reset\n\n context.imageSmoothingEnabled = currentImageSmoothingStatus;\n }\n\n break;\n }\n\n default:\n {\n // @ts-ignore\n throw new Error(`Unimplemented type ${element.type}`);\n }\n }\n\n context.globalAlpha = 1;\n};\nconst pathsCache = new WeakMap([]);\nfunction generateFreeDrawShape(element) {\n const svgPathData = getFreeDrawSvgPath(element);\n const path = new Path2D(svgPathData);\n pathsCache.set(element, path);\n return path;\n}\nfunction getFreeDrawPath2D(element) {\n return pathsCache.get(element);\n}\nfunction getFreeDrawSvgPath(element) {\n return getSvgPathFromStroke(getFreedrawOutlinePoints(element));\n}\nfunction getFreedrawOutlineAsSegments(element, points, elementsMap) {\n const bounds = (0,_bounds__WEBPACK_IMPORTED_MODULE_4__.getElementBounds)(Object.assign(Object.assign({}, element), {\n angle: 0\n }), elementsMap);\n const center = (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_2__.pointFrom)((bounds[0] + bounds[2]) / 2, (bounds[1] + bounds[3]) / 2);\n (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_3__.invariant)(points.length >= 2, \"Freepath outline must have at least 2 points\");\n return points.slice(2).reduce((acc, curr) => {\n acc.push((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_2__.lineSegment)(acc[acc.length - 1][1], (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_2__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_2__.pointFrom)(curr[0] + element.x, curr[1] + element.y), center, element.angle)));\n return acc;\n }, [(0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_2__.lineSegment)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_2__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_2__.pointFrom)(points[0][0] + element.x, points[0][1] + element.y), center, element.angle), (0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_2__.pointRotateRads)((0,_excalidraw_math__WEBPACK_IMPORTED_MODULE_2__.pointFrom)(points[1][0] + element.x, points[1][1] + element.y), center, element.angle))]);\n}\nfunction getFreedrawOutlinePoints(element) {\n var _a, _b, _c, _d, _e, _f, _g, _h; // If input points are empty (should they ever be?) return a dot\n\n\n const inputPoints = element.simulatePressure ? element.points : element.points.length ? element.points.map(([x, y], i) => [x, y, element.pressures[i]]) : [[0, 0, 0.5]]; // Consider changing the options for simulated pressure vs real pressure\n\n const customOptions = (_b = (_a = element.customData) === null || _a === void 0 ? void 0 : _a.strokeOptions) === null || _b === void 0 ? void 0 : _b.options; //zsviczian\n\n const options = customOptions //zsviczian\n ? Object.assign(Object.assign(Object.assign(Object.assign({}, customOptions), {\n simulatePressure: (_c = customOptions.simulatePressure) !== null && _c !== void 0 ? _c : element.simulatePressure,\n size: element.strokeWidth * 4.25,\n last: true,\n easing: (_d = _easingFunctions__WEBPACK_IMPORTED_MODULE_13__[\"default\"][customOptions.easing]) !== null && _d !== void 0 ? _d : t => t\n }), ((_e = customOptions.start) === null || _e === void 0 ? void 0 : _e.easing) ? {\n start: Object.assign(Object.assign({}, customOptions.start), {\n easing: (_f = _easingFunctions__WEBPACK_IMPORTED_MODULE_13__[\"default\"][customOptions.start.easing]) !== null && _f !== void 0 ? _f : t => t\n })\n } : {\n start: customOptions.start\n }), ((_g = customOptions.end) === null || _g === void 0 ? void 0 : _g.easing) ? {\n end: Object.assign(Object.assign({}, customOptions.end), {\n easing: (_h = _easingFunctions__WEBPACK_IMPORTED_MODULE_13__[\"default\"][customOptions.end.easing]) !== null && _h !== void 0 ? _h : t => t\n })\n } : {\n end: customOptions.end\n }) : {\n simulatePressure: element.simulatePressure,\n size: element.strokeWidth * 4.25,\n thinning: 0.6,\n smoothing: 0.5,\n streamline: 0.5,\n easing: _easingFunctions__WEBPACK_IMPORTED_MODULE_13__[\"default\"].easeOutSine,\n last: true\n };\n return (0,perfect_freehand__WEBPACK_IMPORTED_MODULE_1__.getStroke)(inputPoints, options);\n}\n\nfunction med(A, B) {\n return [(A[0] + B[0]) / 2, (A[1] + B[1]) / 2];\n} // Trim SVG path data so number are each two decimal points. This\n// improves SVG exports, and prevents rendering errors on points\n// with long decimals.\n\n\nconst TO_FIXED_PRECISION = /(\\s?[A-Z]?,?-?[0-9]*\\.[0-9]{0,2})(([0-9]|e|-)*)/g;\n\nfunction getSvgPathFromStroke(points) {\n if (!points.length) {\n return \"\";\n }\n\n const max = points.length - 1;\n return points.reduce((acc, point, i, arr) => {\n if (i === max) {\n acc.push(point, med(point, arr[0]), \"L\", arr[0], \"Z\");\n } else {\n acc.push(point, med(point, arr[i + 1]));\n }\n\n return acc;\n }, [\"M\", points[0], \"Q\"]).join(\" \").replace(TO_FIXED_PRECISION, \"$1\");\n}\n\n//# sourceURL=webpack://ExcalidrawLib/../element/src/renderElement.ts?");
13425
13425
 
13426
13426
  /***/ }),
13427
13427
 
@@ -14246,7 +14246,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
14246
14246
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
14247
14247
 
14248
14248
  "use strict";
14249
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ trackEvent: () => (/* binding */ trackEvent)\n/* harmony export */ });\n/* harmony import */ var _excalidraw_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @excalidraw/common */ \"../common/src/index.ts\");\n// place here categories that you want to track. We want to track just a\n // small subset of categories at a given time.\n\nconst ALLOWED_CATEGORIES_TO_TRACK = new Set([\"command_palette\", \"export\"]);\nconst trackEvent = (category, action, label, value) => {\n try {\n if (typeof window === \"undefined\" || ({\"MODE\":\"development\",\"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_PLUS_LP\":\"https://plus.excalidraw.com\",\"VITE_APP_PLUS_APP\":\"http://localhost:3000\",\"VITE_APP_AI_BACKEND\":\"http://localhost:3015\",\"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_DISABLE_LIVE_RELOAD\":\"\",\"VITE_APP_ENABLE_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_APP_ENABLE_PWA\":\"false\",\"VITE_APP_PLUS_EXPORT_PUBLIC_KEY\":\"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm2g5T+Rub6Kbf1Mf57t0\\n7r2zeHuVg4dla3r5ryXMswtzz6x767octl6oLThn33mQsPSy3GKglFZoCTXJR4ij\\nba8SxB04sL/N8eRrKja7TFWjCVtRwTTfyy771NYYNFVJclkxHyE5qw4m27crHF1y\\nUNWEjuqNMi/lwAErS9fFa2oJlWyT8U7zzv/5kQREkxZI6y9v0AF3qcbsy2731FnD\\ns9ChJvOUW9toIab2gsIdrKW8ZNpu084ZFVKb6LNjvIXI1Se4oMTHeszXzNptzlot\\nkdxxjOoaQMAyfljFSot1F1FlU6MQlag7UnFGvFjRHN1JI5q4K+n3a67DX+TMyRqS\\nHQIDAQAB\",\"VITE_APP_DISABLE_PREVENT_UNLOAD\":\"\",\"VITE_PKG_NAME\":\"@zsviczian/excalidraw\",\"VITE_PKG_VERSION\":\"0.18.0-53\",\"VITE_IS_EXCALIDRAW_NPM_PACKAGE\":true}).VITE_WORKER_ID || \"true\" !== \"true\") {\n return;\n }\n\n if (!ALLOWED_CATEGORIES_TO_TRACK.has(category)) {\n return;\n }\n\n if ((0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.isDevEnv)()) {\n // comment out to debug in dev\n return;\n }\n\n if (true) {\n console.info(\"trackEvent\", {\n category,\n action,\n label,\n value\n });\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?");
14249
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ trackEvent: () => (/* binding */ trackEvent)\n/* harmony export */ });\n/* harmony import */ var _excalidraw_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @excalidraw/common */ \"../common/src/index.ts\");\n// place here categories that you want to track. We want to track just a\n // small subset of categories at a given time.\n\nconst ALLOWED_CATEGORIES_TO_TRACK = new Set([\"command_palette\", \"export\"]);\nconst trackEvent = (category, action, label, value) => {\n try {\n if (typeof window === \"undefined\" || ({\"MODE\":\"development\",\"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_PLUS_LP\":\"https://plus.excalidraw.com\",\"VITE_APP_PLUS_APP\":\"http://localhost:3000\",\"VITE_APP_AI_BACKEND\":\"http://localhost:3015\",\"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_DISABLE_LIVE_RELOAD\":\"\",\"VITE_APP_ENABLE_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_APP_ENABLE_PWA\":\"false\",\"VITE_APP_PLUS_EXPORT_PUBLIC_KEY\":\"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm2g5T+Rub6Kbf1Mf57t0\\n7r2zeHuVg4dla3r5ryXMswtzz6x767octl6oLThn33mQsPSy3GKglFZoCTXJR4ij\\nba8SxB04sL/N8eRrKja7TFWjCVtRwTTfyy771NYYNFVJclkxHyE5qw4m27crHF1y\\nUNWEjuqNMi/lwAErS9fFa2oJlWyT8U7zzv/5kQREkxZI6y9v0AF3qcbsy2731FnD\\ns9ChJvOUW9toIab2gsIdrKW8ZNpu084ZFVKb6LNjvIXI1Se4oMTHeszXzNptzlot\\nkdxxjOoaQMAyfljFSot1F1FlU6MQlag7UnFGvFjRHN1JI5q4K+n3a67DX+TMyRqS\\nHQIDAQAB\",\"VITE_APP_DISABLE_PREVENT_UNLOAD\":\"\",\"VITE_PKG_NAME\":\"@zsviczian/excalidraw\",\"VITE_PKG_VERSION\":\"0.18.0-54\",\"VITE_IS_EXCALIDRAW_NPM_PACKAGE\":true}).VITE_WORKER_ID || \"true\" !== \"true\") {\n return;\n }\n\n if (!ALLOWED_CATEGORIES_TO_TRACK.has(category)) {\n return;\n }\n\n if ((0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.isDevEnv)()) {\n // comment out to debug in dev\n return;\n }\n\n if (true) {\n console.info(\"trackEvent\", {\n category,\n action,\n label,\n value\n });\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?");
14250
14250
 
14251
14251
  /***/ }),
14252
14252
 
@@ -15104,7 +15104,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n// extracted by mini-css-extr
15104
15104
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
15105
15105
 
15106
15106
  "use strict";
15107
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ HintViewer: () => (/* binding */ HintViewer)\n/* harmony export */ });\n/* harmony import */ var _excalidraw_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @excalidraw/common */ \"../common/src/index.ts\");\n/* harmony import */ var _excalidraw_element__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @excalidraw/element */ \"../element/src/index.ts\");\n/* harmony import */ var _i18n__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../i18n */ \"./i18n.ts\");\n/* harmony import */ var _shortcut__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../shortcut */ \"./shortcut.ts\");\n/* harmony import */ var _appState__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../appState */ \"./appState.ts\");\n/* harmony import */ var _snapping__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../snapping */ \"./snapping.ts\");\n/* harmony import */ var _HintViewer_scss__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./HintViewer.scss */ \"./components/HintViewer.scss\");\n\n\n\n\n\n\n\n\n\nconst getTaggedShortcutKey = key => Array.isArray(key) ? `<kbd>${key.map(_shortcut__WEBPACK_IMPORTED_MODULE_3__.getShortcutKey).join(\" + \")}</kbd>` : `<kbd>${(0,_shortcut__WEBPACK_IMPORTED_MODULE_3__.getShortcutKey)(key)}</kbd>`;\n\nconst getHints = ({\n appState,\n isMobile,\n editorInterface,\n app\n}) => {\n var _a, _b, _c, _d;\n\n const {\n activeTool,\n isResizing,\n isRotating,\n lastPointerDownWith\n } = appState;\n const multiMode = appState.multiElement !== null;\n\n if (((_a = appState.openSidebar) === null || _a === void 0 ? void 0 : _a.name) === _excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.DEFAULT_SIDEBAR.name && appState.openSidebar.tab === _excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.CANVAS_SEARCH_TAB && ((_b = appState.searchMatches) === null || _b === void 0 ? void 0 : _b.matches.length)) {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.dismissSearch\", {\n shortcut: getTaggedShortcutKey(\"Escape\")\n });\n }\n\n if (appState.openSidebar && !editorInterface.canFitSidebar) {\n return null;\n }\n\n if ((0,_appState__WEBPACK_IMPORTED_MODULE_4__.isEraserActive)(appState)) {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.eraserRevert\", {\n shortcut: getTaggedShortcutKey(\"Alt\")\n });\n }\n\n if (activeTool.type === \"arrow\" || activeTool.type === \"line\") {\n if (multiMode) {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.linearElementMulti\", {\n shortcut_1: getTaggedShortcutKey(\"Escape\"),\n shortcut_2: getTaggedShortcutKey(\"Enter\")\n });\n }\n\n if (activeTool.type === \"arrow\") {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.arrowTool\", {\n shortcut: getTaggedShortcutKey(\"A\")\n });\n }\n\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.linearElement\");\n }\n\n if (activeTool.type === \"freedraw\") {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.freeDraw\");\n }\n\n if (activeTool.type === \"text\") {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.text\");\n }\n\n if (activeTool.type === \"embeddable\") {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.embeddable\");\n }\n\n const selectedElements = app.scene.getSelectedElements(appState);\n\n if (isResizing && lastPointerDownWith === \"mouse\" && selectedElements.length === 1) {\n const targetElement = selectedElements[0];\n\n if ((0,_excalidraw_element__WEBPACK_IMPORTED_MODULE_1__.isLinearElement)(targetElement) && targetElement.points.length === 2) {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.lockAngle\", {\n shortcut: getTaggedShortcutKey(\"Shift\")\n });\n }\n\n return (0,_excalidraw_element__WEBPACK_IMPORTED_MODULE_1__.isImageElement)(targetElement) ? (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.resizeImage\", {\n shortcut_1: getTaggedShortcutKey(\"Shift\"),\n shortcut_2: getTaggedShortcutKey(\"Alt\")\n }) : (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.resize\", {\n shortcut_1: getTaggedShortcutKey(\"Shift\"),\n shortcut_2: getTaggedShortcutKey(\"Alt\")\n });\n }\n\n if (isRotating && lastPointerDownWith === \"mouse\") {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.rotate\", {\n shortcut: getTaggedShortcutKey(\"Shift\")\n });\n }\n\n if (selectedElements.length === 1 && (0,_excalidraw_element__WEBPACK_IMPORTED_MODULE_1__.isTextElement)(selectedElements[0])) {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.text_selected\", {\n shortcut: getTaggedShortcutKey(\"Enter\")\n });\n }\n\n if (appState.editingTextElement) {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.text_editing\", {\n shortcut_1: getTaggedShortcutKey(\"Escape\"),\n shortcut_2: getTaggedShortcutKey([\"CtrlOrCmd\", \"Enter\"])\n });\n }\n\n if (appState.croppingElementId) {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.leaveCropEditor\", {\n shortcut_1: getTaggedShortcutKey(\"Enter\"),\n shortcut_2: getTaggedShortcutKey(\"Escape\")\n });\n }\n\n if (selectedElements.length === 1 && (0,_excalidraw_element__WEBPACK_IMPORTED_MODULE_1__.isImageElement)(selectedElements[0])) {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.enterCropEditor\", {\n shortcut: getTaggedShortcutKey(\"Enter\")\n });\n }\n\n if (activeTool.type === \"selection\") {\n if (appState.selectionElement && !selectedElements.length && !appState.editingTextElement && !((_c = appState.selectedLinearElement) === null || _c === void 0 ? void 0 : _c.isEditing)) {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.deepBoxSelect\", {\n shortcut: getTaggedShortcutKey(\"CtrlOrCmd\")\n });\n }\n\n if ((0,_snapping__WEBPACK_IMPORTED_MODULE_5__.isGridModeEnabled)(app) && appState.selectedElementsAreBeingDragged) {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.disableSnapping\", {\n shortcut: getTaggedShortcutKey(\"CtrlOrCmd\")\n });\n }\n\n if (!selectedElements.length && !isMobile) {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.canvasPanning\", {\n shortcut_1: getTaggedShortcutKey((0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"keys.mmb\")),\n shortcut_2: getTaggedShortcutKey(\"Space\")\n });\n }\n\n if (selectedElements.length === 1) {\n if ((0,_excalidraw_element__WEBPACK_IMPORTED_MODULE_1__.isLinearElement)(selectedElements[0])) {\n if ((_d = appState.selectedLinearElement) === null || _d === void 0 ? void 0 : _d.isEditing) {\n return appState.selectedLinearElement.selectedPointsIndices ? (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.lineEditor_pointSelected\", {\n shortcut_1: getTaggedShortcutKey(\"Delete\"),\n shortcut_2: getTaggedShortcutKey([\"CtrlOrCmd\", \"D\"])\n }) : (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.lineEditor_nothingSelected\", {\n shortcut_1: getTaggedShortcutKey(\"Shift\"),\n shortcut_2: getTaggedShortcutKey(\"Alt\")\n });\n }\n\n return (0,_excalidraw_element__WEBPACK_IMPORTED_MODULE_1__.isLineElement)(selectedElements[0]) ? (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.lineEditor_line_info\", {\n shortcut: getTaggedShortcutKey(\"Enter\")\n }) : (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.lineEditor_info\", {\n shortcut_1: getTaggedShortcutKey(\"CtrlOrCmd\"),\n shortcut_2: getTaggedShortcutKey([\"CtrlOrCmd\", \"Enter\"])\n });\n }\n\n if (!appState.newElement && !appState.selectedElementsAreBeingDragged && (0,_excalidraw_element__WEBPACK_IMPORTED_MODULE_1__.isTextBindableContainer)(selectedElements[0])) {\n const bindTextToElement = (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.bindTextToElement\", {\n shortcut: getTaggedShortcutKey(\"Enter\")\n });\n const createFlowchart = (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.createFlowchart\", {\n shortcut: getTaggedShortcutKey([\"CtrlOrCmd\", \"↑↓\"])\n });\n\n if ((0,_excalidraw_element__WEBPACK_IMPORTED_MODULE_1__.isFlowchartNodeElement)(selectedElements[0])) {\n if ((0,_excalidraw_element__WEBPACK_IMPORTED_MODULE_1__.isNodeInFlowchart)(selectedElements[0], app.scene.getNonDeletedElementsMap())) {\n return [bindTextToElement, createFlowchart];\n }\n\n return [bindTextToElement, createFlowchart];\n }\n\n return bindTextToElement;\n }\n }\n }\n\n return null;\n};\n\nconst HintViewer = ({\n appState,\n isMobile,\n editorInterface,\n app\n}) => {\n const hints = getHints({\n appState,\n isMobile,\n editorInterface,\n app\n });\n\n if (!hints) {\n return null;\n }\n\n const hint = Array.isArray(hints) ? hints.map(hint => hint.replace(/\\. ?$/, \"\")).join(\", \") : hints;\n const hintJSX = hint.split(/(<kbd>[^<]+<\\/kbd>)/g).map((part, index) => {\n if (index % 2 === 1) {\n const shortcutMatch = part[0] === \"<\" && part.match(/^<kbd>([^<]+)<\\/kbd>$/);\n return React.createElement(\"kbd\", {\n key: index\n }, shortcutMatch ? shortcutMatch[1] : part);\n }\n\n return part;\n });\n return React.createElement(\"div\", {\n className: \"HintViewer\"\n }, React.createElement(\"span\", null, hintJSX));\n};\n\n//# sourceURL=webpack://ExcalidrawLib/./components/HintViewer.tsx?");
15107
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ HintViewer: () => (/* binding */ HintViewer)\n/* harmony export */ });\n/* harmony import */ var _excalidraw_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @excalidraw/common */ \"../common/src/index.ts\");\n/* harmony import */ var _excalidraw_element__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @excalidraw/element */ \"../element/src/index.ts\");\n/* harmony import */ var _i18n__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../i18n */ \"./i18n.ts\");\n/* harmony import */ var _shortcut__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../shortcut */ \"./shortcut.ts\");\n/* harmony import */ var _appState__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../appState */ \"./appState.ts\");\n/* harmony import */ var _snapping__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../snapping */ \"./snapping.ts\");\n/* harmony import */ var _HintViewer_scss__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./HintViewer.scss */ \"./components/HintViewer.scss\");\n\n\n\n\n\n\n\n\n\nconst getTaggedShortcutKey = key => Array.isArray(key) ? `<kbd>${key.map(_shortcut__WEBPACK_IMPORTED_MODULE_3__.getShortcutKey).join(\" + \")}</kbd>` : `<kbd>${(0,_shortcut__WEBPACK_IMPORTED_MODULE_3__.getShortcutKey)(key)}</kbd>`;\n\nconst getHints = ({\n appState,\n isMobile,\n editorInterface,\n app\n}) => {\n var _a, _b, _c, _d, _e, _f;\n\n const {\n activeTool,\n isResizing,\n isRotating,\n lastPointerDownWith\n } = appState;\n const multiMode = appState.multiElement !== null;\n\n if (((_a = appState.openSidebar) === null || _a === void 0 ? void 0 : _a.name) === _excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.DEFAULT_SIDEBAR.name && appState.openSidebar.tab === _excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.CANVAS_SEARCH_TAB && ((_b = appState.searchMatches) === null || _b === void 0 ? void 0 : _b.matches.length)) {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.dismissSearch\", {\n shortcut: getTaggedShortcutKey(\"Escape\")\n });\n }\n\n if (appState.openSidebar && !editorInterface.canFitSidebar) {\n return null;\n }\n\n if ((0,_appState__WEBPACK_IMPORTED_MODULE_4__.isEraserActive)(appState)) {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.eraserRevert\", {\n shortcut: getTaggedShortcutKey(\"Alt\")\n });\n }\n\n const selectedElements = app.scene.getSelectedElements(appState); // creating or dragging arrow point\n\n if (((_c = appState.selectedLinearElement) === null || _c === void 0 ? void 0 : _c.isDragging) && ((_d = selectedElements[0]) === null || _d === void 0 ? void 0 : _d.type) === \"arrow\") {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.arrowBindModifiers\", {\n shortcut_1: getTaggedShortcutKey(\"Ctrl\"),\n shortcut_2: getTaggedShortcutKey(\"Alt\")\n });\n }\n\n if (activeTool.type === \"arrow\" || activeTool.type === \"line\") {\n if (multiMode) {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.linearElementMulti\", {\n shortcut_1: getTaggedShortcutKey(\"Escape\"),\n shortcut_2: getTaggedShortcutKey(\"Enter\")\n });\n }\n\n if (activeTool.type === \"arrow\") {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.arrowTool\", {\n shortcut: getTaggedShortcutKey(\"A\")\n });\n }\n\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.linearElement\");\n }\n\n if (activeTool.type === \"freedraw\") {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.freeDraw\");\n }\n\n if (activeTool.type === \"text\") {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.text\");\n }\n\n if (activeTool.type === \"embeddable\") {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.embeddable\");\n }\n\n if (isResizing && lastPointerDownWith === \"mouse\" && selectedElements.length === 1) {\n const targetElement = selectedElements[0];\n\n if ((0,_excalidraw_element__WEBPACK_IMPORTED_MODULE_1__.isLinearElement)(targetElement) && targetElement.points.length === 2) {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.lockAngle\", {\n shortcut: getTaggedShortcutKey(\"Shift\")\n });\n }\n\n return (0,_excalidraw_element__WEBPACK_IMPORTED_MODULE_1__.isImageElement)(targetElement) ? (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.resizeImage\", {\n shortcut_1: getTaggedShortcutKey(\"Shift\"),\n shortcut_2: getTaggedShortcutKey(\"Alt\")\n }) : (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.resize\", {\n shortcut_1: getTaggedShortcutKey(\"Shift\"),\n shortcut_2: getTaggedShortcutKey(\"Alt\")\n });\n }\n\n if (isRotating && lastPointerDownWith === \"mouse\") {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.rotate\", {\n shortcut: getTaggedShortcutKey(\"Shift\")\n });\n }\n\n if (selectedElements.length === 1 && (0,_excalidraw_element__WEBPACK_IMPORTED_MODULE_1__.isTextElement)(selectedElements[0])) {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.text_selected\", {\n shortcut: getTaggedShortcutKey(\"Enter\")\n });\n }\n\n if (appState.editingTextElement) {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.text_editing\", {\n shortcut_1: getTaggedShortcutKey(\"Escape\"),\n shortcut_2: getTaggedShortcutKey([\"CtrlOrCmd\", \"Enter\"])\n });\n }\n\n if (appState.croppingElementId) {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.leaveCropEditor\", {\n shortcut_1: getTaggedShortcutKey(\"Enter\"),\n shortcut_2: getTaggedShortcutKey(\"Escape\")\n });\n }\n\n if (selectedElements.length === 1 && (0,_excalidraw_element__WEBPACK_IMPORTED_MODULE_1__.isImageElement)(selectedElements[0])) {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.enterCropEditor\", {\n shortcut: getTaggedShortcutKey(\"Enter\")\n });\n }\n\n if (activeTool.type === \"selection\") {\n if (appState.selectionElement && !selectedElements.length && !appState.editingTextElement && !((_e = appState.selectedLinearElement) === null || _e === void 0 ? void 0 : _e.isEditing)) {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.deepBoxSelect\", {\n shortcut: getTaggedShortcutKey(\"CtrlOrCmd\")\n });\n }\n\n if ((0,_snapping__WEBPACK_IMPORTED_MODULE_5__.isGridModeEnabled)(app) && appState.selectedElementsAreBeingDragged) {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.disableSnapping\", {\n shortcut: getTaggedShortcutKey(\"CtrlOrCmd\")\n });\n }\n\n if (!selectedElements.length && !isMobile) {\n return (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.canvasPanning\", {\n shortcut_1: getTaggedShortcutKey((0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"keys.mmb\")),\n shortcut_2: getTaggedShortcutKey(\"Space\")\n });\n }\n\n if (selectedElements.length === 1) {\n if ((0,_excalidraw_element__WEBPACK_IMPORTED_MODULE_1__.isLinearElement)(selectedElements[0])) {\n if ((_f = appState.selectedLinearElement) === null || _f === void 0 ? void 0 : _f.isEditing) {\n return appState.selectedLinearElement.selectedPointsIndices ? (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.lineEditor_pointSelected\", {\n shortcut_1: getTaggedShortcutKey(\"Delete\"),\n shortcut_2: getTaggedShortcutKey([\"CtrlOrCmd\", \"D\"])\n }) : (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.lineEditor_nothingSelected\", {\n shortcut_1: getTaggedShortcutKey(\"Shift\"),\n shortcut_2: getTaggedShortcutKey(\"Alt\")\n });\n }\n\n return (0,_excalidraw_element__WEBPACK_IMPORTED_MODULE_1__.isLineElement)(selectedElements[0]) ? (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.lineEditor_line_info\", {\n shortcut: getTaggedShortcutKey(\"Enter\")\n }) : (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.lineEditor_info\", {\n shortcut_1: getTaggedShortcutKey(\"CtrlOrCmd\"),\n shortcut_2: getTaggedShortcutKey([\"CtrlOrCmd\", \"Enter\"])\n });\n }\n\n if (!appState.newElement && !appState.selectedElementsAreBeingDragged && (0,_excalidraw_element__WEBPACK_IMPORTED_MODULE_1__.isTextBindableContainer)(selectedElements[0])) {\n const bindTextToElement = (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.bindTextToElement\", {\n shortcut: getTaggedShortcutKey(\"Enter\")\n });\n const createFlowchart = (0,_i18n__WEBPACK_IMPORTED_MODULE_2__.t)(\"hints.createFlowchart\", {\n shortcut: getTaggedShortcutKey([\"CtrlOrCmd\", \"↑↓\"])\n });\n\n if ((0,_excalidraw_element__WEBPACK_IMPORTED_MODULE_1__.isFlowchartNodeElement)(selectedElements[0])) {\n if ((0,_excalidraw_element__WEBPACK_IMPORTED_MODULE_1__.isNodeInFlowchart)(selectedElements[0], app.scene.getNonDeletedElementsMap())) {\n return [bindTextToElement, createFlowchart];\n }\n\n return [bindTextToElement, createFlowchart];\n }\n\n return bindTextToElement;\n }\n }\n }\n\n return null;\n};\n\nconst HintViewer = ({\n appState,\n isMobile,\n editorInterface,\n app\n}) => {\n const hints = getHints({\n appState,\n isMobile,\n editorInterface,\n app\n });\n\n if (!hints) {\n return null;\n }\n\n const hint = Array.isArray(hints) ? hints.map(hint => hint.replace(/\\. ?$/, \"\")).join(\", \") : hints;\n const hintJSX = hint.split(/(<kbd>[^<]+<\\/kbd>)/g).map((part, index) => {\n if (index % 2 === 1) {\n const shortcutMatch = part[0] === \"<\" && part.match(/^<kbd>([^<]+)<\\/kbd>$/);\n return React.createElement(\"kbd\", {\n key: index\n }, shortcutMatch ? shortcutMatch[1] : part);\n }\n\n return part;\n });\n return React.createElement(\"div\", {\n className: \"HintViewer\"\n }, React.createElement(\"span\", null, hintJSX));\n};\n\n//# sourceURL=webpack://ExcalidrawLib/./components/HintViewer.tsx?");
15108
15108
 
15109
15109
  /***/ }),
15110
15110
 
@@ -15236,7 +15236,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n// extracted by mini-css-extr
15236
15236
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
15237
15237
 
15238
15238
  "use strict";
15239
- 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 clsx__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! clsx */ \"../../node_modules/clsx/dist/clsx.m.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 _excalidraw_common__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @excalidraw/common */ \"../common/src/index.ts\");\n/* harmony import */ var _excalidraw_element__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @excalidraw/element */ \"../element/src/index.ts\");\n/* harmony import */ var _actions__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../actions */ \"./actions/index.ts\");\n/* harmony import */ var _analytics__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../analytics */ \"./analytics.ts\");\n/* harmony import */ var _appState__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../appState */ \"./appState.ts\");\n/* harmony import */ var _context_tunnels__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../context/tunnels */ \"./context/tunnels.ts\");\n/* harmony import */ var _context_ui_appState__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../context/ui-appState */ \"./context/ui-appState.ts\");\n/* harmony import */ var _editor_jotai__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../editor-jotai */ \"./editor-jotai.ts\");\n/* harmony import */ var _i18n__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../i18n */ \"./i18n.ts\");\n/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../scene */ \"./scene/index.ts\");\n/* harmony import */ var _Actions__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./Actions */ \"./components/Actions.tsx\");\n/* harmony import */ var _LoadingMessage__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./LoadingMessage */ \"./components/LoadingMessage.tsx\");\n/* harmony import */ var _LockButton__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./LockButton */ \"./components/LockButton.tsx\");\n/* harmony import */ var _MobileMenu__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./MobileMenu */ \"./components/MobileMenu.tsx\");\n/* harmony import */ var _PasteChartDialog__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./PasteChartDialog */ \"./components/PasteChartDialog.tsx\");\n/* harmony import */ var _Section__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./Section */ \"./components/Section.tsx\");\n/* harmony import */ var _Stack__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./Stack */ \"./components/Stack.tsx\");\n/* harmony import */ var _UserList__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./UserList */ \"./components/UserList.tsx\");\n/* harmony import */ var _PenModeButton__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./PenModeButton */ \"./components/PenModeButton.tsx\");\n/* harmony import */ var _footer_Footer__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./footer/Footer */ \"./components/footer/Footer.tsx\");\n/* harmony import */ var _Sidebar_Sidebar__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./Sidebar/Sidebar */ \"./components/Sidebar/Sidebar.tsx\");\n/* harmony import */ var _main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./main-menu/MainMenu */ \"./components/main-menu/MainMenu.tsx\");\n/* harmony import */ var _ActiveConfirmDialog__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./ActiveConfirmDialog */ \"./components/ActiveConfirmDialog.tsx\");\n/* harmony import */ var _App__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./App */ \"./components/App.tsx\");\n/* harmony import */ var _OverwriteConfirm_OverwriteConfirm__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./OverwriteConfirm/OverwriteConfirm */ \"./components/OverwriteConfirm/OverwriteConfirm.tsx\");\n/* harmony import */ var _icons__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./icons */ \"./components/icons.tsx\");\n/* harmony import */ var _DefaultSidebar__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./DefaultSidebar */ \"./components/DefaultSidebar.tsx\");\n/* harmony import */ var _TTDDialog_TTDDialog__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./TTDDialog/TTDDialog */ \"./components/TTDDialog/TTDDialog.tsx\");\n/* harmony import */ var _Stats__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./Stats */ \"./components/Stats/index.tsx\");\n/* harmony import */ var _ElementLinkDialog__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ./ElementLinkDialog */ \"./components/ElementLinkDialog.tsx\");\n/* harmony import */ var _ErrorDialog__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ./ErrorDialog */ \"./components/ErrorDialog.tsx\");\n/* harmony import */ var _EyeDropper__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ./EyeDropper */ \"./components/EyeDropper.tsx\");\n/* harmony import */ var _FixedSideContainer__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ./FixedSideContainer */ \"./components/FixedSideContainer.tsx\");\n/* harmony import */ var _HandButton__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ./HandButton */ \"./components/HandButton.tsx\");\n/* harmony import */ var _HelpDialog__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ./HelpDialog */ \"./components/HelpDialog.tsx\");\n/* harmony import */ var _HintViewer__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ./HintViewer */ \"./components/HintViewer.tsx\");\n/* harmony import */ var _ImageExportDialog__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! ./ImageExportDialog */ \"./components/ImageExportDialog.tsx\");\n/* harmony import */ var _Island__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(/*! ./Island */ \"./components/Island.tsx\");\n/* harmony import */ var _JSONExportDialog__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(/*! ./JSONExportDialog */ \"./components/JSONExportDialog.tsx\");\n/* harmony import */ var _LaserPointerButton__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(/*! ./LaserPointerButton */ \"./components/LaserPointerButton.tsx\");\n/* harmony import */ var _LayerUI_scss__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(/*! ./LayerUI.scss */ \"./components/LayerUI.scss\");\n/* harmony import */ var _Toolbar_scss__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(/*! ./Toolbar.scss */ \"./components/Toolbar.scss\");\n/* harmony import */ var _TrayMenu__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(/*! ./TrayMenu */ \"./components/TrayMenu.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\nconst DefaultMainMenu = ({\n UIOptions\n}) => {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"], {\n __fallback: true\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"].DefaultItems.LoadScene, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"].DefaultItems.SaveToActiveFile, null), UIOptions.canvasActions.export && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"].DefaultItems.Export, null), UIOptions.canvasActions.saveAsImage && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"].DefaultItems.SaveAsImage, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"].DefaultItems.SearchMenu, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"].DefaultItems.Help, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"].DefaultItems.ClearCanvas, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"].Separator, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"].Group, {\n title: \"Excalidraw links\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"].DefaultItems.Socials, null)), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"].Separator, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"].DefaultItems.ToggleTheme, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"].DefaultItems.ChangeCanvasBackground, null));\n};\n\nconst DefaultOverwriteConfirmDialog = () => {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_OverwriteConfirm_OverwriteConfirm__WEBPACK_IMPORTED_MODULE_26__.OverwriteConfirmDialog, {\n __fallback: true\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_OverwriteConfirm_OverwriteConfirm__WEBPACK_IMPORTED_MODULE_26__.OverwriteConfirmDialog.Actions.SaveToDisk, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_OverwriteConfirm_OverwriteConfirm__WEBPACK_IMPORTED_MODULE_26__.OverwriteConfirmDialog.Actions.ExportToImage, null));\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 renderTopLeftUI,\n renderTopRightUI,\n renderCustomStats,\n UIOptions,\n onExportImage,\n renderWelcomeScreen,\n children,\n app,\n isCollaborating,\n generateLinkForSelection\n}) => {\n var _a, _b, _c;\n\n const editorInterface = (0,_App__WEBPACK_IMPORTED_MODULE_25__.useEditorInterface)();\n const stylesPanelMode = (0,_App__WEBPACK_IMPORTED_MODULE_25__.useStylesPanelMode)();\n const isCompactStylesPanel = stylesPanelMode === \"compact\";\n const tunnels = (0,_context_tunnels__WEBPACK_IMPORTED_MODULE_7__.useInitializeTunnels)();\n const spacing = isCompactStylesPanel ? {\n menuTopGap: 4,\n toolbarColGap: 4,\n toolbarRowGap: 1,\n toolbarInnerRowGap: 0.5,\n islandPadding: 1,\n collabMarginLeft: 8\n } : {\n menuTopGap: 6,\n toolbarColGap: 4,\n toolbarRowGap: 1,\n toolbarInnerRowGap: 1,\n islandPadding: 1,\n collabMarginLeft: 8\n };\n const TunnelsJotaiProvider = tunnels.tunnelsJotai.Provider;\n const [eyeDropperState, setEyeDropperState] = (0,_editor_jotai__WEBPACK_IMPORTED_MODULE_9__.useAtom)(_EyeDropper__WEBPACK_IMPORTED_MODULE_33__.activeEyeDropperAtom);\n\n const renderJSONExportDialog = () => {\n if (!UIOptions.canvasActions.export) {\n return null;\n }\n\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_JSONExportDialog__WEBPACK_IMPORTED_MODULE_40__.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 var _a;\n\n if (!UIOptions.canvasActions.saveAsImage || ((_a = appState.openDialog) === null || _a === void 0 ? void 0 : _a.name) !== \"imageExport\") {\n return null;\n }\n\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_ImageExportDialog__WEBPACK_IMPORTED_MODULE_38__.ImageExportDialog, {\n elements: elements,\n appState: appState,\n files: files,\n actionManager: actionManager,\n onExportImage: onExportImage,\n onCloseRequest: () => setAppState({\n openDialog: null\n }),\n name: app.getName()\n });\n };\n\n const renderCanvasActions = () => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(\"div\", {\n style: {\n position: \"relative\"\n }\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(tunnels.MainMenuTunnel.Out, null), renderWelcomeScreen && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(tunnels.WelcomeScreenMenuHintTunnel.Out, null));\n\n const renderSelectedShapeActions = () => {\n const isCompactMode = isCompactStylesPanel;\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Section__WEBPACK_IMPORTED_MODULE_17__.Section, {\n heading: \"selectedShapeActions\",\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(\"selected-shape-actions zen-mode-transition\", {\n \"transition-left\": appState.zenModeEnabled\n })\n }, isCompactMode ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Island__WEBPACK_IMPORTED_MODULE_39__.Island, {\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(\"compact-shape-actions-island\"),\n padding: 0,\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 }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Actions__WEBPACK_IMPORTED_MODULE_12__.CompactShapeActions, {\n appState: appState,\n elementsMap: app.scene.getNonDeletedElementsMap(),\n renderAction: actionManager.renderAction,\n app: app,\n setAppState: setAppState\n })) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Island__WEBPACK_IMPORTED_MODULE_39__.Island, {\n className: _excalidraw_common__WEBPACK_IMPORTED_MODULE_2__.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 }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Actions__WEBPACK_IMPORTED_MODULE_12__.SelectedShapeActions, {\n appState: appState,\n elementsMap: app.scene.getNonDeletedElementsMap(),\n renderAction: actionManager.renderAction,\n app: app\n })));\n };\n\n const renderFixedSideContainer = () => {\n var _a, _b, _c, _d, _e, _f;\n\n const shouldRenderSelectedShapeActions = (0,_excalidraw_element__WEBPACK_IMPORTED_MODULE_3__.showSelectedShapeActions)(appState, elements);\n\n if (appState.viewModeEnabled) {\n return null;\n } //zsviczian\n\n\n const shouldShowStats = appState.stats.open && !appState.zenModeEnabled && !appState.viewModeEnabled && ((_a = appState.openDialog) === null || _a === void 0 ? void 0 : _a.name) !== \"elementLinkSelector\";\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_FixedSideContainer__WEBPACK_IMPORTED_MODULE_34__.FixedSideContainer, {\n side: \"top\",\n sidepanelOpen: !!appState.openSidebar\n /*zsviczian*/\n\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(\"div\", {\n className: \"App-menu App-menu_top\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Stack__WEBPACK_IMPORTED_MODULE_18__[\"default\"].Col, {\n gap: spacing.menuTopGap,\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(\"App-menu_top__left\")\n }, renderCanvasActions(), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(\"div\", {\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(\"selected-shape-actions-container\", {\n \"selected-shape-actions-container--compact\": isCompactStylesPanel\n })\n }, shouldRenderSelectedShapeActions && renderSelectedShapeActions())), !appState.viewModeEnabled && ((_b = appState.openDialog) === null || _b === void 0 ? void 0 : _b.name) !== \"elementLinkSelector\" && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Section__WEBPACK_IMPORTED_MODULE_17__.Section, {\n heading: \"shapes\",\n className: \"shapes-section\"\n }, heading => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(\"div\", {\n style: {\n position: \"relative\"\n }\n }, renderWelcomeScreen && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(tunnels.WelcomeScreenToolbarHintTunnel.Out, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Stack__WEBPACK_IMPORTED_MODULE_18__[\"default\"].Col, {\n gap: spacing.toolbarColGap,\n align: \"start\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Stack__WEBPACK_IMPORTED_MODULE_18__[\"default\"].Row, {\n gap: spacing.toolbarRowGap,\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(\"App-toolbar-container\", {\n \"zen-mode\": appState.zenModeEnabled\n })\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Island__WEBPACK_IMPORTED_MODULE_39__.Island, {\n padding: spacing.islandPadding,\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(\"App-toolbar\", {\n \"zen-mode\": appState.zenModeEnabled,\n \"App-toolbar--compact\": isCompactStylesPanel\n })\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_HintViewer__WEBPACK_IMPORTED_MODULE_37__.HintViewer, {\n appState: appState,\n isMobile: editorInterface.formFactor === \"phone\",\n editorInterface: editorInterface,\n app: app\n }), heading, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Stack__WEBPACK_IMPORTED_MODULE_18__[\"default\"].Row, {\n gap: spacing.toolbarInnerRowGap\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_PenModeButton__WEBPACK_IMPORTED_MODULE_20__.PenModeButton, {\n zenModeEnabled: appState.zenModeEnabled,\n checked: appState.penMode,\n onChange: () => onPenModeToggle(null),\n title: (0,_i18n__WEBPACK_IMPORTED_MODULE_10__.t)(\"toolBar.penMode\"),\n penDetected: appState.penDetected\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_LockButton__WEBPACK_IMPORTED_MODULE_14__.LockButton, {\n checked: appState.activeTool.locked,\n onChange: onLockToggle,\n title: (0,_i18n__WEBPACK_IMPORTED_MODULE_10__.t)(\"toolBar.lock\")\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(\"div\", {\n className: \"App-toolbar__divider\"\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_HandButton__WEBPACK_IMPORTED_MODULE_35__.HandButton, {\n checked: (0,_appState__WEBPACK_IMPORTED_MODULE_6__.isHandToolActive)(appState),\n onChange: () => onHandToolToggle(),\n title: (0,_i18n__WEBPACK_IMPORTED_MODULE_10__.t)(\"toolBar.hand\"),\n isMobile: true\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Actions__WEBPACK_IMPORTED_MODULE_12__.ShapesSwitcher, {\n setAppState: setAppState,\n activeTool: appState.activeTool,\n UIOptions: UIOptions,\n app: app\n }))), isCollaborating && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Island__WEBPACK_IMPORTED_MODULE_39__.Island, {\n style: {\n marginLeft: spacing.collabMarginLeft,\n alignSelf: \"center\",\n height: \"fit-content\"\n }\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_LaserPointerButton__WEBPACK_IMPORTED_MODULE_41__.LaserPointerButton, {\n title: (0,_i18n__WEBPACK_IMPORTED_MODULE_10__.t)(\"toolBar.laser\"),\n checked: appState.activeTool.type === _excalidraw_common__WEBPACK_IMPORTED_MODULE_2__.TOOL_TYPE.laser,\n onChange: () => app.setActiveTool({\n type: _excalidraw_common__WEBPACK_IMPORTED_MODULE_2__.TOOL_TYPE.laser\n }),\n isMobile: true\n })))))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(\"div\", {\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(\"mobile-misc-tools-container zen-mode-transition\", //zsviczian\n {\n \"transition-right\": appState.zenModeEnabled,\n \"layer-ui__wrapper__top-right--compact\": isCompactStylesPanel\n }),\n style: //zsviczian\n ((_c = document.body) === null || _c === void 0 ? void 0 : _c.classList.contains(\"mod-rtl\")) ? {\n right: \"inherit\",\n left: \"calc(var(--editor-container-padding) * -1)\"\n } : undefined\n }, appState.collaborators.size > 0 && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_UserList__WEBPACK_IMPORTED_MODULE_19__.UserList, {\n collaborators: appState.collaborators,\n userToFollow: ((_d = appState.userToFollow) === null || _d === void 0 ? void 0 : _d.socketId) || null\n }), !appState.viewModeEnabled && ( //zsviczian\n renderTopRightUI === null || renderTopRightUI === void 0 ? void 0 : renderTopRightUI(editorInterface.formFactor === \"phone\", appState)), !appState.viewModeEnabled && ((_e = appState.openDialog) === null || _e === void 0 ? void 0 : _e.name) !== \"elementLinkSelector\" && ( // hide button when sidebar docked\n !isSidebarDocked || ((_f = appState.openSidebar) === null || _f === void 0 ? void 0 : _f.name) !== _excalidraw_common__WEBPACK_IMPORTED_MODULE_2__.DEFAULT_SIDEBAR.name) && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(tunnels.DefaultSidebarTriggerTunnel.Out, null), shouldShowStats && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Stats__WEBPACK_IMPORTED_MODULE_30__.Stats, {\n app: app,\n onClose: () => {\n actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleStats);\n },\n renderCustomStats: renderCustomStats\n }))));\n };\n\n const isTrayMode = !(appState.viewModeEnabled || appState.zenModeEnabled) && editorInterface.formFactor !== \"phone\" && editorInterface.preferTrayMode; //zsviczian\n\n const isTrayModeOrMobile = isTrayMode || editorInterface.formFactor === \"phone\"; //zsviczian\n\n const renderSidebars = () => {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_DefaultSidebar__WEBPACK_IMPORTED_MODULE_28__.DefaultSidebar, {\n __fallback: true,\n onDock: docked => {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_5__.trackEvent)(\"sidebar\", `toggleDock (${docked ? \"dock\" : \"undock\"})`, `(${editorInterface.formFactor === \"phone\" ? \"mobile\" : \"desktop\"})`);\n }\n });\n };\n\n const isSidebarDocked = (0,_editor_jotai__WEBPACK_IMPORTED_MODULE_9__.useAtomValue)(_Sidebar_Sidebar__WEBPACK_IMPORTED_MODULE_22__.isSidebarDockedAtom);\n const layerUIJSX = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement((react__WEBPACK_IMPORTED_MODULE_1___default().Fragment), null, children, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(DefaultMainMenu, {\n UIOptions: UIOptions\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_DefaultSidebar__WEBPACK_IMPORTED_MODULE_28__.DefaultSidebar.Trigger, {\n __fallback: true,\n icon: _icons__WEBPACK_IMPORTED_MODULE_27__.sidebarRightIcon,\n title: (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_2__.capitalizeString)((0,_i18n__WEBPACK_IMPORTED_MODULE_10__.t)(\"toolBar.library\")),\n onToggle: open => {\n if (open) {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_5__.trackEvent)(\"sidebar\", `${_excalidraw_common__WEBPACK_IMPORTED_MODULE_2__.DEFAULT_SIDEBAR.name} (open)`, `button (${editorInterface.formFactor === \"phone\" ? \"mobile\" : \"desktop\"})`);\n }\n },\n tab: _excalidraw_common__WEBPACK_IMPORTED_MODULE_2__.DEFAULT_SIDEBAR.defaultTab\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(DefaultOverwriteConfirmDialog, null), ((_a = appState.openDialog) === null || _a === void 0 ? void 0 : _a.name) === \"ttd\" && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_TTDDialog_TTDDialog__WEBPACK_IMPORTED_MODULE_29__.TTDDialog, {\n __fallback: true\n }), appState.isLoading && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_LoadingMessage__WEBPACK_IMPORTED_MODULE_13__.LoadingMessage, {\n delay: 250\n }), appState.errorMessage && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_ErrorDialog__WEBPACK_IMPORTED_MODULE_32__.ErrorDialog, {\n onClose: () => setAppState({\n errorMessage: null\n })\n }, appState.errorMessage), eyeDropperState && editorInterface.formFactor !== \"phone\" && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_EyeDropper__WEBPACK_IMPORTED_MODULE_33__.EyeDropper, {\n colorPickerType: eyeDropperState.colorPickerType,\n onCancel: () => {\n setEyeDropperState(null);\n },\n onChange: (colorPickerType, color, selectedElements, {\n altKey\n }) => {\n if (colorPickerType !== \"elementBackground\" && colorPickerType !== \"elementStroke\") {\n return;\n }\n\n if (selectedElements.length) {\n for (const element of selectedElements) {\n (0,_excalidraw_element__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(element, (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_2__.arrayToMap)(elements), {\n [altKey && eyeDropperState.swapPreviewOnAlt ? colorPickerType === \"elementBackground\" ? \"strokeColor\" : \"backgroundColor\" : colorPickerType === \"elementBackground\" ? \"backgroundColor\" : \"strokeColor\"]: color\n });\n _excalidraw_element__WEBPACK_IMPORTED_MODULE_3__.ShapeCache.delete(element);\n }\n\n app.scene.triggerUpdate();\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 }), ((_b = appState.openDialog) === null || _b === void 0 ? void 0 : _b.name) === \"help\" && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_HelpDialog__WEBPACK_IMPORTED_MODULE_36__.HelpDialog, {\n onClose: () => {\n setAppState({\n openDialog: null\n });\n }\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_ActiveConfirmDialog__WEBPACK_IMPORTED_MODULE_24__.ActiveConfirmDialog, null), ((_c = appState.openDialog) === null || _c === void 0 ? void 0 : _c.name) === \"elementLinkSelector\" && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_ElementLinkDialog__WEBPACK_IMPORTED_MODULE_31__[\"default\"], {\n sourceElementId: appState.openDialog.sourceElementId,\n onClose: () => {\n setAppState({\n openDialog: null\n });\n },\n scene: app.scene,\n appState: appState,\n generateLinkForSelection: generateLinkForSelection\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(tunnels.OverwriteConfirmDialogTunnel.Out, null), renderImageExportDialog(), renderJSONExportDialog(), appState.pasteDialog.shown && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_PasteChartDialog__WEBPACK_IMPORTED_MODULE_16__.PasteChartDialog, {\n setAppState: setAppState,\n appState: appState,\n onClose: () => setAppState({\n pasteDialog: {\n shown: false,\n data: null\n }\n })\n }), editorInterface.formFactor !== \"phone\" && isTrayMode &&\n /*#__PURE__*/\n //zsviczian Added isTrayMode condition\n react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_TrayMenu__WEBPACK_IMPORTED_MODULE_44__.TrayMenu, {\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 editorInterface: editorInterface,\n renderWelcomeScreen: renderWelcomeScreen,\n UIOptions: UIOptions\n }), editorInterface.formFactor === \"phone\" && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_MobileMenu__WEBPACK_IMPORTED_MODULE_15__.MobileMenu, {\n app: app,\n appState: appState,\n elements: elements,\n actionManager: actionManager,\n renderJSONExportDialog: renderJSONExportDialog,\n renderImageExportDialog: renderImageExportDialog,\n setAppState: setAppState,\n onHandToolToggle: onHandToolToggle,\n onPenModeToggle: onPenModeToggle,\n renderTopLeftUI: renderTopLeftUI,\n renderTopRightUI: renderTopRightUI,\n renderSidebars: renderSidebars,\n renderWelcomeScreen: renderWelcomeScreen,\n UIOptions: UIOptions\n }), !isTrayModeOrMobile &&\n /*#__PURE__*/\n //zsviczian changed from !device.editor.isMobile\n react__WEBPACK_IMPORTED_MODULE_1___default().createElement((react__WEBPACK_IMPORTED_MODULE_1___default().Fragment), null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(\"div\", {\n className: \"layer-ui__wrapper\"\n }, renderWelcomeScreen && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(tunnels.WelcomeScreenCenterTunnel.Out, null), renderFixedSideContainer(), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_footer_Footer__WEBPACK_IMPORTED_MODULE_21__[\"default\"], {\n appState: appState,\n actionManager: actionManager,\n showExitZenModeBtn: showExitZenModeBtn,\n renderWelcomeScreen: renderWelcomeScreen\n }), appState.scrolledOutside && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(\"button\", {\n type: \"button\",\n className: \"scroll-back-to-content\",\n onClick: () => {\n setAppState(appState => Object.assign({}, (0,_scene__WEBPACK_IMPORTED_MODULE_11__.calculateScrollCenter)(elements, appState)));\n }\n }, (0,_i18n__WEBPACK_IMPORTED_MODULE_10__.t)(\"buttons.scrollBackToContent\"))), renderSidebars()));\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_context_ui_appState__WEBPACK_IMPORTED_MODULE_8__.UIAppStateContext.Provider, {\n value: appState\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(TunnelsJotaiProvider, null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_context_tunnels__WEBPACK_IMPORTED_MODULE_7__.TunnelsContext.Provider, {\n value: tunnels\n }, layerUIJSX)));\n};\n\nconst stripIrrelevantAppStateProps = appState => {\n const {\n suggestedBinding,\n startBoundElement,\n cursorButton,\n scrollX,\n scrollY\n } = appState,\n ret = __rest(appState, [\"suggestedBinding\", \"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,_excalidraw_common__WEBPACK_IMPORTED_MODULE_2__.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: _excalidraw_common__WEBPACK_IMPORTED_MODULE_2__.isShallowEqual,\n selectedGroupIds: _excalidraw_common__WEBPACK_IMPORTED_MODULE_2__.isShallowEqual\n }) && (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_2__.isShallowEqual)(prev, next);\n};\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (/*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().memo(LayerUI, areEqual));\n\n//# sourceURL=webpack://ExcalidrawLib/./components/LayerUI.tsx?");
15239
+ 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 clsx__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! clsx */ \"../../node_modules/clsx/dist/clsx.m.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 _excalidraw_common__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @excalidraw/common */ \"../common/src/index.ts\");\n/* harmony import */ var _excalidraw_element__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @excalidraw/element */ \"../element/src/index.ts\");\n/* harmony import */ var _actions__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../actions */ \"./actions/index.ts\");\n/* harmony import */ var _analytics__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../analytics */ \"./analytics.ts\");\n/* harmony import */ var _appState__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../appState */ \"./appState.ts\");\n/* harmony import */ var _context_tunnels__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../context/tunnels */ \"./context/tunnels.ts\");\n/* harmony import */ var _context_ui_appState__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../context/ui-appState */ \"./context/ui-appState.ts\");\n/* harmony import */ var _editor_jotai__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../editor-jotai */ \"./editor-jotai.ts\");\n/* harmony import */ var _i18n__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../i18n */ \"./i18n.ts\");\n/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../scene */ \"./scene/index.ts\");\n/* harmony import */ var _Actions__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./Actions */ \"./components/Actions.tsx\");\n/* harmony import */ var _LoadingMessage__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./LoadingMessage */ \"./components/LoadingMessage.tsx\");\n/* harmony import */ var _LockButton__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./LockButton */ \"./components/LockButton.tsx\");\n/* harmony import */ var _MobileMenu__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./MobileMenu */ \"./components/MobileMenu.tsx\");\n/* harmony import */ var _PasteChartDialog__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./PasteChartDialog */ \"./components/PasteChartDialog.tsx\");\n/* harmony import */ var _Section__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./Section */ \"./components/Section.tsx\");\n/* harmony import */ var _Stack__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./Stack */ \"./components/Stack.tsx\");\n/* harmony import */ var _UserList__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./UserList */ \"./components/UserList.tsx\");\n/* harmony import */ var _PenModeButton__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./PenModeButton */ \"./components/PenModeButton.tsx\");\n/* harmony import */ var _footer_Footer__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./footer/Footer */ \"./components/footer/Footer.tsx\");\n/* harmony import */ var _Sidebar_Sidebar__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./Sidebar/Sidebar */ \"./components/Sidebar/Sidebar.tsx\");\n/* harmony import */ var _main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./main-menu/MainMenu */ \"./components/main-menu/MainMenu.tsx\");\n/* harmony import */ var _ActiveConfirmDialog__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./ActiveConfirmDialog */ \"./components/ActiveConfirmDialog.tsx\");\n/* harmony import */ var _App__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./App */ \"./components/App.tsx\");\n/* harmony import */ var _OverwriteConfirm_OverwriteConfirm__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./OverwriteConfirm/OverwriteConfirm */ \"./components/OverwriteConfirm/OverwriteConfirm.tsx\");\n/* harmony import */ var _icons__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./icons */ \"./components/icons.tsx\");\n/* harmony import */ var _DefaultSidebar__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./DefaultSidebar */ \"./components/DefaultSidebar.tsx\");\n/* harmony import */ var _TTDDialog_TTDDialog__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./TTDDialog/TTDDialog */ \"./components/TTDDialog/TTDDialog.tsx\");\n/* harmony import */ var _Stats__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./Stats */ \"./components/Stats/index.tsx\");\n/* harmony import */ var _ElementLinkDialog__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ./ElementLinkDialog */ \"./components/ElementLinkDialog.tsx\");\n/* harmony import */ var _ErrorDialog__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ./ErrorDialog */ \"./components/ErrorDialog.tsx\");\n/* harmony import */ var _EyeDropper__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ./EyeDropper */ \"./components/EyeDropper.tsx\");\n/* harmony import */ var _FixedSideContainer__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ./FixedSideContainer */ \"./components/FixedSideContainer.tsx\");\n/* harmony import */ var _HandButton__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ./HandButton */ \"./components/HandButton.tsx\");\n/* harmony import */ var _HelpDialog__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ./HelpDialog */ \"./components/HelpDialog.tsx\");\n/* harmony import */ var _HintViewer__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ./HintViewer */ \"./components/HintViewer.tsx\");\n/* harmony import */ var _ImageExportDialog__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! ./ImageExportDialog */ \"./components/ImageExportDialog.tsx\");\n/* harmony import */ var _Island__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(/*! ./Island */ \"./components/Island.tsx\");\n/* harmony import */ var _JSONExportDialog__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(/*! ./JSONExportDialog */ \"./components/JSONExportDialog.tsx\");\n/* harmony import */ var _LaserPointerButton__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(/*! ./LaserPointerButton */ \"./components/LaserPointerButton.tsx\");\n/* harmony import */ var _LayerUI_scss__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(/*! ./LayerUI.scss */ \"./components/LayerUI.scss\");\n/* harmony import */ var _Toolbar_scss__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(/*! ./Toolbar.scss */ \"./components/Toolbar.scss\");\n/* harmony import */ var _TrayMenu__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(/*! ./TrayMenu */ \"./components/TrayMenu.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\nconst DefaultMainMenu = ({\n UIOptions\n}) => {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"], {\n __fallback: true\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"].DefaultItems.LoadScene, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"].DefaultItems.SaveToActiveFile, null), UIOptions.canvasActions.export && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"].DefaultItems.Export, null), UIOptions.canvasActions.saveAsImage && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"].DefaultItems.SaveAsImage, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"].DefaultItems.SearchMenu, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"].DefaultItems.Help, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"].DefaultItems.ClearCanvas, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"].Separator, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"].Group, {\n title: \"Excalidraw links\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"].DefaultItems.Socials, null)), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"].Separator, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"].DefaultItems.ToggleTheme, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_main_menu_MainMenu__WEBPACK_IMPORTED_MODULE_23__[\"default\"].DefaultItems.ChangeCanvasBackground, null));\n};\n\nconst DefaultOverwriteConfirmDialog = () => {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_OverwriteConfirm_OverwriteConfirm__WEBPACK_IMPORTED_MODULE_26__.OverwriteConfirmDialog, {\n __fallback: true\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_OverwriteConfirm_OverwriteConfirm__WEBPACK_IMPORTED_MODULE_26__.OverwriteConfirmDialog.Actions.SaveToDisk, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_OverwriteConfirm_OverwriteConfirm__WEBPACK_IMPORTED_MODULE_26__.OverwriteConfirmDialog.Actions.ExportToImage, null));\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 renderTopLeftUI,\n renderTopRightUI,\n renderCustomStats,\n UIOptions,\n onExportImage,\n renderWelcomeScreen,\n children,\n app,\n isCollaborating,\n generateLinkForSelection\n}) => {\n var _a, _b, _c;\n\n const editorInterface = (0,_App__WEBPACK_IMPORTED_MODULE_25__.useEditorInterface)();\n const stylesPanelMode = (0,_App__WEBPACK_IMPORTED_MODULE_25__.useStylesPanelMode)();\n const isCompactStylesPanel = stylesPanelMode === \"compact\";\n const tunnels = (0,_context_tunnels__WEBPACK_IMPORTED_MODULE_7__.useInitializeTunnels)();\n const spacing = isCompactStylesPanel ? {\n menuTopGap: 4,\n toolbarColGap: 4,\n toolbarRowGap: 1,\n toolbarInnerRowGap: 0.5,\n islandPadding: 1,\n collabMarginLeft: 8\n } : {\n menuTopGap: 6,\n toolbarColGap: 4,\n toolbarRowGap: 1,\n toolbarInnerRowGap: 1,\n islandPadding: 1,\n collabMarginLeft: 8\n };\n const TunnelsJotaiProvider = tunnels.tunnelsJotai.Provider;\n const [eyeDropperState, setEyeDropperState] = (0,_editor_jotai__WEBPACK_IMPORTED_MODULE_9__.useAtom)(_EyeDropper__WEBPACK_IMPORTED_MODULE_33__.activeEyeDropperAtom);\n\n const renderJSONExportDialog = () => {\n if (!UIOptions.canvasActions.export) {\n return null;\n }\n\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_JSONExportDialog__WEBPACK_IMPORTED_MODULE_40__.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 var _a;\n\n if (!UIOptions.canvasActions.saveAsImage || ((_a = appState.openDialog) === null || _a === void 0 ? void 0 : _a.name) !== \"imageExport\") {\n return null;\n }\n\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_ImageExportDialog__WEBPACK_IMPORTED_MODULE_38__.ImageExportDialog, {\n elements: elements,\n appState: appState,\n files: files,\n actionManager: actionManager,\n onExportImage: onExportImage,\n onCloseRequest: () => setAppState({\n openDialog: null\n }),\n name: app.getName()\n });\n };\n\n const renderCanvasActions = () => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(\"div\", {\n style: {\n position: \"relative\"\n }\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(tunnels.MainMenuTunnel.Out, null), renderWelcomeScreen && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(tunnels.WelcomeScreenMenuHintTunnel.Out, null));\n\n const renderSelectedShapeActions = () => {\n const isCompactMode = isCompactStylesPanel;\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Section__WEBPACK_IMPORTED_MODULE_17__.Section, {\n heading: \"selectedShapeActions\",\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(\"selected-shape-actions zen-mode-transition\", {\n \"transition-left\": appState.zenModeEnabled\n })\n }, isCompactMode ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Island__WEBPACK_IMPORTED_MODULE_39__.Island, {\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(\"compact-shape-actions-island\"),\n padding: 0,\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 }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Actions__WEBPACK_IMPORTED_MODULE_12__.CompactShapeActions, {\n appState: appState,\n elementsMap: app.scene.getNonDeletedElementsMap(),\n renderAction: actionManager.renderAction,\n app: app,\n setAppState: setAppState\n })) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Island__WEBPACK_IMPORTED_MODULE_39__.Island, {\n className: _excalidraw_common__WEBPACK_IMPORTED_MODULE_2__.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 }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Actions__WEBPACK_IMPORTED_MODULE_12__.SelectedShapeActions, {\n appState: appState,\n elementsMap: app.scene.getNonDeletedElementsMap(),\n renderAction: actionManager.renderAction,\n app: app\n })));\n };\n\n const renderFixedSideContainer = () => {\n var _a, _b, _c, _d, _e, _f;\n\n const shouldRenderSelectedShapeActions = (0,_excalidraw_element__WEBPACK_IMPORTED_MODULE_3__.showSelectedShapeActions)(appState, elements);\n\n if (appState.viewModeEnabled) {\n return null;\n } //zsviczian\n\n\n const shouldShowStats = appState.stats.open && !appState.zenModeEnabled && !appState.viewModeEnabled && ((_a = appState.openDialog) === null || _a === void 0 ? void 0 : _a.name) !== \"elementLinkSelector\";\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_FixedSideContainer__WEBPACK_IMPORTED_MODULE_34__.FixedSideContainer, {\n side: \"top\",\n sidepanelOpen: !!appState.openSidebar\n /*zsviczian*/\n\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(\"div\", {\n className: \"App-menu App-menu_top\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Stack__WEBPACK_IMPORTED_MODULE_18__[\"default\"].Col, {\n gap: spacing.menuTopGap,\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(\"App-menu_top__left\")\n }, renderCanvasActions(), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(\"div\", {\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(\"selected-shape-actions-container\", {\n \"selected-shape-actions-container--compact\": isCompactStylesPanel\n })\n }, shouldRenderSelectedShapeActions && renderSelectedShapeActions())), !appState.viewModeEnabled && ((_b = appState.openDialog) === null || _b === void 0 ? void 0 : _b.name) !== \"elementLinkSelector\" && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Section__WEBPACK_IMPORTED_MODULE_17__.Section, {\n heading: \"shapes\",\n className: \"shapes-section\"\n }, heading => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(\"div\", {\n style: {\n position: \"relative\"\n }\n }, renderWelcomeScreen && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(tunnels.WelcomeScreenToolbarHintTunnel.Out, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Stack__WEBPACK_IMPORTED_MODULE_18__[\"default\"].Col, {\n gap: spacing.toolbarColGap,\n align: \"start\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Stack__WEBPACK_IMPORTED_MODULE_18__[\"default\"].Row, {\n gap: spacing.toolbarRowGap,\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(\"App-toolbar-container\", {\n \"zen-mode\": appState.zenModeEnabled\n })\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Island__WEBPACK_IMPORTED_MODULE_39__.Island, {\n padding: spacing.islandPadding,\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(\"App-toolbar\", {\n \"zen-mode\": appState.zenModeEnabled,\n \"App-toolbar--compact\": isCompactStylesPanel\n })\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_HintViewer__WEBPACK_IMPORTED_MODULE_37__.HintViewer, {\n appState: appState,\n isMobile: editorInterface.formFactor === \"phone\",\n editorInterface: editorInterface,\n app: app\n }), heading, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Stack__WEBPACK_IMPORTED_MODULE_18__[\"default\"].Row, {\n gap: spacing.toolbarInnerRowGap\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_PenModeButton__WEBPACK_IMPORTED_MODULE_20__.PenModeButton, {\n zenModeEnabled: appState.zenModeEnabled,\n checked: appState.penMode,\n onChange: () => onPenModeToggle(null),\n title: (0,_i18n__WEBPACK_IMPORTED_MODULE_10__.t)(\"toolBar.penMode\"),\n penDetected: appState.penDetected\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_LockButton__WEBPACK_IMPORTED_MODULE_14__.LockButton, {\n checked: appState.activeTool.locked,\n onChange: onLockToggle,\n title: (0,_i18n__WEBPACK_IMPORTED_MODULE_10__.t)(\"toolBar.lock\")\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(\"div\", {\n className: \"App-toolbar__divider\"\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_HandButton__WEBPACK_IMPORTED_MODULE_35__.HandButton, {\n checked: (0,_appState__WEBPACK_IMPORTED_MODULE_6__.isHandToolActive)(appState),\n onChange: () => onHandToolToggle(),\n title: (0,_i18n__WEBPACK_IMPORTED_MODULE_10__.t)(\"toolBar.hand\"),\n isMobile: true\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Actions__WEBPACK_IMPORTED_MODULE_12__.ShapesSwitcher, {\n setAppState: setAppState,\n activeTool: appState.activeTool,\n UIOptions: UIOptions,\n app: app\n }))), isCollaborating && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Island__WEBPACK_IMPORTED_MODULE_39__.Island, {\n style: {\n marginLeft: spacing.collabMarginLeft,\n alignSelf: \"center\",\n height: \"fit-content\"\n }\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_LaserPointerButton__WEBPACK_IMPORTED_MODULE_41__.LaserPointerButton, {\n title: (0,_i18n__WEBPACK_IMPORTED_MODULE_10__.t)(\"toolBar.laser\"),\n checked: appState.activeTool.type === _excalidraw_common__WEBPACK_IMPORTED_MODULE_2__.TOOL_TYPE.laser,\n onChange: () => app.setActiveTool({\n type: _excalidraw_common__WEBPACK_IMPORTED_MODULE_2__.TOOL_TYPE.laser\n }),\n isMobile: true\n })))))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(\"div\", {\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(\"mobile-misc-tools-container zen-mode-transition\", //zsviczian\n {\n \"transition-right\": appState.zenModeEnabled,\n \"layer-ui__wrapper__top-right--compact\": isCompactStylesPanel\n }),\n style: //zsviczian\n ((_c = document.body) === null || _c === void 0 ? void 0 : _c.classList.contains(\"mod-rtl\")) ? {\n right: \"inherit\",\n left: \"calc(var(--editor-container-padding) * -1)\"\n } : undefined\n }, appState.collaborators.size > 0 && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_UserList__WEBPACK_IMPORTED_MODULE_19__.UserList, {\n collaborators: appState.collaborators,\n userToFollow: ((_d = appState.userToFollow) === null || _d === void 0 ? void 0 : _d.socketId) || null\n }), !appState.viewModeEnabled && ( //zsviczian\n renderTopRightUI === null || renderTopRightUI === void 0 ? void 0 : renderTopRightUI(editorInterface.formFactor === \"phone\", appState)), !appState.viewModeEnabled && ((_e = appState.openDialog) === null || _e === void 0 ? void 0 : _e.name) !== \"elementLinkSelector\" && ( // hide button when sidebar docked\n !isSidebarDocked || ((_f = appState.openSidebar) === null || _f === void 0 ? void 0 : _f.name) !== _excalidraw_common__WEBPACK_IMPORTED_MODULE_2__.DEFAULT_SIDEBAR.name) && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(tunnels.DefaultSidebarTriggerTunnel.Out, null), shouldShowStats && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_Stats__WEBPACK_IMPORTED_MODULE_30__.Stats, {\n app: app,\n onClose: () => {\n actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleStats);\n },\n renderCustomStats: renderCustomStats\n }))));\n };\n\n const isTrayMode = !(appState.viewModeEnabled || appState.zenModeEnabled) && editorInterface.formFactor !== \"phone\" && editorInterface.preferTrayMode; //zsviczian\n\n const isTrayModeOrMobile = isTrayMode || editorInterface.formFactor === \"phone\"; //zsviczian\n\n const renderSidebars = () => {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_DefaultSidebar__WEBPACK_IMPORTED_MODULE_28__.DefaultSidebar, {\n __fallback: true,\n onDock: docked => {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_5__.trackEvent)(\"sidebar\", `toggleDock (${docked ? \"dock\" : \"undock\"})`, `(${editorInterface.formFactor === \"phone\" ? \"mobile\" : \"desktop\"})`);\n }\n });\n };\n\n const isSidebarDocked = (0,_editor_jotai__WEBPACK_IMPORTED_MODULE_9__.useAtomValue)(_Sidebar_Sidebar__WEBPACK_IMPORTED_MODULE_22__.isSidebarDockedAtom);\n const layerUIJSX = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement((react__WEBPACK_IMPORTED_MODULE_1___default().Fragment), null, children, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(DefaultMainMenu, {\n UIOptions: UIOptions\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_DefaultSidebar__WEBPACK_IMPORTED_MODULE_28__.DefaultSidebar.Trigger, {\n __fallback: true,\n icon: _icons__WEBPACK_IMPORTED_MODULE_27__.sidebarRightIcon,\n title: (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_2__.capitalizeString)((0,_i18n__WEBPACK_IMPORTED_MODULE_10__.t)(\"toolBar.library\")),\n onToggle: open => {\n if (open) {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_5__.trackEvent)(\"sidebar\", `${_excalidraw_common__WEBPACK_IMPORTED_MODULE_2__.DEFAULT_SIDEBAR.name} (open)`, `button (${editorInterface.formFactor === \"phone\" ? \"mobile\" : \"desktop\"})`);\n }\n },\n tab: _excalidraw_common__WEBPACK_IMPORTED_MODULE_2__.DEFAULT_SIDEBAR.defaultTab\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(DefaultOverwriteConfirmDialog, null), ((_a = appState.openDialog) === null || _a === void 0 ? void 0 : _a.name) === \"ttd\" && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_TTDDialog_TTDDialog__WEBPACK_IMPORTED_MODULE_29__.TTDDialog, {\n __fallback: true\n }), appState.isLoading && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_LoadingMessage__WEBPACK_IMPORTED_MODULE_13__.LoadingMessage, {\n delay: 250\n }), appState.errorMessage && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_ErrorDialog__WEBPACK_IMPORTED_MODULE_32__.ErrorDialog, {\n onClose: () => setAppState({\n errorMessage: null\n })\n }, appState.errorMessage), eyeDropperState && editorInterface.formFactor !== \"phone\" && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_EyeDropper__WEBPACK_IMPORTED_MODULE_33__.EyeDropper, {\n colorPickerType: eyeDropperState.colorPickerType,\n onCancel: () => {\n setEyeDropperState(null);\n },\n onChange: (colorPickerType, color, selectedElements, {\n altKey\n }) => {\n if (colorPickerType !== \"elementBackground\" && colorPickerType !== \"elementStroke\") {\n return;\n }\n\n if (selectedElements.length) {\n for (const element of selectedElements) {\n (0,_excalidraw_element__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(element, (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_2__.arrayToMap)(elements), {\n [altKey && eyeDropperState.swapPreviewOnAlt ? colorPickerType === \"elementBackground\" ? \"strokeColor\" : \"backgroundColor\" : colorPickerType === \"elementBackground\" ? \"backgroundColor\" : \"strokeColor\"]: color\n });\n _excalidraw_element__WEBPACK_IMPORTED_MODULE_3__.ShapeCache.delete(element);\n }\n\n app.scene.triggerUpdate();\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 }), ((_b = appState.openDialog) === null || _b === void 0 ? void 0 : _b.name) === \"help\" && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_HelpDialog__WEBPACK_IMPORTED_MODULE_36__.HelpDialog, {\n onClose: () => {\n setAppState({\n openDialog: null\n });\n }\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_ActiveConfirmDialog__WEBPACK_IMPORTED_MODULE_24__.ActiveConfirmDialog, null), ((_c = appState.openDialog) === null || _c === void 0 ? void 0 : _c.name) === \"elementLinkSelector\" && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_ElementLinkDialog__WEBPACK_IMPORTED_MODULE_31__[\"default\"], {\n sourceElementId: appState.openDialog.sourceElementId,\n onClose: () => {\n setAppState({\n openDialog: null\n });\n },\n scene: app.scene,\n appState: appState,\n generateLinkForSelection: generateLinkForSelection\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(tunnels.OverwriteConfirmDialogTunnel.Out, null), renderImageExportDialog(), renderJSONExportDialog(), appState.pasteDialog.shown && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_PasteChartDialog__WEBPACK_IMPORTED_MODULE_16__.PasteChartDialog, {\n setAppState: setAppState,\n appState: appState,\n onClose: () => setAppState({\n pasteDialog: {\n shown: false,\n data: null\n }\n })\n }), editorInterface.formFactor !== \"phone\" && isTrayMode &&\n /*#__PURE__*/\n //zsviczian Added isTrayMode condition\n react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_TrayMenu__WEBPACK_IMPORTED_MODULE_44__.TrayMenu, {\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 editorInterface: editorInterface,\n renderWelcomeScreen: renderWelcomeScreen,\n UIOptions: UIOptions\n }), editorInterface.formFactor === \"phone\" && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_MobileMenu__WEBPACK_IMPORTED_MODULE_15__.MobileMenu, {\n app: app,\n appState: appState,\n elements: elements,\n actionManager: actionManager,\n renderJSONExportDialog: renderJSONExportDialog,\n renderImageExportDialog: renderImageExportDialog,\n setAppState: setAppState,\n onHandToolToggle: onHandToolToggle,\n onPenModeToggle: onPenModeToggle,\n renderTopLeftUI: renderTopLeftUI,\n renderTopRightUI: renderTopRightUI,\n renderSidebars: renderSidebars,\n renderWelcomeScreen: renderWelcomeScreen,\n UIOptions: UIOptions\n }), !isTrayModeOrMobile &&\n /*#__PURE__*/\n //zsviczian changed from !device.editor.isMobile\n react__WEBPACK_IMPORTED_MODULE_1___default().createElement((react__WEBPACK_IMPORTED_MODULE_1___default().Fragment), null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(\"div\", {\n className: \"layer-ui__wrapper\"\n }, renderWelcomeScreen && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(tunnels.WelcomeScreenCenterTunnel.Out, null), renderFixedSideContainer(), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_footer_Footer__WEBPACK_IMPORTED_MODULE_21__[\"default\"], {\n appState: appState,\n actionManager: actionManager,\n showExitZenModeBtn: showExitZenModeBtn,\n renderWelcomeScreen: renderWelcomeScreen\n }), appState.scrolledOutside && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(\"button\", {\n type: \"button\",\n className: \"scroll-back-to-content\",\n onClick: () => {\n setAppState(appState => Object.assign({}, (0,_scene__WEBPACK_IMPORTED_MODULE_11__.calculateScrollCenter)(elements, appState)));\n }\n }, (0,_i18n__WEBPACK_IMPORTED_MODULE_10__.t)(\"buttons.scrollBackToContent\"))), renderSidebars()));\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_context_ui_appState__WEBPACK_IMPORTED_MODULE_8__.UIAppStateContext.Provider, {\n value: appState\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(TunnelsJotaiProvider, null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_context_tunnels__WEBPACK_IMPORTED_MODULE_7__.TunnelsContext.Provider, {\n value: tunnels\n }, layerUIJSX)));\n};\n\nconst stripIrrelevantAppStateProps = appState => {\n const {\n startBoundElement,\n cursorButton,\n scrollX,\n scrollY\n } = appState,\n ret = __rest(appState, [\"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,_excalidraw_common__WEBPACK_IMPORTED_MODULE_2__.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: _excalidraw_common__WEBPACK_IMPORTED_MODULE_2__.isShallowEqual,\n selectedGroupIds: _excalidraw_common__WEBPACK_IMPORTED_MODULE_2__.isShallowEqual\n }) && (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_2__.isShallowEqual)(prev, next);\n};\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (/*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().memo(LayerUI, areEqual));\n\n//# sourceURL=webpack://ExcalidrawLib/./components/LayerUI.tsx?");
15240
15240
 
15241
15241
  /***/ }),
15242
15242
 
@@ -17205,7 +17205,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
17205
17205
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
17206
17206
 
17207
17207
  "use strict";
17208
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ ExcalidrawFontFace: () => (/* binding */ ExcalidrawFontFace)\n/* harmony export */ });\n/* harmony import */ var _excalidraw_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @excalidraw/common */ \"../common/src/index.ts\");\n/* harmony import */ var _subset_subset_main__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../subset/subset-main */ \"./subset/subset-main.ts\");\n/* harmony import */ var _data_encode__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../data/encode */ \"./data/encode.ts\");\n/* harmony import */ var _obsidianUtils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../obsidianUtils */ \"./obsidianUtils.ts\");\n\n\n\n\nclass ExcalidrawFontFace {\n constructor(family, uri, descriptors) {\n this.urls = ExcalidrawFontFace.createUrls(uri);\n const sources = this.urls.map(url => `url(${url}) ${ExcalidrawFontFace.getFormat(url)}`).join(\", \");\n this.fontFace = new FontFace(family, sources, Object.assign({\n display: \"swap\",\n style: \"normal\",\n weight: \"400\"\n }, descriptors));\n }\n /**\r\n * Generates CSS `@font-face` definition with the (subsetted) font source as a data url for the characters within the unicode range.\r\n *\r\n * Retrieves `undefined` otherwise.\r\n */\n\n\n toCSS(characters) {\n // quick exit in case the characters are not within this font face's unicode range\n if (!this.getUnicodeRangeRegex().test(characters)) {\n return;\n } //zsviczian - only woffs are chopped into glyphs other fonts are returned as is\n\n\n if (typeof this.urls[0] === \"string\" && !this.urls[0].startsWith(\"data:font/woff2\")) {\n return Promise.resolve(`@font-face { font-family: ${this.fontFace.family}; src: url(${this.urls[0]}); }`);\n }\n\n const codepoints = Array.from(characters).map(char => char.codePointAt(0));\n return this.getContent(codepoints).then(content => `@font-face { font-family: ${this.fontFace.family}; src: url(${content}); }`);\n }\n /**\r\n * Tries to fetch woff2 content, based on the registered urls (from first to last, treated as fallbacks).\r\n *\r\n * @returns base64 with subsetted glyphs based on the passed codepoint, last defined url otherwise\r\n */\n\n\n async getContent(codePoints) {\n let i = 0;\n const errorMessages = [];\n\n while (i < this.urls.length) {\n const url = this.urls[i];\n\n try {\n const arrayBuffer = await this.fetchFont(url);\n const base64 = await (0,_subset_subset_main__WEBPACK_IMPORTED_MODULE_1__.subsetWoff2GlyphsByCodepoints)(arrayBuffer, codePoints);\n return base64;\n } catch (e) {\n errorMessages.push(`\"${url.toString()}\" returned error \"${e}\"`);\n }\n\n i++;\n }\n\n console.error(`Failed to fetch font family \"${this.fontFace.family}\"`, JSON.stringify(errorMessages, undefined, 2)); // in case of issues, at least return the last url as a content\n // defaults to unpkg for bundled fonts (so that we don't have to host them forever) and http url for others\n\n return this.urls.length ? this.urls[this.urls.length - 1].toString() : \"\";\n }\n\n fetchFont(url) {\n return (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.promiseTry)(async () => {\n const result = await (0,_obsidianUtils__WEBPACK_IMPORTED_MODULE_3__.fetchFontFromVault)(url); //zsviczian\n\n if (result) {\n return result;\n }\n\n const response = await fetch(url, {\n // always prefer cache (even stale), otherwise it always triggers an unnecessary validation request\n // which we don't need as we are controlling freshness of the fonts with the stable hash suffix in the url\n // https://developer.mozilla.org/en-US/docs/Web/API/Request/cache\n cache: \"force-cache\",\n headers: {\n Accept: \"font/woff2\"\n }\n });\n\n if (!response.ok) {\n const urlString = url instanceof URL ? url.toString() : \"dataurl\";\n throw new Error(`Failed to fetch \"${urlString}\": ${response.statusText}`);\n }\n\n const arrayBuffer = await response.arrayBuffer();\n return arrayBuffer;\n });\n }\n\n getUnicodeRangeRegex() {\n // using \\u{h} or \\u{hhhhh} to match any number of hex digits,\n // otherwise we would get an \"Invalid Unicode escape\" error\n // e.g. U+0-1007F -> \\u{0}-\\u{1007F}\n const unicodeRangeRegex = this.fontFace.unicodeRange.split(/,\\s*/).map(range => {\n const [start, end] = range.replace(\"U+\", \"\").split(\"-\");\n\n if (end) {\n return `\\\\u{${start}}-\\\\u{${end}}`;\n }\n\n return `\\\\u{${start}}`;\n }).join(\"\");\n return new RegExp(`[${unicodeRangeRegex}]`, \"u\");\n }\n\n static createUrls(uri) {\n if (uri.startsWith(\"data\")) {\n // don't create the URL instance, as parsing the huge dataurl string is expensive\n return [uri];\n }\n\n if (uri.startsWith(_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.LOCAL_FONT_PROTOCOL)) {\n // no url for local fonts\n return [];\n }\n\n if (uri.startsWith(\"http\")) {\n // one url for http imports or data url\n return [new URL(uri)];\n } // absolute assets paths, which are found in tests and excalidraw-app build, won't work with base url, so we are stripping initial slash away\n\n\n const assetUrl = uri.replace(/^\\/+/, \"\");\n const urls = [];\n\n if (typeof window.EXCALIDRAW_ASSET_PATH === \"string\") {\n const normalizedBaseUrl = this.normalizeBaseUrl(window.EXCALIDRAW_ASSET_PATH);\n urls.push(new URL(assetUrl, normalizedBaseUrl));\n } else if (Array.isArray(window.EXCALIDRAW_ASSET_PATH)) {\n window.EXCALIDRAW_ASSET_PATH.forEach(path => {\n const normalizedBaseUrl = this.normalizeBaseUrl(path);\n urls.push(new URL(assetUrl, normalizedBaseUrl));\n });\n } // fallback url for bundled fonts\n\n\n urls.push(new URL(assetUrl, ExcalidrawFontFace.ASSETS_FALLBACK_URL));\n return urls;\n }\n\n static getFormat(url) {\n if (!(url instanceof URL)) {\n // format is irrelevant for data url\n return \"\";\n }\n\n try {\n const parts = new URL(url).pathname.split(\".\");\n\n if (parts.length === 1) {\n return \"\";\n }\n\n return `format('${parts.pop()}')`;\n } catch (error) {\n return \"\";\n }\n }\n\n static normalizeBaseUrl(baseUrl) {\n var _a;\n\n let result = baseUrl; // in case user passed a root-relative url (~absolute path),\n // like \"/\" or \"/some/path\", or relative (starts with \"./\"),\n // prepend it with `location.origin`\n\n if (/^\\.?\\//.test(result)) {\n result = new URL(result.replace(/^\\.?\\/+/, \"\"), (_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.origin).toString();\n } // ensure there is a trailing slash, otherwise url won't be correctly concatenated\n\n\n result = `${result.replace(/\\/+$/, \"\")}/`;\n return result;\n }\n /**\r\n * zsviczian https://github.com/zsviczian/excalidraw/commit/b4cfaaa4b4f46ca01f94e27fb7bf651a9da99daa\r\n */\n\n\n async getContentLegacy() {\n let i = 0;\n const errorMessages = [];\n\n while (i < this.urls.length) {\n const url = this.urls[i];\n\n if (typeof url === \"string\" && url.startsWith(\"data:\")) {\n // it's dataurl, the font is inlined as base64, no need to fetch\n return url;\n }\n\n try {\n const result = await (0,_obsidianUtils__WEBPACK_IMPORTED_MODULE_3__.fetchFontFromVault)(url); //zsviczian\n\n if (result) {\n return `data:font/woff2;base64,${(0,_data_encode__WEBPACK_IMPORTED_MODULE_2__.stringToBase64)((0,_data_encode__WEBPACK_IMPORTED_MODULE_2__.toByteString)(result), true)}`;\n }\n\n const response = await fetch(url, {\n headers: {\n Accept: \"font/woff2\"\n }\n });\n\n if (response.ok) {\n const mimeType = response.headers.get(\"Content-Type\");\n const buffer = await response.arrayBuffer();\n return `data:${mimeType};base64,${(0,_data_encode__WEBPACK_IMPORTED_MODULE_2__.stringToBase64)((0,_data_encode__WEBPACK_IMPORTED_MODULE_2__.toByteString)(buffer), true)}`;\n } // response not ok, try to continue\n\n\n errorMessages.push(`\"${url.toString()}\" returned status \"${response.status}\"`);\n } catch (e) {\n errorMessages.push(`\"${url.toString()}\" returned error \"${e}\"`);\n }\n\n i++;\n }\n\n console.error(`Failed to fetch font \"${this.fontFace.family}\" from urls \"${this.urls.toString()}`, JSON.stringify(errorMessages, undefined, 2)); // in case of issues, at least return the last url as a content\n // defaults to unpkg for bundled fonts (so that we don't have to host them forever) and http url for others\n\n return this.urls.length ? this.urls[this.urls.length - 1].toString() : \"\";\n }\n\n}\nExcalidrawFontFace.ASSETS_FALLBACK_URL = `https://esm.sh/${({\"MODE\":\"development\",\"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_PLUS_LP\":\"https://plus.excalidraw.com\",\"VITE_APP_PLUS_APP\":\"http://localhost:3000\",\"VITE_APP_AI_BACKEND\":\"http://localhost:3015\",\"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_DISABLE_LIVE_RELOAD\":\"\",\"VITE_APP_ENABLE_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_APP_ENABLE_PWA\":\"false\",\"VITE_APP_PLUS_EXPORT_PUBLIC_KEY\":\"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm2g5T+Rub6Kbf1Mf57t0\\n7r2zeHuVg4dla3r5ryXMswtzz6x767octl6oLThn33mQsPSy3GKglFZoCTXJR4ij\\nba8SxB04sL/N8eRrKja7TFWjCVtRwTTfyy771NYYNFVJclkxHyE5qw4m27crHF1y\\nUNWEjuqNMi/lwAErS9fFa2oJlWyT8U7zzv/5kQREkxZI6y9v0AF3qcbsy2731FnD\\ns9ChJvOUW9toIab2gsIdrKW8ZNpu084ZFVKb6LNjvIXI1Se4oMTHeszXzNptzlot\\nkdxxjOoaQMAyfljFSot1F1FlU6MQlag7UnFGvFjRHN1JI5q4K+n3a67DX+TMyRqS\\nHQIDAQAB\",\"VITE_APP_DISABLE_PREVENT_UNLOAD\":\"\",\"VITE_PKG_NAME\":\"@zsviczian/excalidraw\",\"VITE_PKG_VERSION\":\"0.18.0-53\",\"VITE_IS_EXCALIDRAW_NPM_PACKAGE\":true}).PKG_NAME ? `${({\"MODE\":\"development\",\"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_PLUS_LP\":\"https://plus.excalidraw.com\",\"VITE_APP_PLUS_APP\":\"http://localhost:3000\",\"VITE_APP_AI_BACKEND\":\"http://localhost:3015\",\"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_DISABLE_LIVE_RELOAD\":\"\",\"VITE_APP_ENABLE_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_APP_ENABLE_PWA\":\"false\",\"VITE_APP_PLUS_EXPORT_PUBLIC_KEY\":\"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm2g5T+Rub6Kbf1Mf57t0\\n7r2zeHuVg4dla3r5ryXMswtzz6x767octl6oLThn33mQsPSy3GKglFZoCTXJR4ij\\nba8SxB04sL/N8eRrKja7TFWjCVtRwTTfyy771NYYNFVJclkxHyE5qw4m27crHF1y\\nUNWEjuqNMi/lwAErS9fFa2oJlWyT8U7zzv/5kQREkxZI6y9v0AF3qcbsy2731FnD\\ns9ChJvOUW9toIab2gsIdrKW8ZNpu084ZFVKb6LNjvIXI1Se4oMTHeszXzNptzlot\\nkdxxjOoaQMAyfljFSot1F1FlU6MQlag7UnFGvFjRHN1JI5q4K+n3a67DX+TMyRqS\\nHQIDAQAB\",\"VITE_APP_DISABLE_PREVENT_UNLOAD\":\"\",\"VITE_PKG_NAME\":\"@zsviczian/excalidraw\",\"VITE_PKG_VERSION\":\"0.18.0-53\",\"VITE_IS_EXCALIDRAW_NPM_PACKAGE\":true}).PKG_NAME}@${({\"MODE\":\"development\",\"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_PLUS_LP\":\"https://plus.excalidraw.com\",\"VITE_APP_PLUS_APP\":\"http://localhost:3000\",\"VITE_APP_AI_BACKEND\":\"http://localhost:3015\",\"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_DISABLE_LIVE_RELOAD\":\"\",\"VITE_APP_ENABLE_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_APP_ENABLE_PWA\":\"false\",\"VITE_APP_PLUS_EXPORT_PUBLIC_KEY\":\"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm2g5T+Rub6Kbf1Mf57t0\\n7r2zeHuVg4dla3r5ryXMswtzz6x767octl6oLThn33mQsPSy3GKglFZoCTXJR4ij\\nba8SxB04sL/N8eRrKja7TFWjCVtRwTTfyy771NYYNFVJclkxHyE5qw4m27crHF1y\\nUNWEjuqNMi/lwAErS9fFa2oJlWyT8U7zzv/5kQREkxZI6y9v0AF3qcbsy2731FnD\\ns9ChJvOUW9toIab2gsIdrKW8ZNpu084ZFVKb6LNjvIXI1Se4oMTHeszXzNptzlot\\nkdxxjOoaQMAyfljFSot1F1FlU6MQlag7UnFGvFjRHN1JI5q4K+n3a67DX+TMyRqS\\nHQIDAQAB\",\"VITE_APP_DISABLE_PREVENT_UNLOAD\":\"\",\"VITE_PKG_NAME\":\"@zsviczian/excalidraw\",\"VITE_PKG_VERSION\":\"0.18.0-53\",\"VITE_IS_EXCALIDRAW_NPM_PACKAGE\":true}).PKG_VERSION}` // is provided during package build\n: \"@excalidraw/excalidraw\" // fallback to the latest package version (i.e. for app)\n}/dist/prod/`;\n\n//# sourceURL=webpack://ExcalidrawLib/./fonts/ExcalidrawFontFace.ts?");
17208
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ ExcalidrawFontFace: () => (/* binding */ ExcalidrawFontFace)\n/* harmony export */ });\n/* harmony import */ var _excalidraw_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @excalidraw/common */ \"../common/src/index.ts\");\n/* harmony import */ var _subset_subset_main__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../subset/subset-main */ \"./subset/subset-main.ts\");\n/* harmony import */ var _data_encode__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../data/encode */ \"./data/encode.ts\");\n/* harmony import */ var _obsidianUtils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../obsidianUtils */ \"./obsidianUtils.ts\");\n\n\n\n\nclass ExcalidrawFontFace {\n constructor(family, uri, descriptors) {\n this.urls = ExcalidrawFontFace.createUrls(uri);\n const sources = this.urls.map(url => `url(${url}) ${ExcalidrawFontFace.getFormat(url)}`).join(\", \");\n this.fontFace = new FontFace(family, sources, Object.assign({\n display: \"swap\",\n style: \"normal\",\n weight: \"400\"\n }, descriptors));\n }\n /**\r\n * Generates CSS `@font-face` definition with the (subsetted) font source as a data url for the characters within the unicode range.\r\n *\r\n * Retrieves `undefined` otherwise.\r\n */\n\n\n toCSS(characters) {\n // quick exit in case the characters are not within this font face's unicode range\n if (!this.getUnicodeRangeRegex().test(characters)) {\n return;\n } //zsviczian - only woffs are chopped into glyphs other fonts are returned as is\n\n\n if (typeof this.urls[0] === \"string\" && !this.urls[0].startsWith(\"data:font/woff2\")) {\n return Promise.resolve(`@font-face { font-family: ${this.fontFace.family}; src: url(${this.urls[0]}); }`);\n }\n\n const codepoints = Array.from(characters).map(char => char.codePointAt(0));\n return this.getContent(codepoints).then(content => `@font-face { font-family: ${this.fontFace.family}; src: url(${content}); }`);\n }\n /**\r\n * Tries to fetch woff2 content, based on the registered urls (from first to last, treated as fallbacks).\r\n *\r\n * @returns base64 with subsetted glyphs based on the passed codepoint, last defined url otherwise\r\n */\n\n\n async getContent(codePoints) {\n let i = 0;\n const errorMessages = [];\n\n while (i < this.urls.length) {\n const url = this.urls[i];\n\n try {\n const arrayBuffer = await this.fetchFont(url);\n const base64 = await (0,_subset_subset_main__WEBPACK_IMPORTED_MODULE_1__.subsetWoff2GlyphsByCodepoints)(arrayBuffer, codePoints);\n return base64;\n } catch (e) {\n errorMessages.push(`\"${url.toString()}\" returned error \"${e}\"`);\n }\n\n i++;\n }\n\n console.error(`Failed to fetch font family \"${this.fontFace.family}\"`, JSON.stringify(errorMessages, undefined, 2)); // in case of issues, at least return the last url as a content\n // defaults to unpkg for bundled fonts (so that we don't have to host them forever) and http url for others\n\n return this.urls.length ? this.urls[this.urls.length - 1].toString() : \"\";\n }\n\n fetchFont(url) {\n return (0,_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.promiseTry)(async () => {\n const result = await (0,_obsidianUtils__WEBPACK_IMPORTED_MODULE_3__.fetchFontFromVault)(url); //zsviczian\n\n if (result) {\n return result;\n }\n\n const response = await fetch(url, {\n // always prefer cache (even stale), otherwise it always triggers an unnecessary validation request\n // which we don't need as we are controlling freshness of the fonts with the stable hash suffix in the url\n // https://developer.mozilla.org/en-US/docs/Web/API/Request/cache\n cache: \"force-cache\",\n headers: {\n Accept: \"font/woff2\"\n }\n });\n\n if (!response.ok) {\n const urlString = url instanceof URL ? url.toString() : \"dataurl\";\n throw new Error(`Failed to fetch \"${urlString}\": ${response.statusText}`);\n }\n\n const arrayBuffer = await response.arrayBuffer();\n return arrayBuffer;\n });\n }\n\n getUnicodeRangeRegex() {\n // using \\u{h} or \\u{hhhhh} to match any number of hex digits,\n // otherwise we would get an \"Invalid Unicode escape\" error\n // e.g. U+0-1007F -> \\u{0}-\\u{1007F}\n const unicodeRangeRegex = this.fontFace.unicodeRange.split(/,\\s*/).map(range => {\n const [start, end] = range.replace(\"U+\", \"\").split(\"-\");\n\n if (end) {\n return `\\\\u{${start}}-\\\\u{${end}}`;\n }\n\n return `\\\\u{${start}}`;\n }).join(\"\");\n return new RegExp(`[${unicodeRangeRegex}]`, \"u\");\n }\n\n static createUrls(uri) {\n if (uri.startsWith(\"data\")) {\n // don't create the URL instance, as parsing the huge dataurl string is expensive\n return [uri];\n }\n\n if (uri.startsWith(_excalidraw_common__WEBPACK_IMPORTED_MODULE_0__.LOCAL_FONT_PROTOCOL)) {\n // no url for local fonts\n return [];\n }\n\n if (uri.startsWith(\"http\")) {\n // one url for http imports or data url\n return [new URL(uri)];\n } // absolute assets paths, which are found in tests and excalidraw-app build, won't work with base url, so we are stripping initial slash away\n\n\n const assetUrl = uri.replace(/^\\/+/, \"\");\n const urls = [];\n\n if (typeof window.EXCALIDRAW_ASSET_PATH === \"string\") {\n const normalizedBaseUrl = this.normalizeBaseUrl(window.EXCALIDRAW_ASSET_PATH);\n urls.push(new URL(assetUrl, normalizedBaseUrl));\n } else if (Array.isArray(window.EXCALIDRAW_ASSET_PATH)) {\n window.EXCALIDRAW_ASSET_PATH.forEach(path => {\n const normalizedBaseUrl = this.normalizeBaseUrl(path);\n urls.push(new URL(assetUrl, normalizedBaseUrl));\n });\n } // fallback url for bundled fonts\n\n\n urls.push(new URL(assetUrl, ExcalidrawFontFace.ASSETS_FALLBACK_URL));\n return urls;\n }\n\n static getFormat(url) {\n if (!(url instanceof URL)) {\n // format is irrelevant for data url\n return \"\";\n }\n\n try {\n const parts = new URL(url).pathname.split(\".\");\n\n if (parts.length === 1) {\n return \"\";\n }\n\n return `format('${parts.pop()}')`;\n } catch (error) {\n return \"\";\n }\n }\n\n static normalizeBaseUrl(baseUrl) {\n var _a;\n\n let result = baseUrl; // in case user passed a root-relative url (~absolute path),\n // like \"/\" or \"/some/path\", or relative (starts with \"./\"),\n // prepend it with `location.origin`\n\n if (/^\\.?\\//.test(result)) {\n result = new URL(result.replace(/^\\.?\\/+/, \"\"), (_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.origin).toString();\n } // ensure there is a trailing slash, otherwise url won't be correctly concatenated\n\n\n result = `${result.replace(/\\/+$/, \"\")}/`;\n return result;\n }\n /**\r\n * zsviczian https://github.com/zsviczian/excalidraw/commit/b4cfaaa4b4f46ca01f94e27fb7bf651a9da99daa\r\n */\n\n\n async getContentLegacy() {\n let i = 0;\n const errorMessages = [];\n\n while (i < this.urls.length) {\n const url = this.urls[i];\n\n if (typeof url === \"string\" && url.startsWith(\"data:\")) {\n // it's dataurl, the font is inlined as base64, no need to fetch\n return url;\n }\n\n try {\n const result = await (0,_obsidianUtils__WEBPACK_IMPORTED_MODULE_3__.fetchFontFromVault)(url); //zsviczian\n\n if (result) {\n return `data:font/woff2;base64,${(0,_data_encode__WEBPACK_IMPORTED_MODULE_2__.stringToBase64)((0,_data_encode__WEBPACK_IMPORTED_MODULE_2__.toByteString)(result), true)}`;\n }\n\n const response = await fetch(url, {\n headers: {\n Accept: \"font/woff2\"\n }\n });\n\n if (response.ok) {\n const mimeType = response.headers.get(\"Content-Type\");\n const buffer = await response.arrayBuffer();\n return `data:${mimeType};base64,${(0,_data_encode__WEBPACK_IMPORTED_MODULE_2__.stringToBase64)((0,_data_encode__WEBPACK_IMPORTED_MODULE_2__.toByteString)(buffer), true)}`;\n } // response not ok, try to continue\n\n\n errorMessages.push(`\"${url.toString()}\" returned status \"${response.status}\"`);\n } catch (e) {\n errorMessages.push(`\"${url.toString()}\" returned error \"${e}\"`);\n }\n\n i++;\n }\n\n console.error(`Failed to fetch font \"${this.fontFace.family}\" from urls \"${this.urls.toString()}`, JSON.stringify(errorMessages, undefined, 2)); // in case of issues, at least return the last url as a content\n // defaults to unpkg for bundled fonts (so that we don't have to host them forever) and http url for others\n\n return this.urls.length ? this.urls[this.urls.length - 1].toString() : \"\";\n }\n\n}\nExcalidrawFontFace.ASSETS_FALLBACK_URL = `https://esm.sh/${({\"MODE\":\"development\",\"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_PLUS_LP\":\"https://plus.excalidraw.com\",\"VITE_APP_PLUS_APP\":\"http://localhost:3000\",\"VITE_APP_AI_BACKEND\":\"http://localhost:3015\",\"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_DISABLE_LIVE_RELOAD\":\"\",\"VITE_APP_ENABLE_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_APP_ENABLE_PWA\":\"false\",\"VITE_APP_PLUS_EXPORT_PUBLIC_KEY\":\"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm2g5T+Rub6Kbf1Mf57t0\\n7r2zeHuVg4dla3r5ryXMswtzz6x767octl6oLThn33mQsPSy3GKglFZoCTXJR4ij\\nba8SxB04sL/N8eRrKja7TFWjCVtRwTTfyy771NYYNFVJclkxHyE5qw4m27crHF1y\\nUNWEjuqNMi/lwAErS9fFa2oJlWyT8U7zzv/5kQREkxZI6y9v0AF3qcbsy2731FnD\\ns9ChJvOUW9toIab2gsIdrKW8ZNpu084ZFVKb6LNjvIXI1Se4oMTHeszXzNptzlot\\nkdxxjOoaQMAyfljFSot1F1FlU6MQlag7UnFGvFjRHN1JI5q4K+n3a67DX+TMyRqS\\nHQIDAQAB\",\"VITE_APP_DISABLE_PREVENT_UNLOAD\":\"\",\"VITE_PKG_NAME\":\"@zsviczian/excalidraw\",\"VITE_PKG_VERSION\":\"0.18.0-54\",\"VITE_IS_EXCALIDRAW_NPM_PACKAGE\":true}).PKG_NAME ? `${({\"MODE\":\"development\",\"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_PLUS_LP\":\"https://plus.excalidraw.com\",\"VITE_APP_PLUS_APP\":\"http://localhost:3000\",\"VITE_APP_AI_BACKEND\":\"http://localhost:3015\",\"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_DISABLE_LIVE_RELOAD\":\"\",\"VITE_APP_ENABLE_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_APP_ENABLE_PWA\":\"false\",\"VITE_APP_PLUS_EXPORT_PUBLIC_KEY\":\"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm2g5T+Rub6Kbf1Mf57t0\\n7r2zeHuVg4dla3r5ryXMswtzz6x767octl6oLThn33mQsPSy3GKglFZoCTXJR4ij\\nba8SxB04sL/N8eRrKja7TFWjCVtRwTTfyy771NYYNFVJclkxHyE5qw4m27crHF1y\\nUNWEjuqNMi/lwAErS9fFa2oJlWyT8U7zzv/5kQREkxZI6y9v0AF3qcbsy2731FnD\\ns9ChJvOUW9toIab2gsIdrKW8ZNpu084ZFVKb6LNjvIXI1Se4oMTHeszXzNptzlot\\nkdxxjOoaQMAyfljFSot1F1FlU6MQlag7UnFGvFjRHN1JI5q4K+n3a67DX+TMyRqS\\nHQIDAQAB\",\"VITE_APP_DISABLE_PREVENT_UNLOAD\":\"\",\"VITE_PKG_NAME\":\"@zsviczian/excalidraw\",\"VITE_PKG_VERSION\":\"0.18.0-54\",\"VITE_IS_EXCALIDRAW_NPM_PACKAGE\":true}).PKG_NAME}@${({\"MODE\":\"development\",\"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_PLUS_LP\":\"https://plus.excalidraw.com\",\"VITE_APP_PLUS_APP\":\"http://localhost:3000\",\"VITE_APP_AI_BACKEND\":\"http://localhost:3015\",\"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_DISABLE_LIVE_RELOAD\":\"\",\"VITE_APP_ENABLE_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_APP_ENABLE_PWA\":\"false\",\"VITE_APP_PLUS_EXPORT_PUBLIC_KEY\":\"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm2g5T+Rub6Kbf1Mf57t0\\n7r2zeHuVg4dla3r5ryXMswtzz6x767octl6oLThn33mQsPSy3GKglFZoCTXJR4ij\\nba8SxB04sL/N8eRrKja7TFWjCVtRwTTfyy771NYYNFVJclkxHyE5qw4m27crHF1y\\nUNWEjuqNMi/lwAErS9fFa2oJlWyT8U7zzv/5kQREkxZI6y9v0AF3qcbsy2731FnD\\ns9ChJvOUW9toIab2gsIdrKW8ZNpu084ZFVKb6LNjvIXI1Se4oMTHeszXzNptzlot\\nkdxxjOoaQMAyfljFSot1F1FlU6MQlag7UnFGvFjRHN1JI5q4K+n3a67DX+TMyRqS\\nHQIDAQAB\",\"VITE_APP_DISABLE_PREVENT_UNLOAD\":\"\",\"VITE_PKG_NAME\":\"@zsviczian/excalidraw\",\"VITE_PKG_VERSION\":\"0.18.0-54\",\"VITE_IS_EXCALIDRAW_NPM_PACKAGE\":true}).PKG_VERSION}` // is provided during package build\n: \"@excalidraw/excalidraw\" // fallback to the latest package version (i.e. for app)\n}/dist/prod/`;\n\n//# sourceURL=webpack://ExcalidrawLib/./fonts/ExcalidrawFontFace.ts?");
17209
17209
 
17210
17210
  /***/ }),
17211
17211
 
@@ -20130,7 +20130,7 @@ eval("module.exports = /*#__PURE__*/JSON.parse('{\"labels\":{\"paste\":\"Επι
20130
20130
  /***/ ((module) => {
20131
20131
 
20132
20132
  "use strict";
20133
- eval("module.exports = /*#__PURE__*/JSON.parse('{\"labels\":{\"laser\":\"Toggle laser pointer\",\"paste\":\"Paste\",\"pasteAsPlaintext\":\"Paste as plaintext\",\"pasteCharts\":\"Paste charts\",\"selectAll\":\"Select all\",\"multiSelect\":\"Add element to selection\",\"moveCanvas\":\"Move canvas\",\"cut\":\"Cut\",\"copy\":\"Copy\",\"copyAsPng\":\"Copy to clipboard as PNG\",\"copyAsSvg\":\"Copy to clipboard as SVG\",\"copyText\":\"Copy to clipboard as text\",\"copySource\":\"Copy source to clipboard\",\"convertToCode\":\"Convert to code\",\"bringForward\":\"Bring forward\",\"sendToBack\":\"Send to back\",\"bringToFront\":\"Bring to front\",\"sendBackward\":\"Send backward\",\"delete\":\"Delete\",\"copyStyles\":\"Copy styles\",\"pasteStyles\":\"Paste styles\",\"stroke\":\"Stroke\",\"changeStroke\":\"Change stroke color\",\"background\":\"Background\",\"changeBackground\":\"Change background color\",\"fill\":\"Fill\",\"strokeWidth\":\"Stroke width\",\"strokeStyle\":\"Stroke style\",\"strokeStyle_solid\":\"Solid\",\"strokeStyle_dashed\":\"Dashed\",\"strokeStyle_dotted\":\"Dotted\",\"sloppiness\":\"Sloppiness\",\"opacity\":\"Opacity\",\"textAlign\":\"Text align\",\"edges\":\"Edges\",\"sharp\":\"Sharp\",\"round\":\"Round\",\"arrowheads\":\"Arrowheads\",\"arrowhead_none\":\"None\",\"arrowhead_arrow\":\"Arrow\",\"arrowhead_bar\":\"Bar\",\"arrowhead_dot\":\"Dot\",\"arrowhead_circle\":\"Circle\",\"arrowhead_circle_outline\":\"Circle (outline)\",\"arrowhead_triangle\":\"Triangle\",\"arrowhead_triangle_outline\":\"Triangle (outline)\",\"arrowhead_diamond\":\"Diamond\",\"arrowhead_diamond_outline\":\"Diamond (outline)\",\"arrowhead_crowfoot_many\":\"Crow\\'s foot (many)\",\"arrowhead_crowfoot_one\":\"Crow\\'s foot (one)\",\"arrowhead_crowfoot_one_or_many\":\"Crow\\'s foot (one or many)\",\"more_options\":\"More options\",\"arrowtypes\":\"Arrow type\",\"arrowtype_sharp\":\"Sharp arrow\",\"arrowtype_round\":\"Curved arrow\",\"arrowtype_elbowed\":\"Elbow arrow\",\"fontSize\":\"Font size\",\"fontFamily\":\"Font family\",\"addWatermark\":\"Add \\\\\"Made with Excalidraw\\\\\"\",\"handDrawn\":\"Hand-drawn\",\"normal\":\"Normal\",\"code\":\"Code\",\"localFont\":\"Local Font\",\"small\":\"Small\",\"medium\":\"Medium\",\"large\":\"Large\",\"veryLarge\":\"Very large\",\"solid\":\"Solid\",\"hachure\":\"Hachure\",\"zigzag\":\"Zigzag\",\"crossHatch\":\"Cross-hatch\",\"extraThin\":\"Extra thin\",\"thin\":\"Thin\",\"bold\":\"Bold\",\"left\":\"Left\",\"center\":\"Center\",\"right\":\"Right\",\"extraBold\":\"Extra bold\",\"architect\":\"Architect\",\"artist\":\"Artist\",\"cartoonist\":\"Cartoonist\",\"fileTitle\":\"File name\",\"colorPicker\":\"Color picker\",\"canvasColors\":\"Used on canvas\",\"canvasBackground\":\"Canvas background\",\"drawingCanvas\":\"Drawing canvas\",\"clearCanvas\":\"Clear canvas\",\"layers\":\"Layers\",\"actions\":\"Actions\",\"language\":\"Language\",\"liveCollaboration\":\"Live collaboration...\",\"duplicateSelection\":\"Duplicate\",\"untitled\":\"Untitled\",\"name\":\"Name\",\"yourName\":\"Your name\",\"madeWithExcalidraw\":\"Made with Excalidraw\",\"group\":\"Group selection\",\"ungroup\":\"Ungroup selection\",\"collaborators\":\"Collaborators\",\"toggleGrid\":\"Toggle grid\",\"addToLibrary\":\"Add to library\",\"removeFromLibrary\":\"Remove from library\",\"libraryLoadingMessage\":\"Loading library…\",\"libraries\":\"Browse libraries\",\"loadingScene\":\"Loading scene…\",\"loadScene\":\"Load scene from file\",\"align\":\"Align\",\"alignTop\":\"Align top\",\"alignBottom\":\"Align bottom\",\"alignLeft\":\"Align left\",\"alignRight\":\"Align right\",\"centerVertically\":\"Center vertically\",\"centerHorizontally\":\"Center horizontally\",\"distributeHorizontally\":\"Distribute horizontally\",\"distributeVertically\":\"Distribute vertically\",\"flipHorizontal\":\"Flip horizontal\",\"flipVertical\":\"Flip vertical\",\"viewMode\":\"View mode\",\"share\":\"Share\",\"showStroke\":\"Show stroke color picker\",\"showBackground\":\"Show background color picker\",\"showFonts\":\"Show font picker\",\"toggleTheme\":\"Toggle light/dark theme\",\"theme\":\"Theme\",\"personalLib\":\"Personal Library\",\"excalidrawLib\":\"Excalidraw Library\",\"decreaseFontSize\":\"Decrease font size\",\"increaseFontSize\":\"Increase font size\",\"unbindText\":\"Unbind text\",\"bindText\":\"Bind text to the container\",\"createContainerFromText\":\"Wrap text in a container\",\"link\":{\"edit\":\"Edit link\",\"editEmbed\":\"Edit embeddable link\",\"create\":\"Add link\",\"label\":\"Link\",\"labelEmbed\":\"Link & embed\",\"empty\":\"No link is set\",\"hint\":\"Type or paste your link here\",\"goToElement\":\"Go to target element\"},\"lineEditor\":{\"edit\":\"Edit line\",\"editArrow\":\"Edit arrow\"},\"polygon\":{\"breakPolygon\":\"Break polygon\",\"convertToPolygon\":\"Convert to polygon\"},\"elementLock\":{\"lock\":\"Lock\",\"unlock\":\"Unlock\",\"lockAll\":\"Lock all\",\"unlockAll\":\"Unlock all\"},\"statusPublished\":\"Published\",\"sidebarLock\":\"Keep sidebar open\",\"selectAllElementsInFrame\":\"Select all elements in frame\",\"removeAllElementsFromFrame\":\"Remove all elements from frame\",\"eyeDropper\":\"Pick color from canvas\",\"textToDiagram\":\"Text to diagram\",\"prompt\":\"Prompt\",\"followUs\":\"Follow us\",\"discordChat\":\"Discord chat\",\"zoomToFitViewport\":\"Zoom to fit in viewport\",\"zoomToFitSelection\":\"Zoom to fit selection\",\"zoomToFit\":\"Zoom to fit all elements\",\"installPWA\":\"Install Excalidraw locally (PWA)\",\"autoResize\":\"Enable text auto-resizing\",\"imageCropping\":\"Image cropping\",\"unCroppedDimension\":\"Uncropped dimension\",\"copyElementLink\":\"Copy link to object\",\"linkToElement\":\"Link to object\",\"wrapSelectionInFrame\":\"Wrap selection in frame\",\"tab\":\"Tab\",\"shapeSwitch\":\"Switch shape\",\"toggleFrameRole\":\"Toggle frame role\"},\"elementLink\":{\"title\":\"Link to object\",\"desc\":\"Click on a shape on canvas or paste a link.\",\"notFound\":\"Linked object wasn\\'t found on canvas.\"},\"library\":{\"noItems\":\"No items added yet...\",\"hint_emptyLibrary\":\"Select an item on canvas to add it here, or install a library from the public repository, below.\",\"hint_emptyPrivateLibrary\":\"Select an item on canvas to add it here.\",\"search\":{\"inputPlaceholder\":\"Search library\",\"heading\":\"Library matches\",\"noResults\":\"No matching items found...\",\"clearSearch\":\"Clear search\"}},\"search\":{\"title\":\"Find on canvas\",\"noMatch\":\"No matches found...\",\"singleResult\":\"result\",\"multipleResults\":\"results\",\"placeholder\":\"Find text on canvas...\",\"frames\":\"Frames\",\"texts\":\"Texts\"},\"buttons\":{\"clearReset\":\"Reset the canvas\",\"exportJSON\":\"Export to file\",\"exportImage\":\"Export image...\",\"export\":\"Save to...\",\"copyToClipboard\":\"Copy to clipboard\",\"copyLink\":\"Copy link\",\"save\":\"Save to current file\",\"saveAs\":\"Save as\",\"load\":\"Open\",\"getShareableLink\":\"Get shareable link\",\"close\":\"Close\",\"selectLanguage\":\"Select language\",\"scrollBackToContent\":\"Scroll back to content\",\"zoomIn\":\"Zoom in\",\"zoomOut\":\"Zoom out\",\"resetZoom\":\"Reset zoom\",\"menu\":\"Menu\",\"done\":\"Done\",\"edit\":\"Edit\",\"undo\":\"Undo\",\"redo\":\"Redo\",\"resetLibrary\":\"Reset library\",\"createNewRoom\":\"Create new room\",\"fullScreen\":\"Full screen\",\"darkMode\":\"Dark mode\",\"lightMode\":\"Light mode\",\"systemMode\":\"System mode\",\"zenMode\":\"Zen mode\",\"objectsSnapMode\":\"Snap to objects\",\"exitZenMode\":\"Exit zen mode\",\"cancel\":\"Cancel\",\"saveLibNames\":\"Save name(s) and exit\",\"clear\":\"Clear\",\"remove\":\"Remove\",\"embed\":\"Toggle embedding\",\"publishLibrary\":\"Rename or publish\",\"submit\":\"Submit\",\"confirm\":\"Confirm\",\"embeddableInteractionButton\":\"Click to interact\"},\"alerts\":{\"clearReset\":\"This will clear the whole canvas. Are you sure?\",\"couldNotCreateShareableLink\":\"Couldn\\'t create shareable link.\",\"couldNotCreateShareableLinkTooBig\":\"Couldn\\'t create shareable link: the scene is too big\",\"couldNotLoadInvalidFile\":\"Couldn\\'t load invalid file\",\"importBackendFailed\":\"Importing from backend failed.\",\"cannotExportEmptyCanvas\":\"Cannot export empty canvas.\",\"couldNotCopyToClipboard\":\"Couldn\\'t copy to clipboard.\",\"decryptFailed\":\"Couldn\\'t decrypt data.\",\"uploadedSecurly\":\"The upload has been secured with end-to-end encryption, which means that Excalidraw server and third parties can\\'t read the content.\",\"loadSceneOverridePrompt\":\"Loading external drawing will replace your existing content. Do you wish to continue?\",\"collabStopOverridePrompt\":\"Stopping the session will overwrite your previous, locally stored drawing. Are you sure?\\\\n\\\\n(If you want to keep your local drawing, simply close the browser tab instead.)\",\"errorAddingToLibrary\":\"Couldn\\'t add item to the library\",\"errorRemovingFromLibrary\":\"Couldn\\'t remove item from the library\",\"confirmAddLibrary\":\"This will add {{numShapes}} shape(s) to your library. Are you sure?\",\"imageDoesNotContainScene\":\"This image does not seem to contain any scene data. Have you enabled scene embedding during export?\",\"cannotRestoreFromImage\":\"Scene couldn\\'t be restored from this image file\",\"invalidSceneUrl\":\"Couldn\\'t import scene from the supplied URL. It\\'s either malformed, or doesn\\'t contain valid Excalidraw JSON data.\",\"resetLibrary\":\"This will clear your library. Are you sure?\",\"removeItemsFromsLibrary\":\"Delete {{count}} item(s) from library?\",\"invalidEncryptionKey\":\"Encryption key must be of 22 characters. Live collaboration is disabled.\",\"collabOfflineWarning\":\"No internet connection available.\\\\nYour changes will not be saved!\",\"localStorageQuotaExceeded\":\"Browser storage quota exceeded. Changes will not be saved.\"},\"errors\":{\"unsupportedFileType\":\"Unsupported file type.\",\"imageInsertError\":\"Couldn\\'t insert image. Try again later...\",\"fileTooBig\":\"File is too big. Maximum allowed size is {{maxSize}}.\",\"svgImageInsertError\":\"Couldn\\'t insert SVG image. The SVG markup looks invalid.\",\"failedToFetchImage\":\"Failed to fetch image.\",\"cannotResolveCollabServer\":\"Couldn\\'t connect to the collab server. Please reload the page and try again.\",\"importLibraryError\":\"Couldn\\'t load library\",\"saveLibraryError\":\"Couldn\\'t save library to storage. Please save your library to a file locally to make sure you don\\'t lose changes.\",\"collabSaveFailed\":\"Couldn\\'t save to the backend database. If problems persist, you should save your file locally to ensure you don\\'t lose your work.\",\"collabSaveFailed_sizeExceeded\":\"Couldn\\'t save to the backend database, the canvas seems to be too big. You should save the file locally to ensure you don\\'t lose your work.\",\"imageToolNotSupported\":\"Images are disabled.\",\"brave_measure_text_error\":{\"line1\":\"Looks like you are using Brave browser with the <bold>Aggressively Block Fingerprinting</bold> setting enabled.\",\"line2\":\"This could result in breaking the <bold>Text Elements</bold> in your drawings.\",\"line3\":\"We strongly recommend disabling this setting. You can follow <link>these steps</link> on how to do so.\",\"line4\":\"If disabling this setting doesn\\'t fix the display of text elements, please open an <issueLink>issue</issueLink> on our GitHub, or write us on <discordLink>Discord</discordLink>\"},\"libraryElementTypeError\":{\"embeddable\":\"Embeddable elements cannot be added to the library.\",\"iframe\":\"IFrame elements cannot be added to the library.\",\"image\":\"Support for adding images to the library coming soon!\"},\"asyncPasteFailedOnRead\":\"Couldn\\'t paste (couldn\\'t read from system clipboard).\",\"asyncPasteFailedOnParse\":\"Couldn\\'t paste.\",\"copyToSystemClipboardFailed\":\"Couldn\\'t copy to clipboard.\"},\"toolBar\":{\"selection\":\"Selection\",\"lasso\":\"Lasso selection\",\"image\":\"Insert image\",\"rectangle\":\"Rectangle\",\"diamond\":\"Diamond\",\"ellipse\":\"Ellipse\",\"arrow\":\"Arrow\",\"line\":\"Line\",\"freedraw\":\"Draw\",\"text\":\"Text\",\"library\":\"Library\",\"lock\":\"Keep selected tool active after drawing\",\"penMode\":\"Pen mode - prevent touch\",\"link\":\"Add / Update link for a selected shape\",\"eraser\":\"Eraser\",\"frame\":\"Frame tool\",\"magicframe\":\"Wireframe to code\",\"embeddable\":\"Web Embed\",\"laser\":\"Laser pointer\",\"hand\":\"Hand (panning tool)\",\"extraTools\":\"More tools\",\"mermaidToExcalidraw\":\"Mermaid to Excalidraw\",\"convertElementType\":\"Toggle shape type\"},\"element\":{\"rectangle\":\"Rectangle\",\"diamond\":\"Diamond\",\"ellipse\":\"Ellipse\",\"arrow\":\"Arrow\",\"line\":\"Line\",\"freedraw\":\"Freedraw\",\"text\":\"Text\",\"image\":\"Image\",\"group\":\"Group\",\"frame\":\"Frame\",\"magicframe\":\"Wireframe to code\",\"embeddable\":\"Web Embed\",\"selection\":\"Selection\",\"iframe\":\"IFrame\"},\"headings\":{\"canvasActions\":\"Canvas actions\",\"selectedShapeActions\":\"Selected shape actions\",\"shapes\":\"Shapes\"},\"hints\":{\"dismissSearch\":\"{{shortcut}} to dismiss search\",\"canvasPanning\":\"To move canvas, hold {{shortcut_1}} or {{shortcut_2}} while dragging, or use the hand tool\",\"linearElement\":\"Click to start multiple points, drag for single line\",\"arrowTool\":\"Click to start multiple points, drag for single line. Press {{shortcut}} again to change arrow type.\",\"arrowBindModifiers\":\"Hold {{shortcut_1}} to bind inside, or {{shortcut_2}} to disable binding\",\"freeDraw\":\"Click and drag, release when you\\'re finished\",\"text\":\"Tip: you can also add text by double-clicking anywhere with the selection tool\",\"embeddable\":\"Click-drag to create a website embed\",\"text_selected\":\"Double-click or press {{shortcut}} to edit text\",\"text_editing\":\"Press {{shortcut_1}} or {{shortcut_2}} to finish editing\",\"linearElementMulti\":\"Click on last point or press {{shortcut_1}} or {{shortcut_2}} to finish\",\"lockAngle\":\"You can constrain angle by holding {{shortcut}}\",\"resize\":\"You can constrain proportions by holding {{shortcut_1}} while resizing,\\\\nhold {{shortcut_2}} to resize from the center\",\"resizeImage\":\"You can resize freely by holding {{shortcut_1}},\\\\nhold {{shortcut_2}} to resize from the center\",\"rotate\":\"You can constrain angles by holding {{shortcut}} while rotating\",\"lineEditor_info\":\"Hold {{shortcut_1}} and Double-click or press {{shortcut_2}} to edit points\",\"lineEditor_line_info\":\"Double-click or press {{shortcut}} to edit points\",\"lineEditor_pointSelected\":\"Press {{shortcut_1}} to remove point(s),\\\\n{{shortcut_2}} to duplicate, or drag to move\",\"lineEditor_nothingSelected\":\"Select a point to edit (hold {{shortcut_1}} to select multiple),\\\\nor hold {{shortcut_2}} and click to add new points\",\"publishLibrary\":\"Publish your own library\",\"bindTextToElement\":\"{{shortcut}} to add text\",\"createFlowchart\":\"{{shortcut}} to create a flowchart\",\"deepBoxSelect\":\"Hold {{shortcut}} to deep select, and to prevent dragging\",\"eraserRevert\":\"Hold {{shortcut}} to revert the elements marked for deletion\",\"firefox_clipboard_write\":\"This feature can likely be enabled by setting the \\\\\"dom.events.asyncClipboard.clipboardItem\\\\\" flag to \\\\\"true\\\\\". To change the browser flags in Firefox, visit the \\\\\"about:config\\\\\" page.\",\"disableSnapping\":\"Hold {{shortcut}} to disable snapping\",\"enterCropEditor\":\"Double click the image or press {{shortcut}} to crop the image\",\"leaveCropEditor\":\"Click outside the image or press {{shortcut_1}} or {{shortcut_2}} to finish cropping\"},\"canvasError\":{\"cannotShowPreview\":\"Cannot show preview\",\"canvasTooBig\":\"The canvas may be too big.\",\"canvasTooBigTip\":\"Tip: try moving the farthest elements a bit closer together.\"},\"errorSplash\":{\"headingMain\":\"Encountered an error. Try <button>reloading the page</button>.\",\"clearCanvasMessage\":\"If reloading doesn\\'t work, try <button>clearing the canvas</button>.\",\"clearCanvasCaveat\":\" This will result in loss of work \",\"trackedToSentry\":\"The error with identifier {{eventId}} was tracked on our system.\",\"openIssueMessage\":\"We were very cautious not to include your scene information on the error. If your scene is not private, please consider following up on our <button>bug tracker</button>. Please include information below by copying and pasting into the GitHub issue.\",\"sceneContent\":\"Scene content:\"},\"shareDialog\":{\"or\":\"Or\"},\"roomDialog\":{\"desc_intro\":\"Invite people to collaborate on your drawing.\",\"desc_privacy\":\"Don\\'t worry, the session is end-to-end encrypted, and fully private. Not even our server can see what you draw.\",\"button_startSession\":\"Start session\",\"button_stopSession\":\"Stop session\",\"desc_inProgressIntro\":\"Live-collaboration session is now in progress.\",\"desc_shareLink\":\"Share this link with anyone you want to collaborate with:\",\"desc_exitSession\":\"Stopping the session will disconnect you from the room, but you\\'ll be able to continue working with the scene, locally. Note that this won\\'t affect other people, and they\\'ll still be able to collaborate on their version.\",\"shareTitle\":\"Join a live collaboration session on Excalidraw\"},\"errorDialog\":{\"title\":\"Error\"},\"exportDialog\":{\"disk_title\":\"Save to disk\",\"disk_details\":\"Export the scene data to a file from which you can import later.\",\"disk_button\":\"Save to file\",\"link_title\":\"Shareable link\",\"link_details\":\"Export as a read-only link.\",\"link_button\":\"Export to Link\",\"excalidrawplus_description\":\"Save the scene to your Excalidraw+ workspace.\",\"excalidrawplus_button\":\"Export\",\"excalidrawplus_exportError\":\"Couldn\\'t export to Excalidraw+ at this moment...\"},\"helpDialog\":{\"blog\":\"Read our blog\",\"click\":\"click\",\"deepSelect\":\"Deep select\",\"deepBoxSelect\":\"Deep select within box, and prevent dragging\",\"createFlowchart\":\"Create a flowchart from a generic element\",\"navigateFlowchart\":\"Navigate a flowchart\",\"curvedArrow\":\"Curved arrow\",\"curvedLine\":\"Curved line\",\"documentation\":\"Documentation\",\"doubleClick\":\"double-click\",\"drag\":\"drag\",\"editor\":\"Editor\",\"editLineArrowPoints\":\"Edit line/arrow points\",\"editText\":\"Edit text / add label\",\"github\":\"Found an issue? Submit\",\"howto\":\"Follow our guides\",\"or\":\"or\",\"preventBinding\":\"Prevent arrow binding\",\"tools\":\"Tools\",\"shortcuts\":\"Keyboard shortcuts\",\"textFinish\":\"Finish editing (text editor)\",\"textNewLine\":\"Add new line (text editor)\",\"title\":\"Help\",\"view\":\"View\",\"zoomToFit\":\"Zoom to fit all elements\",\"zoomToSelection\":\"Zoom to selection\",\"toggleElementLock\":\"Lock/unlock selection\",\"movePageUpDown\":\"Move page up/down\",\"movePageLeftRight\":\"Move page left/right\",\"cropStart\":\"Crop image\",\"cropFinish\":\"Finish image cropping\"},\"clearCanvasDialog\":{\"title\":\"Clear canvas\"},\"publishDialog\":{\"title\":\"Publish library\",\"itemName\":\"Item name\",\"authorName\":\"Author name\",\"githubUsername\":\"GitHub username\",\"twitterUsername\":\"Twitter username\",\"libraryName\":\"Library name\",\"libraryDesc\":\"Library description\",\"website\":\"Website\",\"placeholder\":{\"authorName\":\"Your name or username\",\"libraryName\":\"Name of your library\",\"libraryDesc\":\"Description of your library to help people understand its usage\",\"githubHandle\":\"GitHub handle (optional), so you can edit the library once submitted for review\",\"twitterHandle\":\"Twitter username (optional), so we know who to credit when promoting over Twitter\",\"website\":\"Link to your personal website or elsewhere (optional)\"},\"errors\":{\"required\":\"Required\",\"website\":\"Enter a valid URL\"},\"noteDescription\":\"Submit your library to be included in the <link>public library repository</link> for other people to use in their drawings.\",\"noteGuidelines\":\"The library needs to be manually approved first. Please read the <link>guidelines</link> before submitting. You will need a GitHub account to communicate and make changes if requested, but it is not strictly required.\",\"noteLicense\":\"By submitting, you agree the library will be published under the <link>MIT License</link>, which in short means anyone can use them without restrictions.\",\"noteItems\":\"Each library item must have its own name so it\\'s filterable. The following library items will be included:\",\"atleastOneLibItem\":\"Please select at least one library item to get started\",\"republishWarning\":\"Note: some of the selected items are marked as already published/submitted. You should only resubmit items when updating an existing library or submission.\"},\"publishSuccessDialog\":{\"title\":\"Library submitted\",\"content\":\"Thank you {{authorName}}. Your library has been submitted for review. You can track the status <link>here</link>\"},\"confirmDialog\":{\"resetLibrary\":\"Reset library\",\"removeItemsFromLib\":\"Remove selected items from library\"},\"imageExportDialog\":{\"header\":\"Export image\",\"label\":{\"withBackground\":\"Background\",\"onlySelected\":\"Only selected\",\"darkMode\":\"Dark mode\",\"embedScene\":\"Embed scene\",\"scale\":\"Scale\",\"padding\":\"Padding\"},\"tooltip\":{\"embedScene\":\"Scene data will be saved into the exported PNG/SVG file so that the scene can be restored from it.\\\\nWill increase exported file size.\"},\"title\":{\"exportToPng\":\"Export to PNG\",\"exportToSvg\":\"Export to SVG\",\"copyPngToClipboard\":\"Copy PNG to clipboard\"},\"button\":{\"exportToPng\":\"PNG\",\"exportToSvg\":\"SVG\",\"copyPngToClipboard\":\"Copy to clipboard\"}},\"encrypted\":{\"tooltip\":\"Your drawings are end-to-end encrypted so Excalidraw\\'s servers will never see them.\",\"link\":\"Blog post on end-to-end encryption in Excalidraw\"},\"stats\":{\"angle\":\"Angle\",\"shapes\":\"Shapes\",\"height\":\"Height\",\"scene\":\"Scene\",\"selected\":\"Selected\",\"storage\":\"Storage\",\"fullTitle\":\"Canvas & Shape properties\",\"title\":\"Properties\",\"generalStats\":\"General\",\"elementProperties\":\"Shape properties\",\"total\":\"Total\",\"version\":\"Version\",\"versionCopy\":\"Click to copy\",\"versionNotAvailable\":\"Version not available\",\"width\":\"Width\"},\"toast\":{\"addedToLibrary\":\"Added to library\",\"copyStyles\":\"Copied styles.\",\"copyToClipboard\":\"Copied to clipboard.\",\"copyToClipboardAsPng\":\"Copied {{exportSelection}} to clipboard as PNG\\\\n({{exportColorScheme}})\",\"copyToClipboardAsSvg\":\"Copied {{exportSelection}} to clipboard as SVG\\\\n({{exportColorScheme}})\",\"fileSaved\":\"File saved.\",\"fileSavedToFilename\":\"Saved to {filename}\",\"canvas\":\"canvas\",\"selection\":\"selection\",\"pasteAsSingleElement\":\"Use {{shortcut}} to paste as a single element,\\\\nor paste into an existing text editor\",\"unableToEmbed\":\"Embedding this url is currently not allowed. Raise an issue on GitHub to request the url whitelisted\",\"unrecognizedLinkFormat\":\"The link you embedded does not match the expected format. Please try to paste the \\'embed\\' string provided by the source site\",\"elementLinkCopied\":\"Link copied to clipboard\"},\"colors\":{\"transparent\":\"Transparent\",\"black\":\"Black\",\"white\":\"White\",\"red\":\"Red\",\"pink\":\"Pink\",\"grape\":\"Grape\",\"violet\":\"Violet\",\"gray\":\"Gray\",\"blue\":\"Blue\",\"cyan\":\"Cyan\",\"teal\":\"Teal\",\"green\":\"Green\",\"yellow\":\"Yellow\",\"orange\":\"Orange\",\"bronze\":\"Bronze\"},\"welcomeScreen\":{\"app\":{\"center_heading\":\"All your data is saved locally in your browser.\",\"center_heading_plus\":\"Did you want to go to the Excalidraw+ instead?\",\"menuHint\":\"Export, preferences, languages, ...\"},\"defaults\":{\"menuHint\":\"Export, preferences, and more...\",\"center_heading\":\"Diagrams. Made. Simple.\",\"toolbarHint\":\"Pick a tool & Start drawing!\",\"helpHint\":\"Shortcuts & help\"}},\"colorPicker\":{\"color\":\"Color\",\"mostUsedCustomColors\":\"Most used custom colors\",\"colors\":\"Colors\",\"shades\":\"Shades\",\"hexCode\":\"Hex code\",\"noShades\":\"No shades available for this color\"},\"overwriteConfirm\":{\"action\":{\"exportToImage\":{\"title\":\"Export as image\",\"button\":\"Export as image\",\"description\":\"Export the scene data as an image from which you can import later.\"},\"saveToDisk\":{\"title\":\"Save to disk\",\"button\":\"Save to disk\",\"description\":\"Export the scene data to a file from which you can import later.\"},\"excalidrawPlus\":{\"title\":\"Excalidraw+\",\"button\":\"Export to Excalidraw+\",\"description\":\"Save the scene to your Excalidraw+ workspace.\"}},\"modal\":{\"loadFromFile\":{\"title\":\"Load from file\",\"button\":\"Load from file\",\"description\":\"Loading from a file will <bold>replace your existing content</bold>.<br></br>You can back up your drawing first using one of the options below.\"},\"shareableLink\":{\"title\":\"Load from link\",\"button\":\"Replace my content\",\"description\":\"Loading external drawing will <bold>replace your existing content</bold>.<br></br>You can back up your drawing first by using one of the options below.\"}}},\"mermaid\":{\"title\":\"Mermaid to Excalidraw\",\"button\":\"Insert\",\"description\":\"Currently only <flowchartLink>Flowchart</flowchartLink>,<sequenceLink> Sequence, </sequenceLink> and <classLink>Class </classLink>Diagrams are supported. The other types will be rendered as image in Excalidraw.\",\"syntax\":\"Mermaid Syntax\",\"preview\":\"Preview\"},\"quickSearch\":{\"placeholder\":\"Quick search\"},\"fontList\":{\"badge\":{\"old\":\"old\"},\"sceneFonts\":\"In this scene\",\"availableFonts\":\"Available fonts\",\"empty\":\"No fonts found\"},\"userList\":{\"empty\":\"No users found\",\"hint\":{\"text\":\"Click on user to follow\",\"followStatus\":\"You\\'re currently following this user\",\"inCall\":\"User is in a voice call\",\"micMuted\":\"User\\'s microphone is muted\",\"isSpeaking\":\"User is speaking\"}},\"commandPalette\":{\"title\":\"Command palette\",\"shortcuts\":{\"select\":\"Select\",\"confirm\":\"Confirm\",\"close\":\"Close\"},\"recents\":\"Recently used\",\"search\":{\"placeholder\":\"Search menus, commands, and discover hidden gems\",\"noMatch\":\"No matching commands...\"},\"itemNotAvailable\":\"Command is not available...\",\"shortcutHint\":\"For Command palette, use {{shortcut}}\"},\"keys\":{\"ctrl\":\"Ctrl\",\"option\":\"Option\",\"cmd\":\"Cmd\",\"alt\":\"Alt\",\"escape\":\"Esc\",\"enter\":\"Enter\",\"shift\":\"Shift\",\"spacebar\":\"Space\",\"delete\":\"Delete\",\"mmb\":\"Scroll wheel\"}}');\n\n//# sourceURL=webpack://ExcalidrawLib/./locales/en.json?");
20133
+ eval("module.exports = /*#__PURE__*/JSON.parse('{\"labels\":{\"laser\":\"Toggle laser pointer\",\"paste\":\"Paste\",\"pasteAsPlaintext\":\"Paste as plaintext\",\"pasteCharts\":\"Paste charts\",\"selectAll\":\"Select all\",\"multiSelect\":\"Add element to selection\",\"moveCanvas\":\"Move canvas\",\"cut\":\"Cut\",\"copy\":\"Copy\",\"copyAsPng\":\"Copy to clipboard as PNG\",\"copyAsSvg\":\"Copy to clipboard as SVG\",\"copyText\":\"Copy to clipboard as text\",\"copySource\":\"Copy source to clipboard\",\"convertToCode\":\"Convert to code\",\"bringForward\":\"Bring forward\",\"sendToBack\":\"Send to back\",\"bringToFront\":\"Bring to front\",\"sendBackward\":\"Send backward\",\"delete\":\"Delete\",\"copyStyles\":\"Copy styles\",\"pasteStyles\":\"Paste styles\",\"stroke\":\"Stroke\",\"changeStroke\":\"Change stroke color\",\"background\":\"Background\",\"changeBackground\":\"Change background color\",\"fill\":\"Fill\",\"strokeWidth\":\"Stroke width\",\"strokeStyle\":\"Stroke style\",\"strokeStyle_solid\":\"Solid\",\"strokeStyle_dashed\":\"Dashed\",\"strokeStyle_dotted\":\"Dotted\",\"sloppiness\":\"Sloppiness\",\"opacity\":\"Opacity\",\"textAlign\":\"Text align\",\"edges\":\"Edges\",\"sharp\":\"Sharp\",\"round\":\"Round\",\"arrowheads\":\"Arrowheads\",\"arrowhead_none\":\"None\",\"arrowhead_arrow\":\"Arrow\",\"arrowhead_bar\":\"Bar\",\"arrowhead_dot\":\"Dot\",\"arrowhead_circle\":\"Circle\",\"arrowhead_circle_outline\":\"Circle (outline)\",\"arrowhead_triangle\":\"Triangle\",\"arrowhead_triangle_outline\":\"Triangle (outline)\",\"arrowhead_diamond\":\"Diamond\",\"arrowhead_diamond_outline\":\"Diamond (outline)\",\"arrowhead_crowfoot_many\":\"Crow\\'s foot (many)\",\"arrowhead_crowfoot_one\":\"Crow\\'s foot (one)\",\"arrowhead_crowfoot_one_or_many\":\"Crow\\'s foot (one or many)\",\"more_options\":\"More options\",\"arrowtypes\":\"Arrow type\",\"arrowtype_sharp\":\"Sharp arrow\",\"arrowtype_round\":\"Curved arrow\",\"arrowtype_elbowed\":\"Elbow arrow\",\"fontSize\":\"Font size\",\"fontFamily\":\"Font family\",\"addWatermark\":\"Add \\\\\"Made with Excalidraw\\\\\"\",\"handDrawn\":\"Hand-drawn\",\"normal\":\"Normal\",\"code\":\"Code\",\"localFont\":\"Local Font\",\"small\":\"Small\",\"medium\":\"Medium\",\"large\":\"Large\",\"veryLarge\":\"Very large\",\"solid\":\"Solid\",\"hachure\":\"Hachure\",\"zigzag\":\"Zigzag\",\"crossHatch\":\"Cross-hatch\",\"extraThin\":\"Extra thin\",\"thin\":\"Thin\",\"bold\":\"Bold\",\"left\":\"Left\",\"center\":\"Center\",\"right\":\"Right\",\"extraBold\":\"Extra bold\",\"architect\":\"Architect\",\"artist\":\"Artist\",\"cartoonist\":\"Cartoonist\",\"fileTitle\":\"File name\",\"colorPicker\":\"Color picker\",\"canvasColors\":\"Used on canvas\",\"canvasBackground\":\"Canvas background\",\"drawingCanvas\":\"Drawing canvas\",\"clearCanvas\":\"Clear canvas\",\"layers\":\"Layers\",\"actions\":\"Actions\",\"language\":\"Language\",\"liveCollaboration\":\"Live collaboration...\",\"duplicateSelection\":\"Duplicate\",\"untitled\":\"Untitled\",\"name\":\"Name\",\"yourName\":\"Your name\",\"madeWithExcalidraw\":\"Made with Excalidraw\",\"group\":\"Group selection\",\"ungroup\":\"Ungroup selection\",\"collaborators\":\"Collaborators\",\"toggleGrid\":\"Toggle grid\",\"addToLibrary\":\"Add to library\",\"removeFromLibrary\":\"Remove from library\",\"libraryLoadingMessage\":\"Loading library…\",\"libraries\":\"Browse libraries\",\"loadingScene\":\"Loading scene…\",\"loadScene\":\"Load scene from file\",\"align\":\"Align\",\"alignTop\":\"Align top\",\"alignBottom\":\"Align bottom\",\"alignLeft\":\"Align left\",\"alignRight\":\"Align right\",\"centerVertically\":\"Center vertically\",\"centerHorizontally\":\"Center horizontally\",\"distributeHorizontally\":\"Distribute horizontally\",\"distributeVertically\":\"Distribute vertically\",\"flipHorizontal\":\"Flip horizontal\",\"flipVertical\":\"Flip vertical\",\"viewMode\":\"View mode\",\"share\":\"Share\",\"showStroke\":\"Show stroke color picker\",\"showBackground\":\"Show background color picker\",\"showFonts\":\"Show font picker\",\"toggleTheme\":\"Toggle light/dark theme\",\"theme\":\"Theme\",\"personalLib\":\"Personal Library\",\"excalidrawLib\":\"Excalidraw Library\",\"decreaseFontSize\":\"Decrease font size\",\"increaseFontSize\":\"Increase font size\",\"unbindText\":\"Unbind text\",\"bindText\":\"Bind text to the container\",\"createContainerFromText\":\"Wrap text in a container\",\"link\":{\"edit\":\"Edit link\",\"editEmbed\":\"Edit embeddable link\",\"create\":\"Add link\",\"label\":\"Link\",\"labelEmbed\":\"Link & embed\",\"empty\":\"No link is set\",\"hint\":\"Type or paste your link here\",\"goToElement\":\"Go to target element\"},\"lineEditor\":{\"edit\":\"Edit line\",\"editArrow\":\"Edit arrow\"},\"polygon\":{\"breakPolygon\":\"Break polygon\",\"convertToPolygon\":\"Convert to polygon\"},\"elementLock\":{\"lock\":\"Lock\",\"unlock\":\"Unlock\",\"lockAll\":\"Lock all\",\"unlockAll\":\"Unlock all\"},\"statusPublished\":\"Published\",\"sidebarLock\":\"Keep sidebar open\",\"selectAllElementsInFrame\":\"Select all elements in frame\",\"removeAllElementsFromFrame\":\"Remove all elements from frame\",\"eyeDropper\":\"Pick color from canvas\",\"textToDiagram\":\"Text to diagram\",\"prompt\":\"Prompt\",\"followUs\":\"Follow us\",\"discordChat\":\"Discord chat\",\"zoomToFitViewport\":\"Zoom to fit in viewport\",\"zoomToFitSelection\":\"Zoom to fit selection\",\"zoomToFit\":\"Zoom to fit all elements\",\"installPWA\":\"Install Excalidraw locally (PWA)\",\"autoResize\":\"Enable text auto-resizing\",\"imageCropping\":\"Image cropping\",\"unCroppedDimension\":\"Uncropped dimension\",\"copyElementLink\":\"Copy link to object\",\"linkToElement\":\"Link to object\",\"wrapSelectionInFrame\":\"Wrap selection in frame\",\"tab\":\"Tab\",\"shapeSwitch\":\"Switch shape\",\"toggleFrameRole\":\"Toggle frame role\"},\"elementLink\":{\"title\":\"Link to object\",\"desc\":\"Click on a shape on canvas or paste a link.\",\"notFound\":\"Linked object wasn\\'t found on canvas.\"},\"library\":{\"noItems\":\"No items added yet...\",\"hint_emptyLibrary\":\"Select an item on canvas to add it here, or install a library from the public repository, below.\",\"hint_emptyPrivateLibrary\":\"Select an item on canvas to add it here.\",\"search\":{\"inputPlaceholder\":\"Search library\",\"heading\":\"Library matches\",\"noResults\":\"No matching items found...\",\"clearSearch\":\"Clear search\"}},\"search\":{\"title\":\"Find on canvas\",\"noMatch\":\"No matches found...\",\"singleResult\":\"result\",\"multipleResults\":\"results\",\"placeholder\":\"Find text on canvas...\",\"frames\":\"Frames\",\"texts\":\"Texts\"},\"buttons\":{\"clearReset\":\"Reset the canvas\",\"exportJSON\":\"Export to file\",\"exportImage\":\"Export image...\",\"export\":\"Save to...\",\"copyToClipboard\":\"Copy to clipboard\",\"copyLink\":\"Copy link\",\"save\":\"Save to current file\",\"saveAs\":\"Save as\",\"load\":\"Open\",\"getShareableLink\":\"Get shareable link\",\"close\":\"Close\",\"selectLanguage\":\"Select language\",\"scrollBackToContent\":\"Scroll back to content\",\"zoomIn\":\"Zoom in\",\"zoomOut\":\"Zoom out\",\"resetZoom\":\"Reset zoom\",\"menu\":\"Menu\",\"done\":\"Done\",\"edit\":\"Edit\",\"undo\":\"Undo\",\"redo\":\"Redo\",\"resetLibrary\":\"Reset library\",\"createNewRoom\":\"Create new room\",\"fullScreen\":\"Full screen\",\"darkMode\":\"Dark mode\",\"lightMode\":\"Light mode\",\"systemMode\":\"System mode\",\"zenMode\":\"Zen mode\",\"objectsSnapMode\":\"Snap to objects\",\"exitZenMode\":\"Exit zen mode\",\"cancel\":\"Cancel\",\"saveLibNames\":\"Save name(s) and exit\",\"clear\":\"Clear\",\"remove\":\"Remove\",\"embed\":\"Toggle embedding\",\"publishLibrary\":\"Rename or publish\",\"submit\":\"Submit\",\"confirm\":\"Confirm\",\"embeddableInteractionButton\":\"Click to interact\"},\"alerts\":{\"clearReset\":\"This will clear the whole canvas. Are you sure?\",\"couldNotCreateShareableLink\":\"Couldn\\'t create shareable link.\",\"couldNotCreateShareableLinkTooBig\":\"Couldn\\'t create shareable link: the scene is too big\",\"couldNotLoadInvalidFile\":\"Couldn\\'t load invalid file\",\"importBackendFailed\":\"Importing from backend failed.\",\"cannotExportEmptyCanvas\":\"Cannot export empty canvas.\",\"couldNotCopyToClipboard\":\"Couldn\\'t copy to clipboard.\",\"decryptFailed\":\"Couldn\\'t decrypt data.\",\"uploadedSecurly\":\"The upload has been secured with end-to-end encryption, which means that Excalidraw server and third parties can\\'t read the content.\",\"loadSceneOverridePrompt\":\"Loading external drawing will replace your existing content. Do you wish to continue?\",\"collabStopOverridePrompt\":\"Stopping the session will overwrite your previous, locally stored drawing. Are you sure?\\\\n\\\\n(If you want to keep your local drawing, simply close the browser tab instead.)\",\"errorAddingToLibrary\":\"Couldn\\'t add item to the library\",\"errorRemovingFromLibrary\":\"Couldn\\'t remove item from the library\",\"confirmAddLibrary\":\"This will add {{numShapes}} shape(s) to your library. Are you sure?\",\"imageDoesNotContainScene\":\"This image does not seem to contain any scene data. Have you enabled scene embedding during export?\",\"cannotRestoreFromImage\":\"Scene couldn\\'t be restored from this image file\",\"invalidSceneUrl\":\"Couldn\\'t import scene from the supplied URL. It\\'s either malformed, or doesn\\'t contain valid Excalidraw JSON data.\",\"resetLibrary\":\"This will clear your library. Are you sure?\",\"removeItemsFromsLibrary\":\"Delete {{count}} item(s) from library?\",\"invalidEncryptionKey\":\"Encryption key must be of 22 characters. Live collaboration is disabled.\",\"collabOfflineWarning\":\"No internet connection available.\\\\nYour changes will not be saved!\",\"localStorageQuotaExceeded\":\"Browser storage quota exceeded. Changes will not be saved.\"},\"errors\":{\"unsupportedFileType\":\"Unsupported file type.\",\"imageInsertError\":\"Couldn\\'t insert image. Try again later...\",\"fileTooBig\":\"File is too big. Maximum allowed size is {{maxSize}}.\",\"svgImageInsertError\":\"Couldn\\'t insert SVG image. The SVG markup looks invalid.\",\"failedToFetchImage\":\"Failed to fetch image.\",\"cannotResolveCollabServer\":\"Couldn\\'t connect to the collab server. Please reload the page and try again.\",\"importLibraryError\":\"Couldn\\'t load library\",\"saveLibraryError\":\"Couldn\\'t save library to storage. Please save your library to a file locally to make sure you don\\'t lose changes.\",\"collabSaveFailed\":\"Couldn\\'t save to the backend database. If problems persist, you should save your file locally to ensure you don\\'t lose your work.\",\"collabSaveFailed_sizeExceeded\":\"Couldn\\'t save to the backend database, the canvas seems to be too big. You should save the file locally to ensure you don\\'t lose your work.\",\"imageToolNotSupported\":\"Images are disabled.\",\"brave_measure_text_error\":{\"line1\":\"Looks like you are using Brave browser with the <bold>Aggressively Block Fingerprinting</bold> setting enabled.\",\"line2\":\"This could result in breaking the <bold>Text Elements</bold> in your drawings.\",\"line3\":\"We strongly recommend disabling this setting. You can follow <link>these steps</link> on how to do so.\",\"line4\":\"If disabling this setting doesn\\'t fix the display of text elements, please open an <issueLink>issue</issueLink> on our GitHub, or write us on <discordLink>Discord</discordLink>\"},\"libraryElementTypeError\":{\"embeddable\":\"Embeddable elements cannot be added to the library.\",\"iframe\":\"IFrame elements cannot be added to the library.\",\"image\":\"Support for adding images to the library coming soon!\"},\"asyncPasteFailedOnRead\":\"Couldn\\'t paste (couldn\\'t read from system clipboard).\",\"asyncPasteFailedOnParse\":\"Couldn\\'t paste.\",\"copyToSystemClipboardFailed\":\"Couldn\\'t copy to clipboard.\"},\"toolBar\":{\"selection\":\"Selection\",\"lasso\":\"Lasso selection\",\"image\":\"Insert image\",\"rectangle\":\"Rectangle\",\"diamond\":\"Diamond\",\"ellipse\":\"Ellipse\",\"arrow\":\"Arrow\",\"line\":\"Line\",\"freedraw\":\"Draw\",\"text\":\"Text\",\"library\":\"Library\",\"lock\":\"Keep selected tool active after drawing\",\"penMode\":\"Pen mode - prevent touch\",\"link\":\"Add / Update link for a selected shape\",\"eraser\":\"Eraser\",\"frame\":\"Frame tool\",\"magicframe\":\"Wireframe to code\",\"embeddable\":\"Web Embed\",\"laser\":\"Laser pointer\",\"hand\":\"Hand (panning tool)\",\"extraTools\":\"More tools\",\"mermaidToExcalidraw\":\"Mermaid to Excalidraw\",\"convertElementType\":\"Toggle shape type\"},\"element\":{\"rectangle\":\"Rectangle\",\"diamond\":\"Diamond\",\"ellipse\":\"Ellipse\",\"arrow\":\"Arrow\",\"line\":\"Line\",\"freedraw\":\"Freedraw\",\"text\":\"Text\",\"image\":\"Image\",\"group\":\"Group\",\"frame\":\"Frame\",\"magicframe\":\"Wireframe to code\",\"embeddable\":\"Web Embed\",\"selection\":\"Selection\",\"iframe\":\"IFrame\"},\"headings\":{\"canvasActions\":\"Canvas actions\",\"selectedShapeActions\":\"Selected shape actions\",\"shapes\":\"Shapes\"},\"hints\":{\"dismissSearch\":\"{{shortcut}} to dismiss search\",\"canvasPanning\":\"To move canvas, hold {{shortcut_1}} or {{shortcut_2}} while dragging, or use the hand tool\",\"linearElement\":\"Click to start multiple points, drag for single line\",\"arrowTool\":\"Click to start multiple points, drag for single line. Press {{shortcut}} again to change arrow type.\",\"arrowBindModifiers\":\"Hold {{shortcut_1}} to disable binding, or {{shortcut_2}} to bind at a fixed point\",\"freeDraw\":\"Click and drag, release when you\\'re finished\",\"text\":\"Tip: you can also add text by double-clicking anywhere with the selection tool\",\"embeddable\":\"Click-drag to create a website embed\",\"text_selected\":\"Double-click or press {{shortcut}} to edit text\",\"text_editing\":\"Press {{shortcut_1}} or {{shortcut_2}} to finish editing\",\"linearElementMulti\":\"Click on last point or press {{shortcut_1}} or {{shortcut_2}} to finish\",\"lockAngle\":\"You can constrain angle by holding {{shortcut}}\",\"resize\":\"You can constrain proportions by holding {{shortcut_1}} while resizing,\\\\nhold {{shortcut_2}} to resize from the center\",\"resizeImage\":\"You can resize freely by holding {{shortcut_1}},\\\\nhold {{shortcut_2}} to resize from the center\",\"rotate\":\"You can constrain angles by holding {{shortcut}} while rotating\",\"lineEditor_info\":\"Hold {{shortcut_1}} and Double-click or press {{shortcut_2}} to edit points\",\"lineEditor_line_info\":\"Double-click or press {{shortcut}} to edit points\",\"lineEditor_pointSelected\":\"Press {{shortcut_1}} to remove point(s),\\\\n{{shortcut_2}} to duplicate, or drag to move\",\"lineEditor_nothingSelected\":\"Select a point to edit (hold {{shortcut_1}} to select multiple),\\\\nor hold {{shortcut_2}} and click to add new points\",\"publishLibrary\":\"Publish your own library\",\"bindTextToElement\":\"{{shortcut}} to add text\",\"createFlowchart\":\"{{shortcut}} to create a flowchart\",\"deepBoxSelect\":\"Hold {{shortcut}} to deep select, and to prevent dragging\",\"eraserRevert\":\"Hold {{shortcut}} to revert the elements marked for deletion\",\"firefox_clipboard_write\":\"This feature can likely be enabled by setting the \\\\\"dom.events.asyncClipboard.clipboardItem\\\\\" flag to \\\\\"true\\\\\". To change the browser flags in Firefox, visit the \\\\\"about:config\\\\\" page.\",\"disableSnapping\":\"Hold {{shortcut}} to disable snapping\",\"enterCropEditor\":\"Double click the image or press {{shortcut}} to crop the image\",\"leaveCropEditor\":\"Click outside the image or press {{shortcut_1}} or {{shortcut_2}} to finish cropping\"},\"canvasError\":{\"cannotShowPreview\":\"Cannot show preview\",\"canvasTooBig\":\"The canvas may be too big.\",\"canvasTooBigTip\":\"Tip: try moving the farthest elements a bit closer together.\"},\"errorSplash\":{\"headingMain\":\"Encountered an error. Try <button>reloading the page</button>.\",\"clearCanvasMessage\":\"If reloading doesn\\'t work, try <button>clearing the canvas</button>.\",\"clearCanvasCaveat\":\" This will result in loss of work \",\"trackedToSentry\":\"The error with identifier {{eventId}} was tracked on our system.\",\"openIssueMessage\":\"We were very cautious not to include your scene information on the error. If your scene is not private, please consider following up on our <button>bug tracker</button>. Please include information below by copying and pasting into the GitHub issue.\",\"sceneContent\":\"Scene content:\"},\"shareDialog\":{\"or\":\"Or\"},\"roomDialog\":{\"desc_intro\":\"Invite people to collaborate on your drawing.\",\"desc_privacy\":\"Don\\'t worry, the session is end-to-end encrypted, and fully private. Not even our server can see what you draw.\",\"button_startSession\":\"Start session\",\"button_stopSession\":\"Stop session\",\"desc_inProgressIntro\":\"Live-collaboration session is now in progress.\",\"desc_shareLink\":\"Share this link with anyone you want to collaborate with:\",\"desc_exitSession\":\"Stopping the session will disconnect you from the room, but you\\'ll be able to continue working with the scene, locally. Note that this won\\'t affect other people, and they\\'ll still be able to collaborate on their version.\",\"shareTitle\":\"Join a live collaboration session on Excalidraw\"},\"errorDialog\":{\"title\":\"Error\"},\"exportDialog\":{\"disk_title\":\"Save to disk\",\"disk_details\":\"Export the scene data to a file from which you can import later.\",\"disk_button\":\"Save to file\",\"link_title\":\"Shareable link\",\"link_details\":\"Export as a read-only link.\",\"link_button\":\"Export to Link\",\"excalidrawplus_description\":\"Save the scene to your Excalidraw+ workspace.\",\"excalidrawplus_button\":\"Export\",\"excalidrawplus_exportError\":\"Couldn\\'t export to Excalidraw+ at this moment...\"},\"helpDialog\":{\"blog\":\"Read our blog\",\"click\":\"click\",\"deepSelect\":\"Deep select\",\"deepBoxSelect\":\"Deep select within box, and prevent dragging\",\"createFlowchart\":\"Create a flowchart from a generic element\",\"navigateFlowchart\":\"Navigate a flowchart\",\"curvedArrow\":\"Curved arrow\",\"curvedLine\":\"Curved line\",\"documentation\":\"Documentation\",\"doubleClick\":\"double-click\",\"drag\":\"drag\",\"editor\":\"Editor\",\"editLineArrowPoints\":\"Edit line/arrow points\",\"editText\":\"Edit text / add label\",\"github\":\"Found an issue? Submit\",\"howto\":\"Follow our guides\",\"or\":\"or\",\"preventBinding\":\"Prevent arrow binding\",\"tools\":\"Tools\",\"shortcuts\":\"Keyboard shortcuts\",\"textFinish\":\"Finish editing (text editor)\",\"textNewLine\":\"Add new line (text editor)\",\"title\":\"Help\",\"view\":\"View\",\"zoomToFit\":\"Zoom to fit all elements\",\"zoomToSelection\":\"Zoom to selection\",\"toggleElementLock\":\"Lock/unlock selection\",\"movePageUpDown\":\"Move page up/down\",\"movePageLeftRight\":\"Move page left/right\",\"cropStart\":\"Crop image\",\"cropFinish\":\"Finish image cropping\"},\"clearCanvasDialog\":{\"title\":\"Clear canvas\"},\"publishDialog\":{\"title\":\"Publish library\",\"itemName\":\"Item name\",\"authorName\":\"Author name\",\"githubUsername\":\"GitHub username\",\"twitterUsername\":\"Twitter username\",\"libraryName\":\"Library name\",\"libraryDesc\":\"Library description\",\"website\":\"Website\",\"placeholder\":{\"authorName\":\"Your name or username\",\"libraryName\":\"Name of your library\",\"libraryDesc\":\"Description of your library to help people understand its usage\",\"githubHandle\":\"GitHub handle (optional), so you can edit the library once submitted for review\",\"twitterHandle\":\"Twitter username (optional), so we know who to credit when promoting over Twitter\",\"website\":\"Link to your personal website or elsewhere (optional)\"},\"errors\":{\"required\":\"Required\",\"website\":\"Enter a valid URL\"},\"noteDescription\":\"Submit your library to be included in the <link>public library repository</link> for other people to use in their drawings.\",\"noteGuidelines\":\"The library needs to be manually approved first. Please read the <link>guidelines</link> before submitting. You will need a GitHub account to communicate and make changes if requested, but it is not strictly required.\",\"noteLicense\":\"By submitting, you agree the library will be published under the <link>MIT License</link>, which in short means anyone can use them without restrictions.\",\"noteItems\":\"Each library item must have its own name so it\\'s filterable. The following library items will be included:\",\"atleastOneLibItem\":\"Please select at least one library item to get started\",\"republishWarning\":\"Note: some of the selected items are marked as already published/submitted. You should only resubmit items when updating an existing library or submission.\"},\"publishSuccessDialog\":{\"title\":\"Library submitted\",\"content\":\"Thank you {{authorName}}. Your library has been submitted for review. You can track the status <link>here</link>\"},\"confirmDialog\":{\"resetLibrary\":\"Reset library\",\"removeItemsFromLib\":\"Remove selected items from library\"},\"imageExportDialog\":{\"header\":\"Export image\",\"label\":{\"withBackground\":\"Background\",\"onlySelected\":\"Only selected\",\"darkMode\":\"Dark mode\",\"embedScene\":\"Embed scene\",\"scale\":\"Scale\",\"padding\":\"Padding\"},\"tooltip\":{\"embedScene\":\"Scene data will be saved into the exported PNG/SVG file so that the scene can be restored from it.\\\\nWill increase exported file size.\"},\"title\":{\"exportToPng\":\"Export to PNG\",\"exportToSvg\":\"Export to SVG\",\"copyPngToClipboard\":\"Copy PNG to clipboard\"},\"button\":{\"exportToPng\":\"PNG\",\"exportToSvg\":\"SVG\",\"copyPngToClipboard\":\"Copy to clipboard\"}},\"encrypted\":{\"tooltip\":\"Your drawings are end-to-end encrypted so Excalidraw\\'s servers will never see them.\",\"link\":\"Blog post on end-to-end encryption in Excalidraw\"},\"stats\":{\"angle\":\"Angle\",\"shapes\":\"Shapes\",\"height\":\"Height\",\"scene\":\"Scene\",\"selected\":\"Selected\",\"storage\":\"Storage\",\"fullTitle\":\"Canvas & Shape properties\",\"title\":\"Properties\",\"generalStats\":\"General\",\"elementProperties\":\"Shape properties\",\"total\":\"Total\",\"version\":\"Version\",\"versionCopy\":\"Click to copy\",\"versionNotAvailable\":\"Version not available\",\"width\":\"Width\"},\"toast\":{\"addedToLibrary\":\"Added to library\",\"copyStyles\":\"Copied styles.\",\"copyToClipboard\":\"Copied to clipboard.\",\"copyToClipboardAsPng\":\"Copied {{exportSelection}} to clipboard as PNG\\\\n({{exportColorScheme}})\",\"copyToClipboardAsSvg\":\"Copied {{exportSelection}} to clipboard as SVG\\\\n({{exportColorScheme}})\",\"fileSaved\":\"File saved.\",\"fileSavedToFilename\":\"Saved to {filename}\",\"canvas\":\"canvas\",\"selection\":\"selection\",\"pasteAsSingleElement\":\"Use {{shortcut}} to paste as a single element,\\\\nor paste into an existing text editor\",\"unableToEmbed\":\"Embedding this url is currently not allowed. Raise an issue on GitHub to request the url whitelisted\",\"unrecognizedLinkFormat\":\"The link you embedded does not match the expected format. Please try to paste the \\'embed\\' string provided by the source site\",\"elementLinkCopied\":\"Link copied to clipboard\"},\"colors\":{\"transparent\":\"Transparent\",\"black\":\"Black\",\"white\":\"White\",\"red\":\"Red\",\"pink\":\"Pink\",\"grape\":\"Grape\",\"violet\":\"Violet\",\"gray\":\"Gray\",\"blue\":\"Blue\",\"cyan\":\"Cyan\",\"teal\":\"Teal\",\"green\":\"Green\",\"yellow\":\"Yellow\",\"orange\":\"Orange\",\"bronze\":\"Bronze\"},\"welcomeScreen\":{\"app\":{\"center_heading\":\"All your data is saved locally in your browser.\",\"center_heading_plus\":\"Did you want to go to the Excalidraw+ instead?\",\"menuHint\":\"Export, preferences, languages, ...\"},\"defaults\":{\"menuHint\":\"Export, preferences, and more...\",\"center_heading\":\"Diagrams. Made. Simple.\",\"toolbarHint\":\"Pick a tool & Start drawing!\",\"helpHint\":\"Shortcuts & help\"}},\"colorPicker\":{\"color\":\"Color\",\"mostUsedCustomColors\":\"Most used custom colors\",\"colors\":\"Colors\",\"shades\":\"Shades\",\"hexCode\":\"Hex code\",\"noShades\":\"No shades available for this color\"},\"overwriteConfirm\":{\"action\":{\"exportToImage\":{\"title\":\"Export as image\",\"button\":\"Export as image\",\"description\":\"Export the scene data as an image from which you can import later.\"},\"saveToDisk\":{\"title\":\"Save to disk\",\"button\":\"Save to disk\",\"description\":\"Export the scene data to a file from which you can import later.\"},\"excalidrawPlus\":{\"title\":\"Excalidraw+\",\"button\":\"Export to Excalidraw+\",\"description\":\"Save the scene to your Excalidraw+ workspace.\"}},\"modal\":{\"loadFromFile\":{\"title\":\"Load from file\",\"button\":\"Load from file\",\"description\":\"Loading from a file will <bold>replace your existing content</bold>.<br></br>You can back up your drawing first using one of the options below.\"},\"shareableLink\":{\"title\":\"Load from link\",\"button\":\"Replace my content\",\"description\":\"Loading external drawing will <bold>replace your existing content</bold>.<br></br>You can back up your drawing first by using one of the options below.\"}}},\"mermaid\":{\"title\":\"Mermaid to Excalidraw\",\"button\":\"Insert\",\"description\":\"Currently only <flowchartLink>Flowchart</flowchartLink>,<sequenceLink> Sequence, </sequenceLink> and <classLink>Class </classLink>Diagrams are supported. The other types will be rendered as image in Excalidraw.\",\"syntax\":\"Mermaid Syntax\",\"preview\":\"Preview\"},\"quickSearch\":{\"placeholder\":\"Quick search\"},\"fontList\":{\"badge\":{\"old\":\"old\"},\"sceneFonts\":\"In this scene\",\"availableFonts\":\"Available fonts\",\"empty\":\"No fonts found\"},\"userList\":{\"empty\":\"No users found\",\"hint\":{\"text\":\"Click on user to follow\",\"followStatus\":\"You\\'re currently following this user\",\"inCall\":\"User is in a voice call\",\"micMuted\":\"User\\'s microphone is muted\",\"isSpeaking\":\"User is speaking\"}},\"commandPalette\":{\"title\":\"Command palette\",\"shortcuts\":{\"select\":\"Select\",\"confirm\":\"Confirm\",\"close\":\"Close\"},\"recents\":\"Recently used\",\"search\":{\"placeholder\":\"Search menus, commands, and discover hidden gems\",\"noMatch\":\"No matching commands...\"},\"itemNotAvailable\":\"Command is not available...\",\"shortcutHint\":\"For Command palette, use {{shortcut}}\"},\"keys\":{\"ctrl\":\"Ctrl\",\"option\":\"Option\",\"cmd\":\"Cmd\",\"alt\":\"Alt\",\"escape\":\"Esc\",\"enter\":\"Enter\",\"shift\":\"Shift\",\"spacebar\":\"Space\",\"delete\":\"Delete\",\"mmb\":\"Scroll wheel\"}}');\n\n//# sourceURL=webpack://ExcalidrawLib/./locales/en.json?");
20134
20134
 
20135
20135
  /***/ }),
20136
20136
 
@@ -20713,7 +20713,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
20713
20713
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
20714
20714
 
20715
20715
  "use strict";
20716
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _excalidraw_common_constants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @excalidraw/common/constants */ \"../common/src/constants.ts\");\n\n\nif (\"development\" !== _excalidraw_common_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.18.0-53\"}/dist/`;\n}\n\n//# sourceURL=webpack://ExcalidrawLib/./publicPath.js?");
20716
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _excalidraw_common_constants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @excalidraw/common/constants */ \"../common/src/constants.ts\");\n\n\nif (\"development\" !== _excalidraw_common_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.18.0-54\"}/dist/`;\n}\n\n//# sourceURL=webpack://ExcalidrawLib/./publicPath.js?");
20717
20717
 
20718
20718
  /***/ }),
20719
20719